36 public static $PRODUCT_TYPE = 9;
42 public static $TITLE_OPTIONS = [
'titleshowuponpdf',
'titleshowtotalexludingvatonpdf',
'titleforcepagebreak'];
48 public static $SUBTOTAL_OPTIONS = [
'subtotalshowtotalexludingvatonpdf'];
53 public static $ALLOWED_TYPES = [
80 public function addSubtotalLine($langs, $desc, $depth, $options = array(), $parent_line = 0)
82 if (!isset($desc) || trim((
string) $desc) ===
'') {
83 $this->errors[] = $langs->trans(
"TitleNeedDesc");
86 $current_module = $this->element;
88 if (!in_array($current_module, self::$ALLOWED_TYPES)) {
89 $this->errors[] = $langs->trans(
"UnsupportedModuleError");
98 if ($depth < 0 && $current_module !=
'shipping') {
99 foreach ($this->lines as $line) {
100 if (!$next_line && $line->desc == $desc && $line->qty == -$depth) {
104 if ($next_line && $line->desc == $desc && $line->qty == $depth) {
108 if ($next_line && $line->special_code == SUBTOTALS_SPECIAL_CODE && abs($line->qty) <= abs($depth)) {
115 if ($depth > 0 && $current_module !=
'shipping') {
116 $max_existing_level = 0;
118 foreach ($this->lines as $line) {
119 if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty > $max_existing_level) {
120 $max_existing_level = $line->qty;
124 if ($max_existing_level+1 < $depth) {
125 $depth = $max_existing_level+1;
126 $this->errors[] = $langs->trans(
"TitleAddedLevelTooHigh", $depth);
133 if ($current_module ==
'facture' && $this instanceof
Facture) {
134 $result = $this->addline(
152 SUBTOTALS_SPECIAL_CODE
154 } elseif ($current_module ==
'propal' && $this instanceof
Propal) {
155 $result = $this->addline(
169 SUBTOTALS_SPECIAL_CODE
171 } elseif ($current_module ==
'commande' && $this instanceof
Commande) {
172 $result = $this->addline(
189 SUBTOTALS_SPECIAL_CODE
191 } elseif ($current_module ==
'shipping' && $this instanceof
Expedition) {
192 $result = $this->addline(
197 } elseif ($current_module ==
'facturerec' && $this instanceof
FactureRec) {
198 $rang = $rang == -1 ? $rang : $rang-1;
199 $result = $this->addline(
214 SUBTOTALS_SPECIAL_CODE
216 $this->fetch_lines();
217 } elseif ($current_module ==
'supplier_proposal' && $this instanceof
SupplierProposal) {
218 $rang = $rang == -1 ? $rang : $rang-1;
219 $result = $this->addline(
233 SUBTOTALS_SPECIAL_CODE
236 $rang = $rang == -1 ? $rang : $rang-1;
237 $result = $this->addline(
261 SUBTOTALS_SPECIAL_CODE
263 } elseif ($current_module ==
'invoice_supplier' && $this instanceof
FactureFournisseur) {
264 $rang = $rang == -1 ? $rang : $rang-1;
265 $result = $this->addline(
287 SUBTOTALS_SPECIAL_CODE
289 } elseif ($current_module ==
'fichinter' && $this instanceof
Fichinter) {
291 $result = $this->addline(
300 SUBTOTALS_SPECIAL_CODE
305 if ($current_module !=
'shipping' && $result > 0) {
308 if ($current_module ==
'supplier_proposal') {
309 $this->fetch($this->
id);
310 } elseif ($current_module ==
'fichinter') {
311 $this->fetch_lines();
313 foreach ($this->lines as $line) {
314 '@phan-var-force CommonObjectLine $line';
316 if ($line->id == $result) {
317 $line->extraparams[
"subtotal"] = $options;
318 $line->setExtraParameters();
327 return $error > 0 ? 0 : $result;
343 public function deleteSubtotalLine($langs,
$id, $correspondingstline =
false, $user =
null)
345 $current_module = $this->element;
347 if (!in_array($current_module, self::$ALLOWED_TYPES)) {
348 $this->errors[] = $langs->trans(
"UnsupportedModuleError");
354 if ($correspondingstline) {
357 foreach ($this->lines as $line) {
358 if ($line->id ==
$id) {
359 $oldDesc = $line->desc;
360 $oldDepth = $line->qty;
362 if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty == -$oldDepth && $line->desc == $oldDesc) {
363 $this->deleteSubtotalLine($langs, $line->id,
false, $user);
370 if ($current_module ==
'facture' && $this instanceof
Facture) {
372 $result = $this->deleteLine($rowid);
373 } elseif ($current_module ==
'propal' && $this instanceof
Propal) {
375 $result = $this->deleteLine($rowid);
376 } elseif ($current_module ==
'commande' && $this instanceof
Commande) {
378 $result = $this->deleteLine($user, $lineid);
379 } elseif ($current_module ==
'facturerec') {
382 $result = $line->delete($user);
383 } elseif ($current_module ==
'shipping') {
386 $result = $line->delete($user);
387 } elseif ($current_module ==
'supplier_proposal') {
390 $result = $line->delete($user);
391 } elseif ($current_module ==
'order_supplier') {
394 $result = $line->delete($user);
395 } elseif ($current_module ==
'invoice_supplier') {
398 $result = $line->delete();
399 } elseif ($current_module ==
'fichinter') {
402 $result = $line->deleteLine($user);
405 return $result >= 0 ? $result : -1;
423 public function updateSubtotalLine($langs, $lineid, $desc, $depth, $options)
425 $current_module = $this->element;
427 if (!in_array($current_module, self::$ALLOWED_TYPES)) {
428 $this->errors[] = $langs->trans(
"UnsupportedModuleError");
435 $max_existing_level = 0;
438 foreach ($this->lines as $line) {
439 if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty > $max_existing_level && $line->id != $lineid) {
440 $max_existing_level = $line->qty;
445 if ($max_existing_level+1 < $depth) {
446 $depth = $max_existing_level+1;
447 $this->errors[] = $langs->trans(
"TitleEditedLevelTooHigh");
454 foreach ($this->lines as $line) {
455 if ($line->id == $lineid) {
456 $oldDesc = $line->desc;
457 $oldDepth = $line->qty;
459 if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty == -$oldDepth && $line->desc == $oldDesc) {
460 $this->updateSubtotalLine($langs, $line->id, $desc, -$depth, !empty($line->extraparams[
"subtotal"]) ? $line->extraparams[
"subtotal"] : array());
467 if ($current_module ==
'facture' && $this instanceof
Facture) {
468 $result = $this->updateline(
487 SUBTOTALS_SPECIAL_CODE
489 } elseif ($current_module ==
'propal' && $this instanceof
Propal) {
490 $result = $this->updateline(
501 SUBTOTALS_SPECIAL_CODE,
509 } elseif ($current_module ==
'commande' && $this instanceof
Commande) {
510 $result = $this->updateline(
529 SUBTOTALS_SPECIAL_CODE
531 } elseif ($current_module ==
'facturerec' && $this instanceof
FactureRec) {
533 $objectline->fetch($lineid);
534 $line_rang = $objectline->rang;
535 $result = $this->updateline(
551 SUBTOTALS_SPECIAL_CODE
553 } elseif ($current_module ==
'supplier_proposal' && $this instanceof
SupplierProposal) {
555 $objectline->fetch($lineid);
556 $line_rang = $objectline->rang;
557 $result = $this->updateline(
568 SUBTOTALS_SPECIAL_CODE,
578 $objectline->fetch($lineid);
579 $line_rang = $objectline->rang;
581 $result = $this->updateline(
599 } elseif ($current_module ==
'invoice_supplier' && $this instanceof
FactureFournisseur) {
601 $objectline->fetch($lineid);
602 $line_rang = $objectline->rang;
603 $result = $this->updateline(
619 foreach ($this->lines as $line) {
620 '@phan-var-force CommonObjectLine $line';
622 if ($line->id == $lineid) {
623 $line->extraparams[
"subtotal"] = $options;
624 $line->setExtraParameters();
632 return $error > 0 ? 0 : $result;
647 public function updateSubtotalLineBlockLines($langs, $linerang, $mode, $value)
649 $current_module = $this->element;
651 if (!in_array($current_module, self::$ALLOWED_TYPES)) {
652 $this->errors[] = $langs->trans(
"UnsupportedModuleError");
659 $nb_lines = count($this->lines);
661 for ($i = $linerang+1; $i < $nb_lines; $i++) {
662 if ($this->lines[$i]->special_code == SUBTOTALS_SPECIAL_CODE) {
663 if (abs($this->lines[$i]->qty) <= (
int) $this->lines[$linerang]->qty) {
667 if ($current_module ==
'facture' && $this instanceof
Facture) {
669 $line_price_base_type = $this->lines[$i]->getPriceBaseType();
670 $line_pu = ($line_price_base_type ===
'TTC') ? $this->lines[$i]->subprice_ttc : $this->lines[$i]->subprice;
671 $result = $this->updateline(
672 $this->lines[$i]->
id,
673 $this->lines[$i]->desc,
675 $this->lines[$i]->qty,
676 $mode ==
'discount' ? $value : $this->lines[$i]->remise_percent,
677 $this->lines[$i]->date_start,
678 $this->lines[$i]->date_end,
679 $mode ==
'tva' ? $value : $this->lines[$i]->tva_tx,
680 $this->lines[$i]->localtax1_tx,
681 $this->lines[$i]->localtax2_tx,
682 $line_price_base_type,
683 $this->lines[$i]->info_bits,
684 $this->lines[$i]->product_type,
685 $this->lines[$i]->fk_parent_line,
687 $this->lines[$i]->fk_fournprice,
688 $this->lines[$i]->pa_ht,
689 $this->lines[$i]->label,
690 $this->lines[$i]->special_code,
691 $this->lines[$i]->array_options,
692 $this->lines[$i]->situation_percent,
693 $this->lines[$i]->fk_unit,
694 $this->lines[$i]->multicurrency_subprice
696 } elseif ($current_module ==
'commande' && $this instanceof
Commande) {
698 $line_price_base_type = $this->lines[$i]->getPriceBaseType();
699 $line_pu = ($line_price_base_type ===
'TTC') ? $this->lines[$i]->subprice_ttc : $this->lines[$i]->subprice;
700 $result = $this->updateline(
701 $this->lines[$i]->
id,
702 $this->lines[$i]->desc,
704 $this->lines[$i]->qty,
705 $mode ==
'discount' ? $value : $this->lines[$i]->remise_percent,
706 $mode ==
'tva' ? $value : $this->lines[$i]->tva_tx,
707 $this->lines[$i]->localtax1_tx,
708 $this->lines[$i]->localtax2_tx,
709 $line_price_base_type,
710 $this->lines[$i]->info_bits,
711 $this->lines[$i]->date_start,
712 $this->lines[$i]->date_end,
713 $this->lines[$i]->product_type,
714 $this->lines[$i]->fk_parent_line,
716 $this->lines[$i]->fk_fournprice,
717 $this->lines[$i]->pa_ht,
718 $this->lines[$i]->label,
719 $this->lines[$i]->special_code,
720 $this->lines[$i]->array_options,
721 $this->lines[$i]->fk_unit,
722 $this->lines[$i]->multicurrency_subprice
724 } elseif ($current_module ==
'propal' && $this instanceof
Propal) {
726 $line_price_base_type = $this->lines[$i]->getPriceBaseType();
727 $line_pu = ($line_price_base_type ===
'TTC') ? $this->lines[$i]->subprice_ttc : $this->lines[$i]->subprice;
728 $result = $this->updateline(
729 $this->lines[$i]->
id,
731 $this->lines[$i]->qty,
732 $mode ==
'discount' ? $value : $this->lines[$i]->remise_percent,
733 $mode ==
'tva' ? $value : $this->lines[$i]->tva_tx,
734 $this->lines[$i]->localtax1_tx,
735 $this->lines[$i]->localtax2_tx,
736 $this->lines[$i]->desc,
737 $line_price_base_type,
738 $this->lines[$i]->info_bits,
739 $this->lines[$i]->special_code,
740 $this->lines[$i]->fk_parent_line,
742 $this->lines[$i]->fk_fournprice,
743 $this->lines[$i]->pa_ht,
744 $this->lines[$i]->label,
745 $this->lines[$i]->product_type,
746 $this->lines[$i]->date_start,
747 $this->lines[$i]->date_end,
748 $this->lines[$i]->array_options,
749 $this->lines[$i]->fk_unit,
750 $this->lines[$i]->multicurrency_subprice
752 } elseif ($current_module ==
'supplier_proposal' && $this instanceof
SupplierProposal) {
754 $line_price_base_type = $this->lines[$i]->getPriceBaseType();
755 $line_pu = ($line_price_base_type ===
'TTC') ? $this->lines[$i]->subprice_ttc : $this->lines[$i]->subprice;
756 $result = $this->updateline(
757 $this->lines[$i]->
id,
759 $this->lines[$i]->qty,
760 $mode ==
'discount' ? $value : $this->lines[$i]->remise_percent,
761 $mode ==
'tva' ? $value : $this->lines[$i]->tva_tx,
762 $this->lines[$i]->localtax1_tx,
763 $this->lines[$i]->localtax2_tx,
764 $this->lines[$i]->desc,
765 $line_price_base_type,
766 $this->lines[$i]->info_bits,
767 $this->lines[$i]->special_code,
768 $this->lines[$i]->fk_parent_line,
770 $this->lines[$i]->fk_fournprice,
771 $this->lines[$i]->pa_ht,
772 $this->lines[$i]->label,
773 $this->lines[$i]->product_type,
774 $this->lines[$i]->array_options,
775 $this->lines[$i]->ref_supplier,
776 (int) $this->lines[$i]->fk_unit,
777 $this->lines[$i]->multicurrency_subprice
781 $line_price_base_type = $this->lines[$i]->getPriceBaseType();
782 $line_pu = ($line_price_base_type ===
'TTC') ? $this->lines[$i]->subprice_ttc : $this->lines[$i]->subprice;
783 $result = $this->updateline(
784 $this->lines[$i]->
id,
785 $this->lines[$i]->desc,
787 $this->lines[$i]->qty,
788 $mode ==
'discount' ? $value : $this->lines[$i]->remise_percent,
789 $mode ==
'tva' ? $value : $this->lines[$i]->tva_tx,
790 $this->lines[$i]->localtax1_tx,
791 $this->lines[$i]->localtax2_tx,
792 $line_price_base_type,
793 $this->lines[$i]->info_bits,
794 $this->lines[$i]->product_type,
796 $this->lines[$i]->date_start,
797 $this->lines[$i]->date_end,
798 $this->lines[$i]->array_options,
799 $this->lines[$i]->fk_unit,
800 $this->lines[$i]->multicurrency_subprice,
801 $this->lines[$i]->ref_supplier
825 public function getSubtotalLineAmountValue($line, $multicurrency =
false)
827 $field = $multicurrency ?
'multicurrency_total_ht' :
'total_ht';
829 $abovelines = array();
830 $aboverangs = array();
831 foreach ($this->lines as $l) {
832 if (!is_object($l) || $l->rang >= $line->rang) {
835 $aboverangs[] = (int) $l->rang;
839 array_multisort($aboverangs, SORT_DESC, SORT_NUMERIC, $abovelines);
842 foreach ($abovelines as $l) {
843 if ($l->special_code == SUBTOTALS_SPECIAL_CODE && $l->qty > 0) {
844 if ($l->qty <= abs($line->qty)) {
849 $final_amount += (float) $l->$field;
852 return $final_amount;
864 public function getSubtotalLineAmount($line)
866 return price($this->getSubtotalLineAmountValue($line,
false));
878 public function getSubtotalLineMulticurrencyAmount($line)
880 return price($this->getSubtotalLineAmountValue($line,
true));
889 public function getSubtotalColors($level)
901 public function getPossibleTitles()
904 foreach ($this->lines as $line) {
905 if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty > 0) {
906 $titles[$line->desc] = $line->desc;
908 if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty < 0) {
909 unset($titles[$line->desc]);
923 public function getPossibleLevels($langs)
925 $depth_array = array();
926 $max_depth =
getDolGlobalInt(
'SUBTOTAL_'.strtoupper($this->element).
'_MAX_DEPTH', 2);
927 for ($i = 0; $i < $max_depth; $i++) {
928 $depth_array[$i + 1] = $langs->trans(
"SubtotalLevel", $i + 1);
941 public function getPredefinedTitles()
945 $sql =
"SELECT rowid, label FROM ".MAIN_DB_PREFIX.
"c_subtotals_titles";
946 $sql .=
" WHERE active = 1 AND entity IN (".getEntity(
'c_subtotals_titles').
")";
947 $sql .=
" ORDER BY label ASC";
949 $resql = $this->db->query($sql);
951 while ($obj = $this->db->fetch_object($resql)) {
952 $titles[(int) $obj->rowid] = $obj->label;
967 public function getPredefinedTexts()
971 $sql =
"SELECT rowid, label, content FROM ".MAIN_DB_PREFIX.
"c_subtotals_texts";
972 $sql .=
" WHERE active = 1 AND entity IN (".getEntity(
'c_subtotals_texts').
")";
973 $sql .=
" ORDER BY label ASC";
975 $resql = $this->db->query($sql);
977 while ($obj = $this->db->fetch_object($resql)) {
978 $texts[(int) $obj->rowid] = array(
'label' => $obj->label,
'content' => $obj->content);
992 public function getDisabledShippmentSubtotalLines()
994 $toDisableLines = array();
999 foreach ($this->lines as $titleLine) {
1000 if ($titleLine->special_code != SUBTOTALS_SPECIAL_CODE || $titleLine->qty <= 0) {
1003 foreach ($this->lines as $line) {
1004 if ($line->id == $titleLine->id) {
1005 $oldDesc = $line->desc;
1006 $oldDepth = $line->qty;
1008 if ($line->special_code != SUBTOTALS_SPECIAL_CODE && $line->fk_product_type == 0 && !empty($oldDesc) && !empty($oldDepth)) {
1011 if ($line->special_code == SUBTOTALS_SPECIAL_CODE && $line->qty == -$oldDepth && $line->desc == $oldDesc) {
1013 $toDisableLines = array_merge($toDisableLines, array($titleLine->id, $line->id));
1022 return $toDisableLines;
$id
Support class for third parties, contacts, members, users or resources.
Class to manage predefined suppliers products.
Class to manage line orders.
Class to manage customers orders.
Class to manage lines of shipment.
Class to manage suppliers invoices.
Class to manage invoices.
Class to manage invoice lines of templates.
Class to manage invoice templates.
Class to manage intervention lines.
Class to manage proposals.
Class to manage line invoices.
Class to manage price ask supplier.
Class to manage supplier_proposal lines.
dol_html_entity_decode($a, $b, $c='UTF-8', $keepsomeentities=0)
Replace html_entity_decode functions to manage errors.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.