mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-12-06 01:28:19 +01:00
730 lines
22 KiB
PHP
730 lines
22 KiB
PHP
<?php
|
|
/* Copyright (C) 2014-2017 Laurent Destailleur <eldy@users.sourceforge.net>
|
|
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
|
|
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
* or see https://www.gnu.org/
|
|
*/
|
|
|
|
if (!defined('SUBTOTALS_SPECIAL_CODE')) {
|
|
define('SUBTOTALS_SPECIAL_CODE', 81);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Trait CommonSubtotal
|
|
*
|
|
* Add subtotals lines
|
|
*/
|
|
trait CommonSubtotal
|
|
{
|
|
/**
|
|
* @var int
|
|
* Type for subtotals module lines
|
|
*/
|
|
public static $PRODUCT_TYPE = 9;
|
|
|
|
/**
|
|
* @var array<string>
|
|
* Options for subtotals module title lines
|
|
*/
|
|
public static $TITLE_OPTIONS = ['titleshowuponpdf', 'titleshowtotalexludingvatonpdf', 'titleforcepagebreak'];
|
|
|
|
/**
|
|
* @var array<string>
|
|
* Options for subtotals module subtotal lines
|
|
*/
|
|
public static $SUBTOTAL_OPTIONS = ['subtotalshowtotalexludingvatonpdf'];
|
|
|
|
/**
|
|
* @var string[] element of allowed module class
|
|
*/
|
|
public static $ALLOWED_TYPES = [
|
|
'propal',
|
|
'commande',
|
|
'facture',
|
|
'facturerec',
|
|
'shipping',
|
|
];
|
|
|
|
/**
|
|
* Adds a subtotals line to a document.
|
|
* This function inserts a subtotal line based on the given parameters.
|
|
*
|
|
* @param Translate $langs Translation.
|
|
* @param string $desc Description of the line.
|
|
* @param int $depth Level of the line (>0 for title lines, <0 for subtotal lines)
|
|
* @param array<string,string>|string $options Subtotal options for pdf view
|
|
* @param int $parent_line ID of the parent line for shipments
|
|
* @return int ID of the added line if successful, 0 on warning, -1 on error
|
|
*
|
|
* @phan-suppress PhanUndeclaredMethod
|
|
* @phan-suppress PhanUndeclaredProperty
|
|
*/
|
|
public function addSubtotalLine($langs, $desc, $depth, $options = array(), $parent_line = 0)
|
|
{
|
|
if (empty($desc)) {
|
|
if (isset($this->errors)) {
|
|
$this->errors[] = $langs->trans("TitleNeedDesc");
|
|
}
|
|
return -1;
|
|
}
|
|
$current_module = $this->element;
|
|
// Ensure the object is one of the supported types
|
|
if (!in_array($current_module, self::$ALLOWED_TYPES)) {
|
|
if (isset($this->errors)) {
|
|
$this->errors[] = $langs->trans("UnsupportedModuleError");
|
|
}
|
|
return -1; // Unsupported type
|
|
}
|
|
$error = 0;
|
|
$desc = dol_html_entity_decode($desc, ENT_QUOTES);
|
|
$rang = -1;
|
|
$next_line = false;
|
|
$result = 0;
|
|
|
|
if ($depth < 0 && $current_module != 'shipping') {
|
|
foreach ($this->lines as $line) {
|
|
if (!$next_line && $line->desc == $desc && $line->qty == -$depth) {
|
|
$next_line = true;
|
|
continue;
|
|
}
|
|
if ($next_line && $line->desc == $desc && $line->qty == $depth) {
|
|
$next_line = false;
|
|
continue;
|
|
}
|
|
if ($next_line && $line->special_code == SUBTOTALS_SPECIAL_CODE && abs($line->qty) <= abs($depth)) {
|
|
$rang = $line->rang;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($depth > 0 && $current_module != 'shipping') {
|
|
$max_existing_level = 0;
|
|
|
|
foreach ($this->lines as $line) {
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty > $max_existing_level) {
|
|
$max_existing_level = $line->qty;
|
|
}
|
|
}
|
|
|
|
if ($max_existing_level+1 < $depth) {
|
|
$depth = $max_existing_level+1;
|
|
if (isset($this->errors)) {
|
|
$this->errors[] = $langs->trans("TitleAddedLevelTooHigh", $depth);
|
|
}
|
|
|
|
$error ++;
|
|
}
|
|
}
|
|
|
|
// Add the line calling the right module
|
|
if ($current_module == 'facture' && $this instanceof Facture) {
|
|
$result = $this->addline(
|
|
$desc, // Description
|
|
0, // Unit price
|
|
$depth, // Quantity
|
|
0, // VAT rate
|
|
0, // Local tax 1
|
|
0, // Local tax 2
|
|
0, // FK product
|
|
0, // Discount percentage
|
|
'', // Date start
|
|
'', // Date end
|
|
0, // FK code ventilation
|
|
0, // Info bits
|
|
0, // FK remise except
|
|
'', // Price base type
|
|
0, // PU ttc
|
|
self::$PRODUCT_TYPE, // Type
|
|
$rang, // Rang
|
|
SUBTOTALS_SPECIAL_CODE // Special code
|
|
);
|
|
} elseif ($current_module == 'propal' && $this instanceof Propal) {
|
|
$result = $this->addline(
|
|
$desc, // Description
|
|
0, // Unit price
|
|
$depth, // Quantity
|
|
0, // VAT rate
|
|
0, // Local tax 1
|
|
0, // Local tax 2
|
|
0, // FK product
|
|
0, // Discount percentage
|
|
'', // Price base type
|
|
0, // PU ttc
|
|
0, // Info bits
|
|
self::$PRODUCT_TYPE, // Type
|
|
$rang, // Rang
|
|
SUBTOTALS_SPECIAL_CODE // Special code
|
|
);
|
|
} elseif ($current_module == 'commande' && $this instanceof Commande) {
|
|
$result = $this->addline(
|
|
$desc, // Description
|
|
0, // Unit price
|
|
$depth, // Quantity
|
|
0, // VAT rate
|
|
0, // Local tax 1
|
|
0, // Local tax 2
|
|
0, // FK product
|
|
0, // Discount percentage
|
|
0, // Info bits
|
|
0, // FK remise except
|
|
'', // Price base type
|
|
0, // PU ttc
|
|
'', // Date start
|
|
'', // Date end
|
|
self::$PRODUCT_TYPE, // Type
|
|
$rang, // Rang
|
|
SUBTOTALS_SPECIAL_CODE // Special code
|
|
);
|
|
} elseif ($current_module == 'shipping' && $this instanceof Expedition) {
|
|
$result = $this->addline(
|
|
0, // Warehouse ID
|
|
(int) $parent_line, // Source line
|
|
$depth // Quantity
|
|
);
|
|
} elseif ($current_module == 'facturerec' && $this instanceof FactureRec) {
|
|
$rang = $rang == -1 ? $rang : $rang-1;
|
|
$result = $this->addline(
|
|
$desc, // Description
|
|
0, // Unit price
|
|
$depth, // Quantity
|
|
0, // VAT rate
|
|
0, // Local tax 1
|
|
0, // Local tax 2
|
|
0, // FK product
|
|
0, // Discount percentage
|
|
'', // Price base type
|
|
0, // Info bits
|
|
0, // FK remise except
|
|
0, // PU ttc
|
|
self::$PRODUCT_TYPE, // Type
|
|
$rang, // Rang
|
|
SUBTOTALS_SPECIAL_CODE // Special code
|
|
);
|
|
$this->fetch_lines();
|
|
}
|
|
|
|
if ($current_module != 'shipping') {
|
|
foreach ($this->lines as $line) {
|
|
'@phan-var-force CommonObjectLine $line';
|
|
/** @var CommonObjectLine $line */
|
|
if ($line->id == $result) {
|
|
$line->extraparams["subtotal"] = $options;
|
|
$line->setExtraParameters();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($result < 0) {
|
|
return $result;
|
|
}
|
|
|
|
return $error > 0 ? 0 : $result;
|
|
}
|
|
|
|
/**
|
|
* Deletes a subtotal or a title line from a document.
|
|
* If the corresponding subtotal line exists and second parameter true, it will also be deleted.
|
|
*
|
|
* @param Translate $langs Translation.
|
|
* @param int $id ID of the line to delete
|
|
* @param bool $correspondingstline If true, also deletes the corresponding subtotal line
|
|
* @param User $user performing the deletion (used for permissions in some modules)
|
|
* @return int ID of deleted line if successful, -1 on error
|
|
*
|
|
* @phan-suppress PhanUndeclaredMethod
|
|
* @phan-suppress PhanUndeclaredProperty
|
|
*/
|
|
public function deleteSubtotalLine($langs, $id, $correspondingstline = false, $user = null)
|
|
{
|
|
$current_module = $this->element;
|
|
// Ensure the object is one of the supported types
|
|
if (!in_array($current_module, self::$ALLOWED_TYPES)) {
|
|
if (isset($this->errors)) {
|
|
$this->errors[] = $langs->trans("UnsupportedModuleError");
|
|
}
|
|
return -1; // Unsupported type
|
|
}
|
|
|
|
$result = 0;
|
|
|
|
if ($correspondingstline) {
|
|
$oldDesc = "";
|
|
$oldDepth = 0;
|
|
foreach ($this->lines as $line) {
|
|
if ($line->id == $id) {
|
|
$oldDesc = $line->desc;
|
|
$oldDepth = $line->qty;
|
|
}
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty == -$oldDepth && $line->desc == $oldDesc) {
|
|
$this->deleteSubtotalLine($langs, $line->id, false, $user);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add the line calling the right module
|
|
if ($current_module == 'facture' && $this instanceof Facture) {
|
|
$rowid = $id; // for phan suspicious parameter order...
|
|
$result = $this->deleteLine($rowid);
|
|
} elseif ($current_module == 'propal' && $this instanceof Propal) {
|
|
$rowid = $id; // for phan suspicious parameter order...
|
|
$result = $this->deleteLine($rowid);
|
|
} elseif ($current_module == 'commande' && $this instanceof Commande) {
|
|
$lineid = $id; // for phan suspicious parameter order...
|
|
$result = $this->deleteLine($user, $lineid);
|
|
} elseif ($current_module == 'facturerec') {
|
|
$line = new FactureLigneRec($this->db);
|
|
$line->id = $id;
|
|
$result = $line->delete($user);
|
|
} elseif ($current_module == 'shipping') {
|
|
$line = new ExpeditionLigne($this->db);
|
|
$line->id = $id;
|
|
$result = $line->delete($user);
|
|
}
|
|
|
|
return $result >= 0 ? $result : -1; // Return line ID or false
|
|
}
|
|
|
|
/**
|
|
* Updates a subtotal line of a document.
|
|
* This function updates a subtotals line based on its id and the given parameters.
|
|
* Updating a title line updates the corresponding subtotal line except options.
|
|
*
|
|
* @param Translate $langs Translation.
|
|
* @param int $lineid ID of the line to update.
|
|
* @param string $desc Description of the line.
|
|
* @param int $depth Level of the line (>0 for title lines, <0 for subtotal lines)
|
|
* @param array<string,string>|string $options Subtotal options for pdf view
|
|
* @return int ID of the added line if successful, 0 on warning, -1 on error
|
|
*
|
|
* @phan-suppress PhanUndeclaredMethod
|
|
* @phan-suppress PhanUndeclaredProperty
|
|
*/
|
|
public function updateSubtotalLine($langs, $lineid, $desc, $depth, $options) // @phpstan-ignore-line
|
|
{
|
|
$current_module = $this->element;
|
|
// Ensure the object is one of the supported types
|
|
if (!in_array($current_module, self::$ALLOWED_TYPES)) {
|
|
if (isset($this->errors)) {
|
|
$this->errors[] = $langs->trans("UnsupportedModuleError");
|
|
}
|
|
return -1; // Unsupported type
|
|
}
|
|
|
|
$result = 0;
|
|
$error = 0;
|
|
|
|
$max_existing_level = 0;
|
|
|
|
if ($depth>0) {
|
|
foreach ($this->lines as $line) {
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty > $max_existing_level && $line->id != $lineid) {
|
|
$max_existing_level = $line->qty;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($max_existing_level+1 < $depth) {
|
|
$depth = $max_existing_level+1;
|
|
if (isset($this->errors)) {
|
|
$this->errors[] = $langs->trans("TitleEditedLevelTooHigh");
|
|
}
|
|
$error ++;
|
|
}
|
|
|
|
if ($depth>0) {
|
|
$oldDesc = "";
|
|
$oldDepth = 0;
|
|
foreach ($this->lines as $line) {
|
|
if ($line->id == $lineid) {
|
|
$oldDesc = $line->desc;
|
|
$oldDepth = $line->qty;
|
|
}
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty == -$oldDepth && $line->desc == $oldDesc) {
|
|
$this->updateSubtotalLine($langs, $line->id, $desc, -$depth, !empty($line->extraparams["subtotal"]) ? $line->extraparams["subtotal"] : array());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update the line calling the right module
|
|
if ($current_module == 'facture' && $this instanceof Facture) {
|
|
$result = $this->updateline(
|
|
$lineid, // ID of line to change
|
|
$desc, // Description
|
|
0, // Unit price
|
|
$depth, // Quantity
|
|
0, // Discount percentage
|
|
'', // Date start
|
|
'', // Date end
|
|
0, // VAT rate
|
|
0, // Local tax 1
|
|
0, // Local tax 2
|
|
'', // Price base type
|
|
0, // Info bits
|
|
self::$PRODUCT_TYPE, // Type
|
|
0, // FK parent line
|
|
0, // Skip update total
|
|
0, // FK fournprice
|
|
0, // PA ht
|
|
'', // Label
|
|
SUBTOTALS_SPECIAL_CODE // Special code
|
|
);
|
|
} elseif ($current_module == 'propal' && $this instanceof Propal) {
|
|
$result = $this->updateline(
|
|
$lineid, // ID of line to change
|
|
0, // Unit price
|
|
$depth, // Quantity
|
|
0, // Discount percentage
|
|
0, // VAT rate
|
|
0, // Local tax 1
|
|
0, // Local tax 2
|
|
$desc, // Description
|
|
'', // Price base type
|
|
0, // Info bits
|
|
SUBTOTALS_SPECIAL_CODE, // Special code
|
|
0, // FK parent line
|
|
0, // Skip update total
|
|
0, // FK fournprice
|
|
0, // PA ht
|
|
'', // Label
|
|
self::$PRODUCT_TYPE // Type
|
|
);
|
|
} elseif ($current_module == 'commande' && $this instanceof Commande) {
|
|
$result = $this->updateline(
|
|
$lineid, // ID of line to change
|
|
$desc, // Description
|
|
0, // Unit price
|
|
$depth, // Quantity
|
|
0, // Discount percentage
|
|
0, // VAT rate
|
|
0, // Local tax 1
|
|
0, // Local tax 2
|
|
'', // Price base type
|
|
0, // Info bits
|
|
'', // Date start
|
|
'', // Date end
|
|
self::$PRODUCT_TYPE, // Type
|
|
0, // FK parent line
|
|
0, // Skip update total
|
|
0, // FK fournprice
|
|
0, // PA ht
|
|
'', // Label
|
|
SUBTOTALS_SPECIAL_CODE // Special code
|
|
);
|
|
} elseif ($current_module == 'facturerec' && $this instanceof FactureRec) {
|
|
$objectline = new FactureLigneRec($this->db);
|
|
$objectline->fetch($lineid);
|
|
$line_rang = $objectline->rang;
|
|
$result = $this->updateline(
|
|
$lineid, // ID of line to change
|
|
$desc, // Description
|
|
0, // Unit price
|
|
$depth, // Quantity
|
|
0, // VAT rate
|
|
0, // Local tax 1
|
|
0, // Local tax 2
|
|
0, // FK parent line
|
|
0, // Discount percentage
|
|
'', // Price base type
|
|
0, // Info bits
|
|
0, // FK parent line
|
|
0, // PU ttc
|
|
self::$PRODUCT_TYPE, // Type
|
|
$line_rang, // Rang
|
|
SUBTOTALS_SPECIAL_CODE // Special code
|
|
);
|
|
}
|
|
|
|
foreach ($this->lines as $line) {
|
|
'@phan-var-force CommonObjectLine $line';
|
|
/** @var CommonObjectLine $line */
|
|
if ($line->id == $lineid) {
|
|
$line->extraparams["subtotal"] = $options;
|
|
$line->setExtraParameters();
|
|
}
|
|
}
|
|
|
|
if ($result < 0) {
|
|
return $result;
|
|
}
|
|
|
|
return $error > 0 ? 0 : $result;
|
|
}
|
|
|
|
/**
|
|
* Updates a block of lines of a document.
|
|
*
|
|
* @param Translate $langs Translation.
|
|
* @param int $linerang Rang of the line to start from.
|
|
* @param string $mode Column to change (discount or vat).
|
|
* @param int $value Value of the change.
|
|
* @return int Return integer < 0 if KO, 1 if OK
|
|
*
|
|
* @phan-suppress PhanUndeclaredMethod
|
|
* @phan-suppress PhanUndeclaredProperty
|
|
*/
|
|
public function updateSubtotalLineBlockLines($langs, $linerang, $mode, $value) // @phpstan-ignore-line
|
|
{
|
|
$current_module = $this->element;
|
|
// Ensure the object is one of the supported types
|
|
if (!in_array($current_module, self::$ALLOWED_TYPES)) {
|
|
if (isset($this->errors)) {
|
|
$this->errors[] = $langs->trans("UnsupportedModuleError");
|
|
}
|
|
return -1; // Unsupported type
|
|
}
|
|
|
|
$result = 0;
|
|
$linerang -= 1;
|
|
|
|
$nb_lines = count($this->lines)+1;
|
|
|
|
for ($i = $linerang+1; $i < $nb_lines; $i++) {
|
|
if ($this->lines[$i]->special_code == SUBTOTALS_SPECIAL_CODE) {
|
|
if (abs($this->lines[$i]->qty) <= (int) $this->lines[$linerang]->qty) {
|
|
return 1;
|
|
}
|
|
} else {
|
|
if ($current_module == 'facture' && $this instanceof Facture) {
|
|
$result = $this->updateline(
|
|
$this->lines[$i]->id,
|
|
$this->lines[$i]->desc,
|
|
$this->lines[$i]->subprice,
|
|
$this->lines[$i]->qty,
|
|
$mode == 'discount' ? $value : $this->lines[$i]->remise_percent,
|
|
$this->lines[$i]->date_start,
|
|
$this->lines[$i]->date_end,
|
|
$mode == 'tva' ? $value : $this->lines[$i]->tva_tx,
|
|
$this->lines[$i]->localtax1_tx,
|
|
$this->lines[$i]->localtax2_tx,
|
|
'HT',
|
|
$this->lines[$i]->info_bits,
|
|
$this->lines[$i]->product_type,
|
|
$this->lines[$i]->fk_parent_line, 0,
|
|
$this->lines[$i]->fk_fournprice,
|
|
$this->lines[$i]->pa_ht,
|
|
$this->lines[$i]->label,
|
|
$this->lines[$i]->special_code,
|
|
$this->lines[$i]->array_options,
|
|
$this->lines[$i]->situation_percent,
|
|
$this->lines[$i]->fk_unit,
|
|
$this->lines[$i]->multicurrency_subprice
|
|
);
|
|
} elseif ($current_module == 'commande' && $this instanceof Commande) {
|
|
$result = $this->updateline(
|
|
$this->lines[$i]->id,
|
|
$this->lines[$i]->desc,
|
|
$this->lines[$i]->subprice,
|
|
$this->lines[$i]->qty,
|
|
$mode == 'discount' ? $value : $this->lines[$i]->remise_percent,
|
|
$mode == 'tva' ? $value : $this->lines[$i]->tva_tx,
|
|
$this->lines[$i]->localtax1_rate,
|
|
$this->lines[$i]->localtax2_rate,
|
|
'HT',
|
|
$this->lines[$i]->info_bits,
|
|
$this->lines[$i]->date_start,
|
|
$this->lines[$i]->date_end,
|
|
$this->lines[$i]->product_type,
|
|
$this->lines[$i]->fk_parent_line, 0,
|
|
$this->lines[$i]->fk_fournprice,
|
|
$this->lines[$i]->pa_ht,
|
|
$this->lines[$i]->label,
|
|
$this->lines[$i]->special_code,
|
|
$this->lines[$i]->array_options,
|
|
$this->lines[$i]->fk_unit,
|
|
$this->lines[$i]->multicurrency_subprice
|
|
);
|
|
} elseif ($current_module == 'propal' && $this instanceof Propal) {
|
|
$result = $this->updateline(
|
|
$this->lines[$i]->id,
|
|
$this->lines[$i]->subprice,
|
|
$this->lines[$i]->qty,
|
|
$mode == 'discount' ? $value : $this->lines[$i]->remise_percent,
|
|
$mode == 'tva' ? $value : $this->lines[$i]->tva_tx,
|
|
$this->lines[$i]->localtax1_rate,
|
|
$this->lines[$i]->localtax2_rate,
|
|
$this->lines[$i]->desc,
|
|
'HT',
|
|
$this->lines[$i]->info_bits,
|
|
$this->lines[$i]->special_code,
|
|
$this->lines[$i]->fk_parent_line, 0,
|
|
$this->lines[$i]->fk_fournprice,
|
|
$this->lines[$i]->pa_ht,
|
|
$this->lines[$i]->label,
|
|
$this->lines[$i]->product_type,
|
|
$this->lines[$i]->date_start,
|
|
$this->lines[$i]->date_end,
|
|
$this->lines[$i]->array_options,
|
|
$this->lines[$i]->fk_unit,
|
|
$this->lines[$i]->multicurrency_subprice
|
|
);
|
|
}
|
|
if ($result < 0) {
|
|
return $result;
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Return the total_ht of lines that are above the current line (excluded) and that are not a subtotal line
|
|
* until a title line of the same level is found
|
|
*
|
|
* @param object $line Line that needs the subtotal amount.
|
|
* @return string $total_ht
|
|
*
|
|
* @phan-suppress PhanUndeclaredProperty
|
|
*/
|
|
public function getSubtotalLineAmount($line)
|
|
{
|
|
$final_amount = 0;
|
|
for ($i = $line->rang-1; $i > 0; $i--) {
|
|
if (is_null($this->lines[$i-1]) || $this->lines[$i-1]->rang >= $line->rang) {
|
|
continue;
|
|
}
|
|
if ($this->lines[$i-1]->special_code == SUBTOTALS_SPECIAL_CODE && $this->lines[$i-1]->qty > 0) {
|
|
if ($this->lines[$i-1]->qty <= abs($line->qty)) {
|
|
return price($final_amount);
|
|
}
|
|
} else {
|
|
$final_amount += $this->lines[$i-1]->total_ht;
|
|
}
|
|
}
|
|
return price($final_amount);
|
|
}
|
|
|
|
/**
|
|
* Return the multicurrency_total_ht of lines that are above the current line (excluded) and that are not a subtotal line
|
|
* until a title line of the same level is found
|
|
*
|
|
* @param object $line Line that needs the subtotal amount with multicurrency mod activated.
|
|
* @return string $total_ht
|
|
*
|
|
* @phan-suppress PhanUndeclaredProperty
|
|
*/
|
|
public function getSubtotalLineMulticurrencyAmount($line)
|
|
{
|
|
$final_amount = 0;
|
|
for ($i = $line->rang-1; $i > 0; $i--) {
|
|
if (is_null($this->lines[$i-1]) || $this->lines[$i-1]->rang >= $line->rang) {
|
|
continue;
|
|
}
|
|
if ($this->lines[$i-1]->special_code == SUBTOTALS_SPECIAL_CODE && $this->lines[$i-1]->qty>0) {
|
|
if ($this->lines[$i-1]->qty <= abs($line->qty)) {
|
|
return price($final_amount);
|
|
}
|
|
} else {
|
|
$final_amount += $this->lines[$i-1]->multicurrency_total_ht;
|
|
}
|
|
}
|
|
return price($final_amount);
|
|
}
|
|
|
|
/**
|
|
* Retrieve the background color associated with a specific subtotal level.
|
|
*
|
|
* @param int|float $level The level of the subtotal for which the color is requested.
|
|
* @return string|null The background color in hexadecimal format or null if not set.
|
|
*/
|
|
public function getSubtotalColors($level)
|
|
{
|
|
return getDolGlobalString('SUBTOTAL_BACK_COLOR_LEVEL_'.abs($level));
|
|
}
|
|
|
|
/**
|
|
* Retrieve current object possible titles to choose from
|
|
*
|
|
* @return array<string,string> The set of titles, empty if no title line set.
|
|
*
|
|
* @phan-suppress PhanUndeclaredProperty
|
|
*/
|
|
public function getPossibleTitles()
|
|
{
|
|
$titles = array();
|
|
foreach ($this->lines as $line) {
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty > 0) {
|
|
$titles[$line->desc] = $line->desc;
|
|
}
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty < 0) {
|
|
unset($titles[$line->desc]);
|
|
}
|
|
}
|
|
return $titles;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the current object possible levels (defined in admin page)
|
|
*
|
|
* @param Translate $langs Translations.
|
|
* @return array<int,string> The set of possible levels, empty if not defined correctly.
|
|
*
|
|
* @phan-suppress PhanUndeclaredProperty
|
|
*/
|
|
public function getPossibleLevels($langs)
|
|
{
|
|
$depth_array = array();
|
|
$max_depth = getDolGlobalString('SUBTOTAL_'.strtoupper($this->element).'_MAX_DEPTH', 2);
|
|
for ($i = 0; $i < $max_depth; $i++) {
|
|
$depth_array[$i + 1] = $langs->trans("SubtotalLevel", $i + 1);
|
|
}
|
|
return $depth_array;
|
|
}
|
|
|
|
/**
|
|
* Returns an array with the IDs of the line that we don't need to show to avoid empty blocks
|
|
*
|
|
* @return array<int> $total_ht
|
|
*
|
|
* @phan-suppress PhanUndeclaredProperty
|
|
*/
|
|
public function getDisabledShippmentSubtotalLines()
|
|
{
|
|
$toDisableLines = array();
|
|
$toDisable = true;
|
|
$oldDesc = "";
|
|
$oldDepth = 0;
|
|
|
|
foreach ($this->lines as $titleLine) {
|
|
if ($titleLine->special_code != SUBTOTALS_SPECIAL_CODE || $titleLine->qty <= 0) {
|
|
continue;
|
|
}
|
|
foreach ($this->lines as $line) {
|
|
if ($line->id == $titleLine->id) {
|
|
$oldDesc = $line->desc;
|
|
$oldDepth = $line->qty;
|
|
}
|
|
if ($line->special_code != SUBTOTALS_SPECIAL_CODE && $line->fk_product_type == 0 && !empty($oldDesc) && !empty($oldDepth)) {
|
|
$toDisable = false;
|
|
}
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty == -$oldDepth && $line->desc == $oldDesc) {
|
|
if ($toDisable) {
|
|
$toDisableLines = array_merge($toDisableLines, array($titleLine->id, $line->id));
|
|
}
|
|
$oldDesc = "";
|
|
$oldDepth = 0;
|
|
$toDisable = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return $toDisableLines;
|
|
}
|
|
}
|