From 4981404a1a5cda5db662a86aa211f9960e00a669 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jul 2026 14:24:54 +0200 Subject: [PATCH] Debug v24 --- htdocs/core/class/commonobject.class.php | 7 +-- htdocs/core/tpl/objectline_edit.tpl.php | 50 ++++++++++++------- htdocs/core/tpl/objectline_view.tpl.php | 61 +++++++++++++++++------- htdocs/theme/eldy/btn.inc.php | 4 +- htdocs/theme/md/btn.inc.php | 4 +- 5 files changed, 83 insertions(+), 43 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 6e7fff8de91..69fb00a74be 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5702,9 +5702,10 @@ abstract class CommonObject // Recalculate unit price with tax if not defined if (empty((float) $line->subprice_ttc) && $line->qty) { // subprice_ttc may be not stored on old version or not defined for lines with no unit price (like a discount) - // So we calculate an estimated value just to show something on screen + // So we calculate an estimated value just to show something on screen. + // Not: the unit price is always for 100% of line, it is not a prorata of situation invoice (when total is) if ($line->remise_percent != 100) { - $line->subprice_ttc = (float) price2num($line->total_ttc / $line->qty / (1 - $line->remise_percent / 100), 'MU'); + $line->subprice_ttc = (float) price2num($line->total_ttc * ($line->situation_percent ? 100 / $line->situation_percent : 1) / $line->qty / (1 - $line->remise_percent / 100), 'MU'); } else { // Other method is less accurate $line->subprice_ttc = (float) price2num((!empty($line->subprice) ? $line->subprice : 0) * (1 + ((!empty($line->tva_tx) ? $line->tva_tx : 0) / 100)), 'MU'); @@ -6810,7 +6811,7 @@ abstract class CommonObject if (empty($extrafields->attributes[$this->table_element]['type'][$name]) || (!in_array($extrafields->attributes[$this->table_element]['type'][$name], ['separate', 'point', 'multipts', 'linestrg','polygon']))) { $sql .= ", ".$this->db->sanitize($name); } - // use geo sql fonction to read as text + // use geo sql function to read as text if (!empty($extrafields->attributes[$this->table_element]['type'][$name]) && in_array($extrafields->attributes[$this->table_element]['type'][$name], array('point', 'multipts', 'linestrg', 'polygon'))) { // TODO Add an abstraction method in the database driver $sql .= ", ST_AsWKT(".$name.") as ".$this->db->sanitize($name); diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index a905cdc008f..4e0cbd52d17 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -43,6 +43,7 @@ * @var Translate $langs * @var User $user * @var ExtraFields $extrafields + * * @var CommonObject $this * @var CommonObject $object * @var CommonObjectLine $line @@ -69,6 +70,8 @@ if (empty($object) || !is_object($object)) { @phan-var-force int $i '; +global $db; + // Handle subtotals line edit if (defined('SUBTOTALS_SPECIAL_CODE') && $line->special_code == SUBTOTALS_SPECIAL_CODE) { return require DOL_DOCUMENT_ROOT.'/core/tpl/subtotal_edit.tpl.php'; @@ -96,6 +99,33 @@ if (empty($canchangeproduct)) { $canchangeproduct = 0; } +$situationinvoicelinewithparent = 0; +$situationinvoicelinewithchild = 0; + +if (getDolGlobalInt('INVOICE_USE_SITUATION') && in_array($object->element, array('facture', 'facturedet'))) { + /** @var CommonInvoice $object */ + // @phan-suppress-next-line PhanUndeclaredConstantOfClass + + // Set if invoice line has a parent + if (isset($line->fk_prev_id)) { + if ($object->isSituationInvoice()) { // Method isSituationInvoice() exists only on invoices + // Set constant to disallow editing during a situation cycle + $situationinvoicelinewithparent = 1; + } + } + // Set if invoice line has a child + $sqlcheckchild = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."facturedet WHERE fk_prev_id = ".((int) $line->id); + $resqlcheckchild = $db->query($sqlcheckchild); + if ($resqlcheckchild) { + $objcheckchild = $db->fetch_object($resqlcheckchild); + if ($objcheckchild->count > 0) { + $situationinvoicelinewithchild = 1; + } + } else { + dol_print_error($db); + } +} + // Define colspan for the button 'Add' $colspan = 3; // Col total ht + col edit + col delete if (!empty($inputalsopricewithtax)) { @@ -168,23 +198,7 @@ $coldisplay++; $reshook = $hookmanager->executeHooks('formEditProductOptions', $parameters, $this, $action); } - $situationinvoicelinewithparent = 0; - if ($line->fk_prev_id != null && in_array($object->element, array('facture', 'facturedet'))) { - /** @var CommonInvoice $object */ - // @phan-suppress-next-line PhanUndeclaredConstantOfClass - if ($object->type == $object::TYPE_SITUATION) { // The constant TYPE_SITUATION exists only for object invoice - // Set constant to disallow editing during a situation cycle - $situationinvoicelinewithparent = 1; - } - } - - // Do not allow editing during a situation cycle - // but in some situations that is required (update legal information for example) - if (getDolGlobalString('INVOICE_SITUATION_CAN_FORCE_UPDATE_DESCRIPTION')) { - $situationinvoicelinewithparent = 0; - } - - if (!$situationinvoicelinewithparent) { + if (!$situationinvoicelinewithparent || getDolGlobalString('INVOICE_SITUATION_CAN_FORCE_UPDATE_DESCRIPTION')) { // editor wysiwyg require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $nbrows = ROWS_2; @@ -200,7 +214,7 @@ $coldisplay++; $doleditor->Create(); } else { print ''; } diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 5ee06828e07..625888f4662 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -59,6 +59,9 @@ * @var string $description * @var Object $objp * @var int $dateSelector + * @var int $inputalsopricewithtax + * @var int $outputalsopricetotalwithtax + * @var int $disableremove */ // Protection to avoid direct call of template if (empty($object) || !is_object($object)) { @@ -108,6 +111,34 @@ if (empty($outputalsopricetotalwithtax)) { $outputalsopricetotalwithtax = 0; } +$situationinvoicelinewithparent = 0; +$situationinvoicelinewithchild = 0; + +if (getDolGlobalInt('INVOICE_USE_SITUATION') && in_array($object->element, array('facture', 'facturedet'))) { + /** @var CommonInvoice $object */ + // @phan-suppress-next-line PhanUndeclaredConstantOfClass + + // Set if invoice line has a parent + if (isset($line->fk_prev_id)) { + if ($object->isSituationInvoice()) { // Method isSituationInvoice() exists only on invoices + // Set constant to disallow editing during a situation cycle + $situationinvoicelinewithparent = 1; + } + } + // Set if invoice line has a child + $sqlcheckchild = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."facturedet WHERE fk_prev_id = ".((int) $line->id); + $resqlcheckchild = $db->query($sqlcheckchild); + if ($resqlcheckchild) { + $objcheckchild = $db->fetch_object($resqlcheckchild); + if ($objcheckchild->count > 0) { + $situationinvoicelinewithchild = 1; + } + } else { + dol_print_error($db); + } +} + + // add html5 elements $domData = ' data-element="'.$line->element.'"'; $domData .= ' data-id="'.$line->id.'"'; @@ -408,7 +439,8 @@ if (empty($positiverates)) { print $tooltiponprice; print vatrate($positiverates.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''), true, $line->info_bits); print $tooltiponpriceend; -?> +print ''; +?> -multicurrency_code && $this->multicurrency_code != $conf->currency) { ?> +multicurrency_code && $this->multicurrency_code != $conf->currency) { ?> fk_remise_except)) { @@ -433,12 +467,12 @@ print $tooltiponpriceend; subprice_ttc) ? $line->subprice_ttc : null; - if (!$upinctax && $line->total_ttc && $line->qty) { - $upinctax = price2num($line->total_ttc / (float) $line->qty, 'MU'); + if (!$upinctax && $line->total_ttc && $line->qty) { // The unit price including tax was not saved, so we try to guess it + // Note that unit price is always for 100% of line, it is not prorata of situation percent, when total_ttc is. + $upinctax = price2num($line->total_ttc * ($line->situation_percent ? 100 / $line->situation_percent : 1) / (float) $line->qty, 'MU'); } if (!$upinctax) { $multicurrency_upinctax = price2num($line->multicurrency_subprice * (1 + ($line->tva_tx / 100)), 'MU'); // one tax @@ -446,10 +480,11 @@ if (!empty($inputalsopricewithtax) && !getDolGlobalInt('MAIN_NO_INPUT_PRICE_WITH if (empty($line->fk_remise_except)) { print(isset($upinctax) ? price($sign * $upinctax) : price($sign * $line->subprice)); } // if upinctax can't be known, we show subprice excl ta - ?> + ?> + multicurrency_code && $this->multicurrency_code != $conf->currency && !empty($inputalsopricewithtax) && !getDolGlobalInt('MAIN_NO_INPUT_PRICE_WITH_TAX')) { ?> multicurrency_subprice_ttc) ? $line->multicurrency_subprice_ttc : null; @@ -600,16 +635,6 @@ $objectRights = $this->getRights(); $tmppermtoedit = $objectRights->creer; if ($this->status == 0 && $tmppermtoedit && $action != 'selectlines') { - $situationinvoicelinewithparent = 0; - if (isset($line->fk_prev_id) && in_array($object->element, array('facture', 'facturedet'))) { - /** @var CommonInvoice $object */ - // @phan-suppress-next-line PhanUndeclaredConstantOfClass - if ($object->type == $object::TYPE_SITUATION) { // The constant TYPE_SITUATION exists only for object invoice - // Set constant to disallow editing during a situation cycle - $situationinvoicelinewithparent = 1; - } - } - // Asset info if (isModEnabled('asset') && $object->element == 'invoice_supplier') { print ''; @@ -664,7 +689,7 @@ if ($this->status == 0 && $tmppermtoedit && $action != 'selectlines') { // Delete picto print ''; $coldisplay++; - if (!$situationinvoicelinewithparent && empty($disableremove)) { // For situation invoice, deletion is not possible if there is a parent company. + if (!$situationinvoicelinewithchild && empty($disableremove)) { // For situation invoice, deletion is not possible if there is a child line. print 'id.'">'; print img_delete(); print ''; diff --git a/htdocs/theme/eldy/btn.inc.php b/htdocs/theme/eldy/btn.inc.php index c595980a279..7ddf5d267e6 100644 --- a/htdocs/theme/eldy/btn.inc.php +++ b/htdocs/theme/eldy/btn.inc.php @@ -204,7 +204,7 @@ span.butActionNewRefused>span.fa, span.butActionNewRefused>span.fa:hover /* border: 1px solid #633; */ color: #633 !important; } -.button.button-cancel, .button.button-cancel:link, .button.button-cancel:visited, .button.button-cancel:hover, .button.button-cancel:active, .button.button-cancel { +.button.button-cancel:not(.buttongen), .button.button-cancel:link:not(.buttongen), .button.button-cancel:visited:not(.buttongen), .button.button-cancel:hover:not(.buttongen), .button.button-cancel:active:not(.buttongen), .button.button-cancel:not(.buttongen) { background: var(--butactioncancelbg) !important; border: none; color: #333 !important; @@ -213,7 +213,7 @@ span.butActionNewRefused>span.fa, span.butActionNewRefused>span.fa:hover .butActionDelete:hover { box-shadow: 0px 0px 4px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); } -.button.button-cancel:hover { +.button.button-cancel:hover:not(.buttongen) { box-shadow: 0px 0px 4px 1px rgba(50, 50, 50, 0.2), 0px 0px 0px rgba(60,60,60,0.1); } diff --git a/htdocs/theme/md/btn.inc.php b/htdocs/theme/md/btn.inc.php index acf0cbe7976..91a9408cb3c 100644 --- a/htdocs/theme/md/btn.inc.php +++ b/htdocs/theme/md/btn.inc.php @@ -259,7 +259,7 @@ span.butActionNewRefused>span.fa, span.butActionNewRefused>span.fa:hover background: var(--butactiondeletebg); color: #633 !important; } -.button.button-cancel, .button.button-cancel:link, .button.button-cancel:visited, .button.button-cancel:hover, .button.button-cancel:active, .button.button-cancel { +.button.button-cancel:not(.buttongen), .button.button-cancel:link:not(.buttongen), .button.button-cancel:visited:not(.buttongen), .button.button-cancel:hover:not(.buttongen), .button.button-cancel:active:not(.buttongen), .button.button-cancel:not(.buttongen) { background: var(--butactioncancelbg) !important; color: #888 !important; } @@ -267,7 +267,7 @@ span.butActionNewRefused>span.fa, span.butActionNewRefused>span.fa:hover .butActionDelete:hover { box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1); } -.button.button-cancel:hover { +.button.button-cancel:hover:not(.buttongen) { box-shadow: 0px 0px 4px 1px rgba(50, 50, 50, 0.2), 0px 0px 0px rgba(60,60,60,0.1); }