From 5dfe870c4c1913126ad1a7d03b269882d2df37d2 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 14 Oct 2024 01:39:03 +0200 Subject: [PATCH] NEW Invoice - Generate payment information - Structured communication (#31376) * NEW Invoice - Generate payment information - Structured communication * fix tabs/space * Add $substitutionarray['__PAYMENT_STRUCTURED_COMMUNICATION__'] * Fix travis * Move to specific file functions_be.lib.php * Fix function use * Fix code --------- Co-authored-by: Laurent Destailleur --- htdocs/admin/invoice.php | 12 +++ htdocs/core/lib/functions.lib.php | 8 +- htdocs/core/lib/functions_be.lib.php | 77 +++++++++++++++++++ .../modules/facture/doc/pdf_crabe.modules.php | 34 ++++---- .../facture/doc/pdf_octopus.modules.php | 8 ++ .../facture/doc/pdf_sponge.modules.php | 36 +++++---- .../tables/llx_webhook_target-webhook.sql | 2 +- htdocs/langs/en_US/admin.lang | 2 + htdocs/langs/en_US/bills.lang | 1 + 9 files changed, 151 insertions(+), 29 deletions(-) create mode 100644 htdocs/core/lib/functions_be.lib.php diff --git a/htdocs/admin/invoice.php b/htdocs/admin/invoice.php index 163cb2cdab5..6ec4e02bd69 100644 --- a/htdocs/admin/invoice.php +++ b/htdocs/admin/invoice.php @@ -9,6 +9,7 @@ * Copyright (C) 2022 Anthony Berton * Copyright (C) 2024 MDW * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -758,6 +759,17 @@ print ""; print ajax_combobox("chq", array(), 0, 0, 'resolve', '-2'); print ""; + +// Structured communication +// Specific to Belgium - See core/lib/functions_be.lib.php +if ($mysoc->country_code == 'BE') { + print '' . $langs->trans("InvoicePaymentManageStructuredCommunication") . ' '; + print $form->textwithpicto('', $langs->trans("InvoicePaymentManageStructuredCommunicationHelp"), 1, 'help') . ''; + print ''; + print ajax_constantonoff('INVOICE_PAYMENT_ENABLE_STRUCTURED_COMMUNICATION'); + print ''; +} + print ""; print ''; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 9882c04ff67..d55ed19d1b0 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9,7 +9,7 @@ * Copyright (C) 2008 Raphael Bertrand (Resultic) * Copyright (C) 2010-2018 Juanjo Menent * Copyright (C) 2013 Cédric Salvador - * Copyright (C) 2013-2021 Alexandre Spangaro + * Copyright (C) 2013-2024 Alexandre Spangaro * Copyright (C) 2014 Cédric GROSS * Copyright (C) 2014-2015 Marcos García * Copyright (C) 2015 Jean-François Ferry @@ -9303,6 +9303,12 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__ONLINE_PAYMENT_TEXT_AND_URL__'] = ($paymenturl ? str_replace('\n', "\n", $outputlangs->trans("PredefinedMailContentLink", $paymenturl)) : ''); $substitutionarray['__ONLINE_PAYMENT_URL__'] = $paymenturl; + // Show structured communication + if (getDolGlobalString('INVOICE_PAYMENT_ENABLE_STRUCTURED_COMMUNICATION') && $object->element == 'facture') { + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions_be.lib.php'; + $substitutionarray['__PAYMENT_STRUCTURED_COMMUNICATION__'] = dolBECalculateStructuredCommunication($object->ref, $object->type); + } + if (getDolGlobalString('PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD') && is_object($object) && $object->element == 'propal') { $substitutionarray['__DIRECTDOWNLOAD_URL_PROPOSAL__'] = $object->getLastMainDocLink($object->element); } else { diff --git a/htdocs/core/lib/functions_be.lib.php b/htdocs/core/lib/functions_be.lib.php new file mode 100644 index 00000000000..c607b400d3f --- /dev/null +++ b/htdocs/core/lib/functions_be.lib.php @@ -0,0 +1,77 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/lib/functions_be.lib.php + * \brief A set of belgium functions for Dolibarr + * This file contains rare functions. + */ + + +/** + * Calculate Structured Communication / BE Bank payment reference number + * + * @param string $invoice_number Invoice number to generate payment reference + * @param int $invoice_type Invoice type + * @return string String structured communication for payment + */ +function dolBECalculateStructuredCommunication($invoice_number, $invoice_type) +{ + $invoice_number = preg_replace('/[^0-9]/', '', $invoice_number); // Keep only numbers + + // We complete with 0 and take the last 8 digits of the number are used to generate the reference base. + $invoice_number = substr('00000000'.$invoice_number, -8); + + // Prefix with invoice type + switch ($invoice_type) { + case '0': + $invoice_type = '20'; // invoice type standard + break; + case '1': + $invoice_type = '30'; // invoice type replacement + break; + case '2': + $invoice_type = '40'; // invoice type credit note + break; + case '3': + $invoice_type = '21'; // invoice type deposit + break; + case '5': + $invoice_type = '20'; // invoice type situation, force to standard + break; + default: + $invoice_type = '00'; + } + + // Calculate module97 + $invoice_number = $invoice_type.$invoice_number; + $mod97 = intval($invoice_number) % 97; + $controlKey = ($mod97 === 0) ? 97 : $mod97; + + // Add the check digit at the end of the reference + $invoice_number .= $controlKey; + + // Format reference as XXX/XXXX/XXXXX + $part1 = '+++'.substr($invoice_number, 0, 3); + $part2 = substr($invoice_number, 3, 4); + $part3 = substr($invoice_number, 7, 5).'+++'; // Includes last 3 digits + 2 check digits + + $invoice_number = $part1 . '/' . $part2 . '/' . $part3; + + return $invoice_number; +} diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 143d5e9eddb..60660b9aa30 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -1,18 +1,19 @@ - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2008 Raphael Bertrand - * Copyright (C) 2010-2014 Juanjo Menent - * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2012 Cédric Salvador - * Copyright (C) 2012-2014 Raphaël Doursenaud - * Copyright (C) 2015 Marcos García - * Copyright (C) 2017-2018 Ferran Marcet - * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2022 Anthony Berton - * Copyright (C) 2022 Charlene Benke - * Copyright (C) 2024 MDW +/* Copyright (C) 2004-2014 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2014 Juanjo Menent + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cédric Salvador + * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2015 Marcos García + * Copyright (C) 2017-2018 Ferran Marcet + * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2022 Anthony Berton + * Copyright (C) 2022 Charlene Benke + * Copyright (C) 2024 MDW * Copyright (C) 2024 Nick Fragoulis + * Copyright (C) 2024 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1325,6 +1326,13 @@ class pdf_crabe extends ModelePDFFactures $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size); $posy += 2; + + if (getDolGlobalString('INVOICE_PAYMENT_ENABLE_STRUCTURED_COMMUNICATION')) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions_be.lib.php'; + $invoicePaymentKey = dolBECalculateStructuredCommunication($object->ref, $object->type); + + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('StructuredCommunication').": " . $outputlangs->convToOutputCharset($invoicePaymentKey), 0, 'L', 0); + } } } } diff --git a/htdocs/core/modules/facture/doc/pdf_octopus.modules.php b/htdocs/core/modules/facture/doc/pdf_octopus.modules.php index 5513d1bbaf9..2a8a8dd7c2d 100644 --- a/htdocs/core/modules/facture/doc/pdf_octopus.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_octopus.modules.php @@ -1528,6 +1528,14 @@ class pdf_octopus extends ModelePDFFactures $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size); $posy += 2; + + // Show structured communication + if (getDolGlobalString('INVOICE_PAYMENT_ENABLE_STRUCTURED_COMMUNICATION')) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions_be.lib.php'; + $invoicePaymentKey = dolBECalculateStructuredCommunication($object->ref, $object->type); + + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('StructuredCommunication').": " . $outputlangs->convToOutputCharset($invoicePaymentKey), 0, 'L', 0); + } } } } diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 5db21abcc50..dad947ab22a 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -1,18 +1,18 @@ - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2008 Raphael Bertrand - * Copyright (C) 2010-2014 Juanjo Menent - * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2012 Cédric Salvador - * Copyright (C) 2012-2014 Raphaël Doursenaud - * Copyright (C) 2015 Marcos García - * Copyright (C) 2017 Ferran Marcet - * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2022 Anthony Berton - * Copyright (C) 2022 Alexandre Spangaro - * Copyright (C) 2024 MDW - * Copyright (C) 2024 Nick Fragoulis +/* Copyright (C) 2004-2014 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2014 Juanjo Menent + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cédric Salvador + * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2015 Marcos García + * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2022 Anthony Berton + * Copyright (C) 2022-2024 Alexandre Spangaro + * Copyright (C) 2024 MDW + * Copyright (C) 2024 Nick Fragoulis * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1449,6 +1449,14 @@ class pdf_sponge extends ModelePDFFactures $pdf->MultiCell(30, 3, $langs->trans("INVOICE_ADD_EPC_QR_CODEPay"), 0, 'L', 0); $posy = $pdf->GetY() + 2; } + + // Show structured communication + if (getDolGlobalString('INVOICE_PAYMENT_ENABLE_STRUCTURED_COMMUNICATION')) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions_be.lib.php'; + $invoicePaymentKey = dolBECalculateStructuredCommunication($object->ref, $object->type); + + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('StructuredCommunication').": " . $outputlangs->convToOutputCharset($invoicePaymentKey), 0, 'L', 0); + } } } } diff --git a/htdocs/install/mysql/tables/llx_webhook_target-webhook.sql b/htdocs/install/mysql/tables/llx_webhook_target-webhook.sql index da96128d5af..3a6004a2d02 100644 --- a/htdocs/install/mysql/tables/llx_webhook_target-webhook.sql +++ b/htdocs/install/mysql/tables/llx_webhook_target-webhook.sql @@ -14,7 +14,7 @@ -- along with this program. If not, see https://www.gnu.org/licenses/. -CREATE TABLE llx_webhook_target( +CREATE TABLE llx_webhook_target ( -- BEGIN MODULEBUILDER FIELDS rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, ref varchar(128) NOT NULL, diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 913ee3b72ed..601a170444e 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1487,6 +1487,8 @@ ForceInvoiceDate=Force invoice date to validation date SuggestedPaymentModesIfNotDefinedInInvoice=Suggested payments mode on invoice by default if not defined on the invoice SuggestPaymentByRIBOnAccount=Suggest payment by withdrawal on account SuggestPaymentByChequeToAddress=Suggest payment by check to +InvoicePaymentManageStructuredCommunication=Generate structured communication for invoice payment +InvoicePaymentManageStructuredCommunicationHelp=In some countries, it is necessary to display a structured reference to facilitate payments and their reconciliation FreeLegalTextOnInvoices=Free text on invoices WatermarkOnDraftInvoices=Watermark on draft invoices (none if empty) PaymentsNumberingModule=Payments numbering model diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index f1e1bfc4e2d..d5c859db49a 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -514,6 +514,7 @@ PrettyLittleSentence=Accept the amount of payments due by checks issued in my na IntracommunityVATNumber=Intra-Community VAT ID PaymentByChequeOrderedTo=Check payments (including tax) are payable to %s, send to PaymentByChequeOrderedToShort=Check payments (incl. tax) are payable to +StructuredCommunication=Structured communication SendTo=sent to PaymentByTransferOnThisBankAccount=Payment by transfer to the following bank account VATIsNotUsedForInvoice=* Non applicable VAT art-293B of CGI