API Code Samples: Difference between revisions

From RangerMSP Wiki - PSA software for MSPs and IT services providers
Jump to navigation Jump to search
 
(36 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{usermanualsapidevelopersguide}}
{{usermanualsapidevelopersguide}}
==Introduction==
==Introduction==
The Commit API allows you to add/update the following entities:
Following are samples for using the low level RangerMSP API. The samples are basic and provide an easy starting point.
*Accounts
*Assets
*Tickets
*Charges
*Appointments
*Tasks
*History Notes
*Opportunities
*Documents
*Knowledge Base Articles


Each API method requires a list of parameters which contain the field names and their values. The field names are the Database field names. You can see each field's name within the application (so you can verify which field you are about to update), by right-clicking the field and selecting Field Settings > Advanced Tab > view the Tech. Rec ID field.
__TOC__


You can view the complete list of database fields in the [[Commit API Reference Manual#API Reference Manual|API Reference Manual]] above.
==API functions==
For detailed listing of the API functions and their parameters see [[API_Reference_Manual#API_Functions|API Functions Reference Manual]].


Following are samples for using the API by Email and the Programming API. The samples are basic and provide an easy starting point.
==Code samples==
===Data Retrieval API Samples===


__TOC__
====VB Sample - Data Retrieval====
Private Declare Sub CmtInitDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xSoftWareName As String, _
  ByVal xDbPath As String, _
  ByRef xvStatus As Integer)
Private Declare Sub CmtTerminateDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ()
Private Declare Sub CmtGetDescriptionByCode Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xCode As Long, _
  ByVal xDescLen As Long, _
  ByVal xvDesc As String)
Private Declare Sub CmtGetDescriptionByStatus Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xCode As Long, _
  ByVal xDescLen As Long, _
  ByVal xvDesc As String)
 
Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
 
Private Declare Sub CmtGetFieldAttributesByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xXMLRequestBuff As String, _
  ByVal xXMLRequestBuffLen As Integer, _
  ByVal xXMLResponseDataBuff As String, _
  ByVal xXMLResponseDataBuffLen As Integer, _
  ByRef xvStatus As Integer)
 
Private Declare Sub CmtGetRecordDataByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xXMLRequestBuff As String, _
  ByVal xXMLRequestBuffLen As Integer, _
  ByVal xXMLResponseDataBuff As String, _
  ByVal xXMLResponseDataBuffLen As Integer, _
  ByRef xvStatus As Integer)
Private Declare Sub CmtGetQueryRecIds Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xXMLRequestBuff As String, _
  ByVal xXMLRequestBuffLen As Integer, _
  ByVal xXMLResponseDataBuff As String, _
  ByVal xXMLResponseDataBuffLen As Integer, _
  ByRef xvStatus As Integer)
 
  Private Const C_Ok  As Integer = 1
  Private Const C_AppName As String = "Demo"
  Private Const C_ErrorDescSize As Integer = 1024
  Private Const C_REC_ID_LEN As Integer = 20
  Private Const C_TktDataBuffSize  As Integer = 1024
  Private Const C_ChargeDataBuffSize  As Integer = 16384
rem *** XML containing a query for retrieving Charges of a specific Ticket
Private Function GetChargesRecIdOfTkRequstXml(xcTktRecId)
  GetChargesRecIdOfTkRequstXml    =
"<?xml version=""1.0"" ?>"                                              & _
"<?crmxmlqueryrequest version=""1.0"" ?>"                          & _
        "<CRMQueryDataRequest>"                                            & _
        "<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _
        "<Datakind> CHARGE </Datakind>"                                        & _
        "<MaxRecordCount> 100 </MaxRecordCount>"                              & _
        "<Query>"                                                              & _
        "<Where>"                                                            & _
        "<Link> ( </Link>"                                                & _
        "<FLDSLPTICKETID op=""="">" & xcTktRecId & "</FLDSLPTICKETID>"      & _
        "<Link> )  </Link>"                                                & _
        "</Where>"                                                          & _
        "<Order>"                                                            & _
        "<FLDSLPSLIPDATE dir=""asc""> </FLDSLPSLIPDATE>"                  & _
        "</Order>"                                                          & _
        "</Query>"                                                            & _
        "</CRMQueryDataRequest>"
End Function
rem *** String containing the Charge fields to be retrieved
Private Function GetChargeFlds()
  GetChargeFlds = "FLDSLPCARDID_FLDCRDFULLNAME"  & "," & _
                  "FLDSLPCONTACTID_FLDCRDCONTACT" & "," & _
                  "FLDSLPTICKETID_FLDTKTTICKETNO" & "," & _
                  "FLDSLPBCRECID_FLDBCTCODE"      & "," & _
                  "FLDSLPBCRECID_FLDBCTNAME"      & "," & _
                  "FLDSLPITEMID_FLDITMITEMNO"    & "," & _
                  "FLDSLPITEMID_FLDITMNAME"      & "," & _
                  "FLDSLPSLIPDATE"                & "," & _
                  "FLDSLPSTARTTIME"              & "," & _
                  "FLDSLPENDTIME"                & "," & _
                  "FLDSLPQUANTITY"                & "," & _
                  "FLDSLPPRICE"                  & "," & _
                  "FLDSLPBILLTOTAL"              & "," & _
                  "FLDSLPHOURSAMOUNT"            & "," & _
                  "FLDSLPITEMUNITISHOUR"          & "," & _
                  "FLDSLPITEMTYPEGROUP"          & "," & _
                  "FLDSLPRECID"                  & "," & _
                  "FLDSLPDESC"
End Function
rem *** XML for retrieving a specific Charge
Private Function GetChargeRecDataReqXml(xcRecId)
  GetChargeRecDataReqXml =
"<?xml version=""1.0"" ?>" & _
        "<?crmxmlgetrecdatarequest version = ""1.0"" ?>" & _
        "<CRMGetRecDataRequest>" & _
        "<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _
        "<GetRecordByRecId>" & xcRecId & "</GetRecordByRecId>" & _
        "<SelectFieldsList>" & GetChargeFlds() & " </SelectFieldsList>" & _
        "</CRMGetRecDataRequest>"
End Function
rem *************************************************************************************************
rem *** This code shows how to retrieve charges of a specific Ticket.
rem *** It performs the following steps:
rem *** 1. Initialized a connection with the database
rem *** 2. Calls CmtGetQueryRecIds to retrieve the Charges of a specific ticket according to the query
rem ***    defined in aRequestXml (which is returned from GetChargesRecIdOfTkRequstXml) 
rem *** 3. Calls CmtGetRecordDataByRecId to retrieve the Charge details of all charges returned.
rem *************************************************************************************************
Public Sub DbQry()
  Dim nStatus As Integer
  Dim aTktXMLResponseDataBuff As String * C_TktDataBuffSize
  Dim aChargeXMLResponseDataBuff As String * C_ChargeDataBuffSize
  Dim aErrorDescSize As String * C_ErrorDescSize
  Dim aChargesRecIdStr As String
  Dim aCurChargeRecIdStr As String
Rem  **** Establishing connection with RangerMSP, Should be called only once for the entire session ******
  Call CmtInitDbQryDll(C_AppName, "c:\DemoVBA\DB\", nStatus)
  If nStatus <> C_Ok Then
  Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
  MsgBox ("RangerMSP Init failed. Status Error code: " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
  Else
rem *** ADD YOUR CODE HERE (replace the line below this section):
rem *** Change the ticket ID below to fit a real ticket in your database.
  aRequestXml = GetChargesRecIdOfTkRequstXml("TKTVHIUTGO5KGUUCB4SL")
  Call CmtGetQueryRecIds(aRequestXml, Len(aRequestXml), aTktXMLResponseDataBuff, C_TktDataBuffSize, nStatus)
  If nStatus <> C_Ok Then
    MsgBox (aTktXMLResponseDataBuff)
  Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
  MsgBox ("Failed. Status Error : " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
rem *** ADD YOUR CODE HERE:
rem *** parse the XML Buffer -> aTktXMLResponseDataBuff. Extract the error code that was returned from the api***
rem *** Call CmtGetDescriptionByCode(ErrorCodeFromXml, C_ErrorDescSize, aErrorDescSize)
rem *** MsgBox ("Failed. XML Error : " & ErrorCodeFromXml & CHR(13) & CHR(10) & aErrorDescSize )
  Else
    MsgBox (aTktXMLResponseDataBuff)
rem **** ADD YOUR CODE HERE (replace the line below this section):
rem **** parse the XML Buffer(extract the charge(s) recid of the ticket) -> aTktXMLResponseDataBuff ****
rem **** The aChargesRecIdStr vairable contain the Charges recid that were extracted from the XML buffer
    aChargesRecIdStr = "SLPXBV3YB7F9F2DPGDC5SLPLORCIOPWYP5VW4NWASLPFYKGUNYT8E3NE23XU"
    Do while (Len(aChargesRecIdStr)> 0 )
      aCurChargeRecIdStr = Left(aChargesRecIdStr, C_REC_ID_LEN)
      aChargesRecIdStr =  Right(aChargesRecIdStr, Len(aChargesRecIdStr) - C_REC_ID_LEN)
      aRequestXml = GetChargeRecDataReqXml(aCurChargeRecIdStr)
      Call CmtGetRecordDataByRecId(aRequestXml, Len(aRequestXml), aChargeXMLResponseDataBuff, C_ChargeDataBuffSize, nStatus)
      If nStatus <> C_Ok Then
        MsgBox (aChargeXMLResponseDataBuff )
        Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
        MsgBox ("Failed. Status Error : " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
rem *** ADD YOUR CODE HERE:
rem *** parse the XML Buffer -> aChargeXMLResponseDataBuff. Extract the error code that was return from the api***
rem *** Call CmtGetDescriptionByCode(nStatus,C_ErrorDescSize, aErrorDescSize)
rem *** MsgBox ("Failed. XML Error : " & ErrorCodeFromXml & CHR(13) & CHR(10) & aErrorDescSize )
      Else
        MsgBox (aChargeXMLResponseDataBuff)
rem **** ADD YOUR CODE HERE: parse the XML Buffer(extract the charge info) -> aChargeXMLResponseDataBuff ****
      End If
    loop
  End If
  End If
  Call CmtTerminateDbQryDll
End Sub


===Code samples===
====VB Sample - Field Attributes Retrieval====
The following code samples demonstrate how to add and update a record in CommitCRM from VBA, C++ or Delphi programs.  
Private Declare Sub CmtInitDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xSoftWareName As String, _
  ByVal xDbPath As String, _
  ByRef xvStatus As Integer)
Private Declare Sub CmtTerminateDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ()
Private Declare Sub CmtGetDescriptionByCode Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xCode    as long, _
  ByVal xDescLen as long, _
  ByVal xvDesc  As String)
Private Declare Sub CmtGetDescriptionByStatus Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xCode    as long, _
  ByVal xDescLen as long, _
  ByVal xvDesc  As String)
Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
Private Declare Sub CmtGetFieldAttributesByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xXMLRequestBuff As String, _
  ByVal xXMLRequestBuffLen As Integer, _
  ByVal xXMLResponseDataBuff As String, _
  ByVal xXMLResponseDataBuffLen As Integer, _
  ByRef xvStatus As Integer)
