////////////////////////////////////////////////////////////////////////////////
// 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
