diff --git a/Assmann/11_definitions_dbs_invoiceworkflow.jpl b/Assmann/11_definitions_dbs_invoiceworkflow.jpl new file mode 100644 index 0000000..a102fa4 --- /dev/null +++ b/Assmann/11_definitions_dbs_invoiceworkflow.jpl @@ -0,0 +1,227 @@ +//////////////////////////////////////////////////////////////////////////////// +// Hook +// => Definition of variables +// File-Encoding: UTF-8 without BOM( Test: ü,ä,ö ) +//------------------------------------------------------------------------------ +// Created/Edited | Description +//------------------------------------------------------------------------------ +// 08.2017 | dbs | invoice workflow 1.1.0 +//////////////////////////////////////////////////////////////////////////////// + +// WFL PROCESS ID +global gDBS_INVOICE_WFL_ID = "5utr82engsp9i09ljpf5gsk4jm" + +// USERGROUPS (GRP) ( has to be ID !!! ) +global gGRP_CLEARING = "Accounting" +global gGRP_ACCOUNTING = "Accounting" + +// DOCUMTENT TYPES (DTS) +global gDTS_INVOICE = "DERGS" // Document type short name for: Eingangsrechnung/Grutschrift +global gDTS_INVOICE_ATTACHMENT = "DREAN" // Document type short name for: Rechnungsanlage +global gDTS_CREDITOR_TRANS_FOLDER = "AKRVG" // Document type short name for: Kreditorenvorgangsakte +global gDTS_CREDITOR_FOLDER = "AKR" // Document type short name for: Kreditorenakte + +// ATTRIBUTE FIELD NUMBERS (DDF) +global gDDF_CONTACT_ID = 81 +global gDDF_CONTACT_NAME = 43 +global gDDF_STREET = 14 //3 +global gDDF_ZIP = 9 //4 +global gDDF_CITY = 10 //5 +global gDDF_COUNTRY = 15 //6 +global gDDF_INVOICE_ID = 21 //7 +global gDDF_INVOICE_TYPE = 8 +global gDDF_DOCUMENT_CATEGORY = 4 //9 +global gDDF_COMPANY_CODE = 5 //10 +global gDDF_CURRENCY = 11 +global gDDF_ERP_ID = 12 +global gDDF_WFL_STATUS = 13 +global gDDF_WFL_STEP = 3 //14 +global gDDF_CLIENT = 31 //15 +global gDDF_TRANSACTION_ID = 2 +global gDDF_STORAGE = 18 +global gDDF_ACCOUNT_DESCRIPTION = 19 + + +global gDDF_DESCRIPTION = 23 +global gDDF_DEPARTMENT = 35 + +global gDDF_GUID = 47 +global gDDF_SYSTEM_ID = 48 +global gDDF_TECH_ID = 49 + +global gDDF_INVOICE_DATE = 52 +global gDDF_DELIVERY_DATE = 54 +global gDDF_ACCOUNTING_DATE = 50 +global gDDF_PAYED_DATE = 53 +global gDDF_CAPTURE_DATE = 51 + +global gDDF_COST_CENTER = 60 +global gDDF_GL_ACCOUNT = 61 +global gDDF_INTERNAL_ORDER = 62 +global gDDF_DESCRIPTION_LONG = 63 +global gDDF_NET_VALUE = 64 +global gDDF_COST_UNIT = 65 +global gDDF_VERIFIER_STAMP = 66 +global gDDF_MWST_PRODUCT_GROUP = 67 +global gDDF_WFL_MEMBER = 68 +global gDDF_MWST_COMPANY_GROUP = 69 + +global gDDF_APPROVER_STAMP = 99 +global gDDF_APPROVER_STAMP_2ND_LVL = 99 +global gDDF_TAX_KEY = 99 + +global gDDF_GROSS_AMOUNT = 70 +global gDDF_NET_AMOUNT = 71 +global gDDF_TAX_AMOUNT = 72 + + +// GENERAL MODIFICATION FLAGS (GMF) +global gGMF_FORCE_CLEARING_STEP = "0" // Step clearing is forced +global gGMF_FORCE_ACCOUNTING_STEP = "0" // Step accounting is forced +global gGMF_MULTILEVEL_APPROVAL = "0" // Multilevel approval is activated +global gGMF_FIT_MULTILVL_APPROVAL = "1" // Multilevel approval goes not through all levels, just to highest fitting level +global gGMF_DIRECT_ERP_ACCOUNTING = "0" // Direct accounting into ERP-System +global gGMF_REFUSE_IN_CHECK = "0" // Refuse of Invoice in step check enabled +global gGMF_BALANCE_NET_OR_GROSS = "n" // Interpretation of net or gross positions for calculation of balance (n, g) -> when calculation is configured for net amounts, the accounting step should be configures as necessary in gGMF_ACTIVE_ACCOUNTING_STEP +global gGMF_REFUSE_IN_ACCOUNTING = "0" // Refuse of Invoice in step enabled +global gGMF_4_EYES_PRINCIPLE = "0" // 4-Eyes-Principle activated +global gGMF_CHECK_DUPLICATES = "1" // Determination of dublicates activated +global gGMF_REFUSAL_INFORM_USER = "0" // User can be manually informed about refusal of invoice +global gGMF_REFUSAL_INFORM_GROUP = "RefusalI" // Group with all users/groups that can be informed about refusal of invoice +global gGMF_ROUND_DIFF_AUTOMATIC = "0" // Shall rounding differences be balanced automatically +global gGMF_ROUND_DIFF_TOLERANCE = "5" // Maximum difference for automatic balance of rounding differences in cents + +// GENERAL MODIFICATION FLAGS: Force client or company_code +global gGMF_CLIENT_EXISTS = "1" // When client is forced field will be automatically filled and not be shown in wfl +global gGMF_COMPANY_CODE_EXISTS = "0" // When company_code is forced field will be automatically filled and not be shown in wfl + +// GENERAL MODIFICATION FLAGS: DETERMINATION OF VERIFIER AND APPROVER +global gGMF_PRIO_COST_CENTER = "1" // Priority of cost_center within determination of verifier and approver (1 - 4) +global gGMF_PRIO_GL_ACCOUNT = "3" // Priority of gl_account within determination of verifier and approver (1 - 4) +global gGMF_PRIO_INTERNAL_ORDER = "2" // Priority of internal_order within determination of verifier and approver (1 - 4) +global gGMF_PRIO_COST_UNIT = "4" // Priority of cost_unit within determination of verifier and approver (1 - 4) +global gGMF_NET_OR_GROSS = "n" // Interpretation of net or gross amount within determination of verifier and approver (n, g) +global gGMF_MANUALLY_CHOICE_1 = "1" // Manually choice of verifier and approver on first level (0,1) + +// GENERAL MODIFICATION FLAGS: MODIFICATION RELEVANT ATTRIBUTES IN ACCOUNTING +global gGMF_ADD_ROWS_ACCOUNTING = "1" // User in accounting is allowed to add new rows proof and verify them an reduce amounts of other line items +global gGMF_MODR_COST_CENTER = "0" // Is modification of cost_center in position data relevant for return to step check +global gGMF_MODR_COST_UNIT = "0" // Is modification of cost_unit in position data relevant for return to step check +global gGMF_MODR_GL_ACCOUNT = "0" // Is modification of gl_account in position data relevant for return to step check +global gGMF_MODR_INTERNAL_ORDER = "0" // Is modification of internal_order in position data relevant for return to step check +global gGMF_MODR_POS_NET_VALUE = "0" // Is modification of net_value in position data relevant for return to step check +global gGMF_MODR_POS_GROSS_VALUE = "0" // Is modification of gross_value in position data relevant for return to step check +global gGMF_MODR_CLIENT = "0" // Is modification of client in header data relevant for return to step check +global gGMF_MODR_CREDITOR = "0" // Is modification of creditor in header data relevant for return to step check +global gGMF_MODR_COMPANY_CODE = "0" // Is modification of company_code in header data relevant for return to step check +global gGMF_MODR_INV_GROSS_VALUE = "0" // Is modification of gross_value in header data relevant for return to step check + +// GENERAL MODIFICATION FLAGS: ESCALTION RELEVANT CONFIGURATIONS +global gGMF_ESCAL_TIME_CLEARING = 0 // Days until escalation happens in step clearing +global gGMF_ESCAL_TIME_CHECK = 7 // Days until escalation happens in step check +global gGMF_ESCAL_TIME_APPROVAL_1 = 7 // Days until escalation happens in step approval of position data +global gGMF_ESCAL_TIME_APPROVAL_N = 0 // Days until escalation happens in step approval of invoice +global gGMF_ESCAL_TIME_ACCOUNTING = 0 // Days until escalation happens in step accounting + +global gGMF_ESCAL_USER_CLEARING = "Accounting" // User or group to be informed about escalation in step clearing +global gGMF_ESCAL_USER_CHECK = "Accounting" // User or group to be informed about escalation in step check +global gGMF_ESCAL_USER_APPROVAL_1 = "Accounting" // User or group to be informed about escalation in step approval of position data +global gGMF_ESCAL_USER_APPROVAL_N = "Accounting" // User or group to be informed about escalation in step approval of invoice +global gGMF_ESCAL_USER_ACCOUNTING = "Accounting" // User or group to be informed about escalation in step accounting + +// GENERAL MODIFICATION FLAGS: FOR AUTO TRANSACTION ID GENERATION +global gGMF_TRANSACTION_ID_PRAEFIX = "RE" // Prefix of automaticly generated transaction id +global gGMF_TRANSACTION_ID_SIZE = 6 // Length of leading nulls in transaction id counter + +// GENERAL MODIFICATION FLAGS: SMTP SERVER +global gGMF_SEND_QUEST_MAIL = "0" // Shall mails be send when receiving answer in question function +global gGMF_SMTP_SERVER = "" // SMTP-Server for mail sending + +// GENERAL MODIFICATION FLAGS: FOR ERP INTERFACE +global gGMF_CALL_INTERFACE = "1" // Shall the ERP-Interface be called in workflow or not +global gGMF_ERP_VALIDATE_POS_DATA = "0" // Validate item lines against ERP-System +global gGMF_ERP_WRITE_LAST_STEP = "0" // only write or book records in last step of workflow into ERP-System +global gGMF_CONFIG_INTERFACE = "NAVContext.xml" // Name of interface configuration file +global gGMF_WEB_SERVICE_URL = "http\://localhost\:8081/DecsERPServlet/DecsERPServlet" // webservice url (wfWebServiceURL) +global gDBS_RET_CODE_SERVLET_JAVA = "" +global gDBS_RET_MSG_SERVLET_JAVA = "" + +// GENERAL MODIFICATION FLAGS: FOR ERP CONNECTION VIA HOOK -> see 51_erp_dbs_invoice.jpl +global gGMF_GET_ERP_META_DATA_HOOK = "1" // Shall the meta data be loaded from erp system + +// GENERAL MODIFICATION FLAGS: FOR DATABASE TYPE AND SCHEME NAME +vars lGMF_DATABASE_ARRAY[3] = { "MSSQL", "ORACLE", "DB2" } // init array for database type +vars lGMF_DATABASE_TYPE_ID = 1 // Microsoft SQL: 1, Oracle: 2, DB2: 3, configure the database type +global gGMF_DATABASE_TYPE = lGMF_DATABASE_ARRAY[lGMF_DATABASE_TYPE_ID] + +global gGMF_SCHEME_NAME = "" //Scheme name of master data tables in masterdatabase, necessary for DB2 +global gGMF_SCHEME_NAME_RUN_TIME = "" //Scheme name of run-time data tables in database, necessary for DB2 + +//GENERAL MODIFICATION FLAGS : FOR TABLE NAMES OF RUN-TIME DATA TABLES +global gGMF_TABLE_CHECK_FST_APPR = "dbs_inv_auth_check_fst_appr" +global gGMF_TABLE_SND_APPROVAL = "dbs_inv_auth_snd_approval" +global gGMF_TABLE_CUSTOM_COUNTER = "dbs_inv_custom_counter" + +//GENERAL MODIFICATION FLAGS : FOR TABLE NAMES OF MASTER DATA TABLES +global gGMF_TABLE_CREDITORS = "dbs_inv_creditors" +global gGMF_TABLE_COMPANY_CODE = "dbs_inv_company_code" +global gGMF_TABLE_CURRENCIES = "dbs_inv_currencies" +global gGMF_TABLE_COST_CENTERS = "dbs_inv_cost_centers" +global gGMF_TABLE_COST_UNITS = "dbs_inv_cost_unit" +global gGMF_TABLE_GL_ACCOUNT = "dbs_inv_gl_account" +global gGMF_TABLE_INTERNAL_ORDERS = "dbs_inv_internal_orders" +global gGMF_TABLE_PAYMENT_TERMS = "dbs_inv_payment_terms" +global gGMF_TABLE_TAX_KEY = "dbs_inv_tax_key" + +// WORKFLOW (WFL) +// !!! specified in dataset +global gSTORAGE_WORKFLOW = "dbsInvoiceWorkflow" +global gSTORAGE_ARCHIVE = "dbsInvoiceArchive" +// !!! wfl_steps are specified in dataset +global gWFL_STEP_UNDEFINED = "Undefined" +global gWFL_STEP_CLEARING = "dbsInvoiceClearing" +global gWFL_STEP_CHECK = "dbsInvoiceCheck" +global gWFL_STEP_APPROVAL = "dbsInvoiceApproval" +global gWFL_STEP_ACCOUNTING = "dbsInvoiceAccounting" + +// !!! wfl_status are specified in dataset +global gWFL_STATUS_NEW = "dbsInvoiceNew" +global gWFL_STATUS_IN_PROGRESS = "dbsInvoiceInProgress" +global gWFL_STATUS_FINISHED = "dbsInvoiceFinished" +global gWFL_STATUS_REFUSED = "dbsInvoiceRefused" +global gWFL_STATUS_SEND_TO_ERP = "dbsInvoiceSendToERP" +global gWFL_STATUS_ACCOUNTED = "dbsInvoiceAccounted" + +vars lWFL_TITLE_CLRG_ARRAY[2] // init array for titles of hold files in step clearing +vars lWFL_TITLE_CHEC_ARRAY[2] // init array for titles of hold files in step check +vars lWFL_TITLE_APPR_ARRAY[2] // init array for titles of hold files in step approval +vars lWFL_TITLE_ACCT_ARRAY[2] // init array for titles of hold files in step accounting + +lWFL_TITLE_CLRG_ARRAY[1] = "dbs|invoice workflow - Vorkontierung" // german title of hold files in step clearing +lWFL_TITLE_CHEC_ARRAY[1] = "dbs|invoice workflow - Sachliche Prüfung" // german title of hold files in step check +lWFL_TITLE_APPR_ARRAY[1] = "dbs|invoice workflow - Freigabe Stufe" // german title of hold files in step approval +lWFL_TITLE_ACCT_ARRAY[1] = "dbs|invoice workflow - Kontierung" // german title of hold files in step accounting + +lWFL_TITLE_CLRG_ARRAY[2] = "dbs|invoice workflow - Clearing" // english title of hold files in step clearing +lWFL_TITLE_CHEC_ARRAY[2] = "dbs|invoice workflow - Verification" // english title of hold files in step check +lWFL_TITLE_APPR_ARRAY[2] = "dbs|invoice workflow - Approval Level" // english title of hold files in step approval +lWFL_TITLE_ACCT_ARRAY[2] = "dbs|invoice workflow - Accounting" // english title of hold files in step accounting + +global gWFL_MAIN_LANGUAGE = 1 // German: 1, English: 2, configuration of title and history language in holdfiles +global gWFL_TITLE_CLEARING = lWFL_TITLE_CLRG_ARRAY[gWFL_MAIN_LANGUAGE] // configured title of hold files in step clearing +global gWFL_TITLE_CHECK = lWFL_TITLE_CHEC_ARRAY[gWFL_MAIN_LANGUAGE] // configured title of hold files in step check +global gWFL_TITLE_APPROVAL = lWFL_TITLE_APPR_ARRAY[gWFL_MAIN_LANGUAGE] // configured title of hold files in step approval +global gWFL_TITLE_ACCOUNTING = lWFL_TITLE_ACCT_ARRAY[gWFL_MAIN_LANGUAGE] // configured title of hold files in step accounting + +global gWFL_RESP_ADMIN_USER = "sa" // Workflow responsible +global gWFL_RESP_ESCAL_USER = "sa" // Total escalation responsible + +// ERROR CODES (ERR) +global gERR_IMPORT_DUPLICATE_ERR = 310 +global gERR_IMPORT_DUPLICATE_FOUND = 315 +global gERR_ERP_SVLT_WRITE_USER = 320 +global gERR_ERP_SVLT_WRITE_STATE = 325 +global gERR_ERP_SVLT_CREATE_RECORD = 330 + +// Loglevel +global gLOGLEVEL = 9 \ No newline at end of file diff --git a/Assmann/20_hook.jpl b/Assmann/20_hook.jpl new file mode 100644 index 0000000..a71a4e9 --- /dev/null +++ b/Assmann/20_hook.jpl @@ -0,0 +1,130 @@ +//////////////////////////////////////////////////////////////////////////////// +// General hooks for dbs | invoice +// File-Encoding: UTF-8 without BOM( Test: ü,ä,ö ) +//------------------------------------------------------------------------------ +// Created/Edited | Description +//------------------------------------------------------------------------------ +// 08.2017 | dbs | invoice workflow 1.1.0 +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +// InsertEntry10 +//------------------------------------------------------------------------------ +// dbs.invoice specific hooks +//------------------------------------------------------------------------------ +proc InsertEntry10( pUser, pDocTypeShort ) +{ + vars lReturnValue = 0 + lReturnValue = InsertEntry10_dbsInvoice( pUser, pDocTypeShort ) + + if( lReturnValue != 0 ) + { + return lReturnValue + } + + + +} //end of InsertEntry10 + +//------------------------------------------------------------------------------ +// InsertExit30 +//------------------------------------------------------------------------------ +// dbs.invoice specific hooks +//------------------------------------------------------------------------------ +proc InsertExit30( pDocId, pFileDestination, pImportOk, pUser, pDocTypeShort ) +{ + call InsertExit30_dbsInvoice( pDocId, pFileDestination, pImportOk, pUser, pDocTypeShort ) + +} //end of InsertExit30 + + +//------------------------------------------------------------------------------ +// UpdateAttribEntry20 +//------------------------------------------------------------------------------ +// Vorbereitung Start Rückfrage-WFL für Rechnungen, die aus dem NAV per upd-Datei +// in den Bemerkungsfeldern 1 & 2 eine Rückfrage übergeben wurde. +// Nicht dbs Invoice!!! +//------------------------------------------------------------------------------ +proc UpdateAttribEntry20( pDocId, pUser, pDocTypeShort, pDocTypeShortNew ) +{ + /* + //if (pDocTypeShort == gDTS_INVOICE && text[1] != "" && text[2] != "" ) + if (pDocTypeShort == gDTS_INVOICE && dok_dat_feld[gDDF_DEPARTMENT] != "" && dok_dat_feld[gDDF_DESCRIPTION] != "" ) + { + vars lEmpfaenger = dok_dat_feld[gDDF_DEPARTMENT] //text[1] + vars lNotiztext = dok_dat_feld[gDDF_DESCRIPTION] // text[2] + + //Schreiben der Empfaengergruppe in ddf 20 + dok_dat_feld[gDDF_DEPARTMENT] = lEmpfaenger + //Rückfragetext in die Notiz eintragen + SERVER_API_NO_HOOKS = 1 + vars lRueckgabe = api_function("note_add_string",lNotiztext, pDocId, "Master") + SERVER_API_NO_HOOKS = 0 + //msg emsg "lRuckgabe Notiz schreiben :lRueckgabe" + //msg emsg "lEmpfaenger :lEmpfaenger ddf20 :dok_dat_feld[20]" + } + */ +} + + +//------------------------------------------------------------------------------ +// UpdateAttribExit20 +//------------------------------------------------------------------------------ +// dbs.invoice specific hooks +//------------------------------------------------------------------------------ +proc UpdateAttribExit20( pDocId, pErrorNumber, pUser, pDocTypeShort ) +{ + call UpdAttribExit20_dbsInvoice( pDocId, pErrorNumber, pUser, pDocTypeShort ) + + if (pDocTypeShort == gDTS_INVOICE && dok_dat_feld[gDDF_DEPARTMENT] != "" && dok_dat_feld[gDDF_DESCRIPTION] != "") + { + //ID des Rückfrage-Workflows + vars lWflId = "14q28erod7ov9u3o155ahkn3kh" + //Rechnung bereits im WFL? + //vars lLeitwegAktiv = api_function("workpath_get_document_info", pDocId, "Master") + vars lLeitwegAktiv = api_function("attribute_get_all", pDocId, "Master") + //msg emsg "LeitwegAktiv = :lLeitwegAktiv" + //if (pDocTypeShort == gDTS_INVOICE && text[1] != "" && text[2] != "" && lLeitwegAktiv == -523 ) + + if ( api_doc_workflow == 0 ) + { + vars lEmpfaenger = dok_dat_feld[gDDF_DEPARTMENT] //text[1] + vars lNotiztext = dok_dat_feld[gDDF_DESCRIPTION] // text[2] + + //Schreiben der Empfaengergruppe in ddf 20 + //dok_dat_feld[gDDF_DEPARTMENT] = lEmpfaenger + //Rückfragetext in die Notiz eintragen + SERVER_API_NO_HOOKS = 1 + vars lRueckgabe = api_function("note_add_string",lNotiztext, pDocId, "Master") + SERVER_API_NO_HOOKS = 0 + //msg emsg "lRuckgabe Notiz schreiben :lRueckgabe" + //msg emsg "lEmpfaenger :lEmpfaenger ddf20 :dok_dat_feld[20]" + + vars lRueckgabe = api_function("workpath_start_document", lWflId, pDocId, "" ) + if (lRueckgabe == 0) + { + call api_log_info("Rueckfrage-WFL fuer Dokument :pDocId erfolgreich gestartet") + //call api_log_info("Rueckfrage-WFL :pDocId gDDF_DEPARTMENT :dok_dat_feld[gDDF_DEPARTMENT] gDDF_DESCRIPTION :dok_dat_feld[gDDF_DESCRIPTION]") + } + else + { + call api_log_error("FEHLER :lRueckgabe Rueckfrage-WFL konnte für Dokument :pDocId nicht gestartet werden!!!") + } + } + SERVER_API_NO_HOOKS = 1 + call api_function("attribute_update_single", gDDF_DEPARTMENT, "",0, pDocId, "Master") + call api_function("attribute_update_single", gDDF_DESCRIPTION, "",0, pDocId, "Master") + SERVER_API_NO_HOOKS = 0 + } + +}// end of UpdateAttribExit20 + +//------------------------------------------------------------------------------ +// LinkExit10 +//------------------------------------------------------------------------------ +// dbs.invoice specific hooks +//------------------------------------------------------------------------------ +proc LinkExit10( pDocIdFather, pDocIdChild, pErrorCode, pErrorNumber ) +{ + call LinkExit10_dbsInvoice( pDocIdFather, pDocIdChild, pErrorCode, pErrorNumber ) +}// end of LinkExit10 \ No newline at end of file diff --git a/Assmann/21_hook_dbs_invoiceworkflow.jpl b/Assmann/21_hook_dbs_invoiceworkflow.jpl new file mode 100644 index 0000000..a2d5e3a --- /dev/null +++ b/Assmann/21_hook_dbs_invoiceworkflow.jpl @@ -0,0 +1,309 @@ +//////////////////////////////////////////////////////////////////////////////// +// Hook for dbs | invoice +// => Hooks for insert and update of invoice documents +// File-Encoding: UTF-8 without BOM( Test: ü,ä,ö ) +//------------------------------------------------------------------------------ +// Created/Edited | Description +//------------------------------------------------------------------------------ +// 08.2017 | dbs | invoice workflow 1.1.0 +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +// InsertEntry10_dbsInvoice +/*------------------------------------------------------------------------------ +// docType Invoice: +// - get creditor master data +// - check of duplicates +// - default value 'today' for capture date and delivery date +// docType Invoice Attachment: +// [ - copy attributes of vendor transaction folder ( is configured in d.3 administration! )] +//------------------------------------------------------------------------------ +*/ +proc InsertEntry10_dbsInvoice( pUser, pDocTypeShort ) +{ + call api_log( gLOGLEVEL, "Start of InsertEntry10_dbsInvoice( :pUser, :pDocTypeShort )" ) + vars lReturnValue = 0 + + // when doctype short is equal invoice + if ( pDocTypeShort == gDTS_INVOICE ) + { + // get meta data from ERP-System (will only called if modified in 11_defintions_dbs_invoice.jpl) + lReturnValue = getMetaDataFromERP() + if( lReturnValue != 0 ) + { + return lReturnValue + } + + // update / validate creditor master data + call updateCreditorData( "" ) + + // determine if check of duplicates is required + if ( gGMF_CHECK_DUPLICATES == "1" ) + { + vars lYear = dok_dat_feld[ gDDF_INVOICE_DATE ](7,4) // Format in d.3 always is '%0d.%0m.%4y %0h:%0M:%0s' or '%0d.%0m.%4y' + + if ( dok_dat_feld[ gDDF_CONTACT_ID ] != "" && dok_dat_feld[ gDDF_INVOICE_ID ] != "" && lYear != "" ) + { + lReturnValue = checkDuplicates( dok_dat_feld[ gDDF_CONTACT_ID ], dok_dat_feld[ gDDF_INVOICE_ID ], lYear, "" ) + + if ( lReturnValue != 0 ) + { + return lReturnValue + } + } + else + { + call api_log_info("missing mandatory fields for checkDuplicates") + } + } + + // determine if capture date is empty + if ( dok_dat_feld[ gDDF_CAPTURE_DATE ] == "" ) + { + // default = today -> Format in d.3 always is '%0d.%0m.%4y %0h:%0M:%0s' or '%0d.%0m.%4y' + dok_dat_feld[ gDDF_CAPTURE_DATE ] = sm_sdtime(" %0d.%0m.%4y") + } + + // determine if delivery date is empty + if ( dok_dat_feld[ gDDF_DELIVERY_DATE ] == "" ) + { + // default = today -> Format in d.3 always is '%0d.%0m.%4y %0h:%0M:%0s' or '%0d.%0m.%4y' + dok_dat_feld[ gDDF_DELIVERY_DATE ] = sm_sdtime(" %0d.%0m.%4y") + } + + // determine if status is empty + if ( dok_dat_feld[ gDDF_WFL_STATUS ] == "" && dok_dat_feld[ gDDF_STORAGE ] == gSTORAGE_WORKFLOW ) + { + // default = gWFL_STATUS_NEW + dok_dat_feld[ gDDF_WFL_STATUS ] = gWFL_STATUS_NEW + } + + // DIW-211 + vars lTaxValue, lCounter, lArrayLength, lTaxIDMasterData, lSchemeClause + vars lIsString, lWhereClause + + //add scheme to from clause if set + if(gGMF_SCHEME_NAME_RUN_TIME != "") + { + lSchemeClause = ":(gGMF_SCHEME_NAME_RUN_TIME)." + } + else + { + lSchemeClause = "" + } + + lArrayLength = sm_n_num_occurs("dok_dat_feld_:gDDF_TAX_KEY") + for lCounter = 1 while ( lCounter <= lArrayLength ) step 1 + { + lTaxValue = dok_dat_feld_:(gDDF_TAX_KEY)[ lCounter ] + if( lTaxValue != "" ) + { + lIsString = lTaxValue * 1 + // check if lTaxValue is string or number + if( lIsString != lTaxValue ) + { + lWhereClause = "id = :+lTaxValue" + } + else + { + lWhereClause = "value = :lTaxValue OR id = :+lTaxValue" + } + + DBMS ALIAS lTaxIDMasterData + DBMS SQL SELECT TOP 1 id FROM :(lSchemeClause):(gGMF_TABLE_TAX_KEY) \ + WHERE :lWhereClause + DBMS ALIAS + + if( lTaxIDMasterData != "" ) + { + dok_dat_feld_:(gDDF_TAX_KEY)[ lCounter ] = lTaxIDMasterData + } + } + } + // ende DIW-211 + } + else if ( pDocTypeShort == gDTS_INVOICE_ATTACHMENT ) + { + // update / validate creditor master data + call updateCreditorData( "" ) + } + + call api_log( gLOGLEVEL, "End of InsertEntry10_dbsInvoice" ) + + return 0 +} //end of InsertEntry10_dbsInvoice + +//------------------------------------------------------------------------------ +// InsertExit30_dbsInvoice +/*------------------------------------------------------------------------------ +// docType Invoice: +// - generation of transaction id +// docType Invoice Attachment: +// [ - link document with vendor transaction folder ( is configured in d.3 administration! no overwrite of existing documents )] +// - generation of transaction id +//------------------------------------------------------------------------------ +*/ +proc InsertExit30_dbsInvoice( pDocId, pFileDestination, pImportOk, pUser, pDocTypeShort ) +{ + call api_log( gLOGLEVEL, "Start of InsertExit30_dbsInvoice( :pUser, :pFileDestination, :pImportOk, :pUser, :pDocTypeShort )" ) + vars lReturnValue, lCount + + // generation of transaction id required? is invoice? transaction id empty? + if( pDocTypeShort == gDTS_INVOICE ) + { + //vars lNewTransactionId + // set newly generated transaction id to current document if generation of transaction id is configured + //lNewTransactionId = updateTransactionID( pDocId, pDocTypeShort ) + call updateTransactionID( pDocId, pDocTypeShort ) + + // find matching other documents and fill them with generated transaction id + // STEPS: 1. find all documents with current GUID, 2. fill all documents with current GUID with generated transaction id + + // 1. find all documents with current GUID + // delete API-Context + call api_clear_document_context() + + // set search criteria + api_doc_type_short = gDTS_INVOICE_ATTACHMENT + + if(dok_dat_feld[ gDDF_GUID ] != "") + { + api_doc_field[ gDDF_GUID ] = dok_dat_feld[ gDDF_GUID ] + + // execute function document_find_ids + lReturnValue = api_function ("document_find_ids", "") + if (lReturnValue == 0) + { + vars lFoundDocumentIds = api_single_info + api_single_info = "" + + // 2. fill all documents with current GUID with new transaction id + // run through all document ids with current GUID + for lCount = 1 while lCount <= lFoundDocumentIds step 1 + { + // in case of updating transaction id: stop hook execution + SERVER_API_NO_HOOKS = 1 + //call api_function( "attribute_update_single", gDDF_TRANSACTION_ID, lNewTransactionId, 0, api_doc_ids[lCount], "Master" ) + call api_function( "attribute_update_single", gDDF_TRANSACTION_ID, dok_dat_feld[ gDDF_TRANSACTION_ID ], 0, api_doc_ids[lCount], "Master" ) + SERVER_API_NO_HOOKS = 0 + } + } + else + { + call api_log_error("Error code :lReturnValue for document_find_ids in InsertExit30_dbsInvoice!") + } + } + + // create record in erp and start workflow (will only called if modified in 51_erp_dbs_rechnungsworkflow.jpl) + lReturnValue = createRecordInERP( pDocId ) + + if( lReturnValue != 0 ) + { + return lReturnValue + } + } + else + { + // find matching other documents and fill them with transaction id + // STEPS: 1. find all documents with current GUID, 2. find valid transaction id for GUID, 3. fill current document with valid transaction id + if ( pDocTypeShort == gDTS_INVOICE_ATTACHMENT && dok_dat_feld[ gDDF_TRANSACTION_ID ] == "" ) + { + vars lReturnValue // errorcode + vars lCount // counter + vars lTransactionId = "" + // delete API-Context + call api_clear_document_context() + + // 1. find all documents with current GUID + // set search criteria + api_doc_type_short = gDTS_INVOICE + api_doc_field[ gDDF_GUID ] = dok_dat_feld[ gDDF_GUID ] + + // execute function document_find_ids + lReturnValue = api_function ("document_find_ids", "") + + // 2. find valid transaction id for GUID + // run through all document ids with current GUID + if (lReturnValue == 0) + { + vars lFoundDocumentIds = api_single_info + api_single_info = "" + + call api_log_info(":lFoundDocumentIds Document-IDs for current GUID have been found!") + + for lCount = 1 while lCount <= lFoundDocumentIds step 1 + { + // call api_log_info("doc_id :lCount: :api_doc_ids[lCount]") + lReturnValue = api_function( "attribute_get_single", gDDF_TRANSACTION_ID, 0, api_doc_ids[lCount], "Master" ) + if( lReturnValue == 0 && api_single_info != "" ) + { + lTransactionId = api_single_info + break + } + } + + // 3. fill document with valid transaction id + if( lTransactionId != "" ) + { + // run through all document ids with current GUID + // in case of updating transaction: stop hook execution + SERVER_API_NO_HOOKS = 1 + call api_function( "attribute_update_single", gDDF_TRANSACTION_ID, lTransactionId, 0, pDocId, "Master" ) + SERVER_API_NO_HOOKS = 0 + } + } + else + { + call api_log_error("Error code :lReturnValue for document_find_ids in InsertExit30_dbsInvoice!") + } + } + } + + call api_log( gLOGLEVEL, "End of InsertExit30_dbsInvoice" ) + + return 0 +} //end of InsertExit30_dbsInvoice + + +//------------------------------------------------------------------------------ +// LinkExit10_dbsInvoice +/*------------------------------------------------------------------------------ +// docType Invoice and Attachment: +// - copy multval attributes to all corresponding invoice attachments +// - set net_amount, gross_amount and tax_amount always to 0 when values equal null +//------------------------------------------------------------------------------ +*/ +proc LinkExit10_dbsInvoice( pDocIdFather, pDocIdChild, pErrorCode, pErrorNumber ) +{ + call api_log( gLOGLEVEL, "Start of LinkExit10_dbsInvoice( :pDocIdFather, :pDocIdChild, :pErrorCode, :pErrorNumber )" ) + call inheritImpCrdTrsFldAttr( pDocIdFather, pDocIdChild ) + call api_log( gLOGLEVEL, "End of LinkExit10_dbsInvoice" ) +} + +//------------------------------------------------------------------------------ +// UpdateAttribExit20_dbsInvoice +/*------------------------------------------------------------------------------ +// docType Invoice: +// - copy multval attributes to all corresponding invoice attachments +// - set net_amount, gross_amount and tax_amount always to 0 when values equal null +//------------------------------------------------------------------------------ +*/ +proc UpdAttribExit20_dbsInvoice( pDocId, pErrorNumber, pUser, pDocTypeShort ) +{ + call api_log( gLOGLEVEL, "Start of UpdAttribExit20_dbsInvoice( :pDocId, :pErrorNumber, :pUser, :pDocTypeShort, :dokuart_kurz )" ) + + // Update successfull ? + if ( pErrorNumber == 0 ) + { + if ( dokuart_kurz == gDTS_INVOICE ) + { + // inherit creditor transaction folder attributes + call inheritCrdTrsFldAttributes( pDocId, dokuart_kurz, "" ) + // update creditor master data + call updateCreditorData( pDocId ) // not necessary anymore, only write creditor data in import + } + } + call api_log( gLOGLEVEL, "End of UpdAttribExit20_dbsInvoice" ) + + return 0 +}// end of UpdAttribExit20_dbsInvoice \ No newline at end of file diff --git a/Assmann/31_sets_dbs_invoiceworkflow.jpl b/Assmann/31_sets_dbs_invoiceworkflow.jpl new file mode 100644 index 0000000..64ae554 --- /dev/null +++ b/Assmann/31_sets_dbs_invoiceworkflow.jpl @@ -0,0 +1,191 @@ +//////////////////////////////////////////////////////////////////////////////// +// Hook for dbs | invoice +// => Sets for user in d.3 admin +// File-Encoding: UTF-8 without BOM( Test: ü,ä,ö ) +//------------------------------------------------------------------------------ +// Created/Edited | Description +//------------------------------------------------------------------------------ +// 08.2017 | dbs | invoice workflow 1.1.0 +//////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ +// Dynamic value sets +/*------------------------------------------------------------------------------ +// - GetCurrency +// - GetCreditorNo +// - GetCreditorName +// - GetCompanyCode +// - GetClient +//------------------------------------------------------------------------------ +*/ +proc GetCurrency( pReposId, pUser, pDocTypeShort, pRowNo ) +{ + vars lFromClause + //add scheme to from clause if set + if(gGMF_SCHEME_NAME != "") + { + lFromClause = ":(gGMF_SCHEME_NAME).:(gGMF_TABLE_CURRENCIES)" + } + else + { + lFromClause = ":gGMF_TABLE_CURRENCIES" + } + + DBMS ALIAS d3server_value_char_allowed, d3server_repos_id_allowed + DBMS SQL SELECT DISTINCT iso, \ + :pReposId \ + FROM :lFromClause \ + ORDER BY iso + DBMS ALIAS +}//end of GetCurrency + +proc GetCreditorNo( pReposId, pUser, pDocTypeShort, pRowNo ) +{ + vars lWhereClause = "", lContactId = "", lClient = "", lCompanyCode = "", lContactName = "", lFromClause + + lContactId = dok_dat_feld[ gDDF_CONTACT_ID ] + + // add wildcard + lContactId = lContactId ## "%" + lWhereClause = "WHERE creditor_no LIKE :+lContactId" + + // if company code is known add to where-clause + lCompanyCode = dok_dat_feld[ gDDF_COMPANY_CODE ] + if ( lCompanyCode != "" ) + { + lWhereClause = lWhereClause ## " AND company_code = :+lCompanyCode " + } + + // if name is known add to where-clause + lContactName = dok_dat_feld[ gDDF_CONTACT_NAME ] + if ( lContactName != "" ) + { + lContactName = lContactName ## "%" + lWhereClause = lWhereClause ## " AND name LIKE :+lContactName " + } + + // if client is known add to where-clause + lClient = dok_dat_feld[ gDDF_CLIENT ] + if ( lClient != "" ) + { + lWhereClause = lWhereClause ## " AND client = :+lClient " + } + + //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 d3server_value_char_allowed, d3server_repos_id_allowed + DBMS SQL SELECT DISTINCT creditor_no, \ + :pReposId \ + FROM :lFromClause :lWhereClause \ + ORDER BY creditor_no + DBMS ALIAS +}//end of GetCreditorNo + +proc GetCreditorName( pReposId, pUser, pDocTypeShort, pRowNo ) +{ + vars lWhereClause = "", lContactName = "", lClient = "", lCompanyCode = "", lContactId = "", lFromClause + + lContactName = dok_dat_feld[ gDDF_CONTACT_NAME ] + + // add wildcard + lContactName = lContactName ## "%" + lWhereClause = "WHERE name LIKE :+lContactName" + + // if company code is known add to where-clause + lCompanyCode = dok_dat_feld[ gDDF_COMPANY_CODE ] + if ( lCompanyCode != "" ) + { + lWhereClause = lWhereClause ## " AND company_code = :+lCompanyCode " + } + + // if client is known add to where-clause + lClient = dok_dat_feld[ gDDF_CLIENT ] + if ( lClient != "" ) + { + lWhereClause = lWhereClause ## " AND client = :+lClient " + } + + // if creditor_no is known add to where-clause + lContactId = dok_dat_feld[ gDDF_CONTACT_ID ] + if ( lContactId != "" ) + { + lWhereClause = lWhereClause ## " AND creditor_no = :+lContactId " + } + + //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 d3server_value_char_allowed, d3server_repos_id_allowed + DBMS SQL SELECT DISTINCT name, \ + :pReposId \ + FROM :lFromClause :lWhereClause \ + ORDER BY name + DBMS ALIAS +}//end of GetCreditorName + +proc GetClient( pReposId, pUser, pDocTypeShort, pRowNo ) +{ + vars lFromClause + + //add scheme to from clause if set + if(gGMF_SCHEME_NAME != "") + { + lFromClause = ":(gGMF_SCHEME_NAME).:(gGMF_TABLE_COMPANY_CODE)" + } + else + { + lFromClause = ":gGMF_TABLE_COMPANY_CODE" + } + DBMS ALIAS d3server_value_char_allowed, d3server_repos_id_allowed + DBMS SQL SELECT DISTINCT client_id, \ + :pReposId \ + FROM :lFromClause \ + ORDER BY client_id + DBMS ALIAS +}//end of GetClient + +proc GetCompanyCode( pReposId, pUser, pDocTypeShort, pRowNo ) +{ + //CompanyCode depends on Client + vars lFromClause, lWhereClause, lClient + + lWhereClause = "" + lClient = dok_dat_feld[ gDDF_CLIENT ] + + if ( lClient != "" ) + { + lWhereClause = "WHERE client_id = :+lClient" + } + + //add scheme to from clause if set + if(gGMF_SCHEME_NAME != "") + { + lFromClause = ":(gGMF_SCHEME_NAME).:(gGMF_TABLE_COMPANY_CODE)" + } + else + { + lFromClause = ":gGMF_TABLE_COMPANY_CODE" + } + + DBMS ALIAS d3server_value_char_allowed, d3server_repos_id_allowed + DBMS SQL SELECT DISTINCT company_id, \ + :pReposId \ + FROM :lFromClause :lWhereClause \ + ORDER BY company_id + DBMS ALIAS +}//end of GetCompanyCode diff --git a/Assmann/41_functions_dbs_invoiceworkflow.jpl b/Assmann/41_functions_dbs_invoiceworkflow.jpl new file mode 100644 index 0000000..d11323d --- /dev/null +++ b/Assmann/41_functions_dbs_invoiceworkflow.jpl @@ -0,0 +1,1152 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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 diff --git a/Assmann/51_erp_dbs_invoiceworkflow.jpl b/Assmann/51_erp_dbs_invoiceworkflow.jpl new file mode 100644 index 0000000..51b7cb2 --- /dev/null +++ b/Assmann/51_erp_dbs_invoiceworkflow.jpl @@ -0,0 +1,52 @@ +//////////////////////////////////////////////////////////////////////////////// +// Hook for dbs | invoice +// => ERP-Functions (Communication with ERP) +// File-Encoding: UTF-8 without BOM( Test: ü,ä,ö ) +//------------------------------------------------------------------------------ +// Created/Edited | Description +//------------------------------------------------------------------------------ +// 08.2017 | dbs | invoice workflow 1.1.0 +//////////////////////////////////////////////////////////////////////////////// + +vars lGMF_ERP_SYSTEMS[2] = { "XML", "WCS2" } // init array for erp system types + +//--------------------------------------------------------------------------------------------------------------------------------------------------- +// general ERP Configurations +//--------------------------------------------------------------------------------------------------------------------------------------------------- +global gGMF_ERP_SYSTEM = lGMF_ERP_SYSTEMS[1] // XML: 1, WCS2: 2 configure the erp type + +//--------------------------------------------------------------------------------------------------------------------------------------------------- +// getMetaDataFromERP +//--------------------------------------------------------------------------------------------------------------------------------------------------- +proc getMetaDataFromERP() +{ + vars lReturnValue = 0 + if( gGMF_GET_ERP_META_DATA_HOOK == "1" ) + { + } + + return lReturnValue +} // end of getMetaDataFromERP + +//--------------------------------------------------------------------------------------------------------------------------------------------------- +// createRecordInERP +//--------------------------------------------------------------------------------------------------------------------------------------------------- +proc createRecordInERP( pDocId ) +{ + vars lReturnValue = 0 + vars lStorage + + lReturnValue = api_function( "attribute_get_single", gDDF_STORAGE, 0, pDocId, "Master" ) + if ( lReturnValue == 0 && api_single_info != "" ) + { + lStorage = api_single_info + } + + if( gGMF_ERP_SYSTEM == lGMF_ERP_SYSTEMS[2] && lStorage == gSTORAGE_WORKFLOW ) + { + // do WCS2 function create record and start workflow + return createRecordInWCS2( pDocId, gGMF_WEB_SERVICE_URL ) + } + + return lReturnValue +} // end of createRecordInERP diff --git a/Assmann/81_java_dbs_invoiceworkflow_v100.jpl b/Assmann/81_java_dbs_invoiceworkflow_v100.jpl new file mode 100644 index 0000000..449b8b2 --- /dev/null +++ b/Assmann/81_java_dbs_invoiceworkflow_v100.jpl @@ -0,0 +1,188 @@ +//////////////////////////////////////////////////////////////////////////////// +// Hook for dbs | invoice +// => Java-Functions +// File-Encoding: UTF-8 without BOM( Test: ü,ä,ö ) +//------------------------------------------------------------------------------ +// Created/Edited | Description +//------------------------------------------------------------------------------ +// 16.01.2017 | dbs | invoice workflow 1.0.0.0 +// 06.11.2017 tott | Write State mit Langem Usernamen +//////////////////////////////////////////////////////////////////////////////// + +global gDBS_RET_CODE_SERVLET_JAVA = "" +global gDBS_RET_MSG_SERVLET_JAVA = "" + +//--------------------------------------------------------------------------------------------------------------------------------------------------- +// 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() + + vars lSplittedUsers // Number of returned values of function string_split + vars lUsersString = wfUser // string to be splitted + vars lCharSplitter = ";" // split character + vars lCount, h_ReturnValue + vars lUsers + + gDBS_RET_CODE_SERVLET_JAVA = "" + gDBS_RET_MSG_SERVLET_JAVA = "" + + call api_log_info ("Start Function Write State") + + lSplittedUsers = api_function ("string_split", lUsersString, lCharSplitter) + // Ergebnisausgabe + if( lSplittedUsers > 0 ) + { + call api_log_info ("String wfUsers was splitted in :lSplittedUsers Strings.") + + for lCount = 1 while( lCount <= lSplittedUsers ) step 1 + { + // Username anhand ; Splitten und Langnamen ermitteln + HIDE_API_ERROR_ONCE = "1" + h_ReturnValue = api_function ("user_get_data", api_splitted_string[ lCount ]) + + if ( h_ReturnValue == 0 ) + { + // das Komma erst setzen wenn ein User durch + if( lCount != 1 ) + { + lUsers = lUsers ## "; " + } + + // Umlaute umbennnen, da es sonst zu UTF8 Problemen kommt + h_ReturnValue = api_function ("string_replace", api_user_realname, "ä", "ae" ) + h_ReturnValue = api_function ("string_replace", api_converted_string, "ü", "ue" ) + h_ReturnValue = api_function ("string_replace", api_converted_string, "ö", "oe" ) + h_ReturnValue = api_function ("string_replace", api_converted_string, "Ä", "Ae" ) + h_ReturnValue = api_function ("string_replace", api_converted_string, "Ü", "Ue" ) + h_ReturnValue = api_function ("string_replace", api_converted_string, "Ö", "Oe" ) + + // Username Lang speichern + lUsers = lUsers ## api_converted_string + } + + } + } + + 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" ## "|" ## pDocId) // pDocId 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_info( "Error while creating xml request: " ## lReturnCode ) + call api_log_info( "Servlet returned error code: " ## gDBS_RET_CODE_SERVLET_JAVA ) + call api_log_info( "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_log_info ("START write_user.") + + 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_info( "Error while creating xml request: " ## lReturnCode ) + call api_log_info( "Servlet returned error code: " ## gDBS_RET_CODE_SERVLET_JAVA ) + call api_log_info( "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 \ No newline at end of file diff --git a/Assmann/Assmann_RM.jpl b/Assmann/Assmann_RM.jpl new file mode 100644 index 0000000..b96cd14 --- /dev/null +++ b/Assmann/Assmann_RM.jpl @@ -0,0 +1,713 @@ +// ##################################################################################### +// +// d.link for Microsoft Dynamics Nav 3.0 +// +// Raber+Märcker GmbH - 5.3.10 +// +// ##################################################################################### + +global vars h_NavOdbcSource +h_NavOdbcSource = "ERP" + +// doc-dat-field numbers +global vars h_DDF_SQUOTENO = 22 // sales quote number +global vars h_DDF_SORDERNO = 2 // sales order numbers +global vars h_DDF_BARCODE = 6 +global vars h_DDF_DTTEMP = 47 +global vars h_DDF_COMPANY = 0 + +// document types for folder links +global vars h_DT_SOCONF = "dakb" // order confirmation + +global vars h_EditUser = "RM" + +global vars h_UpdateAttributes = 1 + +vars h_ARRAY_MAX = 100 + +// ##################################################################################### +// hook_insert_entry_10_ass +// ##################################################################################### + +proc hook_insert_entry_05_ass(h_User, h_DocType) +{ + if ( h_DocType == "dkoak" ) + { + vars ergebnis + ergebnis = api_function( "string_split", dok_dat_feld[ 32 ], "--" ) + dok_dat_feld[ 32 ] = api_splitted_string[ 1 ] + + zeich_nr = dok_dat_feld[ 32 ] + + call xlog( 5, "zeich_nr " ## zeich_nr ) + call xlog( 5, "dok_dat_feld_32 " ## dok_dat_feld[ 32 ] ) + } +} + +proc hook_insert_entry_10_ass(h_User, h_DocType) +{ + vars lReturnValue + + lReturnValue = InsertEntry10( h_User, h_DocType ) + + if( lReturnValue != 0 ) + { + return lReturnValue + } + // eingefügt von calb/d.OS am 2012.11.08 + vars vorhandene_doku_id, vorhandenes_datum, anzahl_treffer, kampagne, v_dok_dat_feld_51 + + if ( h_DocType == "ddab" ) + { + + // Feststellen, ob das Dokument bereits im System vorhanden ist + dbms alias vorhandene_doku_id, v_dok_dat_feld_51 + dbms sql select doku_id, dok_dat_feld_51 from firmen_spezifisch where dok_dat_feld_2 = :+dok_dat_feld[2] and kue_dokuart = 'ddab' + + anzahl_treffer = @dmrowcount + dbms alias + + if ( anzahl_treffer == 0 ) + { + // Das Dokument existiert noch nicht im System + call xlog( 4, "Das Dokument mit der Nummer :dok_dat_feld[2] existiert noch nicht im System. " ) + + dbms declare ta_session connection for user 'Master' password 'geheim' datasource 'D3P' + + dbms with connection ta_session alias vorhandenes_datum, kampagne + dbms with connection ta_session sql select beleg_dat, kampagne from as_ab_import where auftrags_nr = :+dok_dat_feld[2] + anzahl_treffer = @dmrowcount + dbms with connection ta_session alias + + + + call xlog( 5, "Anzahl Treffer: <:anzahl_treffer> neues Datum: <:vorhandenes_datum> Kampagne: <:kampagne> Auftrags-Nr. <:dok_dat_feld[2]> " ) + + dok_dat_feld[51] = vorhandenes_datum + dok_dat_feld_60[1] = kampagne + + } + else if ( anzahl_treffer > 0 ) + { + // Das Dokument existiert schon im System + call xlog( 3, "Das Dokument mit der Nummer :dok_dat_feld[2] existiert bereits im System mit der Doku-ID <:vorhandene_doku_id> und dem Beleg-Datum <:v_dok_dat_feld_51>. " ) + dbms declare ta_session connection for user 'Master' password 'geheim' datasource 'D3P' + + dbms with connection ta_session alias vorhandenes_datum, kampagne + dbms with connection ta_session sql select beleg_dat, kampagne from as_ab_import where auftrags_nr = :+dok_dat_feld[2] and beleg_dat > v_dok_dat_feld_51 + anzahl_treffer = @dmrowcount + dbms with connection ta_session alias + + if ( anzahl_treffer > 0 ) + { + // Es wurde ein entsprechender Datensatz gefunden + dok_dat_feld[51] = vorhandenes_datum + dok_dat_feld_60[1] = kampagne + call xlog( 5, "Anzahl Treffer: <:anzahl_treffer> neues Datum: <:vorhandenes_datum> Kampagne: <:kampagne> Auftrags-Nr. <:dok_dat_feld[2]> " ) + } + else if ( anzahl_treffer == 0 ) + { + // Es wurde keiner gefunden + // Dokument wird abgelehnt + call xlog( 2, "1 Es ist ein Fehler aufgetreten: :anzahl_treffer " ) + return -202 + } + else + { + // Es ist ein Fehler aufgetreten + call xlog( 2, "2 Es ist ein Fehler aufgetreten: :anzahl_treffer " ) + return -203 + } + + } + else + { + // Es ist ein Fehler aufgetreten + call xlog( 2, "3 Es ist ein Fehler aufgetreten: :anzahl_treffer " ) + return -201 + } + + } + // Ende Einfügung calb/d.OS am 2012.11.08 + + // eingefügt von calb/d.OS am 2013.02.04 + // Import von Konstruktionszeichnungen aus IMOS + vars bauteilart, materialart, orientierung, programm, ppsnummer, barcode, anzahl_treffer, info1, info2, info3, info4, anschlag, ergebnis + + if ( h_DocType == "dkoak" ) + { + // Setzen der zeich_nr und Aufsplitten des Barcodes in insert_entry_05 ausgelagert + // calb/d.velop AG + + // dbms declare ta_session connection for user 'ASSMANN\\DB-connect-IMOS-D3' password 'QK+NE}qj=)q=' datasource 'IMOS-DB-Prod' + dbms declare ta_session connection for user 'sa' password 'aPFb4eNyZT57T' datasource 'IMOS-DB' + + // orientierung ANSCHLAG + dbms with connection ta_session alias bauteilart, materialart, programm, ppsnummer, barcode, info2, info3, info4, anschlag + dbms with connection ta_session sql select PARTTYPE, MATCAT, PROGRAMM, INFO1, BARCODE, INFO2, INFO3, INFO4, ANSCHLAG from IDBEXT where BARCODE = :+dok_dat_feld[ 32 ] + + anzahl_treffer = @dmrowcount + dbms with connection ta_session alias + dbms close connection ta_session + + if ( anzahl_treffer == 0 ) + { + call xlog( 3, "Konstruktionszeichnungen: Achtung: Keine Treffer gefunden! " ) + // return-Statement auskommentiert von calb, 2015.12.10 + // weil: es sollen auch manuell Konstruktionszeichnungen importiert werden können, zu denen es keinen DB-Eintrag gibt. + //return -1012 + } + else + { + ergebnis = api_function( "string_cut_leading_char", anschlag, " " ) + + if ( ergebnis >= 0 ) + { + anschlag = api_converted_string + } + else + { + call xlog( 2, "Konstruktionszeichnungen: Achtung: Fehler beim Entfernen von Leerzeichen im Attribut 'Anschlag'!" ) + return -1001 + } + + if ( bauteilart == "1" ) + { + dok_dat_feld[ 8 ] = "Seiten" + } + + if ( bauteilart == "3" ) + { + dok_dat_feld[ 8 ] = "Einlegeböden" + } + + if ( bauteilart == "4" ) + { + dok_dat_feld[ 8 ] = "Oberböden" + } + + if ( bauteilart == "5" ) + { + dok_dat_feld[ 8 ] = "Unterböden" + } + + if ( bauteilart == "6" ) + { + dok_dat_feld[ 8 ] = "Rückwände" + } + + if ( ( bauteilart == "8" ) || ( bauteilart == "9" ) || ( bauteilart == "10" ) ) + { + dok_dat_feld[ 8 ] = "Türen" + } + + if ( bauteilart == "13" ) + { + dok_dat_feld[ 8 ] = "Konstruktionsböden" + } + + if ( bauteilart == "14" ) + { + dok_dat_feld[ 8 ] = "Mittelseiten" + } + + if ( bauteilart == "23" ) + { + dok_dat_feld[ 8 ] = "Blenden" + } + + if ( bauteilart == "30" ) + { + dok_dat_feld[ 8 ] = "Abdeckplatten" + } + + if ( bauteilart == "21" ) + { + dok_dat_feld[ 8 ] = "Schubkastenboden" + } + + //dok_dat_feld[ 8 ] = bauteilart + + if ( materialart != "" ) + { + dok_dat_feld[ 6 ] = materialart + } + + if ( orientierung != "" ) + { + dok_dat_feld[ 5 ] = orientierung + } + + if ( programm != "" ) + { + dok_dat_feld[ 2 ] = programm + } + + if ( ppsnummer != "" ) + { + dok_dat_feld[ 7 ] = ppsnummer + } + + if ( info2 != "" ) + { + dok_dat_feld[ 37 ] = info2 + } + + if ( info3 != "" ) + { + dok_dat_feld[ 38 ] = info3 + } + + if ( info4 != "" ) + { + dok_dat_feld[ 39 ] = info4 + } + + if ( anschlag != "" ) + { + dok_dat_feld[ 40 ] = anschlag + } + + + + //dok_dat_feld[ 3 ] = barcode + } + + call xlog(3, "Konstruktionszeichnungen: Fertig mit Einlesen! PPS-Nummer: <:dok_dat_feld[ 7 ]>" ) + } + // Ende Einfügung calb/d.OS am 2013.02.04 + + if ( h_DocType == "dang" ) + { + if ( @length( dok_dat_feld[ 1 ] ) == 0 ) + { + dok_dat_feld[ 1 ] = "9999999" + } + } + + + if ( ( h_DocType == "DEBZ" ) || ( h_DocType == "DEBR" ) || ( h_DocType == "DEBG" ) || ( h_DocType == "EKBEL" ) || \ + ( h_DocType == "CHEBZ" ) || ( h_DocType == "CHEBL" ) || ( h_DocType == "CHEBR" ) || ( h_DocType == "CHEBG" ) || ( h_DocType == "EKBEL" ) || \ + ( ( h_DocType == "dlkb" ) && ( dok_dat_feld[ 2 ] == "" ) ) || ( ( h_DocType == "chlkb" ) && ( dok_dat_feld[ 2 ] == "" ) ) ) + { + // calb / d.OS, 2013.06.14 + // Realisierung Einkaufsbelege / Lieferscheine (inkl. Retoure) + if ( dok_dat_feld[ 6 ] != "nicht angegeben" ) + { + call xlog( 4, "rufe Einkaufsbelege ... " ) + //call xlog( 4, "EK-Belege: Barcode: <:dok_dat_feld[ 6 ]> " ) + + vars company[5000], doc_type[5000], field_no[5000], index_value[5000], field_name[5000] + vars i, j, k, anzahl + + DBMS DECLARE DB_Session CONNECTION FOR USER 'EX_D3' PASSWORD 'NAVEX13' DATASOURCE 'ERP' + //DBMS DECLARE DB_Session CONNECTION FOR USER 'calbers' PASSWORD 'calbers' DATASOURCE 'ca_system' + + DBMS WITH CONNECTION DB_Session ALIAS company, doc_type, field_no, index_value, field_name + DBMS WITH CONNECTION DB_Session SQL select Company, ArchiveDocumentType, DocTypeFieldNo, IndexValue, DocTypeFieldName \ + from [Assmann_BM_DE$Index Values 4 Scanning Lines] where Barcode = :+dok_dat_feld[ 6 ] + anzahl = @dmrowcount + DBMS WITH CONNECTION DB_Session ALIAS + DBMS CLOSE CONNECTION DB_Session + + j = 0 + + call xlog( 4, "Anzahl Treffer: " ## anzahl ) + + for i = 1 while i < 100 step 1 + { + dok_dat_feld_60[ i ] = "" + } + // Erweiterung Hook durch Martin Lulei, Raber+Märcker, 13.06.2014, 09:28 (&& datei_erw != "txt") + if ( ( doc_type[ 1 ] == "" ) && ( datei_erw != "TXT" )) + { + call api_log_error( "###MALU Dokumentart = :doc_type[1] Dateierweiterung = :datei_erw") + call xlog( 2, "EK-Belege: Barcode: <:dok_dat_feld[ 6 ]> keine / nur leere Zeilen in der DB gefunden. " ) + additional_info_text = "Barcode: <:dok_dat_feld[ 6 ]> keine / nur leere Zeilen in der DB gefunden." + return -8000 + } + else + { + // Zuweisen der Dokumentart + dok_dat_feld[ 49 ] = doc_type[ 1 ] + + call xlog( 4, "EK-Belege: Barcode: <:dok_dat_feld[ 6 ]> Dokumentart: <:doc_type[ 1 ]> " ) + + for i = 1 while i <= 5000 step 1 + { + if ( doc_type[ i ] == "" ) + { + k = i - 1 + call xlog( 3, "EK-Belege: Barcode: <:dok_dat_feld[ 6 ]> raus hier @ Zeile :k " ) + break + } + + + // Analyse der gelesenen Informationen + + // Zuweisen der Attributfelder + if ( field_no[ i ] != 60 ) + { + // eindimensionales Feld + dok_dat_feld[ field_no[ i ] ] = index_value[ i ] + //call xlog( 4, "EK-Belege: Barcode: <:dok_dat_feld[ 6 ]> Feld: dok_dat_feld_:field_no[ :i ] == <:index_value[ :i ]>" ) + } + else + { + // mehrdimensionales Feld + j = j + 1 + dok_dat_feld_60[ j ] = index_value[ i ] + //call xlog( 4, "EK-Belege: Barcode: <:dok_dat_feld[ 6 ]> Feld: dok_dat_feld_60[ :j ] == <:index_value[ :i ]>" ) + } + } + + // Zuweisen des Mandanten + dok_dat_feld[ 31 ] = company[ 1 ] + //call xlog( 3, "Mandant: <" ## dok_dat_feld[ 31 ] ## ">" ) + } + } + } + // Ende Realisierung Einkaufsbelege + + + call api_log_info( "### hook ### hook_insert_entry_10_ass ## :h_DocType ## start") + + if ( h_DocType != gDTS_INVOICE ) + { + call getBarcodeData() + } + //call xlog( 4, "Mandant: <" ## dok_dat_feld[ 31 ] ## ">" ) + call api_log_info( "### hook ### hook_insert_entry_10_ass ## :h_DocType ## end") +} + +proc getBarcodeData() +{ + vars h_Hits, h_Error, h_ErrMsg + + if (dok_dat_feld[h_DDF_BARCODE]!="") + { + call prepareDbConnection() + + vars h_Company, h_DocType + DBMS WITH CONNECTION :h_NavOdbcSource ALIAS h_Company, h_DocType + DBMS WITH CONNECTION :h_NavOdbcSource \ + SQL SELECT Company, ArchiveDocumentType \ + FROM [Assmann_BM_DE$Index Values 4 Scanning Header] WHERE Barcode=:+dok_dat_feld[h_DDF_BARCODE] + + h_Hits = @dmrowcount + h_Error = @dmengerrcode + h_ErrMsg = @dmengerrmsg + + dok_dat_feld[h_DDF_DTTEMP] = h_DocType + dok_dat_feld[h_DDF_COMPANY] = h_Company + + call api_log_info( "### barcode search: hits: :h_Hits ### DB error: :h_Error") + + DBMS WITH CONNECTION :h_NavOdbcSource ALIAS + + if (h_Hits>0) + { + vars h_FieldNo, h_Index, h_Value + DBMS WITH CONNECTION :h_NavOdbcSource ALIAS h_FieldNo, h_Index, h_Value + DBMS WITH CONNECTION :h_NavOdbcSource \ + SQL SELECT DocTypeFieldNo, NoOfMultipleField, IndexValue \ + FROM [Assmann_BM_DE$Index Values 4 Scanning Lines] WHERE Barcode=:+dok_dat_feld[h_DDF_BARCODE] + + h_Error = @dmengerrcode + + vars h_i = 0 + while (@dmretcode!=DM_NO_MORE_ROWS && h_Error==0 && h_ErrMsg=="") + { + h_i = h_i + 1 + if (h_FieldNo>=60 && h_FieldNo<=69) + { + if (h_Index<=h_ARRAY_MAX) + { + (dok_dat_feld_:h_FieldNo)[h_Index] = h_Value + } + } + else + { + dok_dat_feld[h_FieldNo] = h_Value + } + + DBMS WITH CONNECTION :h_NavOdbcSource CONTINUE + h_Error = @dmengerrcode + } + call api_log_info( "### barcode values: hits: :h_i ## DB error: :h_Error ## Navision") + DBMS WITH CONNECTION :h_NavOdbcSource ALIAS + + vars h_ScanCount, h_ScanCountTemp + DBMS WITH CONNECTION :h_NavOdbcSource ALIAS h_ScanCountTemp + DBMS WITH CONNECTION :h_NavOdbcSource \ + SQL SELECT ScanCount FROM [Assmann_BM_DE$Index Values 4 Scanning Header] WHERE Barcode=:+dok_dat_feld[h_DDF_BARCODE] + + h_ScanCount = h_ScanCountTemp + + // Datum ermitteln + //call api_function ("get_current_datetime", "%0d.%0m.%4y") + //call api_function ("get_current_datetime", "%0m-%0d-%4y") + // Change date format to YYYYMMDD --- + // call api_function ("get_current_datetime", "%4y%0m%0d") + call api_function ("get_current_datetime", "%0m.%0d.%4y") + // Change date format to YYYYMMDD +++ + vars h_Datum = api_single_info + call api_log_info( "### h_Datum: :h_Datum") + + DBMS WITH CONNECTION :h_NavOdbcSource ALIAS + + h_ScanCount = h_ScanCount + 1 + + DBMS WITH CONNECTION :h_NavOdbcSource \ + SQL UPDATE [Assmann_BM_DE$Index Values 4 Scanning Header] SET ScanCount=:h_ScanCount, LastScan=:+h_Datum WHERE Barcode=:+dok_dat_feld[h_DDF_BARCODE] + DBMS WITH CONNECTION :h_NavOdbcSource COMMIT + + h_Error = @dmengerrcode + + call api_log_info( "### barcode scan counter incremented: barcode: :dok_dat_feld[h_DDF_BARCODE], counter: :h_ScanCount, LastScan: :h_Datum ### DB error: :h_Error ## Navision") + } + + return h_Hits + } +} + +// ##################################################################################### +// hook_insert_exit_30_d3Nav +// ##################################################################################### + +proc hook_insert_exit_30_d3Nav (h_DocId, h_FileDestination, h_CountmportOk, h_User, h_DocType) +{ + call api_log_info( "### hook ### hook_insert_exit_30_d3Nav ## :h_DocType :h_DocId ## start") + + call InsertExit30(h_DocId, h_FileDestination, h_CountmportOk, h_User, h_DocType) + + call updateAttributes(h_DocType, h_DocId) + + if(h_DocType == "AKRVG") + { + call linkDeliveryNotes(h_DocId) + } + + call api_log_info( "### hook ### hook_insert_exit_30_d3Nav ## :h_DocType ## end") +} + + + +// ##################################################################################### +// hook_upd_attrib_exit_20_d3Nav +// ##################################################################################### + +proc hook_upd_attrib_exit_20_d3Nav (h_DocId, h_ErrNo, h_User, h_DocType) +{ + call api_log_info("### Hook ## hook_upd_attrib_exit_20_d3Nav ## :h_DocType :h_DocId ## start") + + call UpdateAttribExit20 (h_DocId, h_ErrNo, h_User, h_DocType) + + call updateAttributes(h_DocType, h_DocId) + + if (dok_dat_feld[h_DDF_BARCODE]!="") + { + vars h_Error + + call prepareDbConnection() + + DBMS WITH CONNECTION :h_NavOdbcSource \ + SQL UPDATE [Assmann_BM_DE$Index Values 4 Scanning Header] SET ArchivDocID=:+h_DocId WHERE Barcode=:+dok_dat_feld[h_DDF_BARCODE] + DBMS WITH CONNECTION :h_NavOdbcSource COMMIT + + h_Error = @dmengerrcode + call api_log_info( "### barcode: set doc id: :h_DocId ### DB error: :h_Error ## Navision") + } + + call api_log_info( "### hook ### hook_insert_exit_30_d3Nav ## :h_DocType ## end") + + if(h_DocType == "AKRVG") + { + //Prüfe auf Änderungen der Lieferscheinnummern + vars x + vars hasChanged = "false" + for x=1 while x<=CUR_60ER_FIELD_NR step 1 + { + if(old_dok_dat_feld_63[x] != dok_dat_feld_63[x]) + { + hasChanged = "true" + } + } + if( hasChanged == "true" ) + { + call linkDeliveryNotes(h_DocId) + } + else + { + call api_log_info("no changes relevant for linking") + } + } +} + +proc linkDeliveryNotes(h_DocId) +{ + call api_log_info( "start linkDeliveryNotes") + + //Lösen der Verbindungen + vars h_ReturnValue + h_ReturnValue = api_function("link_get_children", h_DocId, "") + vars client = dok_dat_feld[31] + vars clientNo = dok_dat_feld[81] + vars supplierNoArray[CUR_60ER_FIELD_NR] + vars j + for j=1 while j<=CUR_60ER_FIELD_NR step 1 + { + supplierNoArray[j] = dok_dat_feld_63[j] + } + + if (h_ReturnValue == 0) + { + vars h_Count + vars h_tmpDocId + vars h_creator + vars tmpChildren = api_single_info + for h_Count = 1 while h_Count <= tmpChildren step 1 + { + h_tmpDocId = api_links[h_Count] + h_creator = api_link_creators[h_Count] + if(h_tmpDocId != "" && h_creator != "m") + { + vars h_tmpDoktype + h_ReturnValue = api_function ("document_type_get_short", "", h_tmpDocId) + + if (h_ReturnValue == 0) + { + h_tmpDoktype = api_single_info + if(h_tmpDoktype == "DEBL") + { + h_ReturnValue = api_function ("link_delete", h_DocId, h_tmpDocId, "decsapi") + + if(h_ReturnValue == 0) + { + call api_log_info("Verknüpfung entfernt parent :h_DocId child :h_tmpDocId") + } + else + { + call api_log_error("Fehlernummer :h_ReturnValue") + } + } + } + else + { + call api_log_error("Fehlernummer :h_ReturnValue wurde zurückgeliefert!") + } + } + } + } + else + { + call api_log_error("Fehlernummer :h_ReturnValue wurde zurückgeliefert!") + } + + //Erstellen der Verbindungen + vars i + for i=1 while i<=CUR_60ER_FIELD_NR step 1 + { + if(supplierNoArray[i] != "") + { + call api_clear_document_context() + api_doc_type_short = "DEBL" + api_doc_field[31] = client + api_doc_field[81] = clientNo + api_doc_field[20] = supplierNoArray[i] + + if(api_doc_field[31] != "" && api_doc_field[81] != "" && api_doc_field[20] != "") + { + h_ReturnValue = api_function ("document_find_ids", "decsapi") + if (h_ReturnValue == 0) + { + vars y = api_single_info + for y = 1 while y <= api_single_info step 1 + { + vars tmpChildLinkDocId = api_doc_ids[y] + call api_log_info("doc_id :y: :api_doc_ids[y]") + + h_ReturnValue = api_function ("link_documents", "", tmpChildLinkDocId, "", 0,1) + + if (h_ReturnValue == 0) + { + call api_log_info("Verknüpfung erstellt zwischen parent :h_DocId und child :tmpChildLinkDocId") + } + else + { + call api_log_error("Fehlernummer :h_ReturnValue wurde zurückgeliefert!") + } + } + } + else + { + call api_log_error("Fehlernummer :h_ReturnValue wurde zurückgeliefert!") + } + } + } + } + call api_log_info( "end linkDeliveryNotes") +} + +proc updateAttributes(h_DocType, h_DocId) +{ + if (h_DocType==h_DT_SOCONF) + { + // update quote attribute to relink document + call updateForeignAttribute (h_DocId, h_DocType, h_DDF_SQUOTENO, h_DDF_SORDERNO) + } +} + +proc updateForeignAttribute (h_DocId, h_SourceDocType, h_MatchField, h_CopyField) +{ + vars h_Count, h_MatchValue, h_CopyValue, h_Hits, h_Error + + h_MatchValue = dok_dat_feld[h_MatchField] + h_CopyValue = dok_dat_feld[h_CopyField] + + if (h_MatchValue!="" && h_CopyValue!="" && h_UpdateAttributes==1) + { + h_UpdateAttributes = 0 // avoid recursion + + vars h_UpdateDocIds[100] + DBMS ALIAS h_UpdateDocIds + DBMS SQL SELECT doku_id FROM firmen_spezifisch \ + WHERE dok_dat_feld_:h_MatchField=:+h_MatchValue and kue_dokuart<>:+h_SourceDocType + DBMS ALIAS + + h_Hits = @dmrowcount + h_Error = @dmengerrcode + + for h_Count = 1 while h_UpdateDocIds[h_Count]!="" step 1 + { + call api_log_info("### update foreign attribute ## :h_UpdateDocIds[h_Count] ## match: field :h_MatchField -> :h_MatchValue # copy: field :h_CopyField -> :h_CopyValue ###") + call api_function("attribute_update_single", h_CopyField, h_CopyValue, 1, h_UpdateDocIds[h_Count], h_EditUser) + } + + h_UpdateAttributes = 1 + } +} + +// ##################################################################################### +// helper functions +// ##################################################################################### + +proc prepareDbConnection() +{ + if(!dm_is_connection(h_NavOdbcSource)) + { + vars h_Error + + DBMS DECLARE :h_NavOdbcSource CONNECTION FOR \ + USER 'EX_D3' PASSWORD 'NAVEX13' DATASOURCE ':h_NavOdbcSource' + h_Error = @dmengerrcode + if (h_Error==0) + { + call api_log_info( "### Connect: ODBC source: :h_NavOdbcSource") + } + else + { + call api_log_error( "### Database connection failed. ODBC source: 'ERP'. Error: :h_Error") + } + } +} diff --git a/Assmann/hook_assmann.jpl b/Assmann/hook_assmann.jpl new file mode 100644 index 0000000..031abef --- /dev/null +++ b/Assmann/hook_assmann.jpl @@ -0,0 +1,429 @@ +########################## +## hook_insert_entry_10 ## +########################## + +proc hook_insert_entry_10_ass_1(p_user,P_dokuart) +{ + + + + + + if dok_dat_feld[26](1,1)=="~" + { + vars Anzahl=api_function("string_split", dok_dat_feld[26], "~") + + dok_dat_feld[26]=api_splitted_string[2] + dok_dat_feld[81]=api_splitted_string[3] + dok_dat_feld[14]=api_splitted_string[4] + dok_dat_feld[9]=api_splitted_string[5] + dok_dat_feld[10]=api_splitted_string[6] + } + + // nur bei relevanten Dokarten Metadaten aus ERP holen und nur wenn bisher noch nicht geholt + if ((P_dokuart == "ddab")||(P_dokuart == "ddls")||(P_dokuart == "ddre")||(P_dokuart == "ddgs"))&&(dok_dat_feld[1]=="") + { + // Konvertierung lange Vorgangsnummer in Einzelwerte + // 2 vg_lfd_nr + if dok_dat_feld[2] != "" + { + vars Anzahl=api_function("string_split", dok_dat_feld[2], "/") + // nur 2. Wert relevant, da Vorgangsnummer + if Anzahl > 1 + { + //api_function("string_cut_leading_char", api_splitted_string[2], " ") + //dok_dat_feld[2]=api_converted_string + dok_dat_feld[2]=api_splitted_string[2] + } + } + + // Ermittlung der Dokuart anhand ausgelesener Texte per DCOLD + // DB Connect herstellen + vars v_aenderungs_nr, v_belegdatum, v_kunden_ab_nr, v_kommission, v_debitor_nr, \ + v_name1, v_strasse, v_plz_strasse, v_ort, v_land, v_auftragsart, \ + v_auftragsart_bez, v_bestell_datum, v_erfassungs_datum, \ + v_sachbearbeiter, v_vertreter_nr, v_vertreter, v_beleg_nr, v_ausgabeart, v_kopftext + vars aus_vorhanden + + DBMS ALIAS \ + v_aenderungs_nr, v_belegdatum, v_kunden_ab_nr, v_kommission, v_debitor_nr, \ + v_name1, v_strasse, v_plz_strasse, v_ort, v_land, v_auftragsart, \ + v_auftragsart_bez, v_bestell_datum, v_erfassungs_datum, \ + v_sachbearbeiter, v_vertreter_nr, v_vertreter, v_beleg_nr, v_ausgabeart, v_kopftext + + DBMS SQL \ + SELECT aenderungs_nr, belegdatum, kunden_ab_nr, kommission, debitor_nr, \ + name1, strasse, plz_strasse, ort, land, auftragsart, \ + auftragsart_bez, bestell_datum, erfassungs_datum, \ + sachbearbeiter, vertreter_nr, vertreter_name, beleg_nr, ausgabeart, kopftext \ + FROM as_archiv_info \ + WHERE auftrags_nr = :dok_dat_feld[2] and (status = 0 or status = 98) + + aus_vorhanden = @dmrowcount + DBMS ALIAS + + if (aus_vorhanden > 0) + { + // den Attributen des neuen Dokuments zuweisen + dok_dat_feld[12] = v_aenderungs_nr + dok_dat_feld[51] = v_belegdatum + dok_dat_feld[13] = v_kunden_ab_nr + dok_dat_feld_60[1] = v_kommission + dok_dat_feld[1] = v_debitor_nr + dok_dat_feld[4] = v_name1 + dok_dat_feld[14] = v_strasse + dok_dat_feld[9] = v_plz_strasse + dok_dat_feld[10] = v_ort + dok_dat_feld[15] = v_land + dok_dat_feld[80] = v_auftragsart + dok_dat_feld[16] = v_auftragsart_bez + dok_dat_feld[52] = v_bestell_datum + dok_dat_feld[50] = v_erfassungs_datum + dok_dat_feld[17] = v_sachbearbeiter + dok_dat_feld[18] = v_vertreter_nr + dok_dat_feld[19] = v_vertreter + dok_dat_feld[28] = v_ausgabeart + if v_kopftext!="" + { + vars Anzahl=api_function("string_split", v_kopftext,"") + vars i + for i=1 while i <=Anzahl step 1 + { + dok_dat_feld_63[i]=api_splitted_string[i] + } + } + if (P_dokuart == "ddls") + { + // wenn LS, dann Belegnummmer auf LS-Nr + dok_dat_feld[20] = v_beleg_nr + } + if ((P_dokuart == "ddre")||(P_dokuart == "ddgs")) + { + // wenn RE oder GS, dann Belegnummmer auf RG-Nr + dok_dat_feld[21] = v_beleg_nr + } + DBMS SQL UPDATE as_archiv_info \ + SET status = status + 200 \ + WHERE auftrags_nr = :dok_dat_feld[2] and status <> 98 + } + else + { + msg emsg "Import abgelehnt :dok_dat_feld[2], keine Daten im Status 0" + DBMS SQL UPDATE as_archiv_info \ + SET status = status + 200 \ + WHERE auftrags_nr = :dok_dat_feld[2] AND status <> 98 AND status < 200 + return -4713 + } + + //ermitteln, ob Beleg mit identischer Aenderungsnummer schon im d.3 ist und dann Import ablehnen + vars beleg_vorhanden, v_doku_temp + DBMS ALIAS v_doku_temp + DBMS SQL SELECT doku_id \ + FROM firmen_spezifisch \ + WHERE kue_dokuart = :+P_dokuart \ + and dok_dat_feld_2 = :+dok_dat_feld[2] \ + and dok_dat_feld_12 = :+dok_dat_feld[12] + beleg_vorhanden = @dmrowcount + DBMS ALIAS + + if (beleg_vorhanden > 0) + { + msg emsg "Import abgelehnt :beleg_vorhanden" + return -4712 + } + } + + //Aenderungs-Index bei Teilezeichnung setzen + if (P_dokuart == "dtlz" && dok_dat_feld[23]=="") + { + dok_dat_feld[23]= 1 + } +} + +proc hook_search_entry_10_ass(p_user,P_dokuart) +{ + + if ( ( P_dokuart == "itwar" ) || ( P_dokuart == "ittel" ) || ( P_dokuart == "ittat" ) || ( P_dokuart == "itliz" ) || \ + ( P_dokuart == "itlfs" ) || ( P_dokuart == "iter" ) || ( P_dokuart == "itauf" ) ) + { + vars Anzahl=api_function("string_split", dok_dat_feld[26], "~") + dok_dat_feld[26]=api_splitted_string[1] + //dok_dat_feld[81]=api_splitted_string[3] + //dok_dat_feld[14]=api_splitted_string[4] + //dok_dat_feld[9]=api_splitted_string[5] + //dok_dat_feld[10]=api_splitted_string[6] + //msg emsg ("bin in search entry und splitte") + } +} + +proc hook_val_imp_entry_10_ass(p_user,P_dokuart) +{ + //call xlog( 4, "dok_dat_feld[26] " ## dok_dat_feld[26] ) + if ( ( P_dokuart == "itan" ) || ( P_dokuart == "itauf" ) || ( P_dokuart == "iter" ) || ( P_dokuart == "itlfs" ) \ + || ( P_dokuart == "itliz" ) || ( P_dokuart == "ittat" ) || ( P_dokuart == "ittel" ) || ( P_dokuart == "itwar" ) ) + { + vars ergebnis + vars pos_name = 2 + vars pos_strasse = 4 + vars pos_plz = 5 + vars pos_ort = 6 + + ergebnis = api_function( "string_get_position", dok_dat_feld[26], "~" ) + + if ( ergebnis > 0 ) + { + if ( dok_dat_feld[26](1,1) != "~" ) + { + pos_name = 1 + pos_strasse = 3 + pos_plz = 4 + pos_ort = 5 + } + + + vars Anzahl=api_function("string_split", dok_dat_feld[26], "~") + + dok_dat_feld[26] = api_splitted_string[ pos_name ] + //dok_dat_feld[81] = api_splitted_string[ 3 ] + dok_dat_feld[14] = api_splitted_string[ pos_strasse ] + dok_dat_feld[9] = api_splitted_string[ pos_plz ] + dok_dat_feld[10] = api_splitted_string[ pos_ort ] + } + } +} + + + +################# +## hook_insert_exit_20 ## +################# + +proc hook_insert_exit_20_ass(p_doc_id, p_file_destination, p_import_ok, p_user, P_dokuart) +{ + //msg emsg"Bin im Update fr :dok_dat_feld[2] :p_doc_id, :p_file_destination, :p_import_ok, :p_user, :P_dokuart" + if ((P_dokuart == "ddab")||(P_dokuart == "ddls")||(P_dokuart == "ddre")||(P_dokuart == "ddgs")) + { + DBMS SQL Update as_archiv_info \ + set status = 2 \ + WHERE auftrags_nr = :dok_dat_feld[2] and status = 0 + //msg emsg"Bin im Update fr :dok_dat_feld[2]" + + // Transferstatus + DBMS SQL Update as_archiv_info \ + set transferstatus = 1 \ + WHERE auftrags_nr = :dok_dat_feld[2] + } +} + +################# +## hook_new_version ## +################# + +proc hook_new_version_entry_10_ass(p_doc_id, p_file, p_import, p_user,P_dokuart) +{ + //Aenderungs-Index bei Teilezeichnung hochsetzen + if (P_dokuart == "dtlz") + { + vars hoechstwert, ver_vorhanden + DBMS ALIAS hoechstwert + DBMS SQL select max (dok_dat_feld_23) from firmen_spezifisch \ + where doku_id = :+p_doc_id + ver_vorhanden = @dmrowcount + DBMS ALIAS + + if (ver_vorhanden > 0) + { + dok_dat_feld[23]=hoechstwert + 1 + } + } + + + + // eingefügt von calb/d.OS am 2013.02.04 + // Import von Konstruktionszeichnungen aus IMOS + vars bauteilart, materialart, orientierung, programm, ppsnummer, barcode, anzahl_treffer, info1, info2, info3, info4, anschlag, ergebnis + + if ( P_dokuart == "dkoak" ) + { + + call xlog( 5, "DDF 32: " ## dok_dat_feld[ 32 ] ) + ergebnis = api_function( "string_split", dok_dat_feld[ 32 ], "--" ) + dok_dat_feld[ 32 ] = api_splitted_string[ 1 ] + + + // Angepaßt A.Brink 04.03.2024 + // Abfrage der IMOS-DB-Prod Datenbank (Für die Übernahme der Konstruktionszeichnungen) + + // dbms declare ta_session connection for user 'ASSMANN\\DB-connect-IMOS-D3' password 'QK+NE}qj=)q=' datasource 'IMOS-DB' + dbms declare ta_session connection for user 'sa' password 'd3db49324' datasource 'IMOS-DB' + + // orientierung ANSCHLAG + dbms with connection ta_session alias bauteilart, materialart, programm, ppsnummer, barcode, info2, info3, info4, anschlag + dbms with connection ta_session sql select PARTTYPE, MATCAT, PROGRAMM, INFO1, BARCODE, INFO2, INFO3, INFO4, ANSCHLAG from IDBEXT where BARCODE = :+dok_dat_feld[ 32 ] + + anzahl_treffer = @dmrowcount + dbms with connection ta_session alias + dbms close connection ta_session + + + + if ( anzahl_treffer == 0 ) + { + call xlog( 2, "Achtung: Keine Treffer gefunden! Import wurde verweigert!" ) + return -10000 + } + else + { + ergebnis = api_function( "string_cut_leading_char", anschlag, " " ) + + if ( ergebnis >= 0 ) + { + anschlag = api_converted_string + } + else + { + call xlog( 2, "Achtung: Fehler beim Entfernen von Leerzeichen im Attribut 'Anschlag'!" ) + return -10001 + } + + if ( bauteilart == "1" ) + { + dok_dat_feld[ 8 ] = "Seiten" + } + + if ( bauteilart == "3" ) + { + dok_dat_feld[ 8 ] = "Einlegeböden" + } + + if ( bauteilart == "4" ) + { + dok_dat_feld[ 8 ] = "Oberböden" + } + + if ( bauteilart == "5" ) + { + dok_dat_feld[ 8 ] = "Unterböden" + } + + if ( bauteilart == "6" ) + { + dok_dat_feld[ 8 ] = "Rückwände" + } + + if ( ( bauteilart == "8" ) || ( bauteilart == "9" ) || ( bauteilart == "10" ) ) + { + dok_dat_feld[ 8 ] = "Türen" + } + + if ( bauteilart == "13" ) + { + dok_dat_feld[ 8 ] = "Konstruktionsböden" + } + + if ( bauteilart == "14" ) + { + dok_dat_feld[ 8 ] = "Mittelseiten" + } + + if ( bauteilart == "23" ) + { + dok_dat_feld[ 8 ] = "Blenden" + } + + if ( bauteilart == "30" ) + { + dok_dat_feld[ 8 ] = "Abdeckplatten" + } + + if ( bauteilart == "21" ) + { + dok_dat_feld[ 8 ] = "Schubkastenboden" + } + + + //dok_dat_feld[ 8 ] = bauteilart + if ( materialart != "" ) + { + dok_dat_feld[ 6 ] = materialart + } + + if ( orientierung != "" ) + { + dok_dat_feld[ 5 ] = orientierung + } + + if ( programm != "" ) + { + dok_dat_feld[ 2 ] = programm + } + + if ( ppsnummer != "" ) + { + dok_dat_feld[ 7 ] = ppsnummer + } + + if ( info2 != "" ) + { + dok_dat_feld[ 37 ] = info2 + } + + if ( info3 != "" ) + { + dok_dat_feld[ 38 ] = info3 + } + + if ( info4 != "" ) + { + dok_dat_feld[ 39 ] = info4 + } + + if ( anschlag != "" ) + { + dok_dat_feld[ 40 ] = anschlag + } + + + + + + //dok_dat_feld[ 3 ] = barcode + } + + call xlog(3, "Fertig mit Einlesen! PPS-Nummer: <:ppsnummer>" ) + } + + // Ende Einfügung calb/d.OS am 2013.02.04 +} +########### repository hook ############### + +proc GetLiefName( repos_id, user, dokuart, rowNo ) +{ + + vars v_lfnm[5000], v_lfnr[5000], v_str[5000], v_plz[5000], v_ort[5000] , v_anzahl + DBMS ALIAS v_lfnm, v_lfnr, v_str, v_plz, v_ort + DBMS SQL SELECT distinct dok_dat_feld_26,dok_dat_feld_81, dok_dat_feld_14, dok_dat_feld_9, dok_dat_feld_10 \ + FROM firmen_spezifisch where kue_dokuart in('itan', 'iter', 'itlfs', 'ittat', 'itauf', 'itliz', 'itwar', 'ittel') and dok_dat_feld_26 is not null \ + ORDER BY dok_dat_feld_26 + v_anzahl=@dmrowcount + DBMS ALIAS + //call xlog( 4, "GetLiefName: v_anzahl " ## v_anzahl ) + if v_anzahl > 0 + { + vars i, zusammengesetzt + for i = 1 while( i <= v_anzahl ) step 1 + { + zusammengesetzt = v_lfnm[i] ## "~" ## v_lfnr[i]## "~" ## v_str[i]## "~" ## v_plz[i]## "~" ## v_ort[i] + //call xlog( 4, "GetLiefName: zusammengesetzt " ## zusammengesetzt ) + //msg emsg "zus :zusammengesetzt" + d3server_value_char_allowed[i] = zusammengesetzt + d3server_repos_id_allowed[i] = repos_id + } + } + //return 0 +}// end of GetLiefName + + + + +