Private Declare Sub CmtGetRecordDataByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xXMLRequestBuff As String, _
  ByVal xXMLRequestBuffLen As Integer, _
  ByVal xXMLResponseDataBuff As String, _
  ByVal xXMLResponseDataBuffLen As Integer, _
  ByRef xvStatus As Integer)
Private Declare Sub CmtGetQueryRecIds Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
  ByVal xXMLRequestBuff As String, _
  ByVal xXMLRequestBuffLen As Integer, _
  ByVal xXMLResponseDataBuff As String, _
  ByVal xXMLResponseDataBuffLen As Integer, _
  ByRef xvStatus As Integer)
  Private Const C_Ok  As Integer = 1
  Private Const C_AppName As String = "Demo"
  Private Const C_ErrorDescSize As Integer = 1024
  Private Const C_DataBuffSize  As Integer = 1024
rem *** XML containing the request for CmtGetFieldAttributesByRecId with the requested Field ID
Private Function GetFldAttrRequstXml(xcDicId)
  GetFldAttrRequstXml = "<?xml version=""1.0"" ?>"                                              & _
                        "<?crmxmlgetfieldattributesrequest version = ""1.0"" ?>"          & _
                        "<CRMGetRecDataRequest>"                                          & _
                          "<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _
                          "<GetRecordByRecId>" & xcDicId & "</GetRecordByRecId>"                & _
                        "</CRMGetRecDataRequest>"
End Function
 
