2005-09-15 02:37:03 +02:00
< ? php
2006-12-01 22:35:44 +01:00
/* Copyright ( C ) 2003 - 2006 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2012-08-05 21:30:40 +02:00
* Copyright ( C ) 2004 - 2012 Laurent Destailleur < eldy @ users . sourceforge . net >
2018-10-27 14:43:12 +02:00
* Copyright ( C ) 2005 - 2014 Regis Houssin < regis . houssin @ inodbox . com >
2006-02-12 09:54:15 +01:00
* Copyright ( C ) 2006 Andre Cianfarani < acianfa @ free . fr >
2020-09-03 12:43:38 +02:00
* Copyright ( C ) 2010 - 2020 Juanjo Menent < jmenent @ 2 byte . es >
2011-05-21 09:12:21 +02:00
* Copyright ( C ) 2011 Jean Heimburger < jean @ tiaris . info >
2014-09-24 11:47:34 +02:00
* Copyright ( C ) 2012 - 2014 Christophe Battarel < christophe . battarel @ altairis . fr >
2015-02-26 14:15:33 +01:00
* Copyright ( C ) 2012 Cedric Salvador < csalvador @ gpcsolutions . fr >
2013-09-10 11:04:36 +02:00
* Copyright ( C ) 2013 Florian Henry < florian . henry @ open - concept . pro >
2015-02-15 15:07:24 +01:00
* Copyright ( C ) 2014 - 2015 Marcos GarcÃa < marcosgdf @ gmail . com >
2022-03-23 17:26:25 +01:00
* Copyright ( C ) 2018 Nicolas ZABOURI < info @ inovea - conseil . com >
2022-03-22 13:46:55 +01:00
* Copyright ( C ) 2016 - 2022 Ferran Marcet < fmarcet @ 2 byte . es >
2025-01-05 17:09:38 +01:00
* Copyright ( C ) 2021 - 2025 Frédéric France < frederic . france @ free . fr >
2024-09-16 12:01:04 +02:00
* Copyright ( C ) 2022 Gauthier VERDOL < gauthier . verdol @ atm - consulting . fr >
2025-01-19 02:30:36 +01:00
* Copyright ( C ) 2024 - 2025 MDW < mdeweerd @ users . noreply . github . com >
2024-09-16 11:56:23 +02:00
* Copyright ( C ) 2024 William Mead < william . mead @ manchenumerique . fr >
2005-09-15 02:37:03 +02:00
*
* This program is free software ; you can redistribute it and / or modify
2014-08-18 20:23:06 +02:00
* it under the terms of the GNU General Public License as published by
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2005-09-15 02:37:03 +02:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2005-09-15 02:37:03 +02:00
*/
2008-08-07 22:29:46 +02:00
2005-09-15 02:37:03 +02:00
/**
2010-04-27 10:13:42 +02:00
* \file htdocs / commande / class / commande . class . php
2024-05-13 10:45:20 +02:00
* \ingroup order
2022-08-27 13:55:27 +02:00
* \brief class for orders
2008-08-07 22:29:46 +02:00
*/
2023-09-19 21:16:32 +02:00
2025-01-05 17:23:31 +01:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonorder.class.php' ;
2024-09-04 23:01:53 +02:00
require_once DOL_DOCUMENT_ROOT . '/commande/class/orderline.class.php' ;
2019-11-13 19:37:08 +01:00
require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php' ;
require_once DOL_DOCUMENT_ROOT . '/margin/lib/margins.lib.php' ;
require_once DOL_DOCUMENT_ROOT . '/multicurrency/class/multicurrency.class.php' ;
2023-05-16 09:07:43 +02:00
require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php' ;
2008-08-07 22:29:46 +02:00
2005-09-15 02:37:03 +02:00
/**
2012-08-05 21:30:40 +02:00
* Class to manage customers orders
2008-08-07 22:29:46 +02:00
*/
2012-07-11 18:13:41 +02:00
class Commande extends CommonOrder
2005-09-15 02:37:03 +02:00
{
2018-08-30 09:40:04 +02:00
/**
2018-08-23 17:07:27 +02:00
* @ var string ID to identify managed object
*/
2019-11-13 19:37:08 +01:00
public $element = 'commande' ;
2018-08-30 09:40:04 +02:00
/**
2018-08-22 18:12:44 +02:00
* @ var string Name of table without prefix where object is stored
*/
2019-11-13 19:37:08 +01:00
public $table_element = 'commande' ;
2018-08-30 09:40:04 +02:00
2018-09-02 11:08:41 +02:00
/**
2019-11-02 09:27:06 +01:00
* @ var string Name of subtable line
2018-09-02 11:08:41 +02:00
*/
2018-08-30 09:40:04 +02:00
public $table_element_line = 'commandedet' ;
2018-09-02 11:08:41 +02:00
2019-11-02 09:27:06 +01:00
/**
* @ var string Name of class line
*/
2018-08-30 09:40:04 +02:00
public $class_element_line = 'OrderLine' ;
2018-09-01 15:13:59 +02:00
/**
2019-11-02 09:27:06 +01:00
* @ var string Field name with ID of parent key if this field has a parent
2018-09-01 15:13:59 +02:00
*/
2018-08-30 09:40:04 +02:00
public $fk_element = 'fk_commande' ;
2018-09-01 15:13:59 +02:00
2018-09-05 10:31:12 +02:00
/**
2019-11-02 09:27:06 +01:00
* @ var string String with name of icon for commande class . Here is object_order . png
2018-09-05 10:31:12 +02:00
*/
2018-08-30 09:40:04 +02:00
public $picto = 'order' ;
2018-09-02 11:08:41 +02:00
2018-08-30 09:40:04 +02:00
/**
* 0 = Default , 1 = View may be restricted to sales representative only if no permission to see all or to company of external user if external user
* @ var integer
*/
public $restrictiononfksoc = 1 ;
/**
* { @ inheritdoc }
*/
protected $table_ref_field = 'ref' ;
2014-12-25 21:47:39 +01:00
2015-04-03 05:18:47 +02:00
/**
2022-08-27 13:55:27 +02:00
* @ var int Thirdparty ID
2015-04-03 05:18:47 +02:00
*/
2018-08-30 09:40:04 +02:00
public $socid ;
2015-04-03 05:18:47 +02:00
2019-11-02 09:27:06 +01:00
/**
2022-08-27 13:55:27 +02:00
* @ var string Thirdparty ref of order
2019-11-02 09:27:06 +01:00
*/
2018-08-30 09:40:04 +02:00
public $ref_client ;
2019-11-02 09:27:06 +01:00
2023-05-01 13:09:09 +02:00
/**
* @ var string Thirdparty ref of order
*/
public $ref_customer ;
2020-09-08 21:27:28 +02:00
/**
2019-11-02 09:27:06 +01:00
* @ var int Contact ID
*/
2018-08-30 09:40:04 +02:00
public $contactid ;
2015-04-01 16:33:39 +02:00
2015-03-15 11:48:57 +01:00
/**
2017-07-13 12:42:32 +02:00
* Status of the order
2015-03-15 11:48:57 +01:00
* @ var int
2025-02-11 16:28:37 +01:00
* @ deprecated Use status
2015-03-15 11:48:57 +01:00
*/
2018-08-30 09:40:04 +02:00
public $statut ;
2018-09-02 11:08:41 +02:00
2025-02-11 16:28:37 +01:00
/**
* Status of the order
2025-02-18 10:24:00 +01:00
* @ var int | null
2025-02-11 16:28:37 +01:00
*/
public $status ;
2015-03-15 11:48:57 +01:00
/**
2019-11-02 09:27:06 +01:00
* @ var int Status Billed or not
2015-03-15 11:48:57 +01:00
*/
2019-11-02 09:27:06 +01:00
public $billed ;
2018-08-30 09:40:04 +02:00
2023-10-20 02:20:26 +02:00
/**
2024-01-18 23:28:42 +01:00
* @ var int Deadline for payment
2023-10-20 02:20:26 +02:00
*/
public $date_lim_reglement ;
2021-02-09 22:14:46 +01:00
/**
* @ var string Condition payment code
*/
2020-09-08 21:27:28 +02:00
public $cond_reglement_code ;
2018-08-30 09:40:04 +02:00
2023-08-05 12:50:09 +02:00
/**
* @ var string Condition payment label
*/
public $cond_reglement_doc ;
2021-09-29 12:05:38 +02:00
/**
2024-02-19 15:31:22 +01:00
* @ var float Deposit percent for payment terms .
* Populated by $CommonObject -> setPaymentTerms () .
2024-02-09 18:57:04 +01:00
* @ see setPaymentTerms ()
2021-09-29 12:05:38 +02:00
*/
public $deposit_percent ;
2018-10-09 09:40:00 +02:00
/**
2020-09-08 21:27:28 +02:00
* @ var int bank account ID
*/
2018-08-30 09:40:04 +02:00
public $fk_account ;
/**
2019-11-02 09:27:06 +01:00
* @ var string It holds the label of the payment mode . Use it in case translation cannot be found .
2018-08-30 09:40:04 +02:00
*/
public $mode_reglement ;
/**
2019-11-02 09:27:06 +01:00
* @ var int Payment mode id
2018-08-30 09:40:04 +02:00
*/
public $mode_reglement_id ;
2018-09-02 11:08:41 +02:00
2018-08-30 09:40:04 +02:00
/**
2019-11-02 09:27:06 +01:00
* @ var string Payment mode code
2018-08-30 09:40:04 +02:00
*/
public $mode_reglement_code ;
2018-09-02 11:08:41 +02:00
2018-08-30 09:40:04 +02:00
/**
* Availability delivery time id
* @ var int
*/
public $availability_id ;
2018-09-02 11:08:41 +02:00
2018-08-30 09:40:04 +02:00
/**
* Availability delivery time code
* @ var string
*/
public $availability_code ;
2018-09-02 11:08:41 +02:00
2018-08-30 09:40:04 +02:00
/**
* Label of availability delivery time . Use it in case translation cannot be found .
* @ var string
*/
public $availability ;
2021-02-09 22:14:46 +01:00
/**
* @ var int Source demand reason Id
*/
public $demand_reason_id ;
/**
* @ var string Source reason code . Why we receive order ( after a phone campaign , ... )
*/
2018-08-30 09:40:04 +02:00
public $demand_reason_code ;
2015-12-27 13:10:33 +01:00
2015-04-23 23:21:06 +02:00
/**
2024-06-30 21:04:19 +02:00
* @ var null | int | '' Date of order
2019-11-02 09:27:06 +01:00
*/
public $date ;
2015-12-27 13:10:33 +01:00
2015-04-23 23:21:06 +02:00
/**
2024-06-30 21:04:19 +02:00
* @ var null | int | '' Date of order
2015-04-23 23:21:06 +02:00
* @ deprecated
2019-04-08 16:04:15 +02:00
* @ see $date
2015-04-23 23:21:06 +02:00
*/
2018-08-30 09:40:04 +02:00
public $date_commande ;
2018-09-02 11:08:41 +02:00
2020-11-11 18:08:40 +01:00
/**
2024-09-30 10:05:24 +02:00
* @ var null | int | '' Expected shipment date ( date of start of shipment , not the reception that occurs some days after )
2021-02-09 22:14:46 +01:00
*/
public $delivery_date ;
2018-10-09 09:40:00 +02:00
/**
2020-09-08 21:27:28 +02:00
* @ var int ID
*/
2018-08-30 09:40:04 +02:00
public $fk_remise_except ;
2018-10-09 09:40:00 +02:00
2023-02-28 15:47:33 +01:00
/**
2024-09-30 10:05:24 +02:00
* @ var string
* @ deprecated See $fk_remise_except
2023-02-28 15:47:33 +01:00
*/
2018-08-30 09:40:04 +02:00
public $remise_percent ;
2023-02-28 15:47:33 +01:00
2024-09-30 10:05:24 +02:00
/**
* @ var int
*/
2019-11-13 19:37:08 +01:00
public $source ; // Order mode. How we received order (by phone, by email, ...)
2020-11-28 14:47:39 +01:00
2024-07-16 15:22:54 +02:00
/**
* Status of the contract ( 0 = NoSignature , 1 = SignedBySender , 2 = SignedByReceiver , 9 = SignedByAll )
* @ var int
*/
public $signed_status = 0 ;
2021-02-09 22:14:46 +01:00
/**
* @ var int Warehouse Id
*/
2021-01-12 10:34:15 +01:00
public $warehouse_id ;
2024-09-12 21:16:42 +02:00
/**
* @ var array < string , string > ( Encoded as JSON in database )
*/
2019-11-13 19:37:08 +01:00
public $extraparams = array ();
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
public $linked_objects = array ();
2018-08-30 09:40:04 +02:00
2019-11-02 09:27:06 +01:00
/**
2020-09-08 21:27:28 +02:00
* @ var int User author ID
*/
2018-08-30 09:40:04 +02:00
public $user_author_id ;
2019-11-02 09:27:06 +01:00
2023-01-18 22:37:08 +01:00
/**
* @ var OrderLine one line of an order
*/
public $line ;
2015-03-23 01:39:12 +01:00
/**
* @ var OrderLine []
*/
2016-07-08 21:28:21 +02:00
public $lines = array ();
2011-09-12 19:08:02 +02:00
2016-07-08 18:30:50 +02:00
2024-09-30 10:05:24 +02:00
/**
* @ var string key of module source when order generated from a dedicated module ( 'cashdesk' , 'takepos' , ... )
*/
2019-02-20 12:29:47 +01:00
public $module_source ;
2024-09-30 10:05:24 +02:00
/**
* @ var string key of pos source ( '0' , '1' , ... )
*/
2019-02-20 12:29:47 +01:00
public $pos_source ;
2019-02-25 00:56:48 +01:00
2022-01-24 14:09:53 +01:00
/**
2024-09-30 10:05:24 +02:00
* @ var array < int , float > Array with lines of all shipments ( qty )
2022-01-24 14:09:53 +01:00
*/
public $expeditions ;
2022-03-30 14:06:15 +02:00
/**
* @ var string payment url
*/
public $online_payment_url ;
2020-03-04 00:47:03 +01:00
2023-11-06 16:00:24 +01:00
2020-03-04 00:47:03 +01:00
/**
* 'type' if the field format ( 'integer' , 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]' , 'varchar(x)' , 'double(24,8)' , 'real' , 'price' , 'text' , 'html' , 'date' , 'datetime' , 'timestamp' , 'duration' , 'mail' , 'phone' , 'url' , 'password' )
* Note : Filter can be a string like " (t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL) "
* 'label' the translation key .
* 'enabled' is a condition when the field must be managed .
* 'position' is the sort order of field .
* 'notnull' is set to 1 if not null in database . Set to - 1 if we must set data to null if empty ( '' or 0 ) .
* 'visible' says if field is visible in list ( Examples : 0 = Not visible , 1 = Visible on list and create / update / view forms , 2 = Visible on list only , 3 = Visible on create / update / view form only ( not list ), 4 = Visible on list and update / view form only ( not create ) . 5 = Visible on list and view only ( not create / not update ) . Using a negative value means field is not shown by default on list but can be selected for viewing )
* 'noteditable' says if field is not editable ( 1 or 0 )
* 'default' is a default value for creation ( can still be overwrote by the Setup of Default Values if field is editable in creation form ) . Note : If default is set to '(PROV)' and field is 'ref' , the default value will be set to '(PROVid)' where id is rowid when a new record is created .
* 'index' if we want an index in database .
2024-01-14 12:26:37 +01:00
* 'foreignkey' => 'tablename.field' if the field is a foreign key ( it is recommended to name the field fk_ ... ) .
2020-03-04 00:47:03 +01:00
* 'searchall' is 1 if we want to search in this field when making a search from the quick search button .
* 'isameasure' must be set to 1 if you want to have a total on list for this field . Field type must be summable like integer or double ( 24 , 8 ) .
* 'css' is the CSS style to use on field . For example : 'maxwidth200'
* 'help' is a string visible as a tooltip on field
* 'showoncombobox' if value of the field must be visible into the label of the combobox that list record
* 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute . In most cases , this is never set into the definition of $fields into class , but is set dynamically by some part of code .
2021-04-29 12:10:55 +02:00
* 'arrayofkeyval' to set list of value if type is a list of predefined values . For example : array ( " 0 " => " Draft " , " 1 " => " Active " , " -1 " => " Cancel " )
2020-03-04 00:47:03 +01:00
* 'comment' is not used . You can store here any text of your choice . It is not used by application .
*
* Note : To have value dynamic , you can set value to 0 in definition and edit the value on the fly into the constructor .
*/
// BEGIN MODULEBUILDER PROPERTIES
/**
2025-02-05 00:40:06 +01:00
* @ var array < string , array { type : string , label : string , enabled : int < 0 , 2 >| string , position : int , notnull ? : int , visible : int <- 6 , 6 >| string , alwayseditable ? : int < 0 , 1 > , noteditable ? : int < 0 , 1 > , default ? : string , index ? : int , foreignkey ? : string , searchall ? : int < 0 , 1 > , isameasure ? : int < 0 , 1 > , css ? : string , csslist ? : string , help ? : string , showoncombobox ? : int < 0 , 4 > , disabled ? : int < 0 , 1 > , arrayofkeyval ? : array < int | string , string > , autofocusoncreate ? : int < 0 , 1 > , comment ? : string , copytoclipboard ? : int < 1 , 2 > , validate ? : int < 0 , 1 > , showonheader ? : int < 0 , 1 > } > Array with all fields and their property . Do not use it as a static var . It may be modified by constructor .
2020-03-04 00:47:03 +01:00
*/
2020-03-12 12:45:44 +01:00
public $fields = array (
2024-02-28 23:01:01 +01:00
'rowid' => array ( 'type' => 'integer' , 'label' => 'TechnicalID' , 'enabled' => 1 , 'visible' => - 1 , 'notnull' => 1 , 'position' => 10 ),
2024-03-15 00:10:48 +01:00
'entity' => array ( 'type' => 'integer' , 'label' => 'Entity' , 'default' => '1' , 'enabled' => 1 , 'visible' => - 2 , 'notnull' => 1 , 'position' => 20 , 'index' => 1 ),
2024-02-28 23:01:01 +01:00
'ref' => array ( 'type' => 'varchar(30)' , 'label' => 'Ref' , 'enabled' => 1 , 'visible' => - 1 , 'notnull' => 1 , 'showoncombobox' => 1 , 'position' => 25 ),
'ref_ext' => array ( 'type' => 'varchar(255)' , 'label' => 'RefExt' , 'enabled' => 1 , 'visible' => 0 , 'position' => 26 ),
'ref_client' => array ( 'type' => 'varchar(255)' , 'label' => 'RefCustomer' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 28 ),
'fk_soc' => array ( 'type' => 'integer:Societe:societe/class/societe.class.php' , 'label' => 'ThirdParty' , 'enabled' => 'isModEnabled("societe")' , 'visible' => - 1 , 'notnull' => 1 , 'position' => 20 ),
'fk_projet' => array ( 'type' => 'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)' , 'label' => 'Project' , 'enabled' => " isModEnabled('project') " , 'visible' => - 1 , 'position' => 25 ),
'date_commande' => array ( 'type' => 'date' , 'label' => 'Date' , 'enabled' => 1 , 'visible' => 1 , 'position' => 60 , 'csslist' => 'nowraponall' ),
'date_valid' => array ( 'type' => 'datetime' , 'label' => 'DateValidation' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 62 , 'csslist' => 'nowraponall' ),
'date_cloture' => array ( 'type' => 'datetime' , 'label' => 'DateClosing' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 65 , 'csslist' => 'nowraponall' ),
'fk_user_valid' => array ( 'type' => 'integer:User:user/class/user.class.php' , 'label' => 'UserValidation' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 85 ),
'fk_user_cloture' => array ( 'type' => 'integer:User:user/class/user.class.php' , 'label' => 'UserClosing' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 90 ),
'source' => array ( 'type' => 'smallint(6)' , 'label' => 'Source' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 95 ),
'total_tva' => array ( 'type' => 'double(24,8)' , 'label' => 'VAT' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 125 , 'isameasure' => 1 ),
'localtax1' => array ( 'type' => 'double(24,8)' , 'label' => 'LocalTax1' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 130 , 'isameasure' => 1 ),
'localtax2' => array ( 'type' => 'double(24,8)' , 'label' => 'LocalTax2' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 135 , 'isameasure' => 1 ),
'total_ht' => array ( 'type' => 'double(24,8)' , 'label' => 'TotalHT' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 140 , 'isameasure' => 1 ),
'total_ttc' => array ( 'type' => 'double(24,8)' , 'label' => 'TotalTTC' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 145 , 'isameasure' => 1 ),
2024-07-16 15:22:54 +02:00
'signed_status' => array ( 'type' => 'smallint(6)' , 'label' => 'SignedStatus' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 146 , 'arrayofkeyval' => array ( 0 => 'NoSignature' , 1 => 'SignedSender' , 2 => 'SignedReceiver' , 9 => 'SignedAll' )),
2024-02-28 23:01:01 +01:00
'note_private' => array ( 'type' => 'html' , 'label' => 'NotePrivate' , 'enabled' => 1 , 'visible' => 0 , 'position' => 150 ),
'note_public' => array ( 'type' => 'html' , 'label' => 'NotePublic' , 'enabled' => 1 , 'visible' => 0 , 'position' => 155 ),
'model_pdf' => array ( 'type' => 'varchar(255)' , 'label' => 'PDFTemplate' , 'enabled' => 1 , 'visible' => 0 , 'position' => 160 ),
'fk_account' => array ( 'type' => 'integer' , 'label' => 'BankAccount' , 'enabled' => 'isModEnabled("bank")' , 'visible' => - 1 , 'position' => 170 ),
'fk_currency' => array ( 'type' => 'varchar(3)' , 'label' => 'MulticurrencyID' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 175 ),
'fk_cond_reglement' => array ( 'type' => 'integer' , 'label' => 'PaymentTerm' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 180 ),
'deposit_percent' => array ( 'type' => 'varchar(63)' , 'label' => 'DepositPercent' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 181 ),
'fk_mode_reglement' => array ( 'type' => 'integer' , 'label' => 'PaymentMode' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 185 ),
'date_livraison' => array ( 'type' => 'date' , 'label' => 'DateDeliveryPlanned' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 190 , 'csslist' => 'nowraponall' ),
'fk_shipping_method' => array ( 'type' => 'integer' , 'label' => 'ShippingMethod' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 195 ),
2025-01-14 22:05:08 +01:00
'fk_warehouse' => array ( 'type' => 'integer:Entrepot:product/stock/class/entrepot.class.php' , 'label' => 'DefaultWarehouse' , 'enabled' => 'isModEnabled("stock")' , 'visible' => - 1 , 'position' => 200 , 'nodepth' => 1 ),
2024-02-28 23:01:01 +01:00
'fk_availability' => array ( 'type' => 'integer' , 'label' => 'Availability' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 205 ),
'fk_input_reason' => array ( 'type' => 'integer' , 'label' => 'InputReason' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 210 ),
2020-03-08 19:25:00 +01:00
//'fk_delivery_address' =>array('type'=>'integer', 'label'=>'DeliveryAddress', 'enabled'=>1, 'visible'=>-1, 'position'=>215),
2024-02-28 23:01:01 +01:00
'extraparams' => array ( 'type' => 'varchar(255)' , 'label' => 'Extraparams' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 225 ),
'fk_incoterms' => array ( 'type' => 'integer' , 'label' => 'IncotermCode' , 'enabled' => '$conf->incoterm->enabled' , 'visible' => - 1 , 'position' => 230 ),
'location_incoterms' => array ( 'type' => 'varchar(255)' , 'label' => 'IncotermLabel' , 'enabled' => '$conf->incoterm->enabled' , 'visible' => - 1 , 'position' => 235 ),
'fk_multicurrency' => array ( 'type' => 'integer' , 'label' => 'Fk multicurrency' , 'enabled' => 'isModEnabled("multicurrency")' , 'visible' => - 1 , 'position' => 240 ),
'multicurrency_code' => array ( 'type' => 'varchar(255)' , 'label' => 'MulticurrencyCurrency' , 'enabled' => 'isModEnabled("multicurrency")' , 'visible' => - 1 , 'position' => 245 ),
'multicurrency_tx' => array ( 'type' => 'double(24,8)' , 'label' => 'MulticurrencyRate' , 'enabled' => 'isModEnabled("multicurrency")' , 'visible' => - 1 , 'position' => 250 , 'isameasure' => 1 ),
'multicurrency_total_ht' => array ( 'type' => 'double(24,8)' , 'label' => 'MulticurrencyAmountHT' , 'enabled' => 'isModEnabled("multicurrency")' , 'visible' => - 1 , 'position' => 255 , 'isameasure' => 1 ),
'multicurrency_total_tva' => array ( 'type' => 'double(24,8)' , 'label' => 'MulticurrencyAmountVAT' , 'enabled' => 'isModEnabled("multicurrency")' , 'visible' => - 1 , 'position' => 260 , 'isameasure' => 1 ),
'multicurrency_total_ttc' => array ( 'type' => 'double(24,8)' , 'label' => 'MulticurrencyAmountTTC' , 'enabled' => 'isModEnabled("multicurrency")' , 'visible' => - 1 , 'position' => 265 , 'isameasure' => 1 ),
'last_main_doc' => array ( 'type' => 'varchar(255)' , 'label' => 'LastMainDoc' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 270 ),
'module_source' => array ( 'type' => 'varchar(32)' , 'label' => 'POSModule' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 275 ),
'pos_source' => array ( 'type' => 'varchar(32)' , 'label' => 'POSTerminal' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 280 ),
'fk_user_author' => array ( 'type' => 'integer:User:user/class/user.class.php' , 'label' => 'UserAuthor' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 300 ),
'fk_user_modif' => array ( 'type' => 'integer:User:user/class/user.class.php' , 'label' => 'UserModif' , 'enabled' => 1 , 'visible' => - 2 , 'notnull' => - 1 , 'position' => 302 ),
'date_creation' => array ( 'type' => 'datetime' , 'label' => 'DateCreation' , 'enabled' => 1 , 'visible' => - 2 , 'position' => 304 , 'csslist' => 'nowraponall' ),
'tms' => array ( 'type' => 'timestamp' , 'label' => 'DateModification' , 'enabled' => 1 , 'visible' => - 1 , 'notnull' => 1 , 'position' => 306 ),
'import_key' => array ( 'type' => 'varchar(14)' , 'label' => 'ImportId' , 'enabled' => 1 , 'visible' => - 2 , 'position' => 400 ),
'fk_statut' => array ( 'type' => 'smallint(6)' , 'label' => 'Status' , 'enabled' => 1 , 'visible' => - 1 , 'position' => 500 ),
2020-03-04 00:47:03 +01:00
);
// END MODULEBUILDER PROPERTIES
2018-08-30 09:40:04 +02:00
/**
* ERR Not enough stock
*/
const STOCK_NOT_ENOUGH_FOR_ORDER = - 3 ;
2011-09-12 19:08:02 +02:00
2015-04-03 05:18:47 +02:00
/**
* Canceled status
*/
const STATUS_CANCELED = - 1 ;
/**
* Draft status
*/
const STATUS_DRAFT = 0 ;
/**
* Validated status
*/
const STATUS_VALIDATED = 1 ;
/**
2017-10-07 13:04:31 +02:00
* Shipment on process
2016-04-01 16:59:08 +02:00
*/
2023-09-19 20:29:24 +02:00
const STATUS_SHIPMENTONPROCESS = 2 ; // We set this status when a shipment is validated
2024-06-30 21:04:19 +02:00
/**
* For backward compatibility . Use key STATUS_SHIPMENTONPROCESS instead .
* @ deprecated
*/
const STATUS_ACCEPTED = 2 ;
2017-10-11 11:36:24 +02:00
2015-04-03 05:18:47 +02:00
/**
2017-10-07 13:04:31 +02:00
* Closed ( Sent , billed or not )
2015-04-03 05:18:47 +02:00
*/
const STATUS_CLOSED = 3 ;
2024-07-16 15:22:54 +02:00
/*
* No signature
*/
const STATUS_NO_SIGNATURE = 0 ;
/*
* Signed by sender
*/
2024-08-07 01:20:43 +02:00
const STATUS_SIGNED_SENDER = 1 ;
2024-07-16 15:22:54 +02:00
/*
* Signed by receiver
*/
2024-08-07 01:20:43 +02:00
const STATUS_SIGNED_RECEIVER = 2 ;
2024-07-16 15:22:54 +02:00
/*
* Signed by all
*/
2024-08-07 01:20:43 +02:00
const STATUS_SIGNED_ALL = 9 ; // To handle future kind of signature (ex: tripartite contract)
2024-07-16 15:22:54 +02:00
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
/**
* Constructor
*
* @ param DoliDB $db Database handler
*/
2019-02-25 00:56:48 +01:00
public function __construct ( $db )
2018-08-30 09:40:04 +02:00
{
$this -> db = $db ;
2024-05-05 00:34:19 +02:00
$this -> ismultientitymanaged = 1 ;
$this -> isextrafieldmanaged = 1 ;
2025-01-12 18:00:01 +01:00
$this -> fields [ 'ref_ext' ][ 'visible' ] = getDolGlobalInt ( 'MAIN_LIST_SHOW_REF_EXT' );
2018-08-30 09:40:04 +02:00
}
2012-02-06 17:18:19 +01:00
2018-08-30 09:40:04 +02:00
/**
2011-12-16 12:47:23 +01:00
* Returns the reference to the following non used Order depending on the active numbering module
* defined into COMMANDE_ADDON
*
* @ param Societe $soc Object thirdparty
* @ return string Order free reference
*/
2019-02-25 00:56:48 +01:00
public function getNextNumRef ( $soc )
2018-08-30 09:40:04 +02:00
{
global $langs , $conf ;
$langs -> load ( " order " );
2011-09-12 19:08:02 +02:00
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'COMMANDE_ADDON' )) {
2019-11-13 19:37:08 +01:00
$mybool = false ;
2011-09-12 19:08:02 +02:00
2023-10-15 15:32:35 +02:00
$file = getDolGlobalString ( 'COMMANDE_ADDON' ) . " .php " ;
2024-01-05 04:18:53 +01:00
$classname = getDolGlobalString ( 'COMMANDE_ADDON' );
2015-01-17 18:58:05 +01:00
2015-01-18 17:13:42 +01:00
// Include file with class
2019-11-13 19:37:08 +01:00
$dirmodels = array_merge ( array ( '/' ), ( array ) $conf -> modules_parts [ 'models' ]);
2021-02-23 20:46:19 +01:00
foreach ( $dirmodels as $reldir ) {
2018-08-30 09:40:04 +02:00
$dir = dol_buildpath ( $reldir . " core/modules/commande/ " );
// Load file with numbering class (if found)
2024-03-21 13:21:06 +01:00
$mybool = (( bool ) @ include_once $dir . $file ) || $mybool ;
2018-08-30 09:40:04 +02:00
}
2024-08-07 03:05:02 +02:00
if ( ! $mybool ) {
2024-01-20 09:22:38 +01:00
dol_print_error ( null , " Failed to include file " . $file );
2020-09-08 21:27:28 +02:00
return '' ;
}
2018-08-30 09:40:04 +02:00
$obj = new $classname ();
2025-01-05 17:23:31 +01:00
/** @var ModeleNumRefCommandes $obj */
2024-08-29 15:01:42 +02:00
'@phan-var-force ModeleNumRefCommandes $obj' ;
2019-01-27 11:55:16 +01:00
$numref = $obj -> getNextValue ( $soc , $this );
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( $numref != " " ) {
2018-08-30 09:40:04 +02:00
return $numref ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $obj -> error ;
2018-08-30 09:40:04 +02:00
//dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
return " " ;
}
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
print $langs -> trans ( " Error " ) . " " . $langs -> trans ( " Error_COMMANDE_ADDON_NotDefined " );
return " " ;
}
}
/**
* Validate order
*
* @ param User $user User making status change
* @ param int $idwarehouse Id of warehouse to use for stock decrease
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , 0 = Nothing done , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function valid ( $user , $idwarehouse = 0 , $notrigger = 0 )
2012-07-06 13:43:59 +02:00
{
2020-01-30 01:48:28 +01:00
global $conf , $langs ;
2019-07-28 22:26:55 +02:00
2018-08-30 09:40:04 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2012-07-06 13:43:59 +02:00
2020-01-30 01:48:28 +01:00
$error = 0 ;
2012-07-06 13:43:59 +02:00
2018-08-30 09:40:04 +02:00
// Protection
2021-02-23 20:46:19 +01:00
if ( $this -> statut == self :: STATUS_VALIDATED ) {
2024-01-14 12:26:37 +01:00
dol_syslog ( get_class ( $this ) . " ::valid action abandoned: already validated " , LOG_WARNING );
2018-08-30 09:40:04 +02:00
return 0 ;
}
2023-11-27 11:39:32 +01:00
if ( ! (( ! getDolGlobalString ( 'MAIN_USE_ADVANCED_PERMS' ) && $user -> hasRight ( 'commande' , 'creer' ))
|| ( getDolGlobalString ( 'MAIN_USE_ADVANCED_PERMS' ) && $user -> hasRight ( 'commande' , 'order_advance' , 'validate' )))) {
2019-11-13 19:37:08 +01:00
$this -> error = 'NotEnoughPermissions' ;
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::valid " . $this -> error , LOG_ERR );
return - 1 ;
}
2019-11-13 19:37:08 +01:00
$now = dol_now ();
2018-08-30 09:40:04 +02:00
2012-07-06 13:43:59 +02:00
$this -> db -> begin ();
2018-08-30 09:40:04 +02:00
// Definition du nom de module de numerotation de commande
$soc = new Societe ( $this -> db );
$soc -> fetch ( $this -> socid );
// Class of company linked to order
2023-09-06 13:58:08 +02:00
$result = $soc -> setAsCustomer ();
2018-08-30 09:40:04 +02:00
// Define new ref
2021-02-23 20:46:19 +01:00
if ( ! $error && ( preg_match ( '/^[\(]?PROV/i' , $this -> ref ) || empty ( $this -> ref ))) { // empty should not happened, but when it occurs, the test save life
2018-08-30 09:40:04 +02:00
$num = $this -> getNextNumRef ( $soc );
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$num = $this -> ref ;
}
2020-03-03 11:49:17 +01:00
$this -> newref = dol_sanitizeFileName ( $num );
2018-08-30 09:40:04 +02:00
// Validate
2024-09-26 17:10:25 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . $this -> table_element ;
2020-01-30 01:48:28 +01:00
$sql .= " SET ref = ' " . $this -> db -> escape ( $num ) . " ', " ;
$sql .= " fk_statut = " . self :: STATUS_VALIDATED . " , " ;
2025-01-19 17:38:34 +01:00
$sql .= " date_valid = ' " . $this -> db -> idate ( $now ) . " ', " ;
2022-07-03 12:54:58 +02:00
$sql .= " fk_user_valid = " . ( $user -> id > 0 ? ( int ) $user -> id : " null " ) . " , " ;
2022-01-16 00:13:14 +01:00
$sql .= " fk_user_modif = " . (( int ) $user -> id );
2021-08-23 19:33:24 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2012-07-06 13:43:59 +02:00
2020-10-27 18:30:03 +01:00
dol_syslog ( get_class ( $this ) . " ::valid " , LOG_DEBUG );
2020-01-30 01:48:28 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( ! $resql ) {
2018-08-30 09:40:04 +02:00
dol_print_error ( $this -> db );
2020-01-30 01:48:28 +01:00
$this -> error = $this -> db -> lasterror ();
2018-08-30 09:40:04 +02:00
$error ++ ;
}
2020-12-16 02:44:48 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
// If stock is incremented on validate order, we must increment it
2023-10-08 23:25:46 +02:00
if ( $result >= 0 && isModEnabled ( 'stock' ) && getDolGlobalInt ( 'STOCK_CALCULATE_ON_VALIDATE_ORDER' ) == 1 ) {
2012-08-22 23:11:24 +02:00
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php' ;
2012-07-06 13:43:59 +02:00
$langs -> load ( " agenda " );
2018-08-30 09:40:04 +02:00
// Loop on each line
2020-01-30 01:48:28 +01:00
$cpt = count ( $this -> lines );
2020-12-16 02:44:48 +01:00
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
if ( $this -> lines [ $i ] -> fk_product > 0 ) {
2012-07-06 13:43:59 +02:00
$mouvP = new MouvementStock ( $this -> db );
2018-08-30 09:40:04 +02:00
$mouvP -> origin = & $this ;
2022-03-22 13:46:55 +01:00
$mouvP -> setOrigin ( $this -> element , $this -> id );
2018-08-30 09:40:04 +02:00
// We decrement stock of product (and sub-products)
2019-11-13 19:37:08 +01:00
$result = $mouvP -> livraison ( $user , $this -> lines [ $i ] -> fk_product , $idwarehouse , $this -> lines [ $i ] -> qty , $this -> lines [ $i ] -> subprice , $langs -> trans ( " OrderValidatedInDolibarr " , $num ));
2020-12-16 02:44:48 +01:00
if ( $result < 0 ) {
2012-07-06 13:43:59 +02:00
$error ++ ;
2019-11-13 19:37:08 +01:00
$this -> error = $mouvP -> error ;
2012-07-06 13:43:59 +02:00
}
}
2021-02-23 20:46:19 +01:00
if ( $error ) {
break ;
}
2012-07-06 13:43:59 +02:00
}
}
2018-08-30 09:40:04 +02:00
}
2012-07-06 13:43:59 +02:00
2020-12-16 02:44:48 +01:00
if ( ! $error && ! $notrigger ) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_VALIDATE' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2012-07-06 13:43:59 +02:00
2020-12-16 02:44:48 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> oldref = $this -> ref ;
// Rename directory if dir was a temporary ref
2021-02-23 20:46:19 +01:00
if ( preg_match ( '/^[\(]?PROV/i' , $this -> ref )) {
2019-07-28 22:26:55 +02:00
// Now we rename also files into index
2020-01-30 01:48:28 +01:00
$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 ) . " ' " ;
$sql .= " WHERE filename LIKE ' " . $this -> db -> escape ( $this -> ref ) . " %' AND filepath = 'commande/ " . $this -> db -> escape ( $this -> ref ) . " ' and entity = " . $conf -> entity ;
2019-07-28 22:26:55 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( ! $resql ) {
2023-12-04 12:01:45 +01:00
$error ++ ;
$this -> error = $this -> db -> lasterror ();
2021-02-23 20:46:19 +01:00
}
2023-10-31 19:28:11 +01:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . " ecm_files set filepath = 'commande/ " . $this -> db -> escape ( $this -> newref ) . " ' " ;
$sql .= " WHERE filepath = 'commande/ " . $this -> db -> escape ( $this -> ref ) . " ' and entity = " . $conf -> entity ;
$resql = $this -> db -> query ( $sql );
if ( ! $resql ) {
2023-12-04 12:01:45 +01:00
$error ++ ;
$this -> error = $this -> db -> lasterror ();
2023-10-31 19:28:11 +01:00
}
2019-07-28 22:26:55 +02:00
// We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
2018-08-30 09:40:04 +02:00
$oldref = dol_sanitizeFileName ( $this -> ref );
$newref = dol_sanitizeFileName ( $num );
2019-05-12 14:25:41 +02:00
$dirsource = $conf -> commande -> multidir_output [ $this -> entity ] . '/' . $oldref ;
$dirdest = $conf -> commande -> multidir_output [ $this -> entity ] . '/' . $newref ;
2021-02-23 20:46:19 +01:00
if ( ! $error && file_exists ( $dirsource )) {
2020-10-27 18:30:03 +01:00
dol_syslog ( get_class ( $this ) . " ::valid rename dir " . $dirsource . " into " . $dirdest );
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( @ rename ( $dirsource , $dirdest )) {
2018-08-30 09:40:04 +02:00
dol_syslog ( " Rename ok " );
// Rename docs starting with $oldref with $newref
2020-01-30 01:48:28 +01:00
$listoffiles = dol_dir_list ( $conf -> commande -> multidir_output [ $this -> entity ] . '/' . $newref , 'files' , 1 , '^' . preg_quote ( $oldref , '/' ));
2021-02-23 20:46:19 +01:00
foreach ( $listoffiles as $fileentry ) {
2020-01-30 01:48:28 +01:00
$dirsource = $fileentry [ 'name' ];
$dirdest = preg_replace ( '/^' . preg_quote ( $oldref , '/' ) . '/' , $newref , $dirsource );
$dirsource = $fileentry [ 'path' ] . '/' . $dirsource ;
$dirdest = $fileentry [ 'path' ] . '/' . $dirdest ;
2018-08-30 09:40:04 +02:00
@ rename ( $dirsource , $dirdest );
}
}
2014-06-14 12:30:48 +02:00
}
2012-07-06 13:43:59 +02:00
}
}
2018-08-30 09:40:04 +02:00
// Set new ref and current status
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> ref = $num ;
2023-08-06 00:16:25 +02:00
$this -> statut = self :: STATUS_VALIDATED ; // deprecated
$this -> status = self :: STATUS_VALIDATED ;
2018-08-30 09:40:04 +02:00
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2012-07-06 13:43:59 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
2011-09-12 19:08:02 +02:00
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Set draft status
*
* @ param User $user Object user that modify
* @ param int $idwarehouse Warehouse ID to use for stock change ( Used only if option STOCK_CALCULATE_ON_VALIDATE_ORDER is on )
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2020-09-08 21:27:28 +02:00
public function setDraft ( $user , $idwarehouse = - 1 )
{
//phpcs:enable
2025-01-19 17:38:34 +01:00
global $langs ;
2017-06-09 09:25:15 +02:00
2019-11-13 19:37:08 +01:00
$error = 0 ;
2017-06-09 09:25:15 +02:00
2018-08-30 09:40:04 +02:00
// Protection
2024-07-16 21:54:04 +02:00
if ( $this -> statut <= self :: STATUS_DRAFT && ! getDolGlobalInt ( 'ORDER_REOPEN_TO_DRAFT' )) {
2018-08-30 09:40:04 +02:00
return 0 ;
2016-01-23 00:38:17 +01:00
}
2016-07-08 18:30:50 +02:00
2023-11-27 11:39:32 +01:00
if ( ! (( ! getDolGlobalString ( 'MAIN_USE_ADVANCED_PERMS' ) && $user -> hasRight ( 'commande' , 'creer' ))
|| ( getDolGlobalString ( 'MAIN_USE_ADVANCED_PERMS' ) && $user -> hasRight ( 'commande' , 'order_advance' , 'validate' )))) {
2019-11-13 19:37:08 +01:00
$this -> error = 'Permission denied' ;
2018-08-30 09:40:04 +02:00
return - 1 ;
}
2011-09-12 19:08:02 +02:00
2019-05-01 09:38:27 +02:00
dol_syslog ( __METHOD__ , LOG_DEBUG );
2019-03-21 17:37:56 +01:00
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2024-09-26 17:10:25 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . $this -> table_element ;
2022-01-26 20:13:10 +01:00
$sql .= " SET fk_statut = " . self :: STATUS_DRAFT . " , " ;
2022-01-16 00:13:14 +01:00
$sql .= " fk_user_modif = " . (( int ) $user -> id );
2021-08-23 19:33:24 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( $this -> db -> query ( $sql )) {
if ( ! $error ) {
2020-09-08 21:27:28 +02:00
$this -> oldcopy = clone $this ;
}
2019-03-21 17:37:56 +01:00
2020-09-08 21:27:28 +02:00
// If stock is decremented on validate order, we must reincrement it
2023-10-08 23:25:46 +02:00
if ( isModEnabled ( 'stock' ) && getDolGlobalInt ( 'STOCK_CALCULATE_ON_VALIDATE_ORDER' ) == 1 ) {
2018-08-30 09:40:04 +02:00
$result = 0 ;
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php' ;
$langs -> load ( " agenda " );
2017-11-13 13:07:31 +01:00
2019-11-13 19:37:08 +01:00
$num = count ( $this -> lines );
2021-02-23 20:46:19 +01:00
for ( $i = 0 ; $i < $num ; $i ++ ) {
if ( $this -> lines [ $i ] -> fk_product > 0 ) {
2018-08-30 09:40:04 +02:00
$mouvP = new MouvementStock ( $this -> db );
$mouvP -> origin = & $this ;
2022-03-22 13:46:55 +01:00
$mouvP -> setOrigin ( $this -> element , $this -> id );
2018-08-30 09:40:04 +02:00
// We increment stock of product (and sub-products)
2019-11-13 19:37:08 +01:00
$result = $mouvP -> reception ( $user , $this -> lines [ $i ] -> fk_product , $idwarehouse , $this -> lines [ $i ] -> qty , 0 , $langs -> trans ( " OrderBackToDraftInDolibarr " , $this -> ref ));
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
2023-12-04 12:01:45 +01:00
$error ++ ;
$this -> error = $mouvP -> error ;
break ;
2021-02-23 20:46:19 +01:00
}
2015-04-03 11:00:52 +02:00
}
2018-08-30 09:40:04 +02:00
}
}
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
if ( ! $error ) {
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_UNVALIDATE' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
}
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> statut = self :: STATUS_DRAFT ;
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2019-11-13 19:37:08 +01:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2020-09-08 21:27:28 +02:00
}
2011-09-12 19:08:02 +02:00
2019-02-28 23:19:58 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Tag the order as validated ( opened )
* Function used when order is reopend after being closed .
*
* @ param User $user Object user that change status
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , 0 if nothing is done , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function set_reopen ( $user )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2019-11-13 19:37:08 +01:00
$error = 0 ;
2015-02-26 13:03:17 +01:00
2021-02-23 20:46:19 +01:00
if ( $this -> statut != self :: STATUS_CANCELED && $this -> statut != self :: STATUS_CLOSED ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::set_reopen order has not status closed " , LOG_WARNING );
return 0 ;
}
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2014-09-24 11:47:34 +02:00
2024-09-26 17:10:25 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table_element ;
2022-01-16 00:13:14 +01:00
$sql .= ' SET fk_statut=' . self :: STATUS_VALIDATED . ', facture=0,' ;
$sql .= " fk_user_modif = " . (( int ) $user -> id );
2021-08-27 23:36:06 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::set_reopen " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $resql ) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_REOPEN' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$error ++ ;
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror ();
2018-08-30 09:40:04 +02:00
dol_print_error ( $this -> db );
}
2011-09-12 19:08:02 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> statut = self :: STATUS_VALIDATED ;
$this -> billed = 0 ;
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::set_reopen " . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-08-30 09:40:04 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2018-08-30 09:40:04 +02:00
}
}
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
/**
* Close order
*
2024-01-14 12:26:37 +01:00
* @ param User $user Object user that close
2018-08-30 09:40:04 +02:00
* @ param int $notrigger 1 = Does not execute triggers , 0 = Execute triggers
2025-02-11 16:28:37 +01:00
* @ return int Return integer < 0 if KO , 0 = Nothing done , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function cloture ( $user , $notrigger = 0 )
2018-08-30 09:40:04 +02:00
{
2020-01-30 01:48:28 +01:00
$error = 0 ;
2015-06-01 11:24:30 +02:00
2024-02-09 15:58:49 +01:00
$usercanclose = (( ! getDolGlobalString ( 'MAIN_USE_ADVANCED_PERMS' ) && $user -> hasRight ( 'commande' , 'creer' ))
|| ( getDolGlobalString ( 'MAIN_USE_ADVANCED_PERMS' ) && $user -> hasRight ( 'commande' , 'order_advance' , 'close' )));
2015-06-01 11:24:30 +02:00
2021-02-23 20:46:19 +01:00
if ( $usercanclose ) {
if ( $this -> statut == self :: STATUS_CLOSED ) {
2020-10-23 09:56:35 +02:00
return 0 ;
}
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2011-09-12 19:08:02 +02:00
2020-01-30 01:48:28 +01:00
$now = dol_now ();
2015-10-15 12:17:57 +02:00
2019-10-16 01:20:58 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table_element ;
2020-01-30 01:48:28 +01:00
$sql .= ' SET fk_statut = ' . self :: STATUS_CLOSED . ',' ;
2021-08-27 23:36:06 +02:00
$sql .= ' fk_user_cloture = ' . (( int ) $user -> id ) . ',' ;
2022-01-16 00:13:14 +01:00
$sql .= " date_cloture = ' " . $this -> db -> idate ( $now ) . " ', " ;
$sql .= " fk_user_modif = " . (( int ) $user -> id );
2021-08-27 23:36:06 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . ' AND fk_statut > ' . self :: STATUS_DRAFT ;
2012-07-02 19:30:37 +02:00
2021-02-23 20:46:19 +01:00
if ( $this -> db -> query ( $sql )) {
if ( ! $notrigger ) {
2018-08-30 09:40:04 +02:00
// Call trigger
2020-01-30 01:48:28 +01:00
$result = $this -> call_trigger ( 'ORDER_CLOSE' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2020-01-30 01:48:28 +01:00
$this -> statut = self :: STATUS_CLOSED ;
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror ();
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
return 0 ;
}
2025-02-14 14:29:49 +01:00
/**
2024-08-26 15:45:38 +02:00
* Sets object to given categories .
2025-02-14 14:29:49 +01:00
*
* Adds it to non existing supplied categories .
2024-08-26 15:45:38 +02:00
* Deletes object from existing categories not supplied .
2025-02-14 14:29:49 +01:00
* Existing categories are left untouch .
*
2024-08-26 15:45:38 +02:00
* @ param int [] | int $categories Category ID or array of Categories IDs
*
* @ return int Return integer < 0 if KO , > 0 if OK
2025-02-14 14:29:49 +01:00
*/
public function setCategories ( $categories )
{
require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php' ;
return parent :: setCategoriesCommon ( $categories , Categorie :: TYPE_ORDER );
}
2018-08-30 09:40:04 +02:00
/**
* Cancel an order
* If stock is decremented on order validation , we must reincrement it
*
* @ param int $idwarehouse Id warehouse to use for stock change .
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function cancel ( $idwarehouse = - 1 )
2018-08-30 09:40:04 +02:00
{
2025-01-14 22:05:08 +01:00
global $user , $langs ;
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$error = 0 ;
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2024-09-26 17:10:25 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . $this -> table_element ;
2022-01-16 00:13:14 +01:00
$sql .= " SET fk_statut = " . self :: STATUS_CANCELED . " , " ;
$sql .= " fk_user_modif = " . (( int ) $user -> id );
2021-08-23 19:33:24 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2019-11-13 19:37:08 +01:00
$sql .= " AND fk_statut = " . self :: STATUS_VALIDATED ;
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::cancel " , LOG_DEBUG );
2021-02-23 20:46:19 +01:00
if ( $this -> db -> query ( $sql )) {
2018-08-30 09:40:04 +02:00
// If stock is decremented on validate order, we must reincrement it
2023-10-08 23:25:46 +02:00
if ( isModEnabled ( 'stock' ) && getDolGlobalInt ( 'STOCK_CALCULATE_ON_VALIDATE_ORDER' ) == 1 ) {
2018-08-30 09:40:04 +02:00
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php' ;
$langs -> load ( " agenda " );
2019-11-13 19:37:08 +01:00
$num = count ( $this -> lines );
2021-02-23 20:46:19 +01:00
for ( $i = 0 ; $i < $num ; $i ++ ) {
if ( $this -> lines [ $i ] -> fk_product > 0 ) {
2018-08-30 09:40:04 +02:00
$mouvP = new MouvementStock ( $this -> db );
2022-03-22 13:46:55 +01:00
$mouvP -> setOrigin ( $this -> element , $this -> id );
2018-08-30 09:40:04 +02:00
// We increment stock of product (and sub-products)
2019-11-13 19:37:08 +01:00
$result = $mouvP -> reception ( $user , $this -> lines [ $i ] -> fk_product , $idwarehouse , $this -> lines [ $i ] -> qty , 0 , $langs -> trans ( " OrderCanceledInDolibarr " , $this -> ref )); // price is 0, we don't want WAP to be changed
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
2018-08-30 09:40:04 +02:00
$error ++ ;
2019-11-13 19:37:08 +01:00
$this -> error = $mouvP -> error ;
2018-08-30 09:40:04 +02:00
break ;
}
}
}
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_CANCEL' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> statut = self :: STATUS_CANCELED ;
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::cancel " . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-08-30 09:40:04 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2018-08-30 09:40:04 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Create order
* Note that this -> ref can be set or empty . If empty , we will use " (PROV) "
*
2024-01-14 12:26:37 +01:00
* @ param User $user Object user that make creation
2018-08-30 09:40:04 +02:00
* @ param int $notrigger Disable all triggers
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function create ( $user , $notrigger = 0 )
2018-08-30 09:40:04 +02:00
{
2022-03-01 14:52:47 +01:00
global $conf , $langs , $mysoc ;
2019-11-13 19:37:08 +01:00
$error = 0 ;
2018-08-30 09:40:04 +02:00
// Clean parameters
2020-11-16 12:20:18 +01:00
// Set tmp vars
2018-08-30 09:40:04 +02:00
$date = ( $this -> date_commande ? $this -> date_commande : $this -> date );
2023-10-17 10:36:11 +02:00
$delivery_date = $this -> delivery_date ;
2018-08-30 09:40:04 +02:00
// Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
2021-02-23 20:46:19 +01:00
if ( ! empty ( $this -> multicurrency_code ) && empty ( $this -> multicurrency_tx )) {
list ( $this -> fk_multicurrency , $this -> multicurrency_tx ) = MultiCurrency :: getIdAndTxFromCode ( $this -> db , $this -> multicurrency_code , $date );
} else {
$this -> fk_multicurrency = MultiCurrency :: getIdFromCode ( $this -> db , $this -> multicurrency_code );
}
if ( empty ( $this -> fk_multicurrency )) {
2018-08-30 09:40:04 +02:00
$this -> multicurrency_code = $conf -> currency ;
$this -> fk_multicurrency = 0 ;
$this -> multicurrency_tx = 1 ;
}
2024-11-28 12:11:50 +01:00
// setEntity will set entity with the right value if empty or change it for the right value if multicompany module is active
2024-11-21 19:11:32 +01:00
$this -> entity = setEntity ( $this );
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::create user= " . $user -> id );
// Check parameters
2021-02-23 20:46:19 +01:00
if ( ! empty ( $this -> ref )) { // We check that ref is not already used
2019-11-13 19:37:08 +01:00
$result = self :: isExistingObject ( $this -> element , 0 , $this -> ref ); // Check ref is not yet used
2021-02-23 20:46:19 +01:00
if ( $result > 0 ) {
2019-11-13 19:37:08 +01:00
$this -> error = 'ErrorRefAlreadyExists' ;
2019-01-27 11:55:16 +01:00
dol_syslog ( get_class ( $this ) . " ::create " . $this -> error , LOG_WARNING );
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
$soc = new Societe ( $this -> db );
2020-01-30 01:48:28 +01:00
$result = $soc -> fetch ( $this -> socid );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
2020-01-30 01:48:28 +01:00
$this -> error = " Failed to fetch company " ;
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::create " . $this -> error , LOG_ERR );
return - 2 ;
}
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'ORDER_REQUIRE_SOURCE' ) && $this -> source < 0 ) {
2020-01-30 01:48:28 +01:00
$this -> error = $langs -> trans ( " ErrorFieldRequired " , $langs -> transnoentitiesnoconv ( " Source " ));
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::create " . $this -> error , LOG_ERR );
return - 1 ;
}
2020-01-30 01:48:28 +01:00
$now = dol_now ();
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2024-09-26 17:10:25 +02:00
$sql = " INSERT INTO " . MAIN_DB_PREFIX . $this -> table_element . " ( " ;
2022-09-23 09:35:17 +02:00
$sql .= " ref, fk_soc, date_creation, fk_user_author, fk_projet, date_commande, source, note_private, note_public, ref_ext, ref_client " ;
2021-09-29 12:05:38 +02:00
$sql .= " , model_pdf, fk_cond_reglement, deposit_percent, fk_mode_reglement, fk_account, fk_availability, fk_input_reason, date_livraison, fk_delivery_address " ;
2020-01-30 01:48:28 +01:00
$sql .= " , fk_shipping_method " ;
$sql .= " , fk_warehouse " ;
$sql .= " , fk_incoterms, location_incoterms " ;
$sql .= " , entity, module_source, pos_source " ;
$sql .= " , fk_multicurrency " ;
$sql .= " , multicurrency_code " ;
$sql .= " , multicurrency_tx " ;
$sql .= " ) " ;
2021-08-27 22:42:04 +02:00
$sql .= " VALUES ('(PROV)', " . (( int ) $this -> socid ) . " , ' " . $this -> db -> idate ( $now ) . " ', " . (( int ) $user -> id );
$sql .= " , " . ( $this -> fk_project > 0 ? (( int ) $this -> fk_project ) : " null " );
2020-01-30 01:48:28 +01:00
$sql .= " , ' " . $this -> db -> idate ( $date ) . " ' " ;
$sql .= " , " . ( $this -> source >= 0 && $this -> source != '' ? $this -> db -> escape ( $this -> source ) : 'null' );
$sql .= " , ' " . $this -> db -> escape ( $this -> note_private ) . " ' " ;
$sql .= " , ' " . $this -> db -> escape ( $this -> note_public ) . " ' " ;
$sql .= " , " . ( $this -> ref_ext ? " ' " . $this -> db -> escape ( $this -> ref_ext ) . " ' " : " null " );
$sql .= " , " . ( $this -> ref_client ? " ' " . $this -> db -> escape ( $this -> ref_client ) . " ' " : " null " );
2020-09-10 01:49:09 +02:00
$sql .= " , ' " . $this -> db -> escape ( $this -> model_pdf ) . " ' " ;
2021-08-27 22:42:04 +02:00
$sql .= " , " . ( $this -> cond_reglement_id > 0 ? (( int ) $this -> cond_reglement_id ) : " null " );
2022-08-31 22:14:20 +02:00
$sql .= " , " . ( ! empty ( $this -> deposit_percent ) ? " ' " . $this -> db -> escape ( $this -> deposit_percent ) . " ' " : " null " );
2021-08-27 22:42:04 +02:00
$sql .= " , " . ( $this -> mode_reglement_id > 0 ? (( int ) $this -> mode_reglement_id ) : " null " );
$sql .= " , " . ( $this -> fk_account > 0 ? (( int ) $this -> fk_account ) : 'NULL' );
$sql .= " , " . ( $this -> availability_id > 0 ? (( int ) $this -> availability_id ) : " null " );
$sql .= " , " . ( $this -> demand_reason_id > 0 ? (( int ) $this -> demand_reason_id ) : " null " );
2020-11-16 12:56:13 +01:00
$sql .= " , " . ( $delivery_date ? " ' " . $this -> db -> idate ( $delivery_date ) . " ' " : " null " );
2021-08-27 22:42:04 +02:00
$sql .= " , " . ( $this -> fk_delivery_address > 0 ? (( int ) $this -> fk_delivery_address ) : 'NULL' );
$sql .= " , " . ( ! empty ( $this -> shipping_method_id ) && $this -> shipping_method_id > 0 ? (( int ) $this -> shipping_method_id ) : 'NULL' );
$sql .= " , " . ( ! empty ( $this -> warehouse_id ) && $this -> warehouse_id > 0 ? (( int ) $this -> warehouse_id ) : 'NULL' );
2020-01-30 01:48:28 +01:00
$sql .= " , " . ( int ) $this -> fk_incoterms ;
$sql .= " , ' " . $this -> db -> escape ( $this -> location_incoterms ) . " ' " ;
2024-11-21 19:11:32 +01:00
$sql .= " , " . ( int ) $this -> entity ;
2020-09-08 21:27:28 +02:00
$sql .= " , " . ( $this -> module_source ? " ' " . $this -> db -> escape ( $this -> module_source ) . " ' " : " null " );
2020-01-30 01:48:28 +01:00
$sql .= " , " . ( $this -> pos_source != '' ? " ' " . $this -> db -> escape ( $this -> pos_source ) . " ' " : " null " );
$sql .= " , " . ( int ) $this -> fk_multicurrency ;
$sql .= " , ' " . $this -> db -> escape ( $this -> multicurrency_code ) . " ' " ;
2021-08-27 22:42:04 +02:00
$sql .= " , " . ( float ) $this -> multicurrency_tx ;
2020-01-30 01:48:28 +01:00
$sql .= " ) " ;
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::create " , LOG_DEBUG );
2020-01-30 01:48:28 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $resql ) {
2018-08-30 09:40:04 +02:00
$this -> id = $this -> db -> last_insert_id ( MAIN_DB_PREFIX . 'commande' );
2021-02-23 20:46:19 +01:00
if ( $this -> id ) {
2020-01-30 01:48:28 +01:00
$fk_parent_line = 0 ;
$num = count ( $this -> lines );
2018-08-30 09:40:04 +02:00
/*
* Insert products details into db
*/
2021-02-23 20:46:19 +01:00
for ( $i = 0 ; $i < $num ; $i ++ ) {
2018-08-30 09:40:04 +02:00
$line = $this -> lines [ $i ];
// Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array
//if (! is_object($line)) $line=json_decode(json_encode($line), false); // convert recursively array into object.
2021-02-23 20:46:19 +01:00
if ( ! is_object ( $line )) {
$line = ( object ) $line ;
}
2018-08-30 09:40:04 +02:00
// Reset fk_parent_line for no child products and special product
if (( $line -> product_type != 9 && empty ( $line -> fk_parent_line )) || $line -> product_type == 9 ) {
$fk_parent_line = 0 ;
}
// Complete vat rate with code
$vatrate = $line -> tva_tx ;
2024-03-19 15:12:22 +01:00
if ( $line -> vat_src_code && ! preg_match ( '/\(.*\)/' , ( string ) $vatrate )) {
2021-02-23 20:46:19 +01:00
$vatrate .= ' (' . $line -> vat_src_code . ')' ;
}
2018-08-30 09:40:04 +02:00
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION' )) {
2020-04-10 10:59:32 +02:00
$originid = $line -> origin_id ;
$origintype = $line -> origin ;
2020-03-12 09:44:43 +01:00
} else {
2020-04-10 10:59:32 +02:00
$originid = $line -> id ;
$origintype = $this -> element ;
2020-03-12 09:44:43 +01:00
}
2018-08-30 09:40:04 +02:00
2020-09-04 21:11:58 +02:00
// ref_ext
if ( empty ( $line -> ref_ext )) {
$line -> ref_ext = '' ;
}
2020-03-12 09:44:43 +01:00
2020-09-08 21:27:28 +02:00
$result = $this -> addline (
2018-08-30 09:40:04 +02:00
$line -> desc ,
$line -> subprice ,
$line -> qty ,
$vatrate ,
$line -> localtax1_tx ,
$line -> localtax2_tx ,
$line -> fk_product ,
$line -> remise_percent ,
$line -> info_bits ,
$line -> fk_remise_except ,
'HT' ,
0 ,
$line -> date_start ,
$line -> date_end ,
$line -> product_type ,
$line -> rang ,
$line -> special_code ,
$fk_parent_line ,
$line -> fk_fournprice ,
$line -> pa_ht ,
$line -> label ,
$line -> array_options ,
$line -> fk_unit ,
2020-09-08 21:27:28 +02:00
$origintype ,
$originid ,
2020-09-04 21:26:57 +02:00
0 ,
2022-03-01 14:52:47 +01:00
$line -> ref_ext ,
1
2018-08-30 10:42:47 +02:00
);
2025-02-10 18:09:32 +01:00
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
if ( $result != self :: STOCK_NOT_ENOUGH_FOR_ORDER ) {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror ();
2020-01-19 12:15:47 +01:00
$this -> errors [] = $this -> error ;
2018-08-30 09:40:04 +02:00
dol_print_error ( $this -> db );
}
$this -> db -> rollback ();
return - 1 ;
}
// Defined the new fk_parent_line
2022-09-13 15:12:31 +02:00
if ( $result > 0 && $line -> product_type == 9 ) {
2018-08-30 09:40:04 +02:00
$fk_parent_line = $result ;
}
}
2022-03-01 14:52:47 +01:00
$result = $this -> update_price ( 1 , 'auto' , 0 , $mysoc ); // This method is designed to add line from user input so total calculation must be done using 'auto' mode.
2018-08-30 09:40:04 +02:00
// update ref
2019-11-13 19:37:08 +01:00
$initialref = '(PROV' . $this -> id . ')' ;
2021-02-23 20:46:19 +01:00
if ( ! empty ( $this -> ref )) {
$initialref = $this -> ref ;
}
2018-08-30 09:40:04 +02:00
2024-09-26 17:10:25 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table_element . " SET ref=' " . $this -> db -> escape ( $initialref ) . " ' WHERE rowid= " . (( int ) $this -> id );
2021-02-23 20:46:19 +01:00
if ( $this -> db -> query ( $sql )) {
2019-11-24 18:25:55 +01:00
$this -> ref = $initialref ;
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( ! empty ( $this -> linkedObjectsIds ) && empty ( $this -> linked_objects )) { // To use new linkedObjectsIds instead of old linked_objects
2019-11-24 18:25:55 +01:00
$this -> linked_objects = $this -> linkedObjectsIds ; // TODO Replace linked_objects with linkedObjectsIds
}
2018-08-30 09:40:04 +02:00
2019-11-24 18:25:55 +01:00
// Add object linked
2021-02-23 20:46:19 +01:00
if ( ! $error && $this -> id && ! empty ( $this -> linked_objects ) && is_array ( $this -> linked_objects )) {
foreach ( $this -> linked_objects as $origin => $tmp_origin_id ) {
if ( is_array ( $tmp_origin_id )) { // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
foreach ( $tmp_origin_id as $origin_id ) {
2018-08-30 09:40:04 +02:00
$ret = $this -> add_object_linked ( $origin , $origin_id );
2021-02-23 20:46:19 +01:00
if ( ! $ret ) {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror ();
2018-08-30 09:40:04 +02:00
$error ++ ;
}
2018-08-30 10:30:52 +02:00
}
2023-12-04 12:01:45 +01:00
} else { // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
2019-11-24 18:25:55 +01:00
$origin_id = $tmp_origin_id ;
$ret = $this -> add_object_linked ( $origin , $origin_id );
2021-02-23 20:46:19 +01:00
if ( ! $ret ) {
2019-11-24 18:25:55 +01:00
$this -> error = $this -> db -> lasterror ();
$error ++ ;
}
2018-08-30 09:40:04 +02:00
}
}
2019-11-24 18:25:55 +01:00
}
2018-08-30 09:40:04 +02:00
2023-11-27 11:39:32 +01:00
if ( ! $error && $this -> id && getDolGlobalString ( 'MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN' ) && ! empty ( $this -> origin ) && ! empty ( $this -> origin_id )) { // Get contact from origin object
2019-11-24 18:25:55 +01:00
$originforcontact = $this -> origin ;
$originidforcontact = $this -> origin_id ;
2021-02-23 20:46:19 +01:00
if ( $originforcontact == 'shipping' ) { // shipment and order share the same contacts. If creating from shipment we take data of order
2019-11-24 18:25:55 +01:00
require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php' ;
$exp = new Expedition ( $this -> db );
$exp -> fetch ( $this -> origin_id );
$exp -> fetchObjectLinked ();
2021-02-23 20:46:19 +01:00
if ( count ( $exp -> linkedObjectsIds [ 'commande' ]) > 0 ) {
foreach ( $exp -> linkedObjectsIds [ 'commande' ] as $key => $value ) {
2019-11-24 18:25:55 +01:00
$originforcontact = 'commande' ;
2021-02-23 20:46:19 +01:00
if ( is_object ( $value )) {
$originidforcontact = $value -> id ;
} else {
$originidforcontact = $value ;
2018-08-30 09:40:04 +02:00
}
2019-11-24 18:25:55 +01:00
break ; // We take first one
2018-08-30 09:40:04 +02:00
}
}
2019-11-24 18:25:55 +01:00
}
2018-08-30 09:40:04 +02:00
2019-11-24 18:25:55 +01:00
$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 " ;
2021-03-30 17:53:25 +02:00
$sqlcontact .= " WHERE element_id = " . (( int ) $originidforcontact ) . " AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = ' " . $this -> db -> escape ( $originforcontact ) . " ' " ;
2018-08-30 09:40:04 +02:00
2019-11-24 18:25:55 +01:00
$resqlcontact = $this -> db -> query ( $sqlcontact );
2021-02-23 20:46:19 +01:00
if ( $resqlcontact ) {
while ( $objcontact = $this -> db -> fetch_object ( $resqlcontact )) {
2019-11-24 18:25:55 +01:00
//print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n";
$this -> add_contact ( $objcontact -> fk_socpeople , $objcontact -> code , $objcontact -> source ); // May failed because of duplicate key or because code of contact type does not exists for new object
2018-08-30 09:40:04 +02:00
}
2021-02-23 20:46:19 +01:00
} else {
2024-09-20 17:25:39 +02:00
dol_print_error ( $this -> db );
2018-08-30 09:40:04 +02:00
}
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$result = $this -> insertExtraFields ();
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
}
2021-02-23 20:46:19 +01:00
if ( ! $error && ! $notrigger ) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_CREATE' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return $this -> id ;
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2018-08-30 09:40:04 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror ();
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
2023-01-06 19:24:57 +01:00
return 0 ;
2020-05-21 15:05:19 +02:00
} else {
2023-11-19 14:56:25 +01:00
$this -> error = $this -> db -> lasterror ();
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Load an object from its id and create a new one in database
*
2019-04-25 12:11:32 +02:00
* @ param User $user User making the clone
* @ param int $socid Id of thirdparty
* @ return int New id of clone
2018-08-30 09:40:04 +02:00
*/
2019-04-25 12:11:32 +02:00
public function createFromClone ( User $user , $socid = 0 )
2018-08-30 09:40:04 +02:00
{
2025-01-19 17:38:34 +01:00
global $user , $hookmanager ;
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$error = 0 ;
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
// get lines so they will be clone
2021-02-23 20:46:19 +01:00
foreach ( $this -> lines as $line ) {
2018-08-30 09:40:04 +02:00
$line -> fetch_optionals ();
2021-02-23 20:46:19 +01:00
}
2018-08-30 09:40:04 +02:00
2019-03-27 10:09:45 +01:00
// Load source object
$objFrom = clone $this ;
2018-08-30 10:30:52 +02:00
2019-03-27 10:09:45 +01:00
// Change socid if needed
2021-02-23 20:46:19 +01:00
if ( ! empty ( $socid ) && $socid != $this -> socid ) {
2019-03-27 10:09:45 +01:00
$objsoc = new Societe ( $this -> db );
2018-08-30 10:30:52 +02:00
2021-02-23 20:46:19 +01:00
if ( $objsoc -> fetch ( $socid ) > 0 ) {
2019-11-13 19:37:08 +01:00
$this -> socid = $objsoc -> id ;
$this -> cond_reglement_id = ( ! empty ( $objsoc -> cond_reglement_id ) ? $objsoc -> cond_reglement_id : 0 );
2024-02-19 15:31:22 +01:00
$this -> deposit_percent = ( ! empty ( $objsoc -> deposit_percent ) ? $objsoc -> deposit_percent : 0 );
2019-11-13 19:37:08 +01:00
$this -> mode_reglement_id = ( ! empty ( $objsoc -> mode_reglement_id ) ? $objsoc -> mode_reglement_id : 0 );
$this -> fk_project = 0 ;
$this -> fk_delivery_address = 0 ;
2018-08-30 09:40:04 +02:00
}
2019-03-27 10:09:45 +01:00
// TODO Change product price if multi-prices
}
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$this -> id = 0 ;
2019-03-27 10:09:45 +01:00
$this -> ref = '' ;
2019-11-13 19:37:08 +01:00
$this -> statut = self :: STATUS_DRAFT ;
2018-08-30 09:40:04 +02:00
2019-03-27 10:09:45 +01:00
// Clear fields
$this -> user_author_id = $user -> id ;
2022-07-03 12:54:58 +02:00
$this -> user_validation_id = 0 ;
2019-11-13 19:37:08 +01:00
$this -> date = dol_now ();
$this -> date_commande = dol_now ();
2019-03-27 10:09:45 +01:00
$this -> date_creation = '' ;
$this -> date_validation = '' ;
2023-11-27 11:39:32 +01:00
if ( ! getDolGlobalString ( 'MAIN_KEEP_REF_CUSTOMER_ON_CLONING' )) {
2021-02-23 20:46:19 +01:00
$this -> ref_client = '' ;
2023-05-01 13:09:09 +02:00
$this -> ref_customer = '' ;
2021-02-23 20:46:19 +01:00
}
2020-09-04 21:38:49 +02:00
2020-09-04 21:11:58 +02:00
// Do not clone ref_ext
$num = count ( $this -> lines );
2021-02-23 20:46:19 +01:00
for ( $i = 0 ; $i < $num ; $i ++ ) {
2020-09-04 21:11:58 +02:00
$this -> lines [ $i ] -> ref_ext = '' ;
}
2018-08-30 10:30:52 +02:00
2019-03-27 10:09:45 +01:00
// Create clone
$this -> context [ 'createfromclone' ] = 'createfromclone' ;
2019-11-13 19:37:08 +01:00
$result = $this -> create ( $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 10:30:52 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-03-27 10:09:45 +01:00
// copy internal contacts
2021-02-23 20:46:19 +01:00
if ( $this -> copy_linked_contact ( $objFrom , 'internal' ) < 0 ) {
2019-03-27 10:09:45 +01:00
$error ++ ;
2018-08-30 09:40:04 +02:00
}
2019-03-27 10:09:45 +01:00
}
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-03-27 10:09:45 +01:00
// copy external contacts if same company
2021-02-23 20:46:19 +01:00
if ( $this -> socid == $objFrom -> socid ) {
if ( $this -> copy_linked_contact ( $objFrom , 'external' ) < 0 ) {
2019-03-27 10:09:45 +01:00
$error ++ ;
2021-02-23 20:46:19 +01:00
}
2018-08-30 10:30:52 +02:00
}
2019-03-27 10:09:45 +01:00
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-03-27 10:09:45 +01:00
// Hook of thirdparty module
2021-02-23 20:46:19 +01:00
if ( is_object ( $hookmanager )) {
2024-02-28 23:01:01 +01:00
$parameters = array ( 'objFrom' => $objFrom );
2019-11-13 19:37:08 +01:00
$action = '' ;
$reshook = $hookmanager -> executeHooks ( 'createFrom' , $parameters , $this , $action ); // Note that $action and $object may have been modified by some hooks
2021-02-23 20:46:19 +01:00
if ( $reshook < 0 ) {
2023-02-24 16:57:39 +01:00
$this -> setErrorsFromObject ( $hookmanager );
2021-02-23 20:46:19 +01:00
$error ++ ;
}
2018-08-30 10:30:52 +02:00
}
2019-03-27 10:09:45 +01:00
}
unset ( $this -> context [ 'createfromclone' ]);
// End
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-03-27 10:09:45 +01:00
$this -> db -> commit ();
return $this -> id ;
2020-05-21 15:05:19 +02:00
} else {
2019-03-27 10:09:45 +01:00
$this -> db -> rollback ();
return - 1 ;
}
2018-08-30 09:40:04 +02:00
}
/**
* Load an object from a proposal and create a new order into database
*
2024-09-30 10:05:24 +02:00
* @ param Propal $object Object source
2018-08-30 09:40:04 +02:00
* @ param User $user User making creation
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , 0 if nothing done , 1 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function createFromProposal ( $object , User $user )
2018-08-30 09:40:04 +02:00
{
global $conf , $hookmanager ;
2024-03-13 18:20:41 +01:00
require_once DOL_DOCUMENT_ROOT . '/multicurrency/class/multicurrency.class.php' ;
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php' ;
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$error = 0 ;
2018-08-30 09:40:04 +02:00
$this -> date_commande = dol_now ();
2023-08-06 01:14:36 +02:00
$this -> date = dol_now ();
2018-08-30 09:40:04 +02:00
$this -> source = 0 ;
2019-11-13 19:37:08 +01:00
$num = count ( $object -> lines );
2021-02-23 20:46:19 +01:00
for ( $i = 0 ; $i < $num ; $i ++ ) {
2018-08-30 09:40:04 +02:00
$line = new OrderLine ( $this -> db );
$line -> libelle = $object -> lines [ $i ] -> libelle ;
$line -> label = $object -> lines [ $i ] -> label ;
$line -> desc = $object -> lines [ $i ] -> desc ;
$line -> price = $object -> lines [ $i ] -> price ;
$line -> subprice = $object -> lines [ $i ] -> subprice ;
$line -> vat_src_code = $object -> lines [ $i ] -> vat_src_code ;
$line -> tva_tx = $object -> lines [ $i ] -> tva_tx ;
$line -> localtax1_tx = $object -> lines [ $i ] -> localtax1_tx ;
$line -> localtax2_tx = $object -> lines [ $i ] -> localtax2_tx ;
$line -> qty = $object -> lines [ $i ] -> qty ;
$line -> fk_remise_except = $object -> lines [ $i ] -> fk_remise_except ;
$line -> remise_percent = $object -> lines [ $i ] -> remise_percent ;
$line -> fk_product = $object -> lines [ $i ] -> fk_product ;
$line -> info_bits = $object -> lines [ $i ] -> info_bits ;
$line -> product_type = $object -> lines [ $i ] -> product_type ;
$line -> rang = $object -> lines [ $i ] -> rang ;
$line -> special_code = $object -> lines [ $i ] -> special_code ;
$line -> fk_parent_line = $object -> lines [ $i ] -> fk_parent_line ;
2019-11-13 19:37:08 +01:00
$line -> fk_unit = $object -> lines [ $i ] -> fk_unit ;
2018-08-30 09:40:04 +02:00
2023-08-06 01:14:36 +02:00
$line -> date_start = $object -> lines [ $i ] -> date_start ;
2018-08-30 09:40:04 +02:00
$line -> date_end = $object -> lines [ $i ] -> date_end ;
$line -> fk_fournprice = $object -> lines [ $i ] -> fk_fournprice ;
$marginInfos = getMarginInfos ( $object -> lines [ $i ] -> subprice , $object -> lines [ $i ] -> remise_percent , $object -> lines [ $i ] -> tva_tx , $object -> lines [ $i ] -> localtax1_tx , $object -> lines [ $i ] -> localtax2_tx , $object -> lines [ $i ] -> fk_fournprice , $object -> lines [ $i ] -> pa_ht );
$line -> pa_ht = $marginInfos [ 0 ];
$line -> marge_tx = $marginInfos [ 1 ];
$line -> marque_tx = $marginInfos [ 2 ];
2023-04-23 14:01:52 +02:00
$line -> origin = $object -> element ;
$line -> origin_id = $object -> lines [ $i ] -> id ;
2018-08-30 09:40:04 +02:00
// get extrafields from original line
2018-02-21 14:48:25 +01:00
$object -> lines [ $i ] -> fetch_optionals ();
2021-02-23 20:46:19 +01:00
foreach ( $object -> lines [ $i ] -> array_options as $options_key => $value ) {
2015-10-15 12:17:57 +02:00
$line -> array_options [ $options_key ] = $value ;
2021-02-23 20:46:19 +01:00
}
2014-11-12 17:51:26 +01:00
2023-12-04 12:01:45 +01:00
$this -> lines [ $i ] = $line ;
2018-08-30 09:40:04 +02:00
}
2019-05-12 14:25:41 +02:00
$this -> entity = $object -> entity ;
2018-08-30 09:40:04 +02:00
$this -> socid = $object -> socid ;
$this -> fk_project = $object -> fk_project ;
$this -> cond_reglement_id = $object -> cond_reglement_id ;
2021-09-29 12:05:38 +02:00
$this -> deposit_percent = $object -> deposit_percent ;
2018-08-30 09:40:04 +02:00
$this -> mode_reglement_id = $object -> mode_reglement_id ;
$this -> fk_account = $object -> fk_account ;
$this -> availability_id = $object -> availability_id ;
$this -> demand_reason_id = $object -> demand_reason_id ;
2023-10-17 10:36:11 +02:00
$this -> delivery_date = $object -> delivery_date ;
2018-08-30 09:40:04 +02:00
$this -> shipping_method_id = $object -> shipping_method_id ;
$this -> warehouse_id = $object -> warehouse_id ;
$this -> fk_delivery_address = $object -> fk_delivery_address ;
2023-10-17 10:36:11 +02:00
$this -> contact_id = $object -> contact_id ;
2018-08-30 09:40:04 +02:00
$this -> ref_client = $object -> ref_client ;
2023-05-01 13:09:09 +02:00
$this -> ref_customer = $object -> ref_client ;
2019-03-18 20:09:09 +01:00
2023-11-27 11:39:32 +01:00
if ( ! getDolGlobalString ( 'MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN' )) {
2020-09-08 21:27:28 +02:00
$this -> note_private = $object -> note_private ;
$this -> note_public = $object -> note_public ;
2019-03-18 20:09:09 +01:00
}
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$this -> origin = $object -> element ;
$this -> origin_id = $object -> id ;
2018-08-30 09:40:04 +02:00
2023-12-04 12:01:45 +01:00
// Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
2024-10-07 14:40:29 +02:00
if ( isModEnabled ( 'multicurrency' )) {
2022-12-21 10:55:03 +01:00
if ( ! empty ( $object -> multicurrency_code )) {
$this -> multicurrency_code = $object -> multicurrency_code ;
}
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'MULTICURRENCY_USE_ORIGIN_TX' ) && ! empty ( $object -> multicurrency_tx )) {
2022-12-21 10:55:03 +01:00
$this -> multicurrency_tx = $object -> multicurrency_tx ;
}
2022-12-21 11:00:26 +01:00
if ( ! empty ( $this -> multicurrency_code ) && empty ( $this -> multicurrency_tx )) {
2023-12-04 12:01:45 +01:00
$tmparray = MultiCurrency :: getIdAndTxFromCode ( $this -> db , $this -> multicurrency_code , $this -> date_commande );
$this -> fk_multicurrency = $tmparray [ 0 ];
$this -> multicurrency_tx = $tmparray [ 1 ];
2022-12-21 11:00:26 +01:00
} else {
2023-12-04 12:01:45 +01:00
$this -> fk_multicurrency = MultiCurrency :: getIdFromCode ( $this -> db , $this -> multicurrency_code );
2022-12-21 11:00:26 +01:00
}
if ( empty ( $this -> fk_multicurrency )) {
2023-12-04 12:01:45 +01:00
$this -> multicurrency_code = $conf -> currency ;
$this -> fk_multicurrency = 0 ;
$this -> multicurrency_tx = 1 ;
2022-12-21 11:00:26 +01:00
}
2022-12-21 10:55:03 +01:00
}
2018-08-30 09:40:04 +02:00
// get extrafields from original line
2020-03-27 16:02:58 +01:00
$object -> fetch_optionals ();
2018-08-30 09:40:04 +02:00
$e = new ExtraFields ( $this -> db );
2019-09-28 10:55:09 +02:00
$element_extrafields = $e -> fetch_name_optionals_label ( $this -> table_element );
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
foreach ( $object -> array_options as $options_key => $value ) {
if ( array_key_exists ( str_replace ( 'options_' , '' , $options_key ), $element_extrafields )) {
2018-08-30 09:40:04 +02:00
$this -> array_options [ $options_key ] = $value ;
}
}
// Possibility to add external linked objects with hooks
$this -> linked_objects [ $this -> origin ] = $this -> origin_id ;
2021-06-29 16:30:36 +02:00
if ( isset ( $object -> other_linked_objects ) && is_array ( $object -> other_linked_objects ) && ! empty ( $object -> other_linked_objects )) {
2018-08-30 10:30:52 +02:00
$this -> linked_objects = array_merge ( $this -> linked_objects , $object -> other_linked_objects );
2018-08-30 09:40:04 +02:00
}
$ret = $this -> create ( $user );
2021-02-23 20:46:19 +01:00
if ( $ret > 0 ) {
2018-08-30 09:40:04 +02:00
// Actions hooked (by external module)
$hookmanager -> initHooks ( array ( 'orderdao' ));
2024-02-28 23:01:01 +01:00
$parameters = array ( 'objFrom' => $object );
2019-11-13 19:37:08 +01:00
$action = '' ;
$reshook = $hookmanager -> executeHooks ( 'createFrom' , $parameters , $this , $action ); // Note that $action and $object may have been modified by some hooks
2021-02-23 20:46:19 +01:00
if ( $reshook < 0 ) {
2023-02-24 16:57:39 +01:00
$this -> setErrorsFromObject ( $hookmanager );
2021-02-23 20:46:19 +01:00
$error ++ ;
}
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2024-01-14 12:26:37 +01:00
// Validate immediately the order
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'ORDER_VALID_AFTER_CLOSE_PROPAL' )) {
2018-08-30 09:40:04 +02:00
$this -> fetch ( $ret );
$this -> valid ( $user );
}
return $ret ;
2021-02-23 20:46:19 +01:00
} else {
return - 1 ;
2018-08-30 09:40:04 +02:00
}
2021-02-23 20:46:19 +01:00
} else {
return - 1 ;
2018-08-30 09:40:04 +02:00
}
}
/**
* Add an order line into database ( linked to product / service or not )
*
* @ param string $desc Description of line
* @ param float $pu_ht Unit price ( without tax )
* @ param float $qty Quantite
* @ param float $txtva Force Vat rate , - 1 for auto ( Can contain the vat_src_code too with syntax '9.9 (CODE)' )
* @ param float $txlocaltax1 Local tax 1 rate ( deprecated , use instead txtva with code inside )
* @ param float $txlocaltax2 Local tax 2 rate ( deprecated , use instead txtva with code inside )
* @ param int $fk_product Id of product
2019-03-18 13:45:24 +01:00
* @ param float $remise_percent Percentage discount of the line
2019-06-29 16:29:32 +02:00
* @ param int $info_bits Bits of type of lines
2018-08-30 09:40:04 +02:00
* @ param int $fk_remise_except Id remise
* @ param string $price_base_type HT or TTC
* @ param float $pu_ttc Prix unitaire TTC
2023-12-20 14:22:45 +01:00
* @ param int | string $date_start Start date of the line - Added by Matelli ( See http :// matelli . fr / showcases / patchs - dolibarr / add - dates - in - order - lines . html )
* @ param int | string $date_end End date of the line - Added by Matelli ( See http :// matelli . fr / showcases / patchs - dolibarr / add - dates - in - order - lines . html )
2018-08-30 09:40:04 +02:00
* @ param int $type Type of line ( 0 = product , 1 = service ) . Not used if fk_product is defined , the type of product is used .
* @ param int $rang Position of line
* @ param int $special_code Special code ( also used by externals modules ! )
* @ param int $fk_parent_line Parent line
* @ param int $fk_fournprice Id supplier price
* @ param int $pa_ht Buying price ( without tax )
* @ param string $label Label
2024-09-30 10:05:24 +02:00
* @ param array < string , mixed > $array_options extrafields array . Example array ( 'options_codeforfield1' => 'valueforfield1' , 'options_codeforfield2' => 'valueforfield2' , ... )
* @ param ? int $fk_unit Code of the unit to use . Null to use the default one
2020-03-12 09:44:43 +01:00
* @ param string $origin Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be 'orderdet' , 'propaldet' ... , else 'order' , 'propal,' ....
* @ param int $origin_id Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be Id of origin object ( aka line id ), else object id
2024-09-30 10:05:24 +02:00
* @ param float $pu_ht_devise Unit price in currency
2020-09-04 21:11:58 +02:00
* @ param string $ref_ext line external reference
2022-03-01 14:52:47 +01:00
* @ param int $noupdateafterinsertline No update after insert of line
2018-08-30 09:40:04 +02:00
* @ return int > 0 if OK , < 0 if KO
*
2019-04-08 16:04:15 +02:00
* @ see add_product ()
2018-08-30 09:40:04 +02:00
*
2024-01-14 12:26:37 +01:00
* Les parameters sont deja cense etre juste et avec valeurs finales a l ' appel
2018-08-30 09:40:04 +02:00
* de cette methode . Aussi , pour le taux tva , il doit deja avoir ete defini
* par l ' appelant par la methode get_default_tva ( societe_vendeuse , societe_acheteuse , produit )
* et le desc doit deja avoir la bonne valeur ( a l ' appelant de gerer le multilangue )
*/
2023-12-20 14:22:45 +01:00
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 )
2018-08-30 09:40:04 +02:00
{
2025-01-19 17:38:34 +01:00
global $mysoc , $langs , $user ;
2018-08-30 09:40:04 +02:00
$logtext = " ::addline commandeid= $this->id , desc= $desc , pu_ht= $pu_ht , qty= $qty , txtva= $txtva , fk_product= $fk_product , remise_percent= $remise_percent " ;
2019-11-13 19:37:08 +01:00
$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 " ;
2025-02-10 18:09:32 +01:00
$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 " ;
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . $logtext , LOG_DEBUG );
2021-02-23 20:46:19 +01:00
if ( $this -> statut == self :: STATUS_DRAFT ) {
2018-12-04 14:58:11 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php' ;
2011-09-12 19:08:02 +02:00
2018-12-04 14:58:11 +01:00
// Clean parameters
2020-09-04 21:38:49 +02:00
2021-02-23 20:46:19 +01:00
if ( empty ( $remise_percent )) {
$remise_percent = 0 ;
}
if ( empty ( $qty )) {
$qty = 0 ;
}
if ( empty ( $info_bits )) {
$info_bits = 0 ;
}
if ( empty ( $rang )) {
$rang = 0 ;
}
if ( empty ( $txtva )) {
$txtva = 0 ;
}
if ( empty ( $txlocaltax1 )) {
$txlocaltax1 = 0 ;
}
if ( empty ( $txlocaltax2 )) {
$txlocaltax2 = 0 ;
}
if ( empty ( $fk_parent_line ) || $fk_parent_line < 0 ) {
$fk_parent_line = 0 ;
}
if ( empty ( $this -> fk_multicurrency )) {
$this -> fk_multicurrency = 0 ;
}
if ( empty ( $ref_ext )) {
$ref_ext = '' ;
}
2019-11-13 19:37:08 +01:00
2024-01-23 16:07:59 +01:00
$remise_percent = ( float ) price2num ( $remise_percent );
$qty = ( float ) price2num ( $qty );
2019-11-13 19:37:08 +01:00
$pu_ht = price2num ( $pu_ht );
$pu_ht_devise = price2num ( $pu_ht_devise );
$pu_ttc = price2num ( $pu_ttc );
2025-01-04 22:44:57 +01:00
$pa_ht = price2num ( $pa_ht ); // do not convert to float here, it breaks the functioning of $pa_ht_isemptystring
2024-03-19 15:12:22 +01:00
if ( ! preg_match ( '/\((.*)\)/' , ( string ) $txtva )) {
2019-11-13 19:37:08 +01:00
$txtva = price2num ( $txtva ); // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1'
2018-12-04 14:58:11 +01:00
}
$txlocaltax1 = price2num ( $txlocaltax1 );
$txlocaltax2 = price2num ( $txlocaltax2 );
2021-02-23 20:46:19 +01:00
if ( $price_base_type == 'HT' ) {
2019-11-13 19:37:08 +01:00
$pu = $pu_ht ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$pu = $pu_ttc ;
2018-12-04 14:58:11 +01:00
}
2019-11-13 19:37:08 +01:00
$label = trim ( $label );
$desc = trim ( $desc );
2018-08-30 09:40:04 +02:00
2018-12-04 14:58:11 +01:00
// Check parameters
2021-02-23 20:46:19 +01:00
if ( $type < 0 ) {
return - 1 ;
}
2019-03-27 12:05:42 +01:00
2019-03-24 14:30:00 +01:00
if ( $date_start && $date_end && $date_start > $date_end ) {
$langs -> load ( " errors " );
2019-11-13 19:37:08 +01:00
$this -> error = $langs -> trans ( 'ErrorStartDateGreaterEnd' );
2019-03-24 14:30:00 +01:00
return - 1 ;
}
2018-08-30 09:40:04 +02:00
2020-09-08 21:27:28 +02:00
$this -> db -> begin ();
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$product_type = $type ;
2021-07-04 21:02:02 +02:00
if ( ! empty ( $fk_product ) && $fk_product > 0 ) {
2019-11-13 19:37:08 +01:00
$product = new Product ( $this -> db );
$result = $product -> fetch ( $fk_product );
$product_type = $product -> type ;
2018-08-30 09:40:04 +02:00
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'STOCK_MUST_BE_ENOUGH_FOR_ORDER' ) && $product_type == 0 && $product -> stock_reel < $qty ) {
2018-08-30 09:40:04 +02:00
$langs -> load ( " errors " );
2019-11-13 19:37:08 +01:00
$this -> error = $langs -> trans ( 'ErrorStockIsNotEnoughToAddProductOnOrder' , $product -> ref );
2020-01-19 12:15:47 +01:00
$this -> errors [] = $this -> error ;
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::addline error=Product " . $product -> ref . " : " . $this -> error , LOG_ERR );
$this -> db -> rollback ();
return self :: STOCK_NOT_ENOUGH_FOR_ORDER ;
}
}
// Calcul du total TTC et de la TVA pour la ligne a partir de
// qty, pu, remise_percent et txtva
// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
2019-11-13 19:37:08 +01:00
$localtaxes_type = getLocalTaxesFromRate ( $txtva , 0 , $this -> thirdparty , $mysoc );
2018-08-30 09:40:04 +02:00
2025-01-20 12:50:09 +01:00
if ( getDolGlobalString ( 'PRODUCT_USE_CUSTOMER_PACKAGING' )) {
2025-01-29 19:15:57 +01:00
$tmpproduct = new Product ( $this -> db );
$result = $tmpproduct -> fetch ( $fk_product );
if ( abs ( $qty ) < $tmpproduct -> packaging ) {
$qty = ( float ) $tmpproduct -> packaging ;
2025-01-20 12:50:09 +01:00
} else {
2025-01-29 19:15:57 +01:00
if ( ! empty ( $tmpproduct -> packaging ) && $qty > $tmpproduct -> packaging ) {
$coeff = intval ( abs ( $qty ) / $tmpproduct -> packaging ) + 1 ;
$qty = price2num (( float ) $tmpproduct -> packaging * $coeff , 'MS' );
2025-01-20 12:50:09 +01:00
setEventMessages ( $langs -> trans ( 'QtyRecalculatedWithPackaging' ), null , 'mesgs' );
}
}
}
2018-08-30 10:30:52 +02:00
// Clean vat code
2020-01-13 15:58:03 +01:00
$reg = array ();
2019-11-13 19:37:08 +01:00
$vat_src_code = '' ;
2021-02-23 20:46:19 +01:00
if ( preg_match ( '/\((.*)\)/' , $txtva , $reg )) {
2018-08-30 09:40:04 +02:00
$vat_src_code = $reg [ 1 ];
2019-11-13 19:37:08 +01:00
$txtva = preg_replace ( '/\s*\(.*\)/' , '' , $txtva ); // Remove code into vatrate.
2018-08-30 09:40:04 +02:00
}
$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 );
/* var_dump ( $txlocaltax1 );
2018-08-30 10:30:52 +02:00
var_dump ( $txlocaltax2 );
var_dump ( $localtaxes_type );
var_dump ( $tabprice );
var_dump ( $tabprice [ 9 ]);
var_dump ( $tabprice [ 10 ]);
exit ; */
2018-08-30 09:40:04 +02:00
$total_ht = $tabprice [ 0 ];
$total_tva = $tabprice [ 1 ];
$total_ttc = $tabprice [ 2 ];
$total_localtax1 = $tabprice [ 9 ];
$total_localtax2 = $tabprice [ 10 ];
$pu_ht = $tabprice [ 3 ];
// MultiCurrency
$multicurrency_total_ht = $tabprice [ 16 ];
$multicurrency_total_tva = $tabprice [ 17 ];
$multicurrency_total_ttc = $tabprice [ 18 ];
$pu_ht_devise = $tabprice [ 19 ];
// Rang to use
2019-08-10 00:46:20 +02:00
$ranktouse = $rang ;
2025-02-10 18:09:32 +01:00
2021-02-23 20:46:19 +01:00
if ( $ranktouse == - 1 ) {
2018-08-30 09:40:04 +02:00
$rangmax = $this -> line_max ( $fk_parent_line );
2019-08-10 00:46:20 +02:00
$ranktouse = $rangmax + 1 ;
2018-08-30 09:40:04 +02:00
}
// TODO A virer
// Anciens indicateurs: $price, $remise (a ne plus utiliser)
$price = $pu ;
$remise = 0 ;
2021-02-23 20:46:19 +01:00
if ( $remise_percent > 0 ) {
2024-03-23 01:11:55 +01:00
$remise = round ((( float ) $pu * $remise_percent / 100 ), 2 );
$price = ( float ) $pu - $remise ;
2018-08-30 09:40:04 +02:00
}
// Insert line
2020-01-30 01:48:28 +01:00
$this -> line = new OrderLine ( $this -> db );
2018-08-30 09:40:04 +02:00
$this -> line -> context = $this -> context ;
2020-01-30 01:48:28 +01:00
$this -> line -> fk_commande = $this -> id ;
$this -> line -> label = $label ;
$this -> line -> desc = $desc ;
2025-01-19 02:30:36 +01:00
$this -> line -> qty = ( float ) $qty ;
2020-09-04 21:11:58 +02:00
$this -> line -> ref_ext = $ref_ext ;
2020-01-30 01:48:28 +01:00
$this -> line -> vat_src_code = $vat_src_code ;
$this -> line -> tva_tx = $txtva ;
$this -> line -> localtax1_tx = ( $total_localtax1 ? $localtaxes_type [ 1 ] : 0 );
$this -> line -> localtax2_tx = ( $total_localtax2 ? $localtaxes_type [ 3 ] : 0 );
2020-12-13 13:34:21 +01:00
$this -> line -> localtax1_type = empty ( $localtaxes_type [ 0 ]) ? '' : $localtaxes_type [ 0 ];
$this -> line -> localtax2_type = empty ( $localtaxes_type [ 2 ]) ? '' : $localtaxes_type [ 2 ];
2020-01-30 01:48:28 +01:00
$this -> line -> fk_product = $fk_product ;
$this -> line -> product_type = $product_type ;
$this -> line -> fk_remise_except = $fk_remise_except ;
$this -> line -> remise_percent = $remise_percent ;
2024-11-04 12:32:13 +01:00
$this -> line -> subprice = ( float ) $pu_ht ;
2020-01-30 01:48:28 +01:00
$this -> line -> rang = $ranktouse ;
$this -> line -> info_bits = $info_bits ;
2024-11-04 12:32:13 +01:00
$this -> line -> total_ht = ( float ) $total_ht ;
$this -> line -> total_tva = ( float ) $total_tva ;
$this -> line -> total_localtax1 = ( float ) $total_localtax1 ;
$this -> line -> total_localtax2 = ( float ) $total_localtax2 ;
$this -> line -> total_ttc = ( float ) $total_ttc ;
2020-01-30 01:48:28 +01:00
$this -> line -> special_code = $special_code ;
$this -> line -> origin = $origin ;
$this -> line -> origin_id = $origin_id ;
$this -> line -> fk_parent_line = $fk_parent_line ;
$this -> line -> fk_unit = $fk_unit ;
$this -> line -> date_start = $date_start ;
$this -> line -> date_end = $date_end ;
2018-08-30 09:40:04 +02:00
$this -> line -> fk_fournprice = $fk_fournprice ;
2025-01-05 12:31:33 +01:00
$this -> line -> pa_ht = $pa_ht ; // Can be '' when not defined or 0 if defined to 0 or a price value
2018-08-30 09:40:04 +02:00
// Multicurrency
2020-01-30 01:48:28 +01:00
$this -> line -> fk_multicurrency = $this -> fk_multicurrency ;
$this -> line -> multicurrency_code = $this -> multicurrency_code ;
2024-11-04 12:32:13 +01:00
$this -> line -> multicurrency_subprice = ( float ) $pu_ht_devise ;
$this -> line -> multicurrency_total_ht = ( float ) $multicurrency_total_ht ;
$this -> line -> multicurrency_total_tva = ( float ) $multicurrency_total_tva ;
$this -> line -> multicurrency_total_ttc = ( float ) $multicurrency_total_ttc ;
2018-08-30 09:40:04 +02:00
2025-01-05 12:31:33 +01:00
// TODO Do not use anymore
2020-01-30 01:48:28 +01:00
$this -> line -> price = $price ;
2018-08-30 09:40:04 +02:00
2020-01-30 01:48:28 +01:00
if ( is_array ( $array_options ) && count ( $array_options ) > 0 ) {
$this -> line -> array_options = $array_options ;
2018-08-30 09:40:04 +02:00
}
2020-01-30 01:48:28 +01:00
$result = $this -> line -> insert ( $user );
2021-02-23 20:46:19 +01:00
if ( $result > 0 ) {
2025-02-10 18:09:32 +01:00
// Update denormalized fields at the order level
2022-03-01 14:52:47 +01:00
if ( empty ( $noupdateafterinsertline )) {
$result = $this -> update_price ( 1 , 'auto' , 0 , $mysoc ); // This method is designed to add line from user input so total calculation must be done using 'auto' mode.
}
2021-02-23 20:46:19 +01:00
if ( $result > 0 ) {
2025-02-10 18:09:32 +01:00
if ( ! isset ( $this -> context [ 'createfromclone' ])) {
if ( ! empty ( $fk_parent_line )) {
// Always reorder if child line
$this -> line_order ( true , 'DESC' );
} elseif ( $ranktouse > 0 && $ranktouse <= count ( $this -> lines )) {
// Update all rank of all other lines starting from the same $ranktouse
$linecount = count ( $this -> lines );
for ( $ii = $ranktouse ; $ii <= $linecount ; $ii ++ ) {
$this -> updateRangOfLine ( $this -> lines [ $ii - 1 ] -> id , $ii + 1 );
}
}
$this -> lines [] = $this -> line ;
}
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
2019-11-12 10:11:30 +01:00
return $this -> line -> id ;
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> line -> error ;
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::addline error= " . $this -> error , LOG_ERR );
$this -> db -> rollback ();
return - 2 ;
}
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::addline status of order must be Draft to allow use of ->addline() " , LOG_ERR );
return - 3 ;
}
}
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Add line into array
* $this -> client must be loaded
*
2019-02-25 00:56:48 +01:00
* @ param int $idproduct Product Id
* @ param float $qty Quantity
* @ param float $remise_percent Product discount relative
2023-12-20 14:22:45 +01:00
* @ param int | string $date_start Start date of the line
* @ param int | string $date_end End date of the line
2019-02-25 00:56:48 +01:00
* @ return void
2018-08-30 09:40:04 +02:00
*
2024-01-14 12:26:37 +01:00
* TODO Remplacer les appels a cette fonction par generation object Ligne
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function add_product ( $idproduct , $qty , $remise_percent = 0.0 , $date_start = '' , $date_end = '' )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2018-08-30 09:40:04 +02:00
global $conf , $mysoc ;
2021-02-23 20:46:19 +01:00
if ( ! $qty ) {
$qty = 1 ;
}
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( $idproduct > 0 ) {
2019-11-13 19:37:08 +01:00
$prod = new Product ( $this -> db );
2018-08-30 09:40:04 +02:00
$prod -> fetch ( $idproduct );
2019-01-27 11:55:16 +01:00
$tva_tx = get_default_tva ( $mysoc , $this -> thirdparty , $prod -> id );
$tva_npr = get_default_npr ( $mysoc , $this -> thirdparty , $prod -> id );
2021-02-23 20:46:19 +01:00
if ( empty ( $tva_tx )) {
$tva_npr = 0 ;
}
2019-11-13 19:37:08 +01:00
$vat_src_code = '' ; // May be defined into tva_tx
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$localtax1_tx = get_localtax ( $tva_tx , 1 , $this -> thirdparty , $mysoc , $tva_npr );
$localtax2_tx = get_localtax ( $tva_tx , 2 , $this -> thirdparty , $mysoc , $tva_npr );
2018-08-30 09:40:04 +02:00
// multiprix
2025-01-23 02:42:06 +01:00
if ( getDolGlobalString ( 'PRODUIT_MULTIPRICES' ) && $this -> thirdparty -> price_level ) {
2018-08-30 10:30:52 +02:00
$price = $prod -> multiprices [ $this -> thirdparty -> price_level ];
2018-08-30 10:42:47 +02:00
} else {
$price = $prod -> price ;
}
2019-11-13 19:37:08 +01:00
$line = new OrderLine ( $this -> db );
2018-08-30 10:42:47 +02:00
$line -> context = $this -> context ;
2019-11-13 19:37:08 +01:00
$line -> fk_product = $idproduct ;
$line -> desc = $prod -> description ;
$line -> qty = $qty ;
$line -> subprice = $price ;
$line -> remise_percent = $remise_percent ;
$line -> vat_src_code = $vat_src_code ;
$line -> tva_tx = $tva_tx ;
$line -> localtax1_tx = $localtax1_tx ;
$line -> localtax2_tx = $localtax2_tx ;
2023-08-06 01:14:36 +02:00
$line -> product_ref = $prod -> ref ;
$line -> product_label = $prod -> label ;
2019-11-13 19:37:08 +01:00
$line -> product_desc = $prod -> description ;
$line -> fk_unit = $prod -> fk_unit ;
2018-08-30 10:42:47 +02:00
// Save the start and end date of the line in the object
2021-02-23 20:46:19 +01:00
if ( $date_start ) {
$line -> date_start = $date_start ;
}
if ( $date_end ) {
$line -> date_end = $date_end ;
}
2018-08-30 10:42:47 +02:00
$this -> lines [] = $line ;
/** POUR AJOUTER AUTOMATIQUEMENT LES SOUSPRODUITS a LA COMMANDE
2025-01-19 02:30:36 +01:00
* if ( getDolGlobalString ( 'PRODUIT_SOUSPRODUITS' )) {
* $prod = new Product ( $this -> db );
* $prod -> fetch ( $idproduct );
* $prod -> get_sousproduits_arbo ();
* $prods_arbo = $prod -> get_arbo_each_prod ();
* if ( count ( $prods_arbo ) > 0 )
* {
* foreach ( $prods_arbo as $key => $value )
* {
* // print "id : ".$value[1].' :qty: '.$value[0].'<br>';
* if not in lines {
* $this -> add_product ( $value [ 1 ], $value [ 0 ]);
* }
* }
* }
2018-08-30 10:42:47 +02:00
**/
2018-08-30 09:40:04 +02:00
}
}
/**
2020-02-10 00:22:53 +01:00
* Get object from database . Get also lines .
2018-08-30 09:40:04 +02:00
*
* @ param int $id Id of object to load
* @ param string $ref Ref of object
* @ param string $ref_ext External reference of object
2020-03-06 14:38:06 +01:00
* @ param string $notused Internal reference of other object
2018-08-30 09:40:04 +02:00
* @ return int > 0 if OK , < 0 if KO , 0 if not found
*/
2020-03-06 14:38:06 +01:00
public function fetch ( $id , $ref = '' , $ref_ext = '' , $notused = '' )
2018-08-30 09:40:04 +02:00
{
// Check parameters
2021-02-23 20:46:19 +01:00
if ( empty ( $id ) && empty ( $ref ) && empty ( $ref_ext )) {
return - 1 ;
}
2018-08-30 09:40:04 +02:00
2025-02-11 16:28:37 +01:00
$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' ;
2021-09-29 12:05:38 +02:00
$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' ;
2020-01-30 01:48:28 +01:00
$sql .= ', c.fk_account' ;
$sql .= ', c.date_commande, c.date_valid, c.tms' ;
2020-11-16 12:20:18 +01:00
$sql .= ', c.date_livraison as delivery_date' ;
2020-01-30 01:48:28 +01:00
$sql .= ', c.fk_shipping_method' ;
$sql .= ', c.fk_warehouse' ;
2023-10-20 10:47:08 +02:00
$sql .= ', c.fk_projet as fk_project, c.source, c.facture as billed' ;
2022-09-23 09:35:17 +02:00
$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' ;
2020-01-30 01:48:28 +01:00
$sql .= ', c.fk_incoterms, c.location_incoterms' ;
$sql .= " , c.fk_multicurrency, c.multicurrency_code, c.multicurrency_tx, c.multicurrency_total_ht, c.multicurrency_total_tva, c.multicurrency_total_ttc " ;
$sql .= " , c.module_source, c.pos_source " ;
2020-09-08 21:27:28 +02:00
$sql .= " , i.libelle as label_incoterms " ;
2020-01-30 01:48:28 +01:00
$sql .= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle' ;
$sql .= ', cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle, cr.libelle_facture as cond_reglement_libelle_doc' ;
$sql .= ', ca.code as availability_code, ca.label as availability_label' ;
$sql .= ', dr.code as demand_reason_code' ;
2024-09-26 17:10:25 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this -> table_element . ' as c' ;
2020-01-30 01:48:28 +01:00
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_payment_term as cr ON c.fk_cond_reglement = cr.rowid' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_paiement as p ON c.fk_mode_reglement = p.id' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_availability as ca ON c.fk_availability = ca.rowid' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_input_reason as dr ON c.fk_input_reason = dr.rowid' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_incoterms as i ON c.fk_incoterms = i.rowid' ;
2021-02-23 20:46:19 +01:00
if ( $id ) {
2025-01-19 17:38:34 +01:00
$sql .= " WHERE c.rowid = " . (( int ) $id );
2021-02-23 20:46:19 +01:00
} else {
2024-01-14 12:26:37 +01:00
$sql .= " WHERE c.entity IN ( " . getEntity ( 'commande' ) . " ) " ; // Don't use entity if you use rowid
2021-02-23 20:46:19 +01:00
}
2020-01-30 01:48:28 +01:00
2021-02-23 20:46:19 +01:00
if ( $ref ) {
2025-01-19 17:38:34 +01:00
$sql .= " AND c.ref = ' " . $this -> db -> escape ( $ref ) . " ' " ;
2021-02-23 20:46:19 +01:00
}
if ( $ref_ext ) {
2025-01-19 17:38:34 +01:00
$sql .= " AND c.ref_ext = ' " . $this -> db -> escape ( $ref_ext ) . " ' " ;
2021-02-23 20:46:19 +01:00
}
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::fetch " , LOG_DEBUG );
$result = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $result ) {
2018-08-30 09:40:04 +02:00
$obj = $this -> db -> fetch_object ( $result );
2021-02-23 20:46:19 +01:00
if ( $obj ) {
2019-11-13 19:37:08 +01:00
$this -> id = $obj -> rowid ;
$this -> entity = $obj -> entity ;
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$this -> ref = $obj -> ref ;
$this -> ref_client = $obj -> ref_client ;
$this -> ref_customer = $obj -> ref_client ;
2023-04-26 11:41:02 +02:00
$this -> ref_ext = $obj -> ref_ext ;
2020-02-10 00:22:53 +01:00
2019-11-13 19:37:08 +01:00
$this -> socid = $obj -> fk_soc ;
2020-02-13 12:36:05 +01:00
$this -> thirdparty = null ; // Clear if another value was already set by fetch_thirdparty
2020-02-10 00:22:53 +01:00
$this -> fk_project = $obj -> fk_project ;
2020-02-13 12:36:05 +01:00
$this -> project = null ; // Clear if another value was already set by fetch_projet
2020-02-10 00:22:53 +01:00
2025-02-11 16:28:37 +01:00
$this -> statut = $obj -> status ;
$this -> status = $obj -> status ;
2021-02-02 16:12:03 +01:00
2019-11-13 19:37:08 +01:00
$this -> user_author_id = $obj -> fk_user_author ;
2022-06-28 13:09:53 +02:00
$this -> user_creation_id = $obj -> fk_user_author ;
$this -> user_validation_id = $obj -> fk_user_valid ;
$this -> user_modification_id = $obj -> fk_user_modif ;
2018-08-30 09:40:04 +02:00
$this -> total_ht = $obj -> total_ht ;
$this -> total_tva = $obj -> total_tva ;
$this -> total_localtax1 = $obj -> total_localtax1 ;
$this -> total_localtax2 = $obj -> total_localtax2 ;
$this -> total_ttc = $obj -> total_ttc ;
2019-11-13 19:37:08 +01:00
$this -> date = $this -> db -> jdate ( $obj -> date_commande );
2018-08-30 09:40:04 +02:00
$this -> date_commande = $this -> db -> jdate ( $obj -> date_commande );
2018-10-17 00:06:24 +02:00
$this -> date_creation = $this -> db -> jdate ( $obj -> date_creation );
2023-10-24 11:37:29 +02:00
$this -> date_validation = $this -> db -> jdate ( $obj -> date_valid );
$this -> date_modification = $this -> db -> jdate ( $obj -> tms );
2018-08-30 09:40:04 +02:00
$this -> source = $obj -> source ;
$this -> billed = $obj -> billed ;
2019-11-13 19:37:08 +01:00
$this -> note = $obj -> note_private ; // deprecated
$this -> note_private = $obj -> note_private ;
$this -> note_public = $obj -> note_public ;
2020-08-18 14:48:38 +02:00
$this -> model_pdf = $obj -> model_pdf ;
2019-11-13 19:37:08 +01:00
$this -> last_main_doc = $obj -> last_main_doc ;
2018-08-30 09:40:04 +02:00
$this -> mode_reglement_id = $obj -> fk_mode_reglement ;
$this -> mode_reglement_code = $obj -> mode_reglement_code ;
$this -> mode_reglement = $obj -> mode_reglement_libelle ;
$this -> cond_reglement_id = $obj -> fk_cond_reglement ;
$this -> cond_reglement_code = $obj -> cond_reglement_code ;
$this -> cond_reglement = $obj -> cond_reglement_libelle ;
2019-11-13 19:37:08 +01:00
$this -> cond_reglement_doc = $obj -> cond_reglement_libelle_doc ;
2021-09-29 12:05:38 +02:00
$this -> deposit_percent = $obj -> deposit_percent ;
2019-11-13 19:37:08 +01:00
$this -> fk_account = $obj -> fk_account ;
$this -> availability_id = $obj -> fk_availability ;
2018-08-30 09:40:04 +02:00
$this -> availability_code = $obj -> availability_code ;
$this -> availability = $obj -> availability_label ;
$this -> demand_reason_id = $obj -> fk_input_reason ;
2019-11-13 19:37:08 +01:00
$this -> demand_reason_code = $obj -> demand_reason_code ;
2020-11-16 12:20:18 +01:00
$this -> delivery_date = $this -> db -> jdate ( $obj -> delivery_date );
2019-11-13 19:37:08 +01:00
$this -> shipping_method_id = ( $obj -> fk_shipping_method > 0 ) ? $obj -> fk_shipping_method : null ;
$this -> warehouse_id = ( $obj -> fk_warehouse > 0 ) ? $obj -> fk_warehouse : null ;
$this -> fk_delivery_address = $obj -> fk_delivery_address ;
2019-02-20 12:29:47 +01:00
$this -> module_source = $obj -> module_source ;
$this -> pos_source = $obj -> pos_source ;
2019-02-25 00:56:48 +01:00
2018-08-30 09:40:04 +02:00
//Incoterms
2019-02-20 12:29:47 +01:00
$this -> fk_incoterms = $obj -> fk_incoterms ;
$this -> location_incoterms = $obj -> location_incoterms ;
2019-06-25 13:00:02 +02:00
$this -> label_incoterms = $obj -> label_incoterms ;
2018-08-30 09:40:04 +02:00
// Multicurrency
$this -> fk_multicurrency = $obj -> fk_multicurrency ;
2019-11-13 19:37:08 +01:00
$this -> multicurrency_code = $obj -> multicurrency_code ;
2018-08-30 09:40:04 +02:00
$this -> multicurrency_tx = $obj -> multicurrency_tx ;
2019-11-13 19:37:08 +01:00
$this -> multicurrency_total_ht = $obj -> multicurrency_total_ht ;
2018-08-30 09:40:04 +02:00
$this -> multicurrency_total_tva = $obj -> multicurrency_total_tva ;
$this -> multicurrency_total_ttc = $obj -> multicurrency_total_ttc ;
2023-06-10 10:47:36 +02:00
$this -> extraparams = ! empty ( $obj -> extraparams ) ? ( array ) json_decode ( $obj -> extraparams , true ) : array ();
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$this -> lines = array ();
2018-08-30 09:40:04 +02:00
2020-10-23 20:08:35 +02:00
// Retrieve all extrafield
2018-08-30 09:40:04 +02:00
// fetch optionals attributes and labels
$this -> fetch_optionals ();
$this -> db -> free ( $result );
2020-02-10 00:22:53 +01:00
// Lines
2019-11-13 19:37:08 +01:00
$result = $this -> fetch_lines ();
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
2018-08-30 09:40:04 +02:00
return - 3 ;
}
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = 'Order with id ' . $id . ' not found sql=' . $sql ;
2018-08-30 09:40:04 +02:00
return 0 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
return - 1 ;
}
}
2019-02-28 23:19:58 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
2024-07-25 13:59:12 +02:00
* Add a discount line into a sale order ( as a sale order line ) using an existing absolute discount ( Consume the discount )
2018-08-30 09:40:04 +02:00
*
2024-07-25 13:59:12 +02:00
* @ param int $idremise Id for the fixed discount from table llx_societe_remise_except
2024-01-14 12:26:37 +01:00
* @ return int > 0 if OK , < 0 if KO
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function insert_discount ( $idremise )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2018-08-30 09:40:04 +02:00
global $langs ;
include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php' ;
include_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php' ;
$this -> db -> begin ();
2019-11-13 19:37:08 +01:00
$remise = new DiscountAbsolute ( $this -> db );
$result = $remise -> fetch ( $idremise );
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( $result > 0 ) {
if ( $remise -> fk_facture ) { // Protection against multiple submission
2019-11-13 19:37:08 +01:00
$this -> error = $langs -> trans ( " ErrorDiscountAlreadyUsed " );
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 5 ;
}
$line = new OrderLine ( $this -> db );
2019-11-13 19:37:08 +01:00
$line -> fk_commande = $this -> id ;
$line -> fk_remise_except = $remise -> id ;
$line -> desc = $remise -> description ; // Description ligne
$line -> vat_src_code = $remise -> vat_src_code ;
$line -> tva_tx = $remise -> tva_tx ;
2024-10-26 18:24:40 +02:00
$line -> subprice = - ( float ) $remise -> amount_ht ;
$line -> price = - ( float ) $remise -> amount_ht ;
2019-11-13 19:37:08 +01:00
$line -> fk_product = 0 ; // Id produit predefini
$line -> qty = 1 ;
$line -> remise_percent = 0 ;
$line -> rang = - 1 ;
$line -> info_bits = 2 ;
2018-08-30 09:40:04 +02:00
2024-10-26 18:24:40 +02:00
$line -> total_ht = - ( float ) $remise -> amount_ht ;
$line -> total_tva = - ( float ) $remise -> amount_tva ;
$line -> total_ttc = - ( float ) $remise -> amount_ttc ;
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$result = $line -> insert ();
2021-02-23 20:46:19 +01:00
if ( $result > 0 ) {
2019-11-13 19:37:08 +01:00
$result = $this -> update_price ( 1 );
2021-02-23 20:46:19 +01:00
if ( $result > 0 ) {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $line -> error ;
2021-02-08 20:44:40 +01:00
$this -> errors = $line -> errors ;
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 2 ;
}
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 2 ;
}
}
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Load array lines
*
2022-01-24 14:09:53 +01:00
* @ param int $only_product Return only physical products , not services
2019-06-25 18:12:16 +02:00
* @ param int $loadalsotranslation Return translation for products
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-06-25 15:41:20 +02:00
public function fetch_lines ( $only_product = 0 , $loadalsotranslation = 0 )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2019-11-13 19:37:08 +01:00
$this -> lines = array ();
2018-08-30 09:40:04 +02:00
2020-09-04 21:11:58 +02:00
$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,' ;
2019-11-13 19:37:08 +01:00
$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,' ;
$sql .= ' l.total_ht, l.total_ttc, l.total_tva, l.total_localtax1, l.total_localtax2, l.date_start, l.date_end,' ;
$sql .= ' l.fk_unit,' ;
$sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,' ;
2020-11-24 11:07:35 +01:00
$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,' ;
2025-01-29 19:15:57 +01:00
$sql .= ' p.weight, p.weight_units, p.volume, p.volume_units, p.packaging' ;
2024-09-26 17:10:25 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this -> table_element_line . ' as l' ;
2019-11-13 19:37:08 +01:00
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product as p ON (p.rowid = l.fk_product)' ;
2021-08-27 23:36:06 +02:00
$sql .= ' WHERE l.fk_commande = ' . (( int ) $this -> id );
2021-02-23 20:46:19 +01:00
if ( $only_product ) {
$sql .= ' AND p.fk_product_type = 0' ;
}
2018-08-30 09:40:04 +02:00
$sql .= ' ORDER BY l.rang, l.rowid' ;
dol_syslog ( get_class ( $this ) . " ::fetch_lines " , LOG_DEBUG );
$result = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $result ) {
2018-08-30 09:40:04 +02:00
$num = $this -> db -> num_rows ( $result );
2015-10-15 12:17:57 +02:00
2018-08-30 09:40:04 +02:00
$i = 0 ;
2021-02-23 20:46:19 +01:00
while ( $i < $num ) {
2018-08-30 09:40:04 +02:00
$objp = $this -> db -> fetch_object ( $result );
$line = new OrderLine ( $this -> db );
$line -> rowid = $objp -> rowid ;
$line -> id = $objp -> rowid ;
$line -> fk_commande = $objp -> fk_commande ;
$line -> commande_id = $objp -> fk_commande ;
$line -> label = $objp -> custom_label ;
$line -> desc = $objp -> description ;
2019-11-13 19:37:08 +01:00
$line -> description = $objp -> description ; // Description line
2018-08-30 09:40:04 +02:00
$line -> product_type = $objp -> product_type ;
$line -> qty = $objp -> qty ;
2020-09-04 21:11:58 +02:00
$line -> ref_ext = $objp -> ref_ext ;
2018-08-30 09:40:04 +02:00
$line -> vat_src_code = $objp -> vat_src_code ;
$line -> tva_tx = $objp -> tva_tx ;
$line -> localtax1_tx = $objp -> localtax1_tx ;
$line -> localtax2_tx = $objp -> localtax2_tx ;
$line -> localtax1_type = $objp -> localtax1_type ;
$line -> localtax2_type = $objp -> localtax2_type ;
$line -> total_ht = $objp -> total_ht ;
$line -> total_ttc = $objp -> total_ttc ;
$line -> total_tva = $objp -> total_tva ;
$line -> total_localtax1 = $objp -> total_localtax1 ;
$line -> total_localtax2 = $objp -> total_localtax2 ;
$line -> subprice = $objp -> subprice ;
$line -> fk_remise_except = $objp -> fk_remise_except ;
$line -> remise_percent = $objp -> remise_percent ;
$line -> price = $objp -> price ;
$line -> fk_product = $objp -> fk_product ;
2019-11-13 19:37:08 +01:00
$line -> fk_fournprice = $objp -> fk_fournprice ;
$marginInfos = getMarginInfos ( $objp -> subprice , $objp -> remise_percent , $objp -> tva_tx , $objp -> localtax1_tx , $objp -> localtax2_tx , $line -> fk_fournprice , $objp -> pa_ht );
$line -> pa_ht = $marginInfos [ 0 ];
2018-08-30 09:40:04 +02:00
$line -> marge_tx = $marginInfos [ 1 ];
2018-08-30 10:30:52 +02:00
$line -> marque_tx = $marginInfos [ 2 ];
2018-08-30 09:40:04 +02:00
$line -> rang = $objp -> rang ;
$line -> info_bits = $objp -> info_bits ;
2019-11-13 19:37:08 +01:00
$line -> special_code = $objp -> special_code ;
$line -> fk_parent_line = $objp -> fk_parent_line ;
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$line -> ref = $objp -> product_ref ;
$line -> libelle = $objp -> product_label ;
2020-11-23 21:38:45 +01:00
$line -> product_ref = $objp -> product_ref ;
2019-11-13 19:37:08 +01:00
$line -> product_label = $objp -> product_label ;
2020-11-16 16:31:05 +01:00
$line -> product_tosell = $objp -> product_tosell ;
$line -> product_tobuy = $objp -> product_tobuy ;
2018-08-30 09:40:04 +02:00
$line -> product_desc = $objp -> product_desc ;
$line -> product_tobatch = $objp -> product_tobatch ;
2020-11-23 21:38:45 +01:00
$line -> product_barcode = $objp -> product_barcode ;
2019-11-13 19:37:08 +01:00
$line -> fk_product_type = $objp -> fk_product_type ; // Produit ou service
2018-08-30 09:40:04 +02:00
$line -> fk_unit = $objp -> fk_unit ;
$line -> weight = $objp -> weight ;
$line -> weight_units = $objp -> weight_units ;
$line -> volume = $objp -> volume ;
$line -> volume_units = $objp -> volume_units ;
2025-01-29 19:15:57 +01:00
$line -> packaging = $objp -> packaging ;
2025-01-20 12:50:09 +01:00
2018-08-30 09:40:04 +02:00
$line -> date_start = $this -> db -> jdate ( $objp -> date_start );
$line -> date_end = $this -> db -> jdate ( $objp -> date_end );
2015-10-15 12:17:57 +02:00
2018-08-30 09:40:04 +02:00
// Multicurrency
2019-11-13 19:37:08 +01:00
$line -> fk_multicurrency = $objp -> fk_multicurrency ;
$line -> multicurrency_code = $objp -> multicurrency_code ;
2018-08-30 09:40:04 +02:00
$line -> multicurrency_subprice = $objp -> multicurrency_subprice ;
$line -> multicurrency_total_ht = $objp -> multicurrency_total_ht ;
$line -> multicurrency_total_tva = $objp -> multicurrency_total_tva ;
$line -> multicurrency_total_ttc = $objp -> multicurrency_total_ttc ;
2018-10-04 17:56:56 +02:00
$line -> fetch_optionals ();
2019-06-25 15:41:20 +02:00
// multilangs
2022-09-24 14:37:57 +02:00
if ( getDolGlobalInt ( 'MAIN_MULTILANGS' ) && ! empty ( $objp -> fk_product ) && ! empty ( $loadalsotranslation )) {
2022-05-18 23:52:43 +02:00
$tmpproduct = new Product ( $this -> db );
$tmpproduct -> fetch ( $objp -> fk_product );
$tmpproduct -> getMultiLangs ();
$line -> multilangs = $tmpproduct -> multilangs ;
2020-09-08 21:27:28 +02:00
}
2018-10-04 17:56:56 +02:00
2020-09-08 21:27:28 +02:00
$this -> lines [ $i ] = $line ;
2018-08-30 09:40:04 +02:00
$i ++ ;
}
$this -> db -> free ( $result );
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
return - 3 ;
}
}
/**
* Return number of line with type product .
*
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , Nbr of product lines if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function getNbOfProductsLines ()
2018-08-30 09:40:04 +02:00
{
2019-11-13 19:37:08 +01:00
$nb = 0 ;
2021-02-23 20:46:19 +01:00
foreach ( $this -> lines as $line ) {
if ( $line -> product_type == 0 ) {
$nb ++ ;
}
2018-08-30 09:40:04 +02:00
}
return $nb ;
}
/**
* Return number of line with type service .
*
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , Nbr of service lines if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function getNbOfServicesLines ()
2018-08-30 09:40:04 +02:00
{
2019-11-13 19:37:08 +01:00
$nb = 0 ;
2021-02-23 20:46:19 +01:00
foreach ( $this -> lines as $line ) {
if ( $line -> product_type == 1 ) {
$nb ++ ;
}
2018-08-30 09:40:04 +02:00
}
return $nb ;
}
/**
2019-02-25 00:56:48 +01:00
* Count number of shipments for this order
2018-08-30 09:40:04 +02:00
*
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , Nb of shipment found if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function getNbOfShipments ()
2018-08-30 09:40:04 +02:00
{
$nb = 0 ;
$sql = 'SELECT COUNT(DISTINCT ed.fk_expedition) as nb' ;
2019-11-13 19:37:08 +01:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'expeditiondet as ed,' ;
2024-09-26 17:10:25 +02:00
$sql .= ' ' . MAIN_DB_PREFIX . $this -> table_element_line . ' as cd' ;
2019-11-13 19:37:08 +01:00
$sql .= ' WHERE' ;
2024-04-08 12:44:49 +02:00
$sql .= ' ed.fk_elementdet = cd.rowid' ;
2021-08-27 23:36:06 +02:00
$sql .= ' AND cd.fk_commande = ' . (( int ) $this -> id );
2018-08-30 09:40:04 +02:00
//print $sql;
dol_syslog ( get_class ( $this ) . " ::getNbOfShipments " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $resql ) {
2018-08-30 10:30:52 +02:00
$obj = $this -> db -> fetch_object ( $resql );
2021-02-23 20:46:19 +01:00
if ( $obj ) {
$nb = $obj -> nb ;
}
2018-08-30 09:40:04 +02:00
2018-08-30 10:30:52 +02:00
$this -> db -> free ( $resql );
2018-08-30 09:40:04 +02:00
return $nb ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror ();
2018-08-30 09:40:04 +02:00
return - 1 ;
}
}
/**
* Load array this -> expeditions of lines of shipments with nb of products sent for each order line
* Note : For a dedicated shipment , the fetch_lines can be used to load the qty_asked and qty_shipped . This function is use to return qty_shipped cumulated for the order
*
* @ param int $filtre_statut Filter on shipment status
2022-01-24 14:09:53 +01:00
* @ param int $fk_product Add a filter on a product
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , Nb of lines found if OK
2018-08-30 09:40:04 +02:00
*/
2022-01-24 14:09:53 +01:00
public function loadExpeditions ( $filtre_statut = - 1 , $fk_product = 0 )
2018-08-30 09:40:04 +02:00
{
$this -> expeditions = array ();
$sql = 'SELECT cd.rowid, cd.fk_product,' ;
2019-11-13 19:37:08 +01:00
$sql .= ' sum(ed.qty) as qty' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'expeditiondet as ed,' ;
2021-02-23 20:46:19 +01:00
if ( $filtre_statut >= 0 ) {
$sql .= ' ' . MAIN_DB_PREFIX . 'expedition as e,' ;
}
2024-09-26 17:10:25 +02:00
$sql .= ' ' . MAIN_DB_PREFIX . $this -> table_element_line . ' as cd' ;
2019-11-13 19:37:08 +01:00
$sql .= ' WHERE' ;
2021-02-23 20:46:19 +01:00
if ( $filtre_statut >= 0 ) {
$sql .= ' ed.fk_expedition = e.rowid AND' ;
}
2024-04-08 12:44:49 +02:00
$sql .= ' ed.fk_elementdet = cd.rowid' ;
2021-08-27 23:36:06 +02:00
$sql .= ' AND cd.fk_commande = ' . (( int ) $this -> id );
2022-06-20 16:07:22 +02:00
if ( $fk_product > 0 ) {
$sql .= ' AND cd.fk_product = ' . (( int ) $fk_product );
2021-02-23 20:46:19 +01:00
}
if ( $filtre_statut >= 0 ) {
2021-08-27 23:36:06 +02:00
$sql .= ' AND e.fk_statut >= ' . (( int ) $filtre_statut );
2021-02-23 20:46:19 +01:00
}
2019-11-13 19:37:08 +01:00
$sql .= ' GROUP BY cd.rowid, cd.fk_product' ;
2018-08-30 09:40:04 +02:00
//print $sql;
dol_syslog ( get_class ( $this ) . " ::loadExpeditions " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $resql ) {
2018-08-30 09:40:04 +02:00
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
2021-02-23 20:46:19 +01:00
while ( $i < $num ) {
2018-08-30 09:40:04 +02:00
$obj = $this -> db -> fetch_object ( $resql );
$this -> expeditions [ $obj -> rowid ] = $obj -> qty ;
$i ++ ;
}
$this -> db -> free ( $resql );
return $num ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror ();
2018-08-30 09:40:04 +02:00
return - 1 ;
}
}
/**
2023-01-06 19:24:57 +01:00
* Returns an array with expeditions lines number
2018-08-30 09:40:04 +02:00
*
* @ return int Nb of shipments
*/
2023-01-06 19:24:57 +01:00
public function countNbOfShipments ()
2018-08-30 09:40:04 +02:00
{
$sql = 'SELECT count(*)' ;
2019-11-13 19:37:08 +01:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'expedition as e' ;
$sql .= ', ' . MAIN_DB_PREFIX . 'element_element as el' ;
2021-08-27 23:36:06 +02:00
$sql .= ' WHERE el.fk_source = ' . (( int ) $this -> id );
2021-03-16 14:58:51 +01:00
$sql .= " AND el.sourcetype = 'commande' " ;
2019-11-13 19:37:08 +01:00
$sql .= " AND el.fk_target = e.rowid " ;
$sql .= " AND el.targettype = 'shipping' " ;
2018-08-30 09:40:04 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $resql ) {
2018-08-30 09:40:04 +02:00
$row = $this -> db -> fetch_row ( $resql );
return $row [ 0 ];
2021-02-23 20:46:19 +01:00
} else {
dol_print_error ( $this -> db );
2018-08-30 09:40:04 +02:00
}
2023-01-06 19:24:57 +01:00
return 0 ;
2018-08-30 09:40:04 +02:00
}
/**
* Delete an order line
*
* @ param User $user User object
* @ param int $lineid Id of line to delete
2023-01-04 11:36:46 +01:00
* @ param int $id Id of object ( for a check )
2018-08-30 09:40:04 +02:00
* @ return int > 0 if OK , 0 if nothing to do , < 0 if KO
*/
2024-02-02 23:46:12 +01:00
public function deleteLine ( $user = null , $lineid = 0 , $id = 0 )
2018-08-30 09:40:04 +02:00
{
2021-02-23 20:46:19 +01:00
if ( $this -> statut == self :: STATUS_DRAFT ) {
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2023-01-04 11:36:46 +01:00
// Delete line
$line = new OrderLine ( $this -> db );
2018-08-30 09:40:04 +02:00
2023-01-04 11:36:46 +01:00
$line -> context = $this -> context ;
2018-08-30 09:40:04 +02:00
2023-01-04 11:36:46 +01:00
// Load data
$line -> fetch ( $lineid );
2018-08-30 09:40:04 +02:00
2023-01-04 11:36:46 +01:00
if ( $id > 0 && $line -> fk_commande != $id ) {
$this -> error = 'ErrorLineIDDoesNotMatchWithObjectID' ;
return - 1 ;
}
2018-08-30 09:40:04 +02:00
2023-01-04 11:36:46 +01:00
// Memorize previous line for triggers
$staticline = clone $line ;
$line -> oldline = $staticline ;
2019-03-27 12:05:42 +01:00
2023-01-04 11:36:46 +01:00
if ( $line -> delete ( $user ) > 0 ) {
$result = $this -> update_price ( 1 );
2018-08-30 09:40:04 +02:00
2023-01-04 11:36:46 +01:00
if ( $result > 0 ) {
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
2023-01-04 11:36:46 +01:00
$this -> error = $this -> db -> lasterror ();
return - 1 ;
2018-08-30 09:40:04 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
2023-01-04 11:36:46 +01:00
$this -> error = $line -> error ;
2018-08-30 09:40:04 +02:00
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = 'ErrorDeleteLineNotAllowedByObjectStatus' ;
2018-08-30 09:40:04 +02:00
return - 1 ;
}
}
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Applique une remise relative
*
2024-03-15 19:57:45 +01:00
* @ deprecated Use setDiscount () instead .
2021-02-09 13:25:55 +01:00
* @ see setDiscount ()
2018-08-30 09:40:04 +02:00
* @ param User $user User qui positionne la remise
* @ param float $remise Discount ( percent )
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function set_remise ( $user , $remise , $notrigger = 0 )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2021-02-09 13:25:55 +01:00
dol_syslog ( get_class ( $this ) . " ::set_remise is deprecated, use setDiscount instead " , LOG_NOTICE );
2024-03-15 19:57:45 +01:00
// @phan-suppress-next-line PhanDeprecatedFunction
2021-02-09 13:25:55 +01:00
return $this -> setDiscount ( $user , $remise , $notrigger );
}
2018-08-30 09:40:04 +02:00
2021-02-09 13:25:55 +01:00
/**
2021-04-25 19:21:48 +02:00
* Set a percentage discount
2021-02-09 13:25:55 +01:00
*
2021-04-25 19:21:48 +02:00
* @ param User $user User setting the discount
2024-03-19 15:12:22 +01:00
* @ param float | string $remise Discount ( percent )
* @ param int < 0 , 1 > $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int <- 1 , 1 > Return integer < 0 if KO , > 0 if OK
2021-02-09 13:25:55 +01:00
*/
public function setDiscount ( $user , $remise , $notrigger = 0 )
{
2024-03-19 15:12:22 +01:00
$remise = trim (( string ) $remise ) ? trim (( string ) $remise ) : 0 ;
2018-08-30 09:40:04 +02:00
2023-02-27 10:34:28 +01:00
if ( $user -> hasRight ( 'commande' , 'creer' )) {
2019-11-13 19:37:08 +01:00
$error = 0 ;
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2021-03-29 22:51:36 +02:00
$remise = price2num ( $remise , 2 );
2018-08-30 09:40:04 +02:00
2024-09-26 17:10:25 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table_element ;
2021-03-29 22:51:36 +02:00
$sql .= ' SET remise_percent = ' . (( float ) $remise );
2021-08-27 23:36:06 +02:00
$sql .= ' WHERE rowid = ' . (( int ) $this -> id ) . ' AND fk_statut = ' . (( int ) self :: STATUS_DRAFT );
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( ! $resql ) {
2019-11-13 19:37:08 +01:00
$this -> errors [] = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$error ++ ;
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> oldcopy = clone $this ;
2018-08-30 09:40:04 +02:00
$this -> remise_percent = $remise ;
$this -> update_price ( 1 );
}
2021-02-23 20:46:19 +01:00
if ( ! $notrigger && empty ( $error )) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_MODIFY' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-08-30 09:40:04 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2018-08-30 09:40:04 +02:00
}
}
2023-01-06 19:24:57 +01:00
return 0 ;
2018-08-30 09:40:04 +02:00
}
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Set the order date
*
* @ param User $user Object user making change
* @ param int $date Date
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function set_date ( $user , $date , $notrigger = 0 )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2023-02-27 10:24:24 +01:00
if ( $user -> hasRight ( 'commande' , 'creer' )) {
2019-11-13 19:37:08 +01:00
$error = 0 ;
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2024-09-26 17:10:25 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . $this -> table_element ;
2019-11-13 19:37:08 +01:00
$sql .= " SET date_commande = " . ( $date ? " ' " . $this -> db -> idate ( $date ) . " ' " : 'null' );
2021-08-23 19:33:24 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . " AND fk_statut = " . (( int ) self :: STATUS_DRAFT );
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( ! $resql ) {
2019-11-13 19:37:08 +01:00
$this -> errors [] = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$error ++ ;
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> oldcopy = clone $this ;
2018-08-30 09:40:04 +02:00
$this -> date = $date ;
2015-06-01 11:24:30 +02:00
}
2014-05-13 10:12:45 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $notrigger && empty ( $error )) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_MODIFY' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2015-10-03 18:33:46 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2015-10-03 18:33:46 +02:00
}
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2015-10-03 18:33:46 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
return - 2 ;
}
}
2011-09-12 19:08:02 +02:00
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2020-10-26 16:50:52 +01:00
/**
* Set delivery date
2020-10-26 17:06:05 +01:00
*
2020-10-26 16:50:52 +01:00
* @ param User $user Object user that modify
* @ param int $delivery_date Delivery date
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if ko , > 0 if ok
2020-10-26 16:50:52 +01:00
* @ deprecated Use setDeliveryDate
*/
2020-10-26 18:21:47 +01:00
public function set_date_livraison ( $user , $delivery_date , $notrigger = 0 )
2020-10-26 16:50:52 +01:00
{
2020-10-26 18:13:25 +01:00
// phpcs:enable
2020-10-26 16:50:52 +01:00
return $this -> setDeliveryDate ( $user , $delivery_date , $notrigger );
}
2018-08-30 09:40:04 +02:00
/**
* Set the planned delivery date
*
2024-01-14 12:26:37 +01:00
* @ param User $user Object utilisateur qui modifie
2020-10-06 11:37:55 +02:00
* @ param int $delivery_date Delivery date
2018-08-30 09:40:04 +02:00
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 si ko , > 0 si ok
2018-08-30 09:40:04 +02:00
*/
2020-10-26 16:50:52 +01:00
public function setDeliveryDate ( $user , $delivery_date , $notrigger = 0 )
2018-08-30 09:40:04 +02:00
{
2023-02-27 10:24:24 +01:00
if ( $user -> hasRight ( 'commande' , 'creer' )) {
2019-11-13 19:37:08 +01:00
$error = 0 ;
2016-07-08 18:30:50 +02:00
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2011-09-12 19:08:02 +02:00
2024-09-26 17:10:25 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . $this -> table_element ;
2020-10-06 11:37:55 +02:00
$sql .= " SET date_livraison = " . ( $delivery_date ? " ' " . $this -> db -> idate ( $delivery_date ) . " ' " : 'null' );
2021-08-23 19:33:24 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2012-07-19 10:26:26 +02:00
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( ! $resql ) {
2019-11-13 19:37:08 +01:00
$this -> errors [] = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$error ++ ;
}
2016-01-23 00:38:17 +01:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> oldcopy = clone $this ;
2020-11-11 18:08:40 +01:00
$this -> delivery_date = $delivery_date ;
2018-08-30 09:40:04 +02:00
}
2011-09-12 19:08:02 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $notrigger && empty ( $error )) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_MODIFY' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
2013-06-10 16:05:41 +02:00
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-08-30 09:40:04 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2018-08-30 09:40:04 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
return - 2 ;
}
}
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Return list of orders ( eventuelly filtered on a user ) into an array
*
2024-10-05 18:55:36 +02:00
* @ param int < 0 , 1 > $shortlist 0 = Return array [ id ] = ref , 1 = Return array []( id => id , ref => ref , name => name )
* @ param int < 0 , 1 > $draft 0 = not draft , 1 = draft
* @ param ? User $excluser Object user to exclude
* @ param int $socid Id third party
* @ param int $limit For pagination
* @ param int $offset For pagination
* @ param string $sortfield Sort criteria
* @ param string $sortorder Sort order
* @ return array < int , string >| array < int , array { id : int , ref : string , name : string } >| int <- 1 , - 1 > - 1 if KO , array with result if OK
2018-08-30 09:40:04 +02:00
*/
2023-12-20 14:22:45 +01:00
public function liste_array ( $shortlist = 0 , $draft = 0 , $excluser = null , $socid = 0 , $limit = 0 , $offset = 0 , $sortfield = 'c.date_commande' , $sortorder = 'DESC' )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2018-08-30 09:40:04 +02:00
global $user ;
2018-07-01 18:49:37 +02:00
2018-08-30 09:40:04 +02:00
$ga = array ();
2018-07-01 18:49:37 +02:00
2018-08-30 09:40:04 +02:00
$sql = " SELECT s.rowid, s.nom as name, s.client, " ;
2019-11-13 19:37:08 +01:00
$sql .= " c.rowid as cid, c.ref " ;
2025-01-13 11:58:16 +01:00
if ( empty ( $user -> socid ) && ! $user -> hasRight ( 'societe' , 'client' , 'voir' )) {
2021-02-23 20:46:19 +01:00
$sql .= " , sc.fk_soc, sc.fk_user " ;
}
2024-09-26 17:10:25 +02:00
$sql .= " FROM " . MAIN_DB_PREFIX . " societe as s, " . MAIN_DB_PREFIX . $this -> table_element . " as c " ;
2025-01-13 11:58:16 +01:00
if ( empty ( $user -> socid ) && ! $user -> hasRight ( 'societe' , 'client' , 'voir' )) {
2021-02-23 20:46:19 +01:00
$sql .= " , " . MAIN_DB_PREFIX . " societe_commerciaux as sc " ;
}
2019-11-13 19:37:08 +01:00
$sql .= " WHERE c.entity IN ( " . getEntity ( 'commande' ) . " ) " ;
$sql .= " AND c.fk_soc = s.rowid " ;
2025-01-13 11:58:16 +01:00
if ( empty ( $user -> socid ) && ! $user -> hasRight ( 'societe' , 'client' , 'voir' )) {
2021-08-23 17:41:11 +02:00
$sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . (( int ) $user -> id );
2018-08-30 09:40:04 +02:00
}
2021-02-23 20:46:19 +01:00
if ( $socid ) {
2021-04-24 20:18:11 +02:00
$sql .= " AND s.rowid = " . (( int ) $socid );
2021-02-23 20:46:19 +01:00
}
if ( $draft ) {
$sql .= " AND c.fk_statut = " . self :: STATUS_DRAFT ;
}
if ( is_object ( $excluser )) {
2021-08-23 19:33:24 +02:00
$sql .= " AND c.fk_user_author <> " . (( int ) $excluser -> id );
2021-02-23 20:46:19 +01:00
}
2019-11-13 19:37:08 +01:00
$sql .= $this -> db -> order ( $sortfield , $sortorder );
$sql .= $this -> db -> plimit ( $limit , $offset );
2011-09-12 19:08:02 +02:00
2019-11-13 19:37:08 +01:00
$result = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $result ) {
2018-08-30 09:40:04 +02:00
$numc = $this -> db -> num_rows ( $result );
2021-02-23 20:46:19 +01:00
if ( $numc ) {
2018-08-30 09:40:04 +02:00
$i = 0 ;
2021-02-23 20:46:19 +01:00
while ( $i < $numc ) {
2018-08-30 09:40:04 +02:00
$obj = $this -> db -> fetch_object ( $result );
2018-02-24 16:21:16 +01:00
2021-02-23 20:46:19 +01:00
if ( $shortlist == 1 ) {
2018-08-30 09:40:04 +02:00
$ga [ $obj -> cid ] = $obj -> ref ;
2021-02-23 20:46:19 +01:00
} elseif ( $shortlist == 2 ) {
2018-08-30 09:40:04 +02:00
$ga [ $obj -> cid ] = $obj -> ref . ' (' . $obj -> name . ')' ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$ga [ $i ][ 'id' ] = $obj -> cid ;
2018-08-30 09:40:04 +02:00
$ga [ $i ][ 'ref' ] = $obj -> ref ;
$ga [ $i ][ 'name' ] = $obj -> name ;
}
$i ++ ;
}
}
return $ga ;
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
dol_print_error ( $this -> db );
return - 1 ;
}
}
2012-07-08 12:18:29 +02:00
2018-08-30 09:40:04 +02:00
/**
* Update delivery delay
*
* @ param int $availability_id Id du nouveau mode
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int > 0 if OK , < 0 if KO
*/
2019-02-25 00:56:48 +01:00
public function availability ( $availability_id , $notrigger = 0 )
2018-08-30 09:40:04 +02:00
{
global $user ;
2015-02-10 12:22:07 +01:00
2018-08-30 09:40:04 +02:00
dol_syslog ( 'Commande::availability(' . $availability_id . ')' );
2021-02-23 20:46:19 +01:00
if ( $this -> statut >= self :: STATUS_DRAFT ) {
2019-11-13 19:37:08 +01:00
$error = 0 ;
2016-07-08 18:30:50 +02:00
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2011-09-12 19:08:02 +02:00
2024-09-26 17:10:25 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table_element ;
2021-03-30 11:36:50 +02:00
$sql .= ' SET fk_availability = ' . (( int ) $availability_id );
2021-03-14 12:20:23 +01:00
$sql .= ' WHERE rowid=' . (( int ) $this -> id );
2016-07-08 18:30:50 +02:00
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( ! $resql ) {
2019-11-13 19:37:08 +01:00
$this -> errors [] = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$error ++ ;
}
2017-11-02 12:38:36 +01:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> oldcopy = clone $this ;
2018-08-30 09:40:04 +02:00
$this -> availability_id = $availability_id ;
}
2011-09-12 19:08:02 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $notrigger && empty ( $error )) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_MODIFY' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2012-02-06 17:18:19 +01:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-08-30 09:40:04 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2018-08-30 09:40:04 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$error_str = 'Command status do not meet requirement ' . $this -> statut ;
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ . $error_str , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error = $error_str ;
$this -> errors [] = $this -> error ;
2018-08-30 09:40:04 +02:00
return - 2 ;
}
}
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Update order demand_reason
*
* @ param int $demand_reason_id Id of new demand
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int > 0 if ok , < 0 if ko
*/
2019-02-25 00:56:48 +01:00
public function demand_reason ( $demand_reason_id , $notrigger = 0 )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2018-08-30 09:40:04 +02:00
global $user ;
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
dol_syslog ( 'Commande::demand_reason(' . $demand_reason_id . ')' );
2021-02-23 20:46:19 +01:00
if ( $this -> statut >= self :: STATUS_DRAFT ) {
2019-11-13 19:37:08 +01:00
$error = 0 ;
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2024-09-26 17:10:25 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table_element ;
2021-03-30 11:36:50 +02:00
$sql .= ' SET fk_input_reason = ' . (( int ) $demand_reason_id );
2021-03-14 12:20:23 +01:00
$sql .= ' WHERE rowid=' . (( int ) $this -> id );
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( ! $resql ) {
2019-11-13 19:37:08 +01:00
$this -> errors [] = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$error ++ ;
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> oldcopy = clone $this ;
2018-08-30 09:40:04 +02:00
$this -> demand_reason_id = $demand_reason_id ;
}
2021-02-23 20:46:19 +01:00
if ( ! $notrigger && empty ( $error )) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_MODIFY' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-08-30 09:40:04 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2018-08-30 09:40:04 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$error_str = 'order status do not meet requirement ' . $this -> statut ;
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ . $error_str , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error = $error_str ;
$this -> errors [] = $this -> error ;
2018-08-30 09:40:04 +02:00
return - 2 ;
}
}
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Set customer ref
*
* @ param User $user User that make change
* @ param string $ref_client Customer ref
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function set_ref_client ( $user , $ref_client , $notrigger = 0 )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2023-02-27 10:24:24 +01:00
if ( $user -> hasRight ( 'commande' , 'creer' )) {
2019-11-13 19:37:08 +01:00
$error = 0 ;
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2024-09-26 17:10:25 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table_element . ' SET' ;
2021-03-29 22:51:36 +02:00
$sql .= ' ref_client = ' . ( empty ( $ref_client ) ? 'NULL' : " ' " . $this -> db -> escape ( $ref_client ) . " ' " );
2021-08-27 23:36:06 +02:00
$sql .= ' WHERE rowid = ' . (( int ) $this -> id );
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ . ' this->id=' . $this -> id . ', ref_client=' . $ref_client , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( ! $resql ) {
2019-11-13 19:37:08 +01:00
$this -> errors [] = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$error ++ ;
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> oldcopy = clone $this ;
2018-08-30 09:40:04 +02:00
$this -> ref_client = $ref_client ;
2023-05-01 13:09:09 +02:00
$this -> ref_customer = $ref_client ;
2018-08-30 09:40:04 +02:00
}
2021-02-23 20:46:19 +01:00
if ( ! $notrigger && empty ( $error )) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_MODIFY' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-08-30 09:40:04 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2018-08-30 09:40:04 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
return - 1 ;
}
}
2011-09-12 19:08:02 +02:00
2012-07-08 12:18:29 +02:00
/**
* Classify the order as invoiced
*
2016-07-08 21:02:27 +02:00
* @ param User $user Object user making the change
2021-01-14 19:09:57 +01:00
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , 0 if already billed , > 0 if OK
2012-07-08 12:18:29 +02:00
*/
2019-02-25 00:56:48 +01:00
public function classifyBilled ( User $user , $notrigger = 0 )
2012-07-08 12:18:29 +02:00
{
2018-08-30 09:40:04 +02:00
$error = 0 ;
2012-07-08 13:19:13 +02:00
2021-02-23 20:46:19 +01:00
if ( $this -> billed ) {
2020-10-23 09:56:35 +02:00
return 0 ;
}
2011-09-12 19:08:02 +02:00
2012-07-08 13:19:13 +02:00
$this -> db -> begin ();
2011-09-12 19:08:02 +02:00
2024-09-26 17:10:25 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table_element . ' SET facture = 1' ;
2021-08-27 23:36:06 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . ' AND fk_statut > ' . self :: STATUS_DRAFT ;
2012-07-08 13:19:13 +02:00
2014-06-12 11:31:53 +02:00
dol_syslog ( get_class ( $this ) . " ::classifyBilled " , LOG_DEBUG );
2021-02-23 20:46:19 +01:00
if ( $this -> db -> query ( $sql )) {
if ( ! $error ) {
2020-01-30 01:48:28 +01:00
$this -> oldcopy = clone $this ;
$this -> billed = 1 ;
2016-07-08 21:02:27 +02:00
}
2016-07-08 21:28:21 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $notrigger && empty ( $error )) {
2018-08-30 09:40:04 +02:00
// Call trigger
2020-01-30 01:48:28 +01:00
$result = $this -> call_trigger ( 'ORDER_CLASSIFY_BILLED' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
2016-07-08 21:02:27 +02:00
}
2012-07-08 12:18:29 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2012-07-08 13:19:13 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2014-06-14 12:30:48 +02:00
dol_syslog ( get_class ( $this ) . " ::classifyBilled " . $errmsg , LOG_ERR );
2020-01-30 01:48:28 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2014-06-14 12:30:48 +02:00
}
2012-07-08 13:19:13 +02:00
$this -> db -> rollback ();
2020-01-30 01:48:28 +01:00
return - 1 * $error ;
2012-07-08 13:19:13 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2020-01-30 01:48:28 +01:00
$this -> error = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
2012-07-08 12:18:29 +02:00
return - 1 ;
}
}
2016-06-06 13:29:37 +02:00
/**
* Classify the order as not invoiced
*
2021-03-02 02:55:24 +01:00
* @ param User $user Object user making the change
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if ko , > 0 if ok
2016-06-06 13:29:37 +02:00
*/
2021-03-02 02:55:24 +01:00
public function classifyUnBilled ( User $user , $notrigger = 0 )
2016-06-06 13:29:37 +02:00
{
2018-08-30 09:40:04 +02:00
$error = 0 ;
$this -> db -> begin ();
2024-09-26 17:10:25 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table_element . ' SET facture = 0' ;
2021-08-27 23:36:06 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . ' AND fk_statut > ' . self :: STATUS_DRAFT ;
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::classifyUnBilled " , LOG_DEBUG );
2021-02-23 20:46:19 +01:00
if ( $this -> db -> query ( $sql )) {
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> oldcopy = clone $this ;
$this -> billed = 1 ;
2018-08-30 09:40:04 +02:00
}
2021-03-02 02:55:24 +01:00
if ( ! $notrigger && empty ( $error )) {
// Call trigger
$result = $this -> call_trigger ( 'ORDER_CLASSIFY_UNBILLED' , $user );
if ( $result < 0 ) {
$error ++ ;
}
// End call triggers
2021-02-23 20:46:19 +01:00
}
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$this -> billed = 0 ;
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 20:46:19 +01:00
foreach ( $this -> errors as $errmsg ) {
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::classifyUnBilled " . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-08-30 09:40:04 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2018-08-30 09:40:04 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2016-06-06 13:29:37 +02:00
}
2016-07-08 18:30:50 +02:00
2018-08-30 09:40:04 +02:00
/**
* Update a line in database
*
* @ param int $rowid Id of line to update
* @ param string $desc Description of line
* @ param float $pu Unit price
* @ param float $qty Quantity
* @ param float $remise_percent Percent of discount
* @ param float $txtva Taux TVA
* @ param float $txlocaltax1 Local tax 1 rate
* @ param float $txlocaltax2 Local tax 2 rate
* @ param string $price_base_type HT or TTC
2024-01-14 12:26:37 +01:00
* @ param int $info_bits Miscellaneous information on line
2023-12-21 13:43:19 +01:00
* @ param int | string $date_start Start date of the line
* @ param int | string $date_end End date of the line
2018-08-30 09:40:04 +02:00
* @ param int $type Type of line ( 0 = product , 1 = service )
* @ param int $fk_parent_line Id of parent line ( 0 in most cases , used by modules adding sublevels into lines ) .
* @ param int $skip_update_total Keep fields total_xxx to 0 ( used for special lines by some modules )
* @ param int $fk_fournprice Id of origin supplier price
2025-01-05 17:09:38 +01:00
* @ param float $pa_ht Price ( without tax ) of product when it was bought
2018-08-30 09:40:04 +02:00
* @ param string $label Label
* @ param int $special_code Special code ( also used by externals modules ! )
2024-09-30 10:05:24 +02:00
* @ param array < string , mixed > $array_options extrafields array
* @ param ? int $fk_unit Code of the unit to use . Null to use the default one
* @ param float $pu_ht_devise Amount in currency
2018-08-30 09:40:04 +02:00
* @ param int $notrigger disable line update trigger
2020-09-04 21:11:58 +02:00
* @ param string $ref_ext external reference
2024-09-30 10:05:24 +02:00
* @ param int $rang line rank
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2023-12-21 13:43:19 +01:00
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 )
2018-08-30 09:40:04 +02:00
{
2025-01-19 17:38:34 +01:00
global $mysoc , $langs , $user ;
2018-08-30 09:40:04 +02:00
2020-09-04 21:11:58 +02:00
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 " );
2018-08-30 09:40:04 +02:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php' ;
2021-02-23 20:46:19 +01:00
if ( $this -> statut == Commande :: STATUS_DRAFT ) {
2018-08-30 09:40:04 +02:00
// Clean parameters
2021-02-23 20:46:19 +01:00
if ( empty ( $qty )) {
$qty = 0 ;
}
if ( empty ( $info_bits )) {
$info_bits = 0 ;
}
if ( empty ( $txtva )) {
$txtva = 0 ;
}
if ( empty ( $txlocaltax1 )) {
$txlocaltax1 = 0 ;
}
if ( empty ( $txlocaltax2 )) {
$txlocaltax2 = 0 ;
}
if ( empty ( $remise_percent )) {
$remise_percent = 0 ;
}
if ( empty ( $special_code ) || $special_code == 3 ) {
$special_code = 0 ;
}
if ( empty ( $ref_ext )) {
$ref_ext = '' ;
}
2019-03-27 12:05:42 +01:00
2019-03-24 14:30:00 +01:00
if ( $date_start && $date_end && $date_start > $date_end ) {
$langs -> load ( " errors " );
2019-11-13 19:37:08 +01:00
$this -> error = $langs -> trans ( 'ErrorStartDateGreaterEnd' );
2019-03-24 14:30:00 +01:00
return - 1 ;
}
2018-08-30 09:40:04 +02:00
2024-01-23 16:07:59 +01:00
$remise_percent = ( float ) price2num ( $remise_percent );
$qty = ( float ) price2num ( $qty );
2018-08-30 09:40:04 +02:00
$pu = price2num ( $pu );
2025-01-05 17:30:54 +01:00
$pa_ht = price2num ( $pa_ht ); // do not convert to float here, it breaks the functioning of $pa_ht_isemptystring
2019-11-13 19:37:08 +01:00
$pu_ht_devise = price2num ( $pu_ht_devise );
2024-03-19 15:12:22 +01:00
if ( ! preg_match ( '/\((.*)\)/' , ( string ) $txtva )) {
2021-01-02 16:51:34 +01:00
$txtva = price2num ( $txtva ); // $txtva can have format '5.0(XXX)' or '5'
}
2024-01-23 16:07:59 +01:00
$txlocaltax1 = ( float ) price2num ( $txlocaltax1 );
$txlocaltax2 = ( float ) price2num ( $txlocaltax2 );
2019-03-27 12:05:42 +01:00
2019-03-24 14:30:00 +01:00
$this -> db -> begin ();
2018-08-30 09:40:04 +02:00
// Calcul du total TTC et de la TVA pour la ligne a partir de
// qty, pu, remise_percent et txtva
// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
2019-11-13 19:37:08 +01:00
$localtaxes_type = getLocalTaxesFromRate ( $txtva , 0 , $this -> thirdparty , $mysoc );
2018-08-30 09:40:04 +02:00
2018-08-30 10:30:52 +02:00
// Clean vat code
2019-11-13 19:37:08 +01:00
$vat_src_code = '' ;
2020-11-27 14:24:15 +01:00
$reg = array ();
2021-02-23 20:46:19 +01:00
if ( preg_match ( '/\((.*)\)/' , $txtva , $reg )) {
2018-08-30 09:40:04 +02:00
$vat_src_code = $reg [ 1 ];
2019-11-13 19:37:08 +01:00
$txtva = preg_replace ( '/\s*\(.*\)/' , '' , $txtva ); // Remove code into vatrate.
2018-08-30 09:40:04 +02:00
}
2019-11-13 19:37:08 +01:00
$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 );
2018-08-30 09:40:04 +02:00
2023-02-27 10:24:24 +01:00
$total_ht = $tabprice [ 0 ];
2018-08-30 09:40:04 +02:00
$total_tva = $tabprice [ 1 ];
$total_ttc = $tabprice [ 2 ];
$total_localtax1 = $tabprice [ 9 ];
$total_localtax2 = $tabprice [ 10 ];
2023-02-27 10:24:24 +01:00
$pu_ht = $tabprice [ 3 ];
2016-12-11 00:42:52 +01:00
$pu_tva = $tabprice [ 4 ];
$pu_ttc = $tabprice [ 5 ];
2011-09-12 19:08:02 +02:00
2016-01-23 00:38:17 +01:00
// MultiCurrency
2023-02-27 10:24:24 +01:00
$multicurrency_total_ht = $tabprice [ 16 ];
2018-08-30 09:40:04 +02:00
$multicurrency_total_tva = $tabprice [ 17 ];
$multicurrency_total_ttc = $tabprice [ 18 ];
2016-12-11 00:42:52 +01:00
$pu_ht_devise = $tabprice [ 19 ];
2016-07-08 18:30:50 +02:00
2018-08-30 09:40:04 +02:00
// Anciens indicateurs: $price, $subprice (a ne plus utiliser)
$price = $pu_ht ;
2021-02-23 20:46:19 +01:00
if ( $price_base_type == 'TTC' ) {
2016-12-11 00:42:52 +01:00
$subprice = $pu_ttc ;
2020-05-21 15:05:19 +02:00
} else {
2016-12-11 00:42:52 +01:00
$subprice = $pu_ht ;
2016-03-14 17:27:12 +01:00
}
2018-08-30 09:40:04 +02:00
$remise = 0 ;
2021-02-23 20:46:19 +01:00
if ( $remise_percent > 0 ) {
2024-03-23 01:11:55 +01:00
$remise = round ((( float ) $pu * $remise_percent / 100 ), 2 );
$price = (( float ) $pu - $remise );
2018-08-30 09:40:04 +02:00
}
2024-10-15 15:39:29 +02:00
// Fetch current line from the database and then clone the object and set it in $oldline property
2018-08-30 09:40:04 +02:00
$line = new OrderLine ( $this -> db );
$line -> fetch ( $rowid );
2020-01-25 14:03:24 +01:00
$line -> fetch_optionals ();
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( ! empty ( $line -> fk_product )) {
2019-11-13 19:37:08 +01:00
$product = new Product ( $this -> db );
$result = $product -> fetch ( $line -> fk_product );
$product_type = $product -> type ;
2018-08-30 09:40:04 +02:00
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'STOCK_MUST_BE_ENOUGH_FOR_ORDER' ) && $product_type == 0 && $product -> stock_reel < $qty ) {
2018-08-30 09:40:04 +02:00
$langs -> load ( " errors " );
2019-11-13 19:37:08 +01:00
$this -> error = $langs -> trans ( 'ErrorStockIsNotEnoughToAddProductOnOrder' , $product -> ref );
2020-01-19 12:15:47 +01:00
$this -> errors [] = $this -> error ;
2021-04-25 19:21:48 +02:00
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::addline error=Product " . $product -> ref . " : " . $this -> error , LOG_ERR );
2021-04-25 19:21:48 +02:00
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return self :: STOCK_NOT_ENOUGH_FOR_ORDER ;
}
}
$staticline = clone $line ;
$line -> oldline = $staticline ;
$this -> line = $line ;
$this -> line -> context = $this -> context ;
2022-05-11 14:26:21 +02:00
$this -> line -> rang = $rang ;
2018-08-30 09:40:04 +02:00
// Reorder if fk_parent_line change
2021-02-23 20:46:19 +01:00
if ( ! empty ( $fk_parent_line ) && ! empty ( $staticline -> fk_parent_line ) && $fk_parent_line != $staticline -> fk_parent_line ) {
2018-08-30 09:40:04 +02:00
$rangmax = $this -> line_max ( $fk_parent_line );
$this -> line -> rang = $rangmax + 1 ;
}
2025-01-20 12:50:09 +01:00
if ( getDolGlobalString ( 'PRODUCT_USE_CUSTOMER_PACKAGING' )) {
if ( $qty < $this -> line -> packaging ) {
$qty = $this -> line -> packaging ;
} else {
2025-01-28 15:31:08 +01:00
if ( ! empty ( $this -> line -> packaging ) && fmod ( $qty , $this -> line -> packaging ) > 0 ) {
2025-01-20 12:50:09 +01:00
$coeff = intval ( $qty / $this -> line -> packaging ) + 1 ;
$qty = $this -> line -> packaging * $coeff ;
setEventMessage ( $langs -> trans ( 'QtyRecalculatedWithPackaging' ), 'mesgs' );
}
}
}
2020-01-30 01:48:28 +01:00
$this -> line -> id = $rowid ;
2021-06-19 14:52:06 +02:00
$this -> line -> label = $label ;
$this -> line -> desc = $desc ;
$this -> line -> qty = $qty ;
2020-09-04 21:11:58 +02:00
$this -> line -> ref_ext = $ref_ext ;
2018-08-30 09:40:04 +02:00
2020-01-30 01:48:28 +01:00
$this -> line -> vat_src_code = $vat_src_code ;
2018-08-30 09:40:04 +02:00
$this -> line -> tva_tx = $txtva ;
$this -> line -> localtax1_tx = $txlocaltax1 ;
$this -> line -> localtax2_tx = $txlocaltax2 ;
2020-12-22 17:33:17 +01:00
$this -> line -> localtax1_type = empty ( $localtaxes_type [ 0 ]) ? '' : $localtaxes_type [ 0 ];
$this -> line -> localtax2_type = empty ( $localtaxes_type [ 2 ]) ? '' : $localtaxes_type [ 2 ];
2018-08-30 09:40:04 +02:00
$this -> line -> remise_percent = $remise_percent ;
2024-11-04 12:32:13 +01:00
$this -> line -> subprice = ( float ) $pu_ht ;
2018-08-30 09:40:04 +02:00
$this -> line -> info_bits = $info_bits ;
$this -> line -> special_code = $special_code ;
2024-11-04 12:32:13 +01:00
$this -> line -> total_ht = ( float ) $total_ht ;
$this -> line -> total_tva = ( float ) $total_tva ;
$this -> line -> total_localtax1 = ( float ) $total_localtax1 ;
$this -> line -> total_localtax2 = ( float ) $total_localtax2 ;
$this -> line -> total_ttc = ( float ) $total_ttc ;
2018-08-30 09:40:04 +02:00
$this -> line -> date_start = $date_start ;
$this -> line -> date_end = $date_end ;
$this -> line -> product_type = $type ;
$this -> line -> fk_parent_line = $fk_parent_line ;
2019-11-13 19:37:08 +01:00
$this -> line -> skip_update_total = $skip_update_total ;
2018-08-30 09:40:04 +02:00
$this -> line -> fk_unit = $fk_unit ;
2011-09-12 19:08:02 +02:00
2015-10-26 20:33:42 +01:00
$this -> line -> fk_fournprice = $fk_fournprice ;
2012-08-23 07:50:20 +02:00
$this -> line -> pa_ht = $pa_ht ;
2012-07-20 09:57:50 +02:00
2016-01-23 00:38:17 +01:00
// Multicurrency
2024-11-04 12:32:13 +01:00
$this -> line -> multicurrency_subprice = ( float ) $pu_ht_devise ;
$this -> line -> multicurrency_total_ht = ( float ) $multicurrency_total_ht ;
$this -> line -> multicurrency_total_tva = ( float ) $multicurrency_total_tva ;
$this -> line -> multicurrency_total_ttc = ( float ) $multicurrency_total_ttc ;
2016-07-08 18:30:50 +02:00
2018-08-30 09:40:04 +02:00
// TODO deprecated
2019-11-13 19:37:08 +01:00
$this -> line -> price = $price ;
2011-09-12 19:08:02 +02:00
2019-11-13 19:37:08 +01:00
if ( is_array ( $array_options ) && count ( $array_options ) > 0 ) {
2020-01-25 14:03:24 +01:00
// We replace values in this->line->array_options only for entries defined into $array_options
2020-01-30 01:48:28 +01:00
foreach ( $array_options as $key => $value ) {
2020-01-25 14:03:24 +01:00
$this -> line -> array_options [ $key ] = $array_options [ $key ];
}
2013-06-10 16:05:41 +02:00
}
2019-11-13 19:37:08 +01:00
$result = $this -> line -> update ( $user , $notrigger );
2021-02-23 20:46:19 +01:00
if ( $result > 0 ) {
2018-08-30 09:40:04 +02:00
// Reorder if child line
2021-02-23 20:46:19 +01:00
if ( ! empty ( $fk_parent_line )) {
$this -> line_order ( true , 'DESC' );
}
2018-08-30 09:40:04 +02:00
// Mise a jour info denormalisees
2023-06-29 16:50:21 +02:00
$this -> update_price ( 1 , 'auto' );
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return $result ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> line -> error ;
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = get_class ( $this ) . " ::updateline Order status makes operation forbidden " ;
$this -> errors = array ( 'OrderStatusMakeOperationForbidden' );
2018-08-30 09:40:04 +02:00
return - 2 ;
}
}
2011-09-12 19:08:02 +02:00
2015-01-10 01:07:18 +01:00
/**
* Update database
*
* @ param User $user User that modify
* @ param int $notrigger 0 = launch triggers after , 1 = disable triggers
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2015-01-10 01:07:18 +01:00
*/
2019-02-25 00:56:48 +01:00
public function update ( User $user , $notrigger = 0 )
2015-01-10 01:07:18 +01:00
{
2019-11-13 19:37:08 +01:00
$error = 0 ;
2015-01-10 01:07:18 +01:00
// Clean parameters
2021-02-23 20:46:19 +01:00
if ( isset ( $this -> ref )) {
$this -> ref = trim ( $this -> ref );
}
if ( isset ( $this -> ref_client )) {
$this -> ref_client = trim ( $this -> ref_client );
}
2023-05-01 13:09:09 +02:00
if ( isset ( $this -> ref_customer )) {
$this -> ref_customer = trim ( $this -> ref_customer );
}
2021-02-23 20:46:19 +01:00
if ( isset ( $this -> note ) || isset ( $this -> note_private )) {
$this -> note_private = ( isset ( $this -> note_private ) ? trim ( $this -> note_private ) : trim ( $this -> note ));
}
if ( isset ( $this -> note_public )) {
$this -> note_public = trim ( $this -> note_public );
}
if ( isset ( $this -> model_pdf )) {
$this -> model_pdf = trim ( $this -> model_pdf );
}
if ( isset ( $this -> import_key )) {
$this -> import_key = trim ( $this -> import_key );
}
2023-10-17 10:36:11 +02:00
$delivery_date = $this -> delivery_date ;
2015-01-10 01:07:18 +01:00
// Check parameters
// Put here code to add control on parameters values
// Update request
2024-09-26 17:10:25 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . $this -> table_element . " SET " ;
2015-01-10 01:07:18 +01:00
2019-11-13 19:37:08 +01:00
$sql .= " ref= " . ( isset ( $this -> ref ) ? " ' " . $this -> db -> escape ( $this -> ref ) . " ' " : " null " ) . " , " ;
$sql .= " ref_client= " . ( isset ( $this -> ref_client ) ? " ' " . $this -> db -> escape ( $this -> ref_client ) . " ' " : " null " ) . " , " ;
$sql .= " ref_ext= " . ( isset ( $this -> ref_ext ) ? " ' " . $this -> db -> escape ( $this -> ref_ext ) . " ' " : " null " ) . " , " ;
$sql .= " fk_soc= " . ( isset ( $this -> socid ) ? $this -> socid : " null " ) . " , " ;
$sql .= " date_commande= " . ( strval ( $this -> date_commande ) != '' ? " ' " . $this -> db -> idate ( $this -> date_commande ) . " ' " : 'null' ) . " , " ;
$sql .= " date_valid= " . ( strval ( $this -> date_validation ) != '' ? " ' " . $this -> db -> idate ( $this -> date_validation ) . " ' " : 'null' ) . " , " ;
2021-02-20 08:00:27 +01:00
$sql .= " total_tva= " . ( isset ( $this -> total_tva ) ? $this -> total_tva : " null " ) . " , " ;
2019-11-13 19:37:08 +01:00
$sql .= " localtax1= " . ( isset ( $this -> total_localtax1 ) ? $this -> total_localtax1 : " null " ) . " , " ;
$sql .= " localtax2= " . ( isset ( $this -> total_localtax2 ) ? $this -> total_localtax2 : " null " ) . " , " ;
$sql .= " total_ht= " . ( isset ( $this -> total_ht ) ? $this -> total_ht : " null " ) . " , " ;
$sql .= " total_ttc= " . ( isset ( $this -> total_ttc ) ? $this -> total_ttc : " null " ) . " , " ;
$sql .= " fk_statut= " . ( isset ( $this -> statut ) ? $this -> statut : " null " ) . " , " ;
2024-03-27 14:59:42 +01:00
$sql .= " fk_user_modif= " . ( isset ( $user -> id ) ? $user -> id : " null " ) . " , " ;
2023-10-17 11:10:25 +02:00
$sql .= " fk_user_valid= " . (( isset ( $this -> user_validation_id ) && $this -> user_validation_id > 0 ) ? $this -> user_validation_id : " null " ) . " , " ;
2019-11-13 19:37:08 +01:00
$sql .= " fk_projet= " . ( isset ( $this -> fk_project ) ? $this -> fk_project : " null " ) . " , " ;
$sql .= " fk_cond_reglement= " . ( isset ( $this -> cond_reglement_id ) ? $this -> cond_reglement_id : " null " ) . " , " ;
2022-08-31 22:14:20 +02:00
$sql .= " deposit_percent= " . ( ! empty ( $this -> deposit_percent ) ? strval ( $this -> deposit_percent ) : " null " ) . " , " ;
2019-11-13 19:37:08 +01:00
$sql .= " fk_mode_reglement= " . ( isset ( $this -> mode_reglement_id ) ? $this -> mode_reglement_id : " null " ) . " , " ;
2021-02-09 19:24:36 +01:00
$sql .= " date_livraison= " . ( strval ( $this -> delivery_date ) != '' ? " ' " . $this -> db -> idate ( $this -> delivery_date ) . " ' " : 'null' ) . " , " ;
$sql .= " fk_shipping_method= " . ( isset ( $this -> shipping_method_id ) ? $this -> shipping_method_id : " null " ) . " , " ;
2019-11-13 19:37:08 +01:00
$sql .= " fk_account= " . ( $this -> fk_account > 0 ? $this -> fk_account : " null " ) . " , " ;
2020-12-03 16:01:17 +01:00
$sql .= " fk_input_reason= " . ( $this -> demand_reason_id > 0 ? $this -> demand_reason_id : " null " ) . " , " ;
2019-11-13 19:37:08 +01:00
$sql .= " note_private= " . ( isset ( $this -> note_private ) ? " ' " . $this -> db -> escape ( $this -> note_private ) . " ' " : " null " ) . " , " ;
$sql .= " note_public= " . ( isset ( $this -> note_public ) ? " ' " . $this -> db -> escape ( $this -> note_public ) . " ' " : " null " ) . " , " ;
2021-02-08 18:30:09 +01:00
$sql .= " model_pdf= " . ( isset ( $this -> model_pdf ) ? " ' " . $this -> db -> escape ( $this -> model_pdf ) . " ' " : " null " ) . " , " ;
2022-12-28 13:04:11 +01:00
$sql .= " import_key= " . ( isset ( $this -> import_key ) ? " ' " . $this -> db -> escape ( $this -> import_key ) . " ' " : " null " );
2019-11-13 19:37:08 +01:00
2021-03-14 12:20:23 +01:00
$sql .= " WHERE rowid= " . (( int ) $this -> id );
2015-01-10 01:07:18 +01:00
$this -> db -> begin ();
dol_syslog ( get_class ( $this ) . " ::update " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2019-11-13 19:37:08 +01:00
if ( ! $resql ) {
2023-12-04 12:01:45 +01:00
$error ++ ;
$this -> errors [] = " Error " . $this -> db -> lasterror ();
2015-01-10 01:07:18 +01:00
}
2021-02-23 20:46:19 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$result = $this -> insertExtraFields ();
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
2018-08-12 16:29:26 +02:00
$error ++ ;
2015-01-10 01:07:18 +01:00
}
}
2021-02-23 20:46:19 +01:00
if ( ! $error && ! $notrigger ) {
2018-08-12 16:29:26 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_MODIFY' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-12 16:29:26 +02:00
// End call triggers
}
2015-01-10 01:07:18 +01:00
// Commit or rollback
2021-02-23 20:46:19 +01:00
if ( $error ) {
foreach ( $this -> errors as $errmsg ) {
2015-01-10 01:07:18 +01:00
dol_syslog ( get_class ( $this ) . " ::update " . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2015-01-10 01:07:18 +01:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
}
}
/**
2022-10-12 15:29:30 +02:00
* Delete the sales order
2018-08-30 09:40:04 +02:00
*
* @ param User $user User object
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2023-12-06 15:46:39 +01:00
* @ return int Return integer <= 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function delete ( $user , $notrigger = 0 )
2018-08-30 09:40:04 +02:00
{
global $conf , $langs ;
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
$error = 0 ;
2019-11-13 19:37:08 +01:00
dol_syslog ( get_class ( $this ) . " ::delete " . $this -> id , LOG_DEBUG );
2018-08-30 09:40:04 +02:00
$this -> db -> begin ();
2020-11-26 09:16:16 +01:00
if ( ! $notrigger ) {
2018-08-30 09:40:04 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'ORDER_DELETE' , $user );
2021-02-23 20:46:19 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
// End call triggers
}
2020-11-26 09:16:16 +01:00
// Test we can delete
2023-01-06 19:24:57 +01:00
if ( $this -> countNbOfShipments () != 0 ) {
2018-08-30 09:40:04 +02:00
$this -> errors [] = $langs -> trans ( 'SomeShipmentExists' );
$error ++ ;
}
2023-07-24 09:42:21 +02:00
// Remove linked categories.
if ( ! $error ) {
$sql = " DELETE FROM " . MAIN_DB_PREFIX . " categorie_order " ;
$sql .= " WHERE fk_order = " . (( int ) $this -> id );
$result = $this -> db -> query ( $sql );
if ( ! $result ) {
$error ++ ;
$this -> errors [] = $this -> db -> lasterror ();
}
}
2020-11-26 09:16:16 +01:00
// Delete extrafields of lines and lines
if ( ! $error && ! empty ( $this -> table_element_line )) {
$tabletodelete = $this -> table_element_line ;
2021-08-23 19:33:24 +02:00
$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 ) . " ) " ;
$sql = " DELETE FROM " . MAIN_DB_PREFIX . $tabletodelete . " WHERE " . $this -> fk_element . " = " . (( int ) $this -> id );
2020-12-01 02:41:19 +01:00
if ( ! $this -> db -> query ( $sqlef ) || ! $this -> db -> query ( $sql )) {
2018-08-30 09:40:04 +02:00
$error ++ ;
2020-11-26 09:16:16 +01:00
$this -> error = $this -> db -> lasterror ();
$this -> errors [] = $this -> error ;
dol_syslog ( get_class ( $this ) . " ::delete error " . $this -> error , LOG_ERR );
2018-08-30 09:40:04 +02:00
}
}
2020-11-26 09:16:16 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
// Delete linked object
$res = $this -> deleteObjectLinked ();
2021-02-23 20:46:19 +01:00
if ( $res < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
}
2020-11-26 09:16:16 +01:00
if ( ! $error ) {
2018-08-30 09:40:04 +02:00
// Delete linked contacts
$res = $this -> delete_linked_contact ();
2021-02-23 20:46:19 +01:00
if ( $res < 0 ) {
$error ++ ;
}
2018-08-30 09:40:04 +02:00
}
2020-11-26 09:16:16 +01:00
// Removed extrafields of object
if ( ! $error ) {
2020-04-23 13:21:39 +02:00
$result = $this -> deleteExtraFields ();
2020-11-26 09:16:16 +01:00
if ( $result < 0 ) {
2020-04-23 13:21:39 +02:00
$error ++ ;
2020-11-26 09:16:16 +01:00
dol_syslog ( get_class ( $this ) . " ::delete error " . $this -> error , LOG_ERR );
2018-08-30 09:40:04 +02:00
}
}
2020-11-26 09:16:16 +01:00
// Delete main record
if ( ! $error ) {
2021-08-23 19:33:24 +02:00
$sql = " DELETE FROM " . MAIN_DB_PREFIX . $this -> table_element . " WHERE rowid = " . (( int ) $this -> id );
2020-11-26 09:16:16 +01:00
$res = $this -> db -> query ( $sql );
2020-12-01 02:41:19 +01:00
if ( ! $res ) {
2018-08-30 09:40:04 +02:00
$error ++ ;
2020-11-26 09:16:16 +01:00
$this -> error = $this -> db -> lasterror ();
$this -> errors [] = $this -> error ;
dol_syslog ( get_class ( $this ) . " ::delete error " . $this -> error , LOG_ERR );
2018-08-30 09:40:04 +02:00
}
}
2020-11-26 09:16:16 +01:00
// Delete record into ECM index and physically
if ( ! $error ) {
$res = $this -> deleteEcmFiles ( 0 ); // Deleting files physically is done later with the dol_delete_dir_recursive
2023-11-13 12:24:47 +01:00
$res = $this -> deleteEcmFiles ( 1 ); // Deleting files physically is done later with the dol_delete_dir_recursive
2020-12-01 02:41:19 +01:00
if ( ! $res ) {
2020-11-26 09:16:16 +01:00
$error ++ ;
}
}
2020-09-12 04:25:54 +02:00
2020-11-26 09:16:16 +01:00
if ( ! $error ) {
// We remove directory
$ref = dol_sanitizeFileName ( $this -> ref );
if ( $conf -> commande -> multidir_output [ $this -> entity ] && ! empty ( $this -> ref )) {
$dir = $conf -> commande -> multidir_output [ $this -> entity ] . " / " . $ref ;
$file = $dir . " / " . $ref . " .pdf " ;
if ( file_exists ( $file )) {
2018-08-30 09:40:04 +02:00
dol_delete_preview ( $this );
2020-11-26 09:16:16 +01:00
if ( ! dol_delete_file ( $file , 0 , 0 , 0 , $this )) {
$this -> error = 'ErrorFailToDeleteFile' ;
$this -> errors [] = $this -> error ;
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return 0 ;
}
}
2020-11-26 09:16:16 +01:00
if ( file_exists ( $dir )) {
$res = @ dol_delete_dir_recursive ( $dir );
if ( ! $res ) {
$this -> error = 'ErrorFailToDeleteDir' ;
$this -> errors [] = $this -> error ;
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
return 0 ;
}
}
}
}
2020-11-26 09:16:16 +01:00
if ( ! $error ) {
dol_syslog ( get_class ( $this ) . " ::delete " . $this -> id . " by " . $user -> id , LOG_DEBUG );
2018-08-30 09:40:04 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
$this -> db -> rollback ();
2020-11-26 09:16:16 +01:00
return - 1 ;
2018-08-30 09:40:04 +02:00
}
}
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Load indicators for dashboard ( this -> nbtodo and this -> nbtodolate )
*
* @ param User $user Object user
2023-07-31 03:00:05 +02:00
* @ param string $mode Mode ( 'toship' , 'tobill' , 'shippedtobill' )
2023-12-06 15:46:39 +01:00
* @ return WorkboardResponse | int Return integer < 0 if KO , WorkboardResponse if OK
2018-08-30 09:40:04 +02:00
*/
2023-07-31 02:36:10 +02:00
public function load_board ( $user , $mode )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2018-08-30 09:40:04 +02:00
global $conf , $langs ;
$clause = " WHERE " ;
$sql = " SELECT c.rowid, c.date_creation as datec, c.date_commande, c.date_livraison as delivery_date, c.fk_statut, c.total_ht " ;
2024-09-26 17:10:25 +02:00
$sql .= " FROM " . MAIN_DB_PREFIX . $this -> table_element . " as c " ;
2025-01-13 11:58:16 +01:00
if ( empty ( $user -> socid ) && ! $user -> hasRight ( 'societe' , 'client' , 'voir' )) {
2020-01-30 01:48:28 +01:00
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " societe_commerciaux as sc ON c.fk_soc = sc.fk_soc " ;
2021-08-23 17:41:11 +02:00
$sql .= " WHERE sc.fk_user = " . (( int ) $user -> id );
2018-08-30 09:40:04 +02:00
$clause = " AND " ;
}
2020-01-30 01:48:28 +01:00
$sql .= $clause . " c.entity IN ( " . getEntity ( 'commande' ) . " ) " ;
2018-08-30 09:40:04 +02:00
//$sql.= " AND c.fk_statut IN (1,2,3) AND c.facture = 0";
2023-07-31 02:36:10 +02:00
if ( $mode == 'toship' ) {
// An order to ship is an open order (validated or in progress)
$sql .= " AND c.fk_statut IN ( " . self :: STATUS_VALIDATED . " , " . self :: STATUS_SHIPMENTONPROCESS . " ) " ;
}
if ( $mode == 'tobill' ) {
// An order to bill is an order not already billed
$sql .= " AND c.fk_statut IN ( " . self :: STATUS_VALIDATED . " , " . self :: STATUS_SHIPMENTONPROCESS . " , " . self :: STATUS_CLOSED . " ) AND c.facture = 0 " ;
}
if ( $mode == 'shippedtobill' ) {
// An order shipped and to bill is a delivered order not already billed
$sql .= " AND c.fk_statut IN ( " . self :: STATUS_CLOSED . " ) AND c.facture = 0 " ;
}
2021-02-23 20:46:19 +01:00
if ( $user -> socid ) {
2021-08-23 17:41:11 +02:00
$sql .= " AND c.fk_soc = " . (( int ) $user -> socid );
2021-02-23 20:46:19 +01:00
}
2018-08-30 09:40:04 +02:00
2020-01-30 01:48:28 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $resql ) {
2023-07-31 02:36:10 +02:00
$delay_warning = 0 ;
$label = $labelShort = $url = '' ;
if ( $mode == 'toship' ) {
$delay_warning = $conf -> commande -> client -> warning_delay / 60 / 60 / 24 ;
$url = DOL_URL_ROOT . '/commande/list.php?search_status=-2&mainmenu=commercial&leftmenu=orders' ;
$label = $langs -> transnoentitiesnoconv ( " OrdersToProcess " );
$labelShort = $langs -> transnoentitiesnoconv ( " Opened " );
}
if ( $mode == 'tobill' ) {
$url = DOL_URL_ROOT . '/commande/list.php?search_status=-3&search_billed=0&mainmenu=commercial&leftmenu=orders' ;
$label = $langs -> trans ( " OrdersToBill " ); // We set here bill but may be billed or ordered
$labelShort = $langs -> trans ( " ToBill " );
}
if ( $mode == 'shippedtobill' ) {
$url = DOL_URL_ROOT . '/commande/list.php?search_status=3&search_billed=0&mainmenu=commercial&leftmenu=orders' ;
$label = $langs -> trans ( " OrdersToBill " ); // We set here bill but may be billed or ordered
$labelShort = $langs -> trans ( " StatusOrderDelivered " ) . ' ' . $langs -> trans ( " and " ) . ' ' . $langs -> trans ( " ToBill " );
}
2018-08-30 09:40:04 +02:00
$response = new WorkboardResponse ();
2024-09-16 11:56:23 +02:00
2023-07-31 02:36:10 +02:00
$response -> warning_delay = $delay_warning ;
$response -> label = $label ;
$response -> labelShort = $labelShort ;
$response -> url = $url ;
2024-09-16 11:56:23 +02:00
$response -> url_late = DOL_URL_ROOT . '/commande/list.php?search_option=late&mainmenu=commercial&leftmenu=orders' ;
2020-01-30 01:48:28 +01:00
$response -> img = img_object ( '' , " order " );
2018-08-30 09:40:04 +02:00
$generic_commande = new Commande ( $this -> db );
2021-02-23 20:46:19 +01:00
while ( $obj = $this -> db -> fetch_object ( $resql )) {
2018-08-30 09:40:04 +02:00
$response -> nbtodo ++ ;
2020-01-30 01:48:28 +01:00
$response -> total += $obj -> total_ht ;
2018-08-30 09:40:04 +02:00
$generic_commande -> statut = $obj -> fk_statut ;
$generic_commande -> date_commande = $this -> db -> jdate ( $obj -> date_commande );
2020-11-11 18:08:40 +01:00
$generic_commande -> date = $this -> db -> jdate ( $obj -> date_commande );
$generic_commande -> delivery_date = $this -> db -> jdate ( $obj -> delivery_date );
2018-08-30 09:40:04 +02:00
2023-07-31 02:36:10 +02:00
if ( $mode == 'toship' && $generic_commande -> hasDelay ()) {
2018-08-30 09:40:04 +02:00
$response -> nbtodolate ++ ;
}
}
return $response ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
return - 1 ;
}
}
/**
* Return source label of order
*
* @ return string Label
*/
2019-02-25 00:56:48 +01:00
public function getLabelSource ()
2018-08-30 09:40:04 +02:00
{
global $langs ;
2019-11-13 19:37:08 +01:00
$label = $langs -> trans ( 'OrderSource' . $this -> source );
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( $label == 'OrderSource' ) {
return '' ;
}
2018-08-30 09:40:04 +02:00
return $label ;
}
/**
* Return status label of Order
*
* @ param int $mode 0 = Long label , 1 = Short label , 2 = Picto + Short label , 3 = Picto , 4 = Picto + Long label , 5 = Short label + Picto , 6 = Long label + Picto
* @ return string Label of status
*/
2019-02-25 00:56:48 +01:00
public function getLibStatut ( $mode )
2018-08-30 09:40:04 +02:00
{
return $this -> LibStatut ( $this -> statut , $this -> billed , $mode );
}
2019-02-25 00:56:48 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-08-30 09:40:04 +02:00
/**
* Return label of status
*
2019-11-01 23:58:14 +01:00
* @ param int $status Id status
2018-08-30 09:40:04 +02:00
* @ param int $billed If invoiced
* @ param int $mode 0 = Long label , 1 = Short label , 2 = Picto + Short label , 3 = Picto , 4 = Picto + Long label , 5 = Short label + Picto , 6 = Long label + Picto
* @ param int $donotshowbilled Do not show billed status after order status
* @ return string Label of status
*/
2019-11-01 23:58:14 +01:00
public function LibStatut ( $status , $billed , $mode , $donotshowbilled = 0 )
2018-08-30 09:40:04 +02:00
{
2020-09-08 21:27:28 +02:00
// phpcs:enable
2023-10-15 22:08:09 +02:00
global $langs , $hookmanager ;
2018-08-30 09:40:04 +02:00
$billedtext = '' ;
2021-02-23 20:46:19 +01:00
if ( empty ( $donotshowbilled )) {
$billedtext .= ( $billed ? ' - ' . $langs -> transnoentitiesnoconv ( " Billed " ) : '' );
}
2018-08-30 09:40:04 +02:00
2020-10-08 09:30:15 +02:00
$labelTooltip = '' ;
2020-01-30 01:48:28 +01:00
if ( $status == self :: STATUS_CANCELED ) {
2020-10-25 14:11:09 +01:00
$labelStatus = $langs -> transnoentitiesnoconv ( 'StatusOrderCanceled' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'StatusOrderCanceledShort' );
2020-09-08 21:27:28 +02:00
$statusType = 'status9' ;
2020-05-21 15:05:19 +02:00
} elseif ( $status == self :: STATUS_DRAFT ) {
2020-10-25 14:11:09 +01:00
$labelStatus = $langs -> transnoentitiesnoconv ( 'StatusOrderDraft' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'StatusOrderDraftShort' );
2020-09-08 21:27:28 +02:00
$statusType = 'status0' ;
2020-05-21 15:05:19 +02:00
} elseif ( $status == self :: STATUS_VALIDATED ) {
2020-10-25 14:11:09 +01:00
$labelStatus = $langs -> transnoentitiesnoconv ( 'StatusOrderValidated' ) . $billedtext ;
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'StatusOrderValidatedShort' ) . $billedtext ;
2020-09-08 21:27:28 +02:00
$statusType = 'status1' ;
2020-05-21 15:05:19 +02:00
} elseif ( $status == self :: STATUS_SHIPMENTONPROCESS ) {
2020-10-25 14:11:09 +01:00
$labelStatus = $langs -> transnoentitiesnoconv ( 'StatusOrderSent' ) . $billedtext ;
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'StatusOrderSentShort' ) . $billedtext ;
2022-09-13 00:11:00 +02:00
$labelTooltip = $langs -> transnoentitiesnoconv ( " StatusOrderSent " );
if ( ! empty ( $this -> delivery_date )) {
$labelTooltip .= ' - ' . $langs -> transnoentitiesnoconv ( " DateDeliveryPlanned " ) . dol_print_date ( $this -> delivery_date , 'day' ) . $billedtext ;
}
2020-09-08 21:27:28 +02:00
$statusType = 'status4' ;
2023-09-19 20:29:24 +02:00
} elseif ( $status == self :: STATUS_CLOSED ) {
2023-09-19 21:16:32 +02:00
$labelStatus = $langs -> transnoentitiesnoconv ( 'StatusOrderDelivered' ) . $billedtext ;
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'StatusOrderDeliveredShort' ) . $billedtext ;
2020-09-08 21:27:28 +02:00
$statusType = 'status6' ;
2020-05-21 15:05:19 +02:00
} else {
2020-10-25 14:11:09 +01:00
$labelStatus = $langs -> transnoentitiesnoconv ( 'Unknown' );
2020-09-08 21:27:28 +02:00
$labelStatusShort = '' ;
$statusType = '' ;
$mode = 0 ;
2019-03-07 11:37:54 +01:00
}
2019-03-15 15:07:52 +01:00
2022-11-08 16:24:05 +01:00
$parameters = array (
'status' => $status ,
'mode' => $mode ,
'billed' => $billed ,
'donotshowbilled' => $donotshowbilled
);
2022-11-08 16:21:32 +01:00
2022-11-08 16:24:05 +01:00
$reshook = $hookmanager -> executeHooks ( 'LibStatut' , $parameters , $this ); // Note that $action and $object may have been modified by hook
2022-11-08 16:21:32 +01:00
2022-11-08 16:24:05 +01:00
if ( $reshook > 0 ) {
2022-11-08 16:21:32 +01:00
return $hookmanager -> resPrint ;
}
2022-11-08 16:24:05 +01:00
2020-10-08 09:30:15 +02:00
return dolGetStatus ( $labelStatus , $labelStatusShort , '' , $statusType , $mode , '' , array ( 'tooltip' => $labelTooltip ));
2015-01-10 01:07:18 +01:00
}
2023-01-30 23:24:23 +01:00
/**
* getTooltipContentArray
2023-08-15 14:44:03 +02:00
*
2024-09-23 03:24:19 +02:00
* @ param array < string , mixed > $params params to construct tooltip data
* @ since v18
* @ return array { picto ? : string , ref ? : string , refsupplier ? : string , label ? : string , date ? : string , date_echeance ? : string , amountht ? : string , total_ht ? : string , totaltva ? : string , amountlt1 ? : string , amountlt2 ? : string , amountrevenustamp ? : string , totalttc ? : string } | array { optimize : string }
2023-01-30 23:24:23 +01:00
*/
2023-01-31 22:43:54 +01:00
public function getTooltipContentArray ( $params )
2023-01-30 23:24:23 +01:00
{
global $conf , $langs , $user ;
2023-04-25 09:46:12 +02:00
$langs -> load ( 'orders' );
2023-01-30 23:24:23 +01:00
$datas = [];
2023-03-13 09:54:19 +01:00
$nofetch = ! empty ( $params [ 'nofetch' ]);
2023-01-30 23:24:23 +01:00
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'MAIN_OPTIMIZEFORTEXTBROWSER' )) {
2023-01-30 23:24:23 +01:00
return [ 'optimize' => $langs -> trans ( " Order " )];
}
2023-01-31 22:43:54 +01:00
if ( $user -> hasRight ( 'commande' , 'lire' )) {
2024-11-07 05:07:41 +01:00
$datas [ 'picto' ] = img_picto ( '' , $this -> picto , '' , 0 , 0 , 0 , '' , 'paddingrightonly' ) . '<u>' . $langs -> trans ( " Order " ) . '</u>' ;
2023-01-30 23:24:23 +01:00
if ( isset ( $this -> statut )) {
2023-05-31 13:53:41 +02:00
$datas [ 'status' ] = ' ' . $this -> getLibStatut ( 5 );
2023-01-30 23:24:23 +01:00
}
$datas [ 'Ref' ] = '<br><b>' . $langs -> trans ( 'Ref' ) . ':</b> ' . $this -> ref ;
2023-03-13 09:54:19 +01:00
if ( ! $nofetch ) {
$langs -> load ( 'companies' );
if ( empty ( $this -> thirdparty )) {
$this -> fetch_thirdparty ();
}
2023-03-14 22:27:35 +01:00
$datas [ 'customer' ] = '<br><b>' . $langs -> trans ( 'Customer' ) . ':</b> ' . $this -> thirdparty -> getNomUrl ( 1 , '' , 0 , 1 );
2023-03-13 09:54:19 +01:00
}
2023-03-13 09:55:47 +01:00
$datas [ 'RefCustomer' ] = '<br><b>' . $langs -> trans ( 'RefCustomer' ) . ':</b> ' . ( empty ( $this -> ref_customer ) ? ( empty ( $this -> ref_client ) ? '' : $this -> ref_client ) : $this -> ref_customer );
2023-03-14 22:27:35 +01:00
if ( ! $nofetch ) {
$langs -> load ( 'project' );
2024-06-15 16:03:53 +02:00
if ( is_null ( $this -> project ) || ( is_object ( $this -> project ) && $this -> project -> isEmpty ())) {
2024-10-26 22:43:44 +02:00
$res = $this -> fetchProject ();
2024-06-15 16:03:53 +02:00
if ( $res > 0 && $this -> project instanceof Project ) {
2025-02-10 21:20:09 +01:00
$datas [ 'project' ] = '<br><b>' . $langs -> trans ( 'Project' ) . ':</b> ' . $this -> project -> getNomUrl ( 1 , '' , 0 , '1' );
2023-03-14 22:27:35 +01:00
}
}
}
2023-01-30 23:24:23 +01:00
if ( ! empty ( $this -> total_ht )) {
$datas [ 'AmountHT' ] = '<br><b>' . $langs -> trans ( 'AmountHT' ) . ':</b> ' . price ( $this -> total_ht , 0 , $langs , 0 , - 1 , - 1 , $conf -> currency );
}
if ( ! empty ( $this -> total_tva )) {
$datas [ 'VAT' ] = '<br><b>' . $langs -> trans ( 'VAT' ) . ':</b> ' . price ( $this -> total_tva , 0 , $langs , 0 , - 1 , - 1 , $conf -> currency );
}
if ( ! empty ( $this -> total_ttc )) {
$datas [ 'AmountTTC' ] = '<br><b>' . $langs -> trans ( 'AmountTTC' ) . ':</b> ' . price ( $this -> total_ttc , 0 , $langs , 0 , - 1 , - 1 , $conf -> currency );
}
if ( ! empty ( $this -> date )) {
$datas [ 'Date' ] = '<br><b>' . $langs -> trans ( 'Date' ) . ':</b> ' . dol_print_date ( $this -> date , 'day' );
}
if ( ! empty ( $this -> delivery_date )) {
$datas [ 'DeliveryDate' ] = '<br><b>' . $langs -> trans ( 'DeliveryDate' ) . ':</b> ' . dol_print_date ( $this -> delivery_date , 'dayhour' );
}
}
return $datas ;
}
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
/**
2024-08-07 01:20:43 +02:00
* Return clickable link of object ( with eventually picto )
2018-08-30 09:40:04 +02:00
*
* @ param int $withpicto Add picto into link
* @ param string $option Where point the link ( 0 => main card , 1 , 2 => shipment , 'nolink' => No link )
* @ param int $max Max length to show
* @ param int $short ? ? ?
* @ param int $notooltip 1 = Disable tooltip
* @ param int $save_lastsearch_value - 1 = Auto , 0 = No save of lastsearch_values when clicking , 1 = Save lastsearch_values whenclicking
2020-02-16 12:05:00 +01:00
* @ param int $addlinktonotes Add link to notes
2022-02-04 15:01:32 +01:00
* @ param string $target attribute target for link
2018-08-30 09:40:04 +02:00
* @ return string String with URL
*/
2022-02-15 09:34:51 +01:00
public function getNomUrl ( $withpicto = 0 , $option = '' , $max = 0 , $short = 0 , $notooltip = 0 , $save_lastsearch_value = - 1 , $addlinktonotes = 0 , $target = '' )
2018-08-30 09:40:04 +02:00
{
2022-02-15 18:14:44 +01:00
global $conf , $langs , $user , $hookmanager ;
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( ! empty ( $conf -> dol_no_mouse_hover )) {
$notooltip = 1 ; // Force disable tooltips
}
2011-09-12 19:08:02 +02:00
2019-11-13 19:37:08 +01:00
$result = '' ;
2017-06-09 09:25:15 +02:00
2024-03-12 11:07:18 +01:00
if ( isModEnabled ( " shipping " ) && ( $option == '1' || $option == '2' )) {
2021-02-23 20:46:19 +01:00
$url = DOL_URL_ROOT . '/expedition/shipment.php?id=' . $this -> id ;
} else {
$url = DOL_URL_ROOT . '/commande/card.php?id=' . $this -> id ;
}
2012-03-18 19:23:01 +01:00
2023-10-15 15:32:35 +02:00
if ( ! $user -> hasRight ( 'commande' , 'lire' )) {
2018-08-30 09:40:04 +02:00
$option = 'nolink' ;
2021-02-23 20:46:19 +01:00
}
2012-03-18 19:23:01 +01:00
2021-02-23 20:46:19 +01:00
if ( $option !== 'nolink' ) {
2018-09-04 11:23:28 +02:00
// Add param to save lastsearch_values or not
2019-11-13 19:37:08 +01:00
$add_save_lastsearch_values = ( $save_lastsearch_value == 1 ? 1 : 0 );
2023-09-10 17:41:22 +02:00
if ( $save_lastsearch_value == - 1 && isset ( $_SERVER [ " PHP_SELF " ]) && preg_match ( '/list\.php/' , $_SERVER [ " PHP_SELF " ])) {
2021-02-23 20:46:19 +01:00
$add_save_lastsearch_values = 1 ;
}
if ( $add_save_lastsearch_values ) {
$url .= '&save_lastsearch_values=1' ;
}
2018-09-04 11:23:28 +02:00
}
2018-03-13 18:04:18 +01:00
2021-02-23 20:46:19 +01:00
if ( $short ) {
return $url ;
}
2023-02-06 22:21:54 +01:00
$params = [
'id' => $this -> id ,
'objecttype' => $this -> element ,
'option' => $option ,
2023-03-13 09:54:19 +01:00
'nofetch' => 1 ,
2023-02-06 22:21:54 +01:00
];
2023-02-05 20:41:29 +01:00
$classfortooltip = 'classfortooltip' ;
$dataparams = '' ;
if ( getDolGlobalInt ( 'MAIN_ENABLE_AJAX_TOOLTIP' )) {
$classfortooltip = 'classforajaxtooltip' ;
2023-04-03 19:51:40 +02:00
$dataparams = ' data-params="' . dol_escape_htmltag ( json_encode ( $params )) . '"' ;
$label = '' ;
} else {
$label = implode ( $this -> getTooltipContentArray ( $params ));
2023-02-05 20:41:29 +01:00
}
2023-02-06 22:21:54 +01:00
$linkclose = '' ;
2023-02-14 22:56:12 +01:00
if ( empty ( $notooltip ) && $user -> hasRight ( 'commande' , 'lire' )) {
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'MAIN_OPTIMIZEFORTEXTBROWSER' )) {
2020-04-20 03:00:10 +02:00
$label = $langs -> trans ( " Order " );
2025-01-09 02:01:49 +01:00
$linkclose .= ' alt="' . dolPrintHTMLForAttribute ( $label ) . '"' ;
2018-08-30 09:40:04 +02:00
}
2025-01-09 02:01:49 +01:00
$linkclose .= ( $label ? ' title="' . dolPrintHTMLForAttribute ( $label ) . '"' : ' title="tocomplete"' );
2023-02-05 20:41:29 +01:00
$linkclose .= $dataparams . ' class="' . $classfortooltip . '"' ;
2022-02-04 14:42:07 +01:00
2023-01-30 23:24:23 +01:00
$target_value = array ( '_self' , '_blank' , '_parent' , '_top' );
2022-02-04 14:42:07 +01:00
if ( in_array ( $target , $target_value )) {
2022-03-07 17:10:28 +01:00
$linkclose .= ' target="' . dol_escape_htmltag ( $target ) . '"' ;
2022-02-04 14:38:34 +01:00
}
2018-09-04 11:23:28 +02:00
}
2018-08-30 09:40:04 +02:00
2018-09-04 11:23:28 +02:00
$linkstart = '<a href="' . $url . '"' ;
2019-11-13 19:37:08 +01:00
$linkstart .= $linkclose . '>' ;
$linkend = '</a>' ;
2018-08-30 09:40:04 +02:00
2018-09-04 11:23:28 +02:00
if ( $option === 'nolink' ) {
$linkstart = '' ;
$linkend = '' ;
}
2018-08-30 09:40:04 +02:00
2018-09-04 11:23:28 +02:00
$result .= $linkstart ;
2021-02-23 20:46:19 +01:00
if ( $withpicto ) {
2023-04-27 15:55:21 +02:00
$result .= img_object (( $notooltip ? '' : $label ), $this -> picto , (( $withpicto != 2 ) ? 'class="paddingright"' : '' ), 0 , 0 , $notooltip ? 0 : 1 );
2021-02-23 20:46:19 +01:00
}
if ( $withpicto != 2 ) {
$result .= $this -> ref ;
}
2018-09-04 11:23:28 +02:00
$result .= $linkend ;
2018-08-30 09:40:04 +02:00
2021-02-23 20:46:19 +01:00
if ( $addlinktonotes ) {
2020-01-15 19:49:45 +01:00
$txttoshow = ( $user -> socid > 0 ? $this -> note_public : $this -> note_private );
2021-02-23 20:46:19 +01:00
if ( $txttoshow ) {
2020-01-15 19:49:45 +01:00
$notetoshow = $langs -> trans ( " ViewPrivateNote " ) . ':<br>' . dol_string_nohtmltag ( $txttoshow , 1 );
$result .= ' <span class="note inline-block">' ;
$result .= '<a href="' . DOL_URL_ROOT . '/commande/note.php?id=' . $this -> id . '" class="classfortooltip" title="' . dol_escape_htmltag ( $notetoshow ) . '">' ;
$result .= img_picto ( '' , 'note' );
$result .= '</a>' ;
//$result.=img_picto($langs->trans("ViewNote"),'object_generic');
//$result.='</a>';
$result .= '</span>' ;
}
}
2022-02-15 10:51:06 +01:00
global $action ;
2022-02-15 11:02:22 +01:00
$hookmanager -> initHooks ( array ( $this -> element . 'dao' ));
2024-02-28 23:01:01 +01:00
$parameters = array ( 'id' => $this -> id , 'getnomurl' => & $result );
2022-02-15 10:51:06 +01:00
$reshook = $hookmanager -> executeHooks ( 'getNomUrl' , $parameters , $this , $action ); // Note that $action and $object may have been modified by some hooks
if ( $reshook > 0 ) {
$result = $hookmanager -> resPrint ;
} else {
$result .= $hookmanager -> resPrint ;
}
2018-09-04 11:23:28 +02:00
return $result ;
2018-08-30 09:40:04 +02:00
}
/**
2024-01-14 12:26:37 +01:00
* Charge les information d 'ordre info dans l' objet commande
2018-08-30 09:40:04 +02:00
*
* @ param int $id Id of order
* @ return void
*/
2019-02-25 00:56:48 +01:00
public function info ( $id )
2018-08-30 09:40:04 +02:00
{
$sql = 'SELECT c.rowid, date_creation as datec, tms as datem,' ;
2019-11-13 19:37:08 +01:00
$sql .= ' date_valid as datev,' ;
$sql .= ' date_cloture as datecloture,' ;
$sql .= ' fk_user_author, fk_user_valid, fk_user_cloture' ;
2024-09-26 17:10:25 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this -> table_element . ' as c' ;
2021-03-14 11:48:39 +01:00
$sql .= ' WHERE c.rowid = ' . (( int ) $id );
2019-11-13 19:37:08 +01:00
$result = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $result ) {
if ( $this -> db -> num_rows ( $result )) {
2018-08-30 09:40:04 +02:00
$obj = $this -> db -> fetch_object ( $result );
$this -> id = $obj -> rowid ;
2021-02-23 20:46:19 +01:00
if ( $obj -> fk_user_author ) {
2022-07-03 12:54:58 +02:00
$this -> user_creation_id = $obj -> fk_user_author ;
2018-08-30 09:40:04 +02:00
}
2021-02-23 20:46:19 +01:00
if ( $obj -> fk_user_valid ) {
2022-07-03 12:54:58 +02:00
$this -> user_validation_id = $obj -> fk_user_valid ;
2018-08-30 09:40:04 +02:00
}
2021-02-23 20:46:19 +01:00
if ( $obj -> fk_user_cloture ) {
2022-07-03 12:54:58 +02:00
$this -> user_closing_id = $obj -> fk_user_cloture ;
2018-08-30 09:40:04 +02:00
}
$this -> date_creation = $this -> db -> jdate ( $obj -> datec );
$this -> date_modification = $this -> db -> jdate ( $obj -> datem );
$this -> date_validation = $this -> db -> jdate ( $obj -> datev );
$this -> date_cloture = $this -> db -> jdate ( $obj -> datecloture );
}
$this -> db -> free ( $result );
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
dol_print_error ( $this -> db );
}
}
/**
* Initialise an instance with random values .
* Used to build previews or test instances .
* id must be 0 if object instance is a specimen .
*
2024-03-02 16:38:35 +01:00
* @ return int
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function initAsSpecimen ()
2018-08-30 09:40:04 +02:00
{
2020-01-21 00:16:11 +01:00
global $conf , $langs ;
2018-08-30 09:40:04 +02:00
dol_syslog ( get_class ( $this ) . " ::initAsSpecimen " );
// Load array of products prodids
$num_prods = 0 ;
$prodids = array ();
$sql = " SELECT rowid " ;
2019-11-13 19:37:08 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " product " ;
$sql .= " WHERE entity IN ( " . getEntity ( 'product' ) . " ) " ;
2020-08-19 01:43:48 +02:00
$sql .= $this -> db -> plimit ( 100 );
2018-08-30 09:40:04 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $resql ) {
2018-08-30 09:40:04 +02:00
$num_prods = $this -> db -> num_rows ( $resql );
$i = 0 ;
2021-02-23 20:46:19 +01:00
while ( $i < $num_prods ) {
2018-08-30 09:40:04 +02:00
$i ++ ;
$row = $this -> db -> fetch_row ( $resql );
$prodids [ $i ] = $row [ 0 ];
}
}
2024-01-14 12:26:37 +01:00
// Initialise parameters
2019-11-13 19:37:08 +01:00
$this -> id = 0 ;
2018-08-30 09:40:04 +02:00
$this -> ref = 'SPECIMEN' ;
2019-11-13 19:37:08 +01:00
$this -> specimen = 1 ;
2023-03-08 21:39:05 +01:00
$this -> entity = $conf -> entity ;
2018-08-30 09:40:04 +02:00
$this -> socid = 1 ;
$this -> date = time ();
2019-11-13 19:37:08 +01:00
$this -> date_lim_reglement = $this -> date + 3600 * 24 * 30 ;
2018-08-30 09:40:04 +02:00
$this -> cond_reglement_code = 'RECEP' ;
$this -> mode_reglement_code = 'CHQ' ;
$this -> availability_code = 'DSP' ;
$this -> demand_reason_code = 'SRC_00' ;
2020-01-21 00:16:11 +01:00
2019-11-13 19:37:08 +01:00
$this -> note_public = 'This is a comment (public)' ;
$this -> note_private = 'This is a comment (private)' ;
2020-01-21 00:16:11 +01:00
$this -> multicurrency_tx = 1 ;
$this -> multicurrency_code = $conf -> currency ;
2024-01-10 21:51:32 +01:00
$this -> status = $this :: STATUS_DRAFT ;
2018-08-30 09:40:04 +02:00
// Lines
2024-11-21 19:34:36 +01:00
$nbp = min ( 1000 , GETPOSTINT ( 'nblines' ) ? GETPOSTINT ( 'nblines' ) : 5 ); // We can force the nb of lines to test from command line (but not more than 1000)
2018-08-30 09:40:04 +02:00
$xnbp = 0 ;
2024-11-21 19:34:36 +01:00
2021-02-23 20:46:19 +01:00
while ( $xnbp < $nbp ) {
2019-11-13 19:37:08 +01:00
$line = new OrderLine ( $this -> db );
2018-08-30 09:40:04 +02:00
2019-11-13 19:37:08 +01:00
$line -> desc = $langs -> trans ( " Description " ) . " " . $xnbp ;
$line -> qty = 1 ;
$line -> subprice = 100 ;
$line -> price = 100 ;
$line -> tva_tx = 20 ;
2021-02-23 20:46:19 +01:00
if ( $xnbp == 2 ) {
2019-11-13 19:37:08 +01:00
$line -> total_ht = 50 ;
$line -> total_ttc = 60 ;
$line -> total_tva = 10 ;
$line -> remise_percent = 50 ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$line -> total_ht = 100 ;
$line -> total_ttc = 120 ;
$line -> total_tva = 20 ;
$line -> remise_percent = 0 ;
2018-08-30 09:40:04 +02:00
}
2021-02-23 20:46:19 +01:00
if ( $num_prods > 0 ) {
2018-08-30 09:40:04 +02:00
$prodid = mt_rand ( 1 , $num_prods );
2019-11-13 19:37:08 +01:00
$line -> fk_product = $prodids [ $prodid ];
$line -> product_ref = 'SPECIMEN' ;
2018-08-30 09:40:04 +02:00
}
2016-07-08 18:30:50 +02:00
2019-11-13 19:37:08 +01:00
$this -> lines [ $xnbp ] = $line ;
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
$this -> total_ht += $line -> total_ht ;
$this -> total_tva += $line -> total_tva ;
$this -> total_ttc += $line -> total_ttc ;
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
$xnbp ++ ;
}
2024-03-02 16:38:35 +01:00
return 1 ;
2018-08-30 09:40:04 +02:00
}
2011-09-12 19:08:02 +02:00
2018-08-30 09:40:04 +02:00
/**
2024-01-14 12:26:37 +01:00
* Load the indicators this -> nb for the state board
2018-08-30 09:40:04 +02:00
*
2024-01-14 12:26:37 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2018-08-30 09:40:04 +02:00
*/
2024-01-18 18:55:53 +01:00
public function loadStateBoard ()
2018-08-30 09:40:04 +02:00
{
global $user ;
2020-01-30 01:48:28 +01:00
$this -> nb = array ();
2018-08-30 09:40:04 +02:00
$clause = " WHERE " ;
$sql = " SELECT count(co.rowid) as nb " ;
2024-09-26 17:10:25 +02:00
$sql .= " FROM " . MAIN_DB_PREFIX . $this -> table_element . " as co " ;
2020-01-30 01:48:28 +01:00
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " societe as s ON co.fk_soc = s.rowid " ;
2025-01-13 11:58:16 +01:00
if ( empty ( $user -> socid ) && ! $user -> hasRight ( 'societe' , 'client' , 'voir' )) {
2020-01-30 01:48:28 +01:00
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " societe_commerciaux as sc ON s.rowid = sc.fk_soc " ;
2021-08-23 17:41:11 +02:00
$sql .= " WHERE sc.fk_user = " . (( int ) $user -> id );
2018-08-30 09:40:04 +02:00
$clause = " AND " ;
}
2020-01-30 01:48:28 +01:00
$sql .= " " . $clause . " co.entity IN ( " . getEntity ( 'commande' ) . " ) " ;
2018-08-30 09:40:04 +02:00
2020-01-30 01:48:28 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 20:46:19 +01:00
if ( $resql ) {
while ( $obj = $this -> db -> fetch_object ( $resql )) {
2020-01-30 01:48:28 +01:00
$this -> nb [ " orders " ] = $obj -> nb ;
2018-08-30 09:40:04 +02:00
}
$this -> db -> free ( $resql );
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-08-30 09:40:04 +02:00
dol_print_error ( $this -> db );
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2018-08-30 09:40:04 +02:00
return - 1 ;
}
}
/**
2016-03-14 14:38:30 +01:00
* Create an array of order lines
*
* @ return int > 0 if OK , < 0 if KO
2018-08-30 09:40:04 +02:00
*/
2019-02-25 00:56:48 +01:00
public function getLinesArray ()
2018-08-30 09:40:04 +02:00
{
return $this -> fetch_lines ();
}
2007-05-05 00:37:06 +02:00
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
/**
2016-10-02 20:15:11 +02:00
* Create a document onto disk according to template module .
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
*
2016-10-02 20:15:11 +02:00
* @ param string $modele Force template to use ( '' to not force )
2024-01-14 12:26:37 +01:00
* @ param Translate $outputlangs object lang a utiliser pour traduction
2024-09-30 10:05:24 +02:00
* @ param int < 0 , 1 > $hidedetails Hide details of lines
* @ param int < 0 , 1 > $hidedesc Hide description
* @ param int < 0 , 1 > $hideref Hide ref
* @ param array < string , mixed > $moreparams Array to provide more information
* @ return int < 0 , 1 > 0 if KO , 1 if OK
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
*/
2019-01-27 15:20:16 +01:00
public function generateDocument ( $modele , $outputlangs , $hidedetails = 0 , $hidedesc = 0 , $hideref = 0 , $moreparams = null )
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
{
2025-02-06 12:04:41 +01:00
global $langs ;
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
$langs -> load ( " orders " );
2020-08-04 11:02:16 +02:00
$outputlangs -> load ( " products " );
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
2020-01-30 01:48:28 +01:00
if ( ! dol_strlen ( $modele )) {
2017-01-16 21:16:05 +01:00
$modele = 'einstein' ;
2020-12-13 13:34:21 +01:00
if ( ! empty ( $this -> model_pdf )) {
$modele = $this -> model_pdf ;
2023-11-27 11:39:32 +01:00
} elseif ( getDolGlobalString ( 'COMMANDE_ADDON_PDF' )) {
2024-01-05 04:18:53 +01:00
$modele = getDolGlobalString ( 'COMMANDE_ADDON_PDF' );
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
}
}
2014-09-21 18:16:14 +02:00
$modelpath = " core/modules/commande/doc/ " ;
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
2018-06-15 09:47:28 +02:00
return $this -> commonGenerateDocument ( $modelpath , $modele , $outputlangs , $hidedetails , $hidedesc , $hideref , $moreparams );
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
}
2015-04-18 18:11:01 +02:00
/**
* Function used to replace a thirdparty id with another one .
*
2022-12-28 13:27:13 +01:00
* @ param DoliDB $dbs Database handler , because function is static we name it $dbs not $db to avoid breaking coding test
* @ param int $origin_id Old thirdparty id
* @ param int $dest_id New thirdparty id
* @ return bool
2015-04-18 18:11:01 +02:00
*/
2022-12-28 13:27:13 +01:00
public static function replaceThirdparty ( DoliDB $dbs , $origin_id , $dest_id )
2015-04-18 18:11:01 +02:00
{
$tables = array (
2018-08-30 10:30:52 +02:00
'commande'
2015-04-18 18:11:01 +02:00
);
2022-12-28 13:27:13 +01:00
return CommonObject :: commonReplaceThirdparty ( $dbs , $origin_id , $dest_id , $tables );
2015-04-18 18:11:01 +02:00
}
2015-09-05 10:42:54 +02:00
2021-11-23 21:38:29 +01:00
/**
* Function used to replace a product id with another one .
*
* @ param DoliDB $db Database handler
* @ param int $origin_id Old product id
* @ param int $dest_id New product id
* @ return bool
*/
public static function replaceProduct ( DoliDB $db , $origin_id , $dest_id )
{
$tables = array (
'commandedet' ,
);
return CommonObject :: commonReplaceProduct ( $db , $origin_id , $dest_id , $tables );
}
2018-08-30 09:40:04 +02:00
/**
2022-10-12 15:29:30 +02:00
* Is the sales order delayed ?
2018-08-30 09:40:04 +02:00
*
* @ return bool true if late , false if not
*/
public function hasDelay ()
{
global $conf ;
2019-11-13 19:37:08 +01:00
if ( ! ( $this -> statut > Commande :: STATUS_DRAFT && $this -> statut < Commande :: STATUS_CLOSED )) {
return false ; // Never late if not inside this status range
2018-08-30 09:40:04 +02:00
}
$now = dol_now ();
2023-05-31 21:36:11 +02:00
return max ( $this -> date , $this -> delivery_date ) < ( $now - $conf -> commande -> client -> warning_delay );
2018-08-30 09:40:04 +02:00
}
/**
* Show the customer delayed info
*
* @ return string Show delayed information
*/
public function showDelay ()
{
global $conf , $langs ;
2023-05-31 21:36:11 +02:00
if ( empty ( $this -> delivery_date )) {
2023-10-17 10:36:11 +02:00
$text = $langs -> trans ( " OrderDate " ) . ' ' . dol_print_date ( $this -> date , 'day' );
2021-02-23 20:46:19 +01:00
} else {
2023-10-17 10:36:11 +02:00
$text = $text = $langs -> trans ( " DeliveryDate " ) . ' ' . dol_print_date ( $this -> delivery_date , 'day' );
2021-02-23 20:46:19 +01:00
}
2019-11-13 19:37:08 +01:00
$text .= ' ' . ( $conf -> commande -> client -> warning_delay > 0 ? '+' : '-' ) . ' ' . round ( abs ( $conf -> commande -> client -> warning_delay ) / 3600 / 24 , 1 ) . ' ' . $langs -> trans ( " days " ) . ' < ' . $langs -> trans ( " Today " );
2018-08-30 09:40:04 +02:00
return $text ;
}
2024-07-16 15:22:54 +02:00
/**
* Set signed status
*
2024-09-30 10:05:24 +02:00
* @ param User $user Object user that modify
* @ param int $status Newsigned status to set ( often a constant like self :: STATUS_XXX )
* @ param int < 0 , 1 > $notrigger 1 = Does not execute triggers , 0 = Execute triggers
* @ param string $triggercode Trigger code to use
2024-07-16 15:22:54 +02:00
* @ return int 0 < if KO , > 0 if OK
*/
public function setSignedStatus ( User $user , int $status = 0 , int $notrigger = 0 , $triggercode = '' ) : int
{
return $this -> setSignedStatusCommon ( $user , $status , $notrigger , $triggercode );
}
2005-09-15 02:37:03 +02:00
}