ITQuants blog

Fusion Invest: how to implement a post-commit treatment when saving an instrument?

Sep 29

Written by:
9/29/2014 2:05 PM  RssIcon

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

Search blog