rem *************************************************************************************************
rem *** This code shows how to retrieve field attributes (e.g Field Label, Field Name, etc.)
rem *** from the RangerMSP database dictionary.
rem *** It performs the following steps:
rem *** 1. Initialized a connection with the database
rem *** 2. Calls CmtGetFieldAttributesByRecId to retrieve the details of a specific field according to the field ID defined
rem ***    in aRequestXml 
rem *************************************************************************************************
Public Sub DbQry()
  Dim nStatus As Integer
  Dim aXMLResponseDataBuff As String * C_DataBuffSize
  Dim aErrorDescSize As String * C_ErrorDescSize
  Dim aRequestXml as String
  Call CmtInitDbQryDll(C_AppName, "c:\DemoVBA\DB\", nStatus)
  If nStatus <> C_Ok Then
    Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
    MsgBox ("RangerMSP Init failed. Status Error code: " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
  Else
    aRequestXml = GetFldAttrRequstXml("FLDCRDCITY")
    Call CmtGetFieldAttributesByRecId(aRequestXml, Len(aRequestXml), aXMLResponseDataBuff, C_DataBuffSize, nStatus)
    If nStatus <> C_Ok Then
      MsgBox (aXMLResponseDataBuff )
    Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
    MsgBox ("Failed. Status Error : " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
rem *** ADD YOUR CODE HERE: parse the XML Buffer -> aXMLResponseDataBuff. Extract the error code that was return from the api***
rem *** Call CmtGetDescriptionByCode(ErrorCodeFromXml , C_ErrorDescSize, aErrorDescSize)
rem *** MsgBox ("Failed. XML Error : " & ErrorCodeFromXml & CHR(13) & CHR(10) & aErrorDescSize )
    Else
      MsgBox (aXMLResponseDataBuff)
rem *** ADD YOUR CODE HERE: parse the XML Buffer -> aXMLResponseDataBuff ***
    End If
  End If
  Call CmtTerminateDbQryDll
End Sub


Make sure to read [[Commit API Reference Manual#Using Commit API|Using Commit API]] before going through the samples, as it provides an overview of the Commit API work-flow and how it should be used.  
===Data Update API Samples===
The following code samples demonstrate how to add and update a record in RangerMSP from VBA, C++ or Delphi programs.  


To test samples, it is recommended that you download a trial version of CommitCRM from our web site and install it on a new computer that is not running CommitCRM. Then, modify the paths in the source code to point to folder <testcomputer>\Commit\LastVer (and to the same files it already points to).  
Make sure to read [[API Developers Guide|RangerMSP API Developers Guide]] before going through the samples, as it provides an overview of the RangerMSP API work-flow and how it should be used.  


When developing your programs please make sure you work under the <testcomputer>\Commit\ThirdParty\UserDev folder (or at least call the dlls in this location). Do not copy the dll’s to any other location.  
To test samples, it is recommended that you download a trial version of RangerMSP from our web site and install it on a new computer that is not running RangerMSP. Then, modify the paths in the source code to point to folder <testcomputer>\RangerMSP\LastVer (and to the same files it already points to).  


These samples create a connection to CommitCRM's database, add a new Account record into
When developing your programs please make sure you work under the <testcomputer>\RangerMSP\ThirdParty\UserDev folder (or at least call the dlls in this location). Do not copy the dll’s to any other location.
the database, and update it. Each transaction should specify the database table to be updated by the transaction:
{| class="wikitable"
|-
! '''Application entity'''
! '''Table name'''
! '''Code'''
|-
| Accounts
| Cards
| 10
|-
| Opportunities
| Opps
| 20
|-
| Documents
| Docs
| 30
|-
| Charges
| Docs
| 30
|-
| Charges
| Slips
| 40
|-
| Appointments/Tasks
| Events
| 50
|-
| History Notes
| Notebook
| 60
|-
| Tickets
| Tickets
| 70
|-
| Items
| Items
| 80
|-
| Assets
| Assets
| 90
|-
| Knowledge Base
| KBArticles
| 100
|}


====API functions====
These samples create a connection to RangerMSP's database, add a new Account record into
The Programming API provides the following API functions:
the database, and update it. Each transaction should specify the database table to be updated by the transaction. See more details in the [[API Reference Manual]].
{| class="wikitable"
|-
! '''Method'''
! '''Return Value'''
! '''Description'''
|-
| '''CmtInitDbEngDll (app_name, path, status)'''
| status (int)
| Establishes a connection to the database. app_name - This string will be used for all functions of the package, and will appear in the application as the user who performs the changes in the records you update. You should specify a meaningful value. path - The path to the DB folder where the Commit server is installed: <server>\Commit\Db status - 1 for success. See Error Codes Description for other values.
|-
| '''CmtInsUpdRec(data_buff, map_buff, flag, tbd,<br>
rec_id_buff_size, error_codes_buff_size,<br>
err_msg_buff_size,rec_id_buff,<br>
err_codes_buff, err_msg_buff, status)'''
| status (int), rec_id (char)
| Adds/Updates records.<br>
data_buff - string containing the values to insert into the Database<br>
map_buff - mapping of the database fields corresponding with the data buff<br>
flag - stop(0)/continue(1) the input process is an invalid data value(s)<br>
tbd - Not used<br>
rec_id_buff_size - length of REC ID Buffer<br>
err_code_buff_size - length of Error Code Buffer<br>
err_msg_buff_size - length of Error Message Buffer<br>
rec_id_buff - buffer for returned REC ID<br>
err_codes_buff - buffer for returned Error Codes<br>
err_msg_buff - buffer for returned Error Messages<br>
status - returned status, 1 for success. <br>
See [[Commit API Reference Manual#Error Codes Description|Error Codes Description]] for other values.
|-
| '''CmtTerminateDbEngDll'''
|
| Close the connection to the database
|-
| '''CmtGetDescriptionByCode''' (code,<br>desc_size,<br>desc)
| message (char)
| Call this function in case of error in<br>
'''CmtInsUpdRec'''. <br>
In case of error (return code other than 1),<br>
you can use this to get error string.
|-
| '''CmtGetDescriptionByStatus'''
|
| Call this function in case of error in<br>
'''CmtInitDbEngDll'''
|}


'''Field buffers'''
The record to be added/updated in the database is passed to the Commit API in two buffers:
{| class="wikitable"
|-
! '''Parameter'''
! '''Description'''
! '''Example'''
|-
| data_buff
| String containing the <u>values</u> to insert into the Database. Separators between the fields are  defined in the map_buff
| "17/04/2008 14:44", "CRD7C9KZPS9JN3LEZVD9", "Charge", "CRDGO0SVQ6074CMAN7DW","Closed","test note in DB Engine", "NTBL6PDPKUU6NXLRHLHP","CRDBSMJ3P72EHMU0HB LX","TKT4S81466E05IM8P23X"
|-
| map_buff
| Mapping of the data_buff: separators, field names.
Field names must be in the same order as the data_buff values.
The field names should be separated with a different separator than the values (e.g. "new line").
| " , FLDHISNOTEDATETIME<br>
FLDHISWORKERID<br>
FLDHISKIND<br>
FLDHISCONTACTID<br>
FLDHISUSER1<br>
FLDHISDESCRIPTION<br>
FLDHISRECID<br>
FLDHISCARDID<br>
FLDHISLINKRECID<br>
|}


====VB Sample====
====VB Sample====
To test the following VB code, create a VB program that includes this code and executes
  Private Declare Sub CmtInitDbEngDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbEng.dll" (ByVal xSoftWareName As String, _
it, or open the Visual Basic editor included with MS-Word, paste the code into it and run it.
  ByVal xDbPath As String, ByRef xvStatus As Integer)
 
 
In order for the VB sample to compile properly, please follow these steps:
#Go to My Computer > Right Click – Properties > Advanced Tab > Environment Variable
#At the bottom of the list, search for the Path variable (not PathText)
#Double click the Path variable > go to the end of the value/line
#Add ;
#Add the path to the folder: <server>\Commit\ThirdParty\UserDev\ and confirm.
 
 
For all field description see the [[API Reference Manual]].
 
  Private Declare Sub CmtInitDbEngDll Lib "C:\DemoVBA\CmtDbEng.dll" (ByVal xSoftWareName As String, _
  ByVal xDbPath As String, ByRef xvStatus As Integer)
 
  Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
  Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
 
 
  Private Declare Sub CmtInsUpdRec Lib "C:\DemoVBA\CmtDbEng.dll" (ByVal xSoftWareName As String, _
  Private Declare Sub CmtInsUpdRec Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbEng.dll" (ByVal xSoftWareName As String, _
   ByVal xDataKind As Integer, _
   ByVal xDataKind As Integer, _
   ByVal xDataBuff As String, _
   ByVal xDataBuff As String, _
Line 192: Line 338:
   ByVal xvErrMsgLogBuff As String, _
   ByVal xvErrMsgLogBuff As String, _
   ByRef xvStatus As Integer)
   ByRef xvStatus As Integer)
    
  Private Const C_DataBuffSize  As Integer = 1024
   Private Const C_DataBuffSize  As Integer = 1024
  Private Const C_MapBufSize  As Integer = 1024
  Private Const C_MapBufSize  As Integer = 1024
  Private Const C_ErrMsgBuffSize  As Integer = 1024
  Private Const C_ErrMsgBuffSize  As Integer = 1024
  Private Const C_ErrCodeBuffSize  As Integer = 64
  Private Const C_ErrCodeBuffSize  As Integer = 64
  Private Const C_RecIDBuffSize  As Integer = 20
  Private Const C_RecIDBuffSize  As Integer = 20
  Private Const C_Flag  As Integer = 1
  Private Const C_Flag  As Integer = 1
  Private Const C_Ok  As Integer = 1
  Private Const C_Ok  As Integer = 1
  Private Const C_AccountsTable  As Integer = 10
  Private Const C_AccountsTable  As Integer = 10
 
  Private Const C_AppName As String = "Demo"
    
    
  Private Const C_AppName As String = "Demo"
  Public Sub DBEng()
  Public Sub DBEng()
    
  Dim nStatus As Integer
   Dim nStatus As Integer
  Dim l As Long
  Dim l As Long
  Dim S As String
  Dim S As String
  Dim pStr As Long
  Dim pStr As Long
  Dim MapBuff As String
  Dim MapBuff As String
  Dim DataBuff As String
  Dim DataBuff As String
  Dim RecIdBuff As String * C_RecIDBuffSize
  Dim RecIdBuff As String * C_RecIDBuffSize
  Dim ErrCodesLogBuff As String * C_ErrCodeBuffSize
  Dim ErrCodesLogBuff As String * C_ErrCodeBuffSize
  Dim ErrMsgLogBuff As String * C_ErrMsgBuffSize
  Dim ErrMsgLogBuff As String * C_ErrMsgBuffSize
   
  Call CmtInitDbEngDll(C_AppName, "C:\DemoVBA\DB\", nStatus)
  Call CmtInitDbEngDll(C_AppName, "c:\DemoVBA\DB\", nStatus)
   
  If nStatus = C_Ok Then
  If nStatus <> C_Ok Then
      
     MsgBox ("RangerMSP Init failed. Error code: " & nStatus)
  Rem  ******************** Establishing connection with Commit, Should be  
  Else
    called only once for the entire session ******
  Rem  ******************** Establishing connection with RangerMSP, Should be called only once for the entire session ******
    MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDFULLNAME" + Chr(13) + "FLDCRDDEAR" +
    MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDFULLNAME" + Chr(13) + "FLDCRDDEAR" + Chr(13) + "FLDCRDCONTACT"
    Chr(13) + "FLDCRDCONTACT"
    DataBuff = "'Bart De Hantsetters','De Hantsetters','Hantsetters'"
    DataBuff = "'Bart De Hantsetters','De Hantsetters','Hantsetters'"
 
    Call CmtInsUpdRec(C_AppName, _
    Call CmtInsUpdRec(C_AccountsTable, _
                      C_AccountsTable, _
                  C_AccountsTable, _
                      DataBuff, _
                  DataBuff, _
                      MapBuff, _
                  MapBuff, _
                      C_Flag, _
                  C_Flag, _
                      0, _
                  0, _
                      C_RecIDBuffSize, _
                  C_RecIDBuffSize, _
                      C_ErrCodeBuffSize, _
                  C_ErrCodeBuffSize, _
                      C_ErrMsgBuffSize, _
                  C_ErrMsgBuffSize, _
                      RecIdBuff, _
                  RecIdBuff, _
                      ErrCodesLogBuff, _
                  ErrCodesLogBuff, _
                      ErrMsgLogBuff, _
                  ErrMsgLogBuff, _
                      nStatus)
                  nStatus)
                 
    If (ErrMsgBuff <> "") Then MsgBox ("Error Message: " + ErrMsgBuff)
    If (ErrMsgBuff <> "") Then MsgBox ("Error Message: " + ErrMsgBuff)
   
    If nStatus <> C_Ok Then
    If nStatus = C_Ok Then
      MsgBox ("Insert new Account. Error code: " & nStatus)
    Else
  Rem      ******************** Updating the Account record we've just created *******************
  Rem      ******************** Updating the Account record we've just created *******************
   
      MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDDEAR" + Chr(13) + "FLDCRDRECID"
      MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDDEAR" + Chr(13) + "FLDCRDRECID"
      DataBuff = "'Doctor','" + RecIdBuff + "'"
      DataBuff = "'Doctor','" + RecIdBuff + "'"
      ErrCodesBuff = ""
      ErrCodesBuff = ""
      ErrMsgBuff = ""
      ErrMsgBuff = ""
     
     
      Call CmtInsUpdRec(C_AppName, _
      Call CmtInsUpdRec(C_AccountsTable, _
                        C_AccountsTable, _
                  C_AccountsTable, _
                        DataBuff, _
                  DataBuff, _
                        MapBuff, _
                  MapBuff, _
                        C_Flag, _
                  C_Flag, _
                        0, _
                  0, _
                        C_RecIDBuffSize, _
                  C_RecIDBuffSize, _
                        C_ErrCodeBuffSize, _
                  C_ErrCodeBuffSize, _
                        C_ErrMsgBuffSize, _
                  C_ErrMsgBuffSize, _
                        RecIdBuff, _
                  RecIdBuff, _
                        ErrCodesLogBuff, _
                  ErrCodesLogBuff, _
                        ErrMsgLogBuff, _
                  ErrMsgLogBuff, _
                        nStatus)
                  nStatus)
      If (ErrMsgBuff <> "") Then MsgBox ("Error Message: " + ErrMsgBuff)
      If nStatus <> C_Ok Then MsgBox ("Update Account. Error code: " & nStatus)
   
  Else
      If (ErrMsgBuff <> "") Then MsgBox ("Error Message: " + ErrMsgBuff)
    MsgBox ("Insert new Account. Error code: " + ErrCodesLogBuff)
    End If
   
  End If
  End If
  Else
    MsgBox ("Commit Init failed. Error code: " + ErrCodesLogBuff)
  End If
   
 
  End Sub
  End Sub


Line 330: Line 471:
   char* C_AppName = "Demo";
   char* C_AppName = "Demo";
    
    
   //* Establishing connection with CommitCRM, Should be called only once for the entire session **
   //* Establishing connection with RangerMSP, Should be called only once for the entire session **
    
    
   CmtInitDbEngDll(C_AppName, // Your application name. This will be used for all functions of the
   CmtInitDbEngDll(C_AppName, // Your application name. This will be used for all functions of the
                             // package.  
                             // package.  
   // Specify a meaningful value.
   // Specify a meaningful value.
         "C:\\Demo\\DB\\", //Path to the database folder where CommitCRM the server is
         "C:\\Demo\\DB\\", //Path to the database folder where RangerMSP the server is
                           // installed <server>\Commit\Db
                           // installed <server>\RangerMSP\Db
   &Status);          //Returned connection status
   &Status);          //Returned connection status
    
    
Line 407: Line 548:
   };
   };
    
    
     //****Terminate connection with CommitCRM*******************
     //****Terminate connection with RangerMSP*******************
     CmtTerminateDbEngDll();
     CmtTerminateDbEngDll();
   }
   }
   else
   else
   {
   {
     printf("Commit Init failed. Error code: %d\n", Status);
     printf("RangerMSP Init failed. Error code: %d\n", Status);
   };
   };
    
    
Line 451: Line 592:
   s: string;
   s: string;
    
    
  //** Establishing connection with CommitCRM, Should be called only once for the entire session *
  //** Establishing connection with RangerMSP, Should be called only once for the entire session *
  Procedure CmtInitDbEngDll (
  Procedure CmtInitDbEngDll (
               xSoftWareName  : PChar; // Your application name. Once selected this  string  
               xSoftWareName  : PChar; // Your application name. Once selected this  string  
                                       // will be used for all
                                       // will be used for all
                                       // functions of the package. Specify a meaningful value.
                                       // functions of the package. Specify a meaningful value.
               xDbPath        : PChar; // Path to the DB folder under where Commit server is  
               xDbPath        : PChar; // Path to the DB folder under where RangerMSP server is  
                                       // installed <server>\Commit\Db
                                       // installed <server>\RangerMSP\Db
    
    
               var xvStatus    : integer          // Returned connection status
               var xvStatus    : integer          // Returned connection status
Line 482: Line 623:
               ); stdcall; external CmtDbEngDll;
               ); stdcall; external CmtDbEngDll;
    
    
  //**** Terminate connection with CommitCRM ****
  //**** Terminate connection with RangerMSP ****
  procedure CmtTerminateDbEngDll; stdcall; external CmtDbEngDll;
  procedure CmtTerminateDbEngDll; stdcall; external CmtDbEngDll;
      
      
Line 523: Line 664:
     GetMem(aStatusErrCode,C_DescSize);
     GetMem(aStatusErrCode,C_DescSize);
     CmtGetDescriptionByStatus(xCode,C_DescSize, aStatusErrCode);
     CmtGetDescriptionByStatus(xCode,C_DescSize, aStatusErrCode);
     writeln('Commit Init failed. Error code: '+Inttostr(xCode)+' Desc: '+string(aStatusErrCode));
     writeln('RangerMSP Init failed. Error code: '+Inttostr(xCode)+' Desc: '+string(aStatusErrCode));
   finally
   finally
     FreeMem(aStatusErrCode);
     FreeMem(aStatusErrCode);
Line 531: Line 672:
  begin
  begin
    
    
   //**** Establishing connection with CommitCRM, Should be called only once for the entire session  
   //**** Establishing connection with RangerMSP, Should be called only once for the entire session  
   CmtInitDbEngDll(C_AppName, // Your application name. Once selected this string will be used  
   CmtInitDbEngDll(C_AppName, // Your application name. Once selected this string will be used  
                             // for all functions of the package. Specify a meaningful value.
                             // for all functions of the package. Specify a meaningful value.
   'C:\DemoDelphi\db\',                    // Path to the DB folder under where Commit server is
   'C:\DemoDelphi\db\',                    // Path to the DB folder under where RangerMSP server is
                                           // installed <server>\Commit\Db
                                           // installed <server>\RangerMSP\Db
   Status                  // Returned connection status
   Status                  // Returned connection status
     );
     );
Line 620: Line 761:
     end;
     end;
    
    
   //**** Terminate connection with CommitCRM****
   //**** Terminate connection with RangerMSP****
      
      
     CmtTerminateDbEngDll();
     CmtTerminateDbEngDll();
Line 632: Line 773:
   readln;
   readln;
  end.
  end.
====Python Sample 1====
For all field description see the [[API Reference Manual]].
''Contributed by: Joe Kogut''
Note: The example was tested on Python 3.5, but will work with Python 2.7 with minor modifications.
<pre>
import os
from ctypes import *
CRMEntity = {
    "Account"      : 10,
    "Accounts"      : 10,
    "Opportunitity" : 20,
    "Opportunities" : 20,
    "Document"      : 30,
    "Documents"    : 30,
    "Charge"        : 40,
    "Charges"      : 40,
    "Event"        : 50,
    "Events"        : 50,
    "HistoryNote"  : 60,
    "HistoryNotes"  : 60,
    "Ticket"        : 70,
    "Tickets"      : 70,
    "Item"          : 80,
    "Items"        : 80,
    "Asset"        : 90,
    "Assets"        : 90,
    "KBArticle"    : 100,
    "KBArticles"    : 100
    }
    class CRMRecord:
        def __init__(self, tableID, dataBuff, mapBuff, recID = ""):
                self.tableID            = tableID
                self.dataBuff          = create_string_buffer(bytes(dataBuff, "ascii"))
                self.mapBuff            = create_string_buffer(bytes(mapBuff, "ascii"))
                self.recIDBuffSize      = 20
                self.errCodesBuffSize  = 64
                self.errMsgBuffSize    = 1024
                self.recIDBuff          = create_string_buffer(bytes(recID, "ascii"), self.recIDBuffSize)
                self.errCodesBuff      = create_string_buffer(self.errCodesBuffSize)
                self.errMsgBuff        = create_string_buffer(self.errMsgBuffSize)
        def getRecID(self):
                return str(self.recIDBuff.raw, encoding='ascii')
               
class CRMDB:       
        def __init__(self, appName = 'CRMAgent', CRMPath = r'C:\RangerMSP'):
                self.CRMPath = CRMPath
                self.serverPath = CRMPath + r'\Server'
                self.DBPath = CRMPath + r'\Db'
                self.DBPath_bytes = create_string_buffer(bytes(self.DBPath, 'ascii'))
                self.appName = appName
                os.environ['PATH'] = self.serverPath + ';' + os.environ['PATH']
                self.CmDBEngDll = windll.LoadLibrary(self.serverPath + r'\cmtdbeng.dll')
               
                self.status = c_int()
        def InitDbEngDll(self):
                self.CmDBEngDll.CmtInitDbEngDll(self.appName, self.DBPath_bytes, byref(self.status))
                                         
        def InsUpdRec(self, record):           
                flag = 1
                tbd = 0
                self.CmDBEngDll.CmtInsUpdRec(create_string_buffer(bytes(self.appName, "ascii")),
                                            record.tableID,
                                            record.dataBuff,
                                            record.mapBuff,
                                            flag, tbd,
                                            record.recIDBuffSize,
                                            record.errCodesBuffSize,
                                            record.errMsgBuffSize,
                                            record.recIDBuff,
                                            record.errCodesBuff,
                                            record.errMsgBuff,
                                            byref(self.status))
               
        def TerminateDbEngDll(self):
                self.CmDBEngDll.CmtTerminateDbEngDll()
               
if __name__ == '__main__':
        # db.status should be 1 if library initialized properly
        db = CRMDB()
        db.InitDbEngDll()
        # Add an account to the database
        dataStr = "'Bart De Hantsetters','Hantsetters'"
        mapStr = "'\n,\nFLDCRDFULLNAME\nFLDCRDCONTACT"
       
        rec = CRMRecord(tableID = CRMEntity["Account"],
                          dataBuff = dataStr,
                          mapBuff = mapStr)
        # db.status should be 1 if operation was successful
        db.InsUpdRec(rec)
        print("Insert status: ", db.status)
        print("RecID: ", rec.getRecID())
        # Update the existing record
        dataStr = "'De Hantsetters','" + rec.getRecID() + "'"
        mapStr = "'\n,\nFLDCRDLASTNAME\nFLDCRDRECID"
        rec = CRMRecord(tableID = CRMEntity["Account"],
                          dataBuff = dataStr,
                          mapBuff = mapStr)
       
        db.InsUpdRec(rec)
        print("Update status: ", db.status)
       
        db.TerminateDbEngDll()
</pre>
====Python Sample 2====
For all field description see the [[API Reference Manual]].
''Contributed by: Ilja Christensen''
<pre>
import clr
from System import String, Char, Int32
CRMLib = clr.AddReference(R'\\RangerMSP\ThirdParty\UserDev\CRMLib.dll')
import CRM
MSP = CRM.Application
MSPConfig = CRM.Config()
MSPConfig.AppName = "CRMAgent"
MSPConfig.DllFolder = R"\\RangerMSP\ThirdParty\UserDev"
MSPConfig.DbFolder = R"\\RangerMSP\Db"
MSP.Initialize(MSPConfig)
print(f"Database initialized: {MSP.instance().initialized_}")
# Search account by name, the list has to be initialized before using it.
accountlist=[]
accountSearch = CRM.ObjectQuery[CRM.Account]()
accountSearch.AddCriteria(CRM.Account.Fields.FileAs, CRM.OperatorEnum.opEqual, 'ACME Cool Company')
accountlist=accountSearch.FetchObjects()
# Display results
print (f"Number of accounts: {len(accountlist)}")
for x in range(len(accountlist)):
    print (f"Found REC_ID: {accountlist[x].AccountREC_ID}")
# If we find exactly one record then we update it (otherwise a new record is created)
if (len(accountlist) == 1):
    account = CRM.Account(accountlist[0].AccountREC_ID)
else:
    account = CRM.Account()
account.FileAs = "ACME Cool Company"
account.Dear = "Mr."
account.Contact = "Johnny Doe"
account.Save()
RecID = account.AccountREC_ID
print (f"Updated: {RecID}")
# Close Database connection
MSP.Terminate()
print(f"Database initialized: {MSP.instance().initialized_}")
</pre>


===XML samples===
===XML samples===


Following are samples for adding a new Ticket and a new Charge to the Commit database using XML formatted messages.
Following are samples for adding a new Ticket and a new Charge to the RangerMSP database using XML formatted messages.


Make sure to go over the [[Email Connector]] setup guide, and perform the XML API setup steps prior to testing the XML API.
Make sure to go over the [[Email Connector]] setup guide, and perform the XML API setup steps prior to testing the XML API.


Also please read [[Commit API Reference Manual|Using Commit API#Using Commit API]] before going through the samples, as it provides an overview of the Commit API work-flow and how it should be used.
Also please read [[API_Developers_Guide#Using_API|RangerMSP API Reference Manual]] before going through the samples, as it provides an overview of the RangerMSP API work-flow and how it should be used.


Notes on API by Email Activation:
Notes on API by Email Activation:
Line 645: Line 957:
*Error Handling - Should the system fail to perform the XML transaction, an error message will be sent to the email address specified in the XML.
*Error Handling - Should the system fail to perform the XML transaction, an error message will be sent to the email address specified in the XML.


*Using a Password - If you wish to use a verification password for the XML transactions, define the password using the ServerConfig.exe utility. To do so, go to the XML tab, enable the API by Email option and set a password (as specified in the XML - see [[Commit API Reference Manual#General XML Tokens|General XML Tokens]]). Make sure to set the same Password in ServerConfig and in the XML email itself.
*Using a Password - If you wish to use a verification password for the XML transactions, define the password using the ServerConfig.exe utility. To do so, go to the XML tab, enable the API by Email option and set a password (as specified in the XML - see [[API_Code_Samples#General_XML_Tokens|General XML Tokens]]). Make sure to set the same Password in ServerConfig and in the XML email itself.


You can read more about the ServerConfig and how to setup the API by Email configuration in the [[Email Connector|Commit Email Connector]] Setup guide.
You can read more about the ServerConfig and how to setup the API by Email configuration in the [[Email Connector|RangerMSP Email Connector]] Setup guide.




Line 657: Line 969:


  <?xml version="1.0" ?>
  <?xml version="1.0" ?>
  <?commitcrmxml version = "1.0" ?>
  <?crmxml version = "1.0" ?>
  <CommitCRMTransaction>
  <crmTransaction>
   <ExternalApplicationName>N-Able</ExternalApplicationName>
   <ExternalApplicationName>N-Able</ExternalApplicationName>
   <SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail>
   <SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail>
Line 668: Line 980:
      ... the transaction goes here ...
      ... the transaction goes here ...
   </RecordData>
   </RecordData>
  </CommitCRMTransaction>
  </crmTransaction>


{| class="wikitable"
{| class="wikitable"
Line 678: Line 990:
| The XML version - Always 1.0
| The XML version - Always 1.0
|-
|-
| <?commitcrmxml version ="1.0" ?>
| <?crmxml version ="1.0" ?>
| The Commit API XML version - Always 1.0
| The RangerMSP API XML version - Always 1.0
|-
|-
| <CommitCRMTransaction>
| <crmTransaction>
| Start and end transactions with this token (may have more than one in a single email)
| Start and end transactions with this token (may have more than one in a single email)
|-
|-
Line 691: Line 1,003:
|-
|-
| <Password>
| <Password>
| Optional Password - Only emails with a password that matches the password set in the Email Connector Settings will be processed (to prevent SPAM email from being processed and added to your CommitCRM database).
| Optional Password - Only emails with a password that matches the password set in the Email Connector Settings will be processed (to prevent SPAM email from being processed and added to your RangerMSP database).
|-
|-
| <DataKind>
| <DataKind>
Line 705: Line 1,017:
OPPORTUNITY - for Sales Opportunities<br>
OPPORTUNITY - for Sales Opportunities<br>
DOCUMENT - for Documents<br>
DOCUMENT - for Documents<br>
KBARTICLE - for Knowledge Base articles<br>
ARTICLE - for Knowledge Base articles<br>
|}
|}


Line 713: Line 1,025:


  <?xml version="1.0" ?>
  <?xml version="1.0" ?>
  <?commitcrmxml version = "1.0" ?>
  <?crmxml version = "1.0" ?>
  <CommitCRMTransaction>
  <crmTransaction>
   <ExternalApplicationName>N-Able</ExternalApplicationName>
   <ExternalApplicationName>N-Able</ExternalApplicationName>
   <SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail>
   <SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail>
Line 732: Line 1,044:
  <FLDTKTFORDISPATCH>Y</FLDTKTFORDISPATCH>
  <FLDTKTFORDISPATCH>Y</FLDTKTFORDISPATCH>
   </RecordData>
   </RecordData>
  </CommitCRMTransaction>
  </crmTransaction>


====Adding new Charges====
====Adding new Charges====


  <?xml version="1.0" ?>
  <?xml version="1.0" ?>
  <?commitcrmxml version = "1.0" ?>
  <?crmxml version = "1.0" ?>
  <CommitCRMTransaction>
  <crmTransaction>
   <ExternalApplicationName>Alert</ExternalApplicationName>
   <ExternalApplicationName>Alert</ExternalApplicationName>
   <SendResponseToEmail>your email address for responses</SendResponseToEmail>
   <SendResponseToEmail>your email address for responses</SendResponseToEmail>
Line 759: Line 1,071:
         <FLDSLPUSER1>  Field 1...  </FLDSLPUSER1>
         <FLDSLPUSER1>  Field 1...  </FLDSLPUSER1>
   </RecordData>
   </RecordData>
  </CommitCRMTransaction>
  </crmTransaction>




Line 770: Line 1,082:


  <?xml version="1.0" ?>
  <?xml version="1.0" ?>
  <?commitcrmxml version="1.0" ?>
  <?crmxml version="1.0" ?>
  <CommitCRMResponse>
  <crmResponse>
  <Status>SUCCESS</Status>
  <Status>SUCCESS</Status>
  <AffectedRecId>TKTN1NIQEYYQ8PBJMDAX</AffectedRecId>
  <AffectedRecId>TKTN1NIQEYYQ8PBJMDAX</AffectedRecId>
  <ReturnTransactionID>data from external application (as-is)</ReturnTransactionID>
  <ReturnTransactionID>data from external application (as-is)</ReturnTransactionID>
  </CommitCRMResponse>
  </crmResponse>


<u>Response in case of error:</u>
<u>Response in case of error:</u>


  <?xml version="1.0" ?>
  <?xml version="1.0" ?>
  <?commitcrmxml version="1.0" ?>
  <?crmxml version="1.0" ?>
  <CommitCRMResponse>
  <crmResponse>
  <Status>FAILURE</Status>
  <Status>FAILURE</Status>
  <AffectedRecId></AffectedRecId>
  <AffectedRecId></AffectedRecId>
Line 790: Line 1,102:
         TKTN1NIQEYYQ8PBJMDAX
         TKTN1NIQEYYQ8PBJMDAX
  </ResultMessage>
  </ResultMessage>
  </CommitCRMResponse>
  </crmResponse>




Line 801: Line 1,113:
| The XML version - Always 1.0
| The XML version - Always 1.0
|-
|-
| <?commitcrmxml version ="1.0" ?>
| <?crmxml version ="1.0" ?>
| The Commit API XML version - Always 1.0
| The RangerMSP API XML version - Always 1.0
|-
|-
| <CommitCRMResponse>
| <crmResponse>
| The response starts and ends with this token
| The response starts and ends with this token
|-
|-
Line 817: Line 1,129:
|-
|-
|<ResultCodes><br><ResultMessage>
|<ResultCodes><br><ResultMessage>
|In case of a failure, this will contain the error code and description. You can find more information about error codes [[Commit API Reference Manual#Error Codes Description|here]].
|In case of a failure, this will contain the error code and description. You can find more information about error codes [[API Reference Manual#Error Codes Description|here]].
|}
|}


== See Also ==  
== See Also ==  
*[[Commit API Developers Guide]]
*[[API Developers Guide|API Developers Guide]]
*[[API Reference Manual]]
*[[API Reference Manual]]
[[Category:User Manuals]]
[[Category:User Manuals]]
[[Category:Integration]]
[[Category:Integration]]

Latest revision as of 11:36, 2 November 2020

User Manuals > API Developers Guide > API Code Samples

Introduction

Following are samples for using the low level RangerMSP API. The samples are basic and provide an easy starting point.

API functions

For detailed listing of the API functions and their parameters see API Functions Reference Manual.

Code samples

Data Retrieval API Samples

VB Sample - Data Retrieval

Private Declare Sub CmtInitDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xSoftWareName As String, _
 ByVal xDbPath As String, _
 ByRef xvStatus As Integer)

Private Declare Sub CmtTerminateDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ()

Private Declare Sub CmtGetDescriptionByCode Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xCode As Long, _
 ByVal xDescLen As Long, _
 ByVal xvDesc As String)

Private Declare Sub CmtGetDescriptionByStatus Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xCode As Long, _
 ByVal xDescLen As Long, _
 ByVal xvDesc As String)
 
Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
 
Private Declare Sub CmtGetFieldAttributesByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xXMLRequestBuff As String, _
 ByVal xXMLRequestBuffLen As Integer, _
 ByVal xXMLResponseDataBuff As String, _
 ByVal xXMLResponseDataBuffLen As Integer, _
 ByRef xvStatus As Integer)
 
Private Declare Sub CmtGetRecordDataByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xXMLRequestBuff As String, _
 ByVal xXMLRequestBuffLen As Integer, _
 ByVal xXMLResponseDataBuff As String, _
 ByVal xXMLResponseDataBuffLen As Integer, _
 ByRef xvStatus As Integer)

Private Declare Sub CmtGetQueryRecIds Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xXMLRequestBuff As String, _
 ByVal xXMLRequestBuffLen As Integer, _
 ByVal xXMLResponseDataBuff As String, _
 ByVal xXMLResponseDataBuffLen As Integer, _
 ByRef xvStatus As Integer)

 
 Private Const C_Ok  As Integer = 1
 Private Const C_AppName As String = "Demo"
 Private Const C_ErrorDescSize As Integer = 1024
 Private Const C_REC_ID_LEN As Integer = 20
 Private Const C_TktDataBuffSize  As Integer = 1024
 Private Const C_ChargeDataBuffSize  As Integer = 16384

rem *** XML containing a query for retrieving Charges of a specific Ticket
Private Function GetChargesRecIdOfTkRequstXml(xcTktRecId)
 GetChargesRecIdOfTkRequstXml     = 
	"<?xml version=""1.0"" ?>"                                               & _
	"<?crmxmlqueryrequest version=""1.0"" ?>"                          & _
       "<CRMQueryDataRequest>"                                            & _
       "<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _
       "<Datakind> CHARGE </Datakind>"                                        & _
       "<MaxRecordCount> 100 </MaxRecordCount>"                               & _
       "<Query>"                                                              & _
       "<Where>"                                                            & _
       "<Link> ( </Link>"                                                 & _
       "<FLDSLPTICKETID op=""="">" & xcTktRecId & "</FLDSLPTICKETID>"      & _
       "<Link> )  </Link>"                                                & _
       "</Where>"                                                           & _
       "<Order>"                                                            & _
       "<FLDSLPSLIPDATE dir=""asc""> </FLDSLPSLIPDATE>"                   & _
       "</Order>"                                                           & _
       "</Query>"                                                             & _
       "</CRMQueryDataRequest>"
End Function

rem *** String containing the Charge fields to be retrieved
Private Function GetChargeFlds()
 GetChargeFlds = "FLDSLPCARDID_FLDCRDFULLNAME"   & "," & _
                 "FLDSLPCONTACTID_FLDCRDCONTACT" & "," & _
                 "FLDSLPTICKETID_FLDTKTTICKETNO" & "," & _
                 "FLDSLPBCRECID_FLDBCTCODE"      & "," & _
                 "FLDSLPBCRECID_FLDBCTNAME"      & "," & _
                 "FLDSLPITEMID_FLDITMITEMNO"     & "," & _
                 "FLDSLPITEMID_FLDITMNAME"       & "," & _
                 "FLDSLPSLIPDATE"                & "," & _
                 "FLDSLPSTARTTIME"               & "," & _
                 "FLDSLPENDTIME"                 & "," & _
                 "FLDSLPQUANTITY"                & "," & _
                 "FLDSLPPRICE"                   & "," & _
                 "FLDSLPBILLTOTAL"               & "," & _
                 "FLDSLPHOURSAMOUNT"             & "," & _
                 "FLDSLPITEMUNITISHOUR"          & "," & _
                 "FLDSLPITEMTYPEGROUP"           & "," & _
                 "FLDSLPRECID"                   & "," & _
                 "FLDSLPDESC"
End Function

rem *** XML for retrieving a specific Charge
Private Function GetChargeRecDataReqXml(xcRecId)
  GetChargeRecDataReqXml = 
	"<?xml version=""1.0"" ?>" & _
       "<?crmxmlgetrecdatarequest version = ""1.0"" ?>" & _
       "<CRMGetRecDataRequest>" & _
       "<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _
       "<GetRecordByRecId>" & xcRecId & "</GetRecordByRecId>" & _
       "<SelectFieldsList>" & GetChargeFlds() & " </SelectFieldsList>" & _
       "</CRMGetRecDataRequest>"
End Function


rem *************************************************************************************************
rem *** This code shows how to retrieve charges of a specific Ticket.
rem *** It performs the following steps:
rem *** 1. Initialized a connection with the database
rem *** 2. Calls CmtGetQueryRecIds to retrieve the Charges of a specific ticket according to the query
rem ***    defined in aRequestXml (which is returned from GetChargesRecIdOfTkRequstXml)  
rem *** 3. Calls CmtGetRecordDataByRecId to retrieve the Charge details of all charges returned.
rem *************************************************************************************************

Public Sub DbQry()

 Dim nStatus As Integer
 Dim aTktXMLResponseDataBuff As String * C_TktDataBuffSize
 Dim aChargeXMLResponseDataBuff As String * C_ChargeDataBuffSize
 Dim aErrorDescSize As String * C_ErrorDescSize
 Dim aChargesRecIdStr As String
 Dim aCurChargeRecIdStr As String

Rem  **** Establishing connection with RangerMSP, Should be called only once for the entire session ******

 Call CmtInitDbQryDll(C_AppName, "c:\DemoVBA\DB\", nStatus)

 If nStatus <> C_Ok Then
  Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
  MsgBox ("RangerMSP Init failed. Status Error code: " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
 Else
rem *** ADD YOUR CODE HERE (replace the line below this section):
rem *** Change the ticket ID below to fit a real ticket in your database.
  aRequestXml = GetChargesRecIdOfTkRequstXml("TKTVHIUTGO5KGUUCB4SL")

  Call CmtGetQueryRecIds(aRequestXml, Len(aRequestXml), aTktXMLResponseDataBuff, C_TktDataBuffSize, nStatus)
  If nStatus <> C_Ok Then
    MsgBox (aTktXMLResponseDataBuff)

  Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
  MsgBox ("Failed. Status Error : " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )

rem *** ADD YOUR CODE HERE:
rem *** parse the XML Buffer -> aTktXMLResponseDataBuff. Extract the error code that was returned from the api***

rem *** Call CmtGetDescriptionByCode(ErrorCodeFromXml, C_ErrorDescSize, aErrorDescSize)
rem *** MsgBox ("Failed. XML Error : " & ErrorCodeFromXml & CHR(13) & CHR(10) & aErrorDescSize )

  Else
    MsgBox (aTktXMLResponseDataBuff)

rem **** ADD YOUR CODE HERE (replace the line below this section): 
rem **** parse the XML Buffer(extract the charge(s) recid of the ticket) -> aTktXMLResponseDataBuff ****
rem **** The aChargesRecIdStr vairable contain the Charges recid that were extracted from the XML buffer 

    aChargesRecIdStr = "SLPXBV3YB7F9F2DPGDC5SLPLORCIOPWYP5VW4NWASLPFYKGUNYT8E3NE23XU"

    Do while (Len(aChargesRecIdStr)> 0 )

      aCurChargeRecIdStr = Left(aChargesRecIdStr, C_REC_ID_LEN)
      aChargesRecIdStr =   Right(aChargesRecIdStr, Len(aChargesRecIdStr) - C_REC_ID_LEN)

      aRequestXml = GetChargeRecDataReqXml(aCurChargeRecIdStr)
      Call CmtGetRecordDataByRecId(aRequestXml, Len(aRequestXml), aChargeXMLResponseDataBuff, C_ChargeDataBuffSize, nStatus)

      If nStatus <> C_Ok Then
        MsgBox (aChargeXMLResponseDataBuff )

        Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
        MsgBox ("Failed. Status Error : " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )

rem *** ADD YOUR CODE HERE: 
rem *** parse the XML Buffer -> aChargeXMLResponseDataBuff. Extract the error code that was return from the api***

rem *** Call CmtGetDescriptionByCode(nStatus,C_ErrorDescSize, aErrorDescSize)
rem *** MsgBox ("Failed. XML Error : " & ErrorCodeFromXml & CHR(13) & CHR(10) & aErrorDescSize )

      Else
        MsgBox (aChargeXMLResponseDataBuff)
rem **** ADD YOUR CODE HERE: parse the XML Buffer(extract the charge info) -> aChargeXMLResponseDataBuff ****
      End If
    loop
  End If
 End If

 Call CmtTerminateDbQryDll

End Sub

VB Sample - Field Attributes Retrieval

Private Declare Sub CmtInitDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xSoftWareName As String, _
 ByVal xDbPath As String, _
 ByRef xvStatus As Integer)

Private Declare Sub CmtTerminateDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ()

Private Declare Sub CmtGetDescriptionByCode Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xCode    as long, _
 ByVal xDescLen as long, _
 ByVal xvDesc   As String)

Private Declare Sub CmtGetDescriptionByStatus Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xCode    as long, _
 ByVal xDescLen as long, _
 ByVal xvDesc   As String)

Private Declare Sub InitCommonControls Lib "comctl32.dll" ()

Private Declare Sub CmtGetFieldAttributesByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xXMLRequestBuff As String, _
 ByVal xXMLRequestBuffLen As Integer, _
 ByVal xXMLResponseDataBuff As String, _
 ByVal xXMLResponseDataBuffLen As Integer, _
 ByRef xvStatus As Integer)

Private Declare Sub CmtGetRecordDataByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xXMLRequestBuff As String, _
 ByVal xXMLRequestBuffLen As Integer, _
 ByVal xXMLResponseDataBuff As String, _
 ByVal xXMLResponseDataBuffLen As Integer, _
 ByRef xvStatus As Integer)

Private Declare Sub CmtGetQueryRecIds Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
 ByVal xXMLRequestBuff As String, _
 ByVal xXMLRequestBuffLen As Integer, _
 ByVal xXMLResponseDataBuff As String, _
 ByVal xXMLResponseDataBuffLen As Integer, _
 ByRef xvStatus As Integer)

 Private Const C_Ok  As Integer = 1
 Private Const C_AppName As String = "Demo"
 Private Const C_ErrorDescSize As Integer = 1024
 Private Const C_DataBuffSize  As Integer = 1024 


rem *** XML containing the request for CmtGetFieldAttributesByRecId with the requested Field ID
Private Function GetFldAttrRequstXml(xcDicId)
  GetFldAttrRequstXml = "<?xml version=""1.0"" ?>"                                               & _
                        "<?crmxmlgetfieldattributesrequest version = ""1.0"" ?>"           & _
                        "<CRMGetRecDataRequest>"                                           & _
                          "<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _
                          "<GetRecordByRecId>" & xcDicId & "</GetRecordByRecId>"                 & _
                        "</CRMGetRecDataRequest>"
End Function 
 

rem *************************************************************************************************
rem *** This code shows how to retrieve field attributes (e.g Field Label, Field Name, etc.) 
rem *** from the RangerMSP database dictionary.
rem *** It performs the following steps:
rem *** 1. Initialized a connection with the database
rem *** 2. Calls CmtGetFieldAttributesByRecId to retrieve the details of a specific field according to the field ID defined 
rem ***    in aRequestXml   
rem *************************************************************************************************


Public Sub DbQry()

 Dim nStatus As Integer
 Dim aXMLResponseDataBuff As String * C_DataBuffSize
 Dim aErrorDescSize As String * C_ErrorDescSize
 Dim aRequestXml as String

 Call CmtInitDbQryDll(C_AppName, "c:\DemoVBA\DB\", nStatus)

 If nStatus <> C_Ok Then
   Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
   MsgBox ("RangerMSP Init failed. Status Error code: " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
 Else
   aRequestXml = GetFldAttrRequstXml("FLDCRDCITY")
   Call CmtGetFieldAttributesByRecId(aRequestXml, Len(aRequestXml), aXMLResponseDataBuff, C_DataBuffSize, nStatus)

   If nStatus <> C_Ok Then
     MsgBox (aXMLResponseDataBuff )

   Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
   MsgBox ("Failed. Status Error : " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )

rem *** ADD YOUR CODE HERE: parse the XML Buffer -> aXMLResponseDataBuff. Extract the error code that was return from the api***

rem *** Call CmtGetDescriptionByCode(ErrorCodeFromXml , C_ErrorDescSize, aErrorDescSize)
rem *** MsgBox ("Failed. XML Error : " & ErrorCodeFromXml & CHR(13) & CHR(10) & aErrorDescSize )

   Else
     MsgBox (aXMLResponseDataBuff)
rem *** ADD YOUR CODE HERE: parse the XML Buffer -> aXMLResponseDataBuff ***
   End If
  End If

  Call CmtTerminateDbQryDll

End Sub

Data Update API Samples

The following code samples demonstrate how to add and update a record in RangerMSP from VBA, C++ or Delphi programs.

Make sure to read RangerMSP API Developers Guide before going through the samples, as it provides an overview of the RangerMSP API work-flow and how it should be used.

To test samples, it is recommended that you download a trial version of RangerMSP from our web site and install it on a new computer that is not running RangerMSP. Then, modify the paths in the source code to point to folder <testcomputer>\RangerMSP\LastVer (and to the same files it already points to).

When developing your programs please make sure you work under the <testcomputer>\RangerMSP\ThirdParty\UserDev folder (or at least call the dlls in this location). Do not copy the dll’s to any other location.

These samples create a connection to RangerMSP's database, add a new Account record into the database, and update it. Each transaction should specify the database table to be updated by the transaction. See more details in the API Reference Manual.


VB Sample

Private Declare Sub CmtInitDbEngDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbEng.dll" (ByVal xSoftWareName As String, _
 ByVal xDbPath As String, ByRef xvStatus As Integer)
 
Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
 
Private Declare Sub CmtInsUpdRec Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbEng.dll" (ByVal xSoftWareName As String, _
 ByVal xDataKind As Integer, _
 ByVal xDataBuff As String, _
 ByVal xMapBuff As String, _
 ByVal xContWhenInvalidData As Integer, _
 ByVal xFlags As Integer, _
 ByVal xRecIDBuffLen As Integer, _
 ByVal xLogErrCodesBuffLen As Integer, _
 ByVal xLogErrMsgBuffLen As Integer, _
 ByVal xvRecIDBuff As String, _
 ByVal xvErrCodesLogBuff As String, _
 ByVal xvErrMsgLogBuff As String, _
 ByRef xvStatus As Integer)

 Private Const C_DataBuffSize  As Integer = 1024
 Private Const C_MapBufSize  As Integer = 1024
 Private Const C_ErrMsgBuffSize  As Integer = 1024
 Private Const C_ErrCodeBuffSize  As Integer = 64
 Private Const C_RecIDBuffSize  As Integer = 20
 Private Const C_Flag  As Integer = 1
 Private Const C_Ok  As Integer = 1
 Private Const C_AccountsTable  As Integer = 10
  
 Private Const C_AppName As String = "Demo"

Public Sub DBEng()

 Dim nStatus As Integer
 Dim l As Long
 Dim S As String
 Dim pStr As Long
 Dim MapBuff As String
 Dim DataBuff As String
 Dim RecIdBuff As String * C_RecIDBuffSize
 Dim ErrCodesLogBuff As String * C_ErrCodeBuffSize
 Dim ErrMsgLogBuff As String * C_ErrMsgBuffSize

 Call CmtInitDbEngDll(C_AppName, "c:\DemoVBA\DB\", nStatus)

 If nStatus <> C_Ok Then
   MsgBox ("RangerMSP Init failed. Error code: " & nStatus)
 Else
Rem  ******************** Establishing connection with RangerMSP, Should be called only once for the entire session ******
   MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDFULLNAME" + Chr(13) + "FLDCRDDEAR" + Chr(13) + "FLDCRDCONTACT"
   DataBuff = "'Bart De Hantsetters','De Hantsetters','Hantsetters'"

   Call CmtInsUpdRec(C_AppName, _
                     C_AccountsTable, _
                     DataBuff, _
                     MapBuff, _
                     C_Flag, _
                     0, _
                     C_RecIDBuffSize, _
                     C_ErrCodeBuffSize, _
                     C_ErrMsgBuffSize, _
                     RecIdBuff, _
                     ErrCodesLogBuff, _
                     ErrMsgLogBuff, _
                     nStatus)

   If (ErrMsgBuff <> "") Then MsgBox ("Error Message: " + ErrMsgBuff)

   If nStatus <> C_Ok Then
     MsgBox ("Insert new Account. Error code: " & nStatus)
   Else
Rem      ******************** Updating the Account record we've just created *******************

     MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDDEAR" + Chr(13) + "FLDCRDRECID"
     DataBuff = "'Doctor','" + RecIdBuff + "'"
     ErrCodesBuff = ""
     ErrMsgBuff = ""

     Call CmtInsUpdRec(C_AppName, _
                       C_AccountsTable, _
                       DataBuff, _
                       MapBuff, _
                       C_Flag, _
                       0, _
                       C_RecIDBuffSize, _
                       C_ErrCodeBuffSize, _
                       C_ErrMsgBuffSize, _
                       RecIdBuff, _
                       ErrCodesLogBuff, _
                       ErrMsgLogBuff, _
                       nStatus)

     If nStatus <> C_Ok Then MsgBox ("Update Account. Error code: " & nStatus)

     If (ErrMsgBuff <> "") Then MsgBox ("Error Message: " + ErrMsgBuff)
   End If
 End If
End Sub

C++ Sample

For all field description see the API Reference Manual.

// Demo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "CmtDBEng.h"
#include <string.h>
#include <stdlib.h>
int ErrCodesParsing (char* ErrCodeBuff)
{
// Demo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "CmtDBEng.h"
#include <string.h>
#include <stdlib.h>
int ErrCodesParsing (char* ErrCodeBuff)
{
 const int C_DescSize = 1024;
 char desc[C_DescSize];
 char Delimiter[] = "\n";
 int Code;
 char* pch;
 pch = strtok (ErrCodeBuff,Delimiter);
 while (pch != NULL)
 {
   Code = atoi(pch);
        CmtGetDescriptionByCode(Code, C_DescSize, desc);
   printf ("%s\n",desc);
   pch = strtok (NULL, Delimiter);
 }
 return 0;
}
int main(int argc, char* argv[])
{
 const int C_DataBuffSize = 1024;
 const int C_MapBufSize = 1024;
 const int C_ErrMsgBuffSize = 1024;
 const int C_ErrCodeBuffSize = 64;
 const int C_RecIDBuffSize = 64;
 const int C_Flag = 1;
 const int C_Ok = 1;
 const int C_AccountsTable = 10;
 const int C_ExampleCode = 54000;
 int Status;
 char DataBuff[C_DataBuffSize] = "";
 char MapBuff[C_MapBufSize] = "";
 char RecIdBuff[C_RecIDBuffSize];
 char ErrCodesBuff[C_ErrCodeBuffSize];
 char ErrMsgBuff[C_ErrMsgBuffSize];
 char* C_AppName = "Demo";
  
 //* Establishing connection with RangerMSP, Should be called only once for the entire session **
  
 CmtInitDbEngDll(C_AppName, // Your application name. This will be used for all functions of the
                            // package. 
 // Specify a meaningful value.
       "C:\\Demo\\DB\\", //Path to the database folder where RangerMSP the server is
                         // installed <server>\RangerMSP\Db
  &Status);           //Returned connection status
  
 if (Status == C_Ok) {
 
  //***Insert New Account into that Accounts table *******************
  strcpy (DataBuff,"'Bart De Hantsetters','De Hantsetters','Hantsetters'");
  strcat (MapBuff, "'\n,\nFLDCRDFULLNAME\nFLDCRDDEAR\nFLDCRDCONTACT");
  strcat (RecIdBuff, "");
  strcat (ErrCodesBuff, "");
  strcat (ErrMsgBuff, "");
 
  CmtInsUpdRec(C_AppName,     //String for your selection.
               C_AccountsTable,    //Desired Table Code
               DataBuff,  //This string contains the values which we want to add to the database
               MapBuff,  //List of database fields where we want to add data
               C_Flag,//Flag - stop(0) continue(1) the input process is data 
                         //value(s) is invalid
               0,                        //Not used
               C_RecIDBuffSize,    //Length of REC ID Buffer
               C_ErrCodeBuffSize, //Length of Error Code Buffer
               C_ErrMsgBuffSize,  //Length of Error Message Buffer
               RecIdBuff,            //Buffer for returned REC ID
               ErrCodesBuff,        //Buffer for returned Error Codes
               ErrMsgBuff,           //Bufer for returned Error Messages
               &Status               //Returned status
       );
 
  if (ErrMsgBuff == "")
  printf("Error Message: %s", ErrMsgBuff);
 
  ErrCodesParsing(ErrCodesBuff);
 
  if (Status == C_Ok) {
 
     //***** Updating the Account record we've just created *************
     strcpy (MapBuff, "'\n,\nFLDCRDDEAR\nFLDCRDRECID"); // Map file for the  update 
     // transaction - the Dear field and the record id
     strcpy (DataBuff,"'Doctor','");
     strcat (DataBuff, RecIdBuff);
     strcat (DataBuff, "'");
     strcat (ErrCodesBuff, "");
     strcat (ErrMsgBuff, "");
 
 
     CmtInsUpdRec(C_AppName,    // string for your selection.
                  C_AccountsTable,    // Desired Table Code
                  DataBuff,   // string contains the values, which we want to add into the Database
                  MapBuff,    // list of the Database Fields in which we want to add data
                  C_Flag,     // Flag - stop(0)/continue(1) the input process is some data
                              // value(s) is invalid
                  0,                         // Not used
                  C_RecIDBuffSize,     // length of RecID Buffer
                  C_ErrCodeBuffSize,  // length of Error Code Buffer
                  C_ErrMsgBuffSize,   // length of Error Message Buffer
                  RecIdBuff,             // buffer for returned RecID
                  ErrCodesBuff,         // buffer for returned Error Codes
                  ErrMsgBuff,            // bufer for returned Error Messages
                  &Status                // returned status
         );
 
     if (ErrMsgBuff == "")
       printf("Error Message: %s", ErrMsgBuff);
 
     ErrCodesParsing(ErrCodesBuff);
   }
   else
   {
      printf("Insert new Account. Error code: %d\n", Status);
  	};
 
   //****Terminate connection with RangerMSP*******************
   CmtTerminateDbEngDll();
 }
 else
 {
   printf("RangerMSP Init failed. Error code: %d\n", Status);
 };
 
 	return 0;
}

Delphi Sample

For all field description see the API Reference Manual.

program Demo;
  
{$APPTYPE CONSOLE}
  
uses
 SysUtils, Classes;
const
 C_DataBuffSize = 1024;
 C_MapBufSize = 1024;
 C_ErrMsgBuffSize = 1024;
 C_DescSize = 1024;
 C_ErrCodeBuffSize = 64;
 C_RecIDBuffSize = 64;
  
 C_Flag = 1;
 C_Ok = 1;
 C_AccountsTable = 10;
 C_AppName = 'Demo';
  
 CmtDbEngDll = 'CmtDbEng.DLL';
  
var
 Status: integer;
 DataBuff: array [0..C_DataBuffSize] of Char;
 MapBuff: array [0..C_MapBufSize] of Char;
 RecIdBuff: array [0..C_RecIDBuffSize] of Char;
 ErrCodesBuff: array [0..C_ErrCodeBuffSize] of Char;
 ErrMsgBuff: array [0..C_ErrMsgBuffSize] of Char;
 s: string;
  
//** Establishing connection with RangerMSP, Should be called only once for the entire session *
Procedure CmtInitDbEngDll (
             xSoftWareName   : PChar; // Your application name. Once selected this  string 
                                      // will be used for all
                                      // functions of the package. Specify a meaningful value.
             xDbPath         : PChar; // Path to the DB folder under where RangerMSP server is 
                                      // installed <server>\RangerMSP\Db
  
             var xvStatus     : integer           // Returned connection status
            ); stdcall; external CmtDbEngDll;
  
//**** Insert/Update record
Procedure CmtInsUpdRec(
             xSoftWareName   : pChar;            // See above
             xDataKind           : integer;      // Desired Table Code
             xDataBuff           : pChar;        // String containing the values, which we want
                                                 // to add into the Database
             xMapBuff            : pChar;        // List of the database fields into 
                                                 //which we want to add data
             xContWhenInvalidData : Integer;     //Flag - stop(0)/continue(1) the input process
                                                 // is some data value(s) is invalid
             xFlags                : Integer;              // Not used
             xRecIDBuffLen      : Integer;          // Length of REC ID Buffer
             xLogErrCodesBuffLen  : Integer;  // Length of Error Code Buffer
             xLogErrMsgBuffLen     : Integer;     // Length of Error Message Buffer
             xvRecIDBuff          : pChar;            // Buffer for returned REC ID
             xvErrCodesLogBuff : pChar;         // Buffer for returned Error Codes
             xvErrMsgLogBuff    : pChar;         // Buffer for returned Error Messages
              var xvStatus       : Integer          // Returned status
             ); stdcall; external CmtDbEngDll;
  
//**** Terminate connection with RangerMSP ****
procedure CmtTerminateDbEngDll; stdcall; external CmtDbEngDll;
   
procedure CmtGetDescriptionByCode(
                                 xCode     : Integer;
                                 xDescLen  : Integer;
                                 xvDesc    : pChar); stdcall; external CmtDbEngDll;
  
procedure CmtGetDescriptionByStatus(
                                   xCode     : Integer;
                                   xDescLen  : Integer;
                                   xvDesc    : pChar); stdcall; external CmtDbEngDll;
  
procedure ErrCodesParsing (ErrCodeBuff: string);
var
 lList: TStringList;
 i: integer;
 aDescErrCode : Pchar;
begin
 try
   lList := TStringList.Create;
   lList.Text := ErrCodeBuff;
   GetMem(aDescErrCode,C_DescSize);
   for i := 0 to lList.Count - 1 do
   begin
     CmtGetDescriptionByCode(StrToInt(lList[i]), C_DescSize, aDescErrCode);
     writeln('Error Code: '+lList[i]+' Desc: '+string(aDescErrCode));
   end;
 finally
   FreeMem(aDescErrCode);
   lList.Destroy;
 end;
end;
 
procedure DisplayErrStatusCode(xCode : Integer);
var
 aStatusErrCode : Pchar;
begin
 try
   GetMem(aStatusErrCode,C_DescSize);
   CmtGetDescriptionByStatus(xCode,C_DescSize, aStatusErrCode);
   writeln('RangerMSP Init failed. Error code: '+Inttostr(xCode)+' Desc: '+string(aStatusErrCode));
 finally
   FreeMem(aStatusErrCode);
 end;
end;
  
begin
  
 //**** Establishing connection with RangerMSP, Should be called only once for the entire session 
 CmtInitDbEngDll(C_AppName, // Your application name. Once selected this string will be used 
                            // for all functions of the package. Specify a meaningful value.
  'C:\DemoDelphi\db\',                    // Path to the DB folder under where RangerMSP server is
                                          // installed <server>\RangerMSP\Db
  Status                   // Returned connection status
   );
   
 if Status = C_Ok then
 begin
  
   //**** Insert a new Account into the Accounts table ****
  
   s := '"Bart De Hantsetters","De Hantsetters","Hantsetters"';
   StrPCopy(DataBuff, s);
   s := '"'+#13','+#13+'FLDCRDFULLNAME'+#13+'FLDCRDDEAR'+#13+'FLDCRDCONTACT'+#0;
   StrPCopy(MapBuff, s);
  
    CmtInsUpdRec(C_AppName,         // Your application name
                 C_AccountsTable,   // Desired Table Code
                 DataBuff,          // String containing the values, which we want to add into
                                    // the Database
                 MapBuff,           // List of the Database Fields in which we want to add data
                 C_Flag,            // Flag - stop(0)/continue(1) the input process is some data
                                    // value(s) is invalid
                 0,                             // Not used
                 C_RecIDBuffSize,         // Llength of REC ID Buffer
                 C_ErrCodeBuffSize,      // Length of Error Code Buffer
                 C_ErrMsgBuffSize,       // Length of Error Message Buffer
                 RecIdBuff,                 // Buffer for returned REC ID
                 ErrCodesBuff,             // Buffer for returned Error Codes
                 ErrMsgBuff,                // Buffer for returned Error Messages
                 Status                      // Returned status
         );
  
  
  
   if (ErrMsgBuff[0] <> #0) then
     writeln('Error Message: '+ ErrMsgBuff);
  
   ErrCodesParsing(ErrCodesBuff);
  
   if Status = C_Ok then
   begin
 //**** Updating the Account record we've just created *****
  
     // Map file for the update transaction - the Dear field and the record id
     s := '"'+#13+','+#13+'FLDCRDDEAR'+#13'FLDCRDRECID';
     StrPCopy(MapBuff, s);
  
     s := '"Doctor","'+RecIdBuff+'"';
     StrPCopy(DataBuff, s);
  
     CmtInsUpdRec(C_AppName,           // Your application name
                  C_AccountsTable,     // Desired Table Code
                  DataBuff,            // String containing  the values, which we want
                                       // to add into the Database
                  MapBuff,             // List of the database fields into which we want to add
                                       //data
                  C_Flag,              // Flag - stop(0)/continue(1) the input process is some
                                       // data value(s) is invalid
                  0,                   // Not used
                  C_RecIDBuffSize,     // Length of REC ID Buffer
                  C_ErrCodeBuffSize,   // Length of Error Code Buffer
                  C_ErrMsgBuffSize,    // Length of Error Message Buffer
                  RecIdBuff,           // Buffer for returned RECID
                  ErrCodesBuff,        // Buffer for returned Error Codes
                  ErrMsgBuff,          // Buffer for returned Error Messages
                  Status               // Returned status
         );
   
     if ((ErrMsgBuff[0] <> #0)) then
       writeln('Error Message: '+ ErrMsgBuff);
  
     ErrCodesParsing(ErrCodesBuff);
  
     if Status = C_Ok then
       Writeln('Completed Successfully');
   end
   else
   begin
     try
       s := IntToStr(Status);
     except
       s := 'ill-defined';
     end;
     writeln('Insert new Account. Error code: '+ s);
   end;
  
 //**** Terminate connection with RangerMSP****
    
   CmtTerminateDbEngDll();
 end
 else
 begin
   DisplayErrStatusCode(Status);
 end;
 
 writeln(#13#10+'press Enter to quit');
 readln;
end.


Python Sample 1

For all field description see the API Reference Manual.

Contributed by: Joe Kogut

Note: The example was tested on Python 3.5, but will work with Python 2.7 with minor modifications.

 import os
 from ctypes import *


 CRMEntity = {
    "Account"       : 10,
    "Accounts"      : 10,
    "Opportunitity" : 20,
    "Opportunities" : 20,
    "Document"      : 30,
    "Documents"     : 30,
    "Charge"        : 40,
    "Charges"       : 40,
    "Event"         : 50,
    "Events"        : 50,
    "HistoryNote"   : 60,
    "HistoryNotes"  : 60,
    "Ticket"        : 70,
    "Tickets"       : 70,
    "Item"          : 80,
    "Items"         : 80,
    "Asset"         : 90,
    "Assets"        : 90,
    "KBArticle"     : 100,
    "KBArticles"    : 100
    }

    class CRMRecord:
        def __init__(self, tableID, dataBuff, mapBuff, recID = ""):
                self.tableID            = tableID
                self.dataBuff           = create_string_buffer(bytes(dataBuff, "ascii"))
                self.mapBuff            = create_string_buffer(bytes(mapBuff, "ascii"))

                self.recIDBuffSize      = 20
                self.errCodesBuffSize   = 64
                self.errMsgBuffSize     = 1024

                self.recIDBuff          = create_string_buffer(bytes(recID, "ascii"), self.recIDBuffSize)
                self.errCodesBuff       = create_string_buffer(self.errCodesBuffSize)
                self.errMsgBuff         = create_string_buffer(self.errMsgBuffSize)

        def getRecID(self):
                return str(self.recIDBuff.raw, encoding='ascii')
                
class CRMDB:        
        def __init__(self, appName = 'CRMAgent', CRMPath = r'C:\RangerMSP'):
                self.CRMPath = CRMPath
                self.serverPath = CRMPath + r'\Server'
                self.DBPath = CRMPath + r'\Db'
                self.DBPath_bytes = create_string_buffer(bytes(self.DBPath, 'ascii'))
                self.appName = appName

                os.environ['PATH'] = self.serverPath + ';' + os.environ['PATH']
                self.CmDBEngDll = windll.LoadLibrary(self.serverPath + r'\cmtdbeng.dll')
                
                self.status = c_int()

        def InitDbEngDll(self):
                self.CmDBEngDll.CmtInitDbEngDll(self.appName, self.DBPath_bytes, byref(self.status))
                                           
        def InsUpdRec(self, record):            
                flag = 1
                tbd = 0

                self.CmDBEngDll.CmtInsUpdRec(create_string_buffer(bytes(self.appName, "ascii")),
                                             record.tableID,
                                             record.dataBuff,
                                             record.mapBuff,
                                             flag, tbd,
                                             record.recIDBuffSize,
                                             record.errCodesBuffSize,
                                             record.errMsgBuffSize,
                                             record.recIDBuff,
                                             record.errCodesBuff,
                                             record.errMsgBuff,
                                             byref(self.status))
                
        def TerminateDbEngDll(self):
                self.CmDBEngDll.CmtTerminateDbEngDll()
                
if __name__ == '__main__':
        # db.status should be 1 if library initialized properly
        db = CRMDB()
        db.InitDbEngDll()

        # Add an account to the database
        dataStr = "'Bart De Hantsetters','Hantsetters'"
        mapStr = "'\n,\nFLDCRDFULLNAME\nFLDCRDCONTACT"
        
        rec = CRMRecord(tableID = CRMEntity["Account"],
                           dataBuff = dataStr,
                           mapBuff = mapStr)

        # db.status should be 1 if operation was successful
        db.InsUpdRec(rec)
        print("Insert status: ", db.status)
        print("RecID: ", rec.getRecID())

        # Update the existing record
        dataStr = "'De Hantsetters','" + rec.getRecID() + "'"
        mapStr = "'\n,\nFLDCRDLASTNAME\nFLDCRDRECID"

        rec = CRMRecord(tableID = CRMEntity["Account"],
                           dataBuff = dataStr,
                           mapBuff = mapStr)
        
        db.InsUpdRec(rec)
        print("Update status: ", db.status)
        
        db.TerminateDbEngDll()



Python Sample 2

For all field description see the API Reference Manual.

Contributed by: Ilja Christensen

import clr
from System import String, Char, Int32
CRMLib = clr.AddReference(R'\\RangerMSP\ThirdParty\UserDev\CRMLib.dll')
import CRM

MSP = CRM.Application
MSPConfig = CRM.Config()
MSPConfig.AppName = "CRMAgent"
MSPConfig.DllFolder = R"\\RangerMSP\ThirdParty\UserDev"
MSPConfig.DbFolder = R"\\RangerMSP\Db"
MSP.Initialize(MSPConfig)
print(f"Database initialized: {MSP.instance().initialized_}")

# Search account by name, the list has to be initialized before using it.
accountlist=[]
accountSearch = CRM.ObjectQuery[CRM.Account]()
accountSearch.AddCriteria(CRM.Account.Fields.FileAs, CRM.OperatorEnum.opEqual, 'ACME Cool Company')
accountlist=accountSearch.FetchObjects()
# Display results
print (f"Number of accounts: {len(accountlist)}")
for x in range(len(accountlist)):
    print (f"Found REC_ID: {accountlist[x].AccountREC_ID}")

# If we find exactly one record then we update it (otherwise a new record is created)
if (len(accountlist) == 1):
    account = CRM.Account(accountlist[0].AccountREC_ID)
else:
    account = CRM.Account()
account.FileAs = "ACME Cool Company"
account.Dear = "Mr."
account.Contact = "Johnny Doe"
account.Save()
RecID = account.AccountREC_ID
print (f"Updated: {RecID}")

# Close Database connection
MSP.Terminate()
print(f"Database initialized: {MSP.instance().initialized_}")

XML samples

Following are samples for adding a new Ticket and a new Charge to the RangerMSP database using XML formatted messages.

Make sure to go over the Email Connector setup guide, and perform the XML API setup steps prior to testing the XML API.

Also please read RangerMSP API Reference Manual before going through the samples, as it provides an overview of the RangerMSP API work-flow and how it should be used.

Notes on API by Email Activation:

  • Error Handling - Should the system fail to perform the XML transaction, an error message will be sent to the email address specified in the XML.
  • Using a Password - If you wish to use a verification password for the XML transactions, define the password using the ServerConfig.exe utility. To do so, go to the XML tab, enable the API by Email option and set a password (as specified in the XML - see General XML Tokens). Make sure to set the same Password in ServerConfig and in the XML email itself.

You can read more about the ServerConfig and how to setup the API by Email configuration in the RangerMSP Email Connector Setup guide.


General XML Tokens

The sample and table demonstrates general parameters which should be used for any XML transaction.

For all field description see the API Reference Manual.

<?xml version="1.0" ?>
<?crmxml version = "1.0" ?>
<crmTransaction>
  <ExternalApplicationName>N-Able</ExternalApplicationName>
  <SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail>
  <Password>the-predefined-api-password</Password>
  <ReturnTransactionID>data from external application (will be returned as-is in the response) 
</ReturnTransactionID>
  <DataKind>TICKET</DataKind>
  <RecordData>
	    ... the transaction goes here ...
  </RecordData>
</crmTransaction>
Token Comment
<?xml version="1.0" ?> The XML version - Always 1.0
<?crmxml version ="1.0" ?> The RangerMSP API XML version - Always 1.0
<crmTransaction> Start and end transactions with this token (may have more than one in a single email)
<ExternalApplicationName> The sender application name, can contain any text
<SendResponseToEmail> When set with an email address, then a response email will be sent after processing this transaction by the Email Connector
<Password> Optional Password - Only emails with a password that matches the password set in the Email Connector Settings will be processed (to prevent SPAM email from being processed and added to your RangerMSP database).
<DataKind> What is the Entity you wish to create/update.

Possible values:
ACCOUNT - for Accounts
TICKET - for Tickets
CHARGE - for Charges
ITEM - for Items
APPOINTMENT-OR-TASK - for Appointments/Task
HISTORY-NOTE - For History notes
ASSET - for Assets
OPPORTUNITY - for Sales Opportunities
DOCUMENT - for Documents
ARTICLE - for Knowledge Base articles

Adding new Ticket

In this sample, we add a new Ticket, and set some additional fields to it, such as Notes, Source, Due Date and Dispatcher flag.

<?xml version="1.0" ?>
<?crmxml version = "1.0" ?>
<crmTransaction>
  <ExternalApplicationName>N-Able</ExternalApplicationName>
  <SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail>
  <Password>the-predefined-api-password</Password>
  <ReturnTransactionID>data from external application (will be returned as-is in the response)
</ReturnTransactionID>
  <DataKind>TICKET</DataKind>
  <RecordData>
        <FLDTKTCARDID> CUSTOMER-RECORD-ID-GOES-HERE-20-CHARS </FLDTKTCARDID>
        <FLDTKTPROBLEM>ticket description...</FLDTKTPROBLEM>
        <FLDTKTSTATUS>100</FLDTKTSTATUS>
 	 <FLDTKTKIND>General</FLDTKTKIND>
	 <FLDTKTNOTES>Notes</FLDTKTNOTES>
	 <FLDTKTSOURCE>Source</FLDTKTSOURCE>
 	 <FLDTKTSCHEDLENESTIM>60</FLDTKTSCHEDLENESTIM>
 	 <FLDTKTDUEDATETIME>02/04/08</FLDTKTDUEDATETIME>
	 <FLDTKTFORDISPATCH>Y</FLDTKTFORDISPATCH>
  </RecordData>
</crmTransaction>

Adding new Charges

<?xml version="1.0" ?>
<?crmxml version = "1.0" ?>
<crmTransaction>
  <ExternalApplicationName>Alert</ExternalApplicationName>
  <SendResponseToEmail>your email address for responses</SendResponseToEmail>
  <Password>12345</Password>  >> Should be the same in the ServerConfig!
  <ReturnTransactionID>data from external application (will be returned as-is in the response) 
</ReturnTransactionID>
  <DataKind>CHARGE</DataKind>
  <RecordData>
        <FLDSLPWORKERID> CRDLS71RGU747TLHTFOR   </FLDSLPWORKERID>
        <FLDSLPCARDID> CRDLQXDL43BP5YCMSGM3</FLDSLPCARDID>
        <FLDSLPITEMID>  ITM1Q3GUI05ANBQGVY8D   </FLDSLPITEMID>
        <FLDSLPDESC>  Charge Description...   </FLDSLPDESC>
        <FLDSLPQUANTITY>  10   </FLDSLPQUANTITY>
        <FLDSLPSLIPDATE>  31/01/2008   </FLDSLPSLIPDATE>
        <FLDSLPSTARTTIME>  12:06  </FLDSLPSTARTTIME>
        <FLDSLPENDTIME>  14:50  </FLDSLPENDTIME>
        <FLDSLPBCRECID>  BCTMA51KBA925J7G0V67 </FLDSLPBCRECID>
        <FLDSLPPRICE> 125.3   </FLDSLPPRICE>
        <FLDSLPADJUSTAMOUNT>  10   </FLDSLPADJUSTAMOUNT>
        <FLDSLPUSER1>  Field 1...   </FLDSLPUSER1>
  </RecordData>
</crmTransaction>


Receiving Response

When adding or updating data via the XML API, the system can send a response (if the XML transaction specifies this in the SendResponseToEmail token). The format of the XML response is as follow:

Response in case of success:

<?xml version="1.0" ?>
<?crmxml version="1.0" ?>
<crmResponse>
	<Status>SUCCESS</Status>
	<AffectedRecId>TKTN1NIQEYYQ8PBJMDAX</AffectedRecId>
	<ReturnTransactionID>data from external application (as-is)</ReturnTransactionID>
</crmResponse>

Response in case of error:

<?xml version="1.0" ?>
<?crmxml version="1.0" ?>
<crmResponse>
	<Status>FAILURE</Status>
	<AffectedRecId></AffectedRecId>
	<ReturnTransactionID>data from external application (as-is)</ReturnTransactionID>
	<ResultCodes>50109</ResultCodes>
	<ResultMessage>
	Fields with illegal values: Operation canceled. Field: Account has invalid data - 
       TKTN1NIQEYYQ8PBJMDAX
	</ResultMessage>
</crmResponse>


Token Comment
<?xml version="1.0" ?> The XML version - Always 1.0
<?crmxml version ="1.0" ?> The RangerMSP API XML version - Always 1.0
<crmResponse> The response starts and ends with this token
<Status> The transaction status. Possible values: FAILURE, SUCCESS
<SendResponseToEmail> When set with an email address, then a response email will be sent after processing this transaction by the Email Connector
<AffectedRecId> The REC ID of the entity which was added or updated when processing the transaction.
<ResultCodes>
<ResultMessage>
In case of a failure, this will contain the error code and description. You can find more information about error codes here.

See Also