39include_once DOL_DOCUMENT_ROOT.
'/core/class/commonorder.class.php';
40require_once DOL_DOCUMENT_ROOT.
'/commande/class/orderline.class.php';
41require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
42require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
43require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
44require_once DOL_DOCUMENT_ROOT.
'/societe/class/societe.class.php';
55 public $element =
'commande';
60 public $table_element =
'commande';
65 public $table_element_line =
'commandedet';
70 public $class_element_line =
'OrderLine';
75 public $fk_element =
'fk_commande';
80 public $picto =
'order';
86 public $restrictiononfksoc = 1;
106 public $ref_customer;
134 public $date_lim_reglement;
138 public $cond_reglement_code;
143 public $cond_reglement_doc;
150 public $deposit_percent;
160 public $mode_reglement;
165 public $mode_reglement_id;
170 public $mode_reglement_code;
176 public $availability_id;
182 public $availability_code;
188 public $availability;
193 public $demand_reason_id;
198 public $demand_reason_code;
210 public $date_commande;
215 public $delivery_date;
220 public $fk_remise_except;
226 public $remise_percent;
237 public $signed_status = 0;
242 public $warehouse_id;
247 public $extraparams = array();
249 public $linked_objects = array();
254 public $user_author_id;
264 public $lines = array();
270 public $module_source;
284 public $online_payment_url;
316 public $fields = array(
317 'rowid' => array(
'type' =>
'integer',
'label' =>
'TechnicalID',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 10),
318 'entity' => array(
'type' =>
'integer',
'label' =>
'Entity',
'default' =>
'1',
'enabled' => 1,
'visible' => -2,
'notnull' => 1,
'position' => 20,
'index' => 1),
319 'ref' => array(
'type' =>
'varchar(30)',
'label' =>
'Ref',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'showoncombobox' => 1,
'position' => 25),
320 'ref_ext' => array(
'type' =>
'varchar(255)',
'label' =>
'RefExt',
'enabled' => 1,
'visible' => 0,
'position' => 26),
321 'ref_client' => array(
'type' =>
'varchar(255)',
'label' =>
'RefCustomer',
'enabled' => 1,
'visible' => -1,
'position' => 28),
322 'fk_soc' => array(
'type' =>
'integer:Societe:societe/class/societe.class.php',
'label' =>
'ThirdParty',
'enabled' =>
'isModEnabled("societe")',
'visible' => -1,
'notnull' => 1,
'position' => 20),
323 'fk_projet' => array(
'type' =>
'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)',
'label' =>
'Project',
'enabled' =>
"isModEnabled('project')",
'visible' => -1,
'position' => 25),
324 'date_commande' => array(
'type' =>
'date',
'label' =>
'Date',
'enabled' => 1,
'visible' => 1,
'position' => 60,
'csslist' =>
'nowraponall'),
325 'date_valid' => array(
'type' =>
'datetime',
'label' =>
'DateValidation',
'enabled' => 1,
'visible' => -1,
'position' => 62,
'csslist' =>
'nowraponall'),
326 'date_cloture' => array(
'type' =>
'datetime',
'label' =>
'DateClosing',
'enabled' => 1,
'visible' => -1,
'position' => 65,
'csslist' =>
'nowraponall'),
327 'fk_user_valid' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserValidation',
'enabled' => 1,
'visible' => -1,
'position' => 85),
328 'fk_user_cloture' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserClosing',
'enabled' => 1,
'visible' => -1,
'position' => 90),
329 'source' => array(
'type' =>
'smallint(6)',
'label' =>
'Source',
'enabled' => 1,
'visible' => -1,
'position' => 95),
330 'total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'VAT',
'enabled' => 1,
'visible' => -1,
'position' => 125,
'isameasure' => 1),
331 'localtax1' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax1',
'enabled' => 1,
'visible' => -1,
'position' => 130,
'isameasure' => 1),
332 'localtax2' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax2',
'enabled' => 1,
'visible' => -1,
'position' => 135,
'isameasure' => 1),
333 'total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalHT',
'enabled' => 1,
'visible' => -1,
'position' => 140,
'isameasure' => 1),
334 'total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalTTC',
'enabled' => 1,
'visible' => -1,
'position' => 145,
'isameasure' => 1),
335 'signed_status' => array(
'type' =>
'smallint(6)',
'label' =>
'SignedStatus',
'enabled' => 1,
'visible' => -1,
'position' => 146,
'arrayofkeyval' => array(0 =>
'NoSignature', 1 =>
'SignedSender', 2 =>
'SignedReceiver', 9 =>
'SignedAll')),
336 'note_private' => array(
'type' =>
'html',
'label' =>
'NotePrivate',
'enabled' => 1,
'visible' => 0,
'position' => 150),
337 'note_public' => array(
'type' =>
'html',
'label' =>
'NotePublic',
'enabled' => 1,
'visible' => 0,
'position' => 155),
338 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'PDFTemplate',
'enabled' => 1,
'visible' => 0,
'position' => 160),
339 'fk_account' => array(
'type' =>
'integer',
'label' =>
'BankAccount',
'enabled' =>
'isModEnabled("bank")',
'visible' => -1,
'position' => 170),
340 'fk_currency' => array(
'type' =>
'varchar(3)',
'label' =>
'MulticurrencyID',
'enabled' => 1,
'visible' => -1,
'position' => 175),
341 'fk_cond_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentTerm',
'enabled' => 1,
'visible' => -1,
'position' => 180),
342 'deposit_percent' => array(
'type' =>
'varchar(63)',
'label' =>
'DepositPercent',
'enabled' => 1,
'visible' => -1,
'position' => 181),
343 'fk_mode_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentMode',
'enabled' => 1,
'visible' => -1,
'position' => 185),
344 'date_livraison' => array(
'type' =>
'date',
'label' =>
'DateDeliveryPlanned',
'enabled' => 1,
'visible' => -1,
'position' => 190,
'csslist' =>
'nowraponall'),
345 'fk_shipping_method' => array(
'type' =>
'integer',
'label' =>
'ShippingMethod',
'enabled' => 1,
'visible' => -1,
'position' => 195),
346 'fk_warehouse' => array(
'type' =>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label' =>
'DefaultWarehouse',
'enabled' =>
'isModEnabled("stock")',
'visible' => -1,
'position' => 200,
'nodepth' => 1),
347 'fk_availability' => array(
'type' =>
'integer',
'label' =>
'Availability',
'enabled' => 1,
'visible' => -1,
'position' => 205),
348 'fk_input_reason' => array(
'type' =>
'integer',
'label' =>
'InputReason',
'enabled' => 1,
'visible' => -1,
'position' => 210),
350 'extraparams' => array(
'type' =>
'varchar(255)',
'label' =>
'Extraparams',
'enabled' => 1,
'visible' => -1,
'position' => 225),
351 'fk_incoterms' => array(
'type' =>
'integer',
'label' =>
'IncotermCode',
'enabled' =>
'$conf->incoterm->enabled',
'visible' => -1,
'position' => 230),
352 'location_incoterms' => array(
'type' =>
'varchar(255)',
'label' =>
'IncotermLabel',
'enabled' =>
'$conf->incoterm->enabled',
'visible' => -1,
'position' => 235),
353 'fk_multicurrency' => array(
'type' =>
'integer',
'label' =>
'Fk multicurrency',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 240),
354 'multicurrency_code' => array(
'type' =>
'varchar(255)',
'label' =>
'MulticurrencyCurrency',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 245),
355 'multicurrency_tx' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyRate',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 250,
'isameasure' => 1),
356 'multicurrency_total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountHT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 255,
'isameasure' => 1),
357 'multicurrency_total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountVAT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 260,
'isameasure' => 1),
358 'multicurrency_total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountTTC',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 265,
'isameasure' => 1),
359 'last_main_doc' => array(
'type' =>
'varchar(255)',
'label' =>
'LastMainDoc',
'enabled' => 1,
'visible' => -1,
'position' => 270),
360 'module_source' => array(
'type' =>
'varchar(32)',
'label' =>
'POSModule',
'enabled' => 1,
'visible' => -1,
'position' => 275),
361 'pos_source' => array(
'type' =>
'varchar(32)',
'label' =>
'POSTerminal',
'enabled' => 1,
'visible' => -1,
'position' => 280),
362 'fk_user_author' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserAuthor',
'enabled' => 1,
'visible' => -1,
'position' => 300),
363 'fk_user_modif' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserModif',
'enabled' => 1,
'visible' => -2,
'notnull' => -1,
'position' => 302),
364 'date_creation' => array(
'type' =>
'datetime',
'label' =>
'DateCreation',
'enabled' => 1,
'visible' => -2,
'position' => 304,
'csslist' =>
'nowraponall'),
365 'tms' => array(
'type' =>
'timestamp',
'label' =>
'DateModification',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 306),
366 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -2,
'position' => 400),
367 'fk_statut' => array(
'type' =>
'smallint(6)',
'label' =>
'Status',
'enabled' => 1,
'visible' => -1,
'position' => 500),
407 const STATUS_NO_SIGNATURE = 0;
412 const STATUS_SIGNED_SENDER = 1;
417 const STATUS_SIGNED_RECEIVER = 2;
422 const STATUS_SIGNED_ALL = 9;
434 $this->ismultientitymanaged = 1;
435 $this->isextrafieldmanaged = 1;
437 $this->fields[
'ref_ext'][
'visible'] =
getDolGlobalInt(
'MAIN_LIST_SHOW_REF_EXT');
449 global $langs,
$conf;
450 $langs->load(
"order");
459 $dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
460 foreach ($dirmodels as $reldir) {
464 $mybool = ((bool) @include_once $dir.$file) || $mybool;
472 $obj =
new $classname();
473 '@phan-var-force ModeleNumRefCommandes $obj';
475 $numref = $obj->getNextValue($soc, $this);
480 $this->error = $obj->error;
485 print $langs->trans(
"Error").
" ".$langs->trans(
"Error_COMMANDE_ADDON_NotDefined");
499 public function valid($user, $idwarehouse = 0, $notrigger = 0)
501 global
$conf, $langs;
503 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
508 if ($this->statut == self::STATUS_VALIDATED) {
509 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
513 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'commande',
'creer'))
514 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'commande',
'order_advance',
'validate')))) {
515 $this->error =
'NotEnoughPermissions';
516 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
526 $soc->fetch($this->socid);
529 $result = $soc->setAsCustomer();
532 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
540 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
541 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
542 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
543 $sql .=
" date_valid='".$this->db->idate($now).
"',";
544 $sql .=
" fk_user_valid = ".($user->id > 0 ? (int) $user->id :
"null").
",";
545 $sql .=
" fk_user_modif = ".((int) $user->id);
546 $sql .=
" WHERE rowid = ".((int) $this->
id);
548 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
549 $resql = $this->db->query($sql);
552 $this->error = $this->db->lasterror();
558 if ($result >= 0 && isModEnabled(
'stock') &&
getDolGlobalInt(
'STOCK_CALCULATE_ON_VALIDATE_ORDER') == 1) {
559 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
560 $langs->load(
"agenda");
563 $cpt = count($this->lines);
564 for ($i = 0; $i < $cpt; $i++) {
565 if ($this->lines[$i]->fk_product > 0) {
567 $mouvP->origin = &$this;
568 $mouvP->setOrigin($this->element, $this->
id);
570 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"OrderValidatedInDolibarr", $num));
573 $this->error = $mouvP->error;
583 if (!$error && !$notrigger) {
593 $this->oldref = $this->ref;
596 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
598 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'commande/".$this->db->escape($this->newref).
"'";
599 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'commande/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
600 $resql = $this->db->query($sql);
603 $this->error = $this->db->lasterror();
605 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'commande/".$this->db->escape($this->newref).
"'";
606 $sql .=
" WHERE filepath = 'commande/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
607 $resql = $this->db->query($sql);
610 $this->error = $this->db->lasterror();
616 $dirsource =
$conf->commande->multidir_output[$this->entity].
'/'.$oldref;
617 $dirdest =
$conf->commande->multidir_output[$this->entity].
'/'.$newref;
618 if (!$error && file_exists($dirsource)) {
619 dol_syslog(get_class($this).
"::valid rename dir ".$dirsource.
" into ".$dirdest);
621 if (@rename($dirsource, $dirdest)) {
624 $listoffiles =
dol_dir_list(
$conf->commande->multidir_output[$this->entity].
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
625 foreach ($listoffiles as $fileentry) {
626 $dirsource = $fileentry[
'name'];
627 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
628 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
629 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
630 @rename($dirsource, $dirdest);
648 $this->db->rollback();
664 global
$conf, $langs;
669 if ($this->statut <= self::STATUS_DRAFT && !
getDolGlobalInt(
'ORDER_REOPEN_TO_DRAFT')) {
673 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'commande',
'creer'))
674 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'commande',
'order_advance',
'validate')))) {
675 $this->error =
'Permission denied';
683 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
684 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT.
",";
685 $sql .=
" fk_user_modif = ".((int) $user->id);
686 $sql .=
" WHERE rowid = ".((int) $this->
id);
688 if ($this->db->query($sql)) {
690 $this->oldcopy = clone $this;
694 if (isModEnabled(
'stock') &&
getDolGlobalInt(
'STOCK_CALCULATE_ON_VALIDATE_ORDER') == 1) {
697 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
698 $langs->load(
"agenda");
700 $num = count($this->lines);
701 for ($i = 0; $i < $num; $i++) {
702 if ($this->lines[$i]->fk_product > 0) {
704 $mouvP->origin = &$this;
705 $mouvP->setOrigin($this->element, $this->
id);
707 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"OrderBackToDraftInDolibarr", $this->ref));
710 $this->error = $mouvP->error;
719 $result = $this->
call_trigger(
'ORDER_UNVALIDATE', $user);
730 $this->db->rollback();
734 $this->error = $this->db->error();
735 $this->db->rollback();
754 if ($this->statut != self::STATUS_CANCELED && $this->statut != self::STATUS_CLOSED) {
755 dol_syslog(get_class($this).
"::set_reopen order has not status closed", LOG_WARNING);
761 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
762 $sql .=
' SET fk_statut='.self::STATUS_VALIDATED.
', facture=0,';
763 $sql .=
" fk_user_modif = ".((int) $user->id);
764 $sql .=
" WHERE rowid = ".((int) $this->
id);
766 dol_syslog(get_class($this).
"::set_reopen", LOG_DEBUG);
767 $resql = $this->db->query($sql);
777 $this->error = $this->db->lasterror();
788 foreach ($this->errors as $errmsg) {
789 dol_syslog(get_class($this).
"::set_reopen ".$errmsg, LOG_ERR);
790 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
792 $this->db->rollback();
804 public function cloture($user, $notrigger = 0)
808 $usercanclose = ((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'commande',
'creer'))
809 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'commande',
'order_advance',
'close')));
812 if ($this->statut == self::STATUS_CLOSED) {
819 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
820 $sql .=
' SET fk_statut = '.self::STATUS_CLOSED.
',';
821 $sql .=
' fk_user_cloture = '.((int) $user->id).
',';
822 $sql .=
" date_cloture = '".$this->db->idate($now).
"',";
823 $sql .=
" fk_user_modif = ".((int) $user->id);
826 if ($this->db->query($sql)) {
843 $this->db->rollback();
847 $this->error = $this->db->lasterror();
849 $this->db->rollback();
863 public function cancel($idwarehouse = -1)
865 global $user, $langs;
871 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
872 $sql .=
" SET fk_statut = ".self::STATUS_CANCELED.
",";
873 $sql .=
" fk_user_modif = ".((int) $user->id);
874 $sql .=
" WHERE rowid = ".((int) $this->
id);
875 $sql .=
" AND fk_statut = ".self::STATUS_VALIDATED;
877 dol_syslog(get_class($this).
"::cancel", LOG_DEBUG);
878 if ($this->db->query($sql)) {
880 if (isModEnabled(
'stock') &&
getDolGlobalInt(
'STOCK_CALCULATE_ON_VALIDATE_ORDER') == 1) {
881 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
882 $langs->load(
"agenda");
884 $num = count($this->lines);
885 for ($i = 0; $i < $num; $i++) {
886 if ($this->lines[$i]->fk_product > 0) {
888 $mouvP->setOrigin($this->element, $this->
id);
890 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"OrderCanceledInDolibarr", $this->ref));
893 $this->error = $mouvP->error;
914 foreach ($this->errors as $errmsg) {
915 dol_syslog(get_class($this).
"::cancel ".$errmsg, LOG_ERR);
916 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
918 $this->db->rollback();
922 $this->error = $this->db->error();
923 $this->db->rollback();
936 public function create($user, $notrigger = 0)
938 global
$conf, $langs, $mysoc;
944 $date = ($this->date_commande ? $this->date_commande : $this->date);
945 $delivery_date = $this->delivery_date;
948 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
953 if (empty($this->fk_multicurrency)) {
954 $this->multicurrency_code =
$conf->currency;
955 $this->fk_multicurrency = 0;
956 $this->multicurrency_tx = 1;
961 dol_syslog(get_class($this).
"::create user=".$user->id);
964 if (!empty($this->
ref)) {
967 $this->error =
'ErrorRefAlreadyExists';
968 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
969 $this->db->rollback();
975 $result = $soc->fetch($this->socid);
977 $this->error =
"Failed to fetch company";
978 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
982 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"Source"));
983 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
991 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
" (";
992 $sql .=
" ref, fk_soc, date_creation, fk_user_author, fk_projet, date_commande, source, note_private, note_public, ref_ext, ref_client";
993 $sql .=
", model_pdf, fk_cond_reglement, deposit_percent, fk_mode_reglement, fk_account, fk_availability, fk_input_reason, date_livraison, fk_delivery_address";
994 $sql .=
", fk_shipping_method";
995 $sql .=
", fk_warehouse";
996 $sql .=
", fk_incoterms, location_incoterms";
997 $sql .=
", entity, module_source, pos_source";
998 $sql .=
", fk_multicurrency";
999 $sql .=
", multicurrency_code";
1000 $sql .=
", multicurrency_tx";
1002 $sql .=
" VALUES ('(PROV)', ".((int) $this->socid).
", '".$this->db->idate($now).
"', ".((int) $user->id);
1003 $sql .=
", ".($this->fk_project > 0 ? ((int) $this->fk_project) :
"null");
1004 $sql .=
", '".$this->db->idate($date).
"'";
1005 $sql .=
", ".($this->source >= 0 && $this->source !=
'' ? $this->db->escape($this->source) :
'null');
1006 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1007 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1008 $sql .=
", ".($this->ref_ext ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null");
1009 $sql .=
", ".($this->ref_client ?
"'".$this->db->escape($this->ref_client).
"'" :
"null");
1010 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1011 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
"null");
1012 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null");
1013 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
"null");
1014 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1015 $sql .=
", ".($this->availability_id > 0 ? ((int) $this->availability_id) :
"null");
1016 $sql .=
", ".($this->demand_reason_id > 0 ? ((int) $this->demand_reason_id) :
"null");
1017 $sql .=
", ".($delivery_date ?
"'".$this->db->idate($delivery_date).
"'" :
"null");
1018 $sql .=
", ".($this->fk_delivery_address > 0 ? ((int) $this->fk_delivery_address) :
'NULL');
1019 $sql .=
", ".(!empty($this->shipping_method_id) && $this->shipping_method_id > 0 ? ((int) $this->shipping_method_id) :
'NULL');
1020 $sql .=
", ".(!empty($this->warehouse_id) && $this->warehouse_id > 0 ? ((int) $this->warehouse_id) :
'NULL');
1021 $sql .=
", ".(int) $this->fk_incoterms;
1022 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1023 $sql .=
", ".(int) $this->entity;
1024 $sql .=
", ".($this->module_source ?
"'".$this->db->escape($this->module_source).
"'" :
"null");
1025 $sql .=
", ".($this->pos_source !=
'' ?
"'".$this->db->escape($this->pos_source).
"'" :
"null");
1026 $sql .=
", ".(int) $this->fk_multicurrency;
1027 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1028 $sql .=
", ".(float) $this->multicurrency_tx;
1031 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1032 $resql = $this->db->query($sql);
1034 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'commande');
1037 $fk_parent_line = 0;
1038 $num = count($this->lines);
1043 for ($i = 0; $i < $num; $i++) {
1044 $line = $this->lines[$i];
1048 if (!is_object($line)) {
1049 $line = (object) $line;
1053 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1054 $fk_parent_line = 0;
1058 $vatrate = $line->tva_tx;
1059 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', (
string) $vatrate)) {
1060 $vatrate .=
' ('.$line->vat_src_code.
')';
1064 $originid = $line->origin_id;
1065 $origintype = $line->origin;
1067 $originid = $line->id;
1068 $origintype = $this->element;
1072 if (empty($line->ref_ext)) {
1073 $line->ref_ext =
'';
1081 $line->localtax1_tx,
1082 $line->localtax2_tx,
1084 $line->remise_percent,
1086 $line->fk_remise_except,
1091 $line->product_type,
1093 $line->special_code,
1095 $line->fk_fournprice,
1098 $line->array_options,
1108 if ($result != self::STOCK_NOT_ENOUGH_FOR_ORDER) {
1109 $this->error = $this->db->lasterror();
1110 $this->errors[] = $this->error;
1113 $this->db->rollback();
1117 if ($result > 0 && $line->product_type == 9) {
1118 $fk_parent_line = $result;
1125 $initialref =
'(PROV'.$this->id.
')';
1126 if (!empty($this->
ref)) {
1127 $initialref = $this->ref;
1130 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
" SET ref='".$this->db->escape($initialref).
"' WHERE rowid=".((int) $this->
id);
1131 if ($this->db->query($sql)) {
1132 $this->
ref = $initialref;
1134 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1135 $this->linked_objects = $this->linkedObjectsIds;
1139 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1140 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1141 if (is_array($tmp_origin_id)) {
1142 foreach ($tmp_origin_id as $origin_id) {
1145 $this->error = $this->db->lasterror();
1150 $origin_id = $tmp_origin_id;
1153 $this->error = $this->db->lasterror();
1160 if (!$error && $this->
id &&
getDolGlobalString(
'MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN') && !empty($this->origin) && !empty($this->origin_id)) {
1161 $originforcontact = $this->origin;
1162 $originidforcontact = $this->origin_id;
1163 if ($originforcontact ==
'shipping') {
1164 require_once DOL_DOCUMENT_ROOT.
'/expedition/class/expedition.class.php';
1166 $exp->fetch($this->origin_id);
1167 $exp->fetchObjectLinked();
1168 if (count($exp->linkedObjectsIds[
'commande']) > 0) {
1169 foreach ($exp->linkedObjectsIds[
'commande'] as $key => $value) {
1170 $originforcontact =
'commande';
1171 if (is_object($value)) {
1172 $originidforcontact = $value->id;
1174 $originidforcontact = $value;
1181 $sqlcontact =
"SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX.
"element_contact as ec, ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1182 $sqlcontact .=
" WHERE element_id = ".((int) $originidforcontact).
" AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$this->db->escape($originforcontact).
"'";
1184 $resqlcontact = $this->db->query($sqlcontact);
1185 if ($resqlcontact) {
1186 while ($objcontact = $this->db->fetch_object($resqlcontact)) {
1188 $this->
add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);
1202 if (!$error && !$notrigger) {
1212 $this->db->commit();
1215 $this->db->rollback();
1219 $this->error = $this->db->lasterror();
1220 $this->db->rollback();
1227 $this->error = $this->db->lasterror();
1228 $this->db->rollback();
1243 global
$conf, $user, $hookmanager;
1250 foreach ($this->lines as $line) {
1251 $line->fetch_optionals();
1255 $objFrom = clone $this;
1258 if (!empty($socid) && $socid != $this->socid) {
1259 $objsoc =
new Societe($this->db);
1261 if ($objsoc->fetch($socid) > 0) {
1262 $this->socid = $objsoc->id;
1263 $this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1264 $this->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent : 0);
1265 $this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1266 $this->fk_project = 0;
1267 $this->fk_delivery_address = 0;
1278 $this->user_author_id = $user->id;
1279 $this->user_validation_id = 0;
1281 $this->date_commande =
dol_now();
1282 $this->date_creation =
'';
1283 $this->date_validation =
'';
1285 $this->ref_client =
'';
1286 $this->ref_customer =
'';
1290 $num = count($this->lines);
1291 for ($i = 0; $i < $num; $i++) {
1292 $this->lines[$i]->ref_ext =
'';
1296 $this->context[
'createfromclone'] =
'createfromclone';
1297 $result = $this->
create($user);
1311 if ($this->socid == $objFrom->socid) {
1320 if (is_object($hookmanager)) {
1321 $parameters = array(
'objFrom' => $objFrom);
1323 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1331 unset($this->context[
'createfromclone']);
1335 $this->db->commit();
1338 $this->db->rollback();
1353 global
$conf, $hookmanager;
1355 require_once DOL_DOCUMENT_ROOT .
'/multicurrency/class/multicurrency.class.php';
1356 require_once DOL_DOCUMENT_ROOT .
'/core/class/extrafields.class.php';
1360 $this->date_commande =
dol_now();
1365 for ($i = 0; $i < $num; $i++) {
1368 $line->libelle =
$object->lines[$i]->libelle;
1369 $line->label =
$object->lines[$i]->label;
1370 $line->desc =
$object->lines[$i]->desc;
1371 $line->price =
$object->lines[$i]->price;
1372 $line->subprice =
$object->lines[$i]->subprice;
1373 $line->vat_src_code =
$object->lines[$i]->vat_src_code;
1374 $line->tva_tx =
$object->lines[$i]->tva_tx;
1375 $line->localtax1_tx =
$object->lines[$i]->localtax1_tx;
1376 $line->localtax2_tx =
$object->lines[$i]->localtax2_tx;
1377 $line->qty =
$object->lines[$i]->qty;
1378 $line->fk_remise_except =
$object->lines[$i]->fk_remise_except;
1379 $line->remise_percent =
$object->lines[$i]->remise_percent;
1380 $line->fk_product =
$object->lines[$i]->fk_product;
1381 $line->info_bits =
$object->lines[$i]->info_bits;
1382 $line->product_type =
$object->lines[$i]->product_type;
1383 $line->rang =
$object->lines[$i]->rang;
1384 $line->special_code =
$object->lines[$i]->special_code;
1385 $line->fk_parent_line =
$object->lines[$i]->fk_parent_line;
1386 $line->fk_unit =
$object->lines[$i]->fk_unit;
1388 $line->date_start =
$object->lines[$i]->date_start;
1389 $line->date_end =
$object->lines[$i]->date_end;
1391 $line->fk_fournprice =
$object->lines[$i]->fk_fournprice;
1393 $line->pa_ht = $marginInfos[0];
1394 $line->marge_tx = $marginInfos[1];
1395 $line->marque_tx = $marginInfos[2];
1397 $line->origin =
$object->element;
1398 $line->origin_id =
$object->lines[$i]->id;
1401 $object->lines[$i]->fetch_optionals();
1402 foreach (
$object->lines[$i]->array_options as $options_key => $value) {
1403 $line->array_options[$options_key] = $value;
1406 $this->lines[$i] = $line;
1409 $this->entity =
$object->entity;
1410 $this->socid =
$object->socid;
1411 $this->fk_project =
$object->fk_project;
1412 $this->cond_reglement_id =
$object->cond_reglement_id;
1413 $this->deposit_percent =
$object->deposit_percent;
1414 $this->mode_reglement_id =
$object->mode_reglement_id;
1415 $this->fk_account =
$object->fk_account;
1416 $this->availability_id =
$object->availability_id;
1417 $this->demand_reason_id =
$object->demand_reason_id;
1418 $this->delivery_date =
$object->delivery_date;
1419 $this->shipping_method_id =
$object->shipping_method_id;
1420 $this->warehouse_id =
$object->warehouse_id;
1421 $this->fk_delivery_address =
$object->fk_delivery_address;
1422 $this->contact_id =
$object->contact_id;
1423 $this->ref_client =
$object->ref_client;
1424 $this->ref_customer =
$object->ref_client;
1427 $this->note_private =
$object->note_private;
1428 $this->note_public =
$object->note_public;
1431 $this->origin =
$object->element;
1432 $this->origin_id =
$object->id;
1435 if (isModEnabled(
'multicurrency')) {
1436 if (!empty(
$object->multicurrency_code)) {
1437 $this->multicurrency_code =
$object->multicurrency_code;
1440 $this->multicurrency_tx =
$object->multicurrency_tx;
1443 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1445 $this->fk_multicurrency = $tmparray[0];
1446 $this->multicurrency_tx = $tmparray[1];
1450 if (empty($this->fk_multicurrency)) {
1451 $this->multicurrency_code =
$conf->currency;
1452 $this->fk_multicurrency = 0;
1453 $this->multicurrency_tx = 1;
1461 $element_extrafields = $e->fetch_name_optionals_label($this->table_element);
1463 foreach (
$object->array_options as $options_key => $value) {
1464 if (array_key_exists(str_replace(
'options_',
'', $options_key), $element_extrafields)) {
1465 $this->array_options[$options_key] = $value;
1469 $this->linked_objects[$this->origin] = $this->origin_id;
1470 if (isset(
$object->other_linked_objects) && is_array(
$object->other_linked_objects) && !empty(
$object->other_linked_objects)) {
1471 $this->linked_objects = array_merge($this->linked_objects,
$object->other_linked_objects);
1474 $ret = $this->
create($user);
1478 $hookmanager->initHooks(array(
'orderdao'));
1480 $parameters = array(
'objFrom' =>
$object);
1482 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1492 $this->
valid($user);
1544 public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $info_bits = 0, $fk_remise_except = 0, $price_base_type =
'HT', $pu_ttc = 0, $date_start =
'', $date_end =
'', $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice =
null, $pa_ht = 0, $label =
'', $array_options = array(), $fk_unit =
null, $origin =
'', $origin_id = 0, $pu_ht_devise = 0, $ref_ext =
'', $noupdateafterinsertline = 0)
1546 global $mysoc, $langs, $user;
1548 $logtext =
"::addline commandeid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_percent=$remise_percent";
1549 $logtext .=
", info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, date_start=$date_start";
1550 $logtext .=
", date_end=$date_end, type=$type special_code=$special_code, fk_unit=$fk_unit, origin=$origin, origin_id=$origin_id, pu_ht_devise=$pu_ht_devise, ref_ext=$ref_ext rang=$rang";
1551 dol_syslog(get_class($this).$logtext, LOG_DEBUG);
1553 if ($this->statut == self::STATUS_DRAFT) {
1554 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
1558 if (empty($remise_percent)) {
1559 $remise_percent = 0;
1564 if (empty($info_bits)) {
1570 if (empty($txtva)) {
1573 if (empty($txlocaltax1)) {
1576 if (empty($txlocaltax2)) {
1579 if (empty($fk_parent_line) || $fk_parent_line < 0) {
1580 $fk_parent_line = 0;
1582 if (empty($this->fk_multicurrency)) {
1583 $this->fk_multicurrency = 0;
1585 if (empty($ref_ext)) {
1589 $remise_percent = (float)
price2num($remise_percent);
1592 $pu_ht_devise =
price2num($pu_ht_devise);
1595 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
1600 if ($price_base_type ==
'HT') {
1605 $label = trim($label);
1606 $desc = trim($desc);
1613 if ($date_start && $date_end && $date_start > $date_end) {
1614 $langs->load(
"errors");
1615 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
1621 $product_type = $type;
1622 if (!empty($fk_product) && $fk_product > 0) {
1623 $product =
new Product($this->db);
1624 $result = $product->fetch($fk_product);
1625 $product_type = $product->type;
1627 if (
getDolGlobalString(
'STOCK_MUST_BE_ENOUGH_FOR_ORDER') && $product_type == 0 && $product->stock_reel < $qty) {
1628 $langs->load(
"errors");
1629 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnOrder', $product->ref);
1630 $this->errors[] = $this->error;
1631 dol_syslog(get_class($this).
"::addline error=Product ".$product->ref.
": ".$this->error, LOG_ERR);
1632 $this->db->rollback();
1646 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
1647 $vat_src_code = $reg[1];
1648 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
1651 $tabprice =
calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
1661 $total_ht = $tabprice[0];
1662 $total_tva = $tabprice[1];
1663 $total_ttc = $tabprice[2];
1664 $total_localtax1 = $tabprice[9];
1665 $total_localtax2 = $tabprice[10];
1666 $pu_ht = $tabprice[3];
1669 $multicurrency_total_ht = $tabprice[16];
1670 $multicurrency_total_tva = $tabprice[17];
1671 $multicurrency_total_ttc = $tabprice[18];
1672 $pu_ht_devise = $tabprice[19];
1677 if ($ranktouse == -1) {
1678 $rangmax = $this->
line_max($fk_parent_line);
1679 $ranktouse = $rangmax + 1;
1686 if ($remise_percent > 0) {
1687 $remise = round(((
float) $pu * $remise_percent / 100), 2);
1688 $price = (float) $pu - $remise;
1694 $this->line->context = $this->context;
1696 $this->line->fk_commande = $this->id;
1697 $this->line->label = $label;
1698 $this->line->desc = $desc;
1699 $this->line->qty = $qty;
1700 $this->line->ref_ext = $ref_ext;
1702 $this->line->vat_src_code = $vat_src_code;
1703 $this->line->tva_tx = $txtva;
1704 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
1705 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
1706 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
1707 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
1708 $this->line->fk_product = $fk_product;
1709 $this->line->product_type = $product_type;
1710 $this->line->fk_remise_except = $fk_remise_except;
1711 $this->line->remise_percent = $remise_percent;
1712 $this->line->subprice = (float) $pu_ht;
1713 $this->line->rang = $ranktouse;
1714 $this->line->info_bits = $info_bits;
1715 $this->line->total_ht = (float) $total_ht;
1716 $this->line->total_tva = (float) $total_tva;
1717 $this->line->total_localtax1 = (float) $total_localtax1;
1718 $this->line->total_localtax2 = (float) $total_localtax2;
1719 $this->line->total_ttc = (float) $total_ttc;
1720 $this->line->special_code = $special_code;
1721 $this->line->origin = $origin;
1722 $this->line->origin_id = $origin_id;
1723 $this->line->fk_parent_line = $fk_parent_line;
1724 $this->line->fk_unit = $fk_unit;
1726 $this->line->date_start = $date_start;
1727 $this->line->date_end = $date_end;
1729 $this->line->fk_fournprice = $fk_fournprice;
1730 $this->line->pa_ht = $pa_ht;
1733 $this->line->fk_multicurrency = $this->fk_multicurrency;
1734 $this->line->multicurrency_code = $this->multicurrency_code;
1735 $this->line->multicurrency_subprice = (float) $pu_ht_devise;
1736 $this->line->multicurrency_total_ht = (float) $multicurrency_total_ht;
1737 $this->line->multicurrency_total_tva = (float) $multicurrency_total_tva;
1738 $this->line->multicurrency_total_ttc = (float) $multicurrency_total_ttc;
1741 $this->line->price = $price;
1743 if (is_array($array_options) && count($array_options) > 0) {
1744 $this->line->array_options = $array_options;
1747 $result = $this->line->insert($user);
1750 if (empty($noupdateafterinsertline)) {
1755 if (!isset($this->context[
'createfromclone'])) {
1756 if (!empty($fk_parent_line)) {
1759 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
1761 foreach ($this->lines as $tmpline) {
1762 if ($tmpline->rang >= $ranktouse) {
1763 if (!empty($tmpline->id)) {
1770 $this->lines[] = $this->line;
1773 $this->db->commit();
1774 return $this->line->id;
1776 $this->db->rollback();
1780 $this->error = $this->line->error;
1781 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
1782 $this->db->rollback();
1786 dol_syslog(get_class($this).
"::addline status of order must be Draft to allow use of ->addline()", LOG_ERR);
1806 public function add_product($idproduct, $qty, $remise_percent = 0.0, $date_start =
'', $date_end =
'')
1809 global
$conf, $mysoc;
1815 if ($idproduct > 0) {
1816 $prod =
new Product($this->db);
1817 $prod->fetch($idproduct);
1821 if (empty($tva_tx)) {
1826 $localtax1_tx =
get_localtax($tva_tx, 1, $this->thirdparty, $mysoc, $tva_npr);
1827 $localtax2_tx =
get_localtax($tva_tx, 2, $this->thirdparty, $mysoc, $tva_npr);
1831 $price = $prod->multiprices[$this->thirdparty->price_level];
1833 $price = $prod->price;
1838 $line->context = $this->context;
1840 $line->fk_product = $idproduct;
1841 $line->desc = $prod->description;
1843 $line->subprice = $price;
1844 $line->remise_percent = $remise_percent;
1845 $line->vat_src_code = $vat_src_code;
1846 $line->tva_tx = $tva_tx;
1847 $line->localtax1_tx = $localtax1_tx;
1848 $line->localtax2_tx = $localtax2_tx;
1850 $line->product_ref = $prod->ref;
1851 $line->product_label = $prod->label;
1852 $line->product_desc = $prod->description;
1853 $line->fk_unit = $prod->fk_unit;
1857 $line->date_start = $date_start;
1860 $line->date_end = $date_end;
1863 $this->lines[] = $line;
1895 public function fetch($id, $ref =
'', $ref_ext =
'', $notused =
'')
1898 if (empty($id) && empty($ref) && empty($ref_ext)) {
1902 $sql =
'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_user_modif, c.fk_statut as status';
1903 $sql .=
', c.amount_ht, c.total_ht, c.total_ttc, c.total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.deposit_percent, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason';
1904 $sql .=
', c.fk_account';
1905 $sql .=
', c.date_commande, c.date_valid, c.tms';
1906 $sql .=
', c.date_livraison as delivery_date';
1907 $sql .=
', c.fk_shipping_method';
1908 $sql .=
', c.fk_warehouse';
1909 $sql .=
', c.fk_projet as fk_project, c.source, c.facture as billed';
1910 $sql .=
', c.note_private, c.note_public, c.ref_client, c.ref_ext, c.model_pdf, c.last_main_doc, c.fk_delivery_address, c.extraparams';
1911 $sql .=
', c.fk_incoterms, c.location_incoterms';
1912 $sql .=
", c.fk_multicurrency, c.multicurrency_code, c.multicurrency_tx, c.multicurrency_total_ht, c.multicurrency_total_tva, c.multicurrency_total_ttc";
1913 $sql .=
", c.module_source, c.pos_source";
1914 $sql .=
", i.libelle as label_incoterms";
1915 $sql .=
', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
1916 $sql .=
', cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle, cr.libelle_facture as cond_reglement_libelle_doc';
1917 $sql .=
', ca.code as availability_code, ca.label as availability_label';
1918 $sql .=
', dr.code as demand_reason_code';
1919 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as c';
1920 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_payment_term as cr ON c.fk_cond_reglement = cr.rowid';
1921 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as p ON c.fk_mode_reglement = p.id';
1922 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON c.fk_availability = ca.rowid';
1923 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON c.fk_input_reason = dr.rowid';
1924 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON c.fk_incoterms = i.rowid';
1927 $sql .=
" WHERE c.rowid=".((int) $id);
1929 $sql .=
" WHERE c.entity IN (".getEntity(
'commande').
")";
1933 $sql .=
" AND c.ref='".$this->db->escape($ref).
"'";
1936 $sql .=
" AND c.ref_ext='".$this->db->escape($ref_ext).
"'";
1939 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1940 $result = $this->db->query($sql);
1942 $obj = $this->db->fetch_object($result);
1944 $this->
id = $obj->rowid;
1945 $this->entity = $obj->entity;
1947 $this->
ref = $obj->ref;
1948 $this->ref_client = $obj->ref_client;
1949 $this->ref_customer = $obj->ref_client;
1950 $this->ref_ext = $obj->ref_ext;
1952 $this->socid = $obj->fk_soc;
1953 $this->thirdparty =
null;
1955 $this->fk_project = $obj->fk_project;
1956 $this->project =
null;
1958 $this->statut = $obj->status;
1959 $this->
status = $obj->status;
1961 $this->user_author_id = $obj->fk_user_author;
1962 $this->user_creation_id = $obj->fk_user_author;
1963 $this->user_validation_id = $obj->fk_user_valid;
1964 $this->user_modification_id = $obj->fk_user_modif;
1965 $this->total_ht = $obj->total_ht;
1966 $this->total_tva = $obj->total_tva;
1967 $this->total_localtax1 = $obj->total_localtax1;
1968 $this->total_localtax2 = $obj->total_localtax2;
1969 $this->total_ttc = $obj->total_ttc;
1970 $this->date = $this->db->jdate($obj->date_commande);
1971 $this->date_commande = $this->db->jdate($obj->date_commande);
1972 $this->date_creation = $this->db->jdate($obj->date_creation);
1973 $this->date_validation = $this->db->jdate($obj->date_valid);
1974 $this->date_modification = $this->db->jdate($obj->tms);
1975 $this->source = $obj->source;
1976 $this->billed = $obj->billed;
1977 $this->note = $obj->note_private;
1978 $this->note_private = $obj->note_private;
1979 $this->note_public = $obj->note_public;
1980 $this->model_pdf = $obj->model_pdf;
1981 $this->last_main_doc = $obj->last_main_doc;
1982 $this->mode_reglement_id = $obj->fk_mode_reglement;
1983 $this->mode_reglement_code = $obj->mode_reglement_code;
1984 $this->mode_reglement = $obj->mode_reglement_libelle;
1985 $this->cond_reglement_id = $obj->fk_cond_reglement;
1986 $this->cond_reglement_code = $obj->cond_reglement_code;
1987 $this->cond_reglement = $obj->cond_reglement_libelle;
1988 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1989 $this->deposit_percent = $obj->deposit_percent;
1990 $this->fk_account = $obj->fk_account;
1991 $this->availability_id = $obj->fk_availability;
1992 $this->availability_code = $obj->availability_code;
1994 $this->demand_reason_id = $obj->fk_input_reason;
1995 $this->demand_reason_code = $obj->demand_reason_code;
1996 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1997 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1998 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1999 $this->fk_delivery_address = $obj->fk_delivery_address;
2000 $this->module_source = $obj->module_source;
2001 $this->pos_source = $obj->pos_source;
2004 $this->fk_incoterms = $obj->fk_incoterms;
2005 $this->location_incoterms = $obj->location_incoterms;
2006 $this->label_incoterms = $obj->label_incoterms;
2009 $this->fk_multicurrency = $obj->fk_multicurrency;
2010 $this->multicurrency_code = $obj->multicurrency_code;
2011 $this->multicurrency_tx = $obj->multicurrency_tx;
2012 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
2013 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
2014 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
2016 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
2018 $this->lines = array();
2024 $this->db->free($result);
2033 $this->error =
'Order with id '.$id.
' not found sql='.$sql;
2037 $this->error = $this->db->error();
2055 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
2056 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
2061 $result = $remise->fetch($idremise);
2064 if ($remise->fk_facture) {
2065 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
2066 $this->db->rollback();
2072 $line->fk_commande = $this->id;
2073 $line->fk_remise_except = $remise->id;
2074 $line->desc = $remise->description;
2075 $line->vat_src_code = $remise->vat_src_code;
2076 $line->tva_tx = $remise->tva_tx;
2077 $line->subprice = -(float) $remise->amount_ht;
2078 $line->price = -(float) $remise->amount_ht;
2079 $line->fk_product = 0;
2081 $line->remise_percent = 0;
2083 $line->info_bits = 2;
2085 $line->total_ht = -(float) $remise->amount_ht;
2086 $line->total_tva = -(float) $remise->amount_tva;
2087 $line->total_ttc = -(float) $remise->amount_ttc;
2089 $result = $line->insert();
2093 $this->db->commit();
2096 $this->db->rollback();
2100 $this->error = $line->error;
2101 $this->errors = $line->errors;
2102 $this->db->rollback();
2106 $this->db->rollback();
2120 public function fetch_lines($only_product = 0, $loadalsotranslation = 0)
2123 global $langs,
$conf;
2125 $this->lines = array();
2127 $sql =
'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.product_type, l.fk_commande, l.label as custom_label, l.description, l.price, l.qty, l.vat_src_code, l.tva_tx, l.ref_ext,';
2128 $sql .=
' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.fk_remise_except, l.remise_percent, l.subprice, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht, l.rang, l.info_bits, l.special_code,';
2129 $sql .=
' l.total_ht, l.total_ttc, l.total_tva, l.total_localtax1, l.total_localtax2, l.date_start, l.date_end,';
2130 $sql .=
' l.fk_unit,';
2131 $sql .=
' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2132 $sql .=
' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tosell as product_tosell, p.tobuy as product_tobuy, p.tobatch as product_tobatch, p.barcode as product_barcode,';
2133 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units';
2134 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element_line.
' as l';
2135 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (p.rowid = l.fk_product)';
2136 $sql .=
' WHERE l.fk_commande = '.((int) $this->
id);
2137 if ($only_product) {
2138 $sql .=
' AND p.fk_product_type = 0';
2140 $sql .=
' ORDER BY l.rang, l.rowid';
2142 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
2143 $result = $this->db->query($sql);
2145 $num = $this->db->num_rows($result);
2149 $objp = $this->db->fetch_object($result);
2153 $line->rowid = $objp->rowid;
2154 $line->id = $objp->rowid;
2155 $line->fk_commande = $objp->fk_commande;
2156 $line->commande_id = $objp->fk_commande;
2157 $line->label = $objp->custom_label;
2158 $line->desc = $objp->description;
2159 $line->description = $objp->description;
2160 $line->product_type = $objp->product_type;
2161 $line->qty = $objp->qty;
2162 $line->ref_ext = $objp->ref_ext;
2164 $line->vat_src_code = $objp->vat_src_code;
2165 $line->tva_tx = $objp->tva_tx;
2166 $line->localtax1_tx = $objp->localtax1_tx;
2167 $line->localtax2_tx = $objp->localtax2_tx;
2168 $line->localtax1_type = $objp->localtax1_type;
2169 $line->localtax2_type = $objp->localtax2_type;
2170 $line->total_ht = $objp->total_ht;
2171 $line->total_ttc = $objp->total_ttc;
2172 $line->total_tva = $objp->total_tva;
2173 $line->total_localtax1 = $objp->total_localtax1;
2174 $line->total_localtax2 = $objp->total_localtax2;
2175 $line->subprice = $objp->subprice;
2176 $line->fk_remise_except = $objp->fk_remise_except;
2177 $line->remise_percent = $objp->remise_percent;
2178 $line->price = $objp->price;
2179 $line->fk_product = $objp->fk_product;
2180 $line->fk_fournprice = $objp->fk_fournprice;
2181 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
2182 $line->pa_ht = $marginInfos[0];
2183 $line->marge_tx = $marginInfos[1];
2184 $line->marque_tx = $marginInfos[2];
2185 $line->rang = $objp->rang;
2186 $line->info_bits = $objp->info_bits;
2187 $line->special_code = $objp->special_code;
2188 $line->fk_parent_line = $objp->fk_parent_line;
2190 $line->ref = $objp->product_ref;
2191 $line->libelle = $objp->product_label;
2193 $line->product_ref = $objp->product_ref;
2194 $line->product_label = $objp->product_label;
2195 $line->product_tosell = $objp->product_tosell;
2196 $line->product_tobuy = $objp->product_tobuy;
2197 $line->product_desc = $objp->product_desc;
2198 $line->product_tobatch = $objp->product_tobatch;
2199 $line->product_barcode = $objp->product_barcode;
2201 $line->fk_product_type = $objp->fk_product_type;
2202 $line->fk_unit = $objp->fk_unit;
2204 $line->weight = $objp->weight;
2205 $line->weight_units = $objp->weight_units;
2206 $line->volume = $objp->volume;
2207 $line->volume_units = $objp->volume_units;
2209 $line->date_start = $this->db->jdate($objp->date_start);
2210 $line->date_end = $this->db->jdate($objp->date_end);
2213 $line->fk_multicurrency = $objp->fk_multicurrency;
2214 $line->multicurrency_code = $objp->multicurrency_code;
2215 $line->multicurrency_subprice = $objp->multicurrency_subprice;
2216 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
2217 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
2218 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2220 $line->fetch_optionals();
2223 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
2224 $tmpproduct =
new Product($this->db);
2225 $tmpproduct->fetch($objp->fk_product);
2226 $tmpproduct->getMultiLangs();
2228 $line->multilangs = $tmpproduct->multilangs;
2231 $this->lines[$i] = $line;
2236 $this->db->free($result);
2240 $this->error = $this->db->error();
2254 foreach ($this->lines as $line) {
2255 if ($line->product_type == 0) {
2270 foreach ($this->lines as $line) {
2271 if ($line->product_type == 1) {
2287 $sql =
'SELECT COUNT(DISTINCT ed.fk_expedition) as nb';
2288 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expeditiondet as ed,';
2289 $sql .=
' '.MAIN_DB_PREFIX.$this->table_element_line.
' as cd';
2291 $sql .=
' ed.fk_elementdet = cd.rowid';
2292 $sql .=
' AND cd.fk_commande = '.((int) $this->
id);
2295 dol_syslog(get_class($this).
"::getNbOfShipments", LOG_DEBUG);
2296 $resql = $this->db->query($sql);
2298 $obj = $this->db->fetch_object($resql);
2303 $this->db->free($resql);
2306 $this->error = $this->db->lasterror();
2321 $this->expeditions = array();
2323 $sql =
'SELECT cd.rowid, cd.fk_product,';
2324 $sql .=
' sum(ed.qty) as qty';
2325 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expeditiondet as ed,';
2326 if ($filtre_statut >= 0) {
2327 $sql .=
' '.MAIN_DB_PREFIX.
'expedition as e,';
2329 $sql .=
' '.MAIN_DB_PREFIX.$this->table_element_line.
' as cd';
2331 if ($filtre_statut >= 0) {
2332 $sql .=
' ed.fk_expedition = e.rowid AND';
2334 $sql .=
' ed.fk_elementdet = cd.rowid';
2335 $sql .=
' AND cd.fk_commande = '.((int) $this->
id);
2336 if ($fk_product > 0) {
2337 $sql .=
' AND cd.fk_product = '.((int) $fk_product);
2339 if ($filtre_statut >= 0) {
2340 $sql .=
' AND e.fk_statut >= '.((int) $filtre_statut);
2342 $sql .=
' GROUP BY cd.rowid, cd.fk_product';
2345 dol_syslog(get_class($this).
"::loadExpeditions", LOG_DEBUG);
2346 $resql = $this->db->query($sql);
2348 $num = $this->db->num_rows($resql);
2351 $obj = $this->db->fetch_object($resql);
2352 $this->expeditions[$obj->rowid] = $obj->qty;
2355 $this->db->free($resql);
2358 $this->error = $this->db->lasterror();
2370 $sql =
'SELECT count(*)';
2371 $sql .=
' FROM '.MAIN_DB_PREFIX.
'expedition as e';
2372 $sql .=
', '.MAIN_DB_PREFIX.
'element_element as el';
2373 $sql .=
' WHERE el.fk_source = '.((int) $this->
id);
2374 $sql .=
" AND el.sourcetype = 'commande'";
2375 $sql .=
" AND el.fk_target = e.rowid";
2376 $sql .=
" AND el.targettype = 'shipping'";
2378 $resql = $this->db->query($sql);
2380 $row = $this->db->fetch_row($resql);
2438 if ($this->statut == self::STATUS_DRAFT) {
2444 $line->context = $this->context;
2447 $line->fetch($lineid);
2449 if ($id > 0 && $line->fk_commande != $id) {
2450 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
2455 $staticline = clone $line;
2456 $line->oldline = $staticline;
2458 if ($line->delete($user) > 0) {
2462 $this->db->commit();
2465 $this->db->rollback();
2466 $this->error = $this->db->lasterror();
2470 $this->db->rollback();
2471 $this->error = $line->error;
2475 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
2494 dol_syslog(get_class($this).
"::set_remise is deprecated, use setDiscount instead", LOG_NOTICE);
2496 return $this->
setDiscount($user, $remise, $notrigger);
2509 $remise = trim((
string) $remise) ? trim((
string) $remise) : 0;
2511 if ($user->hasRight(
'commande',
'creer')) {
2518 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2519 $sql .=
' SET remise_percent = '.((float) $remise);
2520 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_DRAFT);
2523 $resql = $this->db->query($sql);
2525 $this->errors[] = $this->db->error();
2530 $this->oldcopy = clone $this;
2531 $this->remise_percent = $remise;
2535 if (!$notrigger && empty($error)) {
2545 $this->db->commit();
2548 foreach ($this->errors as $errmsg) {
2549 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2550 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2552 $this->db->rollback();
2640 if ($user->hasRight(
'commande',
'creer')) {
2645 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
2646 $sql .=
" SET date_commande = ".($date ?
"'".$this->db->idate($date).
"'" :
'null');
2647 $sql .=
" WHERE rowid = ".((int) $this->
id).
" AND fk_statut = ".((int) self::STATUS_DRAFT);
2650 $resql = $this->db->query($sql);
2652 $this->errors[] = $this->db->error();
2657 $this->oldcopy = clone $this;
2658 $this->date = $date;
2661 if (!$notrigger && empty($error)) {
2671 $this->db->commit();
2674 foreach ($this->errors as $errmsg) {
2675 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2676 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2678 $this->db->rollback();
2712 if ($user->hasRight(
'commande',
'creer')) {
2717 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
2718 $sql .=
" SET date_livraison = ".($delivery_date ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2719 $sql .=
" WHERE rowid = ".((int) $this->
id);
2722 $resql = $this->db->query($sql);
2724 $this->errors[] = $this->db->error();
2729 $this->oldcopy = clone $this;
2730 $this->delivery_date = $delivery_date;
2733 if (!$notrigger && empty($error)) {
2743 $this->db->commit();
2746 foreach ($this->errors as $errmsg) {
2747 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2748 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2750 $this->db->rollback();
2772 public function liste_array($shortlist = 0, $draft = 0, $excluser =
null, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'c.date_commande', $sortorder =
'DESC')
2779 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2780 $sql .=
" c.rowid as cid, c.ref";
2781 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
2782 $sql .=
", sc.fk_soc, sc.fk_user";
2784 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.$this->table_element.
" as c";
2785 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
2786 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
2788 $sql .=
" WHERE c.entity IN (".getEntity(
'commande').
")";
2789 $sql .=
" AND c.fk_soc = s.rowid";
2790 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
2791 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
2794 $sql .=
" AND s.rowid = ".((int) $socid);
2797 $sql .=
" AND c.fk_statut = ".self::STATUS_DRAFT;
2799 if (is_object($excluser)) {
2800 $sql .=
" AND c.fk_user_author <> ".((int) $excluser->id);
2802 $sql .= $this->db->order($sortfield, $sortorder);
2803 $sql .= $this->db->plimit($limit, $offset);
2805 $result = $this->db->query($sql);
2807 $numc = $this->db->num_rows($result);
2810 while ($i < $numc) {
2811 $obj = $this->db->fetch_object($result);
2813 if ($shortlist == 1) {
2814 $ga[$obj->cid] = $obj->ref;
2815 } elseif ($shortlist == 2) {
2816 $ga[$obj->cid] = $obj->ref.
' ('.$obj->name.
')';
2818 $ga[$i][
'id'] = $obj->cid;
2819 $ga[$i][
'ref'] = $obj->ref;
2820 $ga[$i][
'name'] = $obj->name;
2843 dol_syslog(
'Commande::availability('.$availability_id.
')');
2844 if ($this->statut >= self::STATUS_DRAFT) {
2849 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2850 $sql .=
' SET fk_availability = '.((int) $availability_id);
2851 $sql .=
' WHERE rowid='.((int) $this->
id);
2854 $resql = $this->db->query($sql);
2856 $this->errors[] = $this->db->error();
2861 $this->oldcopy = clone $this;
2862 $this->availability_id = $availability_id;
2865 if (!$notrigger && empty($error)) {
2875 $this->db->commit();
2878 foreach ($this->errors as $errmsg) {
2879 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2880 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2882 $this->db->rollback();
2886 $error_str =
'Command status do not meet requirement '.$this->statut;
2888 $this->error = $error_str;
2889 $this->errors[] = $this->error;
2907 dol_syslog(
'Commande::demand_reason('.$demand_reason_id.
')');
2908 if ($this->statut >= self::STATUS_DRAFT) {
2913 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
2914 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
2915 $sql .=
' WHERE rowid='.((int) $this->
id);
2918 $resql = $this->db->query($sql);
2920 $this->errors[] = $this->db->error();
2925 $this->oldcopy = clone $this;
2926 $this->demand_reason_id = $demand_reason_id;
2929 if (!$notrigger && empty($error)) {
2939 $this->db->commit();
2942 foreach ($this->errors as $errmsg) {
2943 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2944 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2946 $this->db->rollback();
2950 $error_str =
'order status do not meet requirement '.$this->statut;
2952 $this->error = $error_str;
2953 $this->errors[] = $this->error;
2970 if ($user->hasRight(
'commande',
'creer')) {
2975 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
' SET';
2976 $sql .=
' ref_client = '.(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2977 $sql .=
' WHERE rowid = '.((int) $this->
id);
2979 dol_syslog(__METHOD__.
' this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2980 $resql = $this->db->query($sql);
2982 $this->errors[] = $this->db->error();
2987 $this->oldcopy = clone $this;
2988 $this->ref_client = $ref_client;
2989 $this->ref_customer = $ref_client;
2992 if (!$notrigger && empty($error)) {
3001 $this->db->commit();
3004 foreach ($this->errors as $errmsg) {
3005 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3006 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3008 $this->db->rollback();
3027 if ($this->billed) {
3033 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
' SET facture = 1';
3036 dol_syslog(get_class($this).
"::classifyBilled", LOG_DEBUG);
3037 if ($this->db->query($sql)) {
3039 $this->oldcopy = clone $this;
3043 if (!$notrigger && empty($error)) {
3045 $result = $this->
call_trigger(
'ORDER_CLASSIFY_BILLED', $user);
3053 $this->db->commit();
3056 foreach ($this->errors as $errmsg) {
3057 dol_syslog(get_class($this).
"::classifyBilled ".$errmsg, LOG_ERR);
3058 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3060 $this->db->rollback();
3064 $this->error = $this->db->error();
3065 $this->db->rollback();
3083 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element.
' SET facture = 0';
3086 dol_syslog(get_class($this).
"::classifyUnBilled", LOG_DEBUG);
3087 if ($this->db->query($sql)) {
3089 $this->oldcopy = clone $this;
3093 if (!$notrigger && empty($error)) {
3095 $result = $this->
call_trigger(
'ORDER_CLASSIFY_UNBILLED', $user);
3105 $this->db->commit();
3108 foreach ($this->errors as $errmsg) {
3109 dol_syslog(get_class($this).
"::classifyUnBilled ".$errmsg, LOG_ERR);
3110 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3112 $this->db->rollback();
3116 $this->error = $this->db->error();
3117 $this->db->rollback();
3153 public function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $price_base_type =
'HT', $info_bits = 0, $date_start =
'', $date_end =
'', $type = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice =
null, $pa_ht = 0, $label =
'', $special_code = 0, $array_options = array(), $fk_unit =
null, $pu_ht_devise = 0, $notrigger = 0, $ref_ext =
'', $rang = 0)
3155 global
$conf, $mysoc, $langs, $user;
3157 dol_syslog(get_class($this).
"::updateline id=$rowid, desc=$desc, pu=$pu, qty=$qty, remise_percent=$remise_percent, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, price_base_type=$price_base_type, info_bits=$info_bits, date_start=$date_start, date_end=$date_end, type=$type, fk_parent_line=$fk_parent_line, pa_ht=$pa_ht, special_code=$special_code, ref_ext=$ref_ext");
3158 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
3165 if (empty($info_bits)) {
3168 if (empty($txtva)) {
3171 if (empty($txlocaltax1)) {
3174 if (empty($txlocaltax2)) {
3177 if (empty($remise_percent)) {
3178 $remise_percent = 0;
3180 if (empty($special_code) || $special_code == 3) {
3183 if (empty($ref_ext)) {
3187 if ($date_start && $date_end && $date_start > $date_end) {
3188 $langs->load(
"errors");
3189 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
3193 $remise_percent = (float)
price2num($remise_percent);
3197 $pu_ht_devise =
price2num($pu_ht_devise);
3198 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
3201 $txlocaltax1 = (float)
price2num($txlocaltax1);
3202 $txlocaltax2 = (float)
price2num($txlocaltax2);
3216 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
3217 $vat_src_code = $reg[1];
3218 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
3221 $tabprice =
calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
3223 $total_ht = $tabprice[0];
3224 $total_tva = $tabprice[1];
3225 $total_ttc = $tabprice[2];
3226 $total_localtax1 = $tabprice[9];
3227 $total_localtax2 = $tabprice[10];
3228 $pu_ht = $tabprice[3];
3229 $pu_tva = $tabprice[4];
3230 $pu_ttc = $tabprice[5];
3233 $multicurrency_total_ht = $tabprice[16];
3234 $multicurrency_total_tva = $tabprice[17];
3235 $multicurrency_total_ttc = $tabprice[18];
3236 $pu_ht_devise = $tabprice[19];
3240 if ($price_base_type ==
'TTC') {
3241 $subprice = $pu_ttc;
3246 if ($remise_percent > 0) {
3247 $remise = round(((
float) $pu * $remise_percent / 100), 2);
3248 $price = ((float) $pu - $remise);
3253 $line->fetch($rowid);
3254 $line->fetch_optionals();
3256 if (!empty($line->fk_product)) {
3257 $product =
new Product($this->db);
3258 $result = $product->fetch($line->fk_product);
3259 $product_type = $product->type;
3261 if (
getDolGlobalString(
'STOCK_MUST_BE_ENOUGH_FOR_ORDER') && $product_type == 0 && $product->stock_reel < $qty) {
3262 $langs->load(
"errors");
3263 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnOrder', $product->ref);
3264 $this->errors[] = $this->error;
3266 dol_syslog(get_class($this).
"::addline error=Product ".$product->ref.
": ".$this->error, LOG_ERR);
3268 $this->db->rollback();
3273 $staticline = clone $line;
3275 $line->oldline = $staticline;
3276 $this->line = $line;
3277 $this->line->context = $this->context;
3278 $this->line->rang = $rang;
3281 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
3282 $rangmax = $this->
line_max($fk_parent_line);
3283 $this->line->rang = $rangmax + 1;
3286 $this->line->id = $rowid;
3287 $this->line->label = $label;
3288 $this->line->desc = $desc;
3289 $this->line->qty = $qty;
3290 $this->line->ref_ext = $ref_ext;
3292 $this->line->vat_src_code = $vat_src_code;
3293 $this->line->tva_tx = $txtva;
3294 $this->line->localtax1_tx = $txlocaltax1;
3295 $this->line->localtax2_tx = $txlocaltax2;
3296 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
3297 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
3298 $this->line->remise_percent = $remise_percent;
3299 $this->line->subprice = (float) $pu_ht;
3300 $this->line->info_bits = $info_bits;
3301 $this->line->special_code = $special_code;
3302 $this->line->total_ht = (float) $total_ht;
3303 $this->line->total_tva = (float) $total_tva;
3304 $this->line->total_localtax1 = (float) $total_localtax1;
3305 $this->line->total_localtax2 = (float) $total_localtax2;
3306 $this->line->total_ttc = (float) $total_ttc;
3307 $this->line->date_start = $date_start;
3308 $this->line->date_end = $date_end;
3309 $this->line->product_type = $type;
3310 $this->line->fk_parent_line = $fk_parent_line;
3311 $this->line->skip_update_total = $skip_update_total;
3312 $this->line->fk_unit = $fk_unit;
3314 $this->line->fk_fournprice = $fk_fournprice;
3315 $this->line->pa_ht = $pa_ht;
3318 $this->line->multicurrency_subprice = (float) $pu_ht_devise;
3319 $this->line->multicurrency_total_ht = (float) $multicurrency_total_ht;
3320 $this->line->multicurrency_total_tva = (float) $multicurrency_total_tva;
3321 $this->line->multicurrency_total_ttc = (float) $multicurrency_total_ttc;
3324 $this->line->price = $price;
3326 if (is_array($array_options) && count($array_options) > 0) {
3328 foreach ($array_options as $key => $value) {
3329 $this->line->array_options[$key] = $array_options[$key];
3333 $result = $this->line->update($user, $notrigger);
3336 if (!empty($fk_parent_line)) {
3343 $this->db->commit();
3346 $this->error = $this->line->error;
3348 $this->db->rollback();
3352 $this->error = get_class($this).
"::updateline Order status makes operation forbidden";
3353 $this->errors = array(
'OrderStatusMakeOperationForbidden');
3372 if (isset($this->
ref)) {
3373 $this->
ref = trim($this->
ref);
3375 if (isset($this->ref_client)) {
3376 $this->ref_client = trim($this->ref_client);
3378 if (isset($this->ref_customer)) {
3379 $this->ref_customer = trim($this->ref_customer);
3381 if (isset($this->note) || isset($this->note_private)) {
3382 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
3384 if (isset($this->note_public)) {
3385 $this->note_public = trim($this->note_public);
3387 if (isset($this->model_pdf)) {
3388 $this->model_pdf = trim($this->model_pdf);
3390 if (isset($this->import_key)) {
3391 $this->import_key = trim($this->import_key);
3393 $delivery_date = $this->delivery_date;
3399 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
3401 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
3402 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
3403 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
3404 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
3405 $sql .=
" date_commande=".(strval($this->date_commande) !=
'' ?
"'".$this->db->idate($this->date_commande).
"'" :
'null').
",";
3406 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
3407 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
3408 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
3409 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
3410 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
3411 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
3412 $sql .=
" fk_statut=".(isset($this->statut) ? $this->statut :
"null").
",";
3413 $sql .=
" fk_user_modif=".(isset($user->id) ? $user->id :
"null").
",";
3414 $sql .=
" fk_user_valid=".((isset($this->user_validation_id) && $this->user_validation_id > 0) ? $this->user_validation_id :
"null").
",";
3415 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
3416 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
3417 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ? strval($this->deposit_percent) :
"null").
",";
3418 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
3419 $sql .=
" date_livraison=".(strval($this->delivery_date) !=
'' ?
"'".$this->db->idate($this->delivery_date).
"'" :
'null').
",";
3420 $sql .=
" fk_shipping_method=".(isset($this->shipping_method_id) ? $this->shipping_method_id :
"null").
",";
3421 $sql .=
" fk_account=".($this->fk_account > 0 ? $this->fk_account :
"null").
",";
3422 $sql .=
" fk_input_reason=".($this->demand_reason_id > 0 ? $this->demand_reason_id :
"null").
",";
3423 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
3424 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
3425 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
3426 $sql .=
" fk_warehouse=".($this->warehouse_id > 0 ? $this->warehouse_id :
"null").
",";
3427 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
3429 $sql .=
" WHERE rowid=".((int) $this->
id);
3433 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
3434 $resql = $this->db->query($sql);
3437 $this->errors[] =
"Error ".$this->db->lasterror();
3447 if (!$error && !$notrigger) {
3458 foreach ($this->errors as $errmsg) {
3459 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
3460 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3462 $this->db->rollback();
3465 $this->db->commit();
3477 public function delete($user, $notrigger = 0)
3479 global
$conf, $langs;
3480 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3484 dol_syslog(get_class($this).
"::delete ".$this->
id, LOG_DEBUG);
3499 $this->errors[] = $langs->trans(
'SomeShipmentExists');
3504 if (!$error && !empty($this->table_element_line)) {
3505 $tabletodelete = $this->table_element_line;
3506 $sqlef =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
"_extrafields WHERE fk_object IN (SELECT rowid FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id).
")";
3507 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3508 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3510 $this->error = $this->db->lasterror();
3511 $this->errors[] = $this->error;
3512 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3537 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3543 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3544 $res = $this->db->query($sql);
3547 $this->error = $this->db->lasterror();
3548 $this->errors[] = $this->error;
3549 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3565 if ($conf->commande->multidir_output[$this->entity] && !empty($this->
ref)) {
3566 $dir =
$conf->commande->multidir_output[$this->entity].
"/".$ref;
3567 $file = $dir.
"/".$ref.
".pdf";
3568 if (file_exists($file)) {
3572 $this->error =
'ErrorFailToDeleteFile';
3573 $this->errors[] = $this->error;
3574 $this->db->rollback();
3578 if (file_exists($dir)) {
3581 $this->error =
'ErrorFailToDeleteDir';
3582 $this->errors[] = $this->error;
3583 $this->db->rollback();
3591 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3592 $this->db->commit();
3595 $this->db->rollback();
3612 global
$conf, $langs;
3616 $sql =
"SELECT c.rowid, c.date_creation as datec, c.date_commande, c.date_livraison as delivery_date, c.fk_statut, c.total_ht";
3617 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as c";
3618 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
3619 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON c.fk_soc = sc.fk_soc";
3620 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3623 $sql .= $clause.
" c.entity IN (".
getEntity(
'commande').
")";
3625 if ($mode ==
'toship') {
3627 $sql .=
" AND c.fk_statut IN (" . self::STATUS_VALIDATED .
"," . self::STATUS_SHIPMENTONPROCESS .
")";
3629 if ($mode ==
'tobill') {
3631 $sql .=
" AND c.fk_statut IN (" . self::STATUS_VALIDATED .
"," . self::STATUS_SHIPMENTONPROCESS .
", " . self::STATUS_CLOSED .
") AND c.facture = 0";
3633 if ($mode ==
'shippedtobill') {
3635 $sql .=
" AND c.fk_statut IN (" . self::STATUS_CLOSED .
") AND c.facture = 0";
3638 $sql .=
" AND c.fk_soc = ".((int) $user->socid);
3641 $resql = $this->db->query($sql);
3644 $label = $labelShort = $url =
'';
3645 if ($mode ==
'toship') {
3646 $delay_warning =
$conf->commande->client->warning_delay / 60 / 60 / 24;
3647 $url = DOL_URL_ROOT.
'/commande/list.php?search_status=-2&mainmenu=commercial&leftmenu=orders';
3648 $label = $langs->transnoentitiesnoconv(
"OrdersToProcess");
3649 $labelShort = $langs->transnoentitiesnoconv(
"Opened");
3651 if ($mode ==
'tobill') {
3652 $url = DOL_URL_ROOT.
'/commande/list.php?search_status=-3&search_billed=0&mainmenu=commercial&leftmenu=orders';
3653 $label = $langs->trans(
"OrdersToBill");
3654 $labelShort = $langs->trans(
"ToBill");
3656 if ($mode ==
'shippedtobill') {
3657 $url = DOL_URL_ROOT.
'/commande/list.php?search_status=3&search_billed=0&mainmenu=commercial&leftmenu=orders';
3658 $label = $langs->trans(
"OrdersToBill");
3659 $labelShort = $langs->trans(
"StatusOrderDelivered").
' '.$langs->trans(
"and").
' '.$langs->trans(
"ToBill");
3664 $response->warning_delay = $delay_warning;
3665 $response->label = $label;
3666 $response->labelShort = $labelShort;
3667 $response->url = $url;
3668 $response->url_late = DOL_URL_ROOT.
'/commande/list.php?search_option=late&mainmenu=commercial&leftmenu=orders';
3671 $generic_commande =
new Commande($this->db);
3673 while ($obj = $this->db->fetch_object($resql)) {
3674 $response->nbtodo++;
3675 $response->total += $obj->total_ht;
3677 $generic_commande->statut = $obj->fk_statut;
3678 $generic_commande->date_commande = $this->db->jdate($obj->date_commande);
3679 $generic_commande->date = $this->db->jdate($obj->date_commande);
3680 $generic_commande->delivery_date = $this->db->jdate($obj->delivery_date);
3682 if ($mode ==
'toship' && $generic_commande->hasDelay()) {
3683 $response->nbtodolate++;
3689 $this->error = $this->db->error();
3703 $label = $langs->trans(
'OrderSource'.$this->source);
3705 if ($label ==
'OrderSource') {
3719 return $this->
LibStatut($this->statut, $this->billed, $mode);
3732 public function LibStatut($status, $billed, $mode, $donotshowbilled = 0)
3735 global $langs, $hookmanager;
3738 if (empty($donotshowbilled)) {
3739 $billedtext .= ($billed ?
' - '.$langs->transnoentitiesnoconv(
"Billed") :
'');
3744 if ($status == self::STATUS_CANCELED) {
3745 $labelStatus = $langs->transnoentitiesnoconv(
'StatusOrderCanceled');
3746 $labelStatusShort = $langs->transnoentitiesnoconv(
'StatusOrderCanceledShort');
3747 $statusType =
'status9';
3748 } elseif ($status == self::STATUS_DRAFT) {
3749 $labelStatus = $langs->transnoentitiesnoconv(
'StatusOrderDraft');
3750 $labelStatusShort = $langs->transnoentitiesnoconv(
'StatusOrderDraftShort');
3751 $statusType =
'status0';
3752 } elseif ($status == self::STATUS_VALIDATED) {
3753 $labelStatus = $langs->transnoentitiesnoconv(
'StatusOrderValidated').$billedtext;
3754 $labelStatusShort = $langs->transnoentitiesnoconv(
'StatusOrderValidatedShort').$billedtext;
3755 $statusType =
'status1';
3756 } elseif ($status == self::STATUS_SHIPMENTONPROCESS) {
3757 $labelStatus = $langs->transnoentitiesnoconv(
'StatusOrderSent').$billedtext;
3758 $labelStatusShort = $langs->transnoentitiesnoconv(
'StatusOrderSentShort').$billedtext;
3759 $labelTooltip = $langs->transnoentitiesnoconv(
"StatusOrderSent");
3760 if (!empty($this->delivery_date)) {
3761 $labelTooltip .=
' - '.$langs->transnoentitiesnoconv(
"DateDeliveryPlanned").dol_print_date($this->delivery_date,
'day').$billedtext;
3763 $statusType =
'status4';
3764 } elseif ($status == self::STATUS_CLOSED) {
3765 $labelStatus = $langs->transnoentitiesnoconv(
'StatusOrderDelivered').$billedtext;
3766 $labelStatusShort = $langs->transnoentitiesnoconv(
'StatusOrderDeliveredShort').$billedtext;
3767 $statusType =
'status6';
3769 $labelStatus = $langs->transnoentitiesnoconv(
'Unknown');
3770 $labelStatusShort =
'';
3775 $parameters = array(
3776 'status' => $status,
3778 'billed' => $billed,
3779 'donotshowbilled' => $donotshowbilled
3782 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3785 return $hookmanager->resPrint;
3788 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode,
'', array(
'tooltip' => $labelTooltip));
3800 global
$conf, $langs, $user;
3802 $langs->load(
'orders');
3804 $nofetch = !empty($params[
'nofetch']);
3807 return [
'optimize' => $langs->trans(
"Order")];
3810 if ($user->hasRight(
'commande',
'lire')) {
3811 $datas[
'picto'] =
img_picto(
'', $this->picto,
'', 0, 0, 0,
'',
'paddingrightonly').
'<u>'.$langs->trans(
"Order").
'</u>';
3812 if (isset($this->statut)) {
3813 $datas[
'status'] =
' '.$this->getLibStatut(5);
3815 $datas[
'Ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3817 $langs->load(
'companies');
3818 if (empty($this->thirdparty)) {
3821 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3823 $datas[
'RefCustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.(empty($this->ref_customer) ? (empty($this->ref_client) ?
'' : $this->ref_client) : $this->ref_customer);
3825 $langs->load(
'project');
3826 if (is_null($this->project) || (is_object($this->project) && $this->project->isEmpty())) {
3828 if ($res > 0 && $this->project instanceof
Project) {
3829 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3833 if (!empty($this->total_ht)) {
3834 $datas[
'AmountHT'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1,
$conf->currency);
3836 if (!empty($this->total_tva)) {
3837 $datas[
'VAT'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1,
$conf->currency);
3839 if (!empty($this->total_ttc)) {
3840 $datas[
'AmountTTC'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1,
$conf->currency);
3842 if (!empty($this->date)) {
3843 $datas[
'Date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3845 if (!empty($this->delivery_date)) {
3846 $datas[
'DeliveryDate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3866 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target =
'')
3868 global
$conf, $langs, $user, $hookmanager;
3870 if (!empty(
$conf->dol_no_mouse_hover)) {
3876 if (isModEnabled(
"shipping") && ($option ==
'1' || $option ==
'2')) {
3877 $url = DOL_URL_ROOT.
'/expedition/shipment.php?id='.$this->id;
3879 $url = DOL_URL_ROOT.
'/commande/card.php?id='.$this->id;
3882 if (!$user->hasRight(
'commande',
'lire')) {
3886 if ($option !==
'nolink') {
3888 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3889 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3890 $add_save_lastsearch_values = 1;
3892 if ($add_save_lastsearch_values) {
3893 $url .=
'&save_lastsearch_values=1';
3902 'objecttype' => $this->element,
3903 'option' => $option,
3906 $classfortooltip =
'classfortooltip';
3909 $classfortooltip =
'classforajaxtooltip';
3910 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3917 if (empty($notooltip) && $user->hasRight(
'commande',
'lire')) {
3919 $label = $langs->trans(
"Order");
3920 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
3922 $linkclose .= ($label ?
' title="'.dolPrintHTMLForAttribute($label).
'"' :
' title="tocomplete"');
3923 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3925 $target_value = array(
'_self',
'_blank',
'_parent',
'_top');
3926 if (in_array($target, $target_value)) {
3927 $linkclose .=
' target="'.dol_escape_htmltag($target).
'"';
3931 $linkstart =
'<a href="'.$url.
'"';
3932 $linkstart .= $linkclose.
'>';
3935 if ($option ===
'nolink') {
3940 $result .= $linkstart;
3942 $result .=
img_object(($notooltip ?
'' : $label), $this->picto, (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3944 if ($withpicto != 2) {
3945 $result .= $this->ref;
3947 $result .= $linkend;
3949 if ($addlinktonotes) {
3950 $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private);
3953 $result .=
' <span class="note inline-block">';
3954 $result .=
'<a href="'.DOL_URL_ROOT.
'/commande/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($notetoshow).
'">';
3959 $result .=
'</span>';
3964 $hookmanager->initHooks(array($this->element .
'dao'));
3965 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
3966 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3968 $result = $hookmanager->resPrint;
3970 $result .= $hookmanager->resPrint;
3984 $sql =
'SELECT c.rowid, date_creation as datec, tms as datem,';
3985 $sql .=
' date_valid as datev,';
3986 $sql .=
' date_cloture as datecloture,';
3987 $sql .=
' fk_user_author, fk_user_valid, fk_user_cloture';
3988 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' as c';
3989 $sql .=
' WHERE c.rowid = '.((int) $id);
3990 $result = $this->db->query($sql);
3992 if ($this->db->num_rows($result)) {
3993 $obj = $this->db->fetch_object($result);
3994 $this->
id = $obj->rowid;
3995 if ($obj->fk_user_author) {
3996 $this->user_creation_id = $obj->fk_user_author;
3998 if ($obj->fk_user_valid) {
3999 $this->user_validation_id = $obj->fk_user_valid;
4001 if ($obj->fk_user_cloture) {
4002 $this->user_closing_id = $obj->fk_user_cloture;
4005 $this->date_creation = $this->db->jdate($obj->datec);
4006 $this->date_modification = $this->db->jdate($obj->datem);
4007 $this->date_validation = $this->db->jdate($obj->datev);
4008 $this->date_cloture = $this->db->jdate($obj->datecloture);
4011 $this->db->free($result);
4027 global
$conf, $langs;
4029 dol_syslog(get_class($this).
"::initAsSpecimen");
4034 $sql =
"SELECT rowid";
4035 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
4036 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
4037 $sql .= $this->db->plimit(100);
4039 $resql = $this->db->query($sql);
4041 $num_prods = $this->db->num_rows($resql);
4043 while ($i < $num_prods) {
4045 $row = $this->db->fetch_row($resql);
4046 $prodids[$i] = $row[0];
4052 $this->
ref =
'SPECIMEN';
4053 $this->specimen = 1;
4054 $this->entity =
$conf->entity;
4056 $this->date = time();
4057 $this->date_lim_reglement = $this->date + 3600 * 24 * 30;
4058 $this->cond_reglement_code =
'RECEP';
4059 $this->mode_reglement_code =
'CHQ';
4060 $this->availability_code =
'DSP';
4061 $this->demand_reason_code =
'SRC_00';
4063 $this->note_public =
'This is a comment (public)';
4064 $this->note_private =
'This is a comment (private)';
4066 $this->multicurrency_tx = 1;
4067 $this->multicurrency_code =
$conf->currency;
4069 $this->
status = $this::STATUS_DRAFT;
4075 while ($xnbp < $nbp) {
4078 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
4080 $line->subprice = 100;
4084 $line->total_ht = 50;
4085 $line->total_ttc = 60;
4086 $line->total_tva = 10;
4087 $line->remise_percent = 50;
4089 $line->total_ht = 100;
4090 $line->total_ttc = 120;
4091 $line->total_tva = 20;
4092 $line->remise_percent = 0;
4094 if ($num_prods > 0) {
4095 $prodid = mt_rand(1, $num_prods);
4096 $line->fk_product = $prodids[$prodid];
4097 $line->product_ref =
'SPECIMEN';
4100 $this->lines[$xnbp] = $line;
4102 $this->total_ht += $line->total_ht;
4103 $this->total_tva += $line->total_tva;
4104 $this->total_ttc += $line->total_ttc;
4122 $this->nb = array();
4125 $sql =
"SELECT count(co.rowid) as nb";
4126 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" as co";
4127 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON co.fk_soc = s.rowid";
4128 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
4129 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
4130 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
4133 $sql .=
" ".$clause.
" co.entity IN (".
getEntity(
'commande').
")";
4135 $resql = $this->db->query($sql);
4137 while ($obj = $this->db->fetch_object($resql)) {
4138 $this->nb[
"orders"] = $obj->nb;
4140 $this->db->free($resql);
4144 $this->error = $this->db->error();
4170 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
4172 global
$conf, $langs;
4174 $langs->load(
"orders");
4175 $outputlangs->load(
"products");
4178 $modele =
'einstein';
4180 if (!empty($this->model_pdf)) {
4181 $modele = $this->model_pdf;
4187 $modelpath =
"core/modules/commande/doc/";
4189 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4242 return max($this->date, $this->delivery_date) < ($now -
$conf->commande->client->warning_delay);
4252 global
$conf, $langs;
4254 if (empty($this->delivery_date)) {
4255 $text = $langs->trans(
"OrderDate").
' '.
dol_print_date($this->date,
'day');
4257 $text = $text = $langs->trans(
"DeliveryDate").
' '.
dol_print_date($this->delivery_date,
'day');
4259 $text .=
' '.($conf->commande->client->warning_delay > 0 ?
'+' :
'-').
' '.round(abs(
$conf->commande->client->warning_delay) / 3600 / 24, 1).
' '.$langs->trans(
"days").
' < '.$langs->trans(
"Today");
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Class to manage customers orders.
getNbOfServicesLines()
Return number of line with type service.
getNbOfShipments()
Count number of shipments for this order.
createFromProposal($object, User $user)
Load an object from a proposal and create a new order into database.
setDraft($user, $idwarehouse=-1)
Set draft status.
setDeliveryDate($user, $delivery_date, $notrigger=0)
Set the planned delivery date.
static replaceProduct(DoliDB $db, $origin_id, $dest_id)
Function used to replace a product id with another one.
getLinesArray()
Create an array of order lines.
showDelay()
Show the customer delayed info.
set_date($user, $date, $notrigger=0)
Set a fixed amount discount.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
loadStateBoard()
Load the indicators this->nb for the state board.
fetch_lines($only_product=0, $loadalsotranslation=0)
Load array lines.
createFromClone(User $user, $socid=0)
Load an object from its id and create a new one in database.
const STATUS_SHIPMENTONPROCESS
Shipment on process.
LibStatut($status, $billed, $mode, $donotshowbilled=0)
Return label of status.
getLibStatut($mode)
Return status label of Order.
hasDelay()
Is the sales order delayed?
const STATUS_CLOSED
Closed (Sent, billed or not)
valid($user, $idwarehouse=0, $notrigger=0)
Validate order.
getLabelSource()
Return source label of order.
set_remise($user, $remise, $notrigger=0)
Applique une remise relative.
const STATUS_CANCELED
Canceled status.
getNomUrl($withpicto=0, $option='', $max=0, $short=0, $notooltip=0, $save_lastsearch_value=-1, $addlinktonotes=0, $target='')
Return clickable link of object (with eventually picto)
loadExpeditions($filtre_statut=-1, $fk_product=0)
Load array this->expeditions of lines of shipments with nb of products sent for each order line Note:...
__construct($db)
Constructor.
availability($availability_id, $notrigger=0)
Update delivery delay.
set_reopen($user)
Tag the order as validated (opened) Function used when order is reopend after being closed.
set_ref_client($user, $ref_client, $notrigger=0)
Set customer ref.
getNextNumRef($soc)
Returns the reference to the following non used Order depending on the active numbering module define...
addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $info_bits=0, $fk_remise_except=0, $price_base_type='HT', $pu_ttc=0, $date_start='', $date_end='', $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_options=array(), $fk_unit=null, $origin='', $origin_id=0, $pu_ht_devise=0, $ref_ext='', $noupdateafterinsertline=0)
Add an order line into database (linked to product/service or not)
getTooltipContentArray($params)
getTooltipContentArray
create($user, $notrigger=0)
Create order Note that this->ref can be set or empty.
demand_reason($demand_reason_id, $notrigger=0)
Update order demand_reason.
const STATUS_DRAFT
Draft status.
const STOCK_NOT_ENOUGH_FOR_ORDER
ERR Not enough stock.
initAsSpecimen()
Initialise an instance with random values.
insert_discount($idremise)
Add a discount line into a sale order (as a sale order line) using an existing absolute discount (Con...
getNbOfProductsLines()
Return number of line with type product.
update(User $user, $notrigger=0)
Update database.
classifyUnBilled(User $user, $notrigger=0)
Classify the order as not invoiced.
setDiscount($user, $remise, $notrigger=0)
Set a percentage discount.
cloture($user, $notrigger=0)
Close order.
cancel($idwarehouse=-1)
Cancel an order If stock is decremented on order validation, we must reincrement it.
const STATUS_ACCEPTED
For backward compatibility.
updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_options=array(), $fk_unit=null, $pu_ht_devise=0, $notrigger=0, $ref_ext='', $rang=0)
Update a line in database.
classifyBilled(User $user, $notrigger=0)
Classify the order as invoiced.
info($id)
Charge les information d'ordre info dans l'objet commande.
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
const STATUS_VALIDATED
Validated status.
deleteLine($user=null, $lineid=0, $id=0)
Return a array with the pending stock by product.
countNbOfShipments()
Returns an array with expeditions lines number.
liste_array($shortlist=0, $draft=0, $excluser=null, $socid=0, $limit=0, $offset=0, $sortfield='c.date_commande', $sortorder='DESC')
Return list of orders (eventuelly filtered on a user) into an array.
fetch($id, $ref='', $ref_ext='', $notused='')
Get object from database.
set_date_livraison($user, $delivery_date, $notrigger=0)
Set delivery date.
add_product($idproduct, $qty, $remise_percent=0.0, $date_start='', $date_end='')
Add line into array $this->client must be loaded.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
setSignedStatus(User $user, int $status=0, int $notrigger=0, $triggercode='')
Set signed status.
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true)
Save a new position (field rang) for details lines.
deleteEcmFiles($mode=0)
Delete related files of object in database.
update_price($exclspec=0, $roundingadjust='auto', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
fetchProject()
Load the project with id $this->fk_project into this->project.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
setErrorsFromObject($object)
setErrorsFromObject
static isExistingObject($element, $id, $ref='', $ref_ext='')
Check if an object id or ref exists If you don't need or want to instantiate the object and just need...
updateRangOfLine($rowid, $rang)
Update position of line (rang)
deleteExtraFields()
Delete all extra fields values for the current object.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
static commonReplaceProduct(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a product id with another one.
line_max($fk_parent_line=0)
Get max value used for position of line (rang)
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
call_trigger($triggerName, $user)
Call trigger based on this instance.
add_contact($fk_socpeople, $type_contact, $source='external', $notrigger=0)
Add a link between element $this->element and a contact.
Superclass for orders classes.
Class to manage absolute discounts.
Class to manage Dolibarr database access.
Class to manage stock movements.
static getIdFromCode($dbs, $code)
Get id of currency from code.
static getIdAndTxFromCode($dbs, $code, $date_document='')
Get id and rate of currency from code.
Class to manage order lines.
Class to manage products or services.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
setSignedStatusCommon(User $user, int $status, int $notrigger=0, string $triggercode='')
Set signed status & call trigger with context message.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_delete_preview($object)
Delete all preview files linked to object instance.
setEntity($currentobject)
Set entity id to use when to create an object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
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.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.: VAT NPR in France)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
getMarginInfos($pv_ht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $pa_ht)
Return an array with margins information of a line.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array=[], $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.