Debug v24

This commit is contained in:
Laurent Destailleur 2026-07-01 14:24:54 +02:00
parent 0c50fd0223
commit 4981404a1a
5 changed files with 83 additions and 43 deletions

View file

@ -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);

View file

@ -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 '<textarea id="product_desc" class="flat" name="product_desc" readonly style="width: 200px; height:80px;">';
print GETPOSTISSET('product_desc') ? GETPOST('product_desc', 'restricthtml') : $line->description;
print dolPrintHTMLForTextArea(GETPOSTISSET('product_desc') ? GETPOST('product_desc', 'restricthtml') : $line->description);
print '</textarea>';
}

View file

@ -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;
?></td>
print '</td>';
?>
<td class="linecoluht nowraponall right">
<?php
@ -421,7 +453,9 @@ print $tooltiponpriceend;
?>
</td>
<?php if (isModEnabled("multicurrency") && $this->multicurrency_code && $this->multicurrency_code != $conf->currency) { ?>
<?php
// Multicurrency unit price excluding tax - HT
if (isModEnabled("multicurrency") && $this->multicurrency_code && $this->multicurrency_code != $conf->currency) { ?>
<td class="linecoluht_currency nowraponall right">
<?php $coldisplay++;
if (empty($line->fk_remise_except)) {
@ -433,12 +467,12 @@ print $tooltiponpriceend;
</td>
<?php }
// Multicurrency HT
if (!empty($inputalsopricewithtax) && !getDolGlobalInt('MAIN_NO_INPUT_PRICE_WITH_TAX')) { ?>
<td class="linecoluttc nowraponall right"><?php $coldisplay++; ?><?php
$upinctax = isset($line->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
?></td>
?>
</td>
<?php }
// Multicurrency TTC
// Multicurrency unit price including tax - TTC
if (isModEnabled("multicurrency") && $this->multicurrency_code && $this->multicurrency_code != $conf->currency && !empty($inputalsopricewithtax) && !getDolGlobalInt('MAIN_NO_INPUT_PRICE_WITH_TAX')) { ?>
<td class="linecoluttc_currency nowraponall right"><?php $coldisplay++; ?><?php
$multicurrency_upinctax = isset($line->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 '<td class="linecolasset center">';
@ -664,7 +689,7 @@ if ($this->status == 0 && $tmppermtoedit && $action != 'selectlines') {
// Delete picto
print '<td class="linecoldelete center">';
$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 '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$this->id.'&action=ask_deleteline&token='.newToken().'&lineid='.$line->id.'">';
print img_delete();
print '</a>';

View file

@ -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);
}

View file

@ -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);
}