diff --git a/dev/resources/iso-normes/QR code for invoices.txt b/dev/resources/iso-normes/QR code for invoices.txt index a55c9569297..f03351f453f 100644 --- a/dev/resources/iso-normes/QR code for invoices.txt +++ b/dev/resources/iso-normes/QR code for invoices.txt @@ -8,6 +8,10 @@ https://en.wikipedia.org/wiki/EPC_QR_code#Generators -* For ZATCA QR Code format (Saudi Arabia) ------------------------------------------ +* For ZATCA QR Code format (Saudi Arabia). Used when INVOICE_ADD_ZATCA_QR_CODE is set +------------------------------------------------------------------------------------- https://www.pwc.com/m1/en/services/tax/me-tax-legal-news/2021/saudi-arabia-guide-to-develop-compliant-qr-code-for-simplified-einvoices.html + +https://www.tecklenborgh.com/post/ksa-zatca-publishes-guide-on-how-to-develop-a-fatoora-compliant-qr-code + +Method to encode/decode ZATCA string is available in test/phpunit/BarcodeTest.php diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php index 6fad266ea36..d30e851b9a2 100644 --- a/htdocs/adherents/class/api_members.class.php +++ b/htdocs/adherents/class/api_members.class.php @@ -358,7 +358,7 @@ class Members extends DolibarrApi if ($member->update(DolibarrApiAccess::$user) >= 0) { return $this->get($id); } else { - throw new RestException(500, $member->error); + throw new RestException(500, 'Error when updating member: '.$member->error); } } diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index be8f22f3c45..d95de755166 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -204,7 +204,7 @@ class MembersTypes extends DolibarrApi if ($membertype->update(DolibarrApiAccess::$user) >= 0) { return $this->get($id); } else { - throw new RestException(500, $membertype->error); + throw new RestException(500, 'Error when updating member type: '.$membertype->error); } } diff --git a/htdocs/adherents/class/api_subscriptions.class.php b/htdocs/adherents/class/api_subscriptions.class.php index 55b93df7663..f969017146b 100644 --- a/htdocs/adherents/class/api_subscriptions.class.php +++ b/htdocs/adherents/class/api_subscriptions.class.php @@ -159,7 +159,7 @@ class Subscriptions extends DolibarrApi $subscription->$field = $value; } if ($subscription->create(DolibarrApiAccess::$user) < 0) { - throw new RestException(500, 'Error when creating subscription', array_merge(array($subscription->error), $subscription->errors)); + throw new RestException(500, 'Error when creating contribution', array_merge(array($subscription->error), $subscription->errors)); } return $subscription->id; } @@ -193,7 +193,7 @@ class Subscriptions extends DolibarrApi if ($subscription->update(DolibarrApiAccess::$user) > 0) { return $this->get($id); } else { - throw new RestException(500, $subscription->error); + throw new RestException(500, 'Error when updating contribution: '.$subscription->error); } } diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 6ed3bd00863..36136aeef24 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -214,10 +214,6 @@ if (in_array($type, array('mysql', 'mysqli'))) { print '
'; print '
'.$langs->trans("ExportOptions").''; - print '
'; - print ''; - print ''; - print '
'; if (!empty($conf->global->MYSQL_OLD_OPTION_DISABLE_FK)) { print '
'; @@ -239,14 +235,35 @@ if (in_array($type, array('mysql', 'mysqli'))) { print ''; print ''; print ''; - print '
'; + print '

