From 679625daeeb2581b2a6429f2e4d2f734611ffc53 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 09:51:15 +0200 Subject: [PATCH 01/97] Trans --- htdocs/langs/en_US/withdrawals.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 662c587108a..e869556f691 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -77,7 +77,7 @@ StatusMotif8=Other reason CreateForSepaFRST=Create direct debit file (SEPA FRST) CreateForSepaRCUR=Create direct debit file (SEPA RCUR) CreateAll=Create direct debit file (all) -CreateFileForPaymentByBankTransfer=Create file for credit transfer (all) +CreateFileForPaymentByBankTransfer=Create file for credit transfer CreateSepaFileForPaymentByBankTransfer=Create credit transfer file (SEPA) CreateGuichet=Only office CreateBanque=Only bank From b026896a98b6be72835c6410f7214423b80fb2b5 Mon Sep 17 00:00:00 2001 From: quentin Date: Mon, 3 Aug 2020 10:33:48 +0200 Subject: [PATCH 02/97] FIX product label and desc were never updated when modifying trans --- htdocs/product/traduction.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index 59d30923f87..25c6eeb4caf 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -78,6 +78,7 @@ $cancel != $langs->trans("Cancel") && $object->label = $_POST["libelle"]; $object->description = dol_htmlcleanlastbr($_POST["desc"]); $object->other = dol_htmlcleanlastbr($_POST["other"]); + $object->update($object->id, $user); } else { From 72b2fb442b95fe107c05279bfb0ec606f86318f1 Mon Sep 17 00:00:00 2001 From: quentin Date: Mon, 3 Aug 2020 11:17:39 +0200 Subject: [PATCH 03/97] fix test libelle --- htdocs/core/lib/pdf.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index abff8486cc0..ade9c5f6101 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1215,7 +1215,7 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, global $db, $conf, $langs; $idprod=(! empty($object->lines[$i]->fk_product)?$object->lines[$i]->fk_product:false); - $label=(! empty($object->lines[$i]->label)?$object->lines[$i]->label:(! empty($object->lines[$i]->product_label)?$object->lines[$i]->product_label:'')); + $label=(!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->libelle) ? $object->lines[$i]->libelle : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''))); $desc=(! empty($object->lines[$i]->desc)?$object->lines[$i]->desc:(! empty($object->lines[$i]->description)?$object->lines[$i]->description:'')); $ref_supplier=(! empty($object->lines[$i]->ref_supplier)?$object->lines[$i]->ref_supplier:(! empty($object->lines[$i]->ref_fourn)?$object->lines[$i]->ref_fourn:'')); // TODO Not yet saved for supplier invoices, only supplier orders $note=(! empty($object->lines[$i]->note)?$object->lines[$i]->note:''); From e64b8eaf40de8bffb30f9f50cf88450137e4345b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 11:21:13 +0200 Subject: [PATCH 04/97] Fix debug credit transfer module --- dev/resources/sepa/text.txt | 6 + .../class/bonprelevement.class.php | 374 ++++++++++++------ htdocs/langs/en_US/admin.lang | 6 +- htdocs/langs/fr_FR/withdrawals.lang | 2 +- 4 files changed, 257 insertions(+), 131 deletions(-) diff --git a/dev/resources/sepa/text.txt b/dev/resources/sepa/text.txt index e6c05276be2..dbcfeded5a4 100644 --- a/dev/resources/sepa/text.txt +++ b/dev/resources/sepa/text.txt @@ -1,2 +1,8 @@ +Spec for credit transfer: +https://docs.oracle.com/cd/E39124_01/doc.91/e60210/fields_sepa_pay_file_appx.htm#EOAEL00515 + +To validate a SEPA file: +xmllint --schema pain.001.001.03.xsd T200801.xml --noout + To test a SEPA file: https://www.mesfluxdepaiement.fr/testez-vos-fichiers-sepa diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 29c70ba8fab..00a388e31dd 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1142,7 +1142,7 @@ class BonPrelevement extends CommonObject if (!$error) { /* - * Create file of direct debit order or credit transfer into a XML file + * Create file of type='direct-debit' for direct debit order or type='bank-transfer' for credit transfer into a XML file */ dol_syslog(__METHOD__."::Init direct debit or credit transfer file for ".count($factures_prev)." invoices", LOG_DEBUG); @@ -1569,11 +1569,11 @@ class BonPrelevement extends CommonObject // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf if ($result != -2) { - $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format); + $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); } /** - * SECTION CREATION SEPA FILE - CREDTI TRANSFER - ISO200022 + * SECTION CREATION SEPA FILE - CREDIT TRANSFER - ISO200022 */ // SEPA File Header fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); @@ -1674,7 +1674,7 @@ class BonPrelevement extends CommonObject // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf if ($result != -2) { - $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format); + $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); } /** @@ -1794,6 +1794,22 @@ class BonPrelevement extends CommonObject } + /** + * Build RUM number for a customer bank account + * + * @param string $row_code_client Customer code (soc.code_client) + * @param int $row_datec Creation date of bank account (rib.datec) + * @param string $row_drum Id of customer bank account (rib.rowid) + * @return string RUM number + */ + public static function buildRumNumber($row_code_client, $row_datec, $row_drum) + { + global $langs; + $pre = substr(dol_string_nospecial(dol_string_unaccent($langs->transnoentitiesnoconv('RUM'))), 0, 3); // Must always be on 3 char ('RUM' or 'UMR'. This is a protection against bad translation) + return $pre.'-'.$row_code_client.'-'.$row_drum.'-'.date('U', $row_datec); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Write recipient of request (customer) @@ -1807,9 +1823,11 @@ class BonPrelevement extends CommonObject * @param string $ref ref of invoice * @param int $facid id of invoice * @param string $rib_dom rib domiciliation + * @param string $type 'direct-debit' or 'credit-transfer' * @return void + * @see EnregDestinataireSEPA() */ - public function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $ref, $facid, $rib_dom = '') + public function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $ref, $facid, $rib_dom = '', $type = 'direct-debit') { // phpcs:enable fputs($this->file, "06"); @@ -1866,22 +1884,6 @@ class BonPrelevement extends CommonObject fputs($this->file, "\n"); } - - /** - * Build RUM number for a customer bank account - * - * @param string $row_code_client Customer code (soc.code_client) - * @param int $row_datec Creation date of bank account (rib.datec) - * @param string $row_drum Id of customer bank account (rib.rowid) - * @return string RUM number - */ - public static function buildRumNumber($row_code_client, $row_datec, $row_drum) - { - global $langs; - $pre = substr(dol_string_nospecial(dol_string_unaccent($langs->transnoentitiesnoconv('RUM'))), 0, 3); // Must always be on 3 char ('RUM' or 'UMR'. This is a protection against bad translation) - return $pre.'-'.$row_code_client.'-'.$row_drum.'-'.date('U', $row_datec); - } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Write recipient of request (customer) @@ -1903,9 +1905,11 @@ class BonPrelevement extends CommonObject * @param string $row_datec rib.datec, * @param string $row_drum rib.rowid used to generate rum * @param string $row_rum rib.rum Rum defined on company bank account + * @param string $type 'direct-debit' or 'credit-transfer' * @return string Return string with SEPA part DrctDbtTxInf + * @see EnregDestinataire() */ - public function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_ref, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum, $row_rum) + public function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_ref, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum, $row_rum, $type = 'direct-debit') { // phpcs:enable global $conf; @@ -1913,7 +1917,7 @@ class BonPrelevement extends CommonObject include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $CrLf = "\n"; - $Rowing = sprintf("%06d", $row_idfac); + $Rowing = sprintf("%10d", $row_idfac); // Define value for RUM // Example: RUMCustomerCode-CustomerBankAccountId-01424448606 (note: Date is date of creation of CustomerBankAccountId) @@ -1922,57 +1926,108 @@ class BonPrelevement extends CommonObject // Define date of RUM signature $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d'); - $XML_DEBITOR = ''; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - // $XML_DEBITOR .=' '.('AS-'.dol_trunc($row_ref,20).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters - $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('AS-'.dol_trunc($row_ref, 20)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.round($row_somme, 2).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$Rum.''.$CrLf; - $XML_DEBITOR .= ' '.$DtOfSgntr.''.$CrLf; - $XML_DEBITOR .= ' false'.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$row_bic.''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$row_country_code.''.$CrLf; - $addressline1 = dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))); - $addressline2 = dol_string_unaccent(strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => ""))); - if (trim($addressline1)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline1, 70, 'right', 'UTF-8', true)).''.$CrLf; - if (trim($addressline2)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline2, 70, 'right', 'UTF-8', true)).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.preg_replace('/\s/', '', $row_iban).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - // $XML_DEBITOR .=' '.($row_ref.'/'.$Rowing.'/'.$Rum).''.$CrLf; - // $XML_DEBITOR .=' '.dol_trunc($row_ref, 135).''.$CrLf; // 140 max - $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_USTRD != "") ? $conf->global->PRELEVEMENT_USTRD : dol_trunc($row_ref, 135)).''.$CrLf; // 140 max - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - return $XML_DEBITOR; + if ($type != 'credit-transfer') { + // SEPA Paiement Information of buyer for Direct debit + $XML_DEBITOR = ''; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum) + $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('AS-'.dol_trunc($row_ref, 20)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.round($row_somme, 2).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$Rum.''.$CrLf; + $XML_DEBITOR .= ' '.$DtOfSgntr.''.$CrLf; + $XML_DEBITOR .= ' false'.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$row_bic.''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$row_country_code.''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => ""))); + if (trim($addressline1)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline1, 70, 'right', 'UTF-8', true)).''.$CrLf; + if (trim($addressline2)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline2, 70, 'right', 'UTF-8', true)).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.preg_replace('/\s/', '', $row_iban).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + // A string with some information on payment - 140 max + $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_USTRD != "") ? $conf->global->PRELEVEMENT_USTRD : dol_trunc($row_ref, 135)).''.$CrLf; // 140 max + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + return $XML_DEBITOR; + } else { + // SEPA Paiement Information of seller for Credit Transfer + $XML_CREDITOR = ''; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum) + $XML_CREDITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('AS-'.dol_trunc($row_ref, 20)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.round($row_somme, 2).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + /* + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$Rum.''.$CrLf; + $XML_CREDITOR .= ' '.$DtOfSgntr.''.$CrLf; + $XML_CREDITOR .= ' false'.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + */ + //$XML_CREDITOR .= ' SLEV'.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$row_bic.''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$row_country_code.''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => ""))); + if (trim($addressline1)) $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc($addressline1, 70, 'right', 'UTF-8', true)).''.$CrLf; + if (trim($addressline2)) $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc($addressline2, 70, 'right', 'UTF-8', true)).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.preg_replace('/\s/', '', $row_iban).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + // A string with some information on payment - 140 max + $XML_CREDITOR .= ' '.(($conf->global->PRELEVEMENT_USTRD != "") ? $conf->global->PRELEVEMENT_USTRD : dol_trunc($row_ref, 135)).''.$CrLf; // 140 max + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + return $XML_CREDITOR; + } } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Write sender of request (me) + * Write sender of request (me). * + * @param string $type 'direct-debit' or 'credit-transfer' * @return void + * @see EnregEmetteurSEPA() */ - public function EnregEmetteur() + public function EnregEmetteur($type = 'direct-debit') { // phpcs:enable fputs($this->file, "03"); @@ -2044,9 +2099,11 @@ class BonPrelevement extends CommonObject * @param float $total Total * @param string $CrLf End of line character * @param string $format FRST or RCUR or ALL + * @param string $type 'direct-debit' or 'credit-transfer' * @return string String with SEPA Sender + * @see EnregEmetteur() */ - public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST') + public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST', $type = 'direct-debit') { // phpcs:enable // SEPA INITIALISATION @@ -2073,7 +2130,7 @@ class BonPrelevement extends CommonObject $this->raison_sociale = $account->proprio; } - // Récupération info demandeur + // Get pending payments $sql = "SELECT rowid, ref"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_bons as pb"; @@ -2084,69 +2141,132 @@ class BonPrelevement extends CommonObject { $obj = $this->db->fetch_object($resql); - // DONNEES BRUTES : par la suite Rows['XXX'] de la requete au dessus $country = explode(':', $configuration->global->MAIN_INFO_SOCIETE_COUNTRY); $IdBon = sprintf("%05d", $obj->rowid); $RefBon = $obj->ref; - // SEPA Paiement Information - $XML_SEPA_INFO = ''; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; - $XML_SEPA_INFO .= ' DD'.$CrLf; - $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; - $XML_SEPA_INFO .= ' '.$total.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' CORE'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$format.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$dateTime_ETAD.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; - $addressline1 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""))); - $addressline2 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""))); - if ($addressline1) $XML_SEPA_INFO .= ' '.$addressline1.''.$CrLf; - if ($addressline2) $XML_SEPA_INFO .= ' '.$addressline2.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $this->emetteur_iban).''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->emetteur_bic.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - /* $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->raison_sociale.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; - $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; - $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf;*/ - $XML_SEPA_INFO .= ' SLEV'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; + if ($type != 'credit-transfer') { + // SEPA Paiement Information of my company for Direct debit + $XML_SEPA_INFO = ''; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' DD'.$CrLf; + $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; + $XML_SEPA_INFO .= ' '.$total.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' CORE'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$format.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$dateTime_ETAD.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""))); + if ($addressline1) $XML_SEPA_INFO .= ' '.$addressline1.''.$CrLf; + if ($addressline2) $XML_SEPA_INFO .= ' '.$addressline2.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $this->emetteur_iban).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_bic.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + /* $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->raison_sociale.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ + $XML_SEPA_INFO .= ' SLEV'.$CrLf; // Field "Responsible of fees". Must be SLEV + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + } else { + // SEPA Paiement Information of my company for Credit Transfer + $XML_SEPA_INFO = ''; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' TRF'.$CrLf; + //$XML_SEPA_INFO .= ' False'.$CrLf; + $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; + $XML_SEPA_INFO .= ' '.$total.''.$CrLf; + /* + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' TRF'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SECU'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + */ + $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""))); + if ($addressline1) $XML_SEPA_INFO .= ' '.$addressline1.''.$CrLf; + if ($addressline2) $XML_SEPA_INFO .= ' '.$addressline2.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $this->emetteur_iban).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_bic.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + /* $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->raison_sociale.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ + $XML_SEPA_INFO .= ' SLEV'.$CrLf; // Field "Responsible of fees". Must be SLEV + /*$XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ + } } else { diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 57d430fc9e4..bd957f0ca02 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -546,9 +546,9 @@ Module54Desc=Management of contracts (services or recurring subscriptions) Module55Name=Barcodes Module55Desc=Barcode management Module56Name=Payment by credit transfer -Module56Desc=Management of payment of suppliers by credit transfer orders. It includes generation of SEPA file for European countries. -Module57Name=Bank Direct Debit payments -Module57Desc=Management of Direct Debit payment orders. It includes generation of SEPA file for European countries. +Module56Desc=Management of payment of suppliers by Credit Transfer orders. It includes generation of SEPA file for European countries. +Module57Name=Payments by Direct Debit +Module57Desc=Management of Direct Debit orders. It includes generation of SEPA file for European countries. Module58Name=ClickToDial Module58Desc=Integration of a ClickToDial system (Asterisk, ...) Module59Name=Bookmark4u diff --git a/htdocs/langs/fr_FR/withdrawals.lang b/htdocs/langs/fr_FR/withdrawals.lang index 446de9e09d3..d05f2663cfc 100644 --- a/htdocs/langs/fr_FR/withdrawals.lang +++ b/htdocs/langs/fr_FR/withdrawals.lang @@ -77,7 +77,7 @@ StatusMotif8=Autre motif CreateForSepaFRST=Créer fichier de prélèvement (SEPA FRST) CreateForSepaRCUR=Créer fichier de prélèvement (SEPA RCUR) CreateAll=Créer le fichier de prélèvement (tout) -CreateFileForPaymentByBankTransfer=Créer un virement (tout) +CreateFileForPaymentByBankTransfer=Créer un fichier de virement CreateSepaFileForPaymentByBankTransfer=Créer un fichier de virement (SEPA) CreateGuichet=Seulement guichet CreateBanque=Seulement banque From 55f3a8b4f8754d7df76ef5dc3147147af1243c73 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 11:37:55 +0200 Subject: [PATCH 05/97] Fix col size too large by migrating to dynamic format on tables --- htdocs/admin/system/database-tables.php | 38 ++++++++++++++++--------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php index 97b8237c6f2..e20347b954c 100644 --- a/htdocs/admin/system/database-tables.php +++ b/htdocs/admin/system/database-tables.php @@ -28,21 +28,27 @@ require '../../main.inc.php'; $langs->load("admin"); -if (!$user->admin) +if (!$user->admin) { accessforbidden(); +} $action = GETPOST('action', 'alpha'); if ($action == 'convert') { - $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." ENGINE=INNODB"; + $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." ENGINE=INNODB"; $db->query($sql); } if ($action == 'convertutf8') { - $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." CHARACTER SET utf8 COLLATE utf8_unicode_ci"; - $db->query($sql); + $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." CHARACTER SET utf8 COLLATE utf8_unicode_ci"; + $db->query($sql); +} +if ($action == 'convertdynamic') +{ + $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." ROW_FORMAT=DYNAMIC;"; + $db->query($sql); } @@ -87,8 +93,8 @@ else { if ($base == 1) { - print '
'; - print ''; + print '
'; + print '
'; print ''; print ''; print ''; @@ -119,13 +125,19 @@ else print ''; if (isset($obj->Engine) && $obj->Engine == "MyISAM") { - print ''; + print ''; } else { print ''; } - print ''; + print ''; print ''; print ''; print ''; @@ -136,7 +148,7 @@ else print ''; print ''; @@ -149,8 +161,8 @@ else if ($base == 2) { - print '
'; - print '
'.$langs->trans("TableName").''.$langs->trans("Type").''.$obj->Engine.''.$langs->trans("Convert").' InnoDb'.$langs->trans("Convert").' InnoDb '.$obj->Row_format.''; + print $obj->Row_format; + if (isset($obj->Row_format) && (in_array($obj->Row_format, array("Compact")))) + { + print '
'.$langs->trans("Convert").' Dynamic'; + } + print '
'.$obj->Rows.''.$obj->Avg_row_length.''.$obj->Data_length.''.$obj->Collation; if (isset($obj->Collation) && (in_array($obj->Collation, array("utf8mb4_general_ci", "utf8mb4_unicode_ci", "latin1_swedish_ci")))) { - print '
'.$langs->trans("Convert").' UTF8'; + print '
'.$langs->trans("Convert").' UTF8'; } print '
'; + print '
'; + print '
'; print ''; print ''; print ''; @@ -189,8 +201,8 @@ else if ($base == 4) { // Sqlite by PDO or by Sqlite3 - print '
'; - print '
'.$langs->trans("TableName").'Nb of tuples
'; + print '
'; + print '
'; print ''; print ''; print ''; From bbfca90260576890d2b1e77833caa7ec782c77d7 Mon Sep 17 00:00:00 2001 From: quentin Date: Mon, 3 Aug 2020 11:54:26 +0200 Subject: [PATCH 06/97] FIX Missing PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE conf in supplier order --- htdocs/fourn/commande/card.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 43964b38431..0b7eb338b69 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -460,11 +460,26 @@ if (empty($reshook)) if ($idprod > 0) { $label = $productsupplier->label; - + // Define output language + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id', 'aZ09')) + $newlang = GETPOST('lang_id', 'aZ09'); + if (empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $desc = (!empty($productsupplier->multilangs [$outputlangs->defaultlang] ["description"])) ? $productsupplier->multilangs [$outputlangs->defaultlang] ["description"] : $productsupplier->description; + } else { + $desc = $productsupplier->description; + } // if we use supplier description of the products if (!empty($productsupplier->desc_supplier) && !empty($conf->global->PRODUIT_FOURN_TEXTS)) { $desc = $productsupplier->desc_supplier; - } else $desc = $productsupplier->description; + } if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); From d59bcd3f5bd251f7574bb7460558423be3db886e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 12:08:33 +0200 Subject: [PATCH 07/97] FFIX error creating record when extrafields price exists in other entity --- htdocs/core/class/commonobject.class.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ae8ae544d52..3359dcb9a64 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5531,11 +5531,12 @@ abstract class CommonObject $new_array_options[$key] = null; } break; - case 'double': + case 'price': + case 'double': $value = price2num($value); if (!is_numeric($value) && $value != '') { - dol_syslog($langs->trans("ExtraFieldHasWrongValue")." sur ".$attributeLabel."(".$value."is not '".$attributeType."')", LOG_DEBUG); + dol_syslog($langs->trans("ExtraFieldHasWrongValue")." for ".$attributeLabel."(".$value."is not '".$attributeType."')", LOG_DEBUG); $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); return -1; } @@ -5589,9 +5590,6 @@ abstract class CommonObject $new_array_options[$key] = $this->array_options[$key]; } break; - case 'price': - $new_array_options[$key] = price2num($this->array_options[$key]); - break; case 'date': case 'datetime': // If data is a string instead of a timestamp, we convert it @@ -5689,7 +5687,7 @@ abstract class CommonObject { if (!isset($extrafields->attributes[$this->table_element]['type'][$tmpkey])) // If field not already added previously { - if (in_array($tmpval, array('int', 'double'))) $sql .= ", 0"; + if (in_array($tmpval, array('int', 'double', 'price'))) $sql .= ", 0"; else $sql .= ", ''"; } } @@ -7963,6 +7961,7 @@ abstract class CommonObject $now = dol_now(); $fieldvalues = $this->setSaveQuery(); + if (array_key_exists('date_creation', $fieldvalues) && empty($fieldvalues['date_creation'])) $fieldvalues['date_creation'] = $this->db->idate($now); if (array_key_exists('fk_user_creat', $fieldvalues) && !($fieldvalues['fk_user_creat'] > 0)) $fieldvalues['fk_user_creat'] = $user->id; unset($fieldvalues['rowid']); // The field 'rowid' is reserved field name for autoincrement field so we don't need it into insert. From 576363f353ff6d1392d407be58b544d769379cd9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 12:26:26 +0200 Subject: [PATCH 08/97] Fix error message --- htdocs/projet/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 1fb01bb52bb..587493709f2 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -180,14 +180,14 @@ if (empty($reshook)) if ($result < 0) { $langs->load("errors"); - setEventMessages($langs->trans($object->error), null, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); $error++; } } else { $langs->load("errors"); - setEventMessages($langs->trans($object->error), null, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); $error++; } if (!$error && !empty($object->id) > 0) From ce18a4f029d10a04fce28a17f8041d3f937938ec Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Mon, 3 Aug 2020 12:28:12 +0200 Subject: [PATCH 09/97] FIX 12.0 - in dol_string_onlythesehtmltags, remove the class attribute by default --- htdocs/core/lib/functions.lib.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 91a3061dd41..76b94481823 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5685,12 +5685,13 @@ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto = * Clean a string to keep only desirable HTML tags. * * @param string $stringtoclean String to clean - * @param string $cleanalsosomestyles Clean also some tags + * @param boolean $cleanalsosomestyles Remove absolute/fixed positioning from inline styles + * @param boolean $removeclassattribute Remove the class attribute from tags * @return string String cleaned * * @see dol_escape_htmltag() strip_tags() dol_string_nohtmltag() dol_string_neverthesehtmltags() */ -function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1) +function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1, $removeclassattribute = 1) { $allowed_tags = array( "html", "head", "meta", "body", "article", "a", "abbr", "b", "blockquote", "br", "cite", "div", "dl", "dd", "dt", "em", "font", "img", "ins", "hr", "i", "li", "link", @@ -5702,7 +5703,10 @@ function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1) $allowed_tags_string = '<'.$allowed_tags_string.'>'; if ($cleanalsosomestyles) { - $stringtoclean = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/', '', $stringtoclean); // Note: If hacker try to introduce css comment into string to bypass this regex, the string must also be encoded by the dol_htmlentitiesbr during output so it become harmless + $stringtoclean = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/i', '', $stringtoclean); // Note: If hacker try to introduce css comment into string to bypass this regex, the string must also be encoded by the dol_htmlentitiesbr during output so it become harmless + } + if ($removeclassattribute) { + $stringtoclean = preg_replace('/(<[^>]+)\s+class=((["\']).*?\\3|\\w*)/i', '\\1', $stringtoclean); } $temp = strip_tags($stringtoclean, $allowed_tags_string); From c2bb0431f0b0f390a3d8263d6e57504dce29623c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 12:31:30 +0200 Subject: [PATCH 10/97] FIX input field of extrafields must keep data if form submit fails. --- htdocs/core/class/commonobject.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 3359dcb9a64..9894d2e6c64 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7048,7 +7048,7 @@ abstract class CommonObject if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label']) > 0) { $out .= "\n"; - $out .= ' '; + $out .= ' '; $out .= "\n"; $extrafields_collapse_num = ''; @@ -7186,7 +7186,7 @@ abstract class CommonObject // HTML, select, integer and text add default value if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('html', 'text', 'select', 'int'))) { - if ($action == 'create') $value = $extrafields->attributes[$this->table_element]['default'][$key]; + if ($action == 'create') $value = GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix) ? GETPOST($keyprefix.'options_'.$key.$keysuffix, 'none', 3) : $extrafields->attributes[$this->table_element]['default'][$key]; else $value = $this->array_options['options_'.$key]; } @@ -7270,7 +7270,7 @@ abstract class CommonObject setListDependencies(); }); '."\n"; - $out .= ' '."\n"; + $out .= ' '."\n"; } } return $out; From defbd26f95f058d59c91800ecf7773a1a6f2c047 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 12:33:22 +0200 Subject: [PATCH 11/97] Help to fight errors ErrorBadValueForParamNotAString --- htdocs/core/class/translate.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index 3fc3151030a..f20fcbcd5b9 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -546,7 +546,10 @@ class Translate { global $conf, $db; - if (!is_string($key)) return 'ErrorBadValueForParamNotAString'; // Avoid multiple errors with code not using function correctly. + if (!is_string($key)) { + //xdebug_print_function_stack('ErrorBadValueForParamNotAString'); + return 'ErrorBadValueForParamNotAString'; // Avoid multiple errors with code not using function correctly. + } $newstr = $key; if (preg_match('/^Civility([0-9A-Z]+)$/i', $key, $reg)) From 8c34acbf55ae69153cfa3fa5292c5f2071bc3e21 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 14:11:15 +0200 Subject: [PATCH 12/97] FIX Warning if no bank account defined --- .../class/bonprelevement.class.php | 252 +++++++++--------- htdocs/compta/prelevement/create.php | 13 +- htdocs/societe/class/societe.class.php | 42 +-- 3 files changed, 158 insertions(+), 149 deletions(-) diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 00a388e31dd..929c0958d71 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1473,7 +1473,7 @@ class BonPrelevement extends CommonObject * * @param string $format FRST, RCUR or ALL * @param string $executiondate Date to execute transfer - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return int >=0 if OK, <0 if KO */ public function generate($format = 'ALL', $executiondate = '', $type = 'direct-debit') @@ -1501,114 +1501,9 @@ class BonPrelevement extends CommonObject { $found++; - if ($type == 'bank-transfer') { + if ($type != 'bank-transfer') { /** - * SECTION CREATION FICHIER SEPA - CREDIT TRANSFER - */ - // SEPA Initialisation - $CrLf = "\n"; - - $now = dol_now(); - - $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S'); - - $date_actu = $now; - if (!empty($executiondate)) $date_actu = $executiondate; - - $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d'); - $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S'); - $fileCrediteurSection = ''; - $fileEmetteurSection = ''; - $i = 0; - - /* - * Section Creditor (sepa Crediteurs bloc lines) - */ - - $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; - $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; - $sql .= " f.ref as fac, pf.fk_facture as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; - $sql .= " FROM"; - $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; - $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf,"; - $sql .= " ".MAIN_DB_PREFIX."societe as soc,"; - $sql .= " ".MAIN_DB_PREFIX."c_country as c,"; - $sql .= " ".MAIN_DB_PREFIX."societe_rib as rib"; - $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; - $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql .= " AND pf.fk_facture_fourn = f.rowid"; - $sql .= " AND soc.fk_pays = c.rowid"; - $sql .= " AND soc.rowid = f.fk_soc"; - $sql .= " AND rib.fk_soc = f.fk_soc"; - $sql .= " AND rib.default_rib = 1"; - $sql .= " AND rib.type = 'ban'"; - //print $sql; - - // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice. - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); - $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum); - $this->total = $this->total + $obj->somme; - $i++; - } - $nbtotalDrctDbtTxInf = $i; - } - else - { - fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers - $result = -2; - } - - // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf - if ($result != -2) - { - $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); - } - - /** - * SECTION CREATION SEPA FILE - CREDIT TRANSFER - ISO200022 - */ - // SEPA File Header - fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); - fputs($this->file, ''.$CrLf); - fputs($this->file, ' '.$CrLf); - // SEPA Group header - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.('CREDTRANS'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); - fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); - fputs($this->file, ' '.$i.''.$CrLf); - fputs($this->file, ' '.$this->total.''.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$conf->global->PRELEVEMENT_ICS.''.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - // SEPA File Emetteur (mycompany) - if ($result != -2) - { fputs($this-> file, $fileEmetteurSection); } - // SEPA File Creditors - if ($result != -2) - { fputs($this-> file, $fileCrediteurSection); } - // SEPA FILE FOOTER - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ''.$CrLf); - } else { - /** - * SECTION CREATION FICHIER SEPA + * SECTION CREATION FICHIER SEPA - DIRECT DEBIT */ // SEPA Initialisation $CrLf = "\n"; @@ -1659,7 +1554,7 @@ class BonPrelevement extends CommonObject { $obj = $this->db->fetch_object($resql); $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); - $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum); + $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); $this->total = $this->total + $obj->somme; $i++; } @@ -1686,7 +1581,7 @@ class BonPrelevement extends CommonObject fputs($this->file, ' '.$CrLf); // SEPA Group header fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.('PREL'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); + fputs($this->file, ' '.('DD/'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); fputs($this->file, ' '.$i.''.$CrLf); fputs($this->file, ' '.$this->total.''.$CrLf); @@ -1711,21 +1606,126 @@ class BonPrelevement extends CommonObject fputs($this->file, ' '.$CrLf); fputs($this->file, ' '.$CrLf); fputs($this->file, ''.$CrLf); + } else { + /** + * SECTION CREATION FICHIER SEPA - CREDIT TRANSFER + */ + // SEPA Initialisation + $CrLf = "\n"; + + $now = dol_now(); + + $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S'); + + $date_actu = $now; + if (!empty($executiondate)) $date_actu = $executiondate; + + $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d'); + $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S'); + $fileCrediteurSection = ''; + $fileEmetteurSection = ''; + $i = 0; + + /* + * Section Creditor (sepa Crediteurs bloc lines) + */ + + $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; + $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; + $sql .= " f.ref as fac, pf.fk_facture_fourn as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; + $sql .= " FROM"; + $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; + $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf,"; + $sql .= " ".MAIN_DB_PREFIX."societe as soc,"; + $sql .= " ".MAIN_DB_PREFIX."c_country as c,"; + $sql .= " ".MAIN_DB_PREFIX."societe_rib as rib"; + $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; + $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; + $sql .= " AND pf.fk_facture_fourn = f.rowid"; + $sql .= " AND soc.fk_pays = c.rowid"; + $sql .= " AND soc.rowid = f.fk_soc"; + $sql .= " AND rib.fk_soc = f.fk_soc"; + $sql .= " AND rib.default_rib = 1"; + $sql .= " AND rib.type = 'ban'"; + //print $sql; + + // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice. + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); + $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); + $this->total = $this->total + $obj->somme; + $i++; + } + $nbtotalDrctDbtTxInf = $i; + } + else + { + fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers + $result = -2; + } + + // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf + if ($result != -2) + { + $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); + } + + /** + * SECTION CREATION SEPA FILE - CREDIT TRANSFER - ISO200022 + */ + // SEPA File Header + fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); + fputs($this->file, ''.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA Group header + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.('TRF/'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); + fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); + fputs($this->file, ' '.$i.''.$CrLf); + fputs($this->file, ' '.$this->total.''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$conf->global->PRELEVEMENT_ICS.''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA File Emetteur (mycompany) + if ($result != -2) + { fputs($this-> file, $fileEmetteurSection); } + // SEPA File Creditors + if ($result != -2) + { fputs($this-> file, $fileCrediteurSection); } + // SEPA FILE FOOTER + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ''.$CrLf); } } // Build file for Other Countries with unknow format if (!$found) { - if ($type == 'bank-transfer') { + if ($type != 'bank-transfer') { $sql = "SELECT pl.amount"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql .= " ".MAIN_DB_PREFIX."facture as f,"; $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf"; $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql .= " AND pf.fk_facture_fourn = f.rowid"; + $sql .= " AND pf.fk_facture = f.rowid"; // Lines $i = 0; @@ -1751,11 +1751,11 @@ class BonPrelevement extends CommonObject $sql = "SELECT pl.amount"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql .= " ".MAIN_DB_PREFIX."facture as f,"; + $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf"; $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql .= " AND pf.fk_facture = f.rowid"; + $sql .= " AND pf.fk_facture_fourn = f.rowid"; // Lines $i = 0; @@ -1795,7 +1795,7 @@ class BonPrelevement extends CommonObject /** - * Build RUM number for a customer bank account + * Generate dynamically a RUM number for a customer bank account * * @param string $row_code_client Customer code (soc.code_client) * @param int $row_datec Creation date of bank account (rib.datec) @@ -1823,7 +1823,7 @@ class BonPrelevement extends CommonObject * @param string $ref ref of invoice * @param int $facid id of invoice * @param string $rib_dom rib domiciliation - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return void * @see EnregDestinataireSEPA() */ @@ -1905,7 +1905,7 @@ class BonPrelevement extends CommonObject * @param string $row_datec rib.datec, * @param string $row_drum rib.rowid used to generate rum * @param string $row_rum rib.rum Rum defined on company bank account - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return string Return string with SEPA part DrctDbtTxInf * @see EnregDestinataire() */ @@ -1917,7 +1917,7 @@ class BonPrelevement extends CommonObject include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $CrLf = "\n"; - $Rowing = sprintf("%10d", $row_idfac); + $Rowing = sprintf("%010d", $row_idfac); // Define value for RUM // Example: RUMCustomerCode-CustomerBankAccountId-01424448606 (note: Date is date of creation of CustomerBankAccountId) @@ -1926,7 +1926,7 @@ class BonPrelevement extends CommonObject // Define date of RUM signature $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d'); - if ($type != 'credit-transfer') { + if ($type != 'bank-transfer') { // SEPA Paiement Information of buyer for Direct debit $XML_DEBITOR = ''; $XML_DEBITOR .= ' '.$CrLf; @@ -2023,7 +2023,7 @@ class BonPrelevement extends CommonObject /** * Write sender of request (me). * - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return void * @see EnregEmetteurSEPA() */ @@ -2099,7 +2099,7 @@ class BonPrelevement extends CommonObject * @param float $total Total * @param string $CrLf End of line character * @param string $format FRST or RCUR or ALL - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return string String with SEPA Sender * @see EnregEmetteur() */ @@ -2145,11 +2145,11 @@ class BonPrelevement extends CommonObject $IdBon = sprintf("%05d", $obj->rowid); $RefBon = $obj->ref; - if ($type != 'credit-transfer') { + if ($type != 'bank-transfer') { // SEPA Paiement Information of my company for Direct debit $XML_SEPA_INFO = ''; $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' '.('DD/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; $XML_SEPA_INFO .= ' DD'.$CrLf; $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; $XML_SEPA_INFO .= ' '.$total.''.$CrLf; @@ -2208,7 +2208,7 @@ class BonPrelevement extends CommonObject // SEPA Paiement Information of my company for Credit Transfer $XML_SEPA_INFO = ''; $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' '.('TRF/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; $XML_SEPA_INFO .= ' TRF'.$CrLf; //$XML_SEPA_INFO .= ' False'.$CrLf; $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; @@ -2224,7 +2224,7 @@ class BonPrelevement extends CommonObject $XML_SEPA_INFO .= ' SECU'.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; */ - $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; + $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index fdbb6189c5c..e3f3e6beaf4 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -379,10 +379,15 @@ if ($resql) // RUM print ''; // Amount diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index e3d6409ddd6..6c8ab008252 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2798,7 +2798,7 @@ class Societe extends CommonObject * Return bank number property of thirdparty (label or rum) * * @param string $mode 'label' or 'rum' or 'format' - * @return string Bank number + * @return string Bank label or RUM or '' if no bank account found */ public function display_rib($mode = 'label') { @@ -2808,27 +2808,31 @@ class Societe extends CommonObject $bac = new CompanyBankAccount($this->db); $bac->fetch(0, $this->id); - if ($mode == 'label') - { - return $bac->getRibLabel(true); - } - elseif ($mode == 'rum') - { - if (empty($bac->rum)) + if ($bac->id > 0) { // If a bank account has been found for company $this->id + if ($mode == 'label') { - require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; - $prelevement = new BonPrelevement($this->db); - $bac->fetch_thirdparty(); - $bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id); + return $bac->getRibLabel(true); } - return $bac->rum; + elseif ($mode == 'rum') + { + if (empty($bac->rum)) + { + require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; + $prelevement = new BonPrelevement($this->db); + $bac->fetch_thirdparty(); + $bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id); + } + return $bac->rum; + } + elseif ($mode == 'format') + { + return $bac->frstrecur; + } else { + return 'BadParameterToFunctionDisplayRib'; + } + } else { + return ''; } - elseif ($mode == 'format') - { - return $bac->frstrecur; - } - - return 'BadParameterToFunctionDisplayRib'; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps From d1f92fb66b749585d779dce5795be8b88c306443 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 14:15:14 +0200 Subject: [PATCH 13/97] NEW: Add module Credit transfer SEPA to manage payment of supplier using bank credit transfer SEPA files --- ChangeLog | 2 +- htdocs/core/modules/modPaymentByBankTransfer.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c74f30755c6..5df348fce77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,7 @@ English Dolibarr ChangeLog ***** ChangeLog for 13.0.0 compared to 12.0.0 ***** For users: - +NEW: Add module Credit transfer SEPA to manage payment of supplier using bank credit transfer SEPA files WARNING: diff --git a/htdocs/core/modules/modPaymentByBankTransfer.class.php b/htdocs/core/modules/modPaymentByBankTransfer.class.php index d68274e2dee..9ea1bf00f29 100644 --- a/htdocs/core/modules/modPaymentByBankTransfer.class.php +++ b/htdocs/core/modules/modPaymentByBankTransfer.class.php @@ -54,7 +54,7 @@ class modPaymentByBankTransfer extends DolibarrModules $this->description = "Management of payment by bank transfer"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'development'; + $this->version = 'dolibarr'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Name of png file (without png) used for this module From b6a3938921476d29138b07f73e880050d041372e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 14:32:42 +0200 Subject: [PATCH 14/97] FIX Size of image on the help popup of modules --- htdocs/admin/modulehelp.php | 2 +- htdocs/theme/eldy/global.inc.php | 3 ++- htdocs/theme/md/style.css.php | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index d5bf12f1061..ec0e5d8bb9b 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -272,7 +272,7 @@ print '
'; $picto = 'object_'.$objMod->picto; -print load_fiche_titre(($modulename ? $modulename : $moduledesc), $moreinfo, $picto); +print load_fiche_titre(($modulename ? $modulename : $moduledesc), $moreinfo, $picto, 0, '', 'titlemodulehelp'); print '
'; dol_fiche_head($head, $mode, '', -1); diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 76df116ec08..9f2e00946bd 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -3948,7 +3948,8 @@ div.boximport { .fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor); } td.widthpictotitle { width: 26px; text-align: ; } -span.widthpictotitle { font-size: 1.7em; }; +span.widthpictotitle { font-size: 1.7em; } +table.titlemodulehelp tr td img.widthpictotitle { width: 80px; } .dolgraphtitle { margin-top: 6px; margin-bottom: 4px; } .dolgraphtitlecssboxes { /* margin: 0px; */ } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index b9fe51ca252..3d8f424b8ce 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3860,6 +3860,7 @@ div.boximport { .fieldrequired { font-weight: bold; color: #000055; } .widthpictotitle { width: 40px; font-size: 1.4em; text-align: ; } +table.titlemodulehelp tr td img.widthpictotitle { width: 80px; } .dolgraphtitle { margin-top: 6px; margin-bottom: 4px; } .dolgraphtitlecssboxes { /* margin: 0px; */ } From 2d192431bc7ec9c52089a561c83ddbdb887b8a09 Mon Sep 17 00:00:00 2001 From: VERDOL Gauthier Date: Mon, 3 Aug 2020 14:59:51 +0200 Subject: [PATCH 15/97] FIX : wrong element var for fetch_name_optionals_label function with expeditions --- htdocs/core/class/commondocgenerator.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 4a8e097fd6d..9f5dac2a0c3 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -513,7 +513,7 @@ abstract class CommonDocGenerator // Retrieve extrafields if (is_array($object->array_options) && count($object->array_options)) { - $extrafieldkey = $object->element; + $extrafieldkey = $object->table_element; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); From aa696d834356460b6e48d31a1905f8a41be3c0ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 15:17:37 +0200 Subject: [PATCH 16/97] Show warning in kanban view --- htdocs/admin/modules.php | 8 +++--- htdocs/core/modules/DolibarrModules.class.php | 28 +++++-------------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index e5e221c529b..bd30d863bdc 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -506,10 +506,10 @@ if ($mode == 'common' || $mode == 'commonkanban') $moreforfilter .= '
'.$moreinfo.'
'.$moreinfo2.'
'; $moreforfilter .= '
'; - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Keyword').': '; $moreforfilter .= '
'; - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Origin').': '.$form->selectarray('search_nature', $arrayofnatures, dol_escape_htmltag($search_nature), 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); $moreforfilter .= '
'; if (!empty($conf->global->MAIN_FEATURES_LEVEL)) @@ -518,11 +518,11 @@ if ($mode == 'common' || $mode == 'commonkanban') if ($conf->global->MAIN_FEATURES_LEVEL < 0) $array_version['deprecated'] = $langs->trans("Deprecated"); if ($conf->global->MAIN_FEATURES_LEVEL > 0) $array_version['experimental'] = $langs->trans("Experimental"); if ($conf->global->MAIN_FEATURES_LEVEL > 1) $array_version['development'] = $langs->trans("Development"); - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Version').': '.$form->selectarray('search_version', $array_version, $search_version, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); $moreforfilter .= '
'; } - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Status').': '.$form->selectarray('search_status', array('active'=>$langs->transnoentitiesnoconv("Enabled"), 'disabled'=>$langs->transnoentitiesnoconv("Disabled")), $search_status, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); $moreforfilter .= '
'; $moreforfilter .= ' '; diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 273947ec205..03afbb0c7af 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -2217,6 +2217,12 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($this))); + $version = $this->getVersion(0); + $versiontrans = ''; + if (preg_match('/development/i', $version)) $versiontrans .= 'warning'; + if (preg_match('/experimental/i', $version)) $versiontrans .= 'warning'; + if (preg_match('/deprecated/i', $version)) $versiontrans .= 'warning'; + print '
@@ -2233,39 +2239,19 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it print img_object($alttext, 'generic', 'class="inline-block valignmiddle"'); } - $version = $this->getVersion(0); - $versiontrans = ''; - if (preg_match('/development/i', $version)) $versiontrans .= 'warning'; - if (preg_match('/experimental/i', $version)) $versiontrans .= 'warning'; - if (preg_match('/deprecated/i', $version)) $versiontrans .= 'warning'; if ($this->isCoreOrExternalModule() == 'external' || preg_match('/development|experimental|deprecated/i', $version)) { print 'getVersion(1).'">'; print $this->getVersion(1); print ''; } - /*print ''; - print '
'; - print '
'; - print $codeenabledisable; - print '
'; - print '
'; - print $codetoconfig; - print '
'; - print '
'; - print '
'; - */ - print '
'.$this->getName().' '.nl2br($this->getDesc()).''; - /*print 'getVersion(1).'">'; - print $this->getVersion(1); - print ''; */ - print '
'; + if ($versiontrans) print img_warning($langs->trans("Version").' '.$this->getVersion(1)).' '; print ''.img_picto(($this->isCoreOrExternalModule() == 'external' ? $langs->trans("ExternalModule").' - ' : '').$langs->trans("ClickToShowDescription"), $imginfo).''; print '

'; From 15a634959f5d095a08bcd4b0a4ec188e603444f1 Mon Sep 17 00:00:00 2001 From: bahfir abbes Date: Mon, 3 Aug 2020 14:31:33 +0100 Subject: [PATCH 17/97] fix:value of checked option must be the same as in showInputfield function --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 3b13b867fd7..08b3e037499 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -156,7 +156,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = (GETPOST($key) == 'on' ? 1 : 0); + $value = (GETPOST($key) == '1' ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From fa26d2acdfcc7c59b1cc3a1a0ae24183bbaeeca5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 16:31:52 +0200 Subject: [PATCH 18/97] css --- htdocs/core/modules/DolibarrModules.class.php | 6 +++--- htdocs/theme/eldy/info-box.inc.php | 14 +++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 03afbb0c7af..764519862a6 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -2226,7 +2226,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it print '
-
'; +
'; $alttext = ''; //if (is_array($objMod->need_dolibarr_version)) $alttext.=($alttext?' - ':'').'Dolibarr >= '.join('.',$objMod->need_dolibarr_version); @@ -2246,12 +2246,12 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it } print '
-
+
'.$this->getName().' '.nl2br($this->getDesc()).''; print '
'; - if ($versiontrans) print img_warning($langs->trans("Version").' '.$this->getVersion(1)).' '; + //if ($versiontrans) print img_warning($langs->trans("Version").' '.$this->getVersion(1)).' '; print ''.img_picto(($this->isCoreOrExternalModule() == 'external' ? $langs->trans("ExternalModule").' - ' : '').$langs->trans("ClickToShowDescription"), $imginfo).''; print '

'; diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index b995b551f43..e90da687135 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -166,15 +166,17 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> padding: 5px 10px; margin-left: 84px; } - .info-box-sm .info-box-content{ margin-left: 80px; } -/*.info-box-setup span { - color: var(--colortexttitlenotab2); +.info-box-sm .info-box-module-enabled { + background: linear-gradient(0.35turn, #fff, #fff, #f6faf8, #e4efe8) } -.tdsetuppicto span { - color: var(--colortexttitlenotab2); +.info-box-sm .info-box-content-warning { + background: #ffd7a3; +} +/*.info-box-icon.info-box-icon-module-enabled { + background: #e4f0e4 !important; }*/ .info-box-number { @@ -212,6 +214,8 @@ a.info-box-text{ text-decoration: none;} + + /* ICONS INFO BOX */ Date: Mon, 3 Aug 2020 16:36:31 +0200 Subject: [PATCH 19/97] css --- htdocs/theme/eldy/info-box.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index e90da687135..27b0ee34481 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -170,7 +170,8 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> margin-left: 80px; } .info-box-sm .info-box-module-enabled { - background: linear-gradient(0.35turn, #fff, #fff, #f6faf8, #e4efe8) + /* background: linear-gradient(0.35turn, #fff, #fff, #f6faf8, #e4efe8) */ + background: linear-gradient(0.4turn, #fff, #fff, #fff, #e4efe8); } .info-box-sm .info-box-content-warning { background: #ffd7a3; From c78b19b3b89e49b04c0dbfee1bcc390254d8ce24 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 16:39:52 +0200 Subject: [PATCH 20/97] Move module as experimental (it is working enough). --- htdocs/core/modules/modRecruitment.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modRecruitment.class.php b/htdocs/core/modules/modRecruitment.class.php index c9093c34272..0cbe9da017b 100644 --- a/htdocs/core/modules/modRecruitment.class.php +++ b/htdocs/core/modules/modRecruitment.class.php @@ -62,7 +62,7 @@ class modRecruitment extends DolibarrModules // Used only if file README.md and README-LL.md not found. $this->descriptionlong = "Manage and follow recruitment campaign for new job positions"; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = 'development'; + $this->version = 'experimental'; // Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; From 22f69f0da94b8669175108e836e945365b7d23cb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 17:39:18 +0200 Subject: [PATCH 21/97] CSS --- htdocs/theme/eldy/global.inc.php | 2 ++ htdocs/theme/eldy/info-box.inc.php | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 67702d93ee6..45214c06a4d 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -4053,6 +4053,8 @@ div.titre { } div.fiche > table.table-fiche-title:first-of-type div { color: var(--colortexttitlenotab); + font-size: 1.05em; + /* text-transform: uppercase; */ /* font-weight: 600; */ } div.titre { diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index 27b0ee34481..bf8d6220e00 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -173,9 +173,12 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> /* background: linear-gradient(0.35turn, #fff, #fff, #f6faf8, #e4efe8) */ background: linear-gradient(0.4turn, #fff, #fff, #fff, #e4efe8); } -.info-box-sm .info-box-content-warning { - background: #ffd7a3; +.info-box-content-warning span.font-status4 { + color: #bc9526 !important; } +/*.info-box-sm .info-box-content-warning { + background: #ffd7a3; +}*/ /*.info-box-icon.info-box-icon-module-enabled { background: #e4f0e4 !important; }*/ From f62717a16afcb5e975dab5de8741fe0095111fe9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 20:16:33 +0200 Subject: [PATCH 22/97] FIX Debug module direct debit order. Solve conflict with credit transfer --- htdocs/compta/prelevement/card.php | 4 +- .../class/bonprelevement.class.php | 274 ++++++++++-------- .../class/ligneprelevement.class.php | 2 +- htdocs/compta/prelevement/factures.php | 40 ++- htdocs/compta/prelevement/fiche-rejet.php | 4 +- htdocs/compta/prelevement/fiche-stat.php | 2 +- .../fourn/class/fournisseur.facture.class.php | 2 +- htdocs/langs/en_US/withdrawals.lang | 6 +- 8 files changed, 195 insertions(+), 139 deletions(-) diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index ab8b5b8ae40..00bcd088e27 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -146,11 +146,9 @@ if (empty($reshook)) $dt = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); $error = $object->set_infocredit($user, $dt); - if ($error) { - header("Location: card.php?id=".$id."&error=$error"); - exit; + setEventMessages($object->error, $object->errors, 'errors'); } } } diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 929c0958d71..9210e0e62c0 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; @@ -67,6 +68,9 @@ class BonPrelevement extends CommonObject public $emetteur_bic; public $emetteur_ics; + public $date_trans; + public $user_trans; + public $total; public $fetched; public $statut; // 0-Wait, 1-Trans, 2-Done @@ -425,7 +429,7 @@ class BonPrelevement extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Set direct debit order to "credited" status. + * Set direct debit or credit transfer order to "paid" status. * * @param User $user Id of user * @param int $date date of action @@ -440,128 +444,158 @@ class BonPrelevement extends CommonObject if ($this->fetched == 1) { - if ($date >= $this->date_trans) + if ($date < $this->date_trans) { - if ($this->db->begin()) + $this->error = 'DateOfMovementLowerThanDateOfFileTransmission'; + dol_syslog("bon-prelevment::set_infocredit 1027 ".$this->error); + return -1027; + } + + $this->db->begin(); + + $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_bons "; + $sql .= " SET fk_user_credit = ".$user->id; + $sql .= ", statut = ".self::STATUS_CREDITED; + $sql .= ", date_credit = '".$this->db->idate($date)."'"; + $sql .= " WHERE rowid=".$this->id; + $sql .= " AND entity = ".$conf->entity; + $sql .= " AND statut = ".self::STATUS_TRANSFERED; + + $resql = $this->db->query($sql); + if ($resql) + { + $langs->load('withdrawals'); + $subject = $langs->trans("InfoCreditSubject", $this->ref); + $message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour')); + + //Add payment of withdrawal into bank + $bankaccount = $conf->global->PRELEVEMENT_ID_BANKACCOUNT; + $facs = array(); + $amounts = array(); + $amountsperthirdparty = array(); + + $facs = $this->getListInvoices(1); + + // Loop on each invoice. $facs=array(0=>id, 1=>amount requested) + $num = count($facs); + for ($i = 0; $i < $num; $i++) { - $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_bons "; - $sql .= " SET fk_user_credit = ".$user->id; - $sql .= ", statut = ".self::STATUS_CREDITED; - $sql .= ", date_credit = '".$this->db->idate($date)."'"; - $sql .= " WHERE rowid=".$this->id; - $sql .= " AND entity = ".$conf->entity; - $sql .= " AND statut = ".self::STATUS_TRANSFERED; - - if ($this->db->query($sql)) - { - $langs->load('withdrawals'); - $subject = $langs->trans("InfoCreditSubject", $this->ref); - $message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour')); - - //Add payment of withdrawal into bank - $bankaccount = $conf->global->PRELEVEMENT_ID_BANKACCOUNT; - $facs = array(); - $amounts = array(); - $amountsperthirdparty = array(); - - $facs = $this->getListInvoices(1); - - // Loop on each invoice. $facs=array(0=>id, 1=>amount requested) - $num = count($facs); - for ($i = 0; $i < $num; $i++) - { - $fac = new Facture($this->db); - $fac->fetch($facs[$i][0]); - $amounts[$fac->id] = $facs[$i][1]; - $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1]; - - $totalpaye = $fac->getSommePaiement(); - $totalcreditnotes = $fac->getSumCreditNotesUsed(); - $totaldeposits = $fac->getSumDepositsUsed(); - $alreadypayed = $totalpaye + $totalcreditnotes + $totaldeposits; - - if (price2num($alreadypayed + $facs[$i][1], 'MT') == $fac->total_ttc) { - $result = $fac->set_paid($user); - } - } - - // Make one payment per customer - foreach ($amountsperthirdparty as $thirdpartyid => $cursoramounts) - { - $paiement = new Paiement($this->db); - $paiement->datepaye = $date; - $paiement->amounts = $cursoramounts; // Array with detail of dispatching of payments for each invoice - $paiement->paiementid = 3; // - $paiement->num_payment = $this->ref; // Set ref of direct debit note - $paiement->num_paiement = $this->ref; // For backward compatibility - $paiement->id_prelevement = $this->id; - - $paiement_id = $paiement->create($user); - if ($paiement_id < 0) - { - dol_syslog(get_class($this)."::set_infocredit AddPayment Error"); - $error++; - } - else - { - $result = $paiement->addPaymentToBank($user, 'payment', '(WithdrawalPayment)', $bankaccount, '', ''); - if ($result < 0) - { - dol_syslog(get_class($this)."::set_infocredit AddPaymentToBank Error"); - $error++; - } - } - //var_dump($paiement->amounts); - //var_dump($thirdpartyid); - //var_dump($cursoramounts); - } - - // Update withdrawal line - // TODO: Translate to ligneprelevement.class.php - $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_lignes"; - $sql .= " SET statut = 2"; - $sql .= " WHERE fk_prelevement_bons = ".$this->id; - - if (!$this->db->query($sql)) - { - dol_syslog(get_class($this)."::set_infocredit Update lines Error"); - $error++; - } - } - else - { - dol_syslog(get_class($this)."::set_infocredit Update Bons Error"); - $error++; + if ($this->type == 'bank-transfer') { + $fac = new FactureFournisseur($this->db); + } else { + $fac = new Facture($this->db); } - /* - * End of procedure - */ - if ($error == 0) - { - $this->date_credit = $date; - $this->statut = self::STATUS_CREDITED; + $result = $fac->fetch($facs[$i][0]); - $this->db->commit(); - return 0; - } - else - { - $this->db->rollback(); - dol_syslog("bon-prelevment::set_infocredit ROLLBACK "); - return -1; + $amounts[$fac->id] = $facs[$i][1]; + $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1]; + + $totalpaye = $fac->getSommePaiement(); + $totalcreditnotes = $fac->getSumCreditNotesUsed(); + $totaldeposits = $fac->getSumDepositsUsed(); + $alreadypayed = $totalpaye + $totalcreditnotes + $totaldeposits; + + // @TODO Move this after creation of payment + if (price2num($alreadypayed + $facs[$i][1], 'MT') == $fac->total_ttc) { + $result = $fac->set_paid($user); + if ($result < 0) { + $this->error = $fac->error; + $this->errors = $fac->errors; + } } } - else + //var_dump($amountsperthirdparty);exit; + + // Make one payment per customer + foreach ($amountsperthirdparty as $thirdpartyid => $cursoramounts) { - dol_syslog(get_class($this)."::set_infocredit 1025 Open SQL transaction impossible "); - return -1025; + if ($this->type == 'bank-transfer') { + $paiement = new PaiementFourn($this->db); + } else { + $paiement = new Paiement($this->db); + } + $paiement->datepaye = $date; + $paiement->amounts = $cursoramounts; // Array with detail of dispatching of payments for each invoice + + if ($this->type == 'bank-transfer') { + $paiement->paiementid = 2; + $paiement->paiementcode = 'VIR'; + } else { + $paiement->paiementid = 3; + $paiement->paiementcode = 'PRE'; + } + + $paiement->num_payment = $this->ref; // Set ref of direct debit note + $paiement->num_paiement = $this->ref; // For backward compatibility + $paiement->id_prelevement = $this->id; + + $paiement_id = $paiement->create($user); // This use ->paiementid, that is ID of payment mode + if ($paiement_id < 0) + { + $error++; + $this->error = $paiement->error; + $this->errors = $paiement->errors; + dol_syslog(get_class($this)."::set_infocredit AddPayment Error ".$this->error); + } + else + { + if ($this->type == 'bank-transfer') { + $modeforaddpayment = 'payment_supplier'; + } else { + $modeforaddpayment = 'payment'; + } + + $result = $paiement->addPaymentToBank($user, $modeforaddpayment, '(WithdrawalPayment)', $bankaccount, '', ''); + if ($result < 0) + { + $error++; + $this->error = $paiement->error; + $this->errors = $paiement->errors; + dol_syslog(get_class($this)."::set_infocredit AddPaymentToBank Error ".$this->error); + } + } + //var_dump($paiement->amounts); + //var_dump($thirdpartyid); + //var_dump($cursoramounts); + } + + // Update withdrawal line + // TODO: Translate to ligneprelevement.class.php + if (! $error) { + $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_lignes"; + $sql .= " SET statut = 2"; + $sql .= " WHERE fk_prelevement_bons = ".$this->id; + + if (!$this->db->query($sql)) + { + dol_syslog(get_class($this)."::set_infocredit Update lines Error"); + $error++; + } } } else { - dol_syslog("bon-prelevment::set_infocredit 1027 Date de credit < Date de trans "); - return -1027; + $this->error = $this->db->lasterror(); + dol_syslog(get_class($this)."::set_infocredit Update Bons Error"); + $error++; + } + + /* + * End of procedure + */ + if ($error == 0) + { + $this->date_credit = $date; + $this->statut = self::STATUS_CREDITED; + + $this->db->commit(); + return 0; + } + else + { + $this->db->rollback(); + return -1; } } else @@ -593,7 +627,7 @@ class BonPrelevement extends CommonObject $sql .= " SET fk_user_trans = ".$user->id; $sql .= " , date_trans = '".$this->db->idate($date)."'"; $sql .= " , method_trans = ".$method; - $sql .= " , statut = 1"; + $sql .= " , statut = ".self::STATUS_TRANSFERED; $sql .= " WHERE rowid = ".$this->id; $sql .= " AND entity = ".$conf->entity; $sql .= " AND statut = 0"; @@ -617,6 +651,7 @@ class BonPrelevement extends CommonObject { $this->date_trans = $date; $this->statut = 1; + $this->user_trans = $user->id; $this->db->commit(); return 0; @@ -651,7 +686,12 @@ class BonPrelevement extends CommonObject /* * Returns all invoices presented within same order */ - $sql = "SELECT fk_facture"; + $sql = "SELECT "; + if ($this->type == 'bank-transfer') { + $sql .= " pf.fk_facture_fourn"; + } else { + $sql .= " pf.fk_facture"; + } if ($amounts) $sql .= ", SUM(pl.amount)"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; $sql .= " , ".MAIN_DB_PREFIX."prelevement_lignes as pl"; @@ -660,7 +700,13 @@ class BonPrelevement extends CommonObject $sql .= " AND pl.fk_prelevement_bons = p.rowid"; $sql .= " AND p.rowid = ".$this->id; $sql .= " AND p.entity = ".$conf->entity; - if ($amounts) $sql .= " GROUP BY fk_facture"; + if ($amounts) { + if ($this->type == 'bank-transfer') { + $sql .= " GROUP BY fk_facture_fourn"; + } else { + $sql .= " GROUP BY fk_facture"; + } + } $resql = $this->db->query($sql); if ($resql) diff --git a/htdocs/compta/prelevement/class/ligneprelevement.class.php b/htdocs/compta/prelevement/class/ligneprelevement.class.php index d2dd9f3470f..10f3c05c25a 100644 --- a/htdocs/compta/prelevement/class/ligneprelevement.class.php +++ b/htdocs/compta/prelevement/class/ligneprelevement.class.php @@ -59,7 +59,7 @@ class LignePrelevement $langs->load("withdrawals"); $this->statuts[0] = $langs->trans("StatusWaiting"); - $this->statuts[2] = $langs->trans("StatusCredited"); + $this->statuts[2] = $langs->trans("StatusPaid"); $this->statuts[3] = $langs->trans("StatusRefused"); } diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 816795bfdbd..0e4ff799ba6 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -105,7 +105,7 @@ if ($id > 0 || $ref) print '
'; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''; @@ -160,7 +160,7 @@ if ($id > 0 || $ref) // List of invoices -$sql = "SELECT pf.rowid,"; +$sql = "SELECT pf.rowid, p.type,"; $sql .= " f.rowid as facid, f.ref as ref, f.total_ttc,"; $sql .= " s.rowid as socid, s.nom as name, pl.statut, pl.amount as amount_requested"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; @@ -193,8 +193,8 @@ $sql .= $db->order($sortfield, $sortorder); $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + $resql = $db->query($sql); + $nbtotalofrecords = $db->num_rows($resql); if (($page * $limit) > $nbtotalofrecords) // if total resultset is smaller then paging size (filtering), goto and load page 0 { $page = 0; @@ -204,10 +204,10 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $sql .= $db->plimit($limit + 1, $offset); -$result = $db->query($sql); -if ($result) +$resql = $db->query($sql); +if ($resql) { - $num = $db->num_rows($result); + $num = $db->num_rows($resql); $i = 0; $param = "&id=".$id; @@ -236,22 +236,28 @@ if ($result) print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "s.nom", '', $param, '', $sortfield, $sortorder); print_liste_field_titre("AmountInvoice", $_SERVER["PHP_SELF"], "f.total_ttc", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("AmountRequested", $_SERVER["PHP_SELF"], "pl.amount", "", $param, 'class="right"', $sortfield, $sortorder); - print_liste_field_titre("StatusDebitCredit", $_SERVER["PHP_SELF"], "", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "", "", $param, 'align="center"', $sortfield, $sortorder); print_liste_field_titre(''); print "\n"; $totalinvoices = 0; $totalamount_requested = 0; + $invoicetmpcustomer = new Facture($db); + $invoicetmpsupplier = new FactureFournisseur($db); + while ($i < min($num, $limit)) { - $obj = $db->fetch_object($result); + $obj = $db->fetch_object($resql); - $invoicetmp->id = $obj->facid; - $invoicetmp->ref = $obj->ref; + if ($obj->type == 'bank-transfer') { + $invoicetmp = $invoicetmpsupplier; + } else { + $invoicetmp = $invoicetmpcustomer; + } + $invoicetmp->fetch($obj->facid); - $thirdpartytmp->id = $obj->socid; - $thirdpartytmp->name = $obj->name; + $thirdpartytmp->fetch($obj->socid); print ''; @@ -278,7 +284,11 @@ if ($result) } elseif ($obj->statut == 2) { - print $langs->trans("StatusCredited"); + if ($obj->type == 'bank-transfer') { + print $langs->trans("StatusDebited"); + } else { + print $langs->trans("StatusCredited"); + } } elseif ($obj->statut == 3) { @@ -317,7 +327,7 @@ if ($result) print "
'.$langs->trans("TableName").''.$langs->trans("NbOfRecord").''; - print $thirdpartystatic->display_rib('rum'); - $format = $thirdpartystatic->display_rib('format'); - if ($type != 'bank-transfer') { - if ($format) print ' ('.$format.')'; + $rumtoshow = $thirdpartystatic->display_rib('rum'); + if ($rumtoshow) { + print $rumtoshow; + $format = $thirdpartystatic->display_rib('format'); + if ($type != 'bank-transfer') { + if ($format) print ' ('.$format.')'; + } + } else { + print img_warning($langs->trans("NoBankAccount")); } print '
'.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
'.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
"; print '
'; - $db->free($result); + $db->free($resql); } else { diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index 10abbcf5166..cbc1a666def 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -99,7 +99,7 @@ if ($prev_id > 0 || $ref) print ''.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print ''; @@ -234,7 +234,7 @@ if ($resql) } else { - print ''.$langs->trans("None").''; + print ''.$langs->trans("None").''; } if ($num > 0) diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php index 49508cdde46..d94edfa5107 100644 --- a/htdocs/compta/prelevement/fiche-stat.php +++ b/htdocs/compta/prelevement/fiche-stat.php @@ -98,7 +98,7 @@ if ($prev_id > 0 || $ref) print ''.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print ''; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 63ca7e0d88b..bbc8a3e6e28 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1290,7 +1290,7 @@ class FactureFournisseur extends CommonInvoice $this->db->begin(); $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn'; - $sql .= ' SET paye = 1, fk_statut=2'; + $sql .= ' SET paye = 1, fk_statut = '.self::STATUS_CLOSED; $sql .= ' WHERE rowid = '.$this->id; dol_syslog("FactureFournisseur::set_paid", LOG_DEBUG); diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 662c587108a..a1bb646bff3 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -63,7 +63,9 @@ InvoiceRefused=Invoice refused (Charge the rejection to customer) StatusDebitCredit=Status debit/credit StatusWaiting=Waiting StatusTrans=Sent +StatusDebited=Debited StatusCredited=Credited +StatusPaid=Paid StatusRefused=Refused StatusMotif0=Unspecified StatusMotif1=Insufficient funds @@ -82,8 +84,8 @@ CreateSepaFileForPaymentByBankTransfer=Create credit transfer file (SEPA) CreateGuichet=Only office CreateBanque=Only bank OrderWaiting=Waiting for treatment -NotifyTransmision=File transmission -NotifyCredit=Withdrawal Credit +NotifyTransmision=Record file transmission of order +NotifyCredit=Record credit of order NumeroNationalEmetter=National Transmitter Number WithBankUsingRIB=For bank accounts using RIB WithBankUsingBANBIC=For bank accounts using IBAN/BIC/SWIFT From 4900e85fa804af1932ed95cf561c1c32b16ba6e2 Mon Sep 17 00:00:00 2001 From: bahfir abbes Date: Mon, 3 Aug 2020 20:31:39 +0100 Subject: [PATCH 23/97] fix: reset link on supplier dispatch --- htdocs/fourn/commande/dispatch.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 0c0f084a230..ede9b22622a 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -743,7 +743,8 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("SupplierRef").''; print ''.$langs->trans("QtyOrdered").''; print ''.$langs->trans("QtyDispatchedShort").''; - print ''.$langs->trans("QtyToDispatchShort").''; + print ' '.$langs->trans("QtyToDispatchShort"); + print ' ('.$langs->trans("Reset").')'.''; print ''; if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { @@ -1068,7 +1069,20 @@ if ($id > 0 || !empty($ref)) { $("select[name=fk_default_warehouse]").change(function() { var fk_default_warehouse = $("option:selected", this).val(); $("select[name^=entrepot_]").val(fk_default_warehouse).change(); - }); + });'; + $i = 0; + print ' + jQuery("#autoreset").click(function() {'; + $i = 0; + while ($i < $nbproduct) + { + print ' + jQuery("#qty_0_'.$i.'").val(0);'; + $i++; + } + print ' + });'; + print ' }); '; From 8dd54e24e7e6924b6b0a6a11f33698a59f1a7771 Mon Sep 17 00:00:00 2001 From: Bahfir Abbes Date: Mon, 3 Aug 2020 20:42:25 +0100 Subject: [PATCH 24/97] empty is more useful than 0 --- htdocs/fourn/commande/dispatch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index ede9b22622a..3bc69e6770b 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -1077,7 +1077,7 @@ if ($id > 0 || !empty($ref)) { while ($i < $nbproduct) { print ' - jQuery("#qty_0_'.$i.'").val(0);'; + jQuery("#qty_0_'.$i.'").val("");'; $i++; } print ' From 063b63d3488a47f7ce6328ac2d9709c763aad357 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 00:36:45 +0200 Subject: [PATCH 25/97] Fix phpcs --- .../prelevement/class/bonprelevement.class.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index e50efe4160f..7e505f97bee 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -517,9 +517,7 @@ class BonPrelevement extends CommonObject $this->error = $paiement->error; $this->errors = $paiement->errors; dol_syslog(get_class($this)."::set_infocredit AddPayment Error ".$this->error); - } - else - { + } else { if ($this->type == 'bank-transfer') { $modeforaddpayment = 'payment_supplier'; } else { @@ -1639,16 +1637,13 @@ class BonPrelevement extends CommonObject $i++; } $nbtotalDrctDbtTxInf = $i; - } - else - { + } else { fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers $result = -2; } // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf - if ($result != -2) - { + if ($result != -2) { $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); } @@ -2238,11 +2233,8 @@ class BonPrelevement extends CommonObject $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf;*/ } - } - else - { + } else { fputs($this->file, 'INCORRECT EMETTEUR '.$XML_SEPA_INFO.$CrLf); - $result = -2; } return $XML_SEPA_INFO; } From bf1f2956026347a53833d45aa152d0d4b50ab159 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 02:50:56 +0200 Subject: [PATCH 26/97] NEW Can disable, from edit page, the whole web site FIX position of a cloned website --- htdocs/theme/eldy/global.inc.php | 2 +- htdocs/website/class/website.class.php | 5 ++- htdocs/website/index.php | 50 +++++++++++++++----------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 45214c06a4d..ab7a56ea89d 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -3984,7 +3984,7 @@ div.boximport { .product_line_stock_ok { color: #002200; } .product_line_stock_too_low { color: #884400; } -.fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor); } +.fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor) !important; } td.widthpictotitle { width: 26px; text-align: ; } span.widthpictotitle { font-size: 1.7em; } diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index c325e672043..768ddbdb19c 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -290,6 +290,7 @@ class Website extends CommonObject $sql .= ' t.rowid,'; $sql .= " t.entity,"; $sql .= " t.ref,"; + $sql .= " t.position,"; $sql .= " t.description,"; $sql .= " t.lang,"; $sql .= " t.otherlang,"; @@ -319,6 +320,7 @@ class Website extends CommonObject $this->entity = $obj->entity; $this->ref = $obj->ref; + $this->position = $obj->position; $this->description = $obj->description; $this->lang = $obj->lang; $this->otherlang = $obj->otherlang; @@ -670,7 +672,8 @@ class Website extends CommonObject $object->virtualhost = ''; $object->date_creation = $now; $object->fk_user_creat = $user->id; - $object->position = $object->position + 1; + $object->position = ((int) $object->position) + 1; + $object->status = self::STATUS_DRAFT; if (empty($object->lang)) $object->lang = substr($langs->defaultlang, 0, 2); // Should not happen. Protection for corrupted site with no languages // Create clone diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 539e7533af6..e0afd583ea2 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2594,11 +2594,11 @@ if (!GETPOST('hide_websitemenu')) $textifempty = 1; $formquestion = array( array('type' => 'hidden', 'name' => 'sourcepageurl', 'value'=> $objectpage->pageurl), - array('type' => 'checkbox', 'tdclass'=>'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0), - array('type' => 'other', 'name' => 'newlang', 'label' => $form->textwithpicto($langs->trans("Language"), $langs->trans("DefineListOfAltLanguagesInWebsiteProperties")), 'value' => $formadmin->select_language($preselectedlanguage, 'newlang', 0, null, $textifempty, 0, 0, 'minwidth200', 0, 1, 0, $onlylang, 1)), - array('type' => 'other', 'name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)), + array('type' => 'other', 'tdclass'=>'fieldrequired', 'name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)), array('type' => 'text', 'tdclass'=>'maxwidth200 fieldrequired', 'name' => 'newtitle', 'label'=> $langs->trans("WEBSITE_TITLE"), 'value'=> $langs->trans("CopyOf").' '.$objectpage->title), array('type' => 'text', 'tdclass'=>'maxwidth200', 'name' => 'newpageurl', 'label'=> $langs->trans("WEBSITE_PAGENAME"), 'value'=> ''), + array('type' => 'checkbox', 'tdclass'=>'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0, 'morecss'=>'margintoponly'), + array('type' => 'other', 'name' => 'newlang', 'label' => $form->textwithpicto($langs->trans("Language"), $langs->trans("DefineListOfAltLanguagesInWebsiteProperties")), 'value' => $formadmin->select_language($preselectedlanguage, 'newlang', 0, null, $textifempty, 0, 0, 'minwidth200', 0, 1, 0, $onlylang, 1)), ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 300, 550); @@ -2972,6 +2972,15 @@ if ($action == 'editcss') print $websitekey; print ''; + // Status of web site + print ''."\n"; + print ''; + print $langs->trans('Status'); + print ''; + print ajax_object_onoff($object, 'status', 'status', 'Enabled', 'Disabled'); + //print dol_print_date($pagedatecreation, 'dayhour'); + print ''; + // Main language print ''; $htmltext = ''; @@ -3288,15 +3297,16 @@ if ($action == 'editmeta' || $action == 'createcontainer') if ($action != 'createcontainer') { - print ''; - print $langs->trans('IDOfPage'); + print ''; + print $langs->trans('IDOfPage').' - '.$langs->trans('InternalURLOfPage'); print ''; print $pageid; - print ''; + //print ''; - print ''; - print $langs->trans('InternalURLOfPage'); - print ''; + //print ''; + //print $langs->trans('InternalURLOfPage'); + //print ''; + print '   -   '; print '/public/website/index.php?website='.urlencode($websitekey).'&pageid='.urlencode($pageid); //if ($objectpage->grabbed_from) print ' - '.$langs->trans('InitiallyGrabbedFrom').' '.$objectpage->grabbed_from.''; print ''; @@ -3334,6 +3344,17 @@ if ($action == 'editmeta' || $action == 'createcontainer') if (GETPOST('WEBSITE_LANG', 'aZ09')) $pagelang = GETPOST('WEBSITE_LANG', 'aZ09'); if (GETPOST('htmlheader', 'none')) $pagehtmlheader = GETPOST('htmlheader', 'none'); + if ($action != 'createcontainer') + { + print ''."\n"; + print ''; + print $langs->trans('Status'); + print ''; + print ajax_object_onoff($objectpage, 'status', 'status', 'Enabled', 'Disabled'); + //print dol_print_date($pagedatecreation, 'dayhour'); + print ''; + } + // Type of container print ''; print $langs->trans('WEBSITE_TYPE_CONTAINER'); @@ -3555,17 +3576,6 @@ if ($action == 'editmeta' || $action == 'createcontainer') print $doleditor->Create(1, '', true, 'HTML Header', 'html'); print ''; - if ($action != 'createcontainer') - { - print ''."\n"; - print ''; - print $langs->trans('Status'); - print ''; - print ajax_object_onoff($objectpage, 'status', 'status', 'Enabled', 'Disabled'); - //print dol_print_date($pagedatecreation, 'dayhour'); - print ''; - } - print ''; if ($action == 'createcontainer') { From 6d957c276c3df287f835bc414329c6808360c98f Mon Sep 17 00:00:00 2001 From: "jove@bisquerra.com" Date: Tue, 4 Aug 2020 08:11:44 +0200 Subject: [PATCH 27/97] Improving TakePOS search informing the user if there is no record or clearing the box if it exists avoiding manually clear every scan --- htdocs/takepos/index.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index ab5acc1ac50..36dcbbe3d55 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -529,8 +529,19 @@ function Search2(keyCodeForEnter) { ClickProduct(0); } } + if (eventKeyCode == keyCodeForEnter){ + ClearSearch(); + if (data.length == 0) { + $('#search').val('load('errors'); + echo dol_escape_js($langs->trans("ErrorRecordNotFound")); + ?>'); + $('#search').select(); + } + } }); } + } function Edit(number) { From 0347f2a46beac5286af06264bafe8ddc07b92064 Mon Sep 17 00:00:00 2001 From: andreubisquerra Date: Tue, 4 Aug 2020 08:19:27 +0200 Subject: [PATCH 28/97] More elegant --- htdocs/takepos/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 36dcbbe3d55..96608ed4fdf 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -530,7 +530,6 @@ function Search2(keyCodeForEnter) { } } if (eventKeyCode == keyCodeForEnter){ - ClearSearch(); if (data.length == 0) { $('#search').val('load('errors'); @@ -538,6 +537,7 @@ function Search2(keyCodeForEnter) { ?>'); $('#search').select(); } + else ClearSearch(); } }); } From 360afccecc6c397e592e2497db5268e0b71d997a Mon Sep 17 00:00:00 2001 From: Tim Otte Date: Tue, 4 Aug 2020 11:02:16 +0200 Subject: [PATCH 29/97] Fixed translation of product units in documents --- htdocs/bom/class/bom.class.php | 1 + htdocs/comm/propal/class/propal.class.php | 1 + htdocs/commande/class/commande.class.php | 1 + htdocs/compta/facture/class/facture.class.php | 1 + htdocs/contrat/class/contrat.class.php | 1 + htdocs/core/class/commonobjectline.class.php | 4 ++-- htdocs/expedition/class/expedition.class.php | 1 + htdocs/fourn/class/fournisseur.commande.class.php | 1 + htdocs/fourn/class/fournisseur.facture.class.php | 1 + htdocs/livraison/class/livraison.class.php | 1 + htdocs/product/class/product.class.php | 1 + htdocs/product/stock/class/entrepot.class.php | 1 + htdocs/product/stock/class/mouvementstock.class.php | 1 + htdocs/supplier_proposal/class/supplier_proposal.class.php | 1 + 14 files changed, 15 insertions(+), 2 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 9ec55ae2f4a..847cf676054 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -927,6 +927,7 @@ class BOM extends CommonObject global $conf, $langs; $langs->load("mrp"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'standard'; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index cef7e3ee48e..d2e2864eef0 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3662,6 +3662,7 @@ class Propal extends CommonObject global $conf, $langs; $langs->load("propale"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'azur'; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 28d2170e49a..a30d04fd761 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3859,6 +3859,7 @@ class Commande extends CommonOrder global $conf, $langs; $langs->load("orders"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'einstein'; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 843b3dd32ea..1eccddbc9ae 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4296,6 +4296,7 @@ class Facture extends CommonInvoice global $conf, $langs; $langs->load("bills"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index c2200a411c2..c1a652a19ba 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2393,6 +2393,7 @@ class Contrat extends CommonObject global $conf, $langs; $langs->load("contracts"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'strato'; diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php index f92004120ff..59b0acee232 100644 --- a/htdocs/core/class/commonobjectline.class.php +++ b/htdocs/core/class/commonobjectline.class.php @@ -74,12 +74,12 @@ abstract class CommonObjectLine extends CommonObject $label_type = 'short_label'; } - $sql = 'select '.$label_type.' from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; + $sql = 'select '.$label_type.',code from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; $resql = $this->db->query($sql); if ($resql && $this->db->num_rows($resql) > 0) { $res = $this->db->fetch_array($resql); - $label = $res[$label_type]; + $label = ($label_type == 'short' ? $res[$label_type] : 'unit'.$res['code']); $this->db->free($resql); return $label; } else { diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 6b08d4db5e6..d05d0c63d37 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2462,6 +2462,7 @@ class Expedition extends CommonObject global $conf, $langs; $langs->load("sendings"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'rouget'; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index c544658a921..e6098cba01e 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2959,6 +2959,7 @@ class CommandeFournisseur extends CommonOrder global $conf, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'muscadet'; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 9949c4d3253..d7e8908312e 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2637,6 +2637,7 @@ class FactureFournisseur extends CommonInvoice global $conf, $user, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); // Set the model on the model name to use if (empty($modele)) diff --git a/htdocs/livraison/class/livraison.class.php b/htdocs/livraison/class/livraison.class.php index 6199bc4ec88..1429e39be8e 100644 --- a/htdocs/livraison/class/livraison.class.php +++ b/htdocs/livraison/class/livraison.class.php @@ -1035,6 +1035,7 @@ class Livraison extends CommonObject global $conf, $user, $langs; $langs->load("deliveries"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'typhon'; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 5de1ee5ad99..5c6f1f3955b 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4426,6 +4426,7 @@ class Product extends CommonObject global $conf, $user, $langs; $langs->load("products"); + $outputlangs->load("products"); // Positionne le modele sur le nom du modele a utiliser if (!dol_strlen($modele)) { diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 068ea05dbab..62a7b5835d4 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -856,6 +856,7 @@ class Entrepot extends CommonObject global $conf, $user, $langs; $langs->load("stocks"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'standard'; diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 509379860c3..d1c703924d4 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -1167,6 +1167,7 @@ class MouvementStock extends CommonObject global $conf, $user, $langs; $langs->load("stocks"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'stdmovement'; diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 907a741c288..871d94b87a4 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2630,6 +2630,7 @@ class SupplierProposal extends CommonObject global $conf, $langs; $langs->load("supplier_proposal"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'aurore'; From 81467e1d0996041e25d26ab769146d0003314861 Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Tue, 4 Aug 2020 11:05:12 +0200 Subject: [PATCH 30/97] FIX search warehouse list --- htdocs/product/stock/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index f5121ea0089..f0b94f99bdb 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -232,7 +232,7 @@ foreach ($search as $key => $val) if ($search[$key] == '-1') $search[$key] = ''; $mode_search = 2; } - if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : $key), $search[$key], (($key == 'status') ? 2 : $mode_search)); + if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : 't.' . $key), $search[$key], (($key == 'status') ? 2 : $mode_search)); } if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all); // Add where from extra fields From 0e03578e913120f963cbbf9bd4f5961ca15b304c Mon Sep 17 00:00:00 2001 From: Tim Otte Date: Tue, 4 Aug 2020 11:02:16 +0200 Subject: [PATCH 31/97] Fixed translation of product units in documents --- htdocs/bom/class/bom.class.php | 1 + htdocs/comm/propal/class/propal.class.php | 1 + htdocs/commande/class/commande.class.php | 1 + htdocs/compta/facture/class/facture.class.php | 1 + htdocs/contrat/class/contrat.class.php | 1 + htdocs/core/class/commonobjectline.class.php | 4 ++-- htdocs/expedition/class/expedition.class.php | 1 + htdocs/fourn/class/fournisseur.commande.class.php | 1 + htdocs/fourn/class/fournisseur.facture.class.php | 1 + htdocs/livraison/class/livraison.class.php | 1 + htdocs/product/class/product.class.php | 1 + htdocs/product/stock/class/entrepot.class.php | 1 + htdocs/product/stock/class/mouvementstock.class.php | 1 + htdocs/supplier_proposal/class/supplier_proposal.class.php | 1 + 14 files changed, 15 insertions(+), 2 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index b23a96372c6..aea05d59a15 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -945,6 +945,7 @@ class BOM extends CommonObject global $conf, $langs; $langs->load("mrp"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'standard'; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 3fd122c0103..0be35671738 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3787,6 +3787,7 @@ class Propal extends CommonObject global $conf, $langs; $langs->load("propale"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'azur'; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index b911a03e3ad..b1c0aac6d15 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3990,6 +3990,7 @@ class Commande extends CommonOrder global $conf, $langs; $langs->load("orders"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'einstein'; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 193be9d5575..f0d67f309f2 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4402,6 +4402,7 @@ class Facture extends CommonInvoice global $conf, $langs; $langs->load("bills"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 1dec473edac..1153f89689d 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2468,6 +2468,7 @@ class Contrat extends CommonObject global $conf, $langs; $langs->load("contracts"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'strato'; diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php index f04e2da11ee..4874dded08d 100644 --- a/htdocs/core/class/commonobjectline.class.php +++ b/htdocs/core/class/commonobjectline.class.php @@ -74,12 +74,12 @@ abstract class CommonObjectLine extends CommonObject $label_type = 'short_label'; } - $sql = 'select '.$label_type.' from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; + $sql = 'select '.$label_type.',code from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; $resql = $this->db->query($sql); if ($resql && $this->db->num_rows($resql) > 0) { $res = $this->db->fetch_array($resql); - $label = $res[$label_type]; + $label = ($label_type == 'short' ? $res[$label_type] : 'unit'.$res['code']); $this->db->free($resql); return $label; } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 8e17403635a..ab77e95983f 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2567,6 +2567,7 @@ class Expedition extends CommonObject global $conf, $langs; $langs->load("sendings"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'rouget'; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 5ca0a154312..6456d3ec07b 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3084,6 +3084,7 @@ class CommandeFournisseur extends CommonOrder global $conf, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'muscadet'; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index bbc8a3e6e28..093be1d9de8 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2721,6 +2721,7 @@ class FactureFournisseur extends CommonInvoice global $conf, $user, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); // Set the model on the model name to use if (empty($modele)) diff --git a/htdocs/livraison/class/livraison.class.php b/htdocs/livraison/class/livraison.class.php index acfe8b29d05..6c5c6e49611 100644 --- a/htdocs/livraison/class/livraison.class.php +++ b/htdocs/livraison/class/livraison.class.php @@ -1068,6 +1068,7 @@ class Livraison extends CommonObject global $conf, $user, $langs; $langs->load("deliveries"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'typhon'; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 4dd4c7b3420..6a832eced1e 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4568,6 +4568,7 @@ class Product extends CommonObject global $conf, $user, $langs; $langs->load("products"); + $outputlangs->load("products"); // Positionne le modele sur le nom du modele a utiliser if (!dol_strlen($modele)) { diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index ea5feaa170c..76e828dda91 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -878,6 +878,7 @@ class Entrepot extends CommonObject global $conf, $user, $langs; $langs->load("stocks"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'standard'; diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index c2599faf942..ffc84f41e92 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -1164,6 +1164,7 @@ class MouvementStock extends CommonObject global $conf, $user, $langs; $langs->load("stocks"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'stdmovement'; diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index fa87111c2e8..dd63a20d40a 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2722,6 +2722,7 @@ class SupplierProposal extends CommonObject global $conf, $langs; $langs->load("supplier_proposal"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'aurore'; From dbb2e8b1ba909f2373d497d2ad9e4de1cad983a9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 11:56:01 +0200 Subject: [PATCH 32/97] Update dispatch.php --- htdocs/fourn/commande/dispatch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 3bc69e6770b..46166cb31e0 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -744,7 +744,7 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("QtyOrdered").''; print ''.$langs->trans("QtyDispatchedShort").''; print ' '.$langs->trans("QtyToDispatchShort"); - print ' ('.$langs->trans("Reset").')'.''; + print ' ('.$langs->trans("Reset").')'; print ''; if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { From fd551261bbd7b1b1573b4db2444400bc2c080c9c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 11:58:29 +0200 Subject: [PATCH 33/97] Update dispatch.php --- htdocs/fourn/commande/dispatch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 46166cb31e0..2293fd8aff0 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -744,7 +744,7 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("QtyOrdered").''; print ''.$langs->trans("QtyDispatchedShort").''; print ' '.$langs->trans("QtyToDispatchShort"); - print ' ('.$langs->trans("Reset").')'; + print '
'.$langs->trans("Reset").')'; print ''; if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { From 4bacb7d48ebbe34d3aa7256fa8aabf339601832e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:00:24 +0200 Subject: [PATCH 34/97] Update dispatch.php --- htdocs/fourn/commande/dispatch.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 2293fd8aff0..c64d158ac2c 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -744,7 +744,7 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("QtyOrdered").''; print ''.$langs->trans("QtyDispatchedShort").''; print ' '.$langs->trans("QtyToDispatchShort"); - print '
'.$langs->trans("Reset").')'; + print '
'.$langs->trans("Reset").''; print ''; if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { @@ -1069,20 +1069,16 @@ if ($id > 0 || !empty($ref)) { $("select[name=fk_default_warehouse]").change(function() { var fk_default_warehouse = $("option:selected", this).val(); $("select[name^=entrepot_]").val(fk_default_warehouse).change(); - });'; - $i = 0; - print ' + }); + jQuery("#autoreset").click(function() {'; $i = 0; - while ($i < $nbproduct) - { - print ' - jQuery("#qty_0_'.$i.'").val("");'; + while ($i < $nbproduct) { + print ' jQuery("#qty_0_'.$i.'").val("");'; $i++; } print ' - });'; - print ' + }); }); '; From fa96fd8a8b0dab7ac14342fb27ee952f04c56d2e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:19:44 +0200 Subject: [PATCH 35/97] Update actions_addupdatedelete.inc.php --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 08b3e037499..b4bcaff370a 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -156,7 +156,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = (GETPOST($key) == '1' ? 1 : 0); + $value = ((GETPOST($key, 'aZ09) == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 0d17682773bb29b22cc92a809dbc2e7abbb7a1aa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:20:10 +0200 Subject: [PATCH 36/97] Update actions_addupdatedelete.inc.php --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index b4bcaff370a..82a76cf8718 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -156,7 +156,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = ((GETPOST($key, 'aZ09) == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); + $value = ((GETPOST($key, 'aZ09') == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 13202dfc7c550c03b10be45f212b35d08e05f6c1 Mon Sep 17 00:00:00 2001 From: bahfir abbes Date: Mon, 3 Aug 2020 14:31:33 +0100 Subject: [PATCH 37/97] fix:value of checked option must be the same as in showInputfield function --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 37a39e7d1f0..c3a93639a05 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -165,7 +165,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = (GETPOST($key) == 'on' ? 1 : 0); + $value = (GETPOST($key) == '1' ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 2aaae47aeffcc9c4f0904546aa1a342f49fb3af2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:19:44 +0200 Subject: [PATCH 38/97] Update actions_addupdatedelete.inc.php --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index c3a93639a05..b30c1c33731 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -165,7 +165,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = (GETPOST($key) == '1' ? 1 : 0); + $value = ((GETPOST($key, 'aZ09) == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 08167b959cc5e7daa91614861681275c6d18a037 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:20:10 +0200 Subject: [PATCH 39/97] Update actions_addupdatedelete.inc.php --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index b30c1c33731..ec35ec4061d 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -165,7 +165,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = ((GETPOST($key, 'aZ09) == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); + $value = ((GETPOST($key, 'aZ09') == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 2076d18825817a4ac90f70bd273f7479465d5d90 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:47:09 +0200 Subject: [PATCH 40/97] FIX Param of fetch_name_optionals_label must be object->table_element --- htdocs/commande/list.php | 2 +- htdocs/compta/facture/invoicetemplate_list.php | 2 +- htdocs/compta/facture/list.php | 2 +- htdocs/contact/list.php | 2 +- htdocs/contrat/list.php | 2 +- htdocs/contrat/services_list.php | 2 +- htdocs/core/class/extrafields.class.php | 3 ++- htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php | 2 +- htdocs/expensereport/list.php | 2 +- htdocs/fichinter/list.php | 2 +- htdocs/fourn/commande/list.php | 2 +- htdocs/modulebuilder/template/class/myobject.class.php | 2 +- htdocs/product/list.php | 2 +- htdocs/projet/activity/perweek.php | 3 +-- htdocs/public/ticket/list.php | 2 +- htdocs/zapier/class/hook.class.php | 4 ++-- 16 files changed, 18 insertions(+), 18 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 3b83e04fe3c..0cc9fa6634b 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -116,7 +116,7 @@ $hookmanager->initHooks(array('orderlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('commande'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); // List of fields to search into when doing a "search in all" diff --git a/htdocs/compta/facture/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php index d8f51290872..5c353d6f2cd 100644 --- a/htdocs/compta/facture/invoicetemplate_list.php +++ b/htdocs/compta/facture/invoicetemplate_list.php @@ -108,7 +108,7 @@ $hookmanager->initHooks(array('invoicereclist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('facture_rec'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 128e0502344..6d12483e303 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -150,7 +150,7 @@ $hookmanager->initHooks(array('invoicelist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('facture'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index f766c8beeb8..39c588ace15 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -143,7 +143,7 @@ $hookmanager->initHooks(array('contactlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('contact'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index a7205730817..37fd99a771e 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -100,7 +100,7 @@ $hookmanager->initHooks(array('contractlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('contrat'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); // List of fields to search into when doing a "search in all" diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 2b81ceff5fa..90f6516a499 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -84,7 +84,7 @@ $hookmanager->initHooks(array('contractservicelist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('contratdet'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index eecb5b54330..5ac47f1a478 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -842,7 +842,7 @@ class ExtraFields /** * Load array this->attributes, or old this->attribute_xxx like attribute_label, attribute_type, ... * - * @param string $elementtype Type of element ('' = all, 'adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). + * @param string $elementtype Type of element ('' = all or $object->table_element like 'adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). * @param boolean $forceload Force load of extra fields whatever is status of cache. * @return array Array of attributes keys+label for all extra fields. */ @@ -856,6 +856,7 @@ class ExtraFields if ($elementtype == 'thirdparty') $elementtype = 'societe'; if ($elementtype == 'contact') $elementtype = 'socpeople'; if ($elementtype == 'order_supplier') $elementtype = 'commande_fournisseur'; + if ($elementtype == 'stock_mouvement') $elementtype = 'movement'; $array_name_label = array(); diff --git a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php index d0e9ba9d1e4..69af56d1e17 100644 --- a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php +++ b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php @@ -183,7 +183,7 @@ class pdf_stdmovement extends ModelePDFMovement /** * Function to build a document on disk using the generic odt module. * - * @param StockMovements $object Object source to build document + * @param MouvementStock $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 07f0e332276..ec54b88a31b 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -109,7 +109,7 @@ $hookmanager->initHooks(array('expensereportlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('expensereport'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 3ecf9a076dc..42031e25ce5 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -85,7 +85,7 @@ $hookmanager->initHooks(array('interventionlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('fichinter'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index acd79212052..417e78023a8 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -120,7 +120,7 @@ $hookmanager->initHooks(array('supplierorderlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('commande_fournisseur'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index bfd1cd46fb5..8fe0b67a233 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -310,7 +310,7 @@ class MyObject extends CommonObject foreach ($object->array_options as $key => $option) { $shortkey = preg_replace('/options_/', '', $key); - if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey])) + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; unset($object->array_options[$key]); diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 57eacb75ed4..19b5c48df8f 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -107,7 +107,7 @@ $extrafields = new ExtraFields($db); $form = new Form($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('product'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); if (empty($action)) $action = 'list'; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 3a5ae388f9f..484a93e8631 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -122,8 +122,7 @@ $object = new Task($db); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -//$extrafields->fetch_name_optionals_label('projet'); -$extrafields->fetch_name_optionals_label('projet_task'); +$extrafields->fetch_name_optionals_label($object->table_element); $arrayfields = array(); /*$arrayfields=array( diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php index 40e6e55cb33..7d794e99a74 100644 --- a/htdocs/public/ticket/list.php +++ b/htdocs/public/ticket/list.php @@ -201,7 +201,7 @@ if ($action == "view_ticketlist") // fetch optionals attributes and labels $extrafields = new ExtraFields($db); - $extrafields->fetch_name_optionals_label('ticket'); + $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/zapier/class/hook.class.php b/htdocs/zapier/class/hook.class.php index b985c77434e..4d3d7296b2f 100644 --- a/htdocs/zapier/class/hook.class.php +++ b/htdocs/zapier/class/hook.class.php @@ -354,10 +354,10 @@ class Hook extends CommonObject // ... // Clear extrafields that are unique if (is_array($object->array_options) && count($object->array_options) > 0) { - $extrafields->fetch_name_optionals_label($this->element); + $extrafields->fetch_name_optionals_label($this->table_element); foreach ($object->array_options as $key => $option) { $shortkey = preg_replace('/options_/', '', $key); - if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey])) { + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { // var_dump($key); // var_dump($clonedObj->array_options[$key]); // exit; From 4587031481f4d15c0897e621e44d16360163beca Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 13:31:29 +0200 Subject: [PATCH 41/97] FIX #14336 --- htdocs/core/tpl/extrafields_list_search_title.tpl.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/core/tpl/extrafields_list_search_title.tpl.php b/htdocs/core/tpl/extrafields_list_search_title.tpl.php index 9a83cbb42aa..6c0e6b0a559 100644 --- a/htdocs/core/tpl/extrafields_list_search_title.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_title.tpl.php @@ -29,6 +29,10 @@ if (!empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_e } else { + if (! empty($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]) && is_object($langs)) { + $langs->load($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]); + } + $tooltip = empty($extrafields->attributes[$extrafieldsobjectkey]['help'][$key]) ? '' : $extrafields->attributes[$extrafieldsobjectkey]['help'][$key]; print getTitleFieldOfList($extrafields->attributes[$extrafieldsobjectkey]['label'][$key], 0, $_SERVER["PHP_SELF"], $sortonfield, "", $param, ($align ? 'align="'.$align.'" data-titlekey="'.$key.'"' : 'data-titlekey="'.$key.'"'), $sortfield, $sortorder, '', $disablesortlink, $tooltip)."\n"; From 39a55839301dae3a33eeecfc86177b8b898904b7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 13:31:29 +0200 Subject: [PATCH 42/97] FIX #14146 --- htdocs/core/tpl/extrafields_list_search_title.tpl.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/core/tpl/extrafields_list_search_title.tpl.php b/htdocs/core/tpl/extrafields_list_search_title.tpl.php index 9a83cbb42aa..6c0e6b0a559 100644 --- a/htdocs/core/tpl/extrafields_list_search_title.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_title.tpl.php @@ -29,6 +29,10 @@ if (!empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_e } else { + if (! empty($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]) && is_object($langs)) { + $langs->load($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]); + } + $tooltip = empty($extrafields->attributes[$extrafieldsobjectkey]['help'][$key]) ? '' : $extrafields->attributes[$extrafieldsobjectkey]['help'][$key]; print getTitleFieldOfList($extrafields->attributes[$extrafieldsobjectkey]['label'][$key], 0, $_SERVER["PHP_SELF"], $sortonfield, "", $param, ($align ? 'align="'.$align.'" data-titlekey="'.$key.'"' : 'data-titlekey="'.$key.'"'), $sortfield, $sortorder, '', $disablesortlink, $tooltip)."\n"; From 9a5d0ab0a293aa859f5fe79232bcbc7d6289c68f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 13:48:11 +0200 Subject: [PATCH 43/97] FIX #14236 --- htdocs/adherents/admin/adherent_emails.php | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/htdocs/adherents/admin/adherent_emails.php b/htdocs/adherents/admin/adherent_emails.php index e0675a6124a..c58dea54a93 100644 --- a/htdocs/adherents/admin/adherent_emails.php +++ b/htdocs/adherents/admin/adherent_emails.php @@ -93,6 +93,7 @@ if ($action == 'update' || $action == 'add') $constnote = (GETPOSTISSET('constnote_'.$constname) ? GETPOST('constnote_'.$constname, 'none') : GETPOST('constnote')); $typetouse = empty($oldtypetonewone[$consttype]) ? $consttype : $oldtypetonewone[$consttype]; + $constvalue = preg_replace('/:member$/', '', $constvalue); $res = dolibarr_set_const($db, $constname, $constvalue, $typetouse, 0, $constnote, $conf->entity); @@ -108,26 +109,6 @@ if ($action == 'update' || $action == 'add') } } -// Action to enable a submodule of the adherent module -if ($action == 'set') -{ - $result = dolibarr_set_const($db, GETPOST('name', 'alpha'), GETPOST('value'), '', 0, '', $conf->entity); - if ($result < 0) - { - print $db->error(); - } -} - -// Action to disable a submodule of the adherent module -if ($action == 'unset') -{ - $result = dolibarr_del_const($db, GETPOST('name', 'alpha'), $conf->entity); - if ($result < 0) - { - print $db->error(); - } -} - /* From e16fd45972a4ba717ca867ab126c07c8b5f7328c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 14:44:52 +0200 Subject: [PATCH 44/97] FIX Label of opportunities in graph with special chars badly encoded --- htdocs/projet/graph_opportunities.inc.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/htdocs/projet/graph_opportunities.inc.php b/htdocs/projet/graph_opportunities.inc.php index 8d0e7bb1e02..2bb9332c2ae 100644 --- a/htdocs/projet/graph_opportunities.inc.php +++ b/htdocs/projet/graph_opportunities.inc.php @@ -1,4 +1,22 @@ + * + * 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 . + */ + +// variable $listofopplabel and $listofoppstatus should be defined + if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { $sql = "SELECT p.fk_opp_status as opp_status, cls.code, COUNT(p.rowid) as nb, SUM(p.opp_amount) as opp_amount, SUM(p.opp_amount * p.opp_percent) as ponderated_opp_amount"; @@ -54,7 +72,7 @@ if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) $labelStatus = ''; $code = dol_getIdFromCode($db, $status, 'c_lead_status', 'rowid', 'code'); - if ($code) $labelStatus = $langs->trans("OppStatus".$code); + if ($code) $labelStatus = $langs->transnoentitiesnoconv("OppStatus".$code); if (empty($labelStatus)) $labelStatus = $listofopplabel[$status]; //$labelStatus .= ' ('.$langs->trans("Coeff").': '.price2num($listofoppstatus[$status]).')'; From 5d20f47473b879c3c63361b1e7eafe140f088012 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 15:00:03 +0200 Subject: [PATCH 45/97] FIX page for confirmation of payments is empty --- htdocs/public/payment/paymentko.php | 10 ++++++---- htdocs/public/payment/paymentok.php | 30 ++++++++++++++++------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index a3f6d733fcb..f84a014d5e5 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -129,10 +129,12 @@ if (!empty($_SESSION['ipaddress'])) // To avoid to make action twice $ipaddress = $_SESSION['ipaddress']; $errormessage = $_SESSION['errormessage']; - // Call trigger - $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_KO', $user); - if ($result < 0) $error++; - // End call triggers + if (is_object($object) && method_exists($object, 'call_trigger')) { + // Call trigger + $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_KO', $user); + if ($result < 0) $error++; + // End call triggers + } // Send an email $sendemail = ''; diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index b1d6c149a51..5203da2284f 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -616,8 +616,8 @@ if ($ispaymentok) { // Record payment include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; - $invoice = new Facture($db); - $result = $invoice->fetch($tmptag['INV']); + $object = new Facture($db); + $result = $object->fetch($tmptag['INV']); if ($result) { $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; @@ -646,11 +646,11 @@ if ($ispaymentok) $paiement->datepaye = $now; if ($currencyCodeType == $conf->currency) { - $paiement->amounts = array($invoice->id => $FinalPaymentAmt); // Array with all payments dispatching with invoice id + $paiement->amounts = array($object->id => $FinalPaymentAmt); // Array with all payments dispatching with invoice id } else { - $paiement->multicurrency_amounts = array($invoice->id => $FinalPaymentAmt); // Array with all payments dispatching + $paiement->multicurrency_amounts = array($object->id => $FinalPaymentAmt); // Array with all payments dispatching $postactionmessages[] = 'Payment was done in a different currency that currency expected of company'; $ispostactionok = -1; @@ -689,7 +689,7 @@ if ($ispaymentok) if ($bankaccountid > 0) { $label = '(CustomerInvoicePayment)'; - if ($invoice->type == Facture::TYPE_CREDIT_NOTE) $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note + if ($object->type == Facture::TYPE_CREDIT_NOTE) $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note $result = $paiement->addPaymentToBank($user, 'payment', $label, $bankaccountid, '', ''); if ($result < 0) { @@ -748,10 +748,12 @@ if ($ispaymentok) $currencyCodeType = $_SESSION['currencyCodeType']; $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; - // Call trigger - $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_OK', $user); - if ($result < 0) $error++; - // End call triggers + if (is_object($object) && method_exists($object, 'call_trigger')) { + // Call trigger + $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_OK', $user); + if ($result < 0) $error++; + // End call triggers + } print $langs->trans("YourPaymentHasBeenRecorded")."
\n"; if ($TRANSACTIONID) print $langs->trans("ThisIsTransactionId", $TRANSACTIONID)."

\n"; @@ -882,10 +884,12 @@ else $currencyCodeType = $_SESSION['currencyCodeType']; $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; - // Call trigger - $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_KO', $user); - if ($result < 0) $error++; - // End call triggers + if (is_object($object) && method_exists($object, 'call_trigger')) { + // Call trigger + $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_KO', $user); + if ($result < 0) $error++; + // End call triggers + } print $langs->trans('DoExpressCheckoutPaymentAPICallFailed')."
\n"; print $langs->trans('DetailedErrorMessage').": ".$ErrorLongMsg."
\n"; From cb0a9868d75f0032bd2d6539abc15c0a8b820ee2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 15:16:11 +0200 Subject: [PATCH 46/97] Space --- htdocs/public/payment/paymentok.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 2d58f2bd2f9..b316e7c68a8 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -186,7 +186,7 @@ if ($urllogo) } -print '

'; +print '


'; if (!empty($conf->paypal->enabled)) From 68fa8fdcaa84f1987ec6d9a05a3c32584db61ed4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 15:18:24 +0200 Subject: [PATCH 47/97] Doc --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f7903361b02..ca9641ce63e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ # We use dist: xenial to have php 5.6+ available os: linux dist: xenial +#dist: bionic sudo: required language: php From 20a11b0f46d4943e90f4dee0eb474f515f464404 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 15:36:35 +0200 Subject: [PATCH 48/97] Doc --- ChangeLog | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/ChangeLog b/ChangeLog index 258a308cce3..c133aed03c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,67 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 12.0.2 compared to 12.0.1 ***** +FIX: computation of the bottom margin of returns NaN because body is not loaded yet +FIX: DebugBar hides content at page bottom +FIX: allow more harmless html tags +FIX: Bad back to link +FIX: Bad param +FIX: Can go on page even when module is disabled +FIX: Change position of line in BOM +FIX: Checkbox "drop table" was not checked when using php method to generate backup dump +FIX: ClickToDial tab of users has disappeared +FIX: CSS +FIX: date in supplier price log tooltip. +FIX: Debug module direct debit order. Solve conflict with credit transfer +FIX: Debug setup of receipt printer module +FIX: dolGetElementUrl and agenda page for external modules +FIX: DO not erase variable $key and $label during output of extrafields +FIX: duration fields size with firefox +FIX: Edit extrafield of type long text loose carriage returns +FIX: Fails to retraive accounting code of social contribution sometimes +FIX: Filter too large for extrafields with type text or html +FIX: for #14253 +FIX: If using a rounding step, localtax1+2 not included in total +FIX: input field of extrafields must keep data if form submit fails. +FIX: Label of opportunities in graph with special chars badly encoded +FIX: locataxes lost on lines when cloning a vendor invoice +FIX: Look and feel v12 +FIX: Missing PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE conf in supplier order +FIX: Navigation in object fails to find the next ref in some cases +FIX: null required +FIX: order by amount ht uses wrong column +FIX: Order by amount in product propal stats must be done on d.total_ht and not p.total +FIX: page for confirmation of payments is empty +FIX: Param of fetch_name_optionals_label must be object->table_element +FIX: Picto of HRM module +FIX: product label and desc were never updated when modifying trans +FIX: redirect on contact card from main search +FIX: Reposition and nav +FIX: search warehouse list +FIX: Setup of clicktodial hang on smartphone +FIX: Setup of currency limit and accuracy +FIX: shipping creation: checks not done on weight and sizes +FIX: Should not be able to edit qty on shipment when no stock available +FIX: Size of image on the help popup of modules +FIX: Sql error on stat by referring entries of a product +FIX: Warning if no bank account defined +FIX: We need to see unit line on PDF even though it's an option +FIX: wrong element var for fetch_name_optionals_label function with expeditions +FIX: wrong link to third invoice templates +FIX: #14076 +FIX: #14146 +FIX: #14209 +FIX: #14222 +FIX: #14236 +FIX: #14241 Mysql 8 compatibility +FIX: #14256 +FIX: #14259 +FIX: #14279 +FIX: #14291 +FIX: #14292 +FIX: #14336 + ***** ChangeLog for 12.0.1 compared to 12.0.0 ***** FIX: reposition was broken if url end with #anchor FIX: $_POST must be GETPOST From e368de9bba65add686d79f5caa9c7616c81851f1 Mon Sep 17 00:00:00 2001 From: Philippe Grand Date: Tue, 4 Aug 2020 16:55:47 +0200 Subject: [PATCH 49/97] Update pdf_ban.modules.php --- htdocs/core/modules/bank/doc/pdf_ban.modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/bank/doc/pdf_ban.modules.php b/htdocs/core/modules/bank/doc/pdf_ban.modules.php index 3aa46add2ac..51dea857f61 100644 --- a/htdocs/core/modules/bank/doc/pdf_ban.modules.php +++ b/htdocs/core/modules/bank/doc/pdf_ban.modules.php @@ -292,7 +292,7 @@ class pdf_ban extends ModeleBankAccountDoc /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Project $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -377,7 +377,7 @@ class pdf_ban extends ModeleBankAccountDoc /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Project $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 7e519da8df2ff0e939015198bca922102f421d46 Mon Sep 17 00:00:00 2001 From: Philippe Grand Date: Tue, 4 Aug 2020 17:00:59 +0200 Subject: [PATCH 50/97] Update pdf_merou.modules.php The comment should be TCPDF and not PDF --- htdocs/core/modules/expedition/doc/pdf_merou.modules.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php index 5fbec0b2c68..bf54298d264 100644 --- a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php @@ -438,7 +438,7 @@ class pdf_merou extends ModelePdfExpedition /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -480,7 +480,7 @@ class pdf_merou extends ModelePdfExpedition /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text @@ -509,7 +509,7 @@ class pdf_merou extends ModelePdfExpedition /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output From 8483d4609cb9cf6f2e38d71542204ee7921985e6 Mon Sep 17 00:00:00 2001 From: Philippe Grand Date: Tue, 4 Aug 2020 17:05:32 +0200 Subject: [PATCH 51/97] Update pdf_rouget.modules.php The comment should be TCPDF and not PDF --- htdocs/core/modules/expedition/doc/pdf_rouget.modules.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php index dc29b6411f5..391b8d0e3bf 100644 --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php @@ -662,7 +662,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart @@ -769,7 +769,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -857,7 +857,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1100,7 +1100,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 9232459b1e7bde1c78e082fd03778e3b76fcdbd9 Mon Sep 17 00:00:00 2001 From: Philippe Grand Date: Tue, 4 Aug 2020 17:07:53 +0200 Subject: [PATCH 52/97] Update pdf_ban.modules.php The comment should be TCPDF and not PDF --- htdocs/core/modules/bank/doc/pdf_ban.modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/bank/doc/pdf_ban.modules.php b/htdocs/core/modules/bank/doc/pdf_ban.modules.php index 3aa46add2ac..51dea857f61 100644 --- a/htdocs/core/modules/bank/doc/pdf_ban.modules.php +++ b/htdocs/core/modules/bank/doc/pdf_ban.modules.php @@ -292,7 +292,7 @@ class pdf_ban extends ModeleBankAccountDoc /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Project $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -377,7 +377,7 @@ class pdf_ban extends ModeleBankAccountDoc /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Project $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 8d2edfc5ab91be85c9b3a2ec761919d686bbe2ce Mon Sep 17 00:00:00 2001 From: Philippe Grand Date: Tue, 4 Aug 2020 17:13:08 +0200 Subject: [PATCH 53/97] Update pdf_crabe.modules.php The comment should be TCPDF and not PDF --- .../core/modules/facture/doc/pdf_crabe.modules.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index cd2f711d23a..96cdf62a53b 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -780,7 +780,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object invoice * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -965,7 +965,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -1139,7 +1139,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Amount already paid (in the currency of invoice) * @param int $posy Position depart @@ -1464,7 +1464,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1586,7 +1586,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1889,7 +1889,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From eed8957e075f8c7f1a2201566f795ece786582fb Mon Sep 17 00:00:00 2001 From: Philippe Grand Date: Tue, 4 Aug 2020 17:33:52 +0200 Subject: [PATCH 54/97] Update pdf_blochet.class.php The comment should be TCPDF and not PDF --- htdocs/core/modules/cheque/doc/pdf_blochet.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/cheque/doc/pdf_blochet.class.php b/htdocs/core/modules/cheque/doc/pdf_blochet.class.php index ec6f52dfec7..264c32e4234 100644 --- a/htdocs/core/modules/cheque/doc/pdf_blochet.class.php +++ b/htdocs/core/modules/cheque/doc/pdf_blochet.class.php @@ -213,7 +213,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts /** * Generate Header * - * @param PDF $pdf Pdf object + * @param TCPDF $pdf Pdf object * @param int $page Current page number * @param int $pages Total number of pages * @param Translate $outputlangs Object language for output @@ -321,7 +321,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts /** * Output array * - * @param PDF $pdf PDF object + * @param TCPDF $pdf PDF object * @param int $pagenb Page nb * @param int $pages Pages * @param Translate $outputlangs Object lang @@ -390,7 +390,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From d8da007e0e1ea0722a50fbf0ec79917f8c1c60fc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 18:50:57 +0200 Subject: [PATCH 55/97] css --- htdocs/compta/prelevement/demandes.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/prelevement/demandes.php b/htdocs/compta/prelevement/demandes.php index feda7f0771d..c3d2370fd4b 100644 --- a/htdocs/compta/prelevement/demandes.php +++ b/htdocs/compta/prelevement/demandes.php @@ -173,9 +173,9 @@ if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) -$newcardbutton = ''.$langs->trans("Back").''; +$newcardbutton = ''.$langs->trans("Back").''; if ($type == 'bank-transfer') { - $newcardbutton = ''.$langs->trans("Back").''; + $newcardbutton = ''.$langs->trans("Back").''; } print '
'; From 5189e8beea4a5d70aebc66c7da8461eb857052ca Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 20:26:57 +0200 Subject: [PATCH 56/97] FIX Debug direct debit module and credit transfer module --- htdocs/compta/paymentbybanktransfer/index.php | 2 +- .../class/bonprelevement.class.php | 107 ++++++++++++------ htdocs/compta/prelevement/create.php | 6 +- .../fourn/class/fournisseur.facture.class.php | 3 +- htdocs/langs/en_US/withdrawals.lang | 1 + 5 files changed, 78 insertions(+), 41 deletions(-) diff --git a/htdocs/compta/paymentbybanktransfer/index.php b/htdocs/compta/paymentbybanktransfer/index.php index 2f9d7ed127f..e2477d86544 100644 --- a/htdocs/compta/paymentbybanktransfer/index.php +++ b/htdocs/compta/paymentbybanktransfer/index.php @@ -68,7 +68,7 @@ print '
'; $thirdpartystatic = new Societe($db); -$invoicestatic = new Facture($db); +$invoicestatic = new FactureFournisseur($db); $bprev = new BonPrelevement($db); print '
'; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 7e505f97bee..a14c781459e 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -884,14 +884,11 @@ class BonPrelevement extends CommonObject $sql .= " AND f.rowid = pfd.fk_facture_fourn"; } $sql .= " AND s.rowid = f.fk_soc"; - //if ($banque || $agence) $sql.= " AND s.rowid = sr.fk_soc"; - $sql .= " AND f.fk_statut = 1"; + $sql .= " AND f.fk_statut = 1"; // Invoice validated $sql .= " AND f.paye = 0"; $sql .= " AND pfd.traite = 0"; $sql .= " AND f.total_ttc > 0"; $sql .= " AND pfd.ext_payment_id IS NULL"; - //if ($banque) $sql.= " AND sr.code_banque = '".$conf->global->PRELEVEMENT_CODE_BANQUE."'"; - //if ($agence) $sql.= " AND sr.code_guichet = '".$conf->global->PRELEVEMENT_CODE_GUICHET."'"; dol_syslog(__METHOD__."::Read invoices, sql=".$sql, LOG_DEBUG); @@ -1000,15 +997,13 @@ class BonPrelevement extends CommonObject if (count($factures_prev) > 0) { - if ($mode == 'real') - { + if ($mode == 'real') { $ok = 1; } else { - print $langs->trans("ModeWarning"); //"Option for real mode was not set, we stop after this simulation\n"; + print $langs->trans("ModeWarning"); // "Option for real mode was not set, we stop after this simulation\n"; } } - if ($ok) { /* @@ -1051,7 +1046,7 @@ class BonPrelevement extends CommonObject // Create withdraw receipt in database $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons ("; - $sql .= " ref, entity, datec, type"; + $sql .= "ref, entity, datec, type"; $sql .= ") VALUES ("; $sql .= "'".$this->db->escape($ref)."'"; $sql .= ", ".$conf->entity; @@ -1077,6 +1072,12 @@ class BonPrelevement extends CommonObject if (!$error) { + if ($type != 'bank-transfer') { + $fact = new Facture($this->db); + } else { + $fact = new FactureFournisseur($this->db); + } + /* * Create withdrawal receipt in database */ @@ -1085,11 +1086,14 @@ class BonPrelevement extends CommonObject foreach ($factures_prev as $fac) // Add a link in database for each invoice { // Fetch invoice - $fact = new Facture($this->db); - $fact->fetch($fac[0]); + $result = $fact->fetch($fac[0]); + if ($result < 0) { + $this->error = 'ERRORBONPRELEVEMENT Failed to load invoice with id '.$fac[0]; + break; + } /* - * Add standing order + * Add standing order. This add record into llx_prelevement_lignes * * $fac[0] : invoice_id * $fac[1] : ??? @@ -1100,9 +1104,7 @@ class BonPrelevement extends CommonObject * $fac[6] : cle rib * $fac[7] : amount * $fac[8] : client nom - * $fac[2] : client id */ - $ri = $this->AddFacture($fac[0], $fac[2], $fac[8], $fac[7], $fac[3], $fac[4], $fac[5], $fac[6], $type); if ($ri <> 0) { @@ -1117,7 +1119,6 @@ class BonPrelevement extends CommonObject $sql .= " WHERE rowid = ".$fac[1]; $resql = $this->db->query($sql); - if (!$resql) { $error++; @@ -1141,6 +1142,9 @@ class BonPrelevement extends CommonObject $this->reference_remise = $ref; $id = $conf->global->PRELEVEMENT_ID_BANKACCOUNT; + if ($type == 'bank-transfer') { + $id = $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT; + } $account = new Account($this->db); if ($account->fetch($id) > 0) { @@ -1162,24 +1166,31 @@ class BonPrelevement extends CommonObject // Generation of direct debit or credti transfer file $this->filename (May be a SEPA file for european countries) // This also set the property $this->total with amount that is included into file $result = $this->generate($format, $executiondate, $type); + if ($result < 0) { + /*var_dump($this->error); + var_dump($this->invoice_in_error); */ + $error++; + } } dol_syslog(__METHOD__."::End withdraw receipt, file ".$this->filename, LOG_DEBUG); } - //var_dump($factures_prev);exit; + //var_dump($this->total);exit; /* * Update total defined after generation of file */ - $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; - $sql .= " SET amount = ".price2num($this->total); - $sql .= " WHERE rowid = ".$this->id; - $sql .= " AND entity = ".$conf->entity; + if (! $error) { + $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; + $sql .= " SET amount = ".price2num($this->total); + $sql .= " WHERE rowid = ".$this->id; + $sql .= " AND entity = ".$conf->entity; - $resql = $this->db->query($sql); - if (!$resql) - { - $error++; - dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR); + $resql = $this->db->query($sql); + if (!$resql) + { + $error++; + dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR); + } } if (!$error && !$notrigger) @@ -1198,11 +1209,13 @@ class BonPrelevement extends CommonObject if (!$error) { $this->db->commit(); + + return count($factures_prev); } else { $this->db->rollback(); - } - return count($factures_prev); + return -1; + } } else { return 0; } @@ -1500,9 +1513,10 @@ class BonPrelevement extends CommonObject * Section Debitor (sepa Debiteurs bloc lines) */ - $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; + $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; - $sql .= " f.ref as fac, pf.fk_facture as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; + $sql .= " f.ref as fac, pf.fk_facture as idfac,"; + $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; $sql .= " ".MAIN_DB_PREFIX."facture as f,"; @@ -1513,21 +1527,31 @@ class BonPrelevement extends CommonObject $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; $sql .= " AND pf.fk_facture = f.rowid"; + $sql .= " AND f.fk_soc = soc.rowid"; $sql .= " AND soc.fk_pays = c.rowid"; - $sql .= " AND soc.rowid = f.fk_soc"; $sql .= " AND rib.fk_soc = f.fk_soc"; $sql .= " AND rib.default_rib = 1"; $sql .= " AND rib.type = 'ban'"; - //print $sql; // Define $fileDebiteurSection. One section DrctDbtTxInf per invoice. $resql = $this->db->query($sql); if ($resql) { + $cachearraytotestduplicate = array(); + $num = $this->db->num_rows($resql); while ($i < $num) { $obj = $this->db->fetch_object($resql); + + if (! empty($cachearraytotestduplicate[$obj->idfac])) { + $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid); + $this->invoice_in_error[$obj->idfac] = $this->error; + $result = -2; + break; + } + $cachearraytotestduplicate[$obj->idfac] = $obj->rowid; + $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); $this->total = $this->total + $obj->somme; @@ -1535,6 +1559,7 @@ class BonPrelevement extends CommonObject } $nbtotalDrctDbtTxInf = $i; } else { + $this->error = $this->db->lasterror(); fputs($this->file, 'ERROR DEBITOR '.$sql.$CrLf); // DEBITOR = Customers $result = -2; } @@ -1603,9 +1628,10 @@ class BonPrelevement extends CommonObject * Section Creditor (sepa Crediteurs bloc lines) */ - $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; + $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; - $sql .= " f.ref as fac, pf.fk_facture_fourn as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; + $sql .= " f.ref as fac, pf.fk_facture_fourn as idfac,"; + $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; @@ -1616,21 +1642,31 @@ class BonPrelevement extends CommonObject $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; $sql .= " AND pf.fk_facture_fourn = f.rowid"; + $sql .= " AND f.fk_soc = soc.rowid"; $sql .= " AND soc.fk_pays = c.rowid"; - $sql .= " AND soc.rowid = f.fk_soc"; $sql .= " AND rib.fk_soc = f.fk_soc"; $sql .= " AND rib.default_rib = 1"; $sql .= " AND rib.type = 'ban'"; - //print $sql; // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice. $resql = $this->db->query($sql); if ($resql) { + $cachearraytotestduplicate = array(); + $num = $this->db->num_rows($resql); while ($i < $num) { $obj = $this->db->fetch_object($resql); + + if (! empty($cachearraytotestduplicate[$obj->idfac])) { + $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid); + $this->invoice_in_error[$obj->idfac] = $this->error; + $result = -2; + break; + } + $cachearraytotestduplicate[$obj->idfac] = $obj->rowid; + $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); $this->total = $this->total + $obj->somme; @@ -1638,6 +1674,7 @@ class BonPrelevement extends CommonObject } $nbtotalDrctDbtTxInf = $i; } else { + $this->error = $this->db->lasterror(); fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers $result = -2; } diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 1de83c99761..f8d67de48c2 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -88,11 +88,9 @@ if (empty($reshook)) // $conf->global->PRELEVEMENT_CODE_BANQUE and $conf->global->PRELEVEMENT_CODE_GUICHET should be empty (we don't use them anymore) $result = $bprev->create($conf->global->PRELEVEMENT_CODE_BANQUE, $conf->global->PRELEVEMENT_CODE_GUICHET, $mode, $format, $executiondate, 0, $type); - if ($result < 0) - { + if ($result < 0) { setEventMessages($bprev->error, $bprev->errors, 'errors'); - } elseif ($result == 0) - { + } elseif ($result == 0) { $mesg = $langs->trans("NoInvoiceCouldBeWithdrawed", $format); setEventMessages($mesg, null, 'errors'); $mesg .= '
'."\n"; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 95f2f97a7fd..04525afa04d 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2267,7 +2267,8 @@ class FactureFournisseur extends CommonInvoice $result = ''; - if ($option == 'document') $url = DOL_URL_ROOT.'/fourn/facture/document.php?facid='.$this->id; + if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id.'&type=bank-transfer'; + elseif ($option == 'document') $url = DOL_URL_ROOT.'/fourn/facture/document.php?facid='.$this->id; else $url = DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$this->id; if ($short) return $url; diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index b7947969811..553e3ac0eaa 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -145,3 +145,4 @@ InfoTransData=Amount: %s
Method: %s
Date: %s InfoRejectSubject=Direct debit payment order refused InfoRejectMessage=Hello,

the direct debit payment order of invoice %s related to the company %s, with an amount of %s has been refused by the bank.

--
%s ModeWarning=Option for real mode was not set, we stop after this simulation +ErrorCompanyHasDuplicateDefaultBAN=Company with id %s has more than one default bank account. No way to know wich one to use. \ No newline at end of file From 84bdfc4bb7547aa45b4cebe19d03b0c4b9c16e0b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 21:06:38 +0200 Subject: [PATCH 57/97] FIX List of invoice waiting for direct debit --- htdocs/compta/prelevement/demandes.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/prelevement/demandes.php b/htdocs/compta/prelevement/demandes.php index c3d2370fd4b..53934deaac1 100644 --- a/htdocs/compta/prelevement/demandes.php +++ b/htdocs/compta/prelevement/demandes.php @@ -105,14 +105,17 @@ if ($type != 'bank-transfer') { llxHeader('', $title); $thirdpartystatic = new Societe($db); -$invoicestatic = new Facture($db); +if ($type == 'bank-transfer') { + $invoicestatic = new FactureFournisseur($db); +} else { + $invoicestatic = new Facture($db); +} // List of requests $sql = "SELECT f.ref, f.rowid, f.total_ttc,"; $sql .= " s.nom as name, s.rowid as socid,"; -$sql .= " pfd.date_demande as date_demande,"; -$sql .= " pfd.fk_user_demande"; +$sql .= " pfd.date_demande as date_demande, pfd.amount, pfd.fk_user_demande"; if ($type != 'bank-transfer') { $sql .= " FROM ".MAIN_DB_PREFIX."facture as f,"; } else { @@ -126,6 +129,7 @@ $sql .= " AND f.entity IN (".getEntity('invoice').")"; if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; if ($socid) $sql .= " AND f.fk_soc = ".$socid; if (!$status) $sql .= " AND pfd.traite = 0"; +$sql .= " AND pfd.ext_payment_id IS NULL"; if ($status) $sql .= " AND pfd.traite = ".$status; $sql .= " AND f.total_ttc > 0"; if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS)) @@ -141,7 +145,6 @@ if ($search_facture) $sql .= natural_search("f.ref", $search_facture); if ($search_societe) $sql .= natural_search("s.nom", $search_societe); $sql .= $db->order($sortfield, $sortorder); - // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) @@ -205,7 +208,7 @@ print ''; print ''; print_liste_field_titre("Bill", $_SERVER["PHP_SELF"]); print_liste_field_titre("Company", $_SERVER["PHP_SELF"]); -print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'right '); +print_liste_field_titre("AmountRequested", $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'right '); print_liste_field_titre("DateRequest", $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'center '); print_liste_field_titre(''); print ''; @@ -228,12 +231,12 @@ while ($i < min($num, $limit)) $obj = $db->fetch_object($resql); if (empty($obj)) break; // Should not happen + $invoicestatic->fetch($obj->rowid); + print ''; // Ref facture print ''; @@ -243,7 +246,9 @@ while ($i < min($num, $limit)) print $thirdpartystatic->getNomUrl(1, 'customer'); print ''; - print ''; + print ''; print ''; From 70d68669d2168729e0867c49cbe57648e3c56f37 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 21:07:01 +0200 Subject: [PATCH 58/97] Doc --- ChangeLog | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c133aed03c5..1144f11726f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,13 +23,12 @@ FIX: duration fields size with firefox FIX: Edit extrafield of type long text loose carriage returns FIX: Fails to retraive accounting code of social contribution sometimes FIX: Filter too large for extrafields with type text or html -FIX: for #14253 FIX: If using a rounding step, localtax1+2 not included in total FIX: input field of extrafields must keep data if form submit fails. FIX: Label of opportunities in graph with special chars badly encoded FIX: locataxes lost on lines when cloning a vendor invoice FIX: Look and feel v12 -FIX: Missing PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE conf in supplier order +FIX: Missing PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE conf support in supplier order FIX: Navigation in object fails to find the next ref in some cases FIX: null required FIX: order by amount ht uses wrong column @@ -37,7 +36,7 @@ FIX: Order by amount in product propal stats must be done on d.total_ht and not FIX: page for confirmation of payments is empty FIX: Param of fetch_name_optionals_label must be object->table_element FIX: Picto of HRM module -FIX: product label and desc were never updated when modifying trans +FIX: product label and desc were never updated when modifying translation FIX: redirect on contact card from main search FIX: Reposition and nav FIX: search warehouse list @@ -57,6 +56,7 @@ FIX: #14209 FIX: #14222 FIX: #14236 FIX: #14241 Mysql 8 compatibility +FIX: #14253 FIX: #14256 FIX: #14259 FIX: #14279 From a3f7cbd63dc4c65f60e12b74bb164a5aec04371f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 18:50:57 +0200 Subject: [PATCH 59/97] css --- htdocs/compta/prelevement/demandes.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/prelevement/demandes.php b/htdocs/compta/prelevement/demandes.php index 2d2be116aaf..e377957888e 100644 --- a/htdocs/compta/prelevement/demandes.php +++ b/htdocs/compta/prelevement/demandes.php @@ -175,9 +175,9 @@ if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) -$newcardbutton = ''.$langs->trans("Back").''; +$newcardbutton = ''.$langs->trans("Back").''; if ($type == 'bank-transfer') { - $newcardbutton = ''.$langs->trans("Back").''; + $newcardbutton = ''.$langs->trans("Back").''; } print ''; From 9d4e672475f6ccb635a7890df90c3b5825c087f9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 20:26:57 +0200 Subject: [PATCH 60/97] FIX Debug direct debit module and credit transfer module Conflicts: htdocs/compta/prelevement/class/bonprelevement.class.php htdocs/compta/prelevement/create.php --- htdocs/compta/paymentbybanktransfer/index.php | 2 +- .../class/bonprelevement.class.php | 125 +++++++++++------- htdocs/compta/prelevement/create.php | 11 +- .../fourn/class/fournisseur.facture.class.php | 3 +- htdocs/langs/en_US/withdrawals.lang | 1 + 5 files changed, 82 insertions(+), 60 deletions(-) diff --git a/htdocs/compta/paymentbybanktransfer/index.php b/htdocs/compta/paymentbybanktransfer/index.php index 79bb2f6e7fb..fb1432a18f1 100644 --- a/htdocs/compta/paymentbybanktransfer/index.php +++ b/htdocs/compta/paymentbybanktransfer/index.php @@ -68,7 +68,7 @@ print '
'; $thirdpartystatic = new Societe($db); -$invoicestatic = new Facture($db); +$invoicestatic = new FactureFournisseur($db); $bprev = new BonPrelevement($db); print '
'; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 9210e0e62c0..b1e7e29a698 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -926,14 +926,11 @@ class BonPrelevement extends CommonObject $sql .= " AND f.rowid = pfd.fk_facture_fourn"; } $sql .= " AND s.rowid = f.fk_soc"; - //if ($banque || $agence) $sql.= " AND s.rowid = sr.fk_soc"; - $sql .= " AND f.fk_statut = 1"; + $sql .= " AND f.fk_statut = 1"; // Invoice validated $sql .= " AND f.paye = 0"; $sql .= " AND pfd.traite = 0"; $sql .= " AND f.total_ttc > 0"; $sql .= " AND pfd.ext_payment_id IS NULL"; - //if ($banque) $sql.= " AND sr.code_banque = '".$conf->global->PRELEVEMENT_CODE_BANQUE."'"; - //if ($agence) $sql.= " AND sr.code_guichet = '".$conf->global->PRELEVEMENT_CODE_GUICHET."'"; dol_syslog(__METHOD__."::Read invoices, sql=".$sql, LOG_DEBUG); @@ -1052,17 +1049,13 @@ class BonPrelevement extends CommonObject if (count($factures_prev) > 0) { - if ($mode == 'real') - { + if ($mode == 'real') { $ok = 1; - } - else - { - print $langs->trans("ModeWarning"); //"Option for real mode was not set, we stop after this simulation\n"; + } else { + print $langs->trans("ModeWarning"); // "Option for real mode was not set, we stop after this simulation\n"; } } - if ($ok) { /* @@ -1105,7 +1098,7 @@ class BonPrelevement extends CommonObject // Create withdraw receipt in database $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons ("; - $sql .= " ref, entity, datec, type"; + $sql .= "ref, entity, datec, type"; $sql .= ") VALUES ("; $sql .= "'".$this->db->escape($ref)."'"; $sql .= ", ".$conf->entity; @@ -1135,6 +1128,12 @@ class BonPrelevement extends CommonObject if (!$error) { + if ($type != 'bank-transfer') { + $fact = new Facture($this->db); + } else { + $fact = new FactureFournisseur($this->db); + } + /* * Create withdrawal receipt in database */ @@ -1143,11 +1142,14 @@ class BonPrelevement extends CommonObject foreach ($factures_prev as $fac) // Add a link in database for each invoice { // Fetch invoice - $fact = new Facture($this->db); - $fact->fetch($fac[0]); + $result = $fact->fetch($fac[0]); + if ($result < 0) { + $this->error = 'ERRORBONPRELEVEMENT Failed to load invoice with id '.$fac[0]; + break; + } /* - * Add standing order + * Add standing order. This add record into llx_prelevement_lignes * * $fac[0] : invoice_id * $fac[1] : ??? @@ -1158,9 +1160,7 @@ class BonPrelevement extends CommonObject * $fac[6] : cle rib * $fac[7] : amount * $fac[8] : client nom - * $fac[2] : client id */ - $ri = $this->AddFacture($fac[0], $fac[2], $fac[8], $fac[7], $fac[3], $fac[4], $fac[5], $fac[6], $type); if ($ri <> 0) { @@ -1175,7 +1175,6 @@ class BonPrelevement extends CommonObject $sql .= " WHERE rowid = ".$fac[1]; $resql = $this->db->query($sql); - if (!$resql) { $error++; @@ -1199,6 +1198,9 @@ class BonPrelevement extends CommonObject $this->reference_remise = $ref; $id = $conf->global->PRELEVEMENT_ID_BANKACCOUNT; + if ($type == 'bank-transfer') { + $id = $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT; + } $account = new Account($this->db); if ($account->fetch($id) > 0) { @@ -1220,24 +1222,31 @@ class BonPrelevement extends CommonObject // Generation of direct debit or credti transfer file $this->filename (May be a SEPA file for european countries) // This also set the property $this->total with amount that is included into file $result = $this->generate($format, $executiondate, $type); + if ($result < 0) { + /*var_dump($this->error); + var_dump($this->invoice_in_error); */ + $error++; + } } dol_syslog(__METHOD__."::End withdraw receipt, file ".$this->filename, LOG_DEBUG); } - //var_dump($factures_prev);exit; + //var_dump($this->total);exit; /* * Update total defined after generation of file */ - $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; - $sql .= " SET amount = ".price2num($this->total); - $sql .= " WHERE rowid = ".$this->id; - $sql .= " AND entity = ".$conf->entity; + if (! $error) { + $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; + $sql .= " SET amount = ".price2num($this->total); + $sql .= " WHERE rowid = ".$this->id; + $sql .= " AND entity = ".$conf->entity; - $resql = $this->db->query($sql); - if (!$resql) - { - $error++; - dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR); + $resql = $this->db->query($sql); + if (!$resql) + { + $error++; + dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR); + } } if (!$error && !$notrigger) @@ -1256,16 +1265,12 @@ class BonPrelevement extends CommonObject if (!$error) { $this->db->commit(); - } - else - { + return count($factures_prev); + } else { $this->db->rollback(); + return -1; } - - return count($factures_prev); - } - else - { + } else { return 0; } } @@ -1571,9 +1576,10 @@ class BonPrelevement extends CommonObject * Section Debitor (sepa Debiteurs bloc lines) */ - $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; + $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; - $sql .= " f.ref as fac, pf.fk_facture as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; + $sql .= " f.ref as fac, pf.fk_facture as idfac,"; + $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; $sql .= " ".MAIN_DB_PREFIX."facture as f,"; @@ -1584,30 +1590,39 @@ class BonPrelevement extends CommonObject $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; $sql .= " AND pf.fk_facture = f.rowid"; + $sql .= " AND f.fk_soc = soc.rowid"; $sql .= " AND soc.fk_pays = c.rowid"; - $sql .= " AND soc.rowid = f.fk_soc"; $sql .= " AND rib.fk_soc = f.fk_soc"; $sql .= " AND rib.default_rib = 1"; $sql .= " AND rib.type = 'ban'"; - //print $sql; // Define $fileDebiteurSection. One section DrctDbtTxInf per invoice. $resql = $this->db->query($sql); if ($resql) { + $cachearraytotestduplicate = array(); + $num = $this->db->num_rows($resql); while ($i < $num) { $obj = $this->db->fetch_object($resql); + + if (! empty($cachearraytotestduplicate[$obj->idfac])) { + $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid); + $this->invoice_in_error[$obj->idfac] = $this->error; + $result = -2; + break; + } + $cachearraytotestduplicate[$obj->idfac] = $obj->rowid; + $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); $this->total = $this->total + $obj->somme; $i++; } $nbtotalDrctDbtTxInf = $i; - } - else - { + } else { + $this->error = $this->db->lasterror(); fputs($this->file, 'ERROR DEBITOR '.$sql.$CrLf); // DEBITOR = Customers $result = -2; } @@ -1676,9 +1691,10 @@ class BonPrelevement extends CommonObject * Section Creditor (sepa Crediteurs bloc lines) */ - $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; + $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; - $sql .= " f.ref as fac, pf.fk_facture_fourn as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; + $sql .= " f.ref as fac, pf.fk_facture_fourn as idfac,"; + $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; @@ -1689,30 +1705,39 @@ class BonPrelevement extends CommonObject $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; $sql .= " AND pf.fk_facture_fourn = f.rowid"; + $sql .= " AND f.fk_soc = soc.rowid"; $sql .= " AND soc.fk_pays = c.rowid"; - $sql .= " AND soc.rowid = f.fk_soc"; $sql .= " AND rib.fk_soc = f.fk_soc"; $sql .= " AND rib.default_rib = 1"; $sql .= " AND rib.type = 'ban'"; - //print $sql; // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice. $resql = $this->db->query($sql); if ($resql) { + $cachearraytotestduplicate = array(); + $num = $this->db->num_rows($resql); while ($i < $num) { $obj = $this->db->fetch_object($resql); + + if (! empty($cachearraytotestduplicate[$obj->idfac])) { + $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid); + $this->invoice_in_error[$obj->idfac] = $this->error; + $result = -2; + break; + } + $cachearraytotestduplicate[$obj->idfac] = $obj->rowid; + $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); $this->total = $this->total + $obj->somme; $i++; } $nbtotalDrctDbtTxInf = $i; - } - else - { + } else { + $this->error = $this->db->lasterror(); fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers $result = -2; } diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index e3f3e6beaf4..b8cac653dc4 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -88,12 +88,9 @@ if (empty($reshook)) // $conf->global->PRELEVEMENT_CODE_BANQUE and $conf->global->PRELEVEMENT_CODE_GUICHET should be empty (we don't use them anymore) $result = $bprev->create($conf->global->PRELEVEMENT_CODE_BANQUE, $conf->global->PRELEVEMENT_CODE_GUICHET, $mode, $format, $executiondate, 0, $type); - if ($result < 0) - { + if ($result < 0) { setEventMessages($bprev->error, $bprev->errors, 'errors'); - } - elseif ($result == 0) - { + } elseif ($result == 0) { $mesg = $langs->trans("NoInvoiceCouldBeWithdrawed", $format); setEventMessages($mesg, null, 'errors'); $mesg .= '
'."\n"; @@ -101,9 +98,7 @@ if (empty($reshook)) { $mesg .= ''.$val."
\n"; } - } - else - { + } else { if ($type != 'bank-transfer') { setEventMessages($langs->trans("DirectDebitOrderCreated", $bprev->getNomUrl(1)), null); } else { diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 093be1d9de8..0767d299b4b 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2339,7 +2339,8 @@ class FactureFournisseur extends CommonInvoice $result = ''; - if ($option == 'document') $url = DOL_URL_ROOT.'/fourn/facture/document.php?facid='.$this->id; + if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id.'&type=bank-transfer'; + elseif ($option == 'document') $url = DOL_URL_ROOT.'/fourn/facture/document.php?facid='.$this->id; else $url = DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$this->id; if ($short) return $url; diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index a1bb646bff3..a18ff7a8d31 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -145,3 +145,4 @@ InfoTransData=Amount: %s
Method: %s
Date: %s InfoRejectSubject=Direct debit payment order refused InfoRejectMessage=Hello,

the direct debit payment order of invoice %s related to the company %s, with an amount of %s has been refused by the bank.

--
%s ModeWarning=Option for real mode was not set, we stop after this simulation +ErrorCompanyHasDuplicateDefaultBAN=Company with id %s has more than one default bank account. No way to know wich one to use. \ No newline at end of file From eefa2bcaba7d27c2829a4a9e757831bdad47dcb1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 21:06:38 +0200 Subject: [PATCH 61/97] FIX List of invoice waiting for direct debit --- htdocs/compta/prelevement/demandes.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/prelevement/demandes.php b/htdocs/compta/prelevement/demandes.php index e377957888e..a83a6a2938c 100644 --- a/htdocs/compta/prelevement/demandes.php +++ b/htdocs/compta/prelevement/demandes.php @@ -107,14 +107,17 @@ if ($type != 'bank-transfer') { llxHeader('', $title); $thirdpartystatic = new Societe($db); -$invoicestatic = new Facture($db); +if ($type == 'bank-transfer') { + $invoicestatic = new FactureFournisseur($db); +} else { + $invoicestatic = new Facture($db); +} // List of requests $sql = "SELECT f.ref, f.rowid, f.total_ttc,"; $sql .= " s.nom as name, s.rowid as socid,"; -$sql .= " pfd.date_demande as date_demande,"; -$sql .= " pfd.fk_user_demande"; +$sql .= " pfd.date_demande as date_demande, pfd.amount, pfd.fk_user_demande"; if ($type != 'bank-transfer') { $sql .= " FROM ".MAIN_DB_PREFIX."facture as f,"; } else { @@ -128,6 +131,7 @@ $sql .= " AND f.entity IN (".getEntity('invoice').")"; if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; if ($socid) $sql .= " AND f.fk_soc = ".$socid; if (!$status) $sql .= " AND pfd.traite = 0"; +$sql .= " AND pfd.ext_payment_id IS NULL"; if ($status) $sql .= " AND pfd.traite = ".$status; $sql .= " AND f.total_ttc > 0"; if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS)) @@ -143,7 +147,6 @@ if ($search_facture) $sql .= natural_search("f.ref", $search_facture); if ($search_societe) $sql .= natural_search("s.nom", $search_societe); $sql .= $db->order($sortfield, $sortorder); - // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) @@ -207,7 +210,7 @@ print '
'; - $invoicestatic->id = $obj->rowid; - $invoicestatic->ref = $obj->ref; print $invoicestatic->getNomUrl(1, 'withdraw'); print ''.price($obj->total_ttc).''; + print price($obj->amount, 1, $langs, 1, -1, -1, $conf->currency).' / '.price($obj->total_ttc, 1, $langs, 1, -1, -1, $conf->currency); + print ''.dol_print_date($db->jdate($obj->date_demande), 'day').'
'; print ''; print_liste_field_titre("Bill", $_SERVER["PHP_SELF"]); print_liste_field_titre("Company", $_SERVER["PHP_SELF"]); -print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'right '); +print_liste_field_titre("AmountRequested", $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'right '); print_liste_field_titre("DateRequest", $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'center '); print_liste_field_titre(''); print ''; @@ -230,12 +233,12 @@ while ($i < min($num, $limit)) $obj = $db->fetch_object($resql); if (empty($obj)) break; // Should not happen + $invoicestatic->fetch($obj->rowid); + print ''; // Ref facture print ''; @@ -245,7 +248,9 @@ while ($i < min($num, $limit)) print $thirdpartystatic->getNomUrl(1, 'customer'); print ''; - print ''; + print ''; print ''; From 04d18e2a68abc90c0c05ef071713843ce457112a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 21:17:13 +0200 Subject: [PATCH 62/97] css --- htdocs/societe/paymentmodes.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index d872c9dfef3..e02a41dab86 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -848,7 +848,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ''; print ''; print ''; - print ''; + print ''; print ''; } print ''; @@ -903,7 +903,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ''; print ''; print ''; - //print ''; + //print ''; print ''; } print ''; From 3a9021f1915a88416c76f2ab6f8d55ce54765713 Mon Sep 17 00:00:00 2001 From: Egils Consulting Date: Tue, 4 Aug 2020 21:47:39 +0200 Subject: [PATCH 63/97] Update api_supplier_invoices.class.php Fix order->invoice and clarify 403 error which is always caused by the invoice already being validated. --- htdocs/fourn/class/api_supplier_invoices.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 5ec2b6f49a6..2840f29dd70 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -293,9 +293,9 @@ class SupplierInvoices extends DolibarrApi } /** - * Validate an order + * Validate an invoice * - * @param int $id Order ID + * @param int $id Invoice ID * @param int $idwarehouse Warehouse ID * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @@ -325,7 +325,7 @@ class SupplierInvoices extends DolibarrApi $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); if ($result == 0) { - throw new RestException(304, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. The invoice is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); From 51ab0a5084c512cd6ebac9c35c5a21de79874fea Mon Sep 17 00:00:00 2001 From: Egils Consulting Date: Tue, 4 Aug 2020 22:02:15 +0200 Subject: [PATCH 64/97] Update api_supplier_invoices.class.php fixes #14831 --- htdocs/fourn/class/api_supplier_invoices.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 5ec2b6f49a6..a8a253a902b 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -453,7 +453,7 @@ class SupplierInvoices extends DolibarrApi $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching $paiement->paiementid = $paiementid; - $paiement->paiementcode = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->oper = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); $paiement->num_payment = $num_payment; $paiement->note_public = $comment; From 201c3f87cab88315ac785670b4e43d860a532bea Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 5 Aug 2020 10:40:43 +0200 Subject: [PATCH 65/97] WIP Inventory module --- .../modulebuilder/template/myobject_card.php | 24 ++- htdocs/product/inventory/card.php | 182 +++++++++++++----- 2 files changed, 143 insertions(+), 63 deletions(-) diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 20d6588f3d6..fd17bfe2d6d 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -287,13 +287,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formconfirm = ''; // Confirmation to delete - if ($action == 'delete') - { + if ($action == 'delete') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteMyObject'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); } // Confirmation to delete line - if ($action == 'deleteline') - { + if ($action == 'deleteline') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); } // Clone confirmation @@ -345,19 +343,19 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (! empty($conf->projet->enabled)) { $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; + $morehtmlref .= '
'.$langs->trans('Project') . ' '; if ($permissiontoadd) { //if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' '; - $morehtmlref.=' : '; + $morehtmlref .= ' : '; if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.=''; + //$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= ''; } else { $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); } diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index 9f3afa55738..00401fa590b 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -22,9 +22,11 @@ */ require '../../main.inc.php'; -include_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; -include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; -include_once DOL_DOCUMENT_ROOT.'/product/inventory/lib/inventory.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/inventory/lib/inventory.lib.php'; // Load translation files required by the page $langs->loadLangs(array("stocks", "other")); @@ -49,7 +51,7 @@ if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) $object = new Inventory($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->stock->dir_output.'/temp/massgeneration/'.$user->id; -$hookmanager->initHooks(array('inventorycard')); // Note that conf->hooks_modules contains array +$hookmanager->initHooks(array('inventorycard', 'globalcard')); // Note that conf->hooks_modules contains array // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); @@ -76,11 +78,19 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be includ if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { + $permissiontoread = $user->rights->stock->lire; $permissiontoadd = $user->rights->stock->creer; $permissiontodelete = $user->rights->stock->supprimer; + $permissionnote = $user->rights->stock->creer; // Used by the include of actions_setnotes.inc.php + $permissiondellink = $user->rights->stock->creer; // Used by the include of actions_dellink.inc.php + $upload_dir = $conf->stock->multidir_output[isset($object->entity) ? $object->entity : 1]; } else { + $permissiontoread = $user->rights->stock->inventory_advance->read; $permissiontoadd = $user->rights->stock->inventory_advance->write; $permissiontodelete = $user->rights->stock->inventory_advance->write; + $permissionnote = $user->rights->stock->inventory_advance->write; // Used by the include of actions_setnotes.inc.php + $permissiondellink = $user->rights->stock->inventory_advance->write; // Used by the include of actions_dellink.inc.php + $upload_dir = $conf->stock->multidir_output[isset($object->entity) ? $object->entity : 1]; } @@ -98,7 +108,15 @@ if (empty($reshook)) $backurlforlist = DOL_URL_ROOT.'/product/inventory/list.php'; - // Actions cancel, add, update, delete or clone + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) $backtopage = $backurlforlist; + else $backtopage = dol_buildpath('/product/inventory/card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + } + } + $triggermodname = 'STOCK_INVENTORY_MODIFY'; // Name of trigger action code to execute when we modify record + + // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php'; // Actions when linking object each other @@ -107,11 +125,26 @@ if (empty($reshook)) // Actions when printing a doc from card include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + // Action to move up and down lines of object + //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; + + // Action to build doc + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + + /*if ($action == 'set_thirdparty' && $permissiontoadd) + { + $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, 'MYOBJECT_MODIFY'); + }*/ + if ($action == 'classin' && $permissiontoadd) + { + $object->setProject(GETPOST('projectid', 'int')); + } + // Actions to send emails - /*$triggersendname = 'MYOBJECT_SENTBYMAIL'; - $autocopy='MAIN_MAIL_AUTOCOPY_MYOBJECT_TO'; - $trackid='myobject'.$object->id; - include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';*/ + $triggersendname = 'INVENTORY_SENTBYMAIL'; + $autocopy='MAIN_MAIL_AUTOCOPY_INVENTORY_TO'; + $trackid='stockinv'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; } @@ -122,8 +155,12 @@ if (empty($reshook)) */ $form = new Form($db); +$formfile = new FormFile($db); +$formproject = new FormProjets($db); -llxHeader('', $langs->trans('Inventory'), ''); +$title = $langs->trans("Inventory"); +$help_url = ''; +llxHeader('', $title, $help_url); // Example : Adding jquery code print ''; - print load_fiche_titre($langs->trans("StockCorrection"), '', 'generic'); +print load_fiche_titre($langs->trans("StockCorrection"), '', 'generic'); - print '
'."\n"; +print ''."\n"; - dol_fiche_head(); +dol_fiche_head(); - print ''; - print ''; - print ''; - print '
'; - $invoicestatic->id = $obj->rowid; - $invoicestatic->ref = $obj->ref; print $invoicestatic->getNomUrl(1, 'withdraw'); print ''.price($obj->total_ttc).''; + print price($obj->amount, 1, $langs, 1, -1, -1, $conf->currency).' / '.price($obj->total_ttc, 1, $langs, 1, -1, -1, $conf->currency); + print ''.dol_print_date($db->jdate($obj->date_demande), 'day').'
'; +print ''; +print ''; +print ''; +print '
'; - // Warehouse or product - print ''; - if ($object->element == 'product') - { - print ''; - print ''; - } - if ($object->element == 'stock') - { - print ''; - print ''; - } - print ''; - print ''; - print ''; +// Warehouse or product +print ''; +if ($object->element == 'product') { + print ''; + print ''; +} +if ($object->element == 'stock') { + print ''; + print ''; +} +print ''; +print ''; +print ''; - // Serial / Eat-by date - if (!empty($conf->productbatch->enabled) && - (($object->element == 'product' && $object->hasbatch()) - || ($object->element == 'stock')) - ) - { - print ''; - print 'element == 'stock' ? '' : ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; - print ''; - print ''; - print ''; - print ''; - print ''; - } +// Serial / Eat-by date +if (!empty($conf->productbatch->enabled) && +(($object->element == 'product' && $object->hasbatch()) +|| ($object->element == 'stock')) +) +{ + print ''; + print 'element == 'stock' ? '' : ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; + print ''; + print ''; + print ''; + print ''; + print ''; +} - // Purchase price and project - print ''; - print ''; - print ''; - if (!empty($conf->projet->enabled)) - { - print ''; - print ''; - } - print ''; +// Purchase price and project +print ''; +print ''; +print ''; +if (!empty($conf->projet->enabled)) +{ + print ''; + print ''; +} +print ''; - // Label of mouvement of id of inventory - $valformovementlabel = ((GETPOST("label") && (GETPOST('label') != $langs->trans("MovementCorrectStock", ''))) ? GETPOST("label") : $langs->trans("MovementCorrectStock", $productref)); - print ''; - print ''; - print ''; - print ''; - print ''; +// Label of mouvement of id of inventory +$valformovementlabel = ((GETPOST("label") && (GETPOST('label') != $langs->trans("MovementCorrectStock", ''))) ? GETPOST("label") : $langs->trans("MovementCorrectStock", $productref)); +print ''; +print ''; +print ''; +print ''; +print ''; - print '
'.$langs->trans("Warehouse").''; - print $formproduct->selectWarehouses((GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ?GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))), 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100'); - print '   '; - print ''.$langs->trans("Product").''; - $form->select_produits(GETPOST('product_id', 'int'), 'product_id', (empty($conf->global->STOCK_SUPPORTS_SERVICES) ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); - print '   '; - print ''.$langs->trans("NumberOfUnit").'
'.$langs->trans("Warehouse").''; + print $formproduct->selectWarehouses((GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ?GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))), 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100'); + print '   '; + print ''.$langs->trans("Product").''; + $form->select_produits(GETPOST('product_id', 'int'), 'product_id', (empty($conf->global->STOCK_SUPPORTS_SERVICES) ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); + print '   '; + print ''.$langs->trans("NumberOfUnit").'
'; - print ''; - print '
'.$langs->trans("EatByDate").''; - $eatbyselected = dol_mktime(0, 0, 0, GETPOST('eatbymonth'), GETPOST('eatbyday'), GETPOST('eatbyyear')); - print $form->selectDate($eatbyselected, 'eatby', '', '', 1, ""); - print ''.$langs->trans("SellByDate").''; - $sellbyselected = dol_mktime(0, 0, 0, GETPOST('sellbymonth'), GETPOST('sellbyday'), GETPOST('sellbyyear')); - print $form->selectDate($sellbyselected, 'sellby', '', '', 1, ""); - print '
'; + print ''; + print '
'.$langs->trans("EatByDate").''; + $eatbyselected = dol_mktime(0, 0, 0, GETPOST('eatbymonth'), GETPOST('eatbyday'), GETPOST('eatbyyear')); + print $form->selectDate($eatbyselected, 'eatby', '', '', 1, ""); + print ''.$langs->trans("SellByDate").''; + $sellbyselected = dol_mktime(0, 0, 0, GETPOST('sellbymonth'), GETPOST('sellbyday'), GETPOST('sellbyyear')); + print $form->selectDate($sellbyselected, 'sellby', '', '', 1, ""); + print '
'.$langs->trans("UnitPurchaseValue").''.$langs->trans('Project').''; - $formproject->select_projects(-1, '', 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth300'); - print '
'.$langs->trans("UnitPurchaseValue").''.$langs->trans('Project').''; + $formproject->select_projects(-1, '', 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth300'); + print '
'.$langs->trans("MovementLabel").''; - print ''; - print ''.$langs->trans("InventoryCode").'
'.$langs->trans("MovementLabel").''; +print ''; +print ''.$langs->trans("InventoryCode").'
'; +print ''; - dol_fiche_end(); +dol_fiche_end(); - print '
'; - print ''; - print '     '; - print ''; - print '
'; +print '
'; +print ''; +print '     '; +print ''; +print '
'; - print ''; +print ''; ?> diff --git a/htdocs/product/stock/tpl/stocktransfer.tpl.php b/htdocs/product/stock/tpl/stocktransfer.tpl.php index dffd18e0176..9bea4a65070 100644 --- a/htdocs/product/stock/tpl/stocktransfer.tpl.php +++ b/htdocs/product/stock/tpl/stocktransfer.tpl.php @@ -29,16 +29,16 @@ if (empty($conf) || !is_object($conf)) { element == 'product') $productref = $object->ref; +$productref = ''; +if ($object->element == 'product') $productref = $object->ref; - $langs->load("productbatch"); +$langs->load("productbatch"); - if (empty($id)) $id = $object->id; +if (empty($id)) $id = $object->id; - $pdluoid = GETPOST('pdluoid', 'int'); +$pdluoid = GETPOST('pdluoid', 'int'); - $pdluo = new Productbatch($db); +$pdluo = new Productbatch($db); if ($pdluoid > 0) { @@ -53,49 +53,47 @@ if ($pdluoid > 0) } } - print load_fiche_titre($langs->trans("StockTransfer"), '', 'generic'); +print load_fiche_titre($langs->trans("StockTransfer"), '', 'generic'); - print '
'."\n"; +print ''."\n"; - dol_fiche_head(); +dol_fiche_head(); - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; if ($pdluoid) { print ''; } - print ''; +print '
'; - // Source warehouse or product - print ''; -if ($object->element == 'product') -{ +// Source warehouse or product +print ''; +if ($object->element == 'product') { print ''; print ''; } -if ($object->element == 'stock') -{ +if ($object->element == 'stock') { print ''; print ''; } - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; - // Serial / Eat-by date +// Serial / Eat-by date if (!empty($conf->productbatch->enabled) && - (($object->element == 'product' && $object->hasbatch()) - || ($object->element == 'stock')) - ) +(($object->element == 'product' && $object->hasbatch()) +|| ($object->element == 'stock')) +) { print ''; print 'element == 'stock' ? '' : ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; } - // Label - $valformovementlabel = (GETPOST("label") ?GETPOST("label") : $langs->trans("MovementTransferStock", $productref)); - print ''; - print ''; - print ''; - print ''; - print ''; +// Label +$valformovementlabel = (GETPOST("label") ?GETPOST("label") : $langs->trans("MovementTransferStock", $productref)); +print ''; +print ''; +print ''; +print ''; +print ''; - print '
'.$langs->trans("WarehouseSource").''; print $formproduct->selectWarehouses((GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ?GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))), 'id_entrepot', 'warehouseopen,warehouseinternal', 1); print ''.$langs->trans("Product").''; $form->select_produits(GETPOST('product_id', 'int'), 'product_id', (empty($conf->global->STOCK_SUPPORTS_SERVICES) ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); print ''.$langs->trans("WarehouseTarget").''; - print $formproduct->selectWarehouses(GETPOST('id_entrepot_destination'), 'id_entrepot_destination', 'warehouseopen,warehouseinternal', 1); - print '
'.$langs->trans("NumberOfUnit").'
'.$langs->trans("WarehouseTarget").''; +print $formproduct->selectWarehouses(GETPOST('id_entrepot_destination'), 'id_entrepot_destination', 'warehouseopen,warehouseinternal', 1); +print '
'.$langs->trans("NumberOfUnit").'
'; @@ -122,26 +120,26 @@ if (!empty($conf->productbatch->enabled) && print '
'.$langs->trans("MovementLabel").''; - print ''; - print ''.$langs->trans("InventoryCode").'
'.$langs->trans("MovementLabel").''; +print ''; +print ''.$langs->trans("InventoryCode").'
'; +print ''; - dol_fiche_end(); +dol_fiche_end(); - print '
'; - print ''; - print '     '; - print ''; - print '
'; +print '
'; +print ''; +print '     '; +print ''; +print '
'; - print '
'; +print ''; ?> From 73ea5b0e2d9dda65d3c57e7c273349d58bfc2d8a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 02:48:16 +0200 Subject: [PATCH 76/97] Fix function to convert price to string --- htdocs/core/lib/functionsnumtoword.lib.php | 409 +++++++++++---------- 1 file changed, 213 insertions(+), 196 deletions(-) diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 9f04a81fa5f..c0636673a14 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -13,125 +13,142 @@ * 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 http://www.gnu.org/ + * along with this program. If not, see . + * or see https://www.gnu.org/ */ /** - * \file htdocs/core/lib/functionsnumbertoword.lib.php + * \file htdocs/core/lib/functionsnumtoword.lib.php * \brief A set of functions for Dolibarr * This file contains all frequently used functions. */ /** - * Function to return number in text. + * Function to return a number into a text. + * May use module NUMBERWORDS if found. * - * - * @param float $num Number to convert - * @param Lang $langs Language - * @param boolean $currency 0=number to translate | 1=currency to translate - * @param boolean $centimes 0=no centimes | 1=centimes to translate - * @return string Text of the number + * @param float $num Number to convert (must be a numeric value, like reported by price2num()) + * @param Translate $langs Language + * @param boolean $currency 0=number to translate | 1=currency to translate + * @param boolean $centimes 0=no cents/centimes | 1=there is cents/centimes to translate + * @return string|false Text of the number */ -function dol_convertToWord($num, $langs, $currency=false, $centimes=false) +function dol_convertToWord($num, $langs, $currency = false, $centimes = false) { global $conf; - $num = str_replace(array(',', ' '), '', trim($num)); - if(! $num) { - return false; - } - if($centimes && strlen($num) == 1) { - $num = $num*10; - } - $TNum = explode('.',$num); - $num = (int) $TNum[0]; - $words = array(); - $list1 = array( - '', - $langs->transnoentitiesnoconv('one'), - $langs->transnoentitiesnoconv('two'), - $langs->transnoentitiesnoconv('three'), - $langs->transnoentitiesnoconv('four'), - $langs->transnoentitiesnoconv('five'), - $langs->transnoentitiesnoconv('six'), - $langs->transnoentitiesnoconv('seven'), - $langs->transnoentitiesnoconv('eight'), - $langs->transnoentitiesnoconv('nine'), - $langs->transnoentitiesnoconv('ten'), - $langs->transnoentitiesnoconv('eleven'), - $langs->transnoentitiesnoconv('twelve'), - $langs->transnoentitiesnoconv('thirteen'), - $langs->transnoentitiesnoconv('fourteen'), - $langs->transnoentitiesnoconv('fifteen'), - $langs->transnoentitiesnoconv('sixteen'), - $langs->transnoentitiesnoconv('seventeen'), - $langs->transnoentitiesnoconv('eighteen'), - $langs->transnoentitiesnoconv('nineteen') - ); - $list2 = array( - '', - $langs->transnoentitiesnoconv('ten'), - $langs->transnoentitiesnoconv('twenty'), - $langs->transnoentitiesnoconv('thirty'), - $langs->transnoentitiesnoconv('forty'), - $langs->transnoentitiesnoconv('fifty'), - $langs->transnoentitiesnoconv('sixty'), - $langs->transnoentitiesnoconv('seventy'), - $langs->transnoentitiesnoconv('eighty'), - $langs->transnoentitiesnoconv('ninety'), - $langs->transnoentitiesnoconv('hundred') - ); - $list3 = array( - '', - $langs->transnoentitiesnoconv('thousand'), - $langs->transnoentitiesnoconv('million'), - $langs->transnoentitiesnoconv('billion'), - $langs->transnoentitiesnoconv('trillion'), - $langs->transnoentitiesnoconv('quadrillion') - ); - - $num_length = strlen($num); - $levels = (int) (($num_length + 2) / 3); - $max_length = $levels * 3; - $num = substr('00' . $num, -$max_length); - $num_levels = str_split($num, 3); - $nboflevels = count($num_levels); - for ($i = 0; $i < $nboflevels; $i++) { - $levels--; - $hundreds = (int) ($num_levels[$i] / 100); - $hundreds = ($hundreds ? ' ' . $list1[$hundreds] . ' '.$langs->transnoentities('hundred') . ( $hundreds == 1 ? '' : 's' ) . ' ': ''); - $tens = (int) ($num_levels[$i] % 100); - $singles = ''; - if ( $tens < 20 ) { - $tens = ($tens ? ' ' . $list1[$tens] . ' ' : '' ); - } else { - $tens = (int) ($tens / 10); - $tens = ' ' . $list2[$tens] . ' '; - $singles = (int) ($num_levels[$i] % 10); - $singles = ' ' . $list1[$singles] . ' '; - } - $words[] = $hundreds . $tens . $singles . ( ( $levels && ( int ) ( $num_levels[$i] ) ) ? ' ' . $list3[$levels] . ' ' : '' ); - } //end for loop - $commas = count($words); - if ($commas > 1) { - $commas = $commas - 1; - } - $concatWords = implode(' ', $words); - // Delete multi whitespaces - $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords)); - - if(!empty($currency)) { - $concatWords .= ' '.$currency; + //$num = str_replace(array(',', ' '), '', trim($num)); This should be useless since $num MUST be a php numeric value + if (!$num) { + return false; } - // If we need to write cents call again this function for cents - if(!empty($TNum[1])) { - if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and'); - $concatWords .= ' '.dol_convertToWord($TNum[1], $langs, $currency, true); - if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes'); + if ($centimes && strlen($num) == 1) { + $num = $num * 10; + } + + if (!empty($conf->global->MAIN_MODULE_NUMBERWORDS)) { + if ($currency) { + $type = 1; + } else { + $type = 0; + } + + $concatWords = $langs->getLabelFromNumber($num, $type); + return $concatWords; + } else { + $TNum = explode('.', $num); + $num = (int) $TNum[0]; + $words = array(); + $list1 = array( + '', + $langs->transnoentitiesnoconv('one'), + $langs->transnoentitiesnoconv('two'), + $langs->transnoentitiesnoconv('three'), + $langs->transnoentitiesnoconv('four'), + $langs->transnoentitiesnoconv('five'), + $langs->transnoentitiesnoconv('six'), + $langs->transnoentitiesnoconv('seven'), + $langs->transnoentitiesnoconv('eight'), + $langs->transnoentitiesnoconv('nine'), + $langs->transnoentitiesnoconv('ten'), + $langs->transnoentitiesnoconv('eleven'), + $langs->transnoentitiesnoconv('twelve'), + $langs->transnoentitiesnoconv('thirteen'), + $langs->transnoentitiesnoconv('fourteen'), + $langs->transnoentitiesnoconv('fifteen'), + $langs->transnoentitiesnoconv('sixteen'), + $langs->transnoentitiesnoconv('seventeen'), + $langs->transnoentitiesnoconv('eighteen'), + $langs->transnoentitiesnoconv('nineteen') + ); + $list2 = array( + '', + $langs->transnoentitiesnoconv('ten'), + $langs->transnoentitiesnoconv('twenty'), + $langs->transnoentitiesnoconv('thirty'), + $langs->transnoentitiesnoconv('forty'), + $langs->transnoentitiesnoconv('fifty'), + $langs->transnoentitiesnoconv('sixty'), + $langs->transnoentitiesnoconv('seventy'), + $langs->transnoentitiesnoconv('eighty'), + $langs->transnoentitiesnoconv('ninety'), + $langs->transnoentitiesnoconv('hundred') + ); + $list3 = array( + '', + $langs->transnoentitiesnoconv('thousand'), + $langs->transnoentitiesnoconv('million'), + $langs->transnoentitiesnoconv('billion'), + $langs->transnoentitiesnoconv('trillion'), + $langs->transnoentitiesnoconv('quadrillion') + ); + + $num_length = strlen($num); + $levels = (int) (($num_length + 2) / 3); + $max_length = $levels * 3; + $num = substr('00'.$num, -$max_length); + $num_levels = str_split($num, 3); + $nboflevels = count($num_levels); + for ($i = 0; $i < $nboflevels; $i++) { + $levels--; + $hundreds = (int) ($num_levels[$i] / 100); + $hundreds = ($hundreds ? ' '.$list1[$hundreds].' '.$langs->transnoentities('hundred').($hundreds == 1 ? '' : 's').' ' : ''); + $tens = (int) ($num_levels[$i] % 100); + $singles = ''; + if ($tens < 20) { + $tens = ($tens ? ' '.$list1[$tens].' ' : ''); + } else { + $tens = (int) ($tens / 10); + $tens = ' '.$list2[$tens].' '; + $singles = (int) ($num_levels[$i] % 10); + $singles = ' '.$list1[$singles].' '; + } + $words[] = $hundreds.$tens.$singles.(($levels && (int) ($num_levels[$i])) ? ' '.$list3[$levels].' ' : ''); + } //end for loop + $commas = count($words); + if ($commas > 1) { + $commas = $commas - 1; + } + $concatWords = implode(' ', $words); + // Delete multi whitespaces + $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords)); + + if (!empty($currency)) { + $concatWords .= ' '.$currency; + } + + // If we need to write cents call again this function for cents + $decimalpart = $TNum[1]; + $decimalpart = preg_replace('/0+$/', '', $decimalpart); + + if ($decimalpart) { + if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and'); + + $concatWords .= ' '.dol_convertToWord($decimalpart, $langs, '', true); + if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes'); + } + return $concatWords; } - return $concatWords; } @@ -139,92 +156,92 @@ function dol_convertToWord($num, $langs, $currency=false, $centimes=false) * Function to return number or amount in text. * * @deprecated - * @param float $numero Number to convert - * @param Lang $langs Language - * @param string $numorcurrency 'number' or 'amount' - * @return string Text of the number or -1 in case TOO LONG (more than 1000000000000.99) + * @param float $numero Number to convert + * @param Translate $langs Language + * @param string $numorcurrency 'number' or 'amount' + * @return string Text of the number or -1 in case TOO LONG (more than 1000000000000.99) */ -function dolNumberToWord($numero, $langs, $numorcurrency='number') +function dolNumberToWord($numero, $langs, $numorcurrency = 'number') { // If the number is negative convert to positive and return -1 if is too long if ($numero < 0) $numero *= -1; if ($numero >= 1000000000001) return -1; - // Get 2 decimals to cents, another functions round or truncate - $strnumber = number_format ($numero,10); - $len=strlen($strnumber); - for ($i=0; $i<$len; $i++) - { - if ($strnumber[$i]=='.') { - $parte_decimal = $strnumber[$i+1].$strnumber[$i+2]; - break; + // Get 2 decimals to cents, another functions round or truncate + $strnumber = number_format($numero, 10); + $len = strlen($strnumber); + for ($i = 0; $i < $len; $i++) + { + if ($strnumber[$i] == '.') { + $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2]; + break; + } } - } - /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and - in case exist why ask $lang like a parameter?*/ - if (((is_object($langs) && $langs->default == 'es_MX') || (! is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') - { - if ($numero>=1 && $numero<2) { - return ("UN PESO ".$parte_decimal." / 100 M.N."); - } - elseif ($numero>=0 && $numero<1){ - return ("CERO PESOS ".$parte_decimal." / 100 M.N."); - } - elseif ($numero>=1000000 && $numero<1000001){ - return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); - } - elseif ($numero>=1000000000000 && $numero<1000000000001){ - return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); - } - else { - $entexto =""; - $number = $numero; - if ($number >= 1000000000){ - $CdMMillon = (int) ($numero / 100000000000); - $numero = $numero - $CdMMillon * 100000000000; - $DdMMillon = (int) ($numero / 10000000000); - $numero = $numero - $DdMMillon * 10000000000; - $UdMMillon = (int) ($numero / 1000000000); - $numero = $numero - $UdMMillon * 1000000000; - $entexto .= hundreds2text ($CdMMillon, $DdMMillon, $UdMMillon); - $entexto .= " MIL "; + /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and + in case exist why ask $lang like a parameter?*/ + if (((is_object($langs) && $langs->default == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') + { + if ($numero >= 1 && $numero < 2) { + return ("UN PESO ".$parte_decimal." / 100 M.N."); } - if ($number >= 1000000){ - $CdMILLON = (int) ($numero / 100000000); - $numero = $numero - $CdMILLON * 100000000; - $DdMILLON = (int) ($numero / 10000000); - $numero = $numero - $DdMILLON * 10000000; - $udMILLON = (int) ($numero / 1000000); - $numero = $numero - $udMILLON * 1000000; - $entexto .= hundreds2text ($CdMILLON, $DdMILLON, $udMILLON); - if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON==1) - $entexto .= " MILLÓN "; - else - $entexto .= " MILLONES "; + elseif ($numero >= 0 && $numero < 1) { + return ("CERO PESOS ".$parte_decimal." / 100 M.N."); } - if ($number >= 1000) { - $cdm = (int) ($numero / 100000); - $numero = $numero - $cdm * 100000; - $ddm = (int) ($numero / 10000); - $numero = $numero - $ddm * 10000; - $udm = (int) ($numero / 1000); - $numero = $numero - $udm * 1000; - $entexto .= hundreds2text ($cdm, $ddm, $udm); - if ($cdm || $ddm || $udm) + elseif ($numero >= 1000000 && $numero < 1000001) { + return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); + } + elseif ($numero >= 1000000000000 && $numero < 1000000000001) { + return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); + } + else { + $entexto = ""; + $number = $numero; + if ($number >= 1000000000) { + $CdMMillon = (int) ($numero / 100000000000); + $numero = $numero - $CdMMillon * 100000000000; + $DdMMillon = (int) ($numero / 10000000000); + $numero = $numero - $DdMMillon * 10000000000; + $UdMMillon = (int) ($numero / 1000000000); + $numero = $numero - $UdMMillon * 1000000000; + $entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon); $entexto .= " MIL "; + } + if ($number >= 1000000) { + $CdMILLON = (int) ($numero / 100000000); + $numero = $numero - $CdMILLON * 100000000; + $DdMILLON = (int) ($numero / 10000000); + $numero = $numero - $DdMILLON * 10000000; + $udMILLON = (int) ($numero / 1000000); + $numero = $numero - $udMILLON * 1000000; + $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON); + if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) + $entexto .= " MILLÓN "; + else + $entexto .= " MILLONES "; + } + if ($number >= 1000) { + $cdm = (int) ($numero / 100000); + $numero = $numero - $cdm * 100000; + $ddm = (int) ($numero / 10000); + $numero = $numero - $ddm * 10000; + $udm = (int) ($numero / 1000); + $numero = $numero - $udm * 1000; + $entexto .= hundreds2text($cdm, $ddm, $udm); + if ($cdm || $ddm || $udm) + $entexto .= " MIL "; + } + $c = (int) ($numero / 100); + $numero = $numero - $c * 100; + $d = (int) ($numero / 10); + $u = (int) $numero - $d * 10; + $entexto .= hundreds2text($c, $d, $u); + if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) + $entexto .= " DE"; + $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; } - $c = (int) ($numero / 100); - $numero = $numero - $c * 100; - $d = (int) ($numero / 10); - $u = (int) $numero - $d * 10; - $entexto .= hundreds2text ($c, $d, $u); - if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number>1000000) - $entexto .= " DE"; - $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; + return $entexto; } - return $entexto; - } } /** @@ -237,40 +254,40 @@ function dolNumberToWord($numero, $langs, $numorcurrency='number') */ function hundreds2text($hundreds, $tens, $units) { - if ($hundreds==1 && $tens==0 && $units==0){ + if ($hundreds == 1 && $tens == 0 && $units == 0) { return "CIEN"; } - $centenas = array("CIENTO","DOSCIENTOS","TRESCIENTOS","CUATROCIENTOS","QUINIENTOS","SEISCIENTOS","SETECIENTOS","OCHOCIENTOS","NOVECIENTOS"); - $decenas = array("","","TREINTA ","CUARENTA ","CINCUENTA ","SESENTA ","SETENTA ","OCHENTA ","NOVENTA "); - $veintis = array("VEINTE","VEINTIUN","VEINTIDÓS","VEINTITRÉS","VEINTICUATRO","VEINTICINCO","VEINTISÉIS","VEINTISIETE","VEINTIOCHO","VEINTINUEVE"); - $diecis = array("DIEZ","ONCE","DOCE","TRECE","CATORCE","QUINCE","DIECISÉIS","DIECISIETE","DIECIOCHO","DIECINUEVE"); - $unidades = array("UN","DOS","TRES","CUATRO","CINCO","SEIS","SIETE","OCHO","NUEVE"); + $centenas = array("CIENTO", "DOSCIENTOS", "TRESCIENTOS", "CUATROCIENTOS", "QUINIENTOS", "SEISCIENTOS", "SETECIENTOS", "OCHOCIENTOS", "NOVECIENTOS"); + $decenas = array("", "", "TREINTA ", "CUARENTA ", "CINCUENTA ", "SESENTA ", "SETENTA ", "OCHENTA ", "NOVENTA "); + $veintis = array("VEINTE", "VEINTIUN", "VEINTIDÓS", "VEINTITRÉS", "VEINTICUATRO", "VEINTICINCO", "VEINTISÉIS", "VEINTISIETE", "VEINTIOCHO", "VEINTINUEVE"); + $diecis = array("DIEZ", "ONCE", "DOCE", "TRECE", "CATORCE", "QUINCE", "DIECISÉIS", "DIECISIETE", "DIECIOCHO", "DIECINUEVE"); + $unidades = array("UN", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE"); $entexto = ""; - if ($hundreds!=0){ - $entexto .= $centenas[$hundreds-1]; + if ($hundreds != 0) { + $entexto .= $centenas[$hundreds - 1]; } - if ($tens>2){ - if ($hundreds!=0) $entexto .= " "; - $entexto .= $decenas[$tens-1]; - if ($units!=0){ + if ($tens > 2) { + if ($hundreds != 0) $entexto .= " "; + $entexto .= $decenas[$tens - 1]; + if ($units != 0) { $entexto .= " Y "; - $entexto .= $unidades[$units-1]; + $entexto .= $unidades[$units - 1]; } return $entexto; } - elseif ($tens==2){ - if ($hundreds!=0) $entexto .= " "; + elseif ($tens == 2) { + if ($hundreds != 0) $entexto .= " "; $entexto .= " ".$veintis[$units]; return $entexto; } - elseif ($tens==1){ - if ($hundreds!=0) $entexto .= " "; + elseif ($tens == 1) { + if ($hundreds != 0) $entexto .= " "; $entexto .= $diecis[$units]; return $entexto; } - if ($units!=0) { - if ($hundreds!=0 || $tens!=0) $entexto .= " "; - $entexto .= $unidades[$units-1]; + if ($units != 0) { + if ($hundreds != 0 || $tens != 0) $entexto .= " "; + $entexto .= $unidades[$units - 1]; } return $entexto; } From 641d9a656548ce601bb42e4d11739f8421cd0b59 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 02:58:07 +0200 Subject: [PATCH 77/97] Fix number to string --- htdocs/core/lib/functionsnumtoword.lib.php | 141 +++++++++++---------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 77a2e6d32b6..6479612de1a 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -163,86 +163,87 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false) */ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') { - // If the number is negative convert to positive and return -1 if is too long + // If the number is negative convert to positive and return -1 if it is too long if ($numero < 0) $numero *= -1; - if ($numero >= 1000000000001) + if ($numero >= 1000000000001) { return -1; + } - // Get 2 decimals to cents, another functions round or truncate - $strnumber = number_format($numero, 10); - $len = strlen($strnumber); - for ($i = 0; $i < $len; $i++) - { - if ($strnumber[$i] == '.') { - $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2]; - break; - } + // Get 2 decimals to cents, another functions round or truncate + $strnumber = number_format($numero, 10); + $len = strlen($strnumber); + for ($i = 0; $i < $len; $i++) + { + if ($strnumber[$i] == '.') { + $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2]; + break; } + } - /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and - in case exist why ask $lang like a parameter?*/ - if (((is_object($langs) && $langs->default == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') - { - if ($numero >= 1 && $numero < 2) { - return ("UN PESO ".$parte_decimal." / 100 M.N."); + /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and + in case exist why ask $lang like a parameter?*/ + if (((is_object($langs) && $langs->default == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') + { + if ($numero >= 1 && $numero < 2) { + return ("UN PESO ".$parte_decimal." / 100 M.N."); + } + elseif ($numero >= 0 && $numero < 1) { + return ("CERO PESOS ".$parte_decimal." / 100 M.N."); + } + elseif ($numero >= 1000000 && $numero < 1000001) { + return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); + } + elseif ($numero >= 1000000000000 && $numero < 1000000000001) { + return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); + } + else { + $entexto = ""; + $number = $numero; + if ($number >= 1000000000) { + $CdMMillon = (int) ($numero / 100000000000); + $numero = $numero - $CdMMillon * 100000000000; + $DdMMillon = (int) ($numero / 10000000000); + $numero = $numero - $DdMMillon * 10000000000; + $UdMMillon = (int) ($numero / 1000000000); + $numero = $numero - $UdMMillon * 1000000000; + $entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon); + $entexto .= " MIL "; } - elseif ($numero >= 0 && $numero < 1) { - return ("CERO PESOS ".$parte_decimal." / 100 M.N."); + if ($number >= 1000000) { + $CdMILLON = (int) ($numero / 100000000); + $numero = $numero - $CdMILLON * 100000000; + $DdMILLON = (int) ($numero / 10000000); + $numero = $numero - $DdMILLON * 10000000; + $udMILLON = (int) ($numero / 1000000); + $numero = $numero - $udMILLON * 1000000; + $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON); + if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) + $entexto .= " MILLÓN "; + else + $entexto .= " MILLONES "; } - elseif ($numero >= 1000000 && $numero < 1000001) { - return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); - } - elseif ($numero >= 1000000000000 && $numero < 1000000000001) { - return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); - } - else { - $entexto = ""; - $number = $numero; - if ($number >= 1000000000) { - $CdMMillon = (int) ($numero / 100000000000); - $numero = $numero - $CdMMillon * 100000000000; - $DdMMillon = (int) ($numero / 10000000000); - $numero = $numero - $DdMMillon * 10000000000; - $UdMMillon = (int) ($numero / 1000000000); - $numero = $numero - $UdMMillon * 1000000000; - $entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon); + if ($number >= 1000) { + $cdm = (int) ($numero / 100000); + $numero = $numero - $cdm * 100000; + $ddm = (int) ($numero / 10000); + $numero = $numero - $ddm * 10000; + $udm = (int) ($numero / 1000); + $numero = $numero - $udm * 1000; + $entexto .= hundreds2text($cdm, $ddm, $udm); + if ($cdm || $ddm || $udm) $entexto .= " MIL "; - } - if ($number >= 1000000) { - $CdMILLON = (int) ($numero / 100000000); - $numero = $numero - $CdMILLON * 100000000; - $DdMILLON = (int) ($numero / 10000000); - $numero = $numero - $DdMILLON * 10000000; - $udMILLON = (int) ($numero / 1000000); - $numero = $numero - $udMILLON * 1000000; - $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON); - if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) - $entexto .= " MILLÓN "; - else - $entexto .= " MILLONES "; - } - if ($number >= 1000) { - $cdm = (int) ($numero / 100000); - $numero = $numero - $cdm * 100000; - $ddm = (int) ($numero / 10000); - $numero = $numero - $ddm * 10000; - $udm = (int) ($numero / 1000); - $numero = $numero - $udm * 1000; - $entexto .= hundreds2text($cdm, $ddm, $udm); - if ($cdm || $ddm || $udm) - $entexto .= " MIL "; - } - $c = (int) ($numero / 100); - $numero = $numero - $c * 100; - $d = (int) ($numero / 10); - $u = (int) $numero - $d * 10; - $entexto .= hundreds2text($c, $d, $u); - if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) - $entexto .= " DE"; - $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; } - return $entexto; + $c = (int) ($numero / 100); + $numero = $numero - $c * 100; + $d = (int) ($numero / 10); + $u = (int) $numero - $d * 10; + $entexto .= hundreds2text($c, $d, $u); + if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) + $entexto .= " DE"; + $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; } + return $entexto; + } } /** From 01babc452ca7c711ad53b0c40e76afcaaf9bb8b2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 03:52:49 +0200 Subject: [PATCH 78/97] More logs --- htdocs/takepos/index.php | 4 ++-- htdocs/takepos/invoice.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index af9c3062ba3..d3fc6b7416a 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -632,7 +632,7 @@ function TakeposPrintingTemp(){ } function OpenDrawer(){ - console.log("OpenDrawer"); + console.log("OpenDrawer call ajax url http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print"); $.ajax({ type: "POST", url: 'http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print', @@ -641,7 +641,7 @@ function OpenDrawer(){ } function DolibarrOpenDrawer() { - console.log("DolibarrOpenDrawer"); + console.log("DolibarrOpenDrawer call ajax url /takepos/ajax/ajax.php?action=opendrawer&term="); $.ajax({ type: "GET", url: "", diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index af4d5aeaf19..a3ef12c92cb 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -717,6 +717,7 @@ function TakeposPrinting(id){ } function TakeposConnector(id){ + console.log("TakeposConnector" + id); var invoice='" + id, From 37f1b27bd29370240f55e29bec260438307d60cc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 03:55:47 +0200 Subject: [PATCH 79/97] Fix phpcs --- htdocs/core/lib/functionsnumtoword.lib.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 6479612de1a..74b585e8b50 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -219,8 +219,8 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON); if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) $entexto .= " MILLÓN "; - else - $entexto .= " MILLONES "; + else + $entexto .= " MILLONES "; } if ($number >= 1000) { $cdm = (int) ($numero / 100000); @@ -240,7 +240,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') $entexto .= hundreds2text($c, $d, $u); if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) $entexto .= " DE"; - $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; + $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; } return $entexto; } From 25c37d9bca4d467e12615ea6035a5ddb16bbbd17 Mon Sep 17 00:00:00 2001 From: "jove@bisquerra.com" Date: Thu, 6 Aug 2020 07:32:28 +0200 Subject: [PATCH 80/97] FIX: Get some taxes in TakePOS --- htdocs/takepos/invoice.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index aee36f9ddfc..7e771a8d4b7 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -348,6 +348,7 @@ if ($action == "addline") } } if ($idoflineadded <= 0) { + $invoice->fetch_thirdparty(); $idoflineadded = $invoice->addline($prod->description, $price, 1, $tva_tx, $localtax1_tx, $localtax2_tx, $idproduct, $customer->remise_percent, '', 0, 0, 0, '', $price_base_type, $price_ttc, $prod->type, -1, 0, '', 0, $parent_line, null, '', '', 0, 100, '', null, 0); } From da59bb811f6bad41a2c9eff3862884e25ecaa0ce Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 12:29:57 +0200 Subject: [PATCH 81/97] Fix backtopage after creating a bookmark --- htdocs/bookmarks/card.php | 1 + htdocs/bookmarks/list.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 385dd506031..411c2c8175f 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -151,6 +151,7 @@ if ($action == 'create') print '
'."\n"; print ''; print ''; + print ''; print load_fiche_titre($langs->trans("NewBookmark")); diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php index 5dd1718b263..1cc6029dbc9 100644 --- a/htdocs/bookmarks/list.php +++ b/htdocs/bookmarks/list.php @@ -158,7 +158,7 @@ print ''; print ''; $newcardbutton = ''; -$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create', '', !empty($user->rights->bookmark->creer)); +$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create&backtopage='.urlencode(DOL_URL_ROOT.'/bookmarks/list.php'), '', !empty($user->rights->bookmark->creer)); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bookmark', 0, $newcardbutton, '', $limit, 0, 0, 1); From e830e7f3d36a6a7000a75122bc5862b212c7eb29 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 13:14:43 +0200 Subject: [PATCH 82/97] Work on recruitment module --- .../install/mysql/migration/12.0.0-13.0.0.sql | 4 + ...llx_recruitment_recruitmentjobposition.sql | 6 +- htdocs/langs/en_US/boxes.lang | 1 + .../modulebuilder/template/mymoduleindex.php | 60 +++---- .../class/recruitmentjobposition.class.php | 9 +- htdocs/recruitment/recruitmentindex.php | 146 +++++++++++++----- .../recruitmentjobposition_card.php | 7 +- 7 files changed, 150 insertions(+), 83 deletions(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index e6797717711..58d85e80526 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -81,6 +81,7 @@ ALTER TABLE llx_c_incoterms ADD COLUMN label varchar(100) NULL; CREATE TABLE llx_recruitment_recruitmentjobposition( rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, ref varchar(128) DEFAULT '(PROV)' NOT NULL, + entity INTEGER DEFAULT 1 NOT NULL, label varchar(255) NOT NULL, qty integer DEFAULT 1 NOT NULL, fk_soc integer, @@ -89,6 +90,7 @@ CREATE TABLE llx_recruitment_recruitmentjobposition( fk_user_supervisor integer, fk_establishment integer, date_planned date, + remuneration_suggested varchar(255), description text, note_public text, note_private text, @@ -113,6 +115,8 @@ ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitmen ALTER TABLE llx_recruitment_recruitmentjobposition ADD INDEX idx_recruitment_recruitmentjobposition_status (status); ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN email_recruiter varchar(255); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN entity INTEGER DEFAULT 1 NOT NULL; +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN remuneration_suggested varchar(255); create table llx_recruitment_recruitmentjobposition_extrafields ( diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql index 88ad12acef1..b342156ccd1 100644 --- a/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql @@ -17,7 +17,8 @@ CREATE TABLE llx_recruitment_recruitmentjobposition( -- BEGIN MODULEBUILDER FIELDS rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, - ref varchar(128) DEFAULT '(PROV)' NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + entity INTEGER DEFAULT 1 NOT NULL, label varchar(255) NOT NULL, qty integer DEFAULT 1 NOT NULL, fk_soc integer, @@ -26,7 +27,8 @@ CREATE TABLE llx_recruitment_recruitmentjobposition( email_recruiter varchar(255), fk_user_supervisor integer, fk_establishment integer, - date_planned date, + date_planned date, + remuneration_suggested varchar(255), description text, note_public text, note_private text, diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang index bd62684421a..69025458630 100644 --- a/htdocs/langs/en_US/boxes.lang +++ b/htdocs/langs/en_US/boxes.lang @@ -83,6 +83,7 @@ BoxTitleLatestModifiedSupplierOrders=Vendor Orders: last %s modified BoxTitleLastModifiedCustomerBills=Customer Invoices: last %s modified BoxTitleLastModifiedCustomerOrders=Sales Orders: last %s modified BoxTitleLastModifiedPropals=Latest %s modified proposals +BoxTitleLatestModifiedJobPositions=Latest %s modified jobs ForCustomersInvoices=Customers invoices ForCustomersOrders=Customers orders ForProposals=Proposals diff --git a/htdocs/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php index 4a3356f1d7e..9050b5319e0 100644 --- a/htdocs/modulebuilder/template/mymoduleindex.php +++ b/htdocs/modulebuilder/template/mymoduleindex.php @@ -106,7 +106,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print ''; print ''; - print ''; + print ''; $var = true; if ($num > 0) @@ -117,22 +117,17 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) $obj = $db->fetch_object($resql); print ''; print ''; print ''; $i++; @@ -171,14 +166,12 @@ $max = 3; // Last modified myobject if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) { - $sql = "SELECT s.rowid, s.nom as name, s.client, s.datec, s.tms, s.canvas"; - $sql.= ", s.code_client"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE s.client IN (1, 2, 3)"; - $sql.= " AND s.entity IN (".getEntity($companystatic->element).")"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND s.rowid = $socid"; + $sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms"; + $sql.= " FROM ".MAIN_DB_PREFIX."mymodule_myobject as s"; + //if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE s.entity IN (".getEntity($myobjectstatic->element).")"; + //if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + //if ($socid) $sql.= " AND s.rowid = $socid"; $sql .= " ORDER BY s.tms DESC"; $sql .= $db->plimit($max, 0); @@ -191,9 +184,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print '
'.$langs->trans("DraftOrders").($num?''.$num.'':'').'
'.$langs->trans("DraftMyObjects").($num?''.$num.'':'').'
'; - $orderstatic->id=$obj->rowid; - $orderstatic->ref=$obj->ref; - $orderstatic->ref_client=$obj->ref_client; - $orderstatic->total_ht = $obj->total_ht; - $orderstatic->total_tva = $obj->total_tva; - $orderstatic->total_ttc = $obj->total_ttc; - print $orderstatic->getNomUrl(1); + + $myobjectstatic->id=$obj->rowid; + $myobjectstatic->ref=$obj->ref; + $myobjectstatic->ref_client=$obj->ref_client; + $myobjectstatic->total_ht = $obj->total_ht; + $myobjectstatic->total_tva = $obj->total_tva; + $myobjectstatic->total_ttc = $obj->total_ttc; + + print $myobjectstatic->getNomUrl(1); print ''; - $companystatic->id=$obj->socid; - $companystatic->name=$obj->name; - $companystatic->client=$obj->client; - $companystatic->code_client = $obj->code_client; - $companystatic->code_fournisseur = $obj->code_fournisseur; - $companystatic->canvas=$obj->canvas; - print $companystatic->getNomUrl(1,'customer',16); print ''.price($obj->total_ttc).'
'; print ''; print ''; print ''; print ''; @@ -202,22 +193,19 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) while ($i < $num) { $objp = $db->fetch_object($resql); - $companystatic->id=$objp->rowid; - $companystatic->name=$objp->name; - $companystatic->client=$objp->client; - $companystatic->code_client = $objp->code_client; - $companystatic->code_fournisseur = $objp->code_fournisseur; - $companystatic->canvas=$objp->canvas; + + $myobjectstatic->id=$objp->rowid; + $myobjectstatic->ref=$objp->ref; + $myobjectstatic->label=$objp->label; + $myobjectstatic->status = $objp->status; + print ''; - print ''; + print ''; print '"; print '"; print ''; $i++; - - } $db->free($resql); diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 048c0d4ee3a..c1ad8c3346d 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -96,15 +96,17 @@ class RecruitmentJobPosition extends CommonObject public $fields=array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'position'=>5, 'notnull'=>1, 'default'=>'1', 'index'=>1), 'label' => array('type'=>'varchar(255)', 'label'=>'JobLabel', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth500', 'showoncombobox'=>'1', 'autofocusoncreate'=>1), 'qty' => array('type'=>'integer', 'label'=>'NbOfEmployeesExpected', 'enabled'=>'1', 'position'=>45, 'notnull'=>1, 'visible'=>1, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp',), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'1', 'position'=>52, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,), - 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>-1, 'foreignkey'=>'user.rowid',), + 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>1, 'foreignkey'=>'user.rowid',), 'email_recruiter' => array('type'=>'varchar(255)', 'label'=>'EmailRecruiter', 'enabled'=>'1', 'position'=>54, 'notnull'=>0, 'visible'=>-1, 'help'=>'ToUseAGenericEmail'), 'fk_user_supervisor' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'FutureManager', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid',), 'fk_establishment' => array('type'=>'integer:Establishment:hrm/class/establishment.class.php', 'label'=>'Establishment', 'enabled'=>'$conf->hrm->enabled', 'position'=>56, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'establishment.rowid',), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'WorkPlace', 'enabled'=>'1', 'position'=>57, 'notnull'=>-1, 'visible'=>-1, 'index'=>1, 'help'=>"IfJobIsLocatedAtAPartner",), 'date_planned' => array('type'=>'date', 'label'=>'DateExpected', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>1,), + 'remuneration_suggested' => array('type'=>'varchar(255)', 'label'=>'Remuneration', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>1,), 'description' => array('type'=>'html', 'label'=>'Description', 'enabled'=>'1', 'position'=>65, 'notnull'=>0, 'visible'=>3,), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>101, 'notnull'=>0, 'visible'=>0,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>102, 'notnull'=>0, 'visible'=>0,), @@ -119,6 +121,7 @@ class RecruitmentJobPosition extends CommonObject ); public $rowid; public $ref; + public $entity; public $label; public $qty; public $fk_soc; @@ -801,11 +804,11 @@ class RecruitmentJobPosition extends CommonObject $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated'); $this->labelStatus[self::STATUS_RECRUITED] = $langs->trans('Recruited'); - $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Canceled'); $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated'); $this->labelStatusShort[self::STATUS_RECRUITED] = $langs->trans('Recruited'); - $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Canceled'); } $statusType = 'status'.$status; diff --git a/htdocs/recruitment/recruitmentindex.php b/htdocs/recruitment/recruitmentindex.php index 71a4cedcc69..dc0b0eac8cf 100644 --- a/htdocs/recruitment/recruitmentindex.php +++ b/htdocs/recruitment/recruitmentindex.php @@ -24,25 +24,12 @@ * \brief Home page of recruitment top menu */ -// Load Dolibarr environment -$res = 0; -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) -if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; -// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME -$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; -while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } -if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; -if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; -// Try main.inc.php using relative path -if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php"; -if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php"; -if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php"; -if (!$res) die("Include of main fails"); - +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page -$langs->loadLangs(array("recruitment")); +$langs->loadLangs(array("recruitment", "boxes")); $action = GETPOST('action', 'alpha'); @@ -73,6 +60,7 @@ $now = dol_now(); $form = new Form($db); $formfile = new FormFile($db); +$staticrecruitmentjobposition = new RecruitmentJobPosition($db); llxHeader("", $langs->trans("RecruitmentArea")); @@ -81,6 +69,91 @@ print load_fiche_titre($langs->trans("RecruitmentArea"), '', 'object_recruitment print '
'; +/* + * Statistics + */ + +if ($conf->use_javascript_ajax) +{ + $sql = "SELECT COUNT(t.rowid) as nb, status"; + $sql .= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as t"; + $sql .= " GROUP BY t.status"; + $sql .= " ORDER BY t.status ASC"; + $resql = $db->query($sql); + + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + $totalnb = 0; + $dataseries = array(); + $colorseries = array(); + $vals = array(); + + include_once DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php'; + + while ($i < $num) + { + $obj = $db->fetch_object($resql); + if ($obj) + { + $vals[$obj->status] = $obj->nb; + + $totalnb += $obj->nb; + } + $i++; + } + $db->free($resql); + + print '
'; + print '
'; - if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastCustomersOrProspects",$max); - else if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastModifiedProspects",$max); - else print $langs->trans("BoxTitleLastModifiedCustomers",$max); + print $langs->trans("BoxTitleLatestModifiedMyObjects",$max); print ''.$langs->trans("DateModificationShort").'
'.$companystatic->getNomUrl(1,'customer',48).''.$myobjectstatic->getNomUrl(1).''; - print $companystatic->getLibCustProspStatut(); print "'.dol_print_date($db->jdate($objp->tms),'day')."
'; + print ''."\n"; + $listofstatus = array(0, 1, 3, 9); + foreach ($listofstatus as $status) + { + $dataseries[] = array($staticrecruitmentjobposition->LibStatut($status, 1), (isset($vals[$status]) ? (int) $vals[$status] : 0)); + if ($status == RecruitmentJobPosition::STATUS_DRAFT) $colorseries[$status] = '-'.$badgeStatus0; + if ($status == RecruitmentJobPosition::STATUS_VALIDATED) $colorseries[$status] = $badgeStatus1; + if ($status == RecruitmentJobPosition::STATUS_RECRUITED) $colorseries[$status] = $badgeStatus4; + if ($status == RecruitmentJobPosition::STATUS_CANCELED) $colorseries[$status] = $badgeStatus9; + + if (empty($conf->use_javascript_ajax)) + { + print ''; + print ''; + print ''; + print "\n"; + } + } + if ($conf->use_javascript_ajax) + { + print ''; + } + print "
'.$langs->trans("Statistics").' - '.$langs->trans("Recruitment").'
'.$staticrecruitmentjobposition->LibStatut($status, 0).''.(isset($vals[$status]) ? $vals[$status] : 0).'
'; + + include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + $dolgraph = new DolGraph(); + $dolgraph->SetData($dataseries); + $dolgraph->SetDataColor(array_values($colorseries)); + $dolgraph->setShowLegend(2); + $dolgraph->setShowPercent(1); + $dolgraph->SetType(array('pie')); + $dolgraph->SetHeight('200'); + $dolgraph->draw('idgraphstatus'); + print $dolgraph->show($totalnb ? 0 : 1); + + print '
"; + print "
"; + + print "
"; + } else { + dol_print_error($db); + } +} + +print '
'; + /* BEGIN MODULEBUILDER DRAFT MYOBJECT // Draft MyObject if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) @@ -89,7 +162,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) $sql = "SELECT c.rowid, c.ref, c.ref_client, c.total_ht, c.tva as total_tva, c.total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas"; $sql.= ", s.code_client"; - $sql.= " FROM ".MAIN_DB_PREFIX."commande as c"; + $sql.= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as c"; $sql.= ", ".MAIN_DB_PREFIX."societe as s"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE c.fk_soc = s.rowid"; @@ -167,18 +240,16 @@ print '
'; $NBMAX = 3; $max = 3; -/* BEGIN MODULEBUILDER LASTMODIFIED MYOBJECT +/* BEGIN MODULEBUILDER LASTMODIFIED MYOBJECT */ // Last modified myobject -if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) +if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitmentjobposition->read) { - $sql = "SELECT s.rowid, s.nom as name, s.client, s.datec, s.tms, s.canvas"; - $sql.= ", s.code_client"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; + $sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms"; + $sql.= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as s"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE s.client IN (1, 2, 3)"; - $sql.= " AND s.entity IN (".getEntity($companystatic->element).")"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND s.rowid = $socid"; + $sql.= " WHERE s.entity IN (".getEntity($staticrecruitmentjobposition->element).")"; + if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; + if ($socid) $sql.= " AND s.fk_soc = $socid"; $sql .= " ORDER BY s.tms DESC"; $sql .= $db->plimit($max, 0); @@ -191,9 +262,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) print ''; print ''; print ''; print ''; print ''; @@ -202,16 +271,15 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) while ($i < $num) { $objp = $db->fetch_object($resql); - $companystatic->id=$objp->rowid; - $companystatic->name=$objp->name; - $companystatic->client=$objp->client; - $companystatic->code_client = $objp->code_client; - $companystatic->code_fournisseur = $objp->code_fournisseur; - $companystatic->canvas=$objp->canvas; + $staticrecruitmentjobposition->id=$objp->rowid; + $staticrecruitmentjobposition->ref=$objp->ref; + $staticrecruitmentjobposition->label=$objp->label; + $staticrecruitmentjobposition->status = $objp->status; + $staticrecruitmentjobposition->date_creation = $objp->date_creation; + print ''; - print ''; + print ''; print '"; print '"; print ''; @@ -227,9 +295,11 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) print ''; } print "
'; - if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastCustomersOrProspects",$max); - else if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastModifiedProspects",$max); - else print $langs->trans("BoxTitleLastModifiedCustomers",$max); + print $langs->trans("BoxTitleLatestModifiedJobPositions",$max); print ''.$langs->trans("DateModificationShort").'
'.$companystatic->getNomUrl(1,'customer',48).''.$staticrecruitmentjobposition->getNomUrl(1, '').''; - print $companystatic->getLibCustProspStatut(); print "'.dol_print_date($db->jdate($objp->tms),'day')."
'.$langs->trans("None").'

"; + } else { + dol_print_error($db); } } -*/ + print '
'; diff --git a/htdocs/recruitment/recruitmentjobposition_card.php b/htdocs/recruitment/recruitmentjobposition_card.php index 137afdd597f..4037147e367 100644 --- a/htdocs/recruitment/recruitmentjobposition_card.php +++ b/htdocs/recruitment/recruitmentjobposition_card.php @@ -503,19 +503,18 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea { print ''.$langs->trans("Enable").''."\n"; } - } + }*/ if ($permissiontoadd) { if ($object->status == $object::STATUS_VALIDATED) { - print ''.$langs->trans("Cancel").''."\n"; + print ''.$langs->trans("Cancel").''."\n"; } else { - print ''.$langs->trans("Re-Open").''."\n"; + print ''.$langs->trans("Re-Open").''."\n"; } } - */ // Delete (need delete permission, or if draft, just need create/modify permission) if ($permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)) From 43b23994e437d29417c862921c7fe600486a57a7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 15:55:04 +0200 Subject: [PATCH 83/97] WIP Recruitment module --- htdocs/core/lib/modulebuilder.lib.php | 24 +- ...recruitment_recruitmentcandidature.key.sql | 27 + ...llx_recruitment_recruitmentcandidature.sql | 36 + ...recruitmentcandidature_extrafields.key.sql | 19 + ...ent_recruitmentcandidature_extrafields.sql | 23 + htdocs/modulebuilder/index.php | 212 ++-- .../modulebuilder/template/modulebuilder.txt | 2 +- htdocs/public/recruitment/view.php | 6 + .../class/recruitmentcandidature.class.php | 1040 +++++++++++++++++ .../class/recruitmentjobposition.class.php | 2 +- ...tandard_recruitmentjobposition.modules.php | 10 +- htdocs/recruitment/modulebuilder.txt | 2 +- .../recruitmentjobposition_candidature.php | 43 - 13 files changed, 1293 insertions(+), 153 deletions(-) create mode 100644 htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql create mode 100644 htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql create mode 100644 htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql create mode 100644 htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql create mode 100644 htdocs/recruitment/class/recruitmentcandidature.class.php diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index 3232bae291a..ff14ec56e18 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -207,11 +207,12 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = * @param string $objectname Name of object * @param string $newmask New mask * @param string $readdir Directory source (use $destdir when not defined) - * @param Object $object If object was already loaded/known, it is pass to avaoid another include and new. + * @param Object $object If object was already loaded/known, it is pass to avoid another include and new. + * @param string $moduletype 'external' or 'internal' * @return int <=0 if KO, >0 if OK * @see rebuildObjectClass() */ -function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null) +function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null, $moduletype = 'external') { global $db, $langs; @@ -223,8 +224,14 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = ' $pathoffiletoclasssrc = $readdir.'/class/'.strtolower($objectname).'.class.php'; // Edit .sql file - $pathoffiletoeditsrc = $readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; - $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); + if ($moduletype == 'internal') { + $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; + $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); + } else { + $pathoffiletoeditsrc = $readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; + $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); + } + if (!dol_is_file($pathoffiletoeditsrc)) { $langs->load("errors"); @@ -293,8 +300,13 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = ' } // Edit .key.sql file - $pathoffiletoeditsrc = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; - $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); + if ($moduletype == 'internal') { + $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; + $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); + } else { + $pathoffiletoeditsrc = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; + $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); + } $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r'); diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql new file mode 100644 index 00000000000..8f92832c2a3 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql @@ -0,0 +1,27 @@ +-- Copyright (C) 2020 Laurent Destailleur +-- +-- 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 https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_rowid (rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_ref (ref); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD CONSTRAINT llx_recruitment_recruitmentcandidature_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_status (status); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_mymodule_myobject ADD UNIQUE INDEX uk_mymodule_myobject_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_mymodule_myobject ADD CONSTRAINT llx_mymodule_myobject_fk_field FOREIGN KEY (fk_field) REFERENCES llx_mymodule_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql new file mode 100644 index 00000000000..c1905f46b63 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql @@ -0,0 +1,36 @@ +-- Copyright (C) 2020 Laurent Destailleur +-- +-- 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 https://www.gnu.org/licenses/. + + +CREATE TABLE llx_recruitment_recruitmentcandidature( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + description text, + note_public text, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + model_pdf varchar(255), + status smallint NOT NULL, + firstname varchar(128), + lastname varchar(128), + remuneration_requested integer, + remuneration_proposed integer + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql new file mode 100644 index 00000000000..fb1522bf6f1 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql @@ -0,0 +1,19 @@ +-- Copyright (C) 2020 Laurent Destailleur +-- +-- 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 https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_recruitment_recruitmentcandidature_extrafields ADD INDEX idx_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql new file mode 100644 index 00000000000..d0fb92fead9 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql @@ -0,0 +1,23 @@ +-- Copyright (C) 2020 Laurent Destailleur +-- +-- 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 https://www.gnu.org/licenses/. + +create table llx_recruitment_recruitmentcandidature_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index df9e58e9b31..c8274a8f8dd 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -95,6 +95,85 @@ $result = restrictedArea($user, 'modulebuilder', null); $error = 0; +// Define $listofmodules +$dirsrootforscan = array($dirread); +// Add also the core modules into the list of modules to show/edit +if ($dirread != DOL_DOCUMENT_ROOT && ($conf->global->MAIN_FEATURES_LEVEL >= 2 || !empty($conf->global->MODULEBUILDER_ADD_DOCUMENT_ROOT))) { $dirsrootforscan[] = DOL_DOCUMENT_ROOT; } + +// Search modules to edit +$textforlistofdirs = ''."\n"; +$listofmodules = array(); +$i = 0; +foreach ($dirsrootforscan as $dirread) +{ + $moduletype = 'external'; + if ($dirread == DOL_DOCUMENT_ROOT) { + $moduletype = 'internal'; + } + + $dirsincustom = dol_dir_list($dirread, 'directories'); + if (is_array($dirsincustom) && count($dirsincustom) > 0) { + foreach ($dirsincustom as $dircustomcursor) { + $fullname = $dircustomcursor['fullname']; + if (dol_is_file($fullname.'/'.$FILEFLAG)) + { + // Get real name of module (MyModule instead of mymodule) + $dirtoscanrel = basename($fullname).'/core/modules/'; + + $descriptorfiles = dol_dir_list(dirname($fullname).'/'.$dirtoscanrel, 'files', 0, 'mod.*\.class\.php$'); + if (empty($descriptorfiles)) // If descriptor not found into module dir, we look into main module dir. + { + $dirtoscanrel = 'core/modules/'; + $descriptorfiles = dol_dir_list($fullname.'/../'.$dirtoscanrel, 'files', 0, 'mod'.strtoupper(basename($fullname)).'\.class\.php$'); + } + $modulenamewithcase = ''; + $moduledescriptorrelpath = ''; + $moduledescriptorfullpath = ''; + + foreach ($descriptorfiles as $descriptorcursor) { + $modulenamewithcase = preg_replace('/^mod/', '', $descriptorcursor['name']); + $modulenamewithcase = preg_replace('/\.class\.php$/', '', $modulenamewithcase); + $moduledescriptorrelpath = $dirtoscanrel.$descriptorcursor['name']; + $moduledescriptorfullpath = $descriptorcursor['fullname']; + //var_dump($descriptorcursor); + } + if ($modulenamewithcase) + { + $listofmodules[$dircustomcursor['name']] = array( + 'modulenamewithcase'=>$modulenamewithcase, + 'moduledescriptorrelpath'=> $moduledescriptorrelpath, + 'moduledescriptorfullpath'=>$moduledescriptorfullpath, + 'moduledescriptorrootpath'=>$dirread, + 'moduletype'=>$moduletype + ); + } + //var_dump($listofmodules); + } + } + } + + if ($forceddirread && empty($listofmodules)) // $forceddirread is 1 if we forced dir to read with dirins=... or with module=...@mydir + { + $listofmodules[strtolower($module)] = array( + 'modulenamewithcase'=>$module, + 'moduledescriptorrelpath'=> 'notyetimplemented', + 'moduledescriptorfullpath'=> 'notyetimplemented', + 'moduledescriptorrootpath'=> 'notyetimplemented', + ); + } + + // Show description of content + $newdircustom = $dirins; + if (empty($newdircustom)) $newdircustom = img_warning(); + // If dirread was forced to somewhere else, by using URL + // htdocs/modulebuilder/index.php?module=Inventory@/home/ldestailleur/git/dolibarr/htdocs/product + if (empty($i)) $textforlistofdirs .= $langs->trans("DirScanned").' : '; + else $textforlistofdirs .= ', '; + $textforlistofdirs .= ''.$dirread.''; + $i++; +} + + /* * Actions */ @@ -214,7 +293,6 @@ if ($dirins && $action == 'initmodule' && $modulename) } $result = dolReplaceInFile($phpfileval['fullname'], $arrayreplacement); - //var_dump($result); if ($result < 0) { @@ -769,6 +847,9 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { $objectname = ucfirst($objectname); + $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $moduletype = $listofmodules[strtolower($module)]['moduletype']; + if (preg_match('/[^a-z0-9_]/i', $objectname)) { $error++; @@ -1076,6 +1157,9 @@ if ($dirins && $action == 'addproperty' && !empty($module) && !empty($tabobj)) $objectname = $tabobj; + $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $moduletype = $listofmodules[strtolower($module)]['moduletype']; + $srcdir = $dirread.'/'.strtolower($module); $destdir = $dirins.'/'.strtolower($module); dol_mkdir($destdir); @@ -1125,7 +1209,9 @@ if ($dirins && $action == 'addproperty' && !empty($module) && !empty($tabobj)) // Edit the class file to write properties if (!$error) { - $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry); + $moduletype = 'external'; + + $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry, $moduletype); if (is_numeric($object) && $object <= 0) { $error++; @@ -1135,7 +1221,9 @@ if ($dirins && $action == 'addproperty' && !empty($module) && !empty($tabobj)) // Edit sql with new properties if (!$error) { - $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object); + $moduletype = 'external'; + + $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object, $moduletype); if ($result <= 0) { $error++; @@ -1477,79 +1565,11 @@ print load_fiche_titre($text, '', 'title_setup'); print ''.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'
'; -$dirsrootforscan = array($dirread); -// Add also the core modules into the list of modules to show/edit -if ($dirread != DOL_DOCUMENT_ROOT && ($conf->global->MAIN_FEATURES_LEVEL >= 2 || !empty($conf->global->MODULEBUILDER_ADD_DOCUMENT_ROOT))) { $dirsrootforscan[] = DOL_DOCUMENT_ROOT; } - -// Search modules to edit -print ''."\n"; -$listofmodules = array(); -$i = 0; -foreach ($dirsrootforscan as $dirread) -{ - $dirsincustom = dol_dir_list($dirread, 'directories'); - if (is_array($dirsincustom) && count($dirsincustom) > 0) { - foreach ($dirsincustom as $dircustomcursor) { - $fullname = $dircustomcursor['fullname']; - if (dol_is_file($fullname.'/'.$FILEFLAG)) - { - // Get real name of module (MyModule instead of mymodule) - $dirtoscanrel = basename($fullname).'/core/modules/'; - - $descriptorfiles = dol_dir_list(dirname($fullname).'/'.$dirtoscanrel, 'files', 0, 'mod.*\.class\.php$'); - if (empty($descriptorfiles)) // If descriptor not found into module dir, we look into main module dir. - { - $dirtoscanrel = 'core/modules/'; - $descriptorfiles = dol_dir_list($fullname.'/../'.$dirtoscanrel, 'files', 0, 'mod'.strtoupper(basename($fullname)).'\.class\.php$'); - } - $modulenamewithcase = ''; - $moduledescriptorrelpath = ''; - $moduledescriptorfullpath = ''; - - foreach ($descriptorfiles as $descriptorcursor) { - $modulenamewithcase = preg_replace('/^mod/', '', $descriptorcursor['name']); - $modulenamewithcase = preg_replace('/\.class\.php$/', '', $modulenamewithcase); - $moduledescriptorrelpath = $dirtoscanrel.$descriptorcursor['name']; - $moduledescriptorfullpath = $descriptorcursor['fullname']; - //var_dump($descriptorcursor); - } - if ($modulenamewithcase) - { - $listofmodules[$dircustomcursor['name']] = array( - 'modulenamewithcase'=>$modulenamewithcase, - 'moduledescriptorrelpath'=> $moduledescriptorrelpath, - 'moduledescriptorfullpath'=>$moduledescriptorfullpath, - 'moduledescriptorrootpath'=>$dirread - ); - } - //var_dump($listofmodules); - } - } - } - - if ($forceddirread && empty($listofmodules)) // $forceddirread is 1 if we forced dir to read with dirins=... or with module=...@mydir - { - $listofmodules[strtolower($module)] = array( - 'modulenamewithcase'=>$module, - 'moduledescriptorrelpath'=> 'notyetimplemented', - 'moduledescriptorfullpath'=> 'notyetimplemented', - 'moduledescriptorrootpath'=> 'notyetimplemented', - ); - } - - // Show description of content - $newdircustom = $dirins; - if (empty($newdircustom)) $newdircustom = img_warning(); - // If dirread was forced to somewhere else, by using URL - // htdocs/modulebuilder/index.php?module=Inventory@/home/ldestailleur/git/dolibarr/htdocs/product - if (empty($i)) print $langs->trans("DirScanned").' : '; - else print ', '; - print ''.$dirread.''; - $i++; -} +print $textforlistofdirs; print '
'; //var_dump($listofmodules); + $message = ''; if (!$dirins) { @@ -1583,7 +1603,6 @@ $error = 0; $moduleobj = null; - if (!empty($module) && $module != 'initmodule' && $module != 'deletemodule') { $modulelowercase = strtolower($module); @@ -1835,6 +1854,8 @@ if ($module == 'initmodule') print '
'; + // Note module is inside $dirread + if ($tab == 'description') { $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; @@ -2315,29 +2336,31 @@ if ($module == 'initmodule') $pathtopicto = strtolower($module).'/img/object_'.strtolower($tabobj).'.png'; $pathtoscript = strtolower($module).'/scripts/'.strtolower($tabobj).'.php'; - //var_dump($pathtolib); - $realpathtoclass = dol_buildpath($pathtoclass, 0, 2); - $realpathtoapi = dol_buildpath($pathtoapi, 0, 2); - $realpathtoagenda = dol_buildpath($pathtoagenda, 0, 2); - $realpathtocard = dol_buildpath($pathtocard, 0, 2); - $realpathtodocument = dol_buildpath($pathtodocument, 0, 2); - $realpathtolist = dol_buildpath($pathtolist, 0, 2); - $realpathtonote = dol_buildpath($pathtonote, 0, 2); - $realpathtophpunit = dol_buildpath($pathtophpunit, 0, 2); - $realpathtosql = dol_buildpath($pathtosql, 0, 2); - $realpathtosqlextra = dol_buildpath($pathtosqlextra, 0, 2); - $realpathtosqlkey = dol_buildpath($pathtosqlkey, 0, 2); - $realpathtosqlextrakey = dol_buildpath($pathtosqlextrakey, 0, 2); - $realpathtolib = dol_buildpath($pathtolib, 0, 2); - $realpathtoobjlib = dol_buildpath($pathtoobjlib, 0, 2); - $realpathtopicto = dol_buildpath($pathtopicto, 0, 2); - $realpathtoscript = dol_buildpath($pathtoscript, 0, 2); + //var_dump($pathtoclass); var_dump($dirread); + $realpathtoclass = $dirread.'/'.$pathtoclass; + $realpathtoapi = $dirread.'/'.$pathtoapi; + $realpathtoagenda = $dirread.'/'.$pathtoagenda; + $realpathtocard = $dirread.'/'.$pathtocard; + $realpathtodocument = $dirread.'/'.$pathtodocument; + $realpathtolist = $dirread.'/'.$pathtolist; + $realpathtonote = $dirread.'/'.$pathtonote; + $realpathtophpunit = $dirread.'/'.$pathtophpunit; + $realpathtosql = $dirread.'/'.$pathtosql; + $realpathtosqlextra = $dirread.'/'.$pathtosqlextra; + $realpathtosqlkey = $dirread.'/'.$pathtosqlkey; + $realpathtosqlextrakey = $dirread.'/'.$pathtosqlextrakey; + $realpathtolib = $dirread.'/'.$pathtolib; + $realpathtoobjlib = $dirread.'/'.$pathtoobjlib; + $realpathtopicto = $dirread.'/'.$pathtopicto; + $realpathtoscript = $dirread.'/'.$pathtoscript; if (empty($realpathtoapi)) // For compatibility with some old modules { $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'s.class.php'; - $realpathtoapi = dol_buildpath($pathtoapi, 0, 2); + $realpathtoapi = $dirread.'/'.$pathtoapi; } + $urloflist = $dirread.'/'.$pathtolist; + $urlofcard = $dirread.'/'.$pathtocard; print '
'; print ' '.$langs->trans("ClassFile").' : '.($realpathtoclass ? '' : '').$pathtoclass.($realpathtoclass ? '' : '').''; @@ -2423,9 +2446,6 @@ if ($module == 'initmodule') print '
'; print '
'; - $urloflist = dol_buildpath($pathtolist, 1); - $urlofcard = dol_buildpath($pathtocard, 1); - print '
'; print ' '.$langs->trans("PageForList").' : '.($realpathtolist ? '' : '').$pathtolist.($realpathtolist ? '' : '').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; @@ -2472,7 +2492,7 @@ if ($module == 'initmodule') if (function_exists('opcache_invalidate')) opcache_invalidate($dirread.'/'.$pathtoclass, true); // remove the include cache hell ! - if (empty($forceddirread)) + if (empty($forceddirread) && empty($dirread)) { $result = dol_include_once($pathtoclass); } else { diff --git a/htdocs/modulebuilder/template/modulebuilder.txt b/htdocs/modulebuilder/template/modulebuilder.txt index 24ea0d6eac5..670a1774929 100644 --- a/htdocs/modulebuilder/template/modulebuilder.txt +++ b/htdocs/modulebuilder/template/modulebuilder.txt @@ -1,3 +1,3 @@ # DO NOT DELETE THIS FILE MANUALLY # File to flag module built using official module template. -# When this file is present into a module directory, you can edit it with the module builder tool. Use ModuleBuilder if you want to delete module. \ No newline at end of file +# When this file is present into a module directory, you can edit it with the module builder tool. \ No newline at end of file diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index 3afc6825c43..2b07d303aa9 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -264,6 +264,12 @@ if ($object->date_planned > $now) { } print '
'; +// Remuneration +print $langs->trans("Remuneration").' : '; +print ''; +print $object->remuneration_suggested; +print '
'; + // Contact $tmpuser = new User($db); $tmpuser->fetch($object->fk_user_recruiter); diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php new file mode 100644 index 00000000000..cacda6674c2 --- /dev/null +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -0,0 +1,1040 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * 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 . + */ + +/** + * \file class/recruitmentcandidature.class.php + * \ingroup recruitment + * \brief This file is a CRUD class file for RecruitmentCandidature (Create/Read/Update/Delete) + */ + +// Put here all includes required by your class file +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class for RecruitmentCandidature + */ +class RecruitmentCandidature extends CommonObject +{ + /** + * @var string ID to identify managed object. + */ + public $element = 'recruitmentcandidature'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'recruitment_recruitmentcandidature'; + + /** + * @var int Does this object support multicompany module ? + * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table + */ + public $ismultientitymanaged = 0; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for recruitmentcandidature. Must be the part after the 'object_' into object_recruitmentcandidature.png + */ + public $picto = 'recruitmentcandidature@recruitment'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3,), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), + 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), + 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), + 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '9'=>'Canceled'),), + 'firstname' => array('type'=>'varchar(128)', 'label'=>'Firstname', 'enabled'=>'1', 'position'=>20, 'notnull'=>0, 'visible'=>1,), + 'lastname' => array('type'=>'varchar(128)', 'label'=>'Lastname', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>1,), + 'remuneration_requested' => array('type'=>'integer', 'label'=>'RequestedRemuneration', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1,), + 'remuneration_proposed' => array('type'=>'integer', 'label'=>'ProposedRemuneration', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1,), + ); + public $rowid; + public $ref; + public $description; + public $note_public; + public $note_private; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $import_key; + public $model_pdf; + public $status; + public $firstname; + public $lastname; + public $remuneration_requested; + public $remuneration_proposed; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + /** + * @var int Name of subtable line + */ + //public $table_element_line = 'recruitment_recruitmentcandidatureline'; + + /** + * @var int Field with ID of parent key if this object has a parent + */ + //public $fk_element = 'fk_recruitmentcandidature'; + + /** + * @var int Name of subtable class that manage subtable lines + */ + //public $class_element_line = 'RecruitmentCandidatureline'; + + /** + * @var array List of child tables. To test if we can delete object. + */ + //protected $childtables = array(); + + /** + * @var array List of child tables. To know object to delete on cascade. + * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will + * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object + */ + //protected $childtablesoncascade = array('recruitment_recruitmentcandidaturedet'); + + /** + * @var RecruitmentCandidatureLine[] Array of subtable lines + */ + //public $lines = array(); + + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + global $conf, $langs; + + $this->db = $db; + + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0; + if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0; + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->recruitment->recruitmentcandidature->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 0; + }*/ + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) + { + if (isset($val['enabled']) && empty($val['enabled'])) + { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) + { + foreach ($this->fields as $key => $val) + { + if (is_array($val['arrayofkeyval'])) + { + foreach ($val['arrayofkeyval'] as $key2 => $val2) + { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + return $this->createCommon($user, $notrigger); + } + + /** + * Clone an object into another one + * + * @param User $user User that creates + * @param int $fromid Id of object to clone + * @return mixed New object created, <0 if KO + */ + public function createFromClone(User $user, $fromid) + { + global $langs, $extrafields; + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $object = new self($this->db); + + $this->db->begin(); + + // Load source object + $result = $object->fetchCommon($fromid); + if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines(); + + // get lines so they will be clone + //foreach($this->lines as $line) + // $line->fetch_optionals(); + + // Reset some properties + unset($object->id); + unset($object->fk_user_creat); + unset($object->import_key); + + + // Clear fields + $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default']; + $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + $object->status = self::STATUS_DRAFT; + // ... + // Clear extrafields that are unique + if (is_array($object->array_options) && count($object->array_options) > 0) + { + $extrafields->fetch_name_optionals_label($this->table_element); + foreach ($object->array_options as $key => $option) + { + $shortkey = preg_replace('/options_/', '', $key); + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) + { + //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; + unset($object->array_options[$key]); + } + } + } + + // Create clone + $object->context['createfromclone'] = 'createfromclone'; + $result = $object->createCommon($user); + if ($result < 0) { + $error++; + $this->error = $object->error; + $this->errors = $object->errors; + } + + if (!$error) + { + // copy internal contacts + if ($this->copy_linked_contact($object, 'internal') < 0) + { + $error++; + } + } + + if (!$error) + { + // copy external contacts if same company + if (property_exists($this, 'socid') && $this->socid == $object->socid) + { + if ($this->copy_linked_contact($object, 'external') < 0) + $error++; + } + } + + unset($object->context['createfromclone']); + + // End + if (!$error) { + $this->db->commit(); + return $object; + } else { + $this->db->rollback(); + return -1; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $ref Ref + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null) + { + $result = $this->fetchCommon($id, $ref); + if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines(); + return $result; + } + + /** + * Load object lines in memory from the database + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetchLines() + { + $this->lines = array(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + + /** + * Load list of objects in memory from the database. + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit limit + * @param int $offset Offset + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) + * @param string $filtermode Filter mode (AND or OR) + * @return array|int int <0 if KO, array of pages if OK + */ + public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + { + global $conf; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $records = array(); + + $sql = 'SELECT '; + $sql .= $this->getFieldList(); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')'; + else $sql .= ' WHERE 1 = 1'; + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.rowid') { + $sqlwhere[] = $key.'='.$value; + } elseif (strpos($key, 'date') !== false) { + $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } else { + $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')'; + } + + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield, $sortorder); + } + if (!empty($limit)) { + $sql .= ' '.$this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < ($limit ? min($limit, $num) : $num)) + { + $obj = $this->db->fetch_object($resql); + + $record = new self($this->db); + $record->setVarsFromFetchObj($obj); + + $records[$record->id] = $record; + + $i++; + } + $this->db->free($resql); + + return $records; + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + return -1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + return $this->updateCommon($user, $notrigger); + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + return $this->deleteCommon($user, $notrigger); + //return $this->deleteCommon($user, $notrigger, 1); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) + { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * Validate object + * + * @param User $user User making status change + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <=0 if OK, 0=Nothing done, >0 if KO + */ + public function validate($user, $notrigger = 0) + { + global $conf, $langs; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) + { + dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitmentcandidature->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitmentcandidature->recruitmentcandidature_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life + { + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " status = ".self::STATUS_VALIDATED; + if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',"; + if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".$user->id; + $sql .= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::validate()", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) + { + dol_print_error($this->db); + $this->error = $this->db->lasterror(); + $error++; + } + + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('RECRUITMENTCANDIDATURE_VALIDATE', $user); + if ($result < 0) $error++; + // End call triggers + } + } + + if (!$error) + { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'recruitmentcandidature/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { $error++; $this->error = $this->db->lasterror(); } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$oldref; + $dirdest = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref; + if (!$error && file_exists($dirsource)) + { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) + { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) + { + $this->ref = $num; + $this->status = self::STATUS_VALIDATED; + } + + if (!$error) + { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, >0 if OK + */ + public function setDraft($user, $notrigger = 0) + { + // Protection + if ($this->status <= self::STATUS_DRAFT) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'RECRUITMENTCANDIDATURE_UNVALIDATE'); + } + + /** + * Set cancel status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function cancel($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_VALIDATED) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTCANDIDATURE_CLOSE'); + } + + /** + * Set back to validated status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function reopen($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_CANCELED) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTCANDIDATURE_REOPEN'); + } + + /** + * Return a link to the object card (with optionaly the picto) + * + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ + public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) + { + global $conf, $langs, $hookmanager; + + if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips + + $result = ''; + + $label = ''.$langs->trans("RecruitmentCandidature").''; + $label .= '
'; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + if (isset($this->status)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } + + $url = dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?id='.$this->id; + + if ($option != 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; + if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; + } + + $linkclose = ''; + if (empty($notooltip)) + { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label = $langs->trans("ShowRecruitmentCandidature"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + + $linkstart = ''; + $linkend = ''; + + $result .= $linkstart; + + if (empty($this->showphoto_on_popup)) { + if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } else { + if ($withpicto) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + list($class, $module) = explode('@', $this->picto); + $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref); + $filearray = dol_dir_list($upload_dir, "files"); + $filename = $filearray[0]['name']; + if (!empty($filename)) { + $pospoint = strpos($filearray[0]['name'], '.'); + + $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint); + if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) { + $result .= '
No photo
'; + } else { + $result .= '
No photo
'; + } + + $result .= '
'; + } else { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } + } + + if ($withpicto != 2) $result .= $this->ref; + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array('recruitmentcandidaturedao')); + $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) $result = $hookmanager->resPrint; + else $result .= $hookmanager->resPrint; + + return $result; + } + + /** + * Return label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLibStatut($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function LibStatut($status, $mode = 0) + { + // phpcs:enable + if (empty($this->labelStatus) || empty($this->labelStatusShort)) + { + global $langs; + //$langs->load("recruitment@recruitment"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); + } + + $statusType = 'status'.$status; + //if ($status == self::STATUS_VALIDATED) $statusType = 'status1'; + if ($status == self::STATUS_CANCELED) $statusType = 'status6'; + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); + } + + /** + * Load the info information in the object + * + * @param int $id Id of object + * @return void + */ + public function info($id) + { + $sql = 'SELECT rowid, date_creation as datec, tms as datem,'; + $sql .= ' fk_user_creat, fk_user_modif'; + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + $sql .= ' WHERE t.rowid = '.$id; + $result = $this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + $this->id = $obj->rowid; + if ($obj->fk_user_author) + { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + + if ($obj->fk_user_valid) + { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_cloture) + { + $cluser = new User($this->db); + $cluser->fetch($obj->fk_user_cloture); + $this->user_cloture = $cluser; + } + + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->datem); + $this->date_validation = $this->db->jdate($obj->datev); + } + + $this->db->free($result); + } else { + dol_print_error($this->db); + } + } + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + $this->initAsSpecimenCommon(); + } + + /** + * Create an array of lines + * + * @return array|int array of lines if OK, <0 if KO + */ + public function getLinesArray() + { + $this->lines = array(); + + $objectline = new RecruitmentCandidatureLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_recruitmentcandidature = '.$this->id)); + + if (is_numeric($result)) + { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("recruitment@recruitment"); + + if (empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) { + $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON = 'mod_recruitmentcandidature_standard'; + } + + if (!empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) + { + $mybool = false; + + $file = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON.".php"; + $classname = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/recruitment/"); + + // Load file with numbering class (if found) + $mybool |= @include_once $dir.$file; + } + + if ($mybool === false) + { + dol_print_error('', "Failed to include file ".$file); + return ''; + } + + if (class_exists($classname)) { + $obj = new $classname(); + $numref = $obj->getNextValue($this); + + if ($numref != '' && $numref != '-1') + { + return $numref; + } else { + $this->error = $obj->error; + //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + return ""; + } + } else { + print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; + return ""; + } + } else { + print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); + return ""; + } + } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @param null|array $moreparams Array to provide more information + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) + { + global $conf, $langs; + + $result = 0; + $includedocgeneration = 1; + + $langs->load("recruitment@recruitment"); + + if (!dol_strlen($modele)) { + $modele = 'standard_recruitmentcandidature'; + + if ($this->modelpdf) { + $modele = $this->modelpdf; + } elseif (!empty($conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF)) { + $modele = $conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF; + } + } + + $modelpath = "core/modules/recruitment/doc/"; + + if ($includedocgeneration) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * Action executed by scheduler + * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' + * Use public function doScheduledJob($param1, $param2, ...) to get parameters + * + * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + */ + public function doScheduledJob() + { + global $conf, $langs; + + //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log'; + + $error = 0; + $this->output = ''; + $this->error = ''; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $now = dol_now(); + + $this->db->begin(); + + // ... + + $this->db->commit(); + + return $error; + } +} + + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; + +/** + * Class RecruitmentCandidatureLine. You can also remove this and generate a CRUD class for lines objects. + */ +class RecruitmentCandidatureLine extends CommonObjectLine +{ + // To complete with content of an object RecruitmentCandidatureLine + // We should have a field rowid, fk_recruitmentcandidature and position + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } +} diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index c1ad8c3346d..aab39e4e433 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -45,7 +45,7 @@ class RecruitmentJobPosition extends CommonObject * @var int Does this object support multicompany module ? * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table */ - public $ismultientitymanaged = 0; + public $ismultientitymanaged = 1; /** * @var int Does object support extrafields ? 0=No, 1=Yes diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index 580b3141d5c..cc28ea8978b 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -358,10 +358,10 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio $pdf->SetDrawColor(128, 128, 128); $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); - $pdf->SetSubject($outputlangs->transnoentities("JobPosition")); + $pdf->SetSubject($object->label); $pdf->SetCreator("Dolibarr ".DOL_VERSION); $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); - $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("JobPosition")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$object->label." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); // Set certificate @@ -872,11 +872,11 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio $pdf->SetFont('', 'B', $default_font_size + 3); $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); - $title = $outputlangs->transnoentities("JobPosition"); - if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $title = $object->label; + /*if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { $title .= ' - '; $title .= $outputlangsbis->transnoentities("JobPosition"); - } + }*/ $pdf->MultiCell($w, 3, $title, '', 'R'); $pdf->SetFont('', 'B', $default_font_size); diff --git a/htdocs/recruitment/modulebuilder.txt b/htdocs/recruitment/modulebuilder.txt index 24ea0d6eac5..670a1774929 100644 --- a/htdocs/recruitment/modulebuilder.txt +++ b/htdocs/recruitment/modulebuilder.txt @@ -1,3 +1,3 @@ # DO NOT DELETE THIS FILE MANUALLY # File to flag module built using official module template. -# When this file is present into a module directory, you can edit it with the module builder tool. Use ModuleBuilder if you want to delete module. \ No newline at end of file +# When this file is present into a module directory, you can edit it with the module builder tool. \ No newline at end of file diff --git a/htdocs/recruitment/recruitmentjobposition_candidature.php b/htdocs/recruitment/recruitmentjobposition_candidature.php index bf2c766771f..d0e15827c2e 100644 --- a/htdocs/recruitment/recruitmentjobposition_candidature.php +++ b/htdocs/recruitment/recruitmentjobposition_candidature.php @@ -539,52 +539,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print ''; // ancre - $includedocgeneration = 1; - - // Documents - if ($includedocgeneration) { - $objref = dol_sanitizeFileName($object->ref); - $relativepath = $objref . '/' . $objref . '.pdf'; - $filedir = $conf->recruitment->dir_output.'/'.$object->element.'/'.$objref; - $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; - $genallowed = $user->rights->recruitment->recruitmentjobposition->read; // If you can read, you can build the PDF to read content - $delallowed = $user->rights->recruitment->recruitmentjobposition->write; // If you can create/edit, you can remove a file on card - print $formfile->showdocuments('recruitment:RecruitmentJobPosition', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); - } - - // Show links to link elements - $linktoelem = $form->showLinkToObjectBlock($object, null, array('recruitmentjobposition')); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - - // Show link to public job page - if ($object->status != RecruitmentJobPosition::STATUS_DRAFT) - { - print '
'."\n"; - // Load translation files required by the page - $langs->loadLangs(array('recruitment')); - - $out = img_picto('', 'globe').' '.$langs->trans("PublicUrl").'
'; - - $url = getPublicJobPositionUrl(0, $object->ref); - $out .= ''; - $out .= ''.img_picto('', 'globe').''; - $out .= ajax_autoselect("recruitmentjobpositionurl", 0); - - print $out; - } print '
'; - $MAXEVENT = 10; - - $morehtmlright = ''; - $morehtmlright .= $langs->trans("SeeAll"); - $morehtmlright .= ''; - - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, $object->element.'@recruitment', (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); print '
'; } From 561520b44c6102f6dbaa21ec4b5b620bc99ace6d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 16:06:15 +0200 Subject: [PATCH 84/97] WIP Recruitment module --- .../install/mysql/migration/12.0.0-13.0.0.sql | 45 +++++++++++++++++++ ...llx_recruitment_recruitmentcandidature.sql | 3 +- .../class/recruitmentcandidature.class.php | 1 + 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 58d85e80526..dd42297dc3b 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -129,6 +129,51 @@ create table llx_recruitment_recruitmentjobposition_extrafields ALTER TABLE llx_recruitment_recruitmentjobposition_extrafields ADD INDEX idx_fk_object(fk_object); + +CREATE TABLE llx_recruitment_recruitmentcandidature( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + fk_recruitmentjobposition INTEGER NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + description text, + note_public text, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + model_pdf varchar(255), + status smallint NOT NULL, + firstname varchar(128), + lastname varchar(128), + remuneration_requested integer, + remuneration_proposed integer + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_rowid (rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_ref (ref); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD CONSTRAINT llx_recruitment_recruitmentcandidature_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_status (status); + + +create table llx_recruitment_recruitmentcandidature_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_recruitment_recruitmentcandidature_extrafields ADD INDEX idx_fk_object(fk_object); + + + + + + + -- Add dictionary for prospect level and action commercial on contacts (Using this is not recommanded) create table llx_c_prospectcontactlevel diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql index c1905f46b63..fb9cf56c8b2 100644 --- a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql @@ -17,7 +17,8 @@ CREATE TABLE llx_recruitment_recruitmentcandidature( -- BEGIN MODULEBUILDER FIELDS rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, - ref varchar(128) DEFAULT '(PROV)' NOT NULL, + fk_recruitmentjobposition INTEGER NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, description text, note_public text, note_private text, diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php index cacda6674c2..4ee4bccbb7a 100644 --- a/htdocs/recruitment/class/recruitmentcandidature.class.php +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -96,6 +96,7 @@ class RecruitmentCandidature extends CommonObject public $fields=array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'fk_recruitmentjobposition' => array('type'=>'integer:RecruitmentJobPosition:recruitment/class/recruitment_recruitmentjobposition.class.php', 'label'=>'Job', 'enabled'=>'1', 'position'=>15, 'notnull'=>1, 'visible'=>1, 'index'=>1), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3,), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), From e6c4c8082ea5bc700c7532eef1d3a7feefe359b4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 16:10:40 +0200 Subject: [PATCH 85/97] Fix phpcs --- .../modulebuilder/template/mymoduleindex.php | 8 ++--- .../modulebuilder/template/myobject_card.php | 32 ++++++----------- htdocs/recruitment/recruitmentindex.php | 10 ++---- .../recruitmentjobposition_card.php | 35 ++++++------------- 4 files changed, 27 insertions(+), 58 deletions(-) diff --git a/htdocs/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php index 9050b5319e0..91eb5eca8da 100644 --- a/htdocs/modulebuilder/template/mymoduleindex.php +++ b/htdocs/modulebuilder/template/mymoduleindex.php @@ -184,7 +184,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print ''; print ''; print ''; print ''; print ''; @@ -203,15 +203,13 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print ''; print '"; - print '"; + print '"; print ''; $i++; } $db->free($resql); - } - else - { + } else { print ''; } print "
'; - print $langs->trans("BoxTitleLatestModifiedMyObjects",$max); + print $langs->trans("BoxTitleLatestModifiedMyObjects", $max); print ''.$langs->trans("DateModificationShort").'
'.$myobjectstatic->getNomUrl(1).''; print "'.dol_print_date($db->jdate($objp->tms),'day')."'.dol_print_date($db->jdate($objp->tms), 'day')."
'.$langs->trans("None").'

"; diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index fd17bfe2d6d..a85f84a50ba 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -468,27 +468,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Back to draft - if ($object->status == $object::STATUS_VALIDATED) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_VALIDATED) { + if ($permissiontoadd) { print ''.$langs->trans("SetToDraft").''; } } // Modify - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("Modify").''."\n"; } else { print ''.$langs->trans('Modify').''."\n"; } // Validate - if ($object->status == $object::STATUS_DRAFT) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_DRAFT) { + if ($permissiontoadd) { if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { print ''.$langs->trans("Validate").''; @@ -500,31 +495,24 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Clone - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("ToClone").''."\n"; } /* if ($permissiontoadd) { - if ($object->status == $object::STATUS_ENABLED) - { + if ($object->status == $object::STATUS_ENABLED) { print ''.$langs->trans("Disable").''."\n"; - } - else - { + } else { print ''.$langs->trans("Enable").''."\n"; } } if ($permissiontoadd) { - if ($object->status == $object::STATUS_VALIDATED) - { + if ($object->status == $object::STATUS_VALIDATED) { print ''.$langs->trans("Cancel").''."\n"; - } - else - { + } else { print ''.$langs->trans("Re-Open").''."\n"; } } diff --git a/htdocs/recruitment/recruitmentindex.php b/htdocs/recruitment/recruitmentindex.php index dc0b0eac8cf..cf1f0e7dee4 100644 --- a/htdocs/recruitment/recruitmentindex.php +++ b/htdocs/recruitment/recruitmentindex.php @@ -262,7 +262,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitm print ''; print ''; print ''; print ''; print ''; @@ -281,17 +281,13 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitm print ''; print '"; - print '"; + print '"; print ''; $i++; - - } $db->free($resql); - } - else - { + } else { print ''; } print "
'; - print $langs->trans("BoxTitleLatestModifiedJobPositions",$max); + print $langs->trans("BoxTitleLatestModifiedJobPositions", $max); print ''.$langs->trans("DateModificationShort").'
'.$staticrecruitmentjobposition->getNomUrl(1, '').''; print "'.dol_print_date($db->jdate($objp->tms),'day')."'.dol_print_date($db->jdate($objp->tms), 'day')."
'.$langs->trans("None").'

"; diff --git a/htdocs/recruitment/recruitmentjobposition_card.php b/htdocs/recruitment/recruitmentjobposition_card.php index 4037147e367..0763b5ca749 100644 --- a/htdocs/recruitment/recruitmentjobposition_card.php +++ b/htdocs/recruitment/recruitmentjobposition_card.php @@ -455,8 +455,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Back to draft - if ($object->status == $object::STATUS_VALIDATED) - { + if ($object->status == $object::STATUS_VALIDATED) { if ($permissiontoadd) { print ''.$langs->trans("SetToDraft").''; @@ -464,18 +463,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Modify - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("Modify").''."\n"; } else { print ''.$langs->trans('Modify').''."\n"; } // Validate - if ($object->status == $object::STATUS_DRAFT) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_DRAFT) { + if ($permissiontoadd) { if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { print ''.$langs->trans("Validate").''; @@ -487,38 +483,29 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Clone - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("ToClone").''."\n"; } /* - if ($permissiontoadd) - { - if ($object->status == $object::STATUS_ENABLED) - { + if ($permissiontoadd) { + if ($object->status == $object::STATUS_ENABLED) { print ''.$langs->trans("Disable").''."\n"; - } - else - { + } else { print ''.$langs->trans("Enable").''."\n"; } }*/ if ($permissiontoadd) { - if ($object->status == $object::STATUS_VALIDATED) - { + if ($object->status == $object::STATUS_VALIDATED) { print ''.$langs->trans("Cancel").''."\n"; - } - else - { + } else { print ''.$langs->trans("Re-Open").''."\n"; } } // Delete (need delete permission, or if draft, just need create/modify permission) - if ($permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)) - { + if ($permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)) { print ''.$langs->trans('Delete').''."\n"; } else { print ''.$langs->trans('Delete').''."\n"; From 53acd8cffd88c4d3d3d19b72dfc0ae623fe95ec2 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 6 Aug 2020 16:28:17 +0200 Subject: [PATCH 86/97] FIX: MAIN_MAIL_FORCE_SENDTO work now for all mail sending method --- htdocs/core/class/CMailFile.class.php | 76 +++++++++++++-------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 853f2f98b05..32545465f45 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -242,6 +242,23 @@ class CMailFile // Add autocopy to (Note: Adding bcc for specific modules are also done from pages) if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc.=($addr_bcc?', ':'').$conf->global->MAIN_MAIL_AUTOCOPY_TO; + $this->addr_to = $to; + $this->addr_cc = $addr_cc; + $this->addr_bcc = $addr_bcc; + $this->reply_to = $replyto; + $this->addr_from = $from; + $this->subject = $subject; + $this->errors_to = $errors_to; + $this->deliveryreceipt = $deliveryreceipt; + $this->trackid = $trackid; + + if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) + { + $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO; + $this->addr_cc = ''; + $this->addr_bcc = ''; + } + // Action according to choosed sending method if ($this->sendmode == 'mail') { @@ -254,16 +271,6 @@ class CMailFile $files_encoded = ""; // Define smtp_headers - $this->subject = $subject; - $this->addr_from = $from; - $this->reply_to = $replyto; - $this->errors_to = $errors_to; - $this->addr_to = $to; - $this->addr_cc = $addr_cc; - $this->addr_bcc = $addr_bcc; - $this->deliveryreceipt = $deliveryreceipt; - $this->trackid = $trackid; - $smtp_headers = $this->write_smtpheaders(); if (! empty($moreinheader)) $smtp_headers.=$moreinheader; // $moreinheader contains the \r\n @@ -311,11 +318,11 @@ class CMailFile $smtps = new SMTPs(); $smtps->setCharSet($conf->file->character_set_client); - $smtps->setSubject($this->encodetorfc2822($subject)); - $smtps->setTO($this->getValidAddress($to, 0, 1)); - $smtps->setFrom($this->getValidAddress($from, 0, 1)); - $smtps->setTrackId($trackid); - $smtps->setReplyTo($this->getValidAddress($replyto, 0, 1)); + $smtps->setSubject($this->encodetorfc2822($this->subject)); + $smtps->setTO($this->getValidAddress($this->addr_to, 0, 1)); + $smtps->setFrom($this->getValidAddress($this->addr_from, 0, 1)); + $smtps->setTrackId($this->trackid); + $smtps->setReplyTo($this->getValidAddress($this->reply_to, 0, 1)); if (! empty($moreinheader)) $smtps->setMoreInHeader($moreinheader); @@ -353,10 +360,10 @@ class CMailFile } } - $smtps->setCC($addr_cc); - $smtps->setBCC($addr_bcc); - $smtps->setErrorsTo($errors_to); - $smtps->setDeliveryReceipt($deliveryreceipt); + $smtps->setCC($this->addr_cc); + $smtps->setBCC($this->addr_bcc); + $smtps->setErrorsTo($this->errors_to); + $smtps->setDeliveryReceipt($this->deliveryreceipt); $this->smtps=$smtps; } @@ -378,8 +385,8 @@ class CMailFile //$this->message = new Swift_SignedMessage(); // Adding a trackid header to a message $headers = $this->message->getHeaders(); - $headers->addTextHeader('X-Dolibarr-TRACKID', $trackid . '@' . $host); - $headerID = time() . '.swiftmailer-dolibarr-' . $trackid . '@' . $host; + $headers->addTextHeader('X-Dolibarr-TRACKID', $this->trackid . '@' . $host); + $headerID = time() . '.swiftmailer-dolibarr-' . $this->trackid . '@' . $host; $msgid = $headers->get('Message-ID'); $msgid->setId($headerID); $headers->addIdHeader('References', $headerID); @@ -387,33 +394,33 @@ class CMailFile // Give the message a subject try { - $result = $this->message->setSubject($subject); + $result = $this->message->setSubject($this->subject); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } // Set the From address with an associative array //$this->message->setFrom(array('john@doe.com' => 'John Doe')); - if (! empty($from)) { + if (! empty($this->addr_from)) { try { - $result = $this->message->setFrom($this->getArrayAddress($from)); + $result = $this->message->setFrom($this->getArrayAddress($this->addr_from)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } } // Set the To addresses with an associative array - if (! empty($to)) { + if (! empty($this->addr_to)) { try { - $result = $this->message->setTo($this->getArrayAddress($to)); + $result = $this->message->setTo($this->getArrayAddress($this->addr_to)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } } - if (! empty($replyto)) { + if (! empty($this->reply_to)) { try { - $result = $this->message->SetReplyTo($this->getArrayAddress($replyto)); + $result = $this->message->SetReplyTo($this->getArrayAddress($this->reply_to)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } @@ -467,10 +474,10 @@ class CMailFile } } - if (! empty($addr_cc)) $this->message->setCc($this->getArrayAddress($addr_cc)); - if (! empty($addr_bcc)) $this->message->setBcc($this->getArrayAddress($addr_bcc)); + if (! empty($this->addr_cc)) $this->message->setCc($this->getArrayAddress($this->addr_cc)); + if (! empty($this->addr_bcc)) $this->message->setBcc($this->getArrayAddress($this->addr_bcc)); //if (! empty($errors_to)) $this->message->setErrorsTo($this->getArrayAddress($errors_to); - if (isset($deliveryreceipt) && $deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($from)); + if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($this->addr_from)); } else { @@ -589,13 +596,6 @@ class CMailFile $keyforstarttls ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING'; } - if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) - { - $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO; - $this->addr_cc = ''; - $this->addr_bcc = ''; - } - // Action according to choosed sending method if ($this->sendmode == 'mail') { From c6ee80eefd2f85e34b66432e8f2869ffb2dd4380 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 12:29:57 +0200 Subject: [PATCH 87/97] FIX Disable svg as supported image by default. Set MAIN_ALLOW_SVG_FILES_AS_IMAGES to 1 to have svg working. --- htdocs/bookmarks/card.php | 1 + htdocs/bookmarks/list.php | 2 +- htdocs/core/lib/images.lib.php | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 385dd506031..411c2c8175f 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -151,6 +151,7 @@ if ($action == 'create') print ''."\n"; print ''; print ''; + print ''; print load_fiche_titre($langs->trans("NewBookmark")); diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php index 5dd1718b263..1cc6029dbc9 100644 --- a/htdocs/bookmarks/list.php +++ b/htdocs/bookmarks/list.php @@ -158,7 +158,7 @@ print ''; print ''; $newcardbutton = ''; -$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create', '', !empty($user->rights->bookmark->creer)); +$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create&backtopage='.urlencode(DOL_URL_ROOT.'/bookmarks/list.php'), '', !empty($user->rights->bookmark->creer)); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bookmark', 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index b65ad51db86..13918b908ad 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -37,7 +37,12 @@ $quality = 80; */ function image_format_supported($file) { - $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm|\.svg'; // See also into product.class.php + global $conf; + + $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into product.class.php + if (! empty($conf->global->MAIN_ALLOW_PREVIEW_OF_UPLOADED_SVG_FILES)) { + $regeximgext .= '|\.svg'; // Not allowed by default. SVG can contains javascript + } // Case filename is not a format image $reg = array(); From c2b03e49e13849f1fa7ba9e7749d893d39da09e6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 17:28:57 +0200 Subject: [PATCH 88/97] Fix logo not visible in setup page --- htdocs/admin/company.php | 31 +++++++++++++++++++++++-------- htdocs/core/lib/images.lib.php | 5 +++-- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index d7761557f22..6268148fdb5 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -494,10 +494,17 @@ if (!empty($mysoc->logo_mini)) { print ''; } print ''; -} else { - print '
'; - print ''; - print '
'; +} elseif (!empty($mysoc->logo)) { + if (file_exists($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) { + print '
'; + print ''; + print '
'; + print ''; + } else { + print '
'; + print ''; + print '
'; + } } print ''; print ''; @@ -514,10 +521,18 @@ if (!empty($mysoc->logo_squarred_mini)) { print ''; } print ''; -} else { - print '
'; - print ''; - print '
'; +} elseif (!empty($mysoc->logo_squarred)) { + if (file_exists($conf->mycompany->dir_output.'/logos/'.$mysoc->logo_squarred)) { + print '
'; + print ''; + print '
'; + print ''; + } + else { + print '
'; + print ''; + print '
'; + } } print ''; print ''; diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index 13918b908ad..0822d3edd4b 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -33,14 +33,15 @@ $quality = 80; * Return if a filename is file name of a supported image format * * @param string $file Filename + * @param int $acceptsvg 0=Default (depends on setup), 1=Always accept SVG as image files * @return int -1=Not image filename, 0=Image filename but format not supported for conversion by PHP, 1=Image filename with format supported by this PHP */ -function image_format_supported($file) +function image_format_supported($file, $acceptsvg = 0) { global $conf; $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into product.class.php - if (! empty($conf->global->MAIN_ALLOW_PREVIEW_OF_UPLOADED_SVG_FILES)) { + if ($acceptsvg || ! empty($conf->global->MAIN_ALLOW_SVG_FILES_AS_IMAGES)) { $regeximgext .= '|\.svg'; // Not allowed by default. SVG can contains javascript } From 582ae36e6cbe925b8467ccabc09f752a2d68d6b6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 17:30:13 +0200 Subject: [PATCH 89/97] Doc --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 1144f11726f..6ee67b86faa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -50,6 +50,7 @@ FIX: Warning if no bank account defined FIX: We need to see unit line on PDF even though it's an option FIX: wrong element var for fetch_name_optionals_label function with expeditions FIX: wrong link to third invoice templates +FIX: Disable svg as supported image by default (can contains javascript). Set MAIN_ALLOW_SVG_FILES_AS_IMAGES to 1 to have svg accepted FIX: #14076 FIX: #14146 FIX: #14209 From 61e194bb6dffd73182f79b845a228d24aac44d89 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 17:37:00 +0200 Subject: [PATCH 90/97] Add protection to allow only jpg and png as image file --- htdocs/admin/company.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 6268148fdb5..6330909f2c0 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -111,6 +111,12 @@ if (($action == 'update' && !GETPOST("cancel", 'alpha')) foreach ($arrayofimages as $varforimage) { + if (! preg_match('/(\.jpeg|\.jpg|\.png)$/i', $_FILES[$varforimage]["tmp_name"])) { // Logo can be used on a lot of different places. Only jpg and png can be supported. + $langs->load("errors"); + setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors'); + break; + } + if ($_FILES[$varforimage]["tmp_name"]) { $reg = array(); From edd19419ad73dc5e82407c3da6df83c8633bfe2c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 17:39:36 +0200 Subject: [PATCH 91/97] Add protection to allow only jpg and png as image file --- htdocs/admin/company.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 6330909f2c0..88f6034a3b6 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -111,7 +111,7 @@ if (($action == 'update' && !GETPOST("cancel", 'alpha')) foreach ($arrayofimages as $varforimage) { - if (! preg_match('/(\.jpeg|\.jpg|\.png)$/i', $_FILES[$varforimage]["tmp_name"])) { // Logo can be used on a lot of different places. Only jpg and png can be supported. + if ($_FILES[$varforimage]["name"] && ! preg_match('/(\.jpeg|\.jpg|\.png)$/i', $_FILES[$varforimage]["name"])) { // Logo can be used on a lot of different places. Only jpg and png can be supported. $langs->load("errors"); setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors'); break; From 20ea6d86d81494c4a251f05bf8da470f1ff2eb46 Mon Sep 17 00:00:00 2001 From: Egils Consulting Date: Thu, 6 Aug 2020 19:57:31 +0200 Subject: [PATCH 92/97] Update api_supplier_orders.class.php Added example of creating a supplier order --- htdocs/fourn/class/api_supplier_orders.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index bee6346386b..b180016bdd9 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -187,6 +187,8 @@ class SupplierOrders extends DolibarrApi /** * Create supplier order object * + * Example: {"ref": "auto", "ref_supplier": "1234", "socid": "1", "multicurrency_code": "SEK", "multicurrency_tx": 1, "tva_tx": 25, "note": "Imported via the REST API"} + * * @param array $request_data Request datas * @return int ID of supplier order */ From 9c254159ab8dad8477c1814beaaf2f6c54d30c4b Mon Sep 17 00:00:00 2001 From: Egils Consulting Date: Fri, 7 Aug 2020 00:06:48 +0200 Subject: [PATCH 93/97] Update api_products.class.php fixes #14309 Throw 400 and add hint to user about using the right endpoint. --- htdocs/product/class/api_products.class.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 1f4bbf870f3..89c9a78ddaa 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -286,6 +286,9 @@ class Products extends DolibarrApi foreach ($request_data as $field => $value) { if ($field == 'id') { continue; + } + if ($field == 'stock_reel') { + throw new RestException(400, 'Stock reel cannot be updated here. Use the /stockmovements endpoint instead'); } $this->product->$field = $value; } From 8b69dd1384f9e82a5aecb61730d1f080f8c14b21 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 09:50:15 +0200 Subject: [PATCH 94/97] Increase length of default password. --- .../modules/security/generate/modGeneratePassStandard.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php index 3a1cf3667aa..23b71244cbd 100644 --- a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php +++ b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php @@ -59,7 +59,7 @@ class modGeneratePassStandard extends ModeleGenPassword public function __construct($db, $conf, $langs, $user) { $this->id = "standard"; - $this->length = 8; + $this->length = 10; $this->db = $db; $this->conf = $conf; From 022fb23cee5806d0426fcdc1bae4531c999a3604 Mon Sep 17 00:00:00 2001 From: "jove@bisquerra.com" Date: Thu, 6 Aug 2020 07:32:28 +0200 Subject: [PATCH 95/97] FIX: Get some taxes in TakePOS --- htdocs/takepos/invoice.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index a3ef12c92cb..d22d2702571 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -341,6 +341,7 @@ if ($action == "addline") } } if ($idoflineadded <= 0) { + $invoice->fetch_thirdparty(); $idoflineadded = $invoice->addline($prod->description, $price, 1, $tva_tx, $localtax1_tx, $localtax2_tx, $idproduct, $customer->remise_percent, '', 0, 0, 0, '', $price_base_type, $price_ttc, $prod->type, -1, 0, '', 0, $parent_line, null, '', '', 0, 100, '', null, 0); } From c52c4229c563f69acfc9936aa087abb51765fcfc Mon Sep 17 00:00:00 2001 From: Egils Consulting Date: Tue, 4 Aug 2020 22:02:15 +0200 Subject: [PATCH 96/97] Update api_supplier_invoices.class.php fixes #14831 --- htdocs/fourn/class/api_supplier_invoices.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 1f20965fab3..f5b3afa4b18 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -454,7 +454,7 @@ class SupplierInvoices extends DolibarrApi $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching $paiement->paiementid = $paiementid; - $paiement->paiementcode = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->oper = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); $paiement->num_payment = $num_payment; $paiement->note_public = $comment; From ed6acfa1e76307c6a30ac7188326b89f269caa02 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 11:45:15 +0200 Subject: [PATCH 97/97] Better compatibility --- htdocs/fourn/class/api_supplier_invoices.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index f5b3afa4b18..b42c578a783 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -454,7 +454,8 @@ class SupplierInvoices extends DolibarrApi $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching $paiement->paiementid = $paiementid; - $paiement->oper = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->paiementcode = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->oper = $paiement->paiementcode; // For backward compatibility $paiement->num_payment = $num_payment; $paiement->note_public = $comment;