ITQuants blog

Fusion Invest/Capital Sophis v7: how to update third parties, using XML?

Apr 29

Written by:
4/29/2016 11:35 AM  RssIcon

In my previous post, I've described how to update third parties using the API, as it was done by several Misys clients. This time, continuing on this subject, I will explain how to update third parties, using XML files. I remembered that I've implemented this solution at least one time by a client, in a web service. Third parties were updated using the Sophis xml definition, that you can find in the party.xsd file stored in the schema folder. The web service implementation is already described more in details in this post : "How to develop a IIS webservice using the API". Unfortunately, the C++ code is not anymore maintained in the v7: C++ header files that were present in the Low Level Toolkit folders are not delivered anymore. A workaround exists, this is the subject of this post of how to replace this code.

In this webservice, I've used the CSRThirdParty::Update method, which accepts a sophis::Tools::dataModel::DataSet parameter as input. This class still exists in v7. The only problem is that nothing permits to update it using a xml string. For example, the previous code was the following one:

#include "SphLLInc/Sphtools/dataModel/BasicDataSet.h"
#include "SphLLInc/Sphtools/dataModel/DataSetArchive.h"
#include "SphLLInc/xml/dataModel/XMLDataAdapter.h"
#include "SphLLInc/XML/dataModel/BasicXMLDocument.h"
 
 
...
sophis::tools::dataModel::BasicDataSetHandle _dataHandle = sophis::tools::dataModel::BasicDataSet::create();
sophis::tools::dataModel::DataSet& _dataset = (*_dataHandle);
 
sophis::xml::dataModel::XMLDataImporter _import(xmlDescription);
try
{
    _import.importTo(_dataset);
}
catch(ExceptionBase& _exception)
{
    exception->set(__ITQ_E_XMLIMPORT__,(const char*)_exception);
}
catch(...)
{
    exception->set(__ITQ_E_XMLIMPORT__,"Unknown exception");
}

The XMLDataImporter class does not exist anymore and should be replaced. By the way,as explained in my previous post, using CSRThirdParty to update data in database does not work anymore too. For remember, the following previous code worked fine:

try
{
    _thirdParty = const_cast<sophis:sophis:sophis::backoffice_kernel::csrthirdparty*>(sophis::backoffice_kernel::CSRThirdParty::Find(_dataset,</sophis:sophis:sophis::backoffice_kernel::csrthirdparty*>false)); // to create or update, we should have at least an identifier permitting the search...
}
catch(ExceptionBase& _exception)
{
    exception->set(__ITQ_E_THIRDPARTY_GETTING__,(const char*)_exception);
}
catch(...)
{
    exception->set(__ITQ_E_THIRDPARTY_GETTING__,"Unknown exception");
}
try
{
    // update in memory (does nothing on the database)
    if(_thirdParty!=NULL)
    {
        _thirdParty = _thirdParty->Clone();
        _thirdParty->Update(_dataset); // only need to update it
    }
    else
        _thirdParty = sophis::backoffice_kernel::CSRThirdParty::Create(_dataset); // create a new third party, must be deleted after
    // after, update in database
    if(_thirdParty!=NULL)
    {
        (*result) = _thirdParty->GetIdent();
        if((*result)==0) // try to get the reserved code, if any
            (*result) = _thirdParty->getReservedCode();
        if((*result)==0) // nothing on the reserved code too, should get ourselves
        {
            errorCode _error = CSRSqlQuery::QueryReturning1Long("select SEQTIERS.nextval from dual",result);
            if(_error==0)
                _thirdParty->reserveCode((*result));
        }
        if(m_transactionMode)
            _thirdParty->MultiSave(sophis::backoffice_kernel::smApi,m_events);
        else
            _thirdParty->Save();
    }
}

By chance, the C# Sophis DotNet Toolkit implements methods that use the native MS XMLReader instead. The solution consists then to use C++ managed code in order to update the third party.

This can be done as follow:

#pragma managed
#include <msclr\marshal.h></msclr\marshal.h>
using namespace System;
using namespace System::Windows::Forms::ComponentModel;
using namespace System::Windows::Forms;
using namespace msclr::interop;
using namespace System::Xml;
 
bool updateThirdParty(long identifier, const char* xmlContent)
{
    sophis::backoffice_kernel::CSMThirdPartyDlg^ _thirdParty = sophis::backoffice_kernel::CSMThirdPartyDlg::GetCSRThirdParty(identifier);
    if(_thirdParty!=nullptr)
    {
        try
        {
            System::String^ _xmlContent = marshal_as<system::string^>(xmlContent);</system::string^>
            XmlReaderSettings^ _settings = gcnew XmlReaderSettings();
            _settings->IgnoreWhitespace = true;
 
            XmlReader^ _writer = XmlReader::Create(gcnew System::IO::StringReader(_xmlContent),_settings);
 
            sophis::backoffice_kernel::CSMThirdPartyDlg^ _clone = _thirdParty->Clone();
            _clone->UpdateFromDescription(_writer);
            _clone->Save();
 
            return true;
        }
        catch(System::Exception^ e)
        {
            String^ s = e->Message;
        }
    }
 
    return false;
}

 

As you can see, it is really even easier!

Search blog