Fusion Invest: how to implement a post-commit treatment when saving an instrument?
Sep
29
Written by:
9/29/2014 2:05 PM
Using the Sophis toolkit, it is easy to save user data by filling the parameter columnName in the CSRElement constructor and the ones of its derivated classes. When overriding the CSRInstrumentDialog class, the data will be then stored in a field of the Sophis native Oracle table TITRES, on which you have to add the expected field. Prefixing the field to remember that the field was created by the client is the common rule used. For other user data on which an entire Oracle table needs to be created, it is safe to override the CSRFitDialog::Save method too. Now, if you have to store other data even when having no GUI open, when using batches for example, the best is to add an implementation of the CSRInstrumentAction class, and to save data on the callback NotifyCreated and NotifyModified. All these things are basic concepts explained in the Sophis documentation. There are some cases on which we need to save data after the Oracle commit. This post will explain how to implement it.
The first thing to do is to catch the fact that the instrument will be saved. This can be done using an implementation of the CSRInstrumentAction class as follow:
In the header file:
class
IDialogNotification
{
public
:
virtual
void
NotifyCreated(
const
CSRInstrument& instrument) = 0;
virtual
void
NotifyModified(
const
CSRInstrument& instrument, NSREnums::eParameterModificationType type) = 0;
virtual
void
OnAfterCommit(
long
sicovam) = 0;
};
class
ITQInstrumentDlgAction :
public
CSRInstrumentAction
{
DECLARATION_INSTRUMENT_ACTION(ITQInstrumentDlgAction)
public
:
static
ITQInstrumentDlgAction* GetInstance();
static
void
AddSubscriber(
HWND
hWnd, IDialogNotification* subscriber);
static
void
RemoveSubscriber(
HWND
hWnd);
// Sophis overrides
virtual
void
NotifyCreated(
const
CSRInstrument &instrument, tools::CSREventVector & message)
throw
(sophisTools::base::ExceptionBase);
virtual
void
NotifyModified(
const
CSRInstrument &instrument, NSREnums::eParameterModificationType type, tools::CSREventVector & message)
throw
(sophisTools::base::ExceptionBase);
private
:
static
ITQInstrumentDlgAction* m_instance;
typedef
std::map<
HWND
,IDialogNotification*> Subscribers;
static
Subscribers m_subscribers;
};
The abstract class IDialogNotification has to be implemented on the derivated class of CSRInstrumentDialog. It will permit to be notified of the actions done on the instrument. In the open method, we have to register the subscription of the notifications. On the Close method, we will remove the subcription. The Sophis callback NotifyCreated and NotifyModified accept as parameter a vector of CSREvent objects, that have to be sent once the commit done. The cleverness consists to use an abstract event that will do extra save on the Send calllback.
On the NotifyModified, you will get some code like this one. We want to notify the dialog once the commit is done. By using the Sophis fWind internal class member, it is possible to retrieve the MFC CDialog object on which we can get the linked Windows handle that we have used to register the callback methods.
void
ITQInstrumentDlgAction::NotifyModified(
const
CSRInstrument& instrument, NSREnums::eParameterModificationType type, CSREventVector& messages)
{
CDialog* _dlg =
dynamic_cast
(
reinterpret_cast
(fWind));
if
(_dlg)
{
Subscribers::const_iterator _search = m_subscribers.find(_dlg->m_hWnd);
if
(_search!=m_subscribers.end() && _search->second!=NULL)
{
_search->second->NotifyModified(instrument,type);
ITQInstrumentEvent* _event =
new
ITQInstrumentEvent(instrument.GetCode(),_search->second,
false
);
messages.push_back(_event);
}
}
}
And the on the Send event, we will notify the dialog for extra savings, using the following code:
void
ITQInstrumentEvent::Send()
{
try
{
if
(m_notification!=NULL)
m_notification->OnAfterCommit(m_sicovam);
}
catch
(...)
{
}
}
That's all folks!
Code provided: Notifications_aftercommit.zip