mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2026-02-13 19:25:22 +01:00
Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 20.0
This commit is contained in:
103
ChangeLog
103
ChangeLog
@@ -2,6 +2,109 @@
|
||||
English Dolibarr ChangeLog
|
||||
--------------------------------------------------------------
|
||||
|
||||
***** ChangeLog for 20.0.4 compared to 20.0.3 *****
|
||||
FIX: $this->origin_object can not be instance of CommandeFournisseur if it is already an instanceof CommonObject
|
||||
FIX: 17.0 API endpoints "PUT": prevent overwriting all extrafields if only some are supplied in the request cf. PR #29237
|
||||
FIX: 17.0 - collisions in cache for dol_getIdFromCode
|
||||
FIX: #18713
|
||||
FIX: 20.0 - PHP8 fatal when creating a reception unless corresponding PDF model is enabled
|
||||
FIX: #21294 Stock import sql query
|
||||
FIX: #26250 fatal error on kit
|
||||
FIX: #28702
|
||||
FIX: #29624 - substitution of __DATE_DELIVERY__
|
||||
FIX: #32113
|
||||
FIX: #32186
|
||||
FIX: #32339 Delete a loan settlement is partial
|
||||
FIX: #32387
|
||||
FIX: #32477 Loan - Insurance amount need decimals
|
||||
FIX: #32611
|
||||
FIX: #32736 + avoid php warning
|
||||
FIX: #32743
|
||||
FIX: #32765 JS Error: Uncaught TypeError
|
||||
FIX: #32801 VAT type is inverted in form VAT selector
|
||||
FIX: #32840
|
||||
FIX: #32843
|
||||
FIX: #32880 - Tags are using a special rendering.
|
||||
FIX: add other fields
|
||||
FIX: autofill price with multicurrency on supplier doc
|
||||
FIX: avoid phan error
|
||||
FIX: avoid php8 warnings
|
||||
FIX: avoid warning with the new Dolistore website
|
||||
FIX: backport from develop to avoid php warning
|
||||
FIX: Bad calculation of the theoretical stock. Did not take into account
|
||||
FIX: bad dispatched quantities for batches on shipment card
|
||||
FIX: Brian is in the kitchen
|
||||
FIX: broken feature, compatibility with "Default search filters"
|
||||
FIX: broken feature with check $pa_ht_isemptystring
|
||||
FIX: Bug on select user on time.php (all project list)
|
||||
FIX: can not delete files in task card
|
||||
FIX: Check "$search_sale" only if it's an internal user
|
||||
FIX: clean unique extrafields when create product combination
|
||||
FIX: code not visible correctly into view of dictionary
|
||||
FIX: compatibility between next_prev_filter and hook return
|
||||
FIX: compatibility with multicompany
|
||||
FIX: Complete path was started in #17243 for pdf_cannelle
|
||||
FIX: Continue for eagle_proforma
|
||||
FIX: country id is not saved when we provide country_code only
|
||||
FIX: #CVE-2024-34051
|
||||
FIX: delete supplier order when at least one line linked to customer order line
|
||||
FIX: display error when loan can't be deleted
|
||||
FIX: display full tree on shipment card when a kit contains a same component in other sub-kit
|
||||
FIX: DROP INDEX IF EXISTS is not possible !
|
||||
FIX: extrafields lost during creation from rec invoice
|
||||
FIX: FEC import
|
||||
FIX: Fiscal year - missing translation on status
|
||||
FIX: Fix return value of hook sendMail when hook return -1 who must be return false in sendfile() function
|
||||
FIX: GETPOST('private_message')
|
||||
FIX: glob is better for search files with wildcard + avoid warning
|
||||
FIX: if $force_entity = 0 ($force_entity != 'default') = false
|
||||
FIX: Loan - Insurance amount need decimals
|
||||
FIX: Many status on invoice linked object block
|
||||
FIX: merge problem
|
||||
FIX: missing company name if donation is linked to third party
|
||||
FIX: missing default values if $objsrc or $soc fields are empty
|
||||
FIX: missing edit extrafields inline for member card
|
||||
FIX: missing quick edit for extrafields
|
||||
FIX: more bugs and warnings
|
||||
FIX: Multilangs : PDF lines description
|
||||
FIX: Must not have both thirdparty and member.
|
||||
FIX: ODT substitution when many HTML tags in string
|
||||
FIX: on the road again
|
||||
FIX: pdf_cannelle (supplier_invoice) add background - Complete #17243
|
||||
FIX: Prices didn't update when clone a propale with update prices
|
||||
FIX: product variants copy: also copy multiprice variations
|
||||
FIX: refactorize (maybe broken feature for not received completely)
|
||||
FIX: remove debug trace
|
||||
FIX: remove socid when cloning a project without third parties
|
||||
FIX: removes traces of <<<HEAD conflicts following the postponement of branch 13 modifications (#32014)
|
||||
FIX: remove unused code
|
||||
FIX: same broken feature for propal and invoice
|
||||
FIX: select 2 no record found translate
|
||||
FIX: selectcontact is loading all contacts if socid is empty and MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT is not set
|
||||
FIX: selectcontact is loading all contacts when update event
|
||||
FIX: select group and severity search fields on ticket list
|
||||
FIX: send email to assigned user on ticket create
|
||||
FIX: sql error with the new sql forge filter
|
||||
FIX: sql "order by" is defined twice
|
||||
FIX: status ticket update for new message
|
||||
FIX: swap tests
|
||||
FIX: switch on/off status of a page of the second website.
|
||||
FIX: There were many status indicator in the invoice linked object block (propal card)
|
||||
FIX: uniformize code
|
||||
FIX: units used scale and scale is an integer
|
||||
FIX: wrong alias table
|
||||
FIX: wrong file path + avoid warning
|
||||
FIX: wrong filter format
|
||||
FIX: wrong "fournisseur" var value checking
|
||||
FIX: wrong left margin
|
||||
FIX: wrong message on update shipment
|
||||
FIX: wrong ODT path for multicompany
|
||||
FIX: wrong path for odt models
|
||||
FIX: wrong search filter, empty product unit is "none"
|
||||
FIX: wrong update function parameter
|
||||
FIX: some wrong var type
|
||||
FIX: some wrong var name
|
||||
|
||||
***** ChangeLog for 20.0.3 compared to 20.0.2 *****
|
||||
FIX: 17.0 - missing error handling for FactureRec::fetch in card-rec.php
|
||||
FIX: 17.0 - warnings due to uninitialized variables + delete code that doesn't apply to recurring invoices (AFAIK, there is no recurring credit note feature)
|
||||
|
||||
@@ -36,7 +36,7 @@ $PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/
|
||||
"RPM_FEDORA"=>"rpmbuild",
|
||||
"RPM_MANDRIVA"=>"rpmbuild",
|
||||
"RPM_OPENSUSE"=>"rpmbuild",
|
||||
"DEB"=>"dpkg",
|
||||
"DEB"=>"dpkg,po2debconf", # need also debhelper
|
||||
"FLATPACK"=>"flatpack",
|
||||
"EXEDOLIWAMP"=>"ISCC.exe",
|
||||
"SNAPSHOT"=>"tar"
|
||||
@@ -85,8 +85,9 @@ if (! $ENV{"DESTIBETARC"} || ! $ENV{"DESTISTABLE"})
|
||||
print "set DESTIBETARC=c:/tmp\n";
|
||||
print "set DESTISTABLE=c:/tmp\n";
|
||||
print "\n";
|
||||
print "Example: DESTIBETARC='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/lastbuild'\n";
|
||||
print "Example: DESTISTABLE='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/stable'\n";
|
||||
print "Example in .bashrc:\n";
|
||||
print "export DESTIBETARC='/mnt/HDDATA1_LD/Mes Archives/Doli/dolibarr/lastbuild'\n";
|
||||
print "export DESTISTABLE='/mnt/HDDATA1_LD/Mes Archives/Doli/dolibarr/stable'\n";
|
||||
sleep 2;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
@@ -1000,7 +1000,7 @@ class AccountancyExport
|
||||
|
||||
// We need to keep the 10 latest number of invoices doc_ref not the beginning part that is the useless almost same part
|
||||
// $tab['num_piece3'] = str_pad(self::trunc($line->piece_num, 10), 10);
|
||||
$tab['num_piece3'] = substr(self::trunc($line->doc_ref, 20), -10);
|
||||
$tab['num_piece3'] = str_pad(substr(self::trunc($line->doc_ref, 20), -10), 10);
|
||||
$tab['reserved'] = str_repeat(' ', 10); // position 159
|
||||
$tab['currency_amount'] = str_repeat(' ', 13); // position 169
|
||||
// get document file
|
||||
|
||||
@@ -614,7 +614,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled
|
||||
$deschelp .= '<div class="info hideonsmartphone">'.$desc."<br></div>\n";
|
||||
}
|
||||
if (getDolGlobalString('MAIN_SETUP_MODULES_INFO')) { // Show a custom message
|
||||
if (getDolGlobalString('MAIN_SETUP_MODULES_INFO')) { // Show a custom message. A good usage for SaaS with option MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING.
|
||||
$deschelp .= '<div class="info">'.$langs->trans(getDolGlobalString('MAIN_SETUP_MODULES_INFO'))."<br></div>\n";
|
||||
}
|
||||
if ($deschelp) {
|
||||
|
||||
@@ -292,7 +292,7 @@ class BOM extends CommonObject
|
||||
* @param int $notrigger false=launch triggers after, true=disable triggers
|
||||
* @return int Return integer <0 if KO, Id of created object if OK
|
||||
*/
|
||||
public function create(User $user, $notrigger = 1)
|
||||
public function create(User $user, $notrigger = 0)
|
||||
{
|
||||
if ($this->efficiency <= 0 || $this->efficiency > 1) {
|
||||
$this->efficiency = 1;
|
||||
@@ -546,7 +546,7 @@ class BOM extends CommonObject
|
||||
* @param int $notrigger 0=launch triggers after, 1=disable triggers
|
||||
* @return int Return integer <0 if KO, >0 if OK
|
||||
*/
|
||||
public function update(User $user, $notrigger = 1)
|
||||
public function update(User $user, $notrigger = 0)
|
||||
{
|
||||
if ($this->efficiency <= 0 || $this->efficiency > 1) {
|
||||
$this->efficiency = 1;
|
||||
|
||||
@@ -461,6 +461,12 @@ if ($filtert > 0 || $usergroup > 0) {
|
||||
if ($usergroup > 0) {
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element";
|
||||
}
|
||||
|
||||
// Add table from hooks
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
||||
$sql .= $hookmanager->resPrint;
|
||||
|
||||
$sql .= " WHERE a.entity IN (".getEntity('agenda').")";
|
||||
// Condition on actioncode
|
||||
if (!empty($actioncode)) {
|
||||
|
||||
@@ -1922,7 +1922,7 @@ if ($action == 'create') {
|
||||
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
|
||||
$warehouse_id = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE');
|
||||
}
|
||||
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->warehouse_id)) {
|
||||
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->fk_warehouse)) {
|
||||
$warehouse_id = $user->fk_warehouse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1836,7 +1836,7 @@ if ($action == 'create' && $usercancreate) {
|
||||
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
|
||||
$warehouse_id = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE');
|
||||
}
|
||||
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->warehouse_id)) {
|
||||
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->fk_warehouse)) {
|
||||
$warehouse_id = $user->fk_warehouse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,7 +767,7 @@ class PaymentVarious extends CommonObject
|
||||
*/
|
||||
public function info($id)
|
||||
{
|
||||
$sql = 'SELECT v.rowid, v.datec, v.fk_user_author';
|
||||
$sql = 'SELECT v.rowid, v.datec, v.fk_user_author, fk_user_modif, tms';
|
||||
$sql .= ' FROM '.MAIN_DB_PREFIX.'payment_various as v';
|
||||
$sql .= ' WHERE v.rowid = '.((int) $id);
|
||||
|
||||
@@ -780,6 +780,7 @@ class PaymentVarious extends CommonObject
|
||||
|
||||
$this->id = $obj->rowid;
|
||||
$this->user_creation = $obj->fk_user_author;
|
||||
$this->user_creation_id = $obj->fk_user_author;
|
||||
$this->user_modification_id = $obj->fk_user_modif;
|
||||
$this->date_creation = $this->db->jdate($obj->datec);
|
||||
$this->date_modification = $this->db->jdate($obj->tms);
|
||||
|
||||
@@ -129,7 +129,7 @@ if ($object->id) {
|
||||
$morehtmlref .= '</div>';
|
||||
$linkback = '<a href="'.DOL_URL_ROOT.'/compta/bank/various_payment/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
|
||||
|
||||
$morehtmlstatus = $morehtmlright;
|
||||
$morehtmlstatus = '';
|
||||
dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlstatus);
|
||||
|
||||
print '<div class="fichecenter">';
|
||||
|
||||
@@ -145,10 +145,14 @@ $result = restrictedArea($user, 'facture', $object->id, $objecttype);
|
||||
/*
|
||||
* Actions
|
||||
*/
|
||||
|
||||
if (GETPOST('cancel', 'alpha')) {
|
||||
$action = 'list';
|
||||
$massaction = '';
|
||||
if ($action != 'updateline') {
|
||||
$action = 'list';
|
||||
$massaction = '';
|
||||
} else {
|
||||
$action = '';
|
||||
$cancel = '';
|
||||
}
|
||||
}
|
||||
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
|
||||
$massaction = '';
|
||||
|
||||
@@ -2006,7 +2006,7 @@ if (empty($reshook)) {
|
||||
$line->fk_prev_id = $line->id;
|
||||
$line->fetch_optionals();
|
||||
if (getDolGlobalInt('INVOICE_USE_SITUATION') == 2) {
|
||||
$line->situation_percent = $line->get_allprev_progress($object->id);; // get good progress including credit note
|
||||
$line->situation_percent = 0; // New situation percent must be 0 (No cumulative)
|
||||
} else {
|
||||
$line->situation_percent = $line->get_prev_progress($object->id); // get good progress including credit note
|
||||
}
|
||||
|
||||
@@ -2496,10 +2496,12 @@ class Facture extends CommonInvoice
|
||||
if (isset($this->retained_warranty)) {
|
||||
$this->retained_warranty = (float) $this->retained_warranty;
|
||||
}
|
||||
|
||||
|
||||
// Check parameters
|
||||
// Put here code to add control on parameters values
|
||||
if (!isset($this->user_creation_id) && isset($this->fk_user_author) ) {
|
||||
$this->user_creation_id = $this->fk_user_author;
|
||||
}
|
||||
if (!isset($this->user_validation_id) && isset($this->fk_user_valid) ) {
|
||||
$this->user_validation_id = $this->fk_user_valid;
|
||||
}
|
||||
|
||||
// Update request
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."facture SET";
|
||||
@@ -2524,7 +2526,8 @@ class Facture extends CommonInvoice
|
||||
$sql .= " total_ttc=".(isset($this->total_ttc) ? (float) $this->total_ttc : "null").",";
|
||||
$sql .= " revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp != '') ? (float) $this->revenuestamp : "null").",";
|
||||
$sql .= " fk_statut=".(isset($this->status) ? (int) $this->status : "null").",";
|
||||
$sql .= " fk_user_valid=".(isset($this->fk_user_valid) ? (int) $this->fk_user_valid : "null").",";
|
||||
$sql .= " fk_user_author=".(isset($this->user_creation_id) ? ((int) $this->user_creation_id) : "null").",";
|
||||
$sql .= " fk_user_valid=".(isset($this->user_validation_id) ? (int) $this->user_validation_id : "null").",";
|
||||
$sql .= " fk_facture_source=".(isset($this->fk_facture_source) ? (int) $this->fk_facture_source : "null").",";
|
||||
$sql .= " fk_projet=".(isset($this->fk_project) ? (int) $this->fk_project : "null").",";
|
||||
$sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? (int) $this->cond_reglement_id : "null").",";
|
||||
@@ -3871,7 +3874,12 @@ class Facture extends CommonInvoice
|
||||
$fk_prev_id = 'null';
|
||||
}
|
||||
if (!isset($situation_percent) || $situation_percent > 100 || (string) $situation_percent == '' || $situation_percent == null) {
|
||||
$situation_percent = 100;
|
||||
// INVOICE_USE_SITUATION = 2 - Lines situation percent on new lines must be 0 (No cumulative)
|
||||
if ($this->type == Facture::TYPE_SITUATION && getDolGlobalInt('INVOICE_USE_SITUATION') == 2 && (int) $situation_percent < 100) {
|
||||
$situation_percent = 0;
|
||||
} else {
|
||||
$situation_percent = 100;
|
||||
}
|
||||
}
|
||||
if (empty($ref_ext)) {
|
||||
$ref_ext = '';
|
||||
@@ -5061,11 +5069,12 @@ class Facture extends CommonInvoice
|
||||
//Avoid php warning Warning: mt_rand(): max(0) is smaller than min(1) when no product exists
|
||||
if (empty($num_prods)) {
|
||||
$num_prods = 1;
|
||||
$prodids[$num_prods] = 1;
|
||||
}
|
||||
|
||||
// Initialize parameters
|
||||
$this->id = 0;
|
||||
$this->entity = 1;
|
||||
$this->entity = $conf->entity;
|
||||
$this->ref = 'SPECIMEN';
|
||||
$this->specimen = 1;
|
||||
$this->socid = 1;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
/* Copyright (C) 2020 Maxime Kohlhaas <maxime@atm-consulting.fr>
|
||||
* Copyright (C) 2023 Ferran Marcet <fmarcet@2byte.es>
|
||||
/* Copyright (C) 2020 Maxime Kohlhaas <maxime@atm-consulting.fr>
|
||||
* Copyright (C) 2023 Ferran Marcet <fmarcet@2byte.es>
|
||||
* Copyright (C) 2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
|
||||
*
|
||||
* 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
|
||||
@@ -56,11 +57,25 @@ $socid = GETPOSTINT('socid');
|
||||
|
||||
// Category
|
||||
$selected_cat = GETPOSTINT('search_categ');
|
||||
if ($selected_cat == -1) {
|
||||
$selected_cat = 0;
|
||||
}
|
||||
$subcat = false;
|
||||
if (GETPOST('subcat', 'alpha') === 'yes') {
|
||||
$subcat = true;
|
||||
}
|
||||
|
||||
// Security check
|
||||
if ($user->socid > 0) {
|
||||
$socid = $user->socid;
|
||||
}
|
||||
if (isModEnabled('comptabilite')) {
|
||||
$result = restrictedArea($user, 'compta', '', '', 'resultat');
|
||||
}
|
||||
if (isModEnabled('accounting')) {
|
||||
$result = restrictedArea($user, 'accounting', '', '', 'comptarapport');
|
||||
}
|
||||
|
||||
// Hook
|
||||
$hookmanager->initHooks(array('supplierturnoverbythirdpartylist'));
|
||||
|
||||
@@ -148,12 +163,24 @@ $commonparams['sortorder'] = $sortorder;
|
||||
$commonparams['sortfield'] = $sortfield;
|
||||
|
||||
$headerparams = array();
|
||||
$headerparams['date_startyear'] = $date_startyear;
|
||||
$headerparams['date_startmonth'] = $date_startmonth;
|
||||
$headerparams['date_startday'] = $date_startday;
|
||||
$headerparams['date_endyear'] = $date_endyear;
|
||||
$headerparams['date_endmonth'] = $date_endmonth;
|
||||
$headerparams['date_endday'] = $date_endday;
|
||||
if (!empty($date_startyear)) {
|
||||
$headerparams['date_startyear'] = $date_startyear;
|
||||
}
|
||||
if (!empty($date_startmonth)) {
|
||||
$headerparams['date_startmonth'] = $date_startmonth;
|
||||
}
|
||||
if (!empty($date_startday)) {
|
||||
$headerparams['date_startday'] = $date_startday;
|
||||
}
|
||||
if (!empty($date_endyear)) {
|
||||
$headerparams['date_endyear'] = $date_endyear;
|
||||
}
|
||||
if (!empty($date_endmonth)) {
|
||||
$headerparams['date_endmonth'] = $date_endmonth;
|
||||
}
|
||||
if (!empty($date_endday)) {
|
||||
$headerparams['date_endday'] = $date_endday;
|
||||
}
|
||||
|
||||
$tableparams = array();
|
||||
$tableparams['search_categ'] = $selected_cat;
|
||||
@@ -173,16 +200,7 @@ foreach ($allparams as $key => $value) {
|
||||
$paramslink .= '&'.$key.'='.$value;
|
||||
}
|
||||
|
||||
// Security check
|
||||
if ($user->socid > 0) {
|
||||
$socid = $user->socid;
|
||||
}
|
||||
if (isModEnabled('comptabilite')) {
|
||||
$result = restrictedArea($user, 'compta', '', '', 'resultat');
|
||||
}
|
||||
if (isModEnabled('accounting')) {
|
||||
$result = restrictedArea($user, 'accounting', '', '', 'comptarapport');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -203,6 +221,9 @@ if ($modecompta == "BOOKKEEPINGCOLLECTED") {
|
||||
$modecompta = "RECETTES-DEPENSES";
|
||||
}
|
||||
|
||||
$namelink = '';
|
||||
$builddate = dol_now();
|
||||
|
||||
// Show report header
|
||||
if ($modecompta == "CREANCES-DETTES") {
|
||||
$name = $langs->trans("PurchaseTurnover").', '.$langs->trans("ByThirdParties");
|
||||
@@ -223,7 +244,6 @@ if ($modecompta == "CREANCES-DETTES") {
|
||||
// TODO
|
||||
}
|
||||
|
||||
$builddate = dol_now();
|
||||
$period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver');
|
||||
$period .= ' - ';
|
||||
$period .= $form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver');
|
||||
@@ -235,7 +255,7 @@ if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) {
|
||||
|
||||
$exportlink = '';
|
||||
|
||||
report_header($name, '', $period, $periodlink, $description, $builddate, $exportlink, $tableparams, $calcmode);
|
||||
report_header($name, $namelink, $period, $periodlink, $description, $builddate, $exportlink, $tableparams, $calcmode);
|
||||
|
||||
if (isModEnabled('accounting')) {
|
||||
if ($modecompta != 'BOOKKEEPING') {
|
||||
|
||||
@@ -395,10 +395,6 @@ $parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
||||
$sql .= $hookmanager->resPrint;
|
||||
|
||||
$sql .= $db->order($sortfield, $sortorder);
|
||||
|
||||
//print $sql;
|
||||
|
||||
// Count total nb of records
|
||||
$nbtotalofrecords = '';
|
||||
if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
|
||||
@@ -410,7 +406,7 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
|
||||
}
|
||||
}
|
||||
|
||||
// Complete request and execute it with limit
|
||||
// Complete request and execute it with order and limit
|
||||
$sql .= $db->order($sortfield, $sortorder);
|
||||
if ($limit) {
|
||||
$sql .= $db->plimit($limit + 1, $offset);
|
||||
|
||||
@@ -701,7 +701,7 @@ abstract class CommonObject
|
||||
public $user_creation;
|
||||
|
||||
/**
|
||||
* @var int User id author/creation
|
||||
* @var int|null User id author/creation
|
||||
*/
|
||||
public $user_creation_id;
|
||||
|
||||
@@ -5487,16 +5487,12 @@ abstract class CommonObject
|
||||
}
|
||||
$this->tpl['label'] .= $discount->getNomUrl(0, 'discount');
|
||||
} elseif (!empty($line->fk_product)) {
|
||||
$productstatic = new Product($this->db);
|
||||
$productstatic->id = $line->fk_product;
|
||||
$productstatic->ref = $line->ref;
|
||||
$productstatic->type = $line->fk_product_type;
|
||||
if (empty($productstatic->ref)) {
|
||||
if (empty($line->product)) {
|
||||
$line->fetch_product();
|
||||
$productstatic = $line->product;
|
||||
}
|
||||
$productstatic = $line->product;
|
||||
|
||||
$this->tpl['label'] .= $productstatic->getNomUrl(1);
|
||||
$this->tpl['label'] .= (is_object($productstatic) ? $productstatic->getNomUrl(1) : $line->ref);
|
||||
$this->tpl['label'] .= ' - '.(!empty($line->label) ? $line->label : $line->product_label);
|
||||
// Dates
|
||||
if ($line->product_type == 1 && ($date_start || $date_end)) {
|
||||
@@ -10059,9 +10055,9 @@ abstract class CommonObject
|
||||
/**
|
||||
* Create object in the database
|
||||
*
|
||||
* @param User $user User that creates
|
||||
* @param int<0,1> $notrigger 0=launch triggers after, 1=disable triggers
|
||||
* @return int<-1,max> Return integer <0 if KO, Id of created object if OK
|
||||
* @param User $user User that creates
|
||||
* @param int<0,1> $notrigger 0=launch triggers after, 1=disable triggers
|
||||
* @return int<-1,max> Return integer <0 if KO, Id of created object if OK
|
||||
*/
|
||||
public function createCommon(User $user, $notrigger = 0)
|
||||
{
|
||||
@@ -10080,6 +10076,7 @@ abstract class CommonObject
|
||||
if (array_key_exists('date_creation', $fieldvalues) && empty($fieldvalues['date_creation'])) {
|
||||
$fieldvalues['date_creation'] = $this->db->idate($now);
|
||||
}
|
||||
// For backward compatibility, if a property ->fk_user_creat exists and not filled.
|
||||
if (array_key_exists('fk_user_creat', $fieldvalues) && !($fieldvalues['fk_user_creat'] > 0)) {
|
||||
$fieldvalues['fk_user_creat'] = $user->id;
|
||||
$this->fk_user_creat = $user->id;
|
||||
|
||||
@@ -58,8 +58,11 @@ class FileUpload
|
||||
$this->element = $element;
|
||||
|
||||
$pathname = str_replace('/class', '', $element_prop['classpath']);
|
||||
|
||||
|
||||
$filename = dol_sanitizeFileName($element_prop['classfile']);
|
||||
$dir_output = dol_sanitizePathName($element_prop['dir_output']);
|
||||
$savingDocMask = '';
|
||||
|
||||
//print 'fileupload.class.php: element='.$element.' pathname='.$pathname.' filename='.$filename.' dir_output='.$dir_output."\n";
|
||||
|
||||
@@ -75,6 +78,11 @@ class FileUpload
|
||||
|
||||
$object_ref = dol_sanitizeFileName($object->ref);
|
||||
|
||||
// add object reference as file name prefix if const MAIN_DISABLE_SUGGEST_REF_AS_PREFIX is not enabled
|
||||
if (!getDolGlobalInt('MAIN_DISABLE_SUGGEST_REF_AS_PREFIX')) {
|
||||
$savingDocMask = $object_ref.'-__file__';
|
||||
}
|
||||
|
||||
// Special cases to forge $object_ref used to forge $upload_dir
|
||||
if ($element == 'invoice_supplier') {
|
||||
$object_ref = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$object_ref;
|
||||
@@ -100,6 +108,7 @@ class FileUpload
|
||||
'script_url' => $_SERVER['PHP_SELF'],
|
||||
'upload_dir' => $dir_output.'/'.$object_ref.'/',
|
||||
'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.$element.'&attachment=1&file=/'.$object_ref.'/',
|
||||
'saving_doc_mask' => $savingDocMask,
|
||||
'param_name' => 'files',
|
||||
// Set the following option to 'POST', if your server does not support
|
||||
// DELETE requests. This is a parameter sent to the client:
|
||||
@@ -425,6 +434,14 @@ class FileUpload
|
||||
|
||||
if ($validate) {
|
||||
if (dol_mkdir($this->options['upload_dir']) >= 0) {
|
||||
// add object reference as file name prefix if const MAIN_DISABLE_SUGGEST_REF_AS_PREFIX is not enabled
|
||||
$fileNameWithoutExt = preg_replace('/\.[^\.]+$/', '', $file->name);
|
||||
$savingDocMask = $this->options['saving_doc_mask'];
|
||||
if ($savingDocMask && strpos($savingDocMask, $fileNameWithoutExt) !== 0) {
|
||||
$fileNameWithPrefix = preg_replace('/__file__/', $file->name, $savingDocMask);
|
||||
$file->name = $fileNameWithPrefix;
|
||||
}
|
||||
|
||||
$file_path = dol_sanitizePathName($this->options['upload_dir']).dol_sanitizeFileName($file->name);
|
||||
$append_file = !$this->options['discard_aborted_uploads'] && dol_is_file($file_path) && $file->size > dol_filesize($file_path);
|
||||
|
||||
|
||||
@@ -4596,7 +4596,7 @@ class Form
|
||||
if (depositPercent.length > 0) {
|
||||
$("#' . $htmlname . '_deposit_percent_container").show().find("#' . $htmlname . '_deposit_percent").val(depositPercent);
|
||||
} else {
|
||||
$("#' . $htmlname . '_deposit_percent_container").hide();
|
||||
$("#' . $htmlname . '_deposit_percent_container").hide().find("#' . $htmlname . '_deposit_percent").val(0);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -3296,7 +3296,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
|
||||
} elseif (isModEnabled("service")) {
|
||||
$original_file = $conf->service->multidir_output[$entity].'/'.$original_file;
|
||||
}
|
||||
} elseif ($modulepart == 'product_batch' || $modulepart == 'produitlot') {
|
||||
} elseif ($modulepart == 'product_batch' || $modulepart == 'productlot') {
|
||||
// Wrapping pour les lots produits
|
||||
if (empty($entity) || (empty($conf->productbatch->multidir_output[$entity]))) {
|
||||
return array('accessallowed' => 0, 'error' => 'Value entity must be provided');
|
||||
|
||||
@@ -13502,7 +13502,7 @@ function forgeSQLFromUniversalSearchCriteria($filter, &$errorstr = '', $noand =
|
||||
$ret = ($noand ? "" : " AND ").($nopar ? "" : '(').preg_replace_callback('/'.$regexstring.'/i', 'dolForgeCriteriaCallback', $filter).($nopar ? "" : ')');
|
||||
|
||||
if (is_object($db)) {
|
||||
$ret = str_replace('__NOW__', $db->idate(dol_now()), $ret);
|
||||
$ret = str_replace('__NOW__', "'".$db->idate(dol_now())."'", $ret);
|
||||
}
|
||||
if (is_object($user)) {
|
||||
$ret = str_replace('__USER_ID__', (string) $user->id, $ret);
|
||||
@@ -13733,8 +13733,10 @@ function dolForgeCriteriaCallback($matches)
|
||||
$tmpescaped = 'NULL';
|
||||
} elseif (is_int($tmpescaped)) {
|
||||
$tmpescaped = (int) $tmpescaped;
|
||||
} else {
|
||||
} elseif (is_numeric((string) $tmpescaped)) { // it can be a float with a .
|
||||
$tmpescaped = (float) $tmpescaped;
|
||||
} else {
|
||||
$tmpescaped = preg_replace('/[^a-z0-9_]/i', '', $tmpescaped); // it can be a name of field or a substitution variable like '__NOW__'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1, $o
|
||||
if ($mode == 1) {
|
||||
$out .= "hash('".$securekeyseed."' + '".$type."' + $type + '_ref)";
|
||||
} else {
|
||||
$out .= '&securekey='.dol_hash($securekeyseed.$type.$ref.(!isModEnabled('multicompany') ? '' : $object->entity), '0');
|
||||
$out .= '&securekey='.dol_hash($securekeyseed.$type.$ref.(!isModEnabled('multicompany') ? '' : $obj->entity), '0');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ class modAdherent extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "MEMBER_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/members";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/members";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -438,8 +438,8 @@ class modAdherent extends DolibarrModules
|
||||
|
||||
// ODT template
|
||||
/*
|
||||
$src=DOL_DOCUMENT_ROOT.'/install/doctemplates/orders/template_order.odt';
|
||||
$dirodt=DOL_DATA_ROOT.'/doctemplates/orders';
|
||||
$src=DOL_DOCUMENT_ROOT.'/install/doctemplates/members/template_member.odt';
|
||||
$dirodt=DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/members';
|
||||
$dest=$dirodt.'/template_order.odt';
|
||||
|
||||
if (file_exists($src) && ! file_exists($dest)) {
|
||||
|
||||
@@ -127,7 +127,7 @@ class modBom extends DolibarrModules
|
||||
$this->const = array(
|
||||
1 => array('BOM_ADDON_PDF', 'chaine', 'generic_bom_odt', 'Name of PDF model of BOM', 0),
|
||||
2 => array('BOM_ADDON', 'chaine', 'mod_bom_standard', 'Name of numbering rules of BOM', 0),
|
||||
3 => array('BOM_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/boms', '', 0)
|
||||
3 => array('BOM_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT'.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/boms', '', 0)
|
||||
);
|
||||
|
||||
// Some keys to add into the overwriting translation tables
|
||||
@@ -479,7 +479,7 @@ class modBom extends DolibarrModules
|
||||
|
||||
// ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/boms/template_bom.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/boms';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/boms';
|
||||
$dest = $dirodt.'/template_bom.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -94,7 +94,7 @@ class modCommande extends DolibarrModules
|
||||
$r++;
|
||||
$this->const[$r][0] = "COMMANDE_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/orders";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/orders";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
|
||||
@@ -459,7 +459,7 @@ class modCommande extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/orders/template_order.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/orders';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/orders';
|
||||
$dest = $dirodt.'/template_order.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -87,7 +87,7 @@ class modContrat extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "CONTRACT_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/contracts";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/contracts";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -230,7 +230,7 @@ class modContrat extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/contracts/template_contract.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/contracts';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/contracts';
|
||||
$dest = $dirodt.'/template_contract.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -99,7 +99,7 @@ class modExpedition extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "EXPEDITION_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/shipments";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/shipments";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -120,7 +120,7 @@ class modExpedition extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "DELIVERY_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/deliveries";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/deliveries";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -343,7 +343,7 @@ class modExpedition extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/shipments/template_shipment.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/shipments';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/shipments';
|
||||
$dest = $dirodt.'/template_shipment.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -95,7 +95,7 @@ class modFacture extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "FACTURE_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/invoices";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/invoices";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -773,7 +773,7 @@ class modFacture extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/invoices/template_invoice.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/invoices';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/invoices';
|
||||
$dest = $dirodt.'/template_invoice.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -117,7 +117,7 @@ class modFournisseur extends DolibarrModules
|
||||
// Add ability ODT for Supplier orders
|
||||
$this->const[$r][0] = "SUPPLIER_ORDER_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/supplier_orders";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/supplier_orders";
|
||||
$this->const[$r][3] = '';
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -125,7 +125,7 @@ class modFournisseur extends DolibarrModules
|
||||
// Add ability ODT for Supplier Invoices
|
||||
$this->const[$r][0] = "SUPPLIER_INVOICE_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/supplier_invoices";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -972,7 +972,7 @@ class modFournisseur extends DolibarrModules
|
||||
|
||||
//ODT template for Supplier Orders
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_orders/template_supplier_order.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/supplier_orders';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/supplier_orders';
|
||||
$dest = $dirodt.'/template_supplier_order.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
@@ -993,7 +993,7 @@ class modFournisseur extends DolibarrModules
|
||||
|
||||
//ODT template for Supplier Invoice
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_invoices/template_supplier_invoices.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/supplier_invoices';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/supplier_invoices';
|
||||
$dest = $dirodt.'/template_supplier_invoices.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -111,7 +111,7 @@ class modHoliday extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "HOLIDAY_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/holiday";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/holiday";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -308,7 +308,7 @@ class modHoliday extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
/*$src=DOL_DOCUMENT_ROOT.'/install/doctemplates/holiday/template_holiday.odt';
|
||||
$dirodt=DOL_DATA_ROOT.'/doctemplates/holiday';
|
||||
$dirodt=DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/holiday';
|
||||
$dest=$dirodt.'/template_order.odt';
|
||||
|
||||
if (file_exists($src) && ! file_exists($dest))
|
||||
|
||||
@@ -138,7 +138,7 @@ class modMrp extends DolibarrModules
|
||||
$this->const = array(
|
||||
//1=>array('MRP_MO_ADDON_PDF', 'chaine', 'vinci', 'Name of default PDF model of MO', 0),
|
||||
2=>array('MRP_MO_ADDON', 'chaine', 'mod_mo_standard', 'Name of numbering rules of MO', 0),
|
||||
3=>array('MRP_MO_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/mrps', '', 0)
|
||||
3=>array('MRP_MO_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT'.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/mrps', '', 0)
|
||||
);
|
||||
|
||||
// Some keys to add into the overwriting translation tables
|
||||
@@ -442,7 +442,7 @@ class modMrp extends DolibarrModules
|
||||
|
||||
// ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/mrps/template_mo.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/mrps';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/mrps';
|
||||
$dest = $dirodt.'/template_mo.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -92,7 +92,7 @@ class modProjet extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "PROJECT_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/projects";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/projects";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -113,7 +113,7 @@ class modProjet extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "PROJECT_TASK_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/tasks";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/tasks";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -379,7 +379,7 @@ class modProjet extends DolibarrModules
|
||||
|
||||
//ODT template for project
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/projects/template_project.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/projects';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/projects';
|
||||
$dest = $dirodt.'/template_project.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
@@ -395,7 +395,7 @@ class modProjet extends DolibarrModules
|
||||
|
||||
//ODT template for tasks
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/tasks/template_task_summary.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/tasks';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/tasks';
|
||||
$dest = $dirodt.'/template_task_summary.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -99,7 +99,7 @@ class modPropale extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "PROPALE_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/proposals";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/proposals";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -489,7 +489,7 @@ class modPropale extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/proposals/template_proposal.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/proposals';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/proposals';
|
||||
$dest = $dirodt.'/template_proposal.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -91,7 +91,7 @@ class modReception extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "RECEPTION_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/receptions";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/receptions";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -266,7 +266,7 @@ class modReception extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/reception/template_reception.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/reception';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/reception';
|
||||
$dest = $dirodt.'/template_reception.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -101,7 +101,7 @@ class modSociete extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "COMPANY_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/thirdparties";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/thirdparties";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
$r++;
|
||||
@@ -947,7 +947,7 @@ class modSociete extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/thirdparties/template_thirdparty.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/thirdparties';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/thirdparties';
|
||||
$dest = $dirodt.'/template_thirdparty.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -96,14 +96,14 @@ class modStock extends DolibarrModules
|
||||
$r++;
|
||||
$this->const[$r][0] = "STOCK_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/stocks";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/stocks";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
|
||||
$r++;
|
||||
$this->const[$r][0] = "MOUVEMENT_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/stocks/movements";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/stocks/movements";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
|
||||
@@ -538,7 +538,7 @@ class modStock extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/stocks/template_warehouse.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/stocks';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/stocks';
|
||||
$dest = $dirodt.'/template_warehouse.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -92,7 +92,7 @@ class modSupplierProposal extends DolibarrModules
|
||||
|
||||
$this->const[$r][0] = "SUPPLIER_PROPOSAL_ADDON_PDF_ODT_PATH";
|
||||
$this->const[$r][1] = "chaine";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/supplier_proposals";
|
||||
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/supplier_proposals";
|
||||
$this->const[$r][3] = "";
|
||||
$this->const[$r][4] = 0;
|
||||
|
||||
@@ -163,7 +163,7 @@ class modSupplierProposal extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_proposals/template_supplier_proposal.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/supplier_proposals';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/supplier_proposals';
|
||||
$dest = $dirodt.'/template_supplier_proposal.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -110,7 +110,7 @@ class modTicket extends DolibarrModules
|
||||
$this->const = array(
|
||||
1 => array('TICKET_ENABLE_PUBLIC_INTERFACE', 'chaine', '0', 'Enable ticket public interface', 0),
|
||||
2 => array('TICKET_ADDON', 'chaine', 'mod_ticket_simple', 'Ticket ref module', 0),
|
||||
3 => array('TICKET_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/tickets', 'Ticket templates ODT/ODS directory for templates', 0),
|
||||
3 => array('TICKET_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT'.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/tickets', 'Ticket templates ODT/ODS directory for templates', 0),
|
||||
4 => array('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND', 'chaine', 0, 'Automatically mark ticket as read when created from backend', 0),
|
||||
5 => array('TICKET_DELAY_BEFORE_FIRST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time before a first answer to a ticket (in hours). Display a warning in tickets list if not respected.', 0),
|
||||
6 => array('TICKET_DELAY_SINCE_LAST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time between two answers on the same ticket (in hours). Display a warning in tickets list if not respected.', 0),
|
||||
@@ -414,7 +414,7 @@ class modTicket extends DolibarrModules
|
||||
|
||||
//ODT template
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/tickets/template_ticket.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/tickets';
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/tickets';
|
||||
$dest = $dirodt.'/template_ticket.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -269,13 +269,14 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
|
||||
$pdf = pdf_getInstance($this->format);
|
||||
$default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
|
||||
$heightforinfotot = 50; // Height reserved to output the info and total part
|
||||
$pdf->SetAutoPageBreak(1, 0);
|
||||
|
||||
$heightforinfotot = 40; // Height reserved to output the info and total part
|
||||
$heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page
|
||||
$heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
|
||||
if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
|
||||
$heightforfooter += 6;
|
||||
}
|
||||
$pdf->SetAutoPageBreak(1, 0);
|
||||
|
||||
if (class_exists('TCPDF')) {
|
||||
$pdf->setPrintHeader(false);
|
||||
@@ -328,6 +329,8 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
|
||||
$tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
|
||||
|
||||
$nexY = $tab_top - 1;
|
||||
|
||||
// Incoterm
|
||||
$height_incoterms = 0;
|
||||
if (isModEnabled('incoterm')) {
|
||||
@@ -337,7 +340,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
|
||||
$pdf->SetFont('', '', $default_font_size - 1);
|
||||
$pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
|
||||
$nexY = $pdf->GetY();
|
||||
$nexY = max($pdf->GetY(), $nexY);
|
||||
$height_incoterms = $nexY - $tab_top;
|
||||
|
||||
// Rect takes a length in 3rd parameter
|
||||
@@ -360,6 +363,8 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
|
||||
$pagenb = $pdf->getPage();
|
||||
if (!empty($notetoshow)) {
|
||||
$tab_top -= 2;
|
||||
|
||||
$tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
|
||||
$pageposbeforenote = $pagenb;
|
||||
|
||||
@@ -368,8 +373,6 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
$notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
|
||||
$notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
|
||||
|
||||
$tab_top -= 2;
|
||||
|
||||
$pdf->startTransaction();
|
||||
|
||||
$pdf->SetFont('', '', $default_font_size - 1);
|
||||
@@ -484,21 +487,11 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
// Use new auto column system
|
||||
$this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
||||
|
||||
$nexY = $tab_top + $this->tabTitleHeight;
|
||||
|
||||
$pageposbeforeprintlines = $pdf->getPage();
|
||||
$pagenb = $pageposbeforeprintlines;
|
||||
|
||||
// Show square
|
||||
if ($pagenb == $pageposbeforeprintlines) {
|
||||
$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
|
||||
$bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
|
||||
} else {
|
||||
$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
|
||||
$bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
|
||||
}
|
||||
|
||||
$nexY = $tab_top + $this->tabTitleHeight;
|
||||
|
||||
// Loop on each lines
|
||||
for ($i = 0; $i < $nblines; $i++) {
|
||||
$curY = $nexY;
|
||||
@@ -547,20 +540,20 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
}
|
||||
|
||||
// Description of product line
|
||||
$curX = $this->posxdesc - 1;
|
||||
$showpricebeforepagebreak = 1;
|
||||
|
||||
if ($this->getColumnStatus('desc')) {
|
||||
$pdf->startTransaction();
|
||||
|
||||
$this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
|
||||
|
||||
$pageposafter = $pdf->getPage();
|
||||
|
||||
if ($pageposafter > $pageposbefore) { // There is a pagebreak
|
||||
$pdf->rollbackTransaction(true);
|
||||
$pageposafter = $pageposbefore;
|
||||
$pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
|
||||
|
||||
$this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
|
||||
|
||||
$pageposafter = $pdf->getPage();
|
||||
$posyafter = $pdf->GetY();
|
||||
if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
|
||||
@@ -587,8 +580,10 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
$posYAfterDescription = $pdf->GetY();
|
||||
}
|
||||
|
||||
$nexY = $pdf->GetY();
|
||||
$nexY = max($pdf->GetY(), $posYAfterImage);
|
||||
|
||||
$pageposafter = $pdf->getPage();
|
||||
|
||||
$pdf->setPage($pageposbefore);
|
||||
$pdf->setTopMargin($this->marge_haute);
|
||||
$pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
|
||||
@@ -790,6 +785,14 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
}
|
||||
}
|
||||
|
||||
// Show square
|
||||
if ($pagenb == $pageposbeforeprintlines) {
|
||||
$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis);
|
||||
} else {
|
||||
$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis);
|
||||
}
|
||||
$bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
|
||||
|
||||
// Affiche zone infos
|
||||
$posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
|
||||
|
||||
@@ -1143,9 +1146,10 @@ class pdf_cornas extends ModelePDFSuppliersOrders
|
||||
* @param int $hidetop Hide top bar of array
|
||||
* @param int $hidebottom Hide bottom bar of array
|
||||
* @param string $currency Currency code
|
||||
* @param Translate $outputlangsbis Langs object bis
|
||||
* @return void
|
||||
*/
|
||||
protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
|
||||
protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
|
||||
@@ -998,9 +998,10 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
|
||||
* @param int $hidetop Hide top bar of array
|
||||
* @param int $hidebottom Hide bottom bar of array
|
||||
* @param string $currency Currency code
|
||||
* @param Translate $outputlangsbis Langs object bis
|
||||
* @return void
|
||||
*/
|
||||
protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
|
||||
protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
|
||||
@@ -773,13 +773,16 @@ if ($object->id > 0 || !empty($object->ref)) {
|
||||
print '</td>'; // Dispatch column
|
||||
print '<td></td>'; // Warehouse column
|
||||
|
||||
$sql = "SELECT ed.rowid, ed.qty, ed.fk_entrepot,";
|
||||
$sql .= " eb.batch, eb.eatby, eb.sellby, cd.fk_product";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed";
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."expeditiondet_batch as eb on ed.rowid = eb.fk_expeditiondet";
|
||||
$sql .= " JOIN ".MAIN_DB_PREFIX."commandedet as cd on ed.fk_elementdet = cd.rowid";
|
||||
$sql .= " WHERE ed.fk_elementdet =".(int) $objp->rowid;
|
||||
$sql .= " AND ed.fk_expedition =".(int) $object->id;
|
||||
$sql = "SELECT ed.rowid";
|
||||
$sql .= ", cd.fk_product";
|
||||
$sql .= ", ".$db->ifsql('eb.rowid IS NULL', 'ed.qty', 'eb.qty')." as qty";
|
||||
$sql .= ", ed.fk_entrepot";
|
||||
$sql .= ", eb.batch, eb.eatby, eb.sellby";
|
||||
$sql .= " FROM ".$db->prefix()."expeditiondet as ed";
|
||||
$sql .= " LEFT JOIN ".$db->prefix()."expeditiondet_batch as eb on ed.rowid = eb.fk_expeditiondet";
|
||||
$sql .= " INNER JOIN ".$db->prefix()."commandedet as cd on ed.fk_origin_line = cd.rowid";
|
||||
$sql .= " WHERE ed.fk_origin_line = ".(int) $objp->rowid;
|
||||
$sql .= " AND ed.fk_expedition = ".(int) $object->id;
|
||||
$sql .= " ORDER BY ed.rowid, ed.fk_elementdet";
|
||||
|
||||
$resultsql = $db->query($sql);
|
||||
|
||||
@@ -35,7 +35,7 @@ if (!defined('DOL_APPLICATION_TITLE')) {
|
||||
define('DOL_APPLICATION_TITLE', 'Dolibarr');
|
||||
}
|
||||
if (!defined('DOL_VERSION')) {
|
||||
define('DOL_VERSION', '20.0.4'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
|
||||
define('DOL_VERSION', '20.0.5'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
|
||||
}
|
||||
|
||||
if (!defined('EURO')) {
|
||||
|
||||
@@ -1684,8 +1684,13 @@ class CommandeFournisseur extends CommonOrder
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
$this->db->commit();
|
||||
return $this->id;
|
||||
if (!$error) {
|
||||
$this->db->commit();
|
||||
return $this->id;
|
||||
} else {
|
||||
$this->db->rollback();
|
||||
return -4;
|
||||
}
|
||||
} else {
|
||||
$this->error = $this->db->lasterror();
|
||||
$this->db->rollback();
|
||||
|
||||
@@ -1962,6 +1962,7 @@ if ($action == 'create') {
|
||||
|
||||
|
||||
$formconfirm = '';
|
||||
$text = '';
|
||||
|
||||
// Confirmation de la suppression de la commande
|
||||
if ($action == 'delete') {
|
||||
|
||||
@@ -722,6 +722,7 @@ if (empty($reshook)) {
|
||||
unset($_POST['date_end_fill']);
|
||||
unset($_POST['situations']);
|
||||
unset($_POST['progress']);
|
||||
unset($_POST['fourn_ref']);
|
||||
} else {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
}
|
||||
@@ -864,6 +865,7 @@ if (empty($reshook)) {
|
||||
unset($_POST['date_endyear']);
|
||||
unset($_POST['situations']);
|
||||
unset($_POST['progress']);
|
||||
unset($_POST['fourn_ref']);
|
||||
} else {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
}
|
||||
|
||||
@@ -910,7 +910,7 @@ if (empty($reshook)) {
|
||||
$object->fk_incoterms = GETPOSTINT('incoterm_id');
|
||||
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
||||
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
|
||||
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
|
||||
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
|
||||
$object->transport_mode_id = GETPOSTINT('transport_mode_id');
|
||||
|
||||
// Proprietes particulieres a facture avoir
|
||||
@@ -1013,7 +1013,7 @@ if (empty($reshook)) {
|
||||
$object->fk_incoterms = GETPOSTINT('incoterm_id');
|
||||
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
||||
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
|
||||
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
|
||||
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
|
||||
|
||||
// Source facture
|
||||
$object->fac_rec = $fac_recid;
|
||||
@@ -1080,7 +1080,7 @@ if (empty($reshook)) {
|
||||
$object->fk_incoterms = GETPOSTINT('incoterm_id');
|
||||
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
||||
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
|
||||
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
|
||||
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
|
||||
$object->transport_mode_id = GETPOSTINT('transport_mode_id');
|
||||
|
||||
// Auto calculation of date due if not filled by user
|
||||
@@ -1122,7 +1122,7 @@ if (empty($reshook)) {
|
||||
$object->origin_id = GETPOSTINT('originid');
|
||||
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
|
||||
dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
|
||||
$classname = ucfirst($subelement);
|
||||
if ($classname == 'Fournisseur.commande') {
|
||||
$classname = 'CommandeFournisseur';
|
||||
@@ -1150,7 +1150,7 @@ if (empty($reshook)) {
|
||||
|
||||
// Add lines
|
||||
if ($id > 0) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
|
||||
dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
|
||||
$classname = ucfirst($subelement);
|
||||
if ($classname == 'Fournisseur.commande') {
|
||||
$classname = 'CommandeFournisseur';
|
||||
@@ -2121,7 +2121,7 @@ if ($action == 'create') {
|
||||
$subelement = 'fournisseur.commande';
|
||||
}
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
|
||||
dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
|
||||
$classname = ucfirst($subelement);
|
||||
if ($classname == 'Fournisseur.commande') {
|
||||
$classname = 'CommandeFournisseur';
|
||||
|
||||
@@ -284,6 +284,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
|
||||
$sql_skill .= " FROM ".MAIN_DB_PREFIX."hrm_skillrank AS sr";
|
||||
$sql_skill .= " JOIN ".MAIN_DB_PREFIX."hrm_skill AS s ON sr.fk_skill = s.rowid";
|
||||
$sql_skill .= " AND sr.fk_object = ".((int) $id);
|
||||
$sql_skill .= " AND sr.objecttype = '".$db->escape($objecttype)."'";
|
||||
$result = $db->query($sql_skill);
|
||||
$numSkills = $db->num_rows($result);
|
||||
$TSkillsJob = array();
|
||||
|
||||
@@ -214,13 +214,13 @@ function testSqlAndScriptInject($val, $type)
|
||||
|
||||
// List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp and https://developer.mozilla.org/en-US/docs/Web/Events
|
||||
$inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)[a-z]*\s*=/i', $val); // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)>
|
||||
$inj += preg_match('/on(abort|after|animation|auxclick|before|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)[a-z]*\s*=/i', $val);
|
||||
$inj += preg_match('/on(abort|after|animation|auxclick|before|blur|bounce|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)[a-z]*\s*=/i', $val);
|
||||
$inj += preg_match('/on(dblclick|drop|durationchange|emptied|end|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)[a-z]*\s*=/i', $val);
|
||||
$inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)[a-z]*\s*=/i', $val);
|
||||
$inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)[a-z]*\s*=/i', $val);
|
||||
$inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)[a-z]*\s*=/i', $val);
|
||||
// More not into the previous list
|
||||
$inj += preg_match('/on(repeat|begin|finish|beforeinput)[a-z]*\s*=/i', $val);
|
||||
$inj += preg_match('/on(repeat|begin|finish)[a-z]*\s*=/i', $val);
|
||||
|
||||
// We refuse html into html because some hacks try to obfuscate evil strings by inserting HTML into HTML.
|
||||
// Example: <img on<a>error=alert(1) or <img onerror<>=alert(1) to bypass test on onerror=
|
||||
@@ -228,13 +228,13 @@ function testSqlAndScriptInject($val, $type)
|
||||
|
||||
// List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp and https://developer.mozilla.org/en-US/docs/Web/Events
|
||||
$inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)[a-z]*\s*=/i', $tmpval); // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)>
|
||||
$inj += preg_match('/on(abort|after|animation|auxclick|before|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)[a-z]*\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(abort|after|animation|auxclick|before|blur|bounce|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)[a-z]*\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(dblclick|drop|durationchange|emptied|end|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)[a-z]*\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)[a-z]*\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)[a-z]*\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)[a-z]*\s*=/i', $tmpval);
|
||||
// More not into the previous list
|
||||
$inj += preg_match('/on(repeat|begin|finish|beforeinput)[a-z]*\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(repeat|begin|finish)[a-z]*\s*=/i', $tmpval);
|
||||
|
||||
//$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ...
|
||||
$inj += preg_match('/:|:|:/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...'
|
||||
|
||||
@@ -496,7 +496,7 @@ class modMyModule extends DolibarrModules
|
||||
}
|
||||
if ($myTmpObjectArray['includerefgeneration']) {
|
||||
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/'.$moduledir.'/template_myobjects.odt';
|
||||
$dirodt = DOL_DATA_ROOT.'/doctemplates/'.$moduledir;
|
||||
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/'.$moduledir;
|
||||
$dest = $dirodt.'/template_myobjects.odt';
|
||||
|
||||
if (file_exists($src) && !file_exists($dest)) {
|
||||
|
||||
@@ -657,7 +657,7 @@ if (empty($conf->use_javascript_ajax)) {
|
||||
'2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')',
|
||||
'3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')',
|
||||
);
|
||||
print $form->selectarray("activate_usesearchtoselectproduct", $arrval, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT);
|
||||
print $form->selectarray("activate_usesearchtoselectproduct", $arrval, getDolGlobalString('PRODUIT_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth400');
|
||||
print '</td>';
|
||||
}
|
||||
print '</tr>';
|
||||
|
||||
@@ -5198,8 +5198,6 @@ class Product extends CommonObject
|
||||
*/
|
||||
public function getChildsArbo($id, $firstlevelonly = 0, $level = 1, $parents = array())
|
||||
{
|
||||
global $alreadyfound;
|
||||
|
||||
if (empty($id)) {
|
||||
return array();
|
||||
}
|
||||
@@ -5216,9 +5214,6 @@ class Product extends CommonObject
|
||||
|
||||
dol_syslog(get_class($this).'::getChildsArbo id='.$id.' level='.$level. ' parents='.(is_array($parents) ? implode(',', $parents) : $parents), LOG_DEBUG);
|
||||
|
||||
if ($level == 1) {
|
||||
$alreadyfound = array($id => 1); // We init array of found object to start of tree, so if we found it later (should not happened), we stop immediately
|
||||
}
|
||||
// Protection against infinite loop
|
||||
if ($level > 30) {
|
||||
return array();
|
||||
@@ -5227,14 +5222,16 @@ class Product extends CommonObject
|
||||
$res = $this->db->query($sql);
|
||||
if ($res) {
|
||||
$prods = array();
|
||||
if ($this->db->num_rows($res) > 0) {
|
||||
$parents[] = $id;
|
||||
}
|
||||
|
||||
while ($rec = $this->db->fetch_array($res)) {
|
||||
if (!empty($alreadyfound[$rec['rowid']])) {
|
||||
if (in_array($rec['id'], $parents)) {
|
||||
dol_syslog(get_class($this).'::getChildsArbo the product id='.$rec['rowid'].' was already found at a higher level in tree. We discard to avoid infinite loop', LOG_WARNING);
|
||||
if (in_array($rec['id'], $parents)) {
|
||||
continue; // We discard this child if it is already found at a higher level in tree in the same branch.
|
||||
}
|
||||
continue; // We discard this child if it is already found at a higher level in tree in the same branch.
|
||||
}
|
||||
$alreadyfound[$rec['rowid']] = 1;
|
||||
|
||||
$prods[$rec['rowid']] = array(
|
||||
0 => $rec['rowid'],
|
||||
1 => $rec['qty'],
|
||||
@@ -5248,7 +5245,6 @@ class Product extends CommonObject
|
||||
//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty'],2=>$rec['fk_product_type']);
|
||||
//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty']);
|
||||
if (empty($firstlevelonly)) {
|
||||
$parents[] = $rec['rowid'];
|
||||
$listofchilds = $this->getChildsArbo($rec['rowid'], 0, $level + 1, $parents);
|
||||
foreach ($listofchilds as $keyChild => $valueChild) {
|
||||
$prods[$rec['rowid']]['childs'][$keyChild] = $valueChild;
|
||||
|
||||
@@ -139,7 +139,7 @@ class Task extends CommonObjectLine
|
||||
public $timespent_old_duration;
|
||||
public $timespent_date;
|
||||
public $timespent_datehour; // More accurate start date (same than timespent_date but includes hours, minutes and seconds)
|
||||
public $timespent_withhour; // 1 = we entered also start hours for timesheet line
|
||||
public $timespent_withhour; // 0 or 1 = we have entered also start hours for timesheet line
|
||||
public $timespent_fk_user;
|
||||
public $timespent_thm;
|
||||
public $timespent_note;
|
||||
@@ -1467,10 +1467,9 @@ class Task extends CommonObjectLine
|
||||
$timespent->fk_user = $this->timespent_fk_user;
|
||||
$timespent->fk_product = $this->timespent_fk_product;
|
||||
$timespent->note = $this->timespent_note;
|
||||
$timespent->datec = $this->db->idate($now);
|
||||
$timespent->datec = $now;
|
||||
|
||||
$result = $timespent->create($user);
|
||||
|
||||
if ($result > 0) {
|
||||
$ret = $result;
|
||||
$this->timespent_id = $result;
|
||||
|
||||
@@ -175,7 +175,6 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
|
||||
$search_year = '';
|
||||
$search_note = '';
|
||||
$search_duration = '';
|
||||
$search_value = '';
|
||||
$search_date_startday = '';
|
||||
$search_date_startmonth = '';
|
||||
$search_date_startyear = '';
|
||||
@@ -249,6 +248,7 @@ if ($action == 'addtimespent' && $user->hasRight('projet', 'time')) {
|
||||
$object->timespent_withhour = 1;
|
||||
} else {
|
||||
$object->timespent_date = dol_mktime(12, 0, 0, GETPOSTINT("timemonth"), GETPOSTINT("timeday"), GETPOSTINT("timeyear"));
|
||||
$object->timespent_withhour = 0;
|
||||
}
|
||||
$object->timespent_fk_user = GETPOSTINT("userid");
|
||||
$object->timespent_fk_product = GETPOSTINT("fk_product");
|
||||
@@ -299,6 +299,7 @@ if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $us
|
||||
$object->timespent_withhour = 1;
|
||||
} else {
|
||||
$object->timespent_date = dol_mktime(12, 0, 0, GETPOST("timelinemonth"), GETPOST("timelineday"), GETPOST("timelineyear"));
|
||||
$object->timespent_withhour = 0;
|
||||
}
|
||||
$object->timespent_fk_user = GETPOSTINT("userid_line");
|
||||
$object->timespent_fk_product = GETPOSTINT("fk_product");
|
||||
@@ -328,6 +329,7 @@ if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $us
|
||||
$object->timespent_withhour = 1;
|
||||
} else {
|
||||
$object->timespent_date = dol_mktime(12, 0, 0, GETPOSTINT("timelinemonth"), GETPOSTINT("timelineday"), GETPOSTINT("timelineyear"));
|
||||
$object->timespent_withhour = 0;
|
||||
}
|
||||
$object->timespent_fk_user = GETPOSTINT("userid_line");
|
||||
$object->timespent_fk_product = GETPOSTINT("fk_product");
|
||||
|
||||
@@ -1441,7 +1441,7 @@ print '</form>';
|
||||
$db->free($resql);
|
||||
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || !empty($show_files)) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -201,6 +201,13 @@ class SecurityTest extends CommonClassTest
|
||||
$result = testSqlAndScriptInject($test, 0);
|
||||
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject bbb');
|
||||
|
||||
$test='<marquee onbeforeintput="alert(1)">';
|
||||
$result=testSqlAndScriptInject($test, 0);
|
||||
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject onbeforeintput');
|
||||
$test='<marquee onbounce="alert(1)">';
|
||||
$result=testSqlAndScriptInject($test, 0);
|
||||
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject onbounce');
|
||||
|
||||
$test = '<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>';
|
||||
$result = testSqlAndScriptInject($test, 0);
|
||||
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ccc');
|
||||
@@ -1094,6 +1101,7 @@ class SecurityTest extends CommonClassTest
|
||||
$this->assertEquals('358080.38', $result);
|
||||
|
||||
global $leftmenu; // Used into strings to eval
|
||||
$conf->global->MAIN_FEATURES_LEVEL = 1;
|
||||
|
||||
$leftmenu = 'AAA';
|
||||
$result = dol_eval('$conf->currency && preg_match(\'/^(AAA|BBB)/\',$leftmenu)', 1, 1, '1');
|
||||
@@ -1116,7 +1124,7 @@ class SecurityTest extends CommonClassTest
|
||||
print "result16 = ".$result."\n";
|
||||
$this->assertFalse($result);
|
||||
|
||||
$string = '(isModEnabled("agenda") || isModEnabled("resource")) && getDolGlobalInt("MAIN_FEATURES_LEVEL") >= 0 && preg_match(\'/^(admintools|all|XXX)/\', $leftmenu)';
|
||||
$string = '(isModEnabled("user") || isModEnabled("resource")) && getDolGlobalInt("MAIN_FEATURES_LEVEL") >= 0 && preg_match(\'/^(admintools|all|XXX)/\', $leftmenu)';
|
||||
$result = dol_eval($string, 1, 1, '1');
|
||||
print "result17 = ".$result."\n";
|
||||
$this->assertTrue($result);
|
||||
|
||||
Reference in New Issue
Block a user