'; - print ''; + print '
'; + print ''; + print ''; + print '
'; + + print ''; print ''; print '
'; + $execmethod = 0; + if (!empty($conf->global->MAIN_EXEC_USE_POPEN)) { + $execmethod = $conf->global->MAIN_EXEC_USE_POPEN; + } + if (empty($execmethod)) { + $execmethod = 1; + } + if ($execmethod == 1) { + // If we use the "exec" method for shell, we ask if we need to use the alternative low memory exec mode. + print ''; + print ''; + print '
'; + } + print ''; diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 28dbef6887e..da49e4cbba7 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -126,7 +126,7 @@ class Documents extends DolibarrApi * @param string $langcode Language code like 'en_US', 'fr_FR', 'es_ES', ... (If not set, use the default language). * @return array List of documents * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 501 * @throws RestException 400 * @throws RestException 401 @@ -249,7 +249,7 @@ class Documents extends DolibarrApi * @throws RestException 400 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @url GET / */ @@ -546,7 +546,7 @@ class Documents extends DolibarrApi * @throws RestException 400 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @url POST /upload */ diff --git a/htdocs/api/index.php b/htdocs/api/index.php index d5bc7e273e2..c66573e8022 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -158,6 +158,25 @@ if (!empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $ $api = new DolibarrApi($db, '', $refreshcache); //var_dump($api->r->apiVersionMap); +// If MAIN_API_DEBUG is set to 1, we save logs into file "dolibarr_api.log" +if (!empty($conf->global->MAIN_API_DEBUG)) { + $r = $api->r; + $r->onCall(function () use ($r) { + // Don't log Luracast Restler Explorer recources calls + //if (!preg_match('/^explorer/', $r->url)) { + // 'method' => $api->r->requestMethod, + // 'url' => $api->r->url, + // 'route' => $api->r->apiMethodInfo->className.'::'.$api->r->apiMethodInfo->methodName, + // 'version' => $api->r->getRequestedApiVersion(), + // 'data' => $api->r->getRequestData(), + //dol_syslog("Debug API input ".var_export($r, true), LOG_DEBUG, 0, '_api'); + dol_syslog("Debug API url ".var_export($r->url, true), LOG_DEBUG, 0, '_api'); + dol_syslog("Debug API input ".var_export($r->getRequestData(), true), LOG_DEBUG, 0, '_api'); + //} + }); +} + + // Enable the Restler API Explorer. // See https://github.com/Luracast/Restler-API-Explorer for more info. $api->r->addAPIClass('Luracast\\Restler\\Explorer'); diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 4a00894d26b..1d084c915d8 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1491,6 +1491,10 @@ if ($id > 0) { $("#fullday").change(function() { setdatefields(); }); + $("#actioncode").change(function() { + if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired"); + else $("#dateend").removeClass("fieldrequired"); + }); })'; print ''."\n"; } @@ -1535,7 +1539,11 @@ if ($id > 0) { print ''.$langs->trans("EventOnFullDay").'fulldayevent ? ' checked' : '').'>'; // Date start - end - print ''.$langs->trans("DateActionStart").' - '.$langs->trans("DateActionEnd").''; + print ''; + print ''.$langs->trans("DateActionStart").''; + print ' - '; + print 'type_code == 'AC_RDV' ? ' class="fieldrequired"' : '').'>'.$langs->trans("DateActionEnd").''; + print ''; $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT'); if (GETPOST("afaire") == 1) { print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 0, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuser') : 'tzuser'); diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 61ecb966359..76a5c92b4cd 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -246,8 +246,11 @@ if (empty($reshook)) { // Remove line $result = $object->deleteline($lineid); // reorder lines - if ($result) { + if ($result > 0) { $object->line_order(true); + } else { + $langs->load("errors"); + setEventMessages($object->error, $object->errors, 'errors'); } if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index f03d66bae54..59a03f78bb2 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -625,7 +625,7 @@ class Proposals extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function deleteContact($id, $contactid, $type) { @@ -799,7 +799,7 @@ class Proposals extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @return array */ diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 6a6031c3a99..e7c1f520949 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -992,6 +992,8 @@ class Propal extends CommonObject $this->db->commit(); return 1; } else { + $this->error = $line->error; + $this->errors = $line->errors; $this->db->rollback(); return -1; } @@ -4194,36 +4196,40 @@ class PropaleLigne extends CommonObjectLine $error = 0; $this->db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE rowid = ".((int) $this->rowid); - dol_syslog("PropaleLigne::delete", LOG_DEBUG); - if ($this->db->query($sql)) { - // Remove extrafields - if (!$error) { - $this->id = $this->rowid; - $result = $this->deleteExtraFields(); - if ($result < 0) { - $error++; - dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); - } + if (!$notrigger) { + // Call trigger + $result = $this->call_trigger('LINEPROPAL_DELETE', $user); + if ($result < 0) { + $error++; } + } + // End call triggers - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('LINEPROPAL_DELETE', $user); - if ($result < 0) { - $this->db->rollback(); - return -1; + if (!$error) { + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "propaldet WHERE rowid = " . ((int) $this->rowid); + dol_syslog("PropaleLigne::delete", LOG_DEBUG); + if ($this->db->query($sql)) { + // Remove extrafields + if (!$error) { + $this->id = $this->rowid; + $result = $this->deleteExtraFields(); + if ($result < 0) { + $error++; + dol_syslog(get_class($this) . "::delete error -4 " . $this->error, LOG_ERR); + } } + } else { + $this->error = $this->db->error() . " sql=" . $sql; + $error++; } - // End call triggers + } - $this->db->commit(); - - return 1; - } else { - $this->error = $this->db->error()." sql=".$sql; + if ($error) { $this->db->rollback(); return -1; + } else { + $this->db->commit(); + return 1; } } diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 48865f958a2..fb912139d5f 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -574,7 +574,7 @@ class Orders extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function deleteContact($id, $contactid, $type) { @@ -704,7 +704,7 @@ class Orders extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @return array */ @@ -974,7 +974,7 @@ class Orders extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function getOrderShipments($id) { @@ -1030,7 +1030,7 @@ class Orders extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function createOrderShipment($id, $warehouse_id) { diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index a73b4fb597f..551edb05731 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -519,7 +519,7 @@ class Invoices extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function deleteContact($id, $contactid, $type) { @@ -661,7 +661,7 @@ class Invoices extends DolibarrApi $result = $this->invoice->delete(DolibarrApiAccess::$user); if ($result < 0) { - throw new RestException(500); + throw new RestException(500, 'Error when deleting invoice'); } return array( @@ -780,7 +780,7 @@ class Invoices extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * */ public function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger = 0) @@ -829,7 +829,7 @@ class Invoices extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * */ public function settodraft($id, $idwarehouse = -1) @@ -932,7 +932,7 @@ class Invoices extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function settopaid($id, $close_code = '', $close_note = '') { @@ -982,7 +982,7 @@ class Invoices extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function settounpaid($id) { @@ -1069,7 +1069,7 @@ class Invoices extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function markAsCreditAvailable($id) { diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 4e4437c1b2c..c9341d23ee3 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2750,8 +2750,8 @@ class ContratLigne extends CommonObjectLine //'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115), //'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>120), //'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>125), - 'fk_user_ouverture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserOpen', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), - 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserCloture', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), + 'fk_user_ouverture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserStartingService', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), + 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosingService', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 4=>'Open', 5=>'Closed')) ); // END MODULEBUILDER PROPERTIES diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index e6446e3585b..55bd7071ee8 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -350,25 +350,43 @@ if ($search_dfyear > 0 && $search_op2df) { $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."' AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; } } -$sql .= $db->order($sortfield, $sortorder); - -$totalnboflines = 0; -$result = $db->query($sql); -if ($result) { - $totalnboflines = $db->num_rows($result); -} $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + //$result = $db->query($sql); + //$nbtotalofrecords = $db->num_rows($result); + + if ($search_dfyear > 0 && $search_op2df) { + $resql = $db->query($sql, 0, 'auto', 1); + while ($db->fetch_object($resql)) { + if (empty($nbtotalofrecords)) { + $nbtotalofrecords = 1; // We can't make +1 because init value is '' + } else { + $nbtotalofrecords++; + } + } + } else { + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/LEFT JOIN '.MAIN_DB_PREFIX.'contratdet as cd ON c.rowid = cd.fk_contrat/', '', $sqlforcount); + $sqlforcount = preg_replace('/LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product=cd.fk_product/', '', $sqlforcount); + $sqlforcount = preg_replace('/AND cp.fk_categorie = '.((int) $search_product_category).'/', '', $sqlforcount); + $sqlforcount = preg_replace('/GROUP BY.*$/', '', $sqlforcount); + + $resql = $db->query($sqlforcount); + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } } -$sql .= $db->plimit($limit + 1, $offset); +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} $resql = $db->query($sql); if (!$resql) { @@ -508,7 +526,7 @@ print ''; print ''; print ''; -print_barre_liste($langs->trans("ListOfContracts"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $totalnboflines, 'contract', 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($langs->trans("ListOfContracts"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'contract', 0, $newcardbutton, '', $limit, 0, 0, 1); $topicmail = "SendContractRef"; $modelmail = "contract"; diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 29fd230a61b..eedc1b2fa10 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -827,8 +827,10 @@ abstract class CommonInvoice extends CommonObject $tmplang->load("main"); $datestring = dol_print_date($this->date, 'dayhourrfc'); - $pricewithtaxstring = price($this->total_ttc, 0, $tmplang, 0, -1, 2); - $pricetaxstring = price($this->total_tva, 0, $tmplang, 0, -1, 2); + //$pricewithtaxstring = price($this->total_ttc, 0, $tmplang, 0, -1, 2); + //$pricetaxstring = price($this->total_tva, 0, $tmplang, 0, -1, 2); + $pricewithtaxstring = price2num($this->total_ttc, 2, 1); + $pricetaxstring = price2num($this->total_tva, 2, 1); /* $name = implode(unpack("H*", $this->thirdparty->name)); @@ -857,7 +859,7 @@ abstract class CommonInvoice extends CommonObject // Using TLV format $s = pack('C1', 1).pack('C1', strlen($this->thirdparty->name)).$this->thirdparty->name; $s .= pack('C1', 2).pack('C1', strlen($this->thirdparty->tva_intra)).$this->thirdparty->tva_intra; - $s .= pack('C1', 3).pack('C1', strlen($datestring)).$this->date; + $s .= pack('C1', 3).pack('C1', strlen($datestring)).$datestring; $s .= pack('C1', 4).pack('C1', strlen($pricewithtaxstring)).$pricewithtaxstring; $s .= pack('C1', 5).pack('C1', strlen($pricetaxstring)).$pricetaxstring; $s .= ''; // Hash of xml invoice diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 7939965828a..bdc5e746566 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -54,12 +54,21 @@ class DiscountAbsolute public $fk_soc; public $discount_type; // 0 => customer discount, 1 => supplier discount - public $amount_ht; // - public $amount_tva; // - public $amount_ttc; // - public $multicurrency_amount_ht; - public $multicurrency_amount_tva; - public $multicurrency_amount_ttc; + + public $total_ht; + public $total_tva; + public $total_ttc; + public $amount_ht; // deprecated + public $amount_tva; // deprecated + public $amount_ttc; // deprecated + + public $multicurrency_total_ht; + public $multicurrency_total_tva; + public $multicurrency_total_ttc; + public $multicurrency_amount_ht; // deprecated + public $multicurrency_amount_tva; // deprecated + public $multicurrency_amount_ttc; // deprecated + // Vat rate public $tva_tx; public $vat_src_code; @@ -163,13 +172,21 @@ class DiscountAbsolute $this->fk_soc = $obj->fk_soc; $this->discount_type = $obj->discount_type; - $this->amount_ht = $obj->amount_ht; - $this->amount_tva = $obj->amount_tva; - $this->amount_ttc = $obj->amount_ttc; + $this->total_ht = $obj->amount_ht; + $this->total_tva = $obj->amount_tva; + $this->total_ttc = $obj->amount_ttc; + // For backward compatibility + $this->amount_ht = $this->total_ht; + $this->amount_tva = $this->total_tva; + $this->amount_ttc = $this->total_ttc; - $this->multicurrency_amount_ht = $this->multicurrency_subprice = $obj->multicurrency_amount_ht; - $this->multicurrency_amount_tva = $obj->multicurrency_amount_tva; - $this->multicurrency_amount_ttc = $obj->multicurrency_amount_ttc; + $this->multicurrency_total_ht = $this->multicurrency_subprice = $obj->multicurrency_amount_ht; + $this->multicurrency_total_tva = $obj->multicurrency_amount_tva; + $this->multicurrency_total_ttc = $obj->multicurrency_amount_ttc; + // For backward compatibility + $this->multicurrency_amount_ht = $this->multicurrency_total_ht; + $this->multicurrency_amount_tva = $this->multicurrency_total_tva; + $this->multicurrency_amount_ttc = $this->multicurrency_total_ttc; $this->tva_tx = $obj->tva_tx; $this->vat_src_code = $obj->vat_src_code; diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 4a2e65ba1f3..23c04a98a81 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -193,10 +193,10 @@ class DolEditor removePlugins : \''.$pluginstodisable.'\', readOnly : '.($this->readonly ? 'true' : 'false').', htmlEncodeOutput :'.$htmlencode_force.', - allowedContent :'.($disallowAnyContent ? 'false' : 'true').', - extraAllowedContent : \'a[target];div{float,display}\', /* Add the style float and display into div to default other allowed tags */ - disallowedContent : '.($disallowAnyContent ? '\'\'' : '\'\'').', - fullPage : '.($fullpage ? 'true' : 'false').', + allowedContent :'.($disallowAnyContent ? 'false' : 'true').', /* Advanced Content Filter (ACF) is own when allowedContent is false */ + extraAllowedContent : \'a[target];div{float,display}\', /* Add the style float and display into div to default other allowed tags */ + disallowedContent : '.($disallowAnyContent ? '\'\'' : '\'\'').', /* Tags that are not allowed */ + fullPage : '.($fullpage ? 'true' : 'false').', /* if true, the html, header and body tags are kept */ toolbar: \''.$this->toolbarname.'\', toolbarStartupExpanded: '.($this->toolbarstartexpanded ? 'true' : 'false').', width: '.($this->width ? '\''.$this->width.'\'' : '\'\'').', diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index f59b248a384..4a4db439822 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -189,7 +189,7 @@ class Utils * @param int $usedefault 1=Use default backup profile (Set this to 1 when used as cron) * @param string $file 'auto' or filename to build * @param int $keeplastnfiles Keep only last n files (not used yet) - * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method + * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec' - need size of dump in memory, but low memory method is used if GETPOST('lowmemorydump') is set, 2=Use the 'popen' method (low memory method) * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) */ public function dumpDatabase($compression = 'none', $type = 'auto', $usedefault = 1, $file = 'auto', $keeplastnfiles = 0, $execmethod = 0) @@ -278,8 +278,8 @@ class Utils if (!empty($dolibarr_main_db_port)) { $param .= " -P ".$dolibarr_main_db_port; } - if (!GETPOST("use_transaction", "alpha")) { - $param .= " -l --single-transaction"; + if (GETPOST("use_transaction", "alpha")) { + $param .= " --single-transaction"; } if (GETPOST("disable_fk", "alpha") || $usedefault) { $param .= " -K"; @@ -342,17 +342,42 @@ class Utils $handle = ''; + $lowmemorydump = GETPOSTISSET("lowmemorydump", "alpha") ? GETPOST("lowmemorydump") : getDolGlobalString('MAIN_LOW_MEMORY_DUMP'); + // Start call method to execute dump $fullcommandcrypted = $command." ".$paramcrypted." 2>&1"; $fullcommandclear = $command." ".$paramclear." 2>&1"; - if ($compression == 'none') { - $handle = fopen($outputfile, 'w'); - } elseif ($compression == 'gz') { - $handle = gzopen($outputfile, 'w'); - } elseif ($compression == 'bz') { - $handle = bzopen($outputfile, 'w'); - } elseif ($compression == 'zstd') { - $handle = fopen($outputfile, 'w'); + if (!$lowmemorydump) { + if ($compression == 'none') { + $handle = fopen($outputfile, 'w'); + } elseif ($compression == 'gz') { + $handle = gzopen($outputfile, 'w'); + } elseif ($compression == 'bz') { + $handle = bzopen($outputfile, 'w'); + } elseif ($compression == 'zstd') { + $handle = fopen($outputfile, 'w'); + } + } else { + if ($compression == 'none') { + $fullcommandclear .= " > ".$outputfile; + $fullcommandcrypted .= " > ".$outputfile; + $handle = 1; + } elseif ($compression == 'gz') { + $fullcommandclear .= " | gzip > ".$outputfile; + $fullcommandcrypted .= " | gzip > ".$outputfile; + $paramcrypted.=" | gzip"; + $handle = 1; + } elseif ($compression == 'bz') { + $fullcommandclear .= " | bzip2 > ".$outputfile; + $fullcommandcrypted .= " | bzip2 > ".$outputfile; + $paramcrypted.=" | bzip2"; + $handle = 1; + } elseif ($compression == 'zstd') { + $fullcommandclear .= " | zstd > ".$outputfile; + $fullcommandcrypted .= " | zstd > ".$outputfile; + $paramcrypted.=" | zstd"; + $handle = 1; + } } $ok = 0; @@ -374,7 +399,8 @@ class Utils } - // TODO Replace with executeCLI function + // TODO Replace with executeCLI function but + // we must first introduce a low memory mode if ($execmethod == 1) { $output_arr = array(); $retval = null; @@ -394,16 +420,23 @@ class Utils if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) { continue; } - fwrite($handle, $read.($execmethod == 2 ? '' : "\n")); - if (preg_match('/'.preg_quote('-- Dump completed', '/').'/i', $read)) { - $ok = 1; - } elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES', '/').'/i', $read)) { - $ok = 1; + if (!$lowmemorydump) { + fwrite($handle, $read.($execmethod == 2 ? '' : "\n")); + if (preg_match('/'.preg_quote('-- Dump completed', '/').'/i', $read)) { + $ok = 1; + } elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES', '/').'/i', $read)) { + $ok = 1; + } + } else { + // If we have a result here in lowmemorydump mode, something is strange } } + } elseif ($lowmemorydump) { + $ok = 1; } } } + if ($execmethod == 2) { // With this method, there is no way to get the return code, only output $handlein = popen($fullcommandclear, 'r'); $i = 0; diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php index 7331b08e13e..ec0ce330dc4 100644 --- a/htdocs/core/customreports.php +++ b/htdocs/core/customreports.php @@ -556,9 +556,26 @@ if (!empty($search_measures) && !empty($search_xaxis)) { $sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')'; } } + + // Add INNER JOIN for all parent tables + //var_dump($arrayofxaxis); var_dump($search_xaxis); + $listoftablesalreadyadded = array($object->table_element => $object->table_element); + foreach ($search_xaxis as $key => $val) { + if (!empty($arrayofxaxis[$val])) { + $tmpval = explode('.', $val); + //var_dump($arrayofxaxis[$val]['table']); + if (! in_array($arrayofxaxis[$val]['table'], $listoftablesalreadyadded)) { // We do not add join for main table already added + $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.$arrayofxaxis[$val]['table'].' as '.$tmpval[0]; + $listoftablesalreadyadded[$arrayofxaxis[$val]['table']] = $arrayofxaxis[$val]['table']; + } + } else { + dol_print_error($db, 'Found an key into search_xaxis not found into arrayofxaxis'); + } + } + $sql .= ' WHERE 1 = 1'; if ($object->ismultientitymanaged == 1) { - $sql .= ' AND entity IN ('.getEntity($object->element).')'; + $sql .= ' AND t.entity IN ('.getEntity($object->element).')'; } // Add the where here $sqlfilters = $search_component_params_hidden; @@ -914,7 +931,7 @@ function fillArrayOfMeasures($object, $tablealias, $labelofobject, &$arrayofmesu * Fill arrayofmesures for an object * * @param mixed $object Any object - * @param string $tablealias Alias of table + * @param string $tablealias Alias of table ('t' for example) * @param string $labelofobject Label of object * @param array $arrayofxaxis Array of xaxis already filled * @param int $level Level @@ -964,14 +981,31 @@ function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis, continue; } if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) { - $arrayofxaxis[$tablealias.'.'.$key.'-year'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.')', 'position' => ($val['position']+($count * 100000)).'.1'); - $arrayofxaxis[$tablealias.'.'.$key.'-month'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', 'position' => ($val['position']+($count * 100000)).'.2'); - $arrayofxaxis[$tablealias.'.'.$key.'-day'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', 'position' => ($val['position']+($count * 100000)).'.3'); + $arrayofxaxis[$tablealias.'.'.$key.'-year'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.')', + 'position' => ($val['position']+($count * 100000)).'.1', + 'table' => $object->table_element + ); + $arrayofxaxis[$tablealias.'.'.$key.'-month'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', + 'position' => ($val['position']+($count * 100000)).'.2', + 'table' => $object->table_element + ); + $arrayofxaxis[$tablealias.'.'.$key.'-day'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', + 'position' => ($val['position']+($count * 100000)).'.3', + 'table' => $object->table_element + ); } else { - $arrayofxaxis[$tablealias.'.'.$key] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']), 'position' => ($val['position']+($count * 100000))); + $arrayofxaxis[$tablealias.'.'.$key] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']), + 'position' => ($val['position']+($count * 100000)), + 'table' => $object->table_element + ); } } } + // Add extrafields to X-Axis if ($object->isextrafieldmanaged) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { @@ -981,9 +1015,14 @@ function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis, if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) { continue; } - $arrayofxaxis[$tablealias.'e.'.$key] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]), 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000)); + $arrayofxaxis[$tablealias.'e.'.$key] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]), + 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000), + 'table' => $object->table_element + ); } } + // Add fields for parent objects foreach ($object->fields as $key => $val) { if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) { @@ -993,10 +1032,7 @@ function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis, dol_include_once($tmptype[2]); if (class_exists($newobject)) { $tmpobject = new $newobject($db); - /*var_dump($val['label']); - var_dump($tmptype); - var_dump($arrayofmesures); - var_dump('t-'.$key);*/ + //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key); $count++; $arrayofxaxis = fillArrayOfXAxis($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofxaxis, $level + 1, $count); } else { diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index fa24e4a70ac..520fba66ce1 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -266,7 +266,7 @@ class DoliDBMysqli extends DoliDB * @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollback to savepoint if error (this allow to have some request with errors inside global transactions). * Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints. * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...) - * @param int $result_mode Result mode + * @param int $result_mode Result mode (Using 1=MYSQLI_USE_RESULT instead of 0=MYSQLI_STORE_RESULT will not buffer the result and save memory) * @return bool|mysqli_result Resultset of answer */ public function query($query, $usesavepoint = 0, $type = 'auto', $result_mode = 0) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index efe8d87ff86..6edc4cb2c3c 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -156,8 +156,8 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'name' => 'Products', 'link' => '/product/index.php?mainmenu=products&leftmenu=', 'title' => (!empty($conf->product->enabled) && !empty($conf->service->enabled)) - ? (array("TMenuProducts", " | ", "TMenuServices")) - : (!empty($conf->product->enabled) ? "TMenuProducts" : "TMenuServices"), + ? (array("TMenuProducts", " | ", "TMenuServices")) + : (!empty($conf->product->enabled) ? "TMenuProducts" : "TMenuServices"), 'level' => 0, 'enabled' => $showmode = isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal), 'target' => $atarget, @@ -232,7 +232,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = || !empty($conf->supplier_order->enabled) || !empty($conf->contrat->enabled) || !empty($conf->ficheinter->enabled) - ) ? 1 : 0, + ) ? 1 : 0, 'perms'=>(!empty($user->rights->propal->lire) || !empty($user->rights->commande->lire) || !empty($user->rights->supplier_proposal->lire) @@ -241,17 +241,17 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = || !empty($user->rights->supplier_order->lire) || !empty($user->rights->contrat->lire) || !empty($user->rights->ficheinter->lire) - ), + ), 'module'=>'propal|commande|supplier_proposal|supplier_order|contrat|ficheinter' ); $onlysupplierorder = !empty($user->rights->fournisseur->commande->lire) && - empty($user->rights->propal->lire) && - empty($user->rights->commande->lire) && - empty($user->rights->supplier_order->lire) && - empty($user->rights->supplier_proposal->lire) && - empty($user->rights->contrat->lire) && - empty($user->rights->ficheinter->lire); + empty($user->rights->propal->lire) && + empty($user->rights->commande->lire) && + empty($user->rights->supplier_order->lire) && + empty($user->rights->supplier_proposal->lire) && + empty($user->rights->contrat->lire) && + empty($user->rights->ficheinter->lire); $menu_arr[] = array( 'name' => 'Commercial', @@ -524,7 +524,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = $idsel, $classname, $newTabMenu[$i]['prefix'] - ); + ); } // Sort on position @@ -544,9 +544,9 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = if (!empty($mysoc->logo_squarred_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_squarred_mini)) { $urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_squarred_mini); /*} elseif (! empty($mysoc->logo_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) - { - $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_mini); - }*/ + { + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_mini); + }*/ } else { $urllogo = DOL_URL_ROOT.'/theme/dolibarr_512x512_white.png'; $logoContainerAdditionalClass = ''; @@ -798,7 +798,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM /* * Menu HRM - */ + */ if ($mainmenu == 'hrm') { get_left_menu_hrm($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } @@ -881,13 +881,13 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM // TODO Use the position property in menu_array to reorder the $menu_array //var_dump($menu_array); /*$new_menu_array = array(); - $level=0; $cusor=0; $position=0; - $nbentry = count($menu_array); - while (findNextEntryForLevel($menu_array, $cursor, $position, $level)) - { + $level=0; $cusor=0; $position=0; + $nbentry = count($menu_array); + while (findNextEntryForLevel($menu_array, $cursor, $position, $level)) + { - $cursor++; - }*/ + $cursor++; + }*/ // Show menu $invert = empty($conf->global->MAIN_MENU_INVERT) ? "" : "invert"; @@ -1046,11 +1046,11 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM /** * Get left Menu HOME * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of user * @return void */ function get_left_menu_home($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) @@ -1165,11 +1165,11 @@ function get_left_menu_home($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = /** * Get left Menu THIRDPARTIES * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_thridparties($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) @@ -1197,12 +1197,12 @@ function get_left_menu_thridparties($mainmenu, &$newmenu, $usemenuhider = 1, $le $langs->load("commercial"); $newmenu->add("/societe/list.php?type=p&leftmenu=prospects", $langs->trans("ListProspectsShort"), 2, $user->rights->societe->lire, '', $mainmenu, 'prospects'); /* no more required, there is a filter that can do more - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=-1", $langs->trans("LastProspectDoNotContact"), 2, $user->rights->societe->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=0", $langs->trans("LastProspectNeverContacted"), 2, $user->rights->societe->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=1", $langs->trans("LastProspectToContact"), 2, $user->rights->societe->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=2", $langs->trans("LastProspectContactInProcess"), 2, $user->rights->societe->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=3", $langs->trans("LastProspectContactDone"), 2, $user->rights->societe->lire); - */ + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=-1", $langs->trans("LastProspectDoNotContact"), 2, $user->rights->societe->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=0", $langs->trans("LastProspectNeverContacted"), 2, $user->rights->societe->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=1", $langs->trans("LastProspectToContact"), 2, $user->rights->societe->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=2", $langs->trans("LastProspectContactInProcess"), 2, $user->rights->societe->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=3", $langs->trans("LastProspectContactDone"), 2, $user->rights->societe->lire); + */ $newmenu->add("/societe/card.php?leftmenu=prospects&action=create&type=p", $langs->trans("MenuNewProspect"), 3, $user->rights->societe->creer); } @@ -1270,11 +1270,11 @@ function get_left_menu_thridparties($mainmenu, &$newmenu, $usemenuhider = 1, $le /** * Get left Menu COMMERCIAL (propal, commande, supplier_proposal, supplier_order, contrat, ficheinter) * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_commercial($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) @@ -1386,11 +1386,11 @@ function get_left_menu_commercial($mainmenu, &$newmenu, $usemenuhider = 1, $left /** * Get left COMPTA-FINANCIAL * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_billing($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) @@ -1567,17 +1567,17 @@ function get_left_menu_billing($mainmenu, &$newmenu, $usemenuhider = 1, $leftmen /** * Get left COMPTA-FINANCIAL (accountancy) * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user - * @param DB $db + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ -function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0, $db) +function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) { global $user, $conf, $langs; + global $db; if ($mainmenu == 'accountancy') { $langs->load("companies"); @@ -1679,7 +1679,7 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef if ($objp->nature == 3 && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled)) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_PURCHASES)) { - $nature = "purchases"; + $nature = "purchases"; } if ($objp->nature == 4 && !empty($conf->banque->enabled)) { $nature = "bank"; @@ -1697,7 +1697,7 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef $nature = "hasnew"; } - // To enable when page exists + // To enable when page exists if (empty($conf->global->ACCOUNTANCY_SHOW_DEVELOP_JOURNAL)) { if ($nature == 'hasnew' || $nature == 'inventory') { $nature = ''; @@ -1709,7 +1709,7 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef $journallabel = $langs->transnoentities($objp->label); // Labels in this table are set by loading llx_accounting_abc.sql. Label can be 'ACCOUNTING_SELL_JOURNAL', 'InventoryJournal', ... $newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal='.$objp->rowid, $journallabel, 2, $user->rights->accounting->comptarapport->lire); } - $i++; + $i++; } } else { // Should not happend. Entries are added @@ -1815,17 +1815,17 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef $newmenu->add("/compta/resultat/index.php?leftmenu=report", $langs->trans("MenuReportInOut"), 1, $user->rights->compta->resultat->lire); $newmenu->add("/compta/resultat/clientfourn.php?leftmenu=report", $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); /* On verra ca avec module compabilite expert - $newmenu->add("/compta/resultat/compteres.php?leftmenu=report","Compte de resultat",2,$user->rights->compta->resultat->lire); - $newmenu->add("/compta/resultat/bilan.php?leftmenu=report","Bilan",2,$user->rights->compta->resultat->lire); - */ + $newmenu->add("/compta/resultat/compteres.php?leftmenu=report","Compte de resultat",2,$user->rights->compta->resultat->lire); + $newmenu->add("/compta/resultat/bilan.php?leftmenu=report","Bilan",2,$user->rights->compta->resultat->lire); + */ /* - $newmenu->add("/compta/stats/cumul.php?leftmenu=report","Cumule",2,$user->rights->compta->resultat->lire); - if (! empty($conf->propal->enabled)) { - $newmenu->add("/compta/stats/prev.php?leftmenu=report","Previsionnel",2,$user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/comp.php?leftmenu=report","Transforme",2,$user->rights->compta->resultat->lire); - } - */ + $newmenu->add("/compta/stats/cumul.php?leftmenu=report","Cumule",2,$user->rights->compta->resultat->lire); + if (! empty($conf->propal->enabled)) { + $newmenu->add("/compta/stats/prev.php?leftmenu=report","Previsionnel",2,$user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/comp.php?leftmenu=report","Transforme",2,$user->rights->compta->resultat->lire); + } + */ $modecompta = 'CREANCES-DETTES'; $newmenu->add("/compta/stats/index.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ReportTurnover"), 1, $user->rights->compta->resultat->lire); @@ -1846,11 +1846,11 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef $newmenu->add("/compta/stats/supplier_turnover_by_prodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 2, $user->rights->compta->resultat->lire); /* - $modecompta = 'RECETTES-DEPENSES'; - $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnoverCollected"), 1, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire); - */ + $modecompta = 'RECETTES-DEPENSES'; + $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnoverCollected"), 1, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire); + */ // Journals $newmenu->add("/compta/journal/sellsjournal.php?leftmenu=report", $langs->trans("SellsJournal"), 1, $user->rights->compta->resultat->lire, '', '', '', 50); @@ -1886,11 +1886,11 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef /** * Get left Menu BANK * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_bank($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) @@ -1969,11 +1969,11 @@ function get_left_menu_bank($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = /** * Get left Menu PRODUCTS-SERVICES * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_products($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) @@ -2100,17 +2100,17 @@ function get_left_menu_products($mainmenu, &$newmenu, $usemenuhider = 1, $leftme /** * Get left Menu PRODUCTS-SERVICES MRP - GPAO * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_mrp($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) { global $user, $conf, $langs; - + if ($mainmenu == 'mrp') { // BOM if (!empty($conf->bom->enabled) || !empty($conf->mrp->enabled)) { @@ -2134,17 +2134,17 @@ function get_left_menu_mrp($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = /** * Get left Menu PROJECTS * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_projects($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) { global $user, $conf, $langs; - + if ($mainmenu == 'project') { if (!empty($conf->projet->enabled)) { $langs->load("projects"); @@ -2208,11 +2208,11 @@ function get_left_menu_projects($mainmenu, &$newmenu, $usemenuhider = 1, $leftme /** * Get left Menu HRM * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) @@ -2315,17 +2315,17 @@ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = /** * Get left Menu TOOLS * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_tools($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) { global $user, $conf, $langs; - + if ($mainmenu == 'tools') { if (empty($user->socid)) { // limit to internal users $langs->load("mails"); @@ -2356,11 +2356,11 @@ function get_left_menu_tools($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu /** * Get left Menu MEMBERS * - * @param string $mainmenu - * @param Menu &$newmenu Object Menu to return back list of menu entries - * @param string $usemenuhider - * @param string $leftmenu - * @param int $type_user + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu * @return void */ function get_left_menu_members($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 68b48af57ea..df4bfeedb9c 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -897,7 +897,7 @@ class pdf_crabe extends ModelePDFFactures $tab3_width = 80; $tab3_height = 4; if ($this->page_largeur < 210) { // To work with US executive format - $tab3_posx -= 20; + $tab3_posx -= 15; } $default_font_size = pdf_getPDFFontSize($outputlangs); @@ -1289,7 +1289,8 @@ class pdf_crabe extends ModelePDFFactures $col1x = 120; $col2x = 170; if ($this->page_largeur < 210) { // To work with US executive format - $col2x -= 20; + $col1x -= 15; + $col2x -= 10; } $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 7f3b543ebba..a5e9c0b841b 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -540,7 +540,7 @@ class pdf_sponge extends ModelePDFFactures $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } // $this->_pagefoot($pdf,$object,$outputlangs,1); $pdf->setTopMargin($tab_top_newpage); @@ -598,7 +598,7 @@ class pdf_sponge extends ModelePDFFactures $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } $height_note = $posyafter - $tab_top_newpage; $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); @@ -620,7 +620,7 @@ class pdf_sponge extends ModelePDFFactures $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } $posyafter = $tab_top_newpage; @@ -870,9 +870,9 @@ class pdf_sponge extends ModelePDFFactures // Retrieve type from database for backward compatibility with old records if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax - $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); - $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : ''; - $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : ''; + $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); + $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : ''; + $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : ''; } // retrieve global local tax @@ -922,7 +922,7 @@ class pdf_sponge extends ModelePDFFactures $pdf->setPage($pagenb); $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } } @@ -940,7 +940,7 @@ class pdf_sponge extends ModelePDFFactures } $pagenb++; if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } } } @@ -989,9 +989,9 @@ class pdf_sponge extends ModelePDFFactures @chmod($file, octdec($conf->global->MAIN_UMASK)); } - $this->result = array('fullpath'=>$file); + $this->result = array('fullpath'=>$file); - return 1; // No error + return 1; // No error } else { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; @@ -1026,7 +1026,7 @@ class pdf_sponge extends ModelePDFFactures $tab3_width = 80; $tab3_height = 4; if ($this->page_largeur < 210) { // To work with US executive format - $tab3_posx -= 20; + $tab3_posx -= 15; } $default_font_size = pdf_getPDFFontSize($outputlangs); @@ -1177,20 +1177,24 @@ class pdf_sponge extends ModelePDFFactures $posy = $pdf->GetY() + 4; } - $posxval = 52; + $posxval = 52; // Position of values of properties shown on left side + $posxend = 110; // End of x for text on left side + if ($this->page_largeur < 210) { // To work with US executive format + $posxend -= 10; + } // Show payments conditions if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement)) { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $titre = $outputlangs->transnoentities("PaymentConditions").':'; - $pdf->MultiCell(43, 4, $titre, 0, 'L'); + $pdf->MultiCell($posxval - $this->marge_gauche, 4, $titre, 0, 'L'); $pdf->SetFont('', '', $default_font_size - 2); $pdf->SetXY($posxval, $posy); $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label); $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement); - $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L'); + $pdf->MultiCell($posxend - $posxval, 4, $lib_condition_paiement, 0, 'L'); $posy = $pdf->GetY() + 3; // We need spaces for 2 lines payment conditions } @@ -1198,42 +1202,42 @@ class pdf_sponge extends ModelePDFFactures if ($object->type != 2) { // Check a payment mode is defined if (empty($object->mode_reglement_code) - && empty($conf->global->FACTURE_CHQ_NUMBER) - && empty($conf->global->FACTURE_RIB_NUMBER)) { - $this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"); + && empty($conf->global->FACTURE_CHQ_NUMBER) + && empty($conf->global->FACTURE_RIB_NUMBER)) { + $this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"); } elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank)) - || ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))) { - // Avoid having any valid PDF with setup that is not complete - $outputlangs->load("errors"); + || ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))) { + // Avoid having any valid PDF with setup that is not complete + $outputlangs->load("errors"); - $pdf->SetXY($this->marge_gauche, $posy); - $pdf->SetTextColor(200, 0, 0); - $pdf->SetFont('', 'B', $default_font_size - 2); - $this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code); - $pdf->MultiCell(80, 3, $this->error, 0, 'L', 0); - $pdf->SetTextColor(0, 0, 0); + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200, 0, 0); + $pdf->SetFont('', 'B', $default_font_size - 2); + $this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $this->error, 0, 'L', 0); + $pdf->SetTextColor(0, 0, 0); - $posy = $pdf->GetY() + 1; + $posy = $pdf->GetY() + 1; } - // Show payment mode + // Show payment mode if (!empty($object->mode_reglement_code) - && $object->mode_reglement_code != 'CHQ' - && $object->mode_reglement_code != 'VIR') { - $pdf->SetFont('', 'B', $default_font_size - 2); - $pdf->SetXY($this->marge_gauche, $posy); - $titre = $outputlangs->transnoentities("PaymentMode").':'; - $pdf->MultiCell(80, 5, $titre, 0, 'L'); + && $object->mode_reglement_code != 'CHQ' + && $object->mode_reglement_code != 'VIR') { + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentMode").':'; + $pdf->MultiCell($posxend - $this->marge_gauche, 5, $titre, 0, 'L'); - $pdf->SetFont('', '', $default_font_size - 2); - $pdf->SetXY($posxval, $posy); - $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement); - $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L'); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement); + $pdf->MultiCell($posxend - $posxval, 5, $lib_mode_reg, 0, 'L'); - $posy = $pdf->GetY(); + $posy = $pdf->GetY(); } - // Show online payment link + // Show online payment link if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') { $useonlinepayment = 0; if (!empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT)) { @@ -1258,13 +1262,13 @@ class pdf_sponge extends ModelePDFFactures $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").''; $pdf->SetXY($this->marge_gauche, $posy); - $pdf->writeHTMLCell(80, 5, '', '', dol_htmlentitiesbr($linktopay), 0, 1); + $pdf->writeHTMLCell($posxend - $this->marge_gauche, 5, '', '', dol_htmlentitiesbr($linktopay), 0, 1); $posy = $pdf->GetY() + 1; } } - // Show payment mode CHQ + // Show payment mode CHQ if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') { // If payment mode unregulated or payment mode forced to CHQ if (!empty($conf->global->FACTURE_CHQ_NUMBER)) { @@ -1276,33 +1280,33 @@ class pdf_sponge extends ModelePDFFactures $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0); $posy = $pdf->GetY() + 1; if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - $diffsizetitle); - $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); $posy = $pdf->GetY() + 2; } } if ($conf->global->FACTURE_CHQ_NUMBER == -1) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); $posy = $pdf->GetY() + 1; if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - $diffsizetitle); - $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); $posy = $pdf->GetY() + 2; } } } } - // If payment mode not forced or forced to VIR, show payment with BAN + // If payment mode not forced or forced to VIR, show payment with BAN if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') { if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) { $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); @@ -1350,13 +1354,18 @@ class pdf_sponge extends ModelePDFFactures $tab2_top = $posy; $tab2_hl = 4; - $pdf->SetFont('', '', $default_font_size - 1); + if (is_object($outputlangsbis)) { // When we show 2 languages we need more room for text, so we use a smaller font. + $pdf->SetFont('', '', $default_font_size - 2); + } else { + $pdf->SetFont('', '', $default_font_size - 1); + } // Total table $col1x = 120; $col2x = 170; if ($this->page_largeur < 210) { // To work with US executive format - $col2x -= 20; + $col1x -= 15; + $col2x -= 10; } $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); @@ -1481,9 +1490,10 @@ class pdf_sponge extends ModelePDFFactures $tab2_top = $posy; $index = 0; + + $tab2_top += 3; } - $tab2_top += 3; // Get Total HT $total_ht = (!empty($conf->multicurrency->enabled) && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); @@ -1804,19 +1814,19 @@ class pdf_sponge extends ModelePDFFactures } /* - if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT) - { - $index++; - $pdf->SetFillColor(255, 255, 255); + if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT) + { + $index++; + $pdf->SetFillColor(255, 255, 255); - $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', 1); - $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', 1); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1); - $resteapayer = 0; - } - */ + $resteapayer = 0; + } + */ $index++; $pdf->SetTextColor(0, 0, 60); @@ -1936,7 +1946,7 @@ class pdf_sponge extends ModelePDFFactures // Show Draft Watermark if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->FACTURE_DRAFT_WATERMARK))) { - pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK); + pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK); } $pdf->SetTextColor(0, 0, 60); @@ -2023,15 +2033,15 @@ class pdf_sponge extends ModelePDFFactures $pdf->SetFont('', 'B', $default_font_size); /* - $posy += 5; - $pdf->SetXY($posx, $posy); - $pdf->SetTextColor(0, 0, 60); - $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref); - if ($object->statut == $object::STATUS_DRAFT) { - $pdf->SetTextColor(128, 0, 0); - $textref .= ' - '.$outputlangs->transnoentities("NotValidated"); - } - $pdf->MultiCell($w, 4, $textref, '', 'R');*/ + $posy += 5; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref); + if ($object->statut == $object::STATUS_DRAFT) { + $pdf->SetTextColor(128, 0, 0); + $textref .= ' - '.$outputlangs->transnoentities("NotValidated"); + } + $pdf->MultiCell($w, 4, $textref, '', 'R');*/ $posy += 3; $pdf->SetFont('', '', $default_font_size - 2); @@ -2295,21 +2305,21 @@ class pdf_sponge extends ModelePDFFactures /* * For exemple - $this->cols['theColKey'] = array( - 'rank' => $rank, // int : use for ordering columns - 'width' => 20, // the column width in mm - 'title' => array( - 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label - 'label' => ' ', // the final label : used fore final generated text - 'align' => 'L', // text alignement : R,C,L - 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left - ), - 'content' => array( - 'align' => 'L', // text alignement : R,C,L - 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left - ), - ); - */ + $this->cols['theColKey'] = array( + 'rank' => $rank, // int : use for ordering columns + 'width' => 20, // the column width in mm + 'title' => array( + 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + 'label' => ' ', // the final label : used fore final generated text + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + */ $rank = 0; // do not use negative rank $this->cols['desc'] = array( diff --git a/htdocs/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php index 597f15b7f10..f9af0568bf0 100644 --- a/htdocs/don/class/api_donations.class.php +++ b/htdocs/don/class/api_donations.class.php @@ -293,7 +293,7 @@ class Donations extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @return array */ diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index df942ff93e6..37319a3ec71 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -401,7 +401,7 @@ class ExpenseReports extends DolibarrApi * * @throws RestException 401 Not allowed * @throws RestException 404 Expense report not found - * @throws RestException 500 + * @throws RestException 500 System error */ public function put($id, $request_data = null) { diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 06c836b4d77..35e783729ff 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -211,7 +211,7 @@ class SupplierInvoices extends DolibarrApi * @return int ID of supplier invoice * * @throws RestException 401 - * @throws RestException 500 + * @throws RestException 500 System error */ public function post($request_data = null) { @@ -283,7 +283,7 @@ class SupplierInvoices extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function delete($id) { @@ -300,7 +300,7 @@ class SupplierInvoices extends DolibarrApi } if ($this->invoice->delete(DolibarrApiAccess::$user) < 0) { - throw new RestException(500); + throw new RestException(500, 'Error when deleting invoice'); } return array( @@ -326,7 +326,7 @@ class SupplierInvoices extends DolibarrApi * @throws RestException 401 * @throws RestException 404 * @throws RestException 405 - * @throws RestException 500 + * @throws RestException 500 System error */ public function validate($id, $idwarehouse = 0, $notrigger = 0) { diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index e21eb3436dc..d55a398dbd6 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -309,7 +309,7 @@ class SupplierOrders extends DolibarrApi } if ($this->order->delete(DolibarrApiAccess::$user) < 0) { - throw new RestException(500); + throw new RestException(500, 'Error when deleting order'); } return array( diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql index 434d30bdfe4..2ec43548bb6 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -84,8 +84,8 @@ UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'a UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'cameleo'; DELETE FROM llx_user_param where param = 'MAIN_THEME' and value in ('auguria', 'amarok', 'cameleo'); -ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64) DEFAULT NULL; -ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging varchar(64) DEFAULT NULL; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging real DEFAULT NULL; +ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging real DEFAULT NULL; -- For v14 diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 5e9a0250a38..2933acd00d7 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -91,6 +91,10 @@ INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (154, INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (154, '15419', '626 - Régimen Simplificado de Confianza', 1); +ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_soc (fk_type, fk_soc, date_partnership_start); +ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_member (fk_type, fk_member, date_partnership_start); + + -- v16 ALTER TABLE llx_projet_task_time ADD COLUMN fk_product integer NULL; diff --git a/htdocs/install/mysql/tables/llx_partnership-partnership.key.sql b/htdocs/install/mysql/tables/llx_partnership-partnership.key.sql index 7d09cdddda8..1a2cf6af5bb 100644 --- a/htdocs/install/mysql/tables/llx_partnership-partnership.key.sql +++ b/htdocs/install/mysql/tables/llx_partnership-partnership.key.sql @@ -19,3 +19,6 @@ ALTER TABLE llx_partnership ADD INDEX idx_partnership_entity (entity); ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_partnership_ref (ref, entity); + +ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_soc (fk_type, fk_soc, date_partnership_start); +ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_member (fk_type, fk_member, date_partnership_start); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index cffd3532c05..9cae7524022 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2225,3 +2225,5 @@ PreviousHash=Previous hash LateWarningAfter="Late" warning after TemplateforBusinessCards=Template for a business card in different size InventorySetup= Inventory Setup +ExportUseLowMemoryMode=Use a low memory mode +ExportUseLowMemoryModeHelp=Use the low memory mode to execute the exec of the dump (compression is done through a pipe instead of into the PHP memory). This method does not allow to check that file is completed and error message can't be reported if it fails. diff --git a/htdocs/langs/en_US/contracts.lang b/htdocs/langs/en_US/contracts.lang index 746c7fdfeb6..8d209623c1b 100644 --- a/htdocs/langs/en_US/contracts.lang +++ b/htdocs/langs/en_US/contracts.lang @@ -102,4 +102,6 @@ TypeContact_contrat_external_CUSTOMER=Follow-up customer contact TypeContact_contrat_external_SALESREPSIGN=Signing contract customer contact HideClosedServiceByDefault=Hide closed services by default ShowClosedServices=Show Closed Services -HideClosedServices=Hide Closed Services \ No newline at end of file +HideClosedServices=Hide Closed Services +UserStartingService=User starting service +UserClosingService=User closing service diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang index 7c2a0f8b6ec..820339e6875 100644 --- a/htdocs/langs/en_US/languages.lang +++ b/htdocs/langs/en_US/languages.lang @@ -16,6 +16,7 @@ Language_bg_BG=Bulgarian Language_bs_BA=Bosnian Language_ca_ES=Catalan Language_cs_CZ=Czech +Language_cy_GB=Welsh Language_da_DA=Danish Language_da_DK=Danish Language_de_DE=German diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 589f4052724..902969ee430 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -369,10 +369,14 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { /* The slow method does not consume memory on mysql (not tested on pgsql) */ /*$resql = $db->query($sql, 0, 'auto', 1); while ($db->fetch_object($resql)) { - $nbtotalofrecords++; - }*/ + if (empty($nbtotalofrecords)) { + $nbtotalofrecords = 1; // We can't make +1 because init value is '' + } else { + $nbtotalofrecords++; + } + }*/ /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); $resql = $db->query($sqlforcount); $objforcount = $db->fetch_object($resql); $nbtotalofrecords = $objforcount->nbtotalofrecords; diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index ad590e0f83c..e44aef221f6 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -742,7 +742,7 @@ class Products extends DolibarrApi * @param int $fk_barcode_type Barcode type * @return int * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url POST {id}/purchase_prices @@ -1161,7 +1161,7 @@ class Products extends DolibarrApi * @param string $ref_ext External reference of Attribute * @return array * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url GET attributes/ref_ext/{ref_ext} @@ -1212,7 +1212,7 @@ class Products extends DolibarrApi * @param string $ref_ext Reference of Attribute * @return int * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url POST attributes @@ -1289,7 +1289,7 @@ class Products extends DolibarrApi * @param int $id ID of Attribute * @return int Result of deletion * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url DELETE attributes/{id} @@ -1317,7 +1317,7 @@ class Products extends DolibarrApi * @param int $id ID of Attribute value * @return array * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url GET attributes/values/{id} @@ -1358,7 +1358,7 @@ class Products extends DolibarrApi * @param string $ref Ref of Attribute value * @return array * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url GET attributes/{id}/values/ref/{ref} @@ -1445,7 +1445,7 @@ class Products extends DolibarrApi * @return array * * @throws RestException 401 - * @throws RestException 500 + * @throws RestException 500 System error * * @url GET attributes/{id}/values */ @@ -1517,7 +1517,7 @@ class Products extends DolibarrApi * @param string $value Value of Attribute value * @return int * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url POST attributes/{id}/values @@ -1551,7 +1551,7 @@ class Products extends DolibarrApi * @return array * * @throws RestException 401 - * @throws RestException 500 + * @throws RestException 500 System error * * @url PUT attributes/values/{id} */ @@ -1596,7 +1596,7 @@ class Products extends DolibarrApi * @param int $id ID of Attribute value * @return int * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url DELETE attributes/values/{id} @@ -1623,7 +1623,7 @@ class Products extends DolibarrApi * @param int $includestock Default value 0. If parameter is set to 1 the response will contain stock data of each variant * @return array * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url GET {id}/variants @@ -1659,7 +1659,7 @@ class Products extends DolibarrApi * @param string $ref Ref of Product * @return array * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url GET ref/{ref}/variants @@ -1701,7 +1701,7 @@ class Products extends DolibarrApi * @param string $ref_ext External reference of variant * @return int * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * @throws RestException 404 * @@ -1758,7 +1758,7 @@ class Products extends DolibarrApi * @param array $features List of attributes pairs id_attribute->id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) * @return int * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * @throws RestException 404 * @@ -1813,7 +1813,7 @@ class Products extends DolibarrApi * @param array $request_data Datas * @return int * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url PUT variants/{id} @@ -1847,7 +1847,7 @@ class Products extends DolibarrApi * @param int $id ID of Variant * @return int Result of deletion * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * * @url DELETE variants/{id} @@ -1875,7 +1875,7 @@ class Products extends DolibarrApi * @param int $selected_warehouse_id ID of warehouse * @return int * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 401 * @throws RestException 404 * diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index aaaf4428ff5..6026e4316e4 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -216,7 +216,7 @@ if (empty($reshook)) { } } - // Save quantity found during inventory + // Save quantity found during inventory (when we click on Save button on inventory page) if ($action =='updateinventorylines' && $permissiontoadd) { $sql = 'SELECT id.rowid, id.datec as date_creation, id.tms as date_modification, id.fk_inventory, id.fk_warehouse,'; $sql .= ' id.fk_product, id.batch, id.qty_stock, id.qty_view, id.qty_regulated'; @@ -236,6 +236,9 @@ if (empty($reshook)) { $line = $db->fetch_object($resql); $lineid = $line->rowid; + $result = 0; + $resultupdate = 0; + if (GETPOST("id_".$lineid, 'alpha') != '') { // If a value was set ('0' or something else) $qtytoupdate = price2num(GETPOST("id_".$lineid, 'alpha'), 'MS'); $result = $inventoryline->fetch($lineid); @@ -265,7 +268,7 @@ if (empty($reshook)) { } } - // Update line with id of stock movement (and the start quantity if it has changed this last recording) + // Update user that update quantities if (! $error) { $sqlupdate = "UPDATE ".MAIN_DB_PREFIX."inventory"; $sqlupdate .= " SET fk_user_modif = ".((int) $user->id); diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 47e893846e6..962bbf021b8 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -1409,7 +1409,7 @@ class Thirdparties extends DolibarrApi if ($result > 0) { return array("success" => $result); } else { - throw new RestException(500); + throw new RestException(500, 'Error generating the document '.$this->error); } } diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php index 75c2db21224..3151f75877b 100644 --- a/htdocs/ticket/class/api_tickets.class.php +++ b/htdocs/ticket/class/api_tickets.class.php @@ -377,7 +377,7 @@ class Tickets extends DolibarrApi } $this->ticket->message = $ticketMessageText; if (!$this->ticket->createTicketMessage(DolibarrApiAccess::$user)) { - throw new RestException(500); + throw new RestException(500, 'Error when creating ticket'); } return $this->ticket->id; } @@ -438,7 +438,7 @@ class Tickets extends DolibarrApi } if (!$this->ticket->delete($id)) { - throw new RestException(500); + throw new RestException(500, 'Error when deleting ticket'); } return array( diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index b2f8085de5a..3ef98da8f5b 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -466,7 +466,7 @@ class Users extends DolibarrApi * * @throws RestException 401 Not allowed * @throws RestException 404 User not found - * @throws RestException 500 Error + * @throws RestException 500 System error * * @url GET {id}/setGroup/{group} */ diff --git a/test/phpunit/BarcodeTest.php b/test/phpunit/BarcodeTest.php new file mode 100644 index 00000000000..132ba8c1126 --- /dev/null +++ b/test/phpunit/BarcodeTest.php @@ -0,0 +1,203 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file test/phpunit/BarcodeTest.php + * \ingroup test + * \brief PHPUnit test + * \remarks To run this script as CLI: phpunit filename.php + */ + +global $conf,$user,$langs,$db; +//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver +//require_once 'PHPUnit/Autoload.php'; +require_once dirname(__FILE__).'/../../htdocs/master.inc.php'; +require_once dirname(__FILE__).'/../../htdocs/compta/facture/class/facture.class.php'; + + +if (empty($user->id)) { + print "Load permissions for admin user nb 1\n"; + $user->fetch(1); + $user->getrights(); +} +$conf->global->MAIN_DISABLE_ALL_MAILS=1; + +$langs->load("main"); + + +/** + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + */ +class BarcodeTest extends PHPUnit\Framework\TestCase +{ + protected $savconf; + protected $savuser; + protected $savlangs; + protected $savdb; + + /** + * Constructor + * We save global variables into local variables + * + * @return BarcodeTest + */ + public function __construct() + { + parent::__construct(); + + //$this->sharedFixture + global $conf,$user,$langs,$db; + $this->savconf=$conf; + $this->savuser=$user; + $this->savlangs=$langs; + $this->savdb=$db; + + print __METHOD__." db->type=".$db->type." user->id=".$user->id; + //print " - db ".$db->db; + print "\n"; + } + + /** + * setUpBeforeClass + * + * @return void + */ + public static function setUpBeforeClass() + { + global $conf,$user,$langs,$db; + $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. + + print __METHOD__."\n"; + } + + /** + * tearDownAfterClass + * + * @return void + */ + public static function tearDownAfterClass() + { + global $conf,$user,$langs,$db; + $db->rollback(); + + print __METHOD__."\n"; + } + + /** + * Init phpunit tests + * + * @return void + */ + protected function setUp() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + print __METHOD__."\n"; + } + + /** + * End phpunit tests + * + * @return void + */ + protected function tearDown() + { + print __METHOD__."\n"; + } + + + /** + * testBarcodeZATCAEncode + * + * @return int + */ + public function testBarcodeZATCAEncode() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $company = new Societe($db); + $company->name = 'Specimen company'; + $company->tva_intra = '123456789'; + + $tmpinvoice = new Facture($db); + + $tmpinvoice->thirdparty = $company; + $tmpinvoice->total_ht = 100; + $tmpinvoice->total_tva = 20; + $tmpinvoice->total_ttc = $tmpinvoice->total_ht + $tmpinvoice->total_tva; + $tmpinvoice->date = dol_mktime(12, 34, 56, 1, 1, 2020, 'gmt'); + + $string_zatca = $tmpinvoice->buildZATCAQRString(); + + $this->assertEquals($string_zatca, "ARBTcGVjaW1lbiBjb21wYW55AgkxMjM0NTY3ODkDFDIwMjAtMDEtMDFUMDk6MzQ6NTZaBAMxMjAFAjIw"); + + return 1; + } + + + + /** + * testBarcodeZATCADecode + * + * @return int + */ + public function testBarcodeZATCADecode() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + //$string_zatca_base64 = "AQZSYWZlZXECDTEyMzQ1Njc4OVQxMjUDFDIwMjEtMDctMTJUMTQ6MjU6MDlaBAM3ODYFAjI1"; + $string_zatca_base64 = "ARBTcGVjaW1lbiBjb21wYW55AgkxMjM0NTY3ODkDFDIwMjAtMDEtMDFUMDk6MzQ6NTZaBAMxMjAFAjIw"; + + $decoded = base64_decode($string_zatca_base64); + + //print_r($decoded) + //raw data + //\u0001\u0006Rafeeq\u0002\t123456789\u0003\u00142021-07-12T14:25:09Z\u0004\u0003786\u0005\u000225 + + $result_data = preg_replace('/[\x00-\x1F\x80-\xFF]/', ',', $decoded); + + $arrayOfData = explode(',,', $result_data); + + + print __METHOD__." result=".var_export($arrayOfData, true)."\n"; + $this->assertEquals("", $arrayOfData[0]); + $this->assertEquals("Specimen company", $arrayOfData[1]); + $this->assertEquals("123456789", $arrayOfData[2]); + $this->assertEquals("2020-01-01T09:34:56Z", $arrayOfData[3]); + $this->assertEquals("120", $arrayOfData[4]); + $this->assertEquals("20", $arrayOfData[5]); + + return 1; + } +}