//////////////////////////////////////////////////////////////////////////////// // Hook for dbs | invoice // => General Functions for Hooks and Workflow // File-Encoding: UTF-8 without BOM( Test: ü,ä,ö ) //------------------------------------------------------------------------------ // Created/Edited | Description //------------------------------------------------------------------------------ // 08.2017 | dbs | invoice workflow 1.1.0 //////////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------------------------------------------------------------------------------- // checkDuplicates //--------------------------------------------------------------------------------------------------------------------------------------------------- proc checkDuplicates( pVendorNo, pInvoiceNo, pInvoiceYear, pDocId ) { call api_log( gLOGLEVEL, "Start of checkDuplicates( :pVendorNo, :pInvoiceNo, :pInvoiceYear )" ) vars lReturnValue vars lRetval = 0 vars lCountResults = -1 vars lCounter = -1 if( pVendorNo != "" && pInvoiceNo != "" && pInvoiceYear != "" ) { // clear api document context call api_clear_document_context() // set search criteria in context api_doc_type_short = gDTS_INVOICE api_doc_field[ gDDF_CONTACT_ID ] = pVendorNo api_doc_field[ gDDF_INVOICE_ID ] = pInvoiceNo lReturnValue = api_function ("document_find_ids", "Master") if( lReturnValue == 0 && api_single_info > 0 ) { lCountResults = api_single_info vars lResultList[lCountResults] for lCounter = 1 while ( lCounter <= lCountResults ) step 1 { lResultList[lCounter] = api_doc_ids[lCounter] } for lCounter = 1 while ( lCounter <= lCountResults ) step 1 { if ( pDocId != lResultList[lCounter] ) { // get attributes call api_clear_document_context() lReturnValue = api_function ("attribute_get_all", lResultList[lCounter], "Master") if ( lReturnValue == 0 ) { // Check invoice year and wfl status if ( api_doc_field[ gDDF_INVOICE_DATE ](7,4) == pInvoiceYear && \ api_doc_field[ gDDF_WFL_STATUS ] != gWFL_STATUS_REFUSED ) // remark: this is not value-key-comparison because api_doc_field is holding key and not translated value (has been tested on 2013-03-19) { call api_log_error( ":gERR_IMPORT_DUPLICATE_FOUND - Duplicate invoice found" ) lRetval = gERR_IMPORT_DUPLICATE_FOUND } } else { call api_log_error("Error during Api-Function attribute_get_all / lReturnValue :lReturnValue") lRetval = gERR_IMPORT_DUPLICATE_ERR } } } } else { if( lReturnValue != 0 ) { call api_log_error("Error during Api-Function document_find_ids / lReturnValue :lReturnValue") lRetval = gERR_IMPORT_DUPLICATE_ERR } else { call api_log_info("No documents for VendorNo ':pVendorNo' and InvoiceNo ':pInvoiceNo' found") } } } else { call api_log_error("missing mandatory fields for validation.") lRetval = gERR_IMPORT_DUPLICATE_ERR } call api_log( gLOGLEVEL, "End of checkDuplicates / return value: :lRetval" ) // clear api document context call api_clear_document_context() return lRetval }//end of checkDuplicatesApi //--------------------------------------------------------------------------------------------------------------------------------------------------- // inherit attributes from doc_type gDTS_CREDITOR_TRANS_FOLDER to children //--------------------------------------------------------------------------------------------------------------------------------------------------- proc inheritCrdTrsFldAttributes( pDocId, pDocTypeShort, pNewChild ) { call api_log( gLOGLEVEL, "Start inheritCrdTrsFldAttributes :pDocId :pDocTypeShort" ) // inherit invoice attributes vars lReturnValue = 0 vars lCounterRows = 0 vars lNumberOfRows = 0 vars lCounterParents = 0 vars lNumberOfParents = 0 vars lCounterChilds = 0 vars lNumberOfChilds = 0 vars lTransactionDokuID = "" vars lDokuIdChilds[1000] vars lCostCenter[1000], lGlAccount[1000], lOrder[1000], lWflMember[1000] vars lCompanyCode, lClient, lCreditorNo, lCreditorName, lStreet, lZipCode, lCity, lCountry, lCurrency, lInvoiceId // backup invoice attributes // initialize header data : CompanyCode, Client, CreditorNo, CreditorName, Street, Zip Code, City, Country, Currency, Invoice ID lCompanyCode = dok_dat_feld[ gDDF_COMPANY_CODE ] lClient = dok_dat_feld[ gDDF_CLIENT ] lCreditorNo = dok_dat_feld[ gDDF_CONTACT_ID ] lCreditorName = dok_dat_feld[ gDDF_CONTACT_NAME ] lStreet = dok_dat_feld[ gDDF_STREET ] lZipCode = dok_dat_feld[ gDDF_ZIP ] lCity = dok_dat_feld[ gDDF_CITY ] lCountry = dok_dat_feld[ gDDF_COUNTRY ] lCurrency = dok_dat_feld[ gDDF_CURRENCY ] lInvoiceId = dok_dat_feld[ gDDF_INVOICE_ID ] // initialize pos data: CostCenter, GlAccount, Order, WflMember for lCounterRows = 1 while( lCounterRows <= 1000 ) step 1 { lCostCenter[lCounterRows] = dok_dat_feld_:(gDDF_COST_CENTER)[ lCounterRows ] lGlAccount[lCounterRows] = dok_dat_feld_:(gDDF_GL_ACCOUNT)[ lCounterRows ] lOrder[lCounterRows] = dok_dat_feld_:(gDDF_INTERNAL_ORDER)[ lCounterRows ] lWflMember[lCounterRows] = dok_dat_feld_:(gDDF_WFL_MEMBER)[ lCounterRows ] if ( lCostCenter[lCounterRows] == "" && lGlAccount[lCounterRows] == "" && lOrder[lCounterRows] == "" && lWflMember[lCounterRows] == "" ) { lNumberOfRows = lCounterRows - 1 break } } // if function is called with vendor transaction folder no search required if( pDocTypeShort == gDTS_CREDITOR_TRANS_FOLDER ) { lTransactionDokuID = pDocId } else { // identify parent documents ( in ideal case it is just one ) lReturnValue = api_function( "link_get_parents", pDocId, "Master" ) if( lReturnValue == 0 ) { lNumberOfParents = api_single_info // keep in mind how many parent documents exists for lCounterParents = 1 while( lCounterParents <= lNumberOfParents ) step 1 { lReturnValue = api_function( "attribute_get_single", "doc_type_short", "", api_links[:lCounterParents], "Master" ) if( lReturnValue == 0 ) { if( api_single_info == gDTS_CREDITOR_TRANS_FOLDER ) { // vendor transaction folder found lTransactionDokuID = api_links[:lCounterParents] } // vendor transaction folder found, cancel loop break } } } } if( lTransactionDokuID != "" ) { // clear context call api_clear_document_context() // change attributes of documents contained in the folder lReturnValue = api_function( "link_get_children", lTransactionDokuID, "Master" ) if( lReturnValue == 0 ) { lNumberOfChilds = api_single_info // keep in mind how many child documents exists for lCounterChilds = 1 while ( lCounterChilds <= lNumberOfChilds ) step 1 { // keep ids of child document in mind lDokuIdChilds[:lCounterChilds] = api_links[:lCounterChilds] } // add new child of folder to doc_ids when child will be added to folder after this hook if( pNewChild != "") { lNumberOfChilds = lNumberOfChilds + 1 lDokuIdChilds[:lNumberOfChilds] = pNewChild } for lCounterChilds = 1 while ( lCounterChilds <= lNumberOfChilds ) step 1 { // skip current invoice if( lDokuIdChilds[:lCounterChilds] != pDocId ) { call api_clear_document_context() lReturnValue = api_function( "attribute_get_all", lDokuIdChilds[:lCounterChilds], "Master" ) if( lReturnValue == 0 ) { // just update invoices and invoice attachments contained in the vendor transaction folder if( api_doc_type_short == gDTS_INVOICE || api_doc_type_short == gDTS_INVOICE_ATTACHMENT ) { call sm_n_clear_array( "api_doc_field_:(gDDF_COST_CENTER)" ) call sm_n_clear_array( "api_doc_field_:(gDDF_GL_ACCOUNT)" ) call sm_n_clear_array( "api_doc_field_:(gDDF_INTERNAL_ORDER)" ) call sm_n_clear_array( "api_doc_field_:(gDDF_WFL_MEMBER)" ) // copy the invoice attributes to context api_doc_field[ gDDF_COMPANY_CODE ] = lCompanyCode api_doc_field[ gDDF_CLIENT ] = lClient api_doc_field[ gDDF_CONTACT_ID ] = lCreditorNo api_doc_field[ gDDF_CONTACT_NAME ] = lCreditorName api_doc_field[ gDDF_INVOICE_ID ] = lInvoiceId if( api_doc_type_short == gDTS_INVOICE ) { api_doc_field[ gDDF_STREET ] = lStreet api_doc_field[ gDDF_ZIP ] = lZipCode api_doc_field[ gDDF_CITY ] = lCity api_doc_field[ gDDF_COUNTRY ] = lCountry api_doc_field[ gDDF_CURRENCY ] = lCurrency } for lCounterRows = 1 while ( lCounterRows <= lNumberOfRows ) step 1 { api_doc_field_:(gDDF_COST_CENTER)[lCounterRows] = lCostCenter[lCounterRows] api_doc_field_:(gDDF_GL_ACCOUNT)[lCounterRows] = lGlAccount[lCounterRows] api_doc_field_:(gDDF_INTERNAL_ORDER)[lCounterRows] = lOrder[lCounterRows] api_doc_field_:(gDDF_WFL_MEMBER)[lCounterRows] = lWflMember[lCounterRows] } // in case of updating refused invoices stop hook execution to avoid an infinit loop SERVER_API_NO_HOOKS = 1 call api_function( "attribute_update_all", lDokuIdChilds[:lCounterChilds], "Master" ) SERVER_API_NO_HOOKS = 0 } } call api_clear_document_context() } } } // --- START UPDATE the transaction folder call api_clear_document_context() lReturnValue = api_function( "attribute_get_all", lTransactionDokuID, "Master" ) if( lReturnValue == 0 ) { // only update the transaction folder if( api_doc_type_short == gDTS_CREDITOR_TRANS_FOLDER ) { call sm_n_clear_array( "api_doc_field_:(gDDF_COST_CENTER)" ) call sm_n_clear_array( "api_doc_field_:(gDDF_GL_ACCOUNT)" ) call sm_n_clear_array( "api_doc_field_:(gDDF_INTERNAL_ORDER)" ) call sm_n_clear_array( "api_doc_field_:(gDDF_WFL_MEMBER)" ) // copy the invoice attributes to context api_doc_field[ gDDF_COMPANY_CODE ] = lCompanyCode api_doc_field[ gDDF_CLIENT ] = lClient api_doc_field[ gDDF_CONTACT_ID ] = lCreditorNo api_doc_field[ gDDF_CONTACT_NAME ] = lCreditorName api_doc_field[ gDDF_INVOICE_ID ] = lInvoiceId api_doc_field[ gDDF_STREET ] = lStreet api_doc_field[ gDDF_ZIP ] = lZipCode api_doc_field[ gDDF_CITY ] = lCity api_doc_field[ gDDF_COUNTRY ] = lCountry for lCounterRows = 1 while ( lCounterRows <= lNumberOfRows ) step 1 { api_doc_field_:(gDDF_COST_CENTER)[lCounterRows] = lCostCenter[lCounterRows] api_doc_field_:(gDDF_GL_ACCOUNT)[lCounterRows] = lGlAccount[lCounterRows] api_doc_field_:(gDDF_INTERNAL_ORDER)[lCounterRows] = lOrder[lCounterRows] api_doc_field_:(gDDF_WFL_MEMBER)[lCounterRows] = lWflMember[lCounterRows] } // stop hook execution to avoid an infinit loop SERVER_API_NO_HOOKS = 1 call api_function( "attribute_update_all", lTransactionDokuID, "Master" ) SERVER_API_NO_HOOKS = 0 } } call api_clear_document_context() // --- ENDE UPDATE the transaction folder } // clear context call api_clear_document_context() call api_log( gLOGLEVEL, "End inheritCrdTrsFldAttributes" ) }//end of inheritCrdTrsFldAttributes //--------------------------------------------------------------------------------------------------------------------------------------------------- // inherit attributes from doc_type gDTS_CREDITOR_TRANS_FOLDER to new linked children //--------------------------------------------------------------------------------------------------------------------------------------------------- proc inheritImpCrdTrsFldAttr( pDocIdFather, pDocIdChild ) { call api_log_info( "Start inheritImpCrdTrsFldAttr Father: :pDocIdFather Child: :pDocIdChild" ) vars lReturnValue, lNumberOfRows, lCounterRows vars lWflMember[1000] vars lDocTypeShortFather, lDocTypeShortChild, lTransactionIdFather, lTransactionIdChild vars lCostCenter[1000], lGlAccount[1000], lOrder[1000], lWflMember[1000] vars lCompanyCode, lClient, lCreditorNo, lCreditorName, lStreet, lZipCode, lCity, lCountry, lCurrency, lInvoiceId call api_clear_document_context() lReturnValue = api_function( "attribute_get_all", pDocIdFather, "Master" ) // backup invoice attributes // initialize header data : CompanyCode, Client, CreditorNo, CreditorName, Street, Zip Code, City, Country, Currency, Invoice ID lDocTypeShortFather = api_doc_type_short lTransactionIdFather = api_doc_field[ gDDF_TRANSACTION_ID ] lCompanyCode = api_doc_field[ gDDF_COMPANY_CODE ] lClient = api_doc_field[ gDDF_CLIENT ] lCreditorNo = api_doc_field[ gDDF_CONTACT_ID ] lCreditorName = api_doc_field[ gDDF_CONTACT_NAME ] lInvoiceId = api_doc_field[ gDDF_INVOICE_ID ] if( lDocTypeShortFather == gDTS_CREDITOR_TRANS_FOLDER && lTransactionIdFather != "" ) { // initialize pos data: CostCenter, GlAccount, Order, WflMember for lCounterRows = 1 while( lCounterRows <= 1000 ) step 1 { lCostCenter[lCounterRows] = api_doc_field_:(gDDF_COST_CENTER)[ lCounterRows ] lGlAccount[lCounterRows] = api_doc_field_:(gDDF_GL_ACCOUNT)[ lCounterRows ] lOrder[lCounterRows] = api_doc_field_:(gDDF_INTERNAL_ORDER)[ lCounterRows ] lWflMember[lCounterRows] = api_doc_field_:(gDDF_WFL_MEMBER)[ lCounterRows ] if ( lCostCenter[lCounterRows] == "" && lGlAccount[lCounterRows] == "" && lOrder[lCounterRows] == "" && lWflMember[lCounterRows] == "" ) { lNumberOfRows = lCounterRows - 1 break } } call api_clear_document_context() lReturnValue = api_function( "attribute_get_all", pDocIdChild, "Master" ) lDocTypeShortChild = api_doc_type_short lTransactionIdChild = api_doc_field[ gDDF_TRANSACTION_ID ] if( lDocTypeShortChild == gDTS_INVOICE_ATTACHMENT && lTransactionIdFather == lTransactionIdChild ) { call sm_n_clear_array( "api_doc_field_:(gDDF_COST_CENTER)" ) call sm_n_clear_array( "api_doc_field_:(gDDF_GL_ACCOUNT)" ) call sm_n_clear_array( "api_doc_field_:(gDDF_INTERNAL_ORDER)" ) call sm_n_clear_array( "api_doc_field_:(gDDF_WFL_MEMBER)" ) // copy the invoice attributes to context api_doc_field[ gDDF_COMPANY_CODE ] = lCompanyCode api_doc_field[ gDDF_CLIENT ] = lClient api_doc_field[ gDDF_CONTACT_ID ] = lCreditorNo api_doc_field[ gDDF_CONTACT_NAME ] = lCreditorName api_doc_field[ gDDF_INVOICE_ID ] = lInvoiceId for lCounterRows = 1 while ( lCounterRows <= lNumberOfRows ) step 1 { api_doc_field_:(gDDF_COST_CENTER)[lCounterRows] = lCostCenter[lCounterRows] api_doc_field_:(gDDF_GL_ACCOUNT)[lCounterRows] = lGlAccount[lCounterRows] api_doc_field_:(gDDF_INTERNAL_ORDER)[lCounterRows] = lOrder[lCounterRows] api_doc_field_:(gDDF_WFL_MEMBER)[lCounterRows] = lWflMember[lCounterRows] } // in case of updating refused invoices stop hook execution to avoid an infinit loop SERVER_API_NO_HOOKS = 1 call api_function( "attribute_update_all", pDocIdChild, "Master" ) SERVER_API_NO_HOOKS = 0 } } call api_clear_document_context() call api_log_info( "End inheritImpCrdTrsFldAttr Father: :pDocIdFather Child: :pDocIdChild" ) } //--------------------------------------------------------------------------------------------------------------------------------------------------- // set new transaction id to current document if generation of transaction id is configured //--------------------------------------------------------------------------------------------------------------------------------------------------- proc updateTransactionID( pDocId, pDocTypeShort ) { call api_log( gLOGLEVEL, "Start updateTransactionID :pDocId :pDocTypeShort" ) if( dok_dat_feld[ gDDF_TRANSACTION_ID ] == "" ) { // generate new transaction number ( transaction safe ) vars lMaxInt, lMaxCount, lSchemeClause, lReturnValue, lNewTransactionId vars lCurrentYear = sm_sdtime("n%4y") lNewTransactionId = "NoValueDefined" //add scheme to from clause if set if(gGMF_SCHEME_NAME_RUN_TIME != "") { lSchemeClause = ":(gGMF_SCHEME_NAME_RUN_TIME)." } else { lSchemeClause = "" } // ATTENTION: DB-TRANSACTIONS ARE ONLY ALLOWED TO BE USED IN THOSE HOOKS // THAT ARE SERVER-INTERNALLY NOT USING TRANSACTIONS THEMSELVES DBMS BEGIN DBMS ALIAS lMaxInt DBMS SQL SELECT maxint \ FROM :(lSchemeClause):(gGMF_TABLE_CUSTOM_COUNTER) \ WHERE cond1 = :+pDocTypeShort \ AND cond2 = :+lCurrentYear lMaxCount = @dmrowcount DBMS ALIAS if( lMaxCount == 0 ) // no data setDatensatz -> new year { DBMS SQL INSERT INTO :(lSchemeClause):(gGMF_TABLE_CUSTOM_COUNTER) ( cond1, cond2, maxint ) \ VALUES ( :+pDocTypeShort, :+lCurrentYear, 1 ) } else { DBMS SQL UPDATE :(lSchemeClause):(gGMF_TABLE_CUSTOM_COUNTER) \ SET maxint = maxint + 1 \ WHERE cond1 = :+pDocTypeShort \ AND cond2 = :+lCurrentYear } DBMS ALIAS lMaxInt DBMS SQL SELECT maxint \ FROM :(lSchemeClause):(gGMF_TABLE_CUSTOM_COUNTER) \ WHERE cond1 = :+pDocTypeShort \ AND cond2 = :+lCurrentYear lMaxCount = @dmrowcount DBMS ALIAS DBMS COMMIT // ATTENTION: DB-TRANSACTIONS ARE ONLY ALLOWED TO BE USED IN THOSE HOOKS // THAT ARE SERVER-INTERNALLY NOT USING TRANSACTIONS THEMSELVES lReturnValue = api_function( "string_fill_leading_char", lMaxInt, "0", gGMF_TRANSACTION_ID_SIZE ) if( lReturnValue >= 0 ) { lNewTransactionId = gGMF_TRANSACTION_ID_PRAEFIX ## lCurrentYear ## "-" ## api_converted_string } // in case of updating transaction is stop hook execution SERVER_API_NO_HOOKS = 1 call api_function( "attribute_update_single", gDDF_TRANSACTION_ID, lNewTransactionId, 0, pDocId, "Master" ) SERVER_API_NO_HOOKS = 0 return lNewTransactionId } return -1 }//end of updateTransactionID //--------------------------------------------------------------------------------------------------------------------------------------------------- // updates creditor data from database //--------------------------------------------------------------------------------------------------------------------------------------------------- proc updateCreditorData( pDocId ) { call api_log( gLOGLEVEL, "Start of updateCreditorData( pDocId = :pDocId )" ) vars lReturnValue, lNumberOfResults = 0 vars lCompanyCode, lClient, lCreditorNo, lCreditorName, lStreet, lZipCode, lCity, lCountry, lCurrency, lWhere, lFromClause vars lCurrCreditorId = dok_dat_feld[ gDDF_CONTACT_ID ] vars lCurrCreditorName = dok_dat_feld[ gDDF_CONTACT_NAME ] vars lCurrClient = dok_dat_feld[ gDDF_CLIENT ] vars lCurrCompanyCode = dok_dat_feld[ gDDF_COMPANY_CODE ] vars lCurrCurrency = dok_dat_feld[ gDDF_CURRENCY ] if( lCurrCreditorId == "89999" ) { return 0 } // get creditor master data if( lCurrCreditorId != "" || lCurrCreditorName != "" ) { if( lCurrCreditorId != "" ) { lWhere = "creditor_no = :+lCurrCreditorId" } else { lWhere = "name = :+lCurrCreditorName" } if( lCurrCompanyCode != "" ) { lWhere = lWhere ## " AND company_code = :+lCurrCompanyCode" } if( lCurrClient != "" ) { lWhere = lWhere ## " AND client = :+lCurrClient" } //add scheme to from clause if set if(gGMF_SCHEME_NAME != "") { lFromClause = ":(gGMF_SCHEME_NAME).:(gGMF_TABLE_CREDITORS)" } else { lFromClause = ":gGMF_TABLE_CREDITORS" } DBMS ALIAS lCompanyCode, lClient, lCreditorNo, lCreditorName, lStreet, lZipCode, lCity, lCountry, lCurrency DBMS SQL SELECT company_code, \ client, \ creditor_no, \ name, \ street, \ zip, \ city, \ country, \ currency \ FROM :lFromClause \ WHERE :lWhere lNumberOfResults = @dmrowcount DBMS ALIAS if( lNumberOfResults != 0 && pDocId == "" ) { dok_dat_feld[ gDDF_COMPANY_CODE ] = lCompanyCode dok_dat_feld[ gDDF_CLIENT ] = lClient dok_dat_feld[ gDDF_CONTACT_ID ] = lCreditorNo dok_dat_feld[ gDDF_CONTACT_NAME ] = lCreditorName dok_dat_feld[ gDDF_STREET ] = lStreet dok_dat_feld[ gDDF_ZIP ] = lZipCode dok_dat_feld[ gDDF_CITY ] = lCity dok_dat_feld[ gDDF_COUNTRY ] = lCountry if( lCurrCurrency == "" ) { dok_dat_feld[ gDDF_CURRENCY ] = lCurrency } } else if( lNumberOfResults != 0 && pDocId != "" ) { call api_clear_document_context() lReturnValue = api_function( "attribute_get_all", pDocId, "Master" ) if( lReturnValue == 0 ) { api_doc_field[ gDDF_COMPANY_CODE ] = lCompanyCode api_doc_field[ gDDF_CLIENT ] = lClient api_doc_field[ gDDF_CONTACT_ID ] = lCreditorNo api_doc_field[ gDDF_CONTACT_NAME ] = lCreditorName api_doc_field[ gDDF_STREET ] = lStreet api_doc_field[ gDDF_ZIP ] = lZipCode api_doc_field[ gDDF_CITY ] = lCity api_doc_field[ gDDF_COUNTRY ] = lCountry if( lCurrCurrency == "" ) { api_doc_field[ gDDF_CURRENCY ] = lCurrency } // in case of updating refused invoices stop hook execution to avoid an infinit loop SERVER_API_NO_HOOKS = 1 call api_function( "attribute_update_all", pDocId, "Master" ) SERVER_API_NO_HOOKS = 0 } call api_clear_document_context() } } call api_log( gLOGLEVEL, "End updateCreditorData" ) } //end of updateCreditorData //=================================================================================================================================================== //========== FUNCTIONS WORKFLOW ===================================================================================================================== //=================================================================================================================================================== //--------------------------------------------------------------------------------------------------------------------------------------------------- // write state of workflow to erp interface // pDocId, 'dbut', gWFL_STATUS_FINISHED, wfStep, wfWebServiceURL //--------------------------------------------------------------------------------------------------------------------------------------------------- proc write_state_webservicedll( pDocId, wfUser, wfState, wfStep, wfStepLvl, wfWebServiceURL ) { vars lReturnCode, lReturnValue, lReturnCodeXML, lReturnMessageXML vars lCurrentTimestamp = getCurrentTimestamp() call api_clear_document_context() lReturnValue = api_function ("attribute_get_all", pDocId, "") if( lReturnValue == 0 ) { // ----------------------------------------------------------- // create request call d3ws_startSession() call d3ws_xml_start() call d3ws_xml_openNode( 'decsERPRequest' ) call d3ws_xml_addNode( 'context', gGMF_CONFIG_INTERFACE ) call d3ws_xml_addNode( 'function', 'writeState' ) call d3ws_xml_openNode( 'parameter' ) call d3ws_xml_addNode( 'ERPID', api_doc_field[gDDF_ERP_ID] ) call d3ws_xml_addNode( 'SYSID', api_doc_field[gDDF_SYSTEM_ID] ) call d3ws_xml_addNode( 'CLIENT', api_doc_field[gDDF_CLIENT] ) call d3ws_xml_addNode( 'COMPANY_CODE', api_doc_field[gDDF_COMPANY_CODE] ) call d3ws_xml_addNode( 'TIME_STAMP', lCurrentTimestamp ) call d3ws_xml_addNode( 'USER', wfUser ) call d3ws_xml_addNode( 'STATE', wfState ) call d3ws_xml_addNode( 'STEP', wfStep ) call d3ws_xml_addNode( 'STEPLVL', wfStepLvl ) call d3ws_xml_closeNode( 'parameter' ) call d3ws_xml_closeNode( 'decsERPRequest' ) call d3ws_xml_stop() lReturnCode = d3ws_http_sendRequest( wfWebServiceURL ) lReturnCodeXML = d3ws_xml_getNodeValue( 'returnCode' ) lReturnMessageXML = d3ws_xml_getNodeValue( 'returnMessage' ) call d3ws_stopSession() if( lReturnCode != "OK" || lReturnCodeXML != 0 ) { call api_log_error( "Error while creating xml request: " ## lReturnCode ) call api_log_error( "Servlet returned error code: " ## lReturnCodeXML ) call api_log_error( "Servlet returned error message: " ## lReturnMessageXML ) return gERR_ERP_SVLT_WRITE_STATE } else { call api_log_info( "Created xml request for write_state(): " ## lReturnCode ) return 0 } } else { call api_log_error ("Errorcode :lReturnValue was returned!") } }//end of write_state //--------------------------------------------------------------------------------------------------------------------------------------------------- // write current users of workflow to erp interface //--------------------------------------------------------------------------------------------------------------------------------------------------- proc write_user_webservicedll( pDocId, wfUsers, wfState, wfStep, wfStepLvl, wfWebServiceURL ) { vars lReturnCode, lReturnValue, global lReturnCodeDBSXML, lReturnMessageDBSXML call api_clear_document_context() lReturnValue = api_function ("attribute_get_all", pDocId, "") if( lReturnValue == 0 ) { // Variablendeklaration vars lSplittedUsers // Number of returned values of function string_split vars lUsersString = wfUsers // string to be splitted vars lCharSplitter = ";" // split character // call string_split lSplittedUsers = api_function ("string_split", lUsersString, lCharSplitter) // Ergebnisausgabe if( lSplittedUsers > 0 ) { call api_log_info ("String wfUsers was splitted in :lSplittedUsers Strings.") // ----------------------------------------------------------- // create request call d3ws_startSession() call d3ws_xml_start() call d3ws_xml_openNode( 'decsERPRequest' ) call d3ws_xml_addNode( 'context', gGMF_CONFIG_INTERFACE ) call d3ws_xml_addNode( 'function', 'writeUser' ) call d3ws_xml_openNode( 'parameter' ) call d3ws_xml_addNode( 'ERPID', api_doc_field[gDDF_ERP_ID] ) call d3ws_xml_addNode( 'SYSID', api_doc_field[gDDF_SYSTEM_ID] ) call d3ws_xml_addNode( 'CLIENT', api_doc_field[gDDF_CLIENT] ) call d3ws_xml_addNode( 'COMPANY_CODE', api_doc_field[gDDF_COMPANY_CODE] ) call d3ws_xml_addNode( 'STEP', wfStep ) call d3ws_xml_addNode( 'STEPLVL', wfStepLvl ) // start of for-loop -------------------------------------------------------------- vars lCount // counter for loop vars lCurrentTimestamp = getCurrentTimestamp() for lCount = 1 while( lCount <= lSplittedUsers ) step 1 { call d3ws_xml_openNode( 'USERS' ) call d3ws_xml_addNode( 'TIME_STAMP', lCurrentTimestamp ) call d3ws_xml_addNode( 'USER', api_splitted_string[ lCount ] ) call d3ws_xml_addNode( 'STATE', wfState ) call d3ws_xml_closeNode( 'USERS' ) } // end of for-loop --------------------------------------------------------------- call d3ws_xml_closeNode( 'parameter' ) call d3ws_xml_closeNode( 'decsERPRequest' ) call d3ws_xml_stop() lReturnCode = d3ws_http_sendRequest( wfWebServiceURL ) lReturnCodeXML = d3ws_xml_getNodeValue( 'returnCode' ) lReturnMessageXML = d3ws_xml_getNodeValue( 'returnMessage' ) call d3ws_stopSession() if( lReturnCode != "OK" || lReturnCodeXML != 0 ) { call api_log_error( "Error while creating xml request: " ## lReturnCode ) call api_log_error( "Servlet returned error code: " ## lReturnCodeXML ) call api_log_error( "Servlet returned error message: " ## lReturnMessageXML ) return gERR_ERP_SVLT_WRITE_USER } else { call api_log_info ( "Created xml request for write_user(): " ## lReturnCode ) } } else { if( lSplittedUsers < 0 ) { call api_log_error ("No users could be determined with string_split in write_user()! Errorcode was :lSplittedUsers.") } } return 0 } else { call api_log_error ("Errorcode :lReturnValue was returned!") } }//end of write_user //--------------------------------------------------------------------------------------------------------------------------------------------------- // write current state of workflow to erp interface via java class //--------------------------------------------------------------------------------------------------------------------------------------------------- proc write_state( pDocId, wfUser, wfState, wfStep, wfStepLvl, wfWebServiceURL ) { vars lReturnCode, lReturnValue vars lCurrentTimestamp = getCurrentTimestamp() gDBS_RET_CODE_SERVLET_JAVA = "" gDBS_RET_MSG_SERVLET_JAVA = "" call api_clear_document_context() lReturnValue = api_function ("attribute_get_all", pDocId, "") if( lReturnValue == 0 ) { // ----------------------------------------------------------- // add request params lReturnValue = api_function ("java_add_param", wfWebServiceURL) // wfWebServiceURL lReturnValue = api_function ("java_add_param", gGMF_CONFIG_INTERFACE) lReturnValue = api_function ("java_add_param", "writeState") lReturnValue = api_function ("java_add_param", "ERPID" ## "|" ## api_doc_field[gDDF_ERP_ID]) lReturnValue = api_function ("java_add_param", "SYSID" ## "|" ## api_doc_field[gDDF_SYSTEM_ID]) lReturnValue = api_function ("java_add_param", "CLIENT" ## "|" ## api_doc_field[gDDF_CLIENT]) lReturnValue = api_function ("java_add_param", "COMPANY_CODE" ## "|" ## api_doc_field[gDDF_COMPANY_CODE]) lReturnValue = api_function ("java_add_param", "TIME_STAMP" ## "|" ## lCurrentTimestamp) lReturnValue = api_function ("java_add_param", "USER" ## "|" ## wfUser) lReturnValue = api_function ("java_add_param", "STATE" ## "|" ## wfState) lReturnValue = api_function ("java_add_param", "STEP" ## "|" ## wfStep) lReturnValue = api_function ("java_add_param", "STEPLVL" ## "|" ## wfStepLvl) lReturnCode = api_function ("java_call_static", "com/dvelop/decs/erp/servlet/javacall/DecsERPServletConnector", "executePost") if( lReturnCode != 0 || gDBS_RET_CODE_SERVLET_JAVA != 0 ) { call api_log_error( "Error while creating xml request: " ## lReturnCode ) call api_log_error( "Servlet returned error code: " ## gDBS_RET_CODE_SERVLET_JAVA ) call api_log_error( "Servlet returned error message: " ## gDBS_RET_MSG_SERVLET_JAVA ) return gERR_ERP_SVLT_WRITE_STATE } else { call api_log_info( "Created xml request for write_state(): " ## lReturnCode ) return 0 } } return 0 } // end of write_state //--------------------------------------------------------------------------------------------------------------------------------------------------- // write current users of workflow to erp interface via java class //--------------------------------------------------------------------------------------------------------------------------------------------------- proc write_user( pDocId, wfUsers, wfState, wfStep, wfStepLvl, wfWebServiceURL ) { vars lReturnCode, lReturnValue gDBS_RET_CODE_SERVLET_JAVA = "" gDBS_RET_MSG_SERVLET_JAVA = "" call api_clear_document_context() lReturnValue = api_function ("attribute_get_all", pDocId, "") if( lReturnValue == 0 ) { // Variablendeklaration vars lSplittedUsers // Number of returned values of function string_split vars lUsersString = wfUsers // string to be splitted vars lCharSplitter = ";" // split character // call string_split lSplittedUsers = api_function ("string_split", lUsersString, lCharSplitter) // Ergebnisausgabe if( lSplittedUsers > 0 ) { call api_log_info ("String wfUsers was splitted in :lSplittedUsers Strings.") // ----------------------------------------------------------- // add request params lReturnValue = api_function ("java_add_param", wfWebServiceURL) // wfWebServiceURL lReturnValue = api_function ("java_add_param", gGMF_CONFIG_INTERFACE) lReturnValue = api_function ("java_add_param", "writeUser") lReturnValue = api_function ("java_add_param", "ERPID" ## "|" ## api_doc_field[gDDF_ERP_ID]) lReturnValue = api_function ("java_add_param", "SYSID" ## "|" ## api_doc_field[gDDF_SYSTEM_ID]) lReturnValue = api_function ("java_add_param", "CLIENT" ## "|" ## api_doc_field[gDDF_CLIENT]) lReturnValue = api_function ("java_add_param", "COMPANY_CODE" ## "|" ## api_doc_field[gDDF_COMPANY_CODE]) lReturnValue = api_function ("java_add_param", "STEP" ## "|" ## wfStep) lReturnValue = api_function ("java_add_param", "STEPLVL" ## "|" ## wfStepLvl) // start of for-loop -------------------------------------------------------------- vars lCount // counter for loop vars lCurrentTimestamp = getCurrentTimestamp() lReturnValue = api_function ("java_add_param", "USERS_TIME_STAMP" ## "|" ## lCurrentTimestamp) lReturnValue = api_function ("java_add_param", "USERS_STATE" ## "|" ## wfState) for lCount = 1 while( lCount <= lSplittedUsers ) step 1 { lReturnValue = api_function ("java_add_param", "USERS_USER" ## "|" ## api_splitted_string[ lCount ]) } // end of for-loop --------------------------------------------------------------- lReturnCode = api_function ("java_call_static", "com/dvelop/decs/erp/servlet/javacall/DecsERPServletConnector", "executePost") if( lReturnCode != 0 || gDBS_RET_CODE_SERVLET_JAVA != 0 ) { call api_log_error( "Error while creating xml request: " ## lReturnCode ) call api_log_error( "Servlet returned error code: " ## gDBS_RET_CODE_SERVLET_JAVA ) call api_log_error( "Servlet returned error message: " ## gDBS_RET_MSG_SERVLET_JAVA ) return gERR_ERP_SVLT_WRITE_USER } else { call api_log_info ( "Created xml request for write_user(): " ## lReturnCode ) } } else { if( lSplittedUsers < 0 ) { call api_log_error ("No users could be determined with string_split in write_user()! Errorcode was :lSplittedUsers.") } } return 0 } else { call api_log_error ("Errorcode :lReturnValue was returned!") } }//end of write_user //--------------------------------------------------------------------------------------------------------------------------------------------------- // return current formatted timestamp, is especially formatted for erp interface -> yyyyMMddHHmmss (defined by erp-interface) //--------------------------------------------------------------------------------------------------------------------------------------------------- string proc getCurrentTimestamp() { vars lReturnValue // format of datetimestamp: yyyyMMddHHmmss (is defined by erp-interface) vars lFormat = "%4y%0m%0d%0h%0M%0s" lReturnValue = api_function ("get_current_datetime", lFormat) call api_log_info ( "getCurrentTimestamp is formatted as :api_single_info" ) if( lReturnValue == 0 ) { return api_single_info } else { call api_log_error ("Error no :lReturnValue was returned!") return -1 } }//end of getCurrentTimestamp proc updateWFLMembers( pDocId, pRecipients ) { vars lSplitReturn, lReturnValue, lCount, lCounterRows, lCurrentUser, lCurrentSubstitute, lCurrentWflMember, lArrayLength, lFound // split string lSplitReturn = api_function ("string_split", pRecipients, ";") // return value if ( lSplitReturn >= 0 ) { call api_log_info("User list was splitted into :lSplitReturn users.") for lCount = 1 while( lCount <= lSplitReturn ) step 1 { lCurrentUser = api_splitted_string[lCount] //CHECK USER call api_clear_document_context() lReturnValue = api_function( "attribute_get_all", pDocId, "Master" ) lArrayLength = sm_n_num_occurs("api_doc_field_:gDDF_WFL_MEMBER") lFound = 0 for lCounterRows = 1 while( lCounterRows <= lArrayLength ) step 1 { lCurrentWflMember = api_doc_field_:(gDDF_WFL_MEMBER)[ lCounterRows ] if ( lCurrentWflMember == lCurrentUser ) { lFound=1 break } } if(lFound == 0) { SERVER_API_NO_HOOKS = 1 lReturnValue = api_function ("attribute_update_single", gDDF_WFL_MEMBER, lCurrentUser, lArrayLength+1, pDocId, "") SERVER_API_NO_HOOKS = 0 } //CHECK SUBSTITUE lCurrentSubstitute = getSubstitute( lCurrentUser ) if( lCurrentSubstitute != "" ) { call api_clear_document_context() lReturnValue = api_function( "attribute_get_all", pDocId, "Master" ) lArrayLength = sm_n_num_occurs("api_doc_field_:gDDF_WFL_MEMBER") lFound = 0 for lCounterRows = 1 while( lCounterRows <= lArrayLength ) step 1 { lCurrentWflMember = api_doc_field_:(gDDF_WFL_MEMBER)[ lCounterRows ] if ( lCurrentWflMember == lCurrentSubstitute ) { lFound=1 break } } if(lFound == 0) { SERVER_API_NO_HOOKS = 1 lReturnValue = api_function ("attribute_update_single", gDDF_WFL_MEMBER, lCurrentSubstitute, lArrayLength+1, pDocId, "") SERVER_API_NO_HOOKS = 0 } } } } } //--------------------------------------------------------------------------------------------------------------------------------------------------- // return substitute of given user, returns "" when no substitute is given //--------------------------------------------------------------------------------------------------------------------------------------------------- string proc getSubstitute( pUser ) { vars lCheckoutText vars lReturnValue // call api HIDE_API_ERROR_ONCE = "1" lReturnValue = api_function ("user_get_data", pUser) // TODO check this funtion if ( lReturnValue == 0 ) { // is user absent if ( api_user_checkout_flag != 0) { lCheckoutText = api_user_checkout_text if( lCheckoutText != "" ) { lReturnValue = api_function ("string_split", lCheckoutText, "@@") if(lReturnValue == 2) { vars lSubstitute lSubstitute = api_splitted_string[2] call api_log_info( "Found :+lSubstitute as substitute for user :+pUser" ) return lSubstitute } return "" } } } return "" } /* //--------------------------------------------------------------------------------------------------------------------------------------------------- // return ERP id of given document id //--------------------------------------------------------------------------------------------------------------------------------------------------- string proc getErpId( pDocId ) { return getSingleAttributeByDocId( pDocId, gDDF_ERP_ID ) }//end of getErpId //--------------------------------------------------------------------------------------------------------------------------------------------------- // return System id of given document id //--------------------------------------------------------------------------------------------------------------------------------------------------- string proc getSystemId( pDocId ) { return getSingleAttributeByDocId( pDocId, gDDF_SYSTEM_ID ) }//end of getSystemId //--------------------------------------------------------------------------------------------------------------------------------------------------- // return client of given document id //--------------------------------------------------------------------------------------------------------------------------------------------------- string proc getClient( pDocId ) { return getSingleAttributeByDocId( pDocId, gDDF_CLIENT ) }//end of getClient //--------------------------------------------------------------------------------------------------------------------------------------------------- // return value of given document id and attribute database position //--------------------------------------------------------------------------------------------------------------------------------------------------- string proc getSingleAttributeByDocId( pDocId, pDDF ) { vars lReturnValue lReturnValue = api_function ("attribute_get_single", pDDF, 0, pDocId, "") if( lReturnValue == 0 ) { return api_single_info } else { call api_log_error ("Errorno :lReturnValue was returned!") return -1 } }//end of getSingleAttributeByDocId */ //--------------------------------------------------------------------------------------------------------------------------------------------------- // load webservice dll for connection with erp-interface //--------------------------------------------------------------------------------------------------------------------------------------------------- proc load_webservice_dll() { vars i, t, fct_name, fct_type vars dll_name = "d3_webservice.dll" call api_log_info ("Loading DLL :dll_name ...") vars dll_step = "" vars dll_error = 0 vars dll_functions[100] dll_functions[1] = "s d3ws_startSession()" dll_functions[2] = "s d3ws_xml_start()" dll_functions[3] = "s d3ws_xml_openNode(s)" dll_functions[4] = "s d3ws_xml_addNode(s,s)" dll_functions[5] = "s d3ws_xml_closeNode(s)" dll_functions[6] = "s d3ws_xml_stop()" dll_functions[7] = "s d3ws_xml_saveToFile(s)" dll_functions[8] = "s d3ws_xml_loadFromFile(s)" dll_functions[9] = "s d3ws_http_addParameter(s,s)" dll_functions[10] = "s d3ws_http_setTraceFile(s)" dll_functions[11] = "s d3ws_http_sendRequest(s)" dll_functions[12] = "s d3ws_http_getTraceData()" dll_functions[13] = "s d3ws_xml_setRootNode()" dll_functions[14] = "s d3ws_xml_setParentNode()" dll_functions[15] = "s d3ws_xml_setNode(s)" dll_functions[16] = "i d3ws_xml_countNodes()" dll_functions[17] = "s d3ws_xml_getNodeName(i)" dll_functions[18] = "s d3ws_xml_getNodeValue(s)" dll_functions[19] = "s d3ws_stopSession()" dll_functions[20] = "" dll_step = "Loading of DLL :dll_name" dll_error = sm_slib_load(dll_name) for i=1 while i<100 step 1 { if ( dll_functions[i] == "" ) break if ( dll_error == 0 ) { t = dll_functions[i] fct_type = t(1,1) fct_name = t(3,100) dll_step = "Registration of function :fct_name (type=:fct_type)" if ( fct_type == "i" ) dll_error = sm_slib_install(fct_name, SLIB_C, SLIB_INTFNC) else dll_error = sm_slib_install(fct_name, SLIB_C, SLIB_STRFNC) } } if ( dll_error != 0 ) { call api_log_error ("ERROR while loading of DLL :dll_name") call api_log_error ("dll_step = :dll_step") call api_log_error ("dll_error = :dll_error") call api_log_error ("sm_slib_error = "##sm_slib_error()) return -1 } call api_log_info ("DLL :dll_name has been loaded and registrated sucessfully") return 0 }//end of load_webservice_dll //--------------------------------------------------------------------------------------------------------------------------------------------------- // calculates days till escalation plus weekends //--------------------------------------------------------------------------------------------------------------------------------------------------- proc calculateWorkDaysInAbsoluteDays( pCountDays ) { vars lReturnValue, lInitialEscalationDays, lRemainingEscalationDays, lDaysTillWeekend, lCountFullWeeks, lWeekdays, lCurrentDay lInitialEscalationDays = pCountDays lWeekdays = 5 lCurrentDay = sm_sdtime("n%.d") lDaysTillWeekend = 7 - lCurrentDay if( lDaysTillWeekend > lInitialEscalationDays ) { return lInitialEscalationDays } else { lRemainingEscalationDays = lInitialEscalationDays - lDaysTillWeekend // Escalation days after first weekend lCountFullWeeks = lRemainingEscalationDays / lWeekdays lReturnValue = api_function( "string_split", lCountFullWeeks, "." ) if( lReturnValue > 0 ) { lCountFullWeeks = api_splitted_string[1] } lRemainingEscalationDays = calcModulo( lRemainingEscalationDays, lWeekdays ) lReturnValue = lDaysTillWeekend + 2 + ( lCountFullWeeks * 7 ) + lRemainingEscalationDays return lReturnValue } }// end of calculateWorkDaysInAbsoluteDays //--------------------------------------------------------------------------------------------------------------------------------------------------- // calcModulo-Function (Rest of division) //--------------------------------------------------------------------------------------------------------------------------------------------------- proc calcModulo( pDivident, pDivisor ) { vars lReturnValue, lCount lCount = pDivident/pDivisor lReturnValue = api_function( "string_split", lCount, "." ) if( lReturnValue > 0 ) { lCount = api_splitted_string[1] } lReturnValue = pDivident - (pDivisor * lCount) return lReturnValue }// end of calcModulo