2004-10-19 22:43:23 +02:00
< ? php
2012-10-31 09:50:20 +01:00
/* Copyright ( C ) 2003 - 2008 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2018-10-27 14:43:12 +02:00
* Copyright ( C ) 2005 - 2012 Regis Houssin < regis . houssin @ inodbox . com >
2012-10-31 09:50:20 +01:00
* Copyright ( C ) 2007 Franky Van Liedekerke < franky . van . liedekerke @ telenet . be >
* Copyright ( C ) 2006 - 2012 Laurent Destailleur < eldy @ users . sourceforge . net >
2020-09-03 12:43:38 +02:00
* Copyright ( C ) 2011 - 2020 Juanjo Menent < jmenent @ 2 byte . es >
2013-06-20 18:37:23 +02:00
* Copyright ( C ) 2013 Florian Henry < florian . henry @ open - concept . pro >
2014-03-07 11:35:16 +01:00
* Copyright ( C ) 2014 Cedric GROSS < c . gross @ kreiz - it . fr >
2015-04-18 20:50:03 +02:00
* Copyright ( C ) 2014 - 2015 Marcos García < marcosgdf @ gmail . com >
2017-10-18 17:01:17 +02:00
* Copyright ( C ) 2014 - 2017 Francis Appels < francis . appels @ yahoo . com >
2016-02-15 01:37:23 +01:00
* Copyright ( C ) 2015 Claudio Aschieri < c . aschieri @ 19. coop >
2024-03-14 16:44:07 +01:00
* Copyright ( C ) 2016 - 2024 Ferran Marcet < fmarcet @ 2 byte . es >
2018-09-12 22:59:15 +02:00
* Copyright ( C ) 2018 Nicolas ZABOURI < info @ inovea - conseil . com >
2025-01-27 19:55:39 +01:00
* Copyright ( C ) 2018 - 2025 Frédéric France < frederic . france @ free . fr >
2020-04-23 07:49:31 +02:00
* Copyright ( C ) 2020 Lenin Rivas < lenin @ leninrivas . com >
2025-01-19 02:30:36 +01:00
* Copyright ( C ) 2024 - 2025 MDW < mdeweerd @ users . noreply . github . com >
2024-09-13 03:09:53 +02:00
* Copyright ( C ) 2024 William Mead < william . mead @ manchenumerique . fr >
2003-11-13 18:36:45 +01:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2003-11-13 18:36:45 +01: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 />.
2003-11-13 18:36:45 +01:00
*/
2005-07-09 03:16:31 +02:00
/**
2010-06-05 15:27:11 +02:00
* \file htdocs / expedition / class / expedition . class . php
2009-11-12 14:33:55 +01:00
* \ingroup expedition
2024-01-13 19:48:41 +01:00
* \brief File of class managing the shipments
2008-05-26 23:27:50 +02:00
*/
2004-08-14 15:05:12 +02:00
2012-08-22 23:11:24 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php' ;
2024-09-12 22:04:35 +02:00
require_once DOL_DOCUMENT_ROOT . " /expedition/class/expeditionligne.class.php " ;
2020-09-16 02:50:18 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonincoterm.class.php' ;
2022-08-23 20:01:34 +02:00
if ( isModEnabled ( " propal " )) {
2021-02-25 22:38:35 +01:00
require_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php' ;
}
2024-02-27 15:30:37 +01:00
if ( isModEnabled ( 'order' )) {
2021-02-25 22:38:35 +01:00
require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php' ;
}
2021-09-27 15:41:58 +02:00
require_once DOL_DOCUMENT_ROOT . '/expedition/class/expeditionlinebatch.class.php' ;
2024-09-13 03:09:53 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonsignedobject.class.php' ;
2006-06-18 16:35:35 +02:00
2016-09-07 12:41:32 +02:00
2008-05-26 23:27:50 +02:00
/**
2012-03-14 14:00:20 +01:00
* Class to manage shipments
2024-09-13 03:09:53 +02:00
* @ property int $signed_status
* @ static array < int > $SIGNED_STATUSES
2008-05-26 23:27:50 +02:00
*/
2006-06-18 16:35:35 +02:00
class Expedition extends CommonObject
2003-11-13 18:36:45 +01:00
{
2020-09-16 02:50:18 +02:00
use CommonIncoterm ;
2024-09-13 03:09:53 +02:00
use CommonSignedObject ;
2020-09-16 02:50:18 +02:00
2018-08-23 18:35:45 +02:00
/**
* @ var string ID to identify managed object
*/
2019-11-13 19:37:08 +01:00
public $element = " shipping " ;
2018-09-01 23:46:13 +02:00
2018-10-06 12:01:00 +02:00
/**
2020-12-05 23:53:55 +01:00
* @ var string Field with ID of parent key if this field has a parent
2018-10-06 12:01:00 +02:00
*/
2019-11-13 19:37:08 +01:00
public $fk_element = " fk_expedition " ;
2018-09-01 23:46:13 +02:00
2018-08-22 18:48:53 +02:00
/**
* @ var string Name of table without prefix where object is stored
*/
2019-11-13 19:37:08 +01:00
public $table_element = " expedition " ;
2018-09-01 23:46:13 +02:00
2018-09-02 11:08:41 +02:00
/**
2020-12-05 23:53:55 +01:00
* @ var string Name of subtable line
2018-09-02 11:08:41 +02:00
*/
2019-11-13 19:37:08 +01:00
public $table_element_line = " expeditiondet " ;
2018-09-02 11:08:41 +02:00
2018-09-05 12:21:13 +02:00
/**
* @ var string String with name of icon for myobject . Must be the part after the 'object_' into object_myobject . png
*/
2020-04-20 15:57:15 +02:00
public $picto = 'dolly' ;
2017-06-23 11:12:17 +02:00
2022-11-17 10:48:44 +01:00
/**
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 .
2022-11-17 10:48:44 +01:00
*/
public $fields = array ();
2023-02-13 23:42:08 +01:00
/**
* @ var int ID of user author
*/
public $user_author_id ;
/**
* @ var int ID of user author
*/
public $fk_user_author ;
2022-11-17 10:48:44 +01:00
2024-10-03 19:40:34 +02:00
/**
* @ var int
*/
2018-09-02 11:08:41 +02:00
public $socid ;
2018-10-25 21:36:01 +02:00
2020-10-05 20:16:18 +02:00
/**
* @ var string Customer ref
* @ deprecated
* @ see $ref_customer
*/
public $ref_client ;
2018-10-25 21:36:01 +02:00
/**
* @ var string Customer ref
*/
2018-09-02 11:08:41 +02:00
public $ref_customer ;
2018-10-25 21:36:01 +02:00
/**
* @ var int warehouse id
*/
2018-09-02 11:08:41 +02:00
public $entrepot_id ;
2018-10-25 21:36:01 +02:00
/**
* @ var string Tracking number
*/
2018-09-02 11:08:41 +02:00
public $tracking_number ;
2018-10-25 21:36:01 +02:00
/**
* @ var string Tracking url
*/
2018-09-02 11:08:41 +02:00
public $tracking_url ;
2024-10-03 19:40:34 +02:00
/**
* @ var int < 0 , 1 >
*/
2018-09-02 11:08:41 +02:00
public $billed ;
2018-10-25 21:36:01 +02:00
2024-10-03 19:40:34 +02:00
/**
* @ var int | string
*/
2018-09-02 11:08:41 +02:00
public $trueWeight ;
2024-10-03 19:40:34 +02:00
/**
* @ var int
*/
2018-09-02 11:08:41 +02:00
public $weight_units ;
2024-10-03 19:40:34 +02:00
/**
* @ var int | string
*/
2018-09-02 11:08:41 +02:00
public $trueWidth ;
2024-10-03 19:40:34 +02:00
/**
2025-02-08 18:30:42 +01:00
* @ var int
2024-10-03 19:40:34 +02:00
*/
2018-09-02 11:08:41 +02:00
public $width_units ;
2024-10-03 19:40:34 +02:00
/**
* @ var int | string
*/
2018-09-02 11:08:41 +02:00
public $trueHeight ;
2024-10-03 19:40:34 +02:00
/**
2025-02-08 18:30:42 +01:00
* @ var int
2024-10-03 19:40:34 +02:00
*/
2018-09-02 11:08:41 +02:00
public $height_units ;
2024-10-03 19:40:34 +02:00
/**
* @ var int | string
*/
2018-09-02 11:08:41 +02:00
public $trueDepth ;
2024-10-03 19:40:34 +02:00
/**
2025-02-08 18:30:42 +01:00
* @ var int
2024-10-03 19:40:34 +02:00
*/
2018-09-02 11:08:41 +02:00
public $depth_units ;
2024-10-03 19:40:34 +02:00
/**
* @ var string A denormalized value
*/
2018-09-02 11:08:41 +02:00
public $trueSize ;
2019-11-10 12:00:19 +01:00
2024-10-03 19:40:34 +02:00
/**
* @ var int
*/
2023-11-14 01:52:42 +01:00
public $livraison_id ;
/**
2024-10-03 19:40:34 +02:00
* @ var float
2023-11-14 01:52:42 +01:00
*/
public $multicurrency_subprice ;
2024-10-03 19:40:34 +02:00
/**
* @ var int | string
*/
2023-11-14 01:52:42 +01:00
public $size_units ;
2024-10-03 19:40:34 +02:00
/**
* @ var int | string
*/
2023-11-14 01:52:42 +01:00
public $sizeH ;
2024-10-03 19:40:34 +02:00
/**
* @ var int | string
*/
2023-11-14 01:52:42 +01:00
public $sizeS ;
2024-10-03 19:40:34 +02:00
/**
* @ var int | string
*/
2023-11-14 01:52:42 +01:00
public $sizeW ;
2024-10-03 19:40:34 +02:00
/**
* @ var int | string
*/
2023-11-14 01:52:42 +01:00
public $weight ;
2019-11-10 12:01:34 +01:00
/**
2024-08-07 02:49:38 +02:00
* @ var int | string Date delivery planned
2019-11-10 12:01:34 +01:00
*/
public $date_delivery ;
2010-05-13 01:03:33 +02:00
2015-04-23 23:21:06 +02:00
/**
2024-10-03 19:40:34 +02:00
* @ var int | string
* @ deprecated Use $dateshipping
2019-04-04 18:33:12 +02:00
* @ see $date_shipping
2015-04-23 23:21:06 +02:00
*/
2018-09-02 11:08:41 +02:00
public $date ;
2015-04-23 23:21:06 +02:00
/**
2024-10-03 19:40:34 +02:00
* @ var int | string
* @ deprecated Use $dateshipping
2019-04-04 18:33:12 +02:00
* @ see $date_shipping
2015-04-23 23:21:06 +02:00
*/
2018-09-02 11:08:41 +02:00
public $date_expedition ;
2015-04-23 23:21:06 +02:00
/**
* Effective delivery date
2024-08-07 02:49:38 +02:00
* @ var int | string
2015-04-23 23:21:06 +02:00
*/
public $date_shipping ;
2012-03-14 14:00:20 +01:00
2019-11-10 12:01:34 +01:00
/**
2024-08-07 02:49:38 +02:00
* @ var int | string date_valid
2019-11-10 12:01:34 +01:00
*/
2018-09-02 11:08:41 +02:00
public $date_valid ;
2024-10-03 19:40:34 +02:00
/**
* @ var string []
*/
2018-09-02 11:08:41 +02:00
public $meths ;
2024-10-03 19:40:34 +02:00
/**
* @ var array < array < string , string >>
*/
2019-11-13 19:37:08 +01:00
public $listmeths ; // List of carriers
2013-04-11 21:53:41 +02:00
2023-02-13 23:42:08 +01:00
/**
* @ var int ID of order
*/
public $commande_id ;
/**
* @ var Commande order
*/
public $commande ;
/**
* @ var ExpeditionLigne [] array of shipping lines
*/
2020-11-28 14:47:39 +01:00
public $lines = array ();
2023-02-13 23:42:08 +01:00
// Multicurrency
/**
* @ var int Currency ID
*/
public $fk_multicurrency ;
/**
* @ var string multicurrency code
*/
public $multicurrency_code ;
2024-10-03 19:40:34 +02:00
/**
* @ var float
*/
2023-02-13 23:42:08 +01:00
public $multicurrency_tx ;
2024-10-03 19:40:34 +02:00
/**
* @ var float
*/
2023-02-13 23:42:08 +01:00
public $multicurrency_total_ht ;
2024-10-03 19:40:34 +02:00
/**
* @ var float
*/
2023-02-13 23:42:08 +01:00
public $multicurrency_total_tva ;
2024-10-03 19:40:34 +02:00
/**
* @ var float
*/
2023-02-13 23:42:08 +01:00
public $multicurrency_total_ttc ;
2020-11-28 14:47:39 +01:00
2020-10-28 17:49:52 +01:00
/**
2018-10-04 09:33:30 +02:00
* Draft status
*/
2016-06-09 22:40:21 +02:00
const STATUS_DRAFT = 0 ;
2018-10-04 09:33:30 +02:00
/**
* Validated status
2024-05-03 18:06:30 +02:00
* -> parcel is ready to be sent
* prev status : draft
* next status : closed or shipment_in_progress
2018-10-04 09:33:30 +02:00
*/
2016-06-09 22:40:21 +02:00
const STATUS_VALIDATED = 1 ;
2018-10-04 09:33:30 +02:00
/**
* Closed status
2024-05-03 18:06:30 +02:00
* -> parcel was received by customer / end of process
* prev status : validated or shipment_in_progress
2018-10-04 09:33:30 +02:00
*/
2016-06-09 22:40:21 +02:00
const STATUS_CLOSED = 2 ;
2016-09-07 12:41:32 +02:00
2020-04-23 07:49:31 +02:00
/**
* Canceled status
*/
const STATUS_CANCELED = - 1 ;
2016-09-07 12:41:32 +02:00
2024-05-03 18:06:30 +02:00
/**
* Expedition in progress
* -> package exit the warehouse and is now
* in the truck or into the hand of the deliverer
* prev status : validated
* next status : closed
*/
const STATUS_SHIPMENT_IN_PROGRESS = 3 ;
2008-10-25 13:16:39 +02:00
/**
2011-09-29 22:32:28 +02:00
* Constructor
*
2012-03-14 14:00:20 +01:00
* @ param DoliDB $db Database handler
2008-10-25 13:16:39 +02:00
*/
2019-02-24 23:32:09 +01:00
public function __construct ( $db )
2008-10-25 13:16:39 +02:00
{
2018-02-15 15:27:06 +01:00
global $conf ;
2012-03-14 14:00:20 +01:00
$this -> db = $db ;
2010-01-05 21:03:37 +01:00
2024-05-05 00:34:19 +02:00
$this -> ismultientitymanaged = 1 ;
$this -> isextrafieldmanaged = 1 ;
2009-12-17 16:52:37 +01:00
// List of long language codes for status
2023-11-24 10:10:24 +01:00
$this -> labelStatus = array ();
$this -> labelStatus [ - 1 ] = 'StatusSendingCanceled' ;
$this -> labelStatus [ 0 ] = 'StatusSendingDraft' ;
$this -> labelStatus [ 1 ] = 'StatusSendingValidated' ;
$this -> labelStatus [ 2 ] = 'StatusSendingProcessed' ;
2018-02-15 15:27:06 +01:00
// List of short language codes for status
2023-11-24 10:10:24 +01:00
$this -> labelStatusShort = array ();
$this -> labelStatusShort [ - 1 ] = 'StatusSendingCanceledShort' ;
$this -> labelStatusShort [ 0 ] = 'StatusSendingDraftShort' ;
$this -> labelStatusShort [ 1 ] = 'StatusSendingValidatedShort' ;
$this -> labelStatusShort [ 2 ] = 'StatusSendingProcessedShort' ;
2008-10-25 13:16:39 +02:00
}
2011-02-20 23:53:59 +01:00
2011-09-29 22:32:28 +02:00
/**
2022-01-04 16:44:13 +01:00
* Return next expedition ref
2011-09-29 22:32:28 +02:00
*
2014-12-20 15:42:03 +01:00
* @ param Societe $soc Thirdparty object
2022-01-04 16:44:13 +01:00
* @ return string Free reference for expedition
2011-02-20 01:20:45 +01:00
*/
2019-02-24 23:32:09 +01:00
public function getNextNumRef ( $soc )
2011-02-20 01:20:45 +01:00
{
2016-05-06 22:43:50 +02:00
global $langs , $conf ;
2011-02-20 01:20:45 +01:00
$langs -> load ( " sendings " );
2023-11-27 11:41:05 +01:00
if ( getDolGlobalString ( 'EXPEDITION_ADDON_NUMBER' )) {
2015-01-17 18:58:05 +01:00
$mybool = false ;
2023-10-15 18:12:03 +02:00
$file = getDolGlobalString ( 'EXPEDITION_ADDON_NUMBER' ) . " .php " ;
2024-01-05 04:18:53 +01:00
$classname = getDolGlobalString ( 'EXPEDITION_ADDON_NUMBER' );
2015-01-17 18:58:05 +01:00
2017-10-07 13:09:31 +02:00
// Include file with class
$dirmodels = array_merge ( array ( '/' ), ( array ) $conf -> modules_parts [ 'models' ]);
2011-02-20 01:20:45 +01:00
2017-10-07 13:09:31 +02:00
foreach ( $dirmodels as $reldir ) {
$dir = dol_buildpath ( $reldir . " core/modules/expedition/ " );
2015-01-17 18:58:05 +01:00
2017-10-07 13:09:31 +02:00
// Load file with numbering class (if found)
2024-03-21 13:21:27 +01:00
$mybool = (( bool ) @ include_once $dir . $file ) || $mybool ;
2017-10-07 13:09:31 +02:00
}
2015-01-17 18:58:05 +01:00
2021-02-25 22:38:35 +01:00
if ( ! $mybool ) {
2024-01-20 09:22:38 +01:00
dol_print_error ( null , " Failed to include file " . $file );
2017-10-07 13:09:31 +02:00
return '' ;
}
2008-10-25 13:16:39 +02:00
2011-02-20 23:53:59 +01:00
$obj = new $classname ();
2024-08-29 13:34:24 +02:00
'@phan-var-force ModelNumRefExpedition $obj' ;
2019-01-27 11:55:16 +01:00
$numref = $obj -> getNextValue ( $soc , $this );
2011-02-20 23:53:59 +01:00
2021-02-25 22:38:35 +01:00
if ( $numref != " " ) {
2011-02-20 23:53:59 +01:00
return $numref ;
2020-05-21 15:05:19 +02:00
} else {
2019-01-27 11:55:16 +01:00
dol_print_error ( $this -> db , get_class ( $this ) . " ::getNextNumRef " . $obj -> error );
2011-02-20 01:20:45 +01:00
return " " ;
}
2020-05-21 15:05:19 +02:00
} else {
2017-10-07 13:09:31 +02:00
print $langs -> trans ( " Error " ) . " " . $langs -> trans ( " Error_EXPEDITION_ADDON_NUMBER_NotDefined " );
return " " ;
}
2011-02-20 01:20:45 +01:00
}
2011-02-20 23:53:59 +01:00
2008-10-25 13:16:39 +02:00
/**
2011-09-29 22:32:28 +02:00
* Create expedition en base
*
2024-01-13 19:48:41 +01:00
* @ param User $user Object du user qui cree
2017-10-07 13:09:31 +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 erreur , id expedition creee si ok
2008-10-25 13:16:39 +02:00
*/
2019-02-24 23:32:09 +01:00
public function create ( $user , $notrigger = 0 )
2008-10-25 13:16:39 +02:00
{
2016-05-06 22:43:50 +02:00
global $conf , $hookmanager ;
2012-07-29 12:54:19 +02:00
2019-11-13 19:37:08 +01:00
$now = dol_now ();
2013-08-07 15:08:30 +02:00
2019-11-13 19:37:08 +01:00
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php' ;
2008-10-25 13:16:39 +02:00
$error = 0 ;
2009-02-03 03:39:28 +01:00
// Clean parameters
2009-04-29 20:02:50 +02:00
$this -> tracking_number = dol_sanitizeFileName ( $this -> tracking_number );
2021-02-25 22:38:35 +01:00
if ( empty ( $this -> fk_project )) {
$this -> fk_project = 0 ;
}
2024-04-28 21:36:33 +02:00
if ( empty ( $this -> date_shipping ) && ! empty ( $this -> date_expedition )) {
$this -> date_shipping = $this -> date_expedition ;
}
2024-11-21 19:11:32 +01:00
$this -> entity = setEntity ( $this );
2009-02-04 23:12:23 +01:00
2008-10-25 13:16:39 +02:00
$this -> user = $user ;
$this -> db -> begin ();
2009-04-30 18:28:53 +02:00
$sql = " INSERT INTO " . MAIN_DB_PREFIX . " expedition ( " ;
2020-03-12 12:45:44 +01:00
$sql .= " ref " ;
$sql .= " , entity " ;
$sql .= " , ref_customer " ;
2020-05-23 16:46:42 +02:00
$sql .= " , ref_ext " ;
2020-03-12 12:45:44 +01:00
$sql .= " , date_creation " ;
$sql .= " , fk_user_author " ;
$sql .= " , date_expedition " ;
$sql .= " , date_delivery " ;
$sql .= " , fk_soc " ;
$sql .= " , fk_projet " ;
$sql .= " , fk_address " ;
$sql .= " , fk_shipping_method " ;
$sql .= " , tracking_number " ;
$sql .= " , weight " ;
$sql .= " , size " ;
$sql .= " , width " ;
$sql .= " , height " ;
$sql .= " , weight_units " ;
$sql .= " , size_units " ;
$sql .= " , note_private " ;
$sql .= " , note_public " ;
$sql .= " , model_pdf " ;
$sql .= " , fk_incoterms, location_incoterms " ;
2024-09-13 03:09:53 +02:00
$sql .= " , signed_status " ;
2020-03-12 12:45:44 +01:00
$sql .= " ) VALUES ( " ;
$sql .= " '(PROV)' " ;
2024-11-21 19:11:32 +01:00
$sql .= " , " . (( int ) $this -> entity );
2020-03-12 12:45:44 +01:00
$sql .= " , " . ( $this -> ref_customer ? " ' " . $this -> db -> escape ( $this -> ref_customer ) . " ' " : " null " );
2020-05-23 16:46:42 +02:00
$sql .= " , " . ( $this -> ref_ext ? " ' " . $this -> db -> escape ( $this -> ref_ext ) . " ' " : " null " );
2020-03-12 12:45:44 +01:00
$sql .= " , ' " . $this -> db -> idate ( $now ) . " ' " ;
2021-09-03 21:25:17 +02:00
$sql .= " , " . (( int ) $user -> id );
2024-04-28 21:36:33 +02:00
$sql .= " , " . ( $this -> date_shipping > 0 ? " ' " . $this -> db -> idate ( $this -> date_shipping ) . " ' " : " null " );
2020-03-12 12:45:44 +01:00
$sql .= " , " . ( $this -> date_delivery > 0 ? " ' " . $this -> db -> idate ( $this -> date_delivery ) . " ' " : " null " );
2021-09-03 21:25:17 +02:00
$sql .= " , " . ( $this -> socid > 0 ? (( int ) $this -> socid ) : " null " );
$sql .= " , " . ( $this -> fk_project > 0 ? (( int ) $this -> fk_project ) : " null " );
2020-03-12 12:45:44 +01:00
$sql .= " , " . ( $this -> fk_delivery_address > 0 ? $this -> fk_delivery_address : " null " );
2021-09-03 21:25:17 +02:00
$sql .= " , " . ( $this -> shipping_method_id > 0 ? (( int ) $this -> shipping_method_id ) : " null " );
2020-03-12 12:45:44 +01:00
$sql .= " , ' " . $this -> db -> escape ( $this -> tracking_number ) . " ' " ;
2020-10-31 14:32:18 +01:00
$sql .= " , " . ( is_numeric ( $this -> weight ) ? $this -> weight : 'NULL' );
$sql .= " , " . ( is_numeric ( $this -> sizeS ) ? $this -> sizeS : 'NULL' ); // TODO Should use this->trueDepth
$sql .= " , " . ( is_numeric ( $this -> sizeW ) ? $this -> sizeW : 'NULL' ); // TODO Should use this->trueWidth
$sql .= " , " . ( is_numeric ( $this -> sizeH ) ? $this -> sizeH : 'NULL' ); // TODO Should use this->trueHeight
2020-03-12 12:45:44 +01:00
$sql .= " , " . ( $this -> weight_units != '' ? ( int ) $this -> weight_units : 'NULL' );
$sql .= " , " . ( $this -> size_units != '' ? ( int ) $this -> size_units : 'NULL' );
$sql .= " , " . ( ! empty ( $this -> note_private ) ? " ' " . $this -> db -> escape ( $this -> note_private ) . " ' " : " null " );
$sql .= " , " . ( ! empty ( $this -> note_public ) ? " ' " . $this -> db -> escape ( $this -> note_public ) . " ' " : " null " );
$sql .= " , " . ( ! empty ( $this -> model_pdf ) ? " ' " . $this -> db -> escape ( $this -> model_pdf ) . " ' " : " null " );
$sql .= " , " . ( int ) $this -> fk_incoterms ;
$sql .= " , ' " . $this -> db -> escape ( $this -> location_incoterms ) . " ' " ;
2024-09-13 03:09:53 +02:00
$sql .= " , " . ( $this -> signed_status );
2020-03-12 12:45:44 +01:00
$sql .= " ) " ;
2008-10-25 13:16:39 +02:00
2014-06-12 11:31:53 +02:00
dol_syslog ( get_class ( $this ) . " ::create " , LOG_DEBUG );
2020-03-12 12:45:44 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
2008-10-25 13:16:39 +02:00
$this -> id = $this -> db -> last_insert_id ( MAIN_DB_PREFIX . " expedition " );
2009-04-30 18:28:53 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . " expedition " ;
2020-03-12 12:45:44 +01:00
$sql .= " SET ref = '(PROV " . $this -> id . " )' " ;
2021-08-27 16:33:03 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2010-01-05 21:03:37 +01:00
2014-06-12 11:31:53 +02:00
dol_syslog ( get_class ( $this ) . " ::create " , LOG_DEBUG );
2021-02-25 22:38:35 +01:00
if ( $this -> db -> query ( $sql )) {
2019-06-29 16:29:32 +02:00
// Insert of lines
2020-03-12 12:45:44 +01:00
$num = count ( $this -> lines );
2021-02-25 22:38:35 +01:00
for ( $i = 0 ; $i < $num ; $i ++ ) {
2023-11-27 11:41:05 +01:00
if ( empty ( $this -> lines [ $i ] -> product_type ) || getDolGlobalString ( 'STOCK_SUPPORTS_SERVICES' ) || getDolGlobalString ( 'SHIPMENT_SUPPORTS_SERVICES' )) {
2022-03-01 01:28:47 +01:00
if ( ! isset ( $this -> lines [ $i ] -> detail_batch )) { // no batch management
if ( $this -> create_line ( $this -> lines [ $i ] -> entrepot_id , $this -> lines [ $i ] -> origin_line_id , $this -> lines [ $i ] -> qty , $this -> lines [ $i ] -> rang , $this -> lines [ $i ] -> array_options ) <= 0 ) {
$error ++ ;
}
} else { // with batch management
if ( $this -> create_line_batch ( $this -> lines [ $i ], $this -> lines [ $i ] -> array_options ) <= 0 ) {
$error ++ ;
}
2014-03-07 11:35:16 +01:00
}
}
2009-12-12 10:13:41 +01:00
}
2010-01-05 21:03:37 +01:00
2021-02-25 22:38:35 +01:00
if ( ! $error && $this -> id && $this -> origin_id ) {
2009-12-12 10:13:41 +01:00
$ret = $this -> add_object_linked ();
2021-02-25 22:38:35 +01:00
if ( ! $ret ) {
2009-12-12 10:13:41 +01:00
$error ++ ;
}
}
2016-09-07 12:41:32 +02:00
2018-04-10 12:03:01 +02:00
// Actions on extra fields
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$result = $this -> insertExtraFields ();
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
2018-04-10 12:03:01 +02:00
$error ++ ;
2015-12-16 16:18:29 +01:00
}
}
2010-01-05 21:03:37 +01:00
2021-02-25 22:38:35 +01:00
if ( ! $error && ! $notrigger ) {
2017-10-07 13:09:31 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'SHIPPING_CREATE' , $user );
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2017-10-07 13:09:31 +02:00
// End call triggers
2011-08-31 16:42:47 +02:00
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2014-06-10 12:05:31 +02:00
$this -> db -> commit ();
return $this -> id ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-25 22:38:35 +01:00
foreach ( $this -> errors as $errmsg ) {
2014-06-10 12:05:31 +02:00
dol_syslog ( get_class ( $this ) . " ::create " . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2014-06-10 12:05:31 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2014-06-10 12:05:31 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2009-12-12 10:13:41 +01:00
$error ++ ;
$this -> db -> rollback ();
return - 3 ;
}
2020-05-21 15:05:19 +02:00
} else {
2009-12-12 10:13:41 +01:00
$error ++ ;
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
2009-12-12 10:13:41 +01:00
$this -> db -> rollback ();
return - 2 ;
}
2020-05-21 15:05:19 +02:00
} else {
2008-10-25 13:16:39 +02:00
$error ++ ;
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error () . " - sql= $sql " ;
2008-10-25 13:16:39 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2008-10-25 13:16:39 +02:00
/**
2011-12-16 15:29:58 +01:00
* Create a expedition line
2012-01-04 23:56:10 +01:00
*
* @ param int $entrepot_id Id of warehouse
* @ param int $origin_line_id Id of source line
2024-03-19 15:55:46 +01:00
* @ param float $qty Quantity
2019-08-06 15:33:26 +02:00
* @ param int $rang Rang
2024-10-03 19:40:34 +02:00
* @ param array < string , mixed > $array_options extrafields array
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , line_id if OK
2008-10-25 13:16:39 +02:00
*/
2024-03-10 01:44:08 +01:00
public function create_line ( $entrepot_id , $origin_line_id , $qty , $rang = 0 , $array_options = [])
2008-10-25 13:16:39 +02:00
{
2019-06-12 22:55:08 +02:00
//phpcs:enable
global $user ;
2017-10-18 17:01:17 +02:00
$expeditionline = new ExpeditionLigne ( $this -> db );
$expeditionline -> fk_expedition = $this -> id ;
$expeditionline -> entrepot_id = $entrepot_id ;
2024-04-08 12:44:49 +02:00
$expeditionline -> fk_elementdet = $origin_line_id ;
$expeditionline -> element_type = $this -> origin ;
2017-10-18 17:01:17 +02:00
$expeditionline -> qty = $qty ;
2019-08-06 15:10:13 +02:00
$expeditionline -> rang = $rang ;
2017-10-31 17:20:29 +01:00
$expeditionline -> array_options = $array_options ;
2017-06-23 11:12:17 +02:00
2021-02-25 22:38:35 +01:00
if (( $lineId = $expeditionline -> insert ( $user )) < 0 ) {
2019-11-13 19:37:08 +01:00
$this -> errors [] = $expeditionline -> error ;
2015-12-16 16:18:29 +01:00
}
2017-10-18 17:01:17 +02:00
return $lineId ;
2008-10-25 13:16:39 +02:00
}
2015-02-16 20:14:16 +01:00
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2014-03-07 11:35:16 +01:00
/**
2021-06-04 10:29:30 +02:00
* Create the detail of the expedition line . Create 1 record into expeditiondet for each warehouse and n record for each lot in this warehouse into expeditiondet_batch .
2014-03-07 11:35:16 +01:00
*
2024-10-03 19:40:34 +02:00
* @ param ExpeditionLigne $line_ext Object with full information of line . $line_ext -> detail_batch must be an array of ExpeditionLineBatch
* @ param array < string , mixed > $array_options extrafields array
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2014-03-07 11:35:16 +01:00
*/
2024-03-10 01:44:08 +01:00
public function create_line_batch ( $line_ext , $array_options = [])
2014-03-07 11:35:16 +01:00
{
2020-10-28 17:49:52 +01:00
// phpcs:enable
2014-03-07 11:35:16 +01:00
$error = 0 ;
2015-12-18 18:00:31 +01:00
$stockLocationQty = array (); // associated array with batch qty in stock location
2016-09-07 12:41:32 +02:00
2019-11-13 19:37:08 +01:00
$tab = $line_ext -> detail_batch ;
2015-12-18 18:00:31 +01:00
// create stockLocation Qty array
2021-02-25 22:38:35 +01:00
foreach ( $tab as $detbatch ) {
2025-02-14 16:47:08 +01:00
if ( ! empty ( $detbatch -> fk_warehouse )) {
if ( empty ( $stockLocationQty [ $detbatch -> fk_warehouse ])) {
$stockLocationQty [ $detbatch -> fk_warehouse ] = 0 ;
2023-05-02 14:32:18 +02:00
}
2025-02-14 16:47:08 +01:00
$stockLocationQty [ $detbatch -> fk_warehouse ] += $detbatch -> qty ;
2015-12-18 18:00:31 +01:00
}
2015-02-16 20:14:16 +01:00
}
2015-12-18 18:00:31 +01:00
// create shipment lines
2021-02-25 22:38:35 +01:00
foreach ( $stockLocationQty as $stockLocation => $qty ) {
2021-01-07 18:24:44 +01:00
$line_id = $this -> create_line ( $stockLocation , $line_ext -> origin_line_id , $qty , $line_ext -> rang , $array_options );
if ( $line_id < 0 ) {
2015-12-18 18:00:31 +01:00
$error ++ ;
2020-05-21 15:05:19 +02:00
} else {
2015-12-18 18:00:31 +01:00
// create shipment batch lines for stockLocation
2021-02-25 22:38:35 +01:00
foreach ( $tab as $detbatch ) {
2025-02-14 16:47:08 +01:00
if ( $detbatch -> fk_warehouse == $stockLocation ) {
2021-06-04 10:29:30 +02:00
if ( ! ( $detbatch -> create ( $line_id ) > 0 )) { // Create an ExpeditionLineBatch
2023-03-07 14:58:55 +01:00
$this -> errors = $detbatch -> errors ;
2015-12-18 18:00:31 +01:00
$error ++ ;
}
2016-09-07 12:41:32 +02:00
}
2014-03-07 11:35:16 +01:00
}
}
}
2015-02-16 20:14:16 +01:00
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
return 1 ;
} else {
return - 1 ;
}
2014-03-07 11:35:16 +01:00
}
2008-10-25 13:16:39 +02:00
/**
2011-05-26 17:33:33 +02:00
* Get object and lines from database
2011-09-29 22:32:28 +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
2015-02-16 19:14:34 +01:00
* @ return int > 0 if OK , 0 if not found , < 0 if KO
2008-10-25 13:16:39 +02:00
*/
2020-03-06 14:38:06 +01:00
public function fetch ( $id , $ref = '' , $ref_ext = '' , $notused = '' )
2008-10-25 13:16:39 +02:00
{
global $conf ;
2011-05-26 17:33:33 +02:00
// Check parameters
2021-02-25 22:38:35 +01:00
if ( empty ( $id ) && empty ( $ref ) && empty ( $ref_ext )) {
return - 1 ;
}
2010-06-06 17:53:49 +02:00
2024-09-13 03:09:53 +02:00
$sql = " SELECT e.rowid, e.entity, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.fk_user_author, e.fk_statut, e.signed_status, e.fk_projet as fk_project, e.billed " ;
2020-10-28 17:49:52 +01:00
$sql .= " , e.date_valid " ;
2020-03-12 12:45:44 +01:00
$sql .= " , e.weight, e.weight_units, e.size, e.size_units, e.width, e.height " ;
$sql .= " , e.date_expedition as date_expedition, e.model_pdf, e.fk_address, e.date_delivery " ;
$sql .= " , e.fk_shipping_method, e.tracking_number " ;
$sql .= " , e.note_private, e.note_public " ;
$sql .= ', e.fk_incoterms, e.location_incoterms' ;
2024-05-05 02:48:02 +02:00
$sql .= ', e.signed_status' ;
2020-03-12 12:45:44 +01:00
$sql .= ', i.libelle as label_incoterms' ;
$sql .= ', s.libelle as shipping_method' ;
2024-03-24 06:12:18 +01:00
$sql .= " , el.fk_source as origin_id, el.sourcetype as origin_type " ;
2020-03-12 12:45:44 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " expedition as e " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " element_element as el ON el.fk_target = e.rowid AND el.targettype = ' " . $this -> db -> escape ( $this -> element ) . " ' " ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_incoterms as i ON e.fk_incoterms = i.rowid' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_shipment_mode as s ON e.fk_shipping_method = s.rowid' ;
$sql .= " WHERE e.entity IN ( " . getEntity ( 'expedition' ) . " ) " ;
2021-02-25 22:38:35 +01:00
if ( $id ) {
2021-04-24 20:18:11 +02:00
$sql .= " AND e.rowid = " . (( int ) $id );
2021-02-25 22:38:35 +01:00
}
if ( $ref ) {
$sql .= " AND e.ref=' " . $this -> db -> escape ( $ref ) . " ' " ;
}
if ( $ref_ext ) {
$sql .= " AND e.ref_ext=' " . $this -> db -> escape ( $ref_ext ) . " ' " ;
}
2008-10-25 13:16:39 +02:00
2014-06-12 11:31:53 +02:00
dol_syslog ( get_class ( $this ) . " ::fetch " , LOG_DEBUG );
2011-09-20 15:32:16 +02:00
$result = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $result ) {
if ( $this -> db -> num_rows ( $result )) {
2009-01-29 21:56:14 +01:00
$obj = $this -> db -> fetch_object ( $result );
$this -> id = $obj -> rowid ;
2020-05-18 11:03:32 +02:00
$this -> entity = $obj -> entity ;
2009-01-29 21:56:14 +01:00
$this -> ref = $obj -> ref ;
$this -> socid = $obj -> socid ;
2020-03-12 12:45:44 +01:00
$this -> ref_customer = $obj -> ref_customer ;
2018-08-30 13:54:10 +02:00
$this -> ref_ext = $obj -> ref_ext ;
2023-02-20 20:57:46 +01:00
$this -> status = $obj -> fk_statut ;
$this -> statut = $this -> status ; // Deprecated
2024-09-13 03:09:53 +02:00
$this -> signed_status = $obj -> signed_status ;
2009-01-29 21:56:14 +01:00
$this -> user_author_id = $obj -> fk_user_author ;
2023-02-13 23:42:08 +01:00
$this -> fk_user_author = $obj -> fk_user_author ;
2010-05-13 01:03:33 +02:00
$this -> date_creation = $this -> db -> jdate ( $obj -> date_creation );
2020-10-28 17:49:52 +01:00
$this -> date_valid = $this -> db -> jdate ( $obj -> date_valid );
2020-03-12 12:45:44 +01:00
$this -> date = $this -> db -> jdate ( $obj -> date_expedition ); // TODO deprecated
$this -> date_expedition = $this -> db -> jdate ( $obj -> date_expedition ); // TODO deprecated
$this -> date_shipping = $this -> db -> jdate ( $obj -> date_expedition ); // Date real
2024-01-13 19:48:41 +01:00
$this -> date_delivery = $this -> db -> jdate ( $obj -> date_delivery ); // Date planned
2010-07-29 14:37:09 +02:00
$this -> fk_delivery_address = $obj -> fk_address ;
2020-08-18 14:48:38 +02:00
$this -> model_pdf = $obj -> model_pdf ;
2018-08-30 13:54:10 +02:00
$this -> shipping_method_id = $obj -> fk_shipping_method ;
2020-03-12 12:45:44 +01:00
$this -> shipping_method = $obj -> shipping_method ;
2009-01-29 21:56:14 +01:00
$this -> tracking_number = $obj -> tracking_number ;
2024-03-24 06:12:18 +01:00
$this -> origin = ( $obj -> origin_type ? $obj -> origin_type : 'commande' ); // For compatibility
$this -> origin_type = ( $obj -> origin_type ? $obj -> origin_type : 'commande' );
2010-03-13 16:52:30 +01:00
$this -> origin_id = $obj -> origin_id ;
2017-10-12 21:19:24 +02:00
$this -> billed = $obj -> billed ;
2020-03-12 12:45:44 +01:00
$this -> fk_project = $obj -> fk_project ;
2024-05-05 02:48:02 +02:00
$this -> signed_status = $obj -> signed_status ;
2009-01-29 21:56:14 +01:00
$this -> trueWeight = $obj -> weight ;
$this -> weight_units = $obj -> weight_units ;
$this -> trueWidth = $obj -> width ;
$this -> width_units = $obj -> size_units ;
$this -> trueHeight = $obj -> height ;
$this -> height_units = $obj -> size_units ;
$this -> trueDepth = $obj -> size ;
$this -> depth_units = $obj -> size_units ;
2013-04-11 21:53:41 +02:00
2013-04-09 17:18:07 +02:00
$this -> note_public = $obj -> note_public ;
$this -> note_private = $obj -> note_private ;
2009-01-29 21:56:14 +01:00
// A denormalized value
2018-08-30 13:54:10 +02:00
$this -> trueSize = $obj -> size . " x " . $obj -> width . " x " . $obj -> height ;
2009-01-29 21:56:14 +01:00
$this -> size_units = $obj -> size_units ;
2015-02-23 09:16:14 +01:00
//Incoterms
2018-08-30 13:54:10 +02:00
$this -> fk_incoterms = $obj -> fk_incoterms ;
$this -> location_incoterms = $obj -> location_incoterms ;
2019-09-27 14:11:14 +02:00
$this -> label_incoterms = $obj -> label_incoterms ;
2015-04-07 02:44:30 +02:00
2009-01-29 21:56:14 +01:00
$this -> db -> free ( $result );
2011-06-19 21:47:09 +02:00
// Tracking url
2018-12-15 18:30:35 +01:00
$this -> getUrlTrackingStatus ( $obj -> tracking_number );
2009-01-29 21:56:14 +01:00
2020-11-16 16:31:05 +01:00
// Thirdparty
2020-12-01 02:41:19 +01:00
$result = $this -> fetch_thirdparty (); // TODO Remove this
2016-09-07 12:41:32 +02:00
2020-10-23 20:08:35 +02:00
// Retrieve extrafields
2018-02-20 19:38:18 +01:00
$this -> fetch_optionals ();
2020-03-31 11:04:46 +02:00
2024-01-13 19:48:41 +01:00
// Fix Get multicurrency param for transmitted
2022-08-31 21:37:10 +02:00
if ( isModEnabled ( 'multicurrency' )) {
2021-02-25 22:38:35 +01:00
if ( ! empty ( $this -> multicurrency_code )) {
$this -> multicurrency_code = $this -> thirdparty -> multicurrency_code ;
}
2023-11-27 11:41:05 +01:00
if ( getDolGlobalString ( 'MULTICURRENCY_USE_ORIGIN_TX' ) && ! empty ( $this -> thirdparty -> multicurrency_tx )) {
2021-02-25 22:38:35 +01:00
$this -> multicurrency_tx = $this -> thirdparty -> multicurrency_tx ;
}
2020-03-31 10:57:52 +02:00
}
2020-03-31 11:04:46 +02:00
2009-01-29 21:56:14 +01:00
/*
2010-03-13 16:52:30 +01:00
* Lines
2009-01-29 21:56:14 +01:00
*/
2019-11-13 19:37:08 +01:00
$result = $this -> fetch_lines ();
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
2009-01-29 21:56:14 +01:00
return - 3 ;
}
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2015-02-16 19:14:34 +01:00
dol_syslog ( get_class ( $this ) . '::Fetch no expedition found' , LOG_ERR );
2023-09-03 22:34:14 +02:00
$this -> error = 'Shipment with id ' . $id . ' not found' ;
2015-02-16 19:14:34 +01:00
return 0 ;
2009-01-29 21:56:14 +01:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2008-10-25 13:16:39 +02:00
return - 1 ;
}
}
/**
2011-11-08 00:03:19 +01:00
* Validate object and update stock if option enabled
2011-09-29 22:32:28 +02:00
*
2011-11-08 00:03:19 +01:00
* @ param User $user Object user that validate
2017-10-07 13:09:31 +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 if OK , > 0 if KO
2008-10-25 13:16:39 +02:00
*/
2019-02-24 23:32:09 +01:00
public function valid ( $user , $notrigger = 0 )
2008-10-25 13:16:39 +02:00
{
2023-09-19 20:29:24 +02:00
global $conf ;
2011-08-31 16:42:47 +02:00
2017-10-07 13:09:31 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2008-10-25 13:16:39 +02:00
2012-01-04 23:56:10 +01:00
dol_syslog ( get_class ( $this ) . " ::valid " );
2008-10-25 13:16:39 +02:00
2009-05-07 23:38:56 +02:00
// Protection
2023-09-19 20:29:24 +02:00
if ( $this -> status ) {
2021-01-08 01:56:23 +01:00
dol_syslog ( get_class ( $this ) . " ::valid not in draft status " , LOG_WARNING );
2009-05-07 23:38:56 +02:00
return 0 ;
}
2023-11-27 11:41:05 +01:00
if ( ! (( ! getDolGlobalString ( 'MAIN_USE_ADVANCED_PERMS' ) && $user -> hasRight ( 'expedition' , 'creer' ))
|| ( getDolGlobalString ( 'MAIN_USE_ADVANCED_PERMS' ) && $user -> hasRight ( 'expedition' , 'shipping_advance' , 'validate' )))) {
2019-11-13 19:37:08 +01:00
$this -> error = 'Permission denied' ;
2012-01-04 23:56:10 +01:00
dol_syslog ( get_class ( $this ) . " ::valid " . $this -> error , LOG_ERR );
2009-05-07 23:38:56 +02:00
return - 1 ;
}
2008-10-25 13:16:39 +02:00
$this -> db -> begin ();
2010-06-17 22:24:11 +02:00
$error = 0 ;
2009-05-07 23:38:56 +02:00
// Define new ref
2011-02-20 01:20:45 +01:00
$soc = new Societe ( $this -> db );
$soc -> fetch ( $this -> socid );
2008-10-25 13:16:39 +02:00
2011-02-20 01:20:45 +01:00
// Class of company linked to order
2023-09-06 13:58:08 +02:00
$result = $soc -> setAsCustomer ();
2011-02-20 01:20:45 +01:00
// Define new ref
2021-02-25 22:38:35 +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
2011-06-15 21:53:37 +02:00
$numref = $this -> getNextNumRef ( $soc );
2023-10-09 19:52:21 +02:00
} elseif ( ! empty ( $this -> ref )) {
$numref = $this -> ref ;
2020-05-21 15:05:19 +02:00
} else {
2011-06-15 21:53:37 +02:00
$numref = " EXP " . $this -> id ;
2011-02-20 01:20:45 +01:00
}
2020-03-03 11:49:17 +01:00
$this -> newref = dol_sanitizeFileName ( $numref );
2011-02-20 23:53:59 +01:00
2019-11-13 19:37:08 +01:00
$now = dol_now ();
2010-05-18 09:22:58 +02:00
2009-05-07 23:38:56 +02:00
// Validate
2010-03-13 16:52:30 +01:00
$sql = " UPDATE " . MAIN_DB_PREFIX . " expedition SET " ;
2020-09-20 02:30:53 +02:00
$sql .= " ref=' " . $this -> db -> escape ( $numref ) . " ' " ;
2019-11-13 19:37:08 +01:00
$sql .= " , fk_statut = 1 " ;
$sql .= " , date_valid = ' " . $this -> db -> idate ( $now ) . " ' " ;
2024-10-29 02:18:17 +01:00
$sql .= " , fk_user_valid = " . (( int ) $user -> id );
2021-08-27 16:33:03 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2008-10-25 13:16:39 +02:00
2014-06-12 11:31:53 +02:00
dol_syslog ( get_class ( $this ) . " ::valid update expedition " , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( ! $resql ) {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror ();
2009-05-07 23:38:56 +02:00
$error ++ ;
}
2009-01-29 13:39:52 +01:00
2024-01-13 19:48:41 +01:00
// If stock increment is done on sending (recommended choice)
2023-11-27 11:41:05 +01:00
if ( ! $error && isModEnabled ( 'stock' ) && getDolGlobalString ( 'STOCK_CALCULATE_ON_SHIPMENT' )) {
2023-09-13 01:39:57 +02:00
$result = $this -> manageStockMvtOnEvt ( $user , " ShipmentValidatedInDolibarr " );
2022-10-14 11:28:49 +02:00
if ( $result < 0 ) {
2010-06-17 22:24:11 +02:00
return - 2 ;
2009-05-07 23:38:56 +02:00
}
2016-05-27 16:49:55 +02:00
}
// Change status of order to "shipment in process"
$ret = $this -> setStatut ( Commande :: STATUS_SHIPMENTONPROCESS , $this -> origin_id , $this -> origin );
2021-02-25 22:38:35 +01:00
if ( ! $ret ) {
2017-10-07 13:09:31 +02:00
$error ++ ;
2009-05-07 23:38:56 +02:00
}
2016-09-07 12:41:32 +02:00
2021-02-25 22:38:35 +01:00
if ( ! $error && ! $notrigger ) {
2017-10-07 13:09:31 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'SHIPPING_VALIDATE' , $user );
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2017-10-07 13:09:31 +02:00
// End call triggers
2014-10-27 03:24:45 +01:00
}
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2017-10-07 13:09:31 +02:00
$this -> oldref = $this -> ref ;
2012-08-22 23:11:24 +02:00
// Rename directory if dir was a temporary ref
2021-02-25 22:38:35 +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-03-12 12:45:44 +01:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . " ecm_files set filename = CONCAT(' " . $this -> db -> escape ( $this -> newref ) . " ', SUBSTR(filename, " . ( strlen ( $this -> ref ) + 1 ) . " )), filepath = 'expedition/sending/ " . $this -> db -> escape ( $this -> newref ) . " ' " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE filename LIKE ' " . $this -> db -> escape ( $this -> ref ) . " %' AND filepath = 'expedition/sending/ " . $this -> db -> escape ( $this -> ref ) . " ' and entity = " . (( int ) $conf -> entity );
2019-07-28 22:26:55 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( ! $resql ) {
2023-12-04 12:12:12 +01:00
$error ++ ;
$this -> error = $this -> db -> lasterror ();
2021-02-25 22:38:35 +01:00
}
2023-10-31 19:28:11 +01:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . " ecm_files set filepath = 'expedition/sending/ " . $this -> db -> escape ( $this -> newref ) . " ' " ;
2024-10-29 02:18:17 +01:00
$sql .= " WHERE filepath = 'expedition/sending/ " . $this -> db -> escape ( $this -> ref ) . " ' and entity = " . (( int ) $conf -> entity );
2023-10-31 19:28:11 +01:00
$resql = $this -> db -> query ( $sql );
if ( ! $resql ) {
2023-12-04 12:12:12 +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
2012-08-22 23:11:24 +02:00
$oldref = dol_sanitizeFileName ( $this -> ref );
$newref = dol_sanitizeFileName ( $numref );
$dirsource = $conf -> expedition -> dir_output . '/sending/' . $oldref ;
$dirdest = $conf -> expedition -> dir_output . '/sending/' . $newref ;
2021-02-25 22:38:35 +01:00
if ( ! $error && file_exists ( $dirsource )) {
2012-08-22 23:11:24 +02:00
dol_syslog ( get_class ( $this ) . " ::valid rename dir " . $dirsource . " into " . $dirdest );
2021-02-25 22:38:35 +01:00
if ( @ rename ( $dirsource , $dirdest )) {
2017-10-07 13:09:31 +02:00
dol_syslog ( " Rename ok " );
// Rename docs starting with $oldref with $newref
2019-11-13 19:37:08 +01:00
$listoffiles = dol_dir_list ( $conf -> expedition -> dir_output . '/sending/' . $newref , 'files' , 1 , '^' . preg_quote ( $oldref , '/' ));
2021-02-25 22:38:35 +01:00
foreach ( $listoffiles as $fileentry ) {
2019-11-13 19:37:08 +01:00
$dirsource = $fileentry [ 'name' ];
$dirdest = preg_replace ( '/^' . preg_quote ( $oldref , '/' ) . '/' , $newref , $dirsource );
$dirsource = $fileentry [ 'path' ] . '/' . $dirsource ;
$dirdest = $fileentry [ 'path' ] . '/' . $dirdest ;
2017-10-07 13:09:31 +02:00
@ rename ( $dirsource , $dirdest );
}
2012-08-22 23:11:24 +02:00
}
}
2009-05-07 23:38:56 +02:00
}
}
2011-06-17 15:39:38 +02:00
// Set new ref and current status
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2011-06-15 21:53:37 +02:00
$this -> ref = $numref ;
2019-02-05 11:58:49 +01:00
$this -> statut = self :: STATUS_VALIDATED ;
2024-03-24 06:23:56 +01:00
$this -> status = self :: STATUS_VALIDATED ;
2009-05-07 23:38:56 +02:00
}
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2009-05-07 23:38:56 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2008-10-25 13:16:39 +02:00
$this -> db -> rollback ();
2020-03-12 12:45:44 +01:00
return - 1 * $error ;
2008-10-25 13:16:39 +02:00
}
}
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2008-10-25 13:16:39 +02:00
/**
2016-01-13 20:41:32 +01:00
* Create a delivery receipt from a shipment
2011-09-29 22:32:28 +02:00
*
2016-01-13 20:41:32 +01:00
* @ param User $user User
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , >= 0 if OK
2008-10-25 13:16:39 +02:00
*/
2019-02-24 23:32:09 +01:00
public function create_delivery ( $user )
2008-10-25 13:16:39 +02:00
{
2020-10-28 17:49:52 +01:00
// phpcs:enable
2008-10-25 13:16:39 +02:00
global $conf ;
2023-04-18 14:04:27 +02:00
if ( getDolGlobalInt ( 'MAIN_SUBMODULE_DELIVERY' )) {
2021-02-25 22:38:35 +01:00
if ( $this -> statut == self :: STATUS_VALIDATED || $this -> statut == self :: STATUS_CLOSED ) {
2009-11-12 14:33:55 +01:00
// Expedition validee
2020-10-05 13:59:06 +02:00
include_once DOL_DOCUMENT_ROOT . '/delivery/class/delivery.class.php' ;
$delivery = new Delivery ( $this -> db );
2019-11-13 19:37:08 +01:00
$result = $delivery -> create_from_sending ( $user , $this -> id );
2021-02-25 22:38:35 +01:00
if ( $result > 0 ) {
2009-08-05 18:42:04 +02:00
return $result ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $delivery -> error ;
2009-08-05 18:42:04 +02:00
return $result ;
}
2021-02-25 22:38:35 +01:00
} else {
return 0 ;
}
} else {
return 0 ;
}
2008-10-25 13:16:39 +02:00
}
/**
2016-11-14 13:40:41 +01:00
* Add an expedition line .
2015-02-16 20:46:54 +01:00
* If STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS is set , you can add a shipment line , with no stock source defined
* If STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT is not set , you can add a shipment line , even if not enough into stock
2022-07-10 18:35:23 +02:00
* Note : For product that need a batch number , you must use addline_batch ()
2012-01-04 23:56:10 +01:00
*
* @ param int $entrepot_id Id of warehouse
2015-02-16 20:46:54 +01:00
* @ param int $id Id of source line ( order line )
2024-03-19 15:55:46 +01:00
* @ param float $qty Quantity
2024-10-03 19:40:34 +02:00
* @ param array < string , mixed > $array_options extrafields array
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2008-10-25 13:16:39 +02:00
*/
2024-03-10 01:44:08 +01:00
public function addline ( $entrepot_id , $id , $qty , $array_options = [])
2008-10-25 13:16:39 +02:00
{
2014-03-15 14:59:27 +01:00
global $conf , $langs ;
2014-10-18 16:27:15 +02:00
2011-09-17 21:49:50 +02:00
$num = count ( $this -> lines );
2010-03-13 16:52:30 +01:00
$line = new ExpeditionLigne ( $this -> db );
2008-10-25 13:16:39 +02:00
2010-03-13 16:52:30 +01:00
$line -> entrepot_id = $entrepot_id ;
$line -> origin_line_id = $id ;
2024-04-08 12:44:49 +02:00
$line -> fk_elementdet = $id ;
$line -> element_type = 'order' ;
2010-03-13 16:52:30 +01:00
$line -> qty = $qty ;
2014-10-18 16:27:15 +02:00
2015-02-16 20:46:54 +01:00
$orderline = new OrderLine ( $this -> db );
$orderline -> fetch ( $id );
2014-10-18 16:27:15 +02:00
2019-08-06 15:10:13 +02:00
// Copy the rang of the order line to the expedition line
$line -> rang = $orderline -> rang ;
2022-03-01 01:28:47 +01:00
$line -> product_type = $orderline -> product_type ;
2019-08-06 15:10:13 +02:00
2022-09-25 06:04:27 +02:00
if ( isModEnabled ( 'stock' ) && ! empty ( $orderline -> fk_product )) {
2015-06-03 21:21:20 +02:00
$fk_product = $orderline -> fk_product ;
2024-03-14 16:44:07 +01:00
if ( ! ( $entrepot_id > 0 ) && ! getDolGlobalString ( 'STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS' ) && ! ( getDolGlobalString ( 'SHIPMENT_SUPPORTS_SERVICES' ) && $line -> product_type == Product :: TYPE_SERVICE )) {
2017-10-07 13:09:31 +02:00
$langs -> load ( " errors " );
2019-11-13 19:37:08 +01:00
$this -> error = $langs -> trans ( " ErrorWarehouseRequiredIntoShipmentLine " );
2015-02-16 20:46:54 +01:00
return - 1 ;
}
2014-10-18 16:27:15 +02:00
2023-11-27 11:41:05 +01:00
if ( getDolGlobalString ( 'STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT' )) {
2019-11-13 19:37:08 +01:00
$product = new Product ( $this -> db );
2020-11-16 16:31:05 +01:00
$product -> fetch ( $fk_product );
2014-10-18 16:27:15 +02:00
2020-11-16 16:31:05 +01:00
// Check must be done for stock of product into warehouse if $entrepot_id defined
2016-02-14 22:20:42 +01:00
if ( $entrepot_id > 0 ) {
2016-12-05 18:14:03 +01:00
$product -> load_stock ( 'warehouseopen' );
2016-02-01 13:40:02 +01:00
$product_stock = $product -> stock_warehouse [ $entrepot_id ] -> real ;
2020-11-16 16:31:05 +01:00
} else {
$product_stock = $product -> stock_reel ;
}
2014-10-18 16:27:15 +02:00
2019-11-13 19:37:08 +01:00
$product_type = $product -> type ;
2023-11-27 11:41:05 +01:00
if ( $product_type == 0 || getDolGlobalString ( 'STOCK_SUPPORTS_SERVICES' )) {
2020-11-16 16:31:05 +01:00
$isavirtualproduct = ( $product -> hasFatherOrChild ( 1 ) > 0 );
// The product is qualified for a check of quantity (must be enough in stock to be added into shipment).
2023-11-27 11:41:05 +01:00
if ( ! $isavirtualproduct || ! getDolGlobalString ( 'PRODUIT_SOUSPRODUITS' ) || ( $isavirtualproduct && ! getDolGlobalString ( 'STOCK_EXCLUDE_VIRTUAL_PRODUCTS' ))) { // If STOCK_EXCLUDE_VIRTUAL_PRODUCTS is set, we do not manage stock for kits/virtual products.
2020-11-16 16:31:05 +01:00
if ( $product_stock < $qty ) {
$langs -> load ( " errors " );
$this -> error = $langs -> trans ( 'ErrorStockIsNotEnoughToAddProductOnShipment' , $product -> ref );
$this -> errorhidden = 'ErrorStockIsNotEnoughToAddProductOnShipment' ;
2020-11-22 02:32:47 +01:00
2020-11-16 16:31:05 +01:00
$this -> db -> rollback ();
return - 3 ;
}
}
2014-03-15 14:59:27 +01:00
}
}
}
2016-09-07 12:41:32 +02:00
2016-11-14 13:40:41 +01:00
// If product need a batch number, we should not have called this function but addline_batch instead.
2022-09-21 00:46:02 +02:00
// If this happen, we may have a bug in card.php page
2022-08-31 21:55:55 +02:00
if ( isModEnabled ( 'productbatch' ) && ! empty ( $orderline -> fk_product ) && ! empty ( $orderline -> product_tobatch )) {
2022-09-21 00:46:02 +02:00
$this -> error = 'ADDLINE_WAS_CALLED_INSTEAD_OF_ADDLINEBATCH ' . $orderline -> id . ' ' . $orderline -> fk_product ; //
2017-10-07 13:09:31 +02:00
return - 4 ;
2016-11-14 13:40:41 +01:00
}
2017-06-23 11:12:17 +02:00
2015-12-16 16:18:29 +01:00
// extrafields
2023-11-27 11:41:05 +01:00
if ( ! getDolGlobalString ( 'MAIN_EXTRAFIELDS_DISABLED' ) && is_array ( $array_options ) && count ( $array_options ) > 0 ) { // For avoid conflicts if trigger used
2015-12-16 16:18:29 +01:00
$line -> array_options = $array_options ;
2021-02-25 22:38:35 +01:00
}
2016-09-07 12:41:32 +02:00
2010-12-15 08:12:28 +01:00
$this -> lines [ $num ] = $line ;
2022-03-01 01:28:47 +01:00
return 1 ;
2008-10-25 13:16:39 +02:00
}
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2017-10-07 13:09:31 +02:00
/**
2014-03-07 11:35:16 +01:00
* Add a shipment line with batch record
*
2024-10-03 19:40:34 +02:00
* @ param array { detail : array < array { id_batch : int , q : int | float } > , qty : int | float , ix_l : int } $dbatch Array of value ( key 'detail' -> Array , key 'qty' total quantity for line , key ix_l : original line index )
* @ param array < string , mixed > $array_options extrafields array
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2014-03-07 11:35:16 +01:00
*/
2024-03-10 01:44:08 +01:00
public function addline_batch ( $dbatch , $array_options = [])
2014-03-07 11:35:16 +01:00
{
2020-10-28 17:49:52 +01:00
// phpcs:enable
2019-11-13 19:37:08 +01:00
global $conf , $langs ;
2016-02-15 01:37:23 +01:00
2014-03-07 11:35:16 +01:00
$num = count ( $this -> lines );
2024-10-03 19:40:34 +02:00
$linebatch = null ;
2023-05-22 18:57:42 +02:00
if ( $dbatch [ 'qty' ] > 0 || ( $dbatch [ 'qty' ] == 0 && getDolGlobalString ( 'SHIPMENT_GETS_ALL_ORDER_PRODUCTS' ))) {
2014-03-07 11:35:16 +01:00
$line = new ExpeditionLigne ( $this -> db );
2019-11-13 19:37:08 +01:00
$tab = array ();
2021-02-25 22:38:35 +01:00
foreach ( $dbatch [ 'detail' ] as $key => $value ) {
2023-05-22 18:57:42 +02:00
if ( $value [ 'q' ] > 0 || ( $value [ 'q' ] == 0 && getDolGlobalString ( 'SHIPMENT_GETS_ALL_ORDER_PRODUCTS' ))) {
2015-08-14 23:53:59 +02:00
// $value['q']=qty to move
// $value['id_batch']=id into llx_product_batch of record to move
2015-08-19 10:42:54 +02:00
//var_dump($value);
2015-08-20 14:36:32 +02:00
2017-10-07 13:09:31 +02:00
$linebatch = new ExpeditionLineBatch ( $this -> db );
2019-11-13 19:37:08 +01:00
$ret = $linebatch -> fetchFromStock ( $value [ 'id_batch' ]); // load serial, sellby, eatby
2021-02-25 22:38:35 +01:00
if ( $ret < 0 ) {
2023-12-02 21:18:10 +01:00
$this -> setErrorsFromObject ( $linebatch );
2014-03-07 11:35:16 +01:00
return - 1 ;
}
2019-11-13 19:37:08 +01:00
$linebatch -> qty = $value [ 'q' ];
2023-05-22 18:57:42 +02:00
if ( $linebatch -> qty == 0 && getDolGlobalString ( 'SHIPMENT_GETS_ALL_ORDER_PRODUCTS' )) {
2023-01-26 12:08:13 +01:00
$linebatch -> batch = null ;
}
2019-11-13 19:37:08 +01:00
$tab [] = $linebatch ;
2015-02-16 20:51:05 +01:00
2023-05-17 10:31:34 +02:00
if ( getDolGlobalString ( " STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT " , '0' )) {
2016-02-03 11:33:13 +01:00
require_once DOL_DOCUMENT_ROOT . '/product/class/productbatch.class.php' ;
$prod_batch = new Productbatch ( $this -> db );
$prod_batch -> fetch ( $value [ 'id_batch' ]);
2021-02-25 22:38:35 +01:00
if ( $prod_batch -> qty < $linebatch -> qty ) {
2017-10-07 13:09:31 +02:00
$langs -> load ( " errors " );
2019-11-13 19:37:08 +01:00
$this -> errors [] = $langs -> trans ( 'ErrorStockIsNotEnoughToAddProductOnShipment' , $prod_batch -> fk_product );
2016-02-03 11:33:13 +01:00
dol_syslog ( get_class ( $this ) . " ::addline_batch error=Product " . $prod_batch -> batch . " : " . $this -> errorsToString (), LOG_ERR );
$this -> db -> rollback ();
return - 1 ;
}
2015-02-16 20:51:05 +01:00
}
2016-09-07 12:41:32 +02:00
2015-08-14 23:53:59 +02:00
//var_dump($linebatch);
2014-03-07 11:35:16 +01:00
}
}
2024-10-03 19:40:34 +02:00
if ( is_object ( $linebatch )) {
2025-02-14 16:47:08 +01:00
$line -> entrepot_id = $linebatch -> fk_warehouse ;
2024-10-03 19:40:34 +02:00
}
2020-04-25 13:52:07 +02:00
$line -> origin_line_id = $dbatch [ 'ix_l' ]; // deprecated
2024-04-08 12:44:49 +02:00
$line -> fk_elementdet = $dbatch [ 'ix_l' ];
2014-03-07 11:35:16 +01:00
$line -> qty = $dbatch [ 'qty' ];
2019-11-13 19:37:08 +01:00
$line -> detail_batch = $tab ;
2015-08-14 23:53:59 +02:00
2015-12-16 16:18:29 +01:00
// extrafields
2023-11-27 11:41:05 +01:00
if ( ! getDolGlobalString ( 'MAIN_EXTRAFIELDS_DISABLED' ) && is_array ( $array_options ) && count ( $array_options ) > 0 ) { // For avoid conflicts if trigger used
2015-12-16 16:18:29 +01:00
$line -> array_options = $array_options ;
2021-02-25 22:38:35 +01:00
}
2016-09-07 12:41:32 +02:00
2015-08-14 23:53:59 +02:00
//var_dump($line);
2014-03-07 11:35:16 +01:00
$this -> lines [ $num ] = $line ;
2016-02-03 11:33:13 +01:00
return 1 ;
2014-03-07 11:35:16 +01:00
}
2023-12-02 21:18:10 +01:00
return 0 ;
2014-03-07 11:35:16 +01:00
}
2017-10-07 13:09:31 +02:00
/**
* Update database
*
2024-10-03 19:40:34 +02:00
* @ param User $user User that modifies the record
* @ param int < 0 , 1 > $notrigger 0 = launch triggers after , 1 = disable triggers
* @ return int Return integer < 0 if KO , > 0 if OK
2017-10-07 13:09:31 +02:00
*/
2019-02-24 23:32:09 +01:00
public function update ( $user = null , $notrigger = 0 )
2017-10-07 13:09:31 +02:00
{
global $conf ;
2019-11-13 19:37:08 +01:00
$error = 0 ;
2010-05-17 16:13:03 +02:00
// Clean parameters
2021-02-25 22:38:35 +01:00
if ( isset ( $this -> ref )) {
$this -> ref = trim ( $this -> ref );
}
if ( isset ( $this -> entity )) {
$this -> entity = ( int ) $this -> entity ;
}
if ( isset ( $this -> ref_customer )) {
$this -> ref_customer = trim ( $this -> ref_customer );
}
if ( isset ( $this -> socid )) {
$this -> socid = ( int ) $this -> socid ;
}
if ( isset ( $this -> fk_user_author )) {
$this -> fk_user_author = ( int ) $this -> fk_user_author ;
}
2024-10-03 19:40:34 +02:00
if ( isset ( $this -> fk_user_valid )) { // @phan-ignore-current-line PhanUndeclaredProperty
// If set, then accept @phan-ignore-next-line PhanUndeclaredProperty
2021-02-25 22:38:35 +01:00
$this -> fk_user_valid = ( int ) $this -> fk_user_valid ;
}
if ( isset ( $this -> fk_delivery_address )) {
$this -> fk_delivery_address = ( int ) $this -> fk_delivery_address ;
}
if ( isset ( $this -> shipping_method_id )) {
$this -> shipping_method_id = ( int ) $this -> shipping_method_id ;
}
if ( isset ( $this -> tracking_number )) {
$this -> tracking_number = trim ( $this -> tracking_number );
}
if ( isset ( $this -> statut )) {
$this -> statut = ( int ) $this -> statut ;
}
if ( isset ( $this -> trueDepth )) {
$this -> trueDepth = trim ( $this -> trueDepth );
}
if ( isset ( $this -> trueWidth )) {
$this -> trueWidth = trim ( $this -> trueWidth );
}
if ( isset ( $this -> trueHeight )) {
$this -> trueHeight = trim ( $this -> trueHeight );
}
if ( isset ( $this -> size_units )) {
$this -> size_units = trim ( $this -> size_units );
}
if ( isset ( $this -> weight_units )) {
2024-10-03 19:40:34 +02:00
$this -> weight_units = ( int ) $this -> weight_units ;
2021-02-25 22:38:35 +01:00
}
if ( isset ( $this -> trueWeight )) {
2024-03-19 21:24:44 +01:00
$this -> weight = trim (( string ) $this -> trueWeight );
2021-02-25 22:38:35 +01:00
}
if ( isset ( $this -> note_private )) {
$this -> note_private = trim ( $this -> note_private );
}
if ( isset ( $this -> note_public )) {
$this -> note_public = trim ( $this -> note_public );
}
if ( isset ( $this -> model_pdf )) {
$this -> model_pdf = trim ( $this -> model_pdf );
}
2024-11-14 13:23:22 +01:00
if ( ! empty ( $this -> date_expedition )) {
$this -> date_shipping = $this -> date_expedition ;
}
2010-05-17 16:13:03 +02:00
// Check parameters
// Put here code to add control on parameters values
2017-10-07 13:09:31 +02:00
// Update request
$sql = " UPDATE " . MAIN_DB_PREFIX . " expedition SET " ;
2024-10-29 02:18:17 +01:00
$sql .= " ref = " . ( isset ( $this -> ref ) ? " ' " . $this -> db -> escape ( $this -> ref ) . " ' " : " null " ) . " , " ;
$sql .= " ref_ext = " . ( isset ( $this -> ref_ext ) ? " ' " . $this -> db -> escape ( $this -> ref_ext ) . " ' " : " null " ) . " , " ;
$sql .= " ref_customer = " . ( isset ( $this -> ref_customer ) ? " ' " . $this -> db -> escape ( $this -> ref_customer ) . " ' " : " null " ) . " , " ;
$sql .= " fk_soc = " . ( isset ( $this -> socid ) ? $this -> socid : " null " ) . " , " ;
$sql .= " date_creation = " . ( dol_strlen ( $this -> date_creation ) != 0 ? " ' " . $this -> db -> idate ( $this -> date_creation ) . " ' " : 'null' ) . " , " ;
$sql .= " fk_user_author = " . ( isset ( $this -> fk_user_author ) ? $this -> fk_user_author : " null " ) . " , " ;
$sql .= " date_valid = " . ( dol_strlen ( $this -> date_valid ) != 0 ? " ' " . $this -> db -> idate ( $this -> date_valid ) . " ' " : 'null' ) . " , " ;
$sql .= " fk_user_valid = " . ( isset ( $this -> fk_user_valid ) ? $this -> fk_user_valid : " null " ) . " , " ;
2024-11-14 13:23:22 +01:00
$sql .= " date_expedition = " . ( dol_strlen ( $this -> date_shipping ) != 0 ? " ' " . $this -> db -> idate ( $this -> date_shipping ) . " ' " : 'null' ) . " , " ;
2024-10-29 02:18:17 +01:00
$sql .= " date_delivery = " . ( dol_strlen ( $this -> date_delivery ) != 0 ? " ' " . $this -> db -> idate ( $this -> date_delivery ) . " ' " : 'null' ) . " , " ;
$sql .= " fk_address = " . ( isset ( $this -> fk_delivery_address ) ? $this -> fk_delivery_address : " null " ) . " , " ;
$sql .= " fk_shipping_method = " . (( isset ( $this -> shipping_method_id ) && $this -> shipping_method_id > 0 ) ? $this -> shipping_method_id : " null " ) . " , " ;
$sql .= " tracking_number = " . ( isset ( $this -> tracking_number ) ? " ' " . $this -> db -> escape ( $this -> tracking_number ) . " ' " : " null " ) . " , " ;
$sql .= " fk_statut = " . ( isset ( $this -> statut ) ? $this -> statut : " null " ) . " , " ;
$sql .= " fk_projet = " . ( isset ( $this -> fk_project ) ? $this -> fk_project : " null " ) . " , " ;
$sql .= " height = " . (( $this -> trueHeight != '' ) ? $this -> trueHeight : " null " ) . " , " ;
$sql .= " width = " . (( $this -> trueWidth != '' ) ? $this -> trueWidth : " null " ) . " , " ;
$sql .= " size_units = " . ( isset ( $this -> size_units ) ? $this -> size_units : " null " ) . " , " ;
$sql .= " size = " . (( $this -> trueDepth != '' ) ? $this -> trueDepth : " null " ) . " , " ;
$sql .= " weight_units = " . ( isset ( $this -> weight_units ) ? $this -> weight_units : " null " ) . " , " ;
$sql .= " weight = " . (( $this -> trueWeight != '' ) ? $this -> trueWeight : " null " ) . " , " ;
$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 " ) . " , " ;
$sql .= " model_pdf = " . ( isset ( $this -> model_pdf ) ? " ' " . $this -> db -> escape ( $this -> model_pdf ) . " ' " : " null " ) . " , " ;
$sql .= " entity = " . (( int ) $conf -> entity );
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2010-05-17 16:13:03 +02:00
$this -> db -> begin ();
2014-06-12 11:31:53 +02:00
dol_syslog ( get_class ( $this ) . " ::update " , LOG_DEBUG );
2017-10-07 13:09:31 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( ! $resql ) {
2023-12-04 12:12:12 +01:00
$error ++ ;
$this -> errors [] = " Error " . $this -> db -> lasterror ();
2021-02-25 22:38:35 +01:00
}
2010-05-17 16:13:03 +02:00
2024-11-26 03:56:15 +01:00
// Actions on extra fields
if ( ! $error ) {
$result = $this -> insertExtraFields ();
if ( $result < 0 ) {
$error ++ ;
}
}
2020-11-15 16:58:40 +01:00
if ( ! $error && ! $notrigger ) {
// Call trigger
$result = $this -> call_trigger ( 'SHIPPING_MODIFY' , $user );
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2020-11-15 16:58:40 +01:00
// End call triggers
2010-05-17 16:13:03 +02:00
}
2017-10-07 13:09:31 +02:00
// Commit or rollback
2021-02-25 22:38:35 +01:00
if ( $error ) {
foreach ( $this -> errors as $errmsg ) {
2017-10-07 13:09:31 +02:00
dol_syslog ( get_class ( $this ) . " ::update " . $errmsg , LOG_ERR );
2019-11-13 19:37:08 +01:00
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2010-05-17 16:13:03 +02:00
}
$this -> db -> rollback ();
2019-11-13 19:37:08 +01:00
return - 1 * $error ;
2020-05-21 15:05:19 +02:00
} else {
2010-05-17 16:13:03 +02:00
$this -> db -> commit ();
return 1 ;
}
2017-10-07 13:09:31 +02:00
}
2010-05-17 16:13:03 +02:00
2020-04-23 07:54:13 +02:00
2020-04-23 07:49:31 +02:00
/**
* Cancel shipment .
*
* @ param int $notrigger Disable triggers
2020-10-28 17:49:52 +01:00
* @ param bool $also_update_stock true if the stock should be increased back ( false by default )
2020-04-23 07:49:31 +02:00
* @ return int > 0 if OK , 0 if deletion done but failed to delete files , < 0 if KO
*/
public function cancel ( $notrigger = 0 , $also_update_stock = false )
{
global $conf , $langs , $user ;
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2020-10-31 14:32:18 +01:00
$error = 0 ;
$this -> error = '' ;
2020-04-23 07:49:31 +02:00
$this -> db -> begin ();
// Add a protection to refuse deleting if shipment has at least one delivery
2020-10-31 14:32:18 +01:00
$this -> fetchObjectLinked ( $this -> id , 'shipping' , 0 , 'delivery' ); // Get deliveries linked to this shipment
2020-11-15 16:58:40 +01:00
if ( count ( $this -> linkedObjectsIds ) > 0 ) {
2020-10-31 14:32:18 +01:00
$this -> error = 'ErrorThereIsSomeDeliveries' ;
2020-04-23 07:49:31 +02:00
$error ++ ;
}
2020-11-15 16:58:40 +01:00
if ( ! $error && ! $notrigger ) {
// Call trigger
$result = $this -> call_trigger ( 'SHIPPING_CANCEL' , $user );
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2020-11-15 16:58:40 +01:00
// End call triggers
2020-04-23 07:49:31 +02:00
}
// Stock control
2022-09-25 15:30:16 +02:00
if ( ! $error && isModEnabled ( 'stock' ) &&
2024-03-24 14:19:44 +01:00
(( getDolGlobalString ( 'STOCK_CALCULATE_ON_SHIPMENT' ) && $this -> statut > self :: STATUS_DRAFT ) ||
( getDolGlobalString ( 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE' ) && $this -> statut == self :: STATUS_CLOSED && $also_update_stock ))) {
2020-04-23 07:49:31 +02:00
require_once DOL_DOCUMENT_ROOT . " /product/stock/class/mouvementstock.class.php " ;
$langs -> load ( " agenda " );
// Loop on each product line to add a stock movement and delete features
$sql = " SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot, ed.rowid as expeditiondet_id " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " commandedet as cd, " ;
$sql .= " " . MAIN_DB_PREFIX . " expeditiondet as ed " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE ed.fk_expedition = " . (( int ) $this -> id );
2024-04-08 12:44:49 +02:00
$sql .= " AND cd.rowid = ed.fk_elementdet " ;
2020-04-23 07:49:31 +02:00
dol_syslog ( get_class ( $this ) . " ::delete select details " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
2020-04-23 07:49:31 +02:00
$cpt = $this -> db -> num_rows ( $resql );
2021-09-27 15:41:58 +02:00
$shipmentlinebatch = new ExpeditionLineBatch ( $this -> db );
2021-02-25 22:38:35 +01:00
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
2020-04-23 07:49:31 +02:00
dol_syslog ( get_class ( $this ) . " ::delete movement index " . $i );
$obj = $this -> db -> fetch_object ( $resql );
$mouvS = new MouvementStock ( $this -> db );
// we do not log origin because it will be deleted
2024-03-07 18:57:38 +01:00
$mouvS -> origin = '' ;
2020-04-23 07:49:31 +02:00
// get lot/serial
$lotArray = null ;
2022-06-21 20:54:28 +02:00
if ( isModEnabled ( 'productbatch' )) {
2021-09-27 20:09:43 +02:00
$lotArray = $shipmentlinebatch -> fetchAll ( $obj -> expeditiondet_id );
2021-02-25 22:38:35 +01:00
if ( ! is_array ( $lotArray )) {
2022-06-02 10:15:04 +02:00
$error ++ ;
$this -> errors [] = " Error " . $this -> db -> lasterror ();
2020-04-23 07:49:31 +02:00
}
}
2021-09-27 20:09:43 +02:00
2020-04-23 07:49:31 +02:00
if ( empty ( $lotArray )) {
// no lot/serial
// We increment stock of product (and sub-products)
// We use warehouse selected for each line
$result = $mouvS -> reception ( $user , $obj -> fk_product , $obj -> fk_entrepot , $obj -> qty , 0 , $langs -> trans ( " ShipmentCanceledInDolibarr " , $this -> ref )); // Price is set to 0, because we don't want to see WAP changed
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
2022-06-02 10:15:04 +02:00
$error ++ ;
$this -> errors = array_merge ( $this -> errors , $mouvS -> errors );
2020-04-23 07:49:31 +02:00
break ;
}
2020-05-21 15:05:19 +02:00
} else {
2020-04-23 07:49:31 +02:00
// We increment stock of batches
// We use warehouse selected for each line
2021-02-25 22:38:35 +01:00
foreach ( $lotArray as $lot ) {
2020-04-23 07:49:31 +02:00
$result = $mouvS -> reception ( $user , $obj -> fk_product , $obj -> fk_entrepot , $lot -> qty , 0 , $langs -> trans ( " ShipmentCanceledInDolibarr " , $this -> ref ), $lot -> eatby , $lot -> sellby , $lot -> batch ); // Price is set to 0, because we don't want to see WAP changed
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
2022-06-02 10:15:04 +02:00
$error ++ ;
$this -> errors = array_merge ( $this -> errors , $mouvS -> errors );
2020-04-23 07:49:31 +02:00
break ;
}
}
2021-02-25 22:38:35 +01:00
if ( $error ) {
2024-01-13 19:48:41 +01:00
break ; // break for loop in case of error
2021-02-25 22:38:35 +01:00
}
2020-04-23 07:49:31 +02:00
}
}
2020-05-21 15:05:19 +02:00
} else {
2023-12-04 12:12:12 +01:00
$error ++ ;
$this -> errors [] = " Error " . $this -> db -> lasterror ();
2020-04-23 07:49:31 +02:00
}
}
// delete batch expedition line
2022-08-31 21:37:10 +02:00
if ( ! $error && isModEnabled ( 'productbatch' )) {
2021-09-27 15:41:58 +02:00
$shipmentlinebatch = new ExpeditionLineBatch ( $this -> db );
if ( $shipmentlinebatch -> deleteFromShipment ( $this -> id ) < 0 ) {
2023-12-04 12:12:12 +01:00
$error ++ ;
$this -> errors [] = " Error " . $this -> db -> lasterror ();
2020-04-23 07:49:31 +02:00
}
}
2020-04-23 07:54:13 +02:00
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2020-04-23 07:49:31 +02:00
$sql = " DELETE FROM " . MAIN_DB_PREFIX . " expeditiondet " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE fk_expedition = " . (( int ) $this -> id );
2020-04-23 07:49:31 +02:00
2021-02-25 22:38:35 +01:00
if ( $this -> db -> query ( $sql )) {
2020-04-23 07:49:31 +02:00
// Delete linked object
$res = $this -> deleteObjectLinked ();
2021-02-25 22:38:35 +01:00
if ( $res < 0 ) {
$error ++ ;
}
2020-04-23 07:49:31 +02:00
// No delete expedition
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2020-04-23 07:49:31 +02:00
$sql = " SELECT rowid FROM " . MAIN_DB_PREFIX . " expedition " ;
2021-08-27 16:33:03 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2020-04-23 07:49:31 +02:00
2021-02-25 22:38:35 +01:00
if ( $this -> db -> query ( $sql )) {
if ( ! empty ( $this -> origin ) && $this -> origin_id > 0 ) {
2020-04-23 07:49:31 +02:00
$this -> fetch_origin ();
2024-10-03 19:40:34 +02:00
$origin_object = $this -> origin_object ;
'@phan-var-force Facture|Commande $origin_object' ;
if ( $origin_object -> statut == Commande :: STATUS_SHIPMENTONPROCESS ) { // If order source of shipment is "shipment in progress"
2020-04-23 07:49:31 +02:00
// Check if there is no more shipment. If not, we can move back status of order to "validated" instead of "shipment in progress"
2024-10-03 19:40:34 +02:00
$origin_object -> loadExpeditions ();
2020-04-23 07:49:31 +02:00
//var_dump($this->$origin->expeditions);exit;
2024-10-03 19:40:34 +02:00
if ( count ( $origin_object -> expeditions ) <= 0 ) {
$origin_object -> setStatut ( Commande :: STATUS_VALIDATED );
2020-04-23 07:49:31 +02:00
}
}
}
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2020-04-23 07:49:31 +02:00
$this -> db -> commit ();
// We delete PDFs
$ref = dol_sanitizeFileName ( $this -> ref );
2021-02-25 22:38:35 +01:00
if ( ! empty ( $conf -> expedition -> dir_output )) {
2020-04-23 07:49:31 +02:00
$dir = $conf -> expedition -> dir_output . '/sending/' . $ref ;
$file = $dir . '/' . $ref . '.pdf' ;
2021-02-25 22:38:35 +01:00
if ( file_exists ( $file )) {
if ( ! dol_delete_file ( $file )) {
2020-04-23 07:49:31 +02:00
return 0 ;
}
}
2021-02-25 22:38:35 +01:00
if ( file_exists ( $dir )) {
if ( ! dol_delete_dir_recursive ( $dir )) {
2020-04-23 07:49:31 +02:00
$this -> error = $langs -> trans ( " ErrorCanNotDeleteDir " , $dir );
return 0 ;
}
}
}
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2020-04-23 07:49:31 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2020-04-23 07:49:31 +02:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
$this -> db -> rollback ();
return - 3 ;
}
2020-05-21 15:05:19 +02:00
} else {
2020-04-23 07:49:31 +02:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
$this -> db -> rollback ();
return - 2 ;
} //*/
2020-05-21 15:05:19 +02:00
} else {
2020-04-23 07:49:31 +02:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
$this -> db -> rollback ();
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2020-04-23 07:49:31 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
2020-04-23 07:54:13 +02:00
2015-10-14 12:16:54 +02:00
/**
2014-04-26 17:27:59 +02:00
* Delete shipment .
2018-03-11 00:00:24 +01:00
* Warning , do not delete a shipment if a delivery is linked to ( with table llx_element_element )
2011-09-29 22:32:28 +02:00
*
2025-01-19 02:30:36 +01:00
* @ param ? User $user User making the deletion
* @ param int < 0 , 1 > $notrigger Disable triggers
* @ param bool $also_update_stock true if the stock should be increased back ( false by default )
* @ return int > 0 if OK , 0 if deletion done but failed to delete files , < 0 if KO
2008-10-25 13:16:39 +02:00
*/
2024-03-07 17:58:02 +01:00
public function delete ( $user = null , $notrigger = 0 , $also_update_stock = false )
2008-10-25 13:16:39 +02:00
{
2024-03-07 17:58:02 +01:00
global $conf , $langs ;
if ( empty ( $user )) {
global $user ;
}
2018-03-11 00:00:24 +01:00
2015-10-14 12:16:54 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2018-03-11 00:00:24 +01:00
2020-03-12 12:45:44 +01:00
$error = 0 ;
$this -> error = '' ;
2013-08-07 15:08:30 +02:00
2018-03-10 23:40:56 +01:00
$this -> db -> begin ();
2018-03-11 00:00:24 +01:00
// Add a protection to refuse deleting if shipment has at least one delivery
2020-03-12 12:45:44 +01:00
$this -> fetchObjectLinked ( $this -> id , 'shipping' , 0 , 'delivery' ); // Get deliveries linked to this shipment
2021-02-25 22:38:35 +01:00
if ( count ( $this -> linkedObjectsIds ) > 0 ) {
2020-03-12 12:45:44 +01:00
$this -> error = 'ErrorThereIsSomeDeliveries' ;
2018-03-11 00:00:24 +01:00
$error ++ ;
}
2020-11-15 16:58:40 +01:00
if ( ! $error && ! $notrigger ) {
// Call trigger
$result = $this -> call_trigger ( 'SHIPPING_DELETE' , $user );
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2020-11-15 16:58:40 +01:00
// End call triggers
2018-03-10 23:40:56 +01:00
}
2013-06-20 18:37:23 +02:00
// Stock control
2022-09-25 15:30:16 +02:00
if ( ! $error && isModEnabled ( 'stock' ) &&
2024-03-24 14:19:44 +01:00
(( getDolGlobalString ( 'STOCK_CALCULATE_ON_SHIPMENT' ) && $this -> statut > self :: STATUS_DRAFT ) ||
( getDolGlobalString ( 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE' ) && $this -> statut == self :: STATUS_CLOSED && $also_update_stock ))) {
2018-07-26 11:57:25 +02:00
require_once DOL_DOCUMENT_ROOT . " /product/stock/class/mouvementstock.class.php " ;
2013-08-07 15:08:30 +02:00
2013-06-20 18:37:23 +02:00
$langs -> load ( " agenda " );
2013-08-07 15:08:30 +02:00
2021-12-06 14:43:11 +01:00
// we try deletion of batch line even if module batch not enabled in case of the module were enabled and disabled previously
$shipmentlinebatch = new ExpeditionLineBatch ( $this -> db );
2013-06-20 18:37:23 +02:00
// Loop on each product line to add a stock movement
2015-10-14 12:16:54 +02:00
$sql = " SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot, ed.rowid as expeditiondet_id " ;
2019-11-13 19:37:08 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " commandedet as cd, " ;
$sql .= " " . MAIN_DB_PREFIX . " expeditiondet as ed " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE ed.fk_expedition = " . (( int ) $this -> id );
2024-04-08 12:44:49 +02:00
$sql .= " AND cd.rowid = ed.fk_elementdet " ;
2013-08-07 15:08:30 +02:00
2014-06-12 11:31:53 +02:00
dol_syslog ( get_class ( $this ) . " ::delete select details " , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
2013-06-20 18:37:23 +02:00
$cpt = $this -> db -> num_rows ( $resql );
2021-02-25 22:38:35 +01:00
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
2013-06-20 18:37:23 +02:00
dol_syslog ( get_class ( $this ) . " ::delete movement index " . $i );
$obj = $this -> db -> fetch_object ( $resql );
2016-09-07 12:41:32 +02:00
2013-06-20 18:37:23 +02:00
$mouvS = new MouvementStock ( $this -> db );
2015-10-14 12:16:54 +02:00
// we do not log origin because it will be deleted
2024-03-07 18:57:38 +01:00
$mouvS -> origin = '' ;
2015-10-14 12:16:54 +02:00
// get lot/serial
2021-12-06 14:43:11 +01:00
$lotArray = $shipmentlinebatch -> fetchAll ( $obj -> expeditiondet_id );
if ( ! is_array ( $lotArray )) {
2023-12-04 12:12:12 +01:00
$error ++ ;
$this -> errors [] = " Error " . $this -> db -> lasterror ();
2013-06-20 18:37:23 +02:00
}
2015-10-14 12:16:54 +02:00
if ( empty ( $lotArray )) {
// no lot/serial
// We increment stock of product (and sub-products)
// We use warehouse selected for each line
2019-11-13 19:37:08 +01:00
$result = $mouvS -> reception ( $user , $obj -> fk_product , $obj -> fk_entrepot , $obj -> qty , 0 , $langs -> trans ( " ShipmentDeletedInDolibarr " , $this -> ref )); // Price is set to 0, because we don't want to see WAP changed
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
2022-06-02 10:15:04 +02:00
$error ++ ;
$this -> errors = array_merge ( $this -> errors , $mouvS -> errors );
2015-10-14 12:16:54 +02:00
break ;
}
2020-05-21 15:05:19 +02:00
} else {
2015-10-14 12:16:54 +02:00
// We increment stock of batches
// We use warehouse selected for each line
2021-02-25 22:38:35 +01:00
foreach ( $lotArray as $lot ) {
2019-11-13 19:37:08 +01:00
$result = $mouvS -> reception ( $user , $obj -> fk_product , $obj -> fk_entrepot , $lot -> qty , 0 , $langs -> trans ( " ShipmentDeletedInDolibarr " , $this -> ref ), $lot -> eatby , $lot -> sellby , $lot -> batch ); // Price is set to 0, because we don't want to see WAP changed
2021-02-25 22:38:35 +01:00
if ( $result < 0 ) {
2022-06-02 10:15:04 +02:00
$error ++ ;
$this -> errors = array_merge ( $this -> errors , $mouvS -> errors );
2015-10-14 12:16:54 +02:00
break ;
}
}
2021-02-25 22:38:35 +01:00
if ( $error ) {
2024-01-13 19:48:41 +01:00
break ; // break for loop in case of error
2021-02-25 22:38:35 +01:00
}
2016-09-07 12:41:32 +02:00
}
2013-06-20 18:37:23 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2023-12-04 12:12:12 +01:00
$error ++ ;
$this -> errors [] = " Error " . $this -> db -> lasterror ();
2013-06-20 18:37:23 +02:00
}
}
2016-09-07 12:41:32 +02:00
2021-12-06 14:43:11 +01:00
// delete batch expedition line
2021-09-15 13:29:19 +02:00
if ( ! $error ) {
2022-01-01 15:27:20 +01:00
$shipmentlinebatch = new ExpeditionLineBatch ( $this -> db );
2021-09-27 15:41:58 +02:00
if ( $shipmentlinebatch -> deleteFromShipment ( $this -> id ) < 0 ) {
2023-12-04 12:12:12 +01:00
$error ++ ;
$this -> errors [] = " Error " . $this -> db -> lasterror ();
2015-10-14 12:16:54 +02:00
}
}
2016-09-07 12:41:32 +02:00
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2021-09-27 15:41:58 +02:00
$main = MAIN_DB_PREFIX . 'expeditiondet' ;
$ef = $main . " _extrafields " ;
$sqlef = " DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_expedition = " . (( int ) $this -> id ) . " ) " ;
2020-04-23 19:09:05 +02:00
2013-06-20 18:37:23 +02:00
$sql = " DELETE FROM " . MAIN_DB_PREFIX . " expeditiondet " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE fk_expedition = " . (( int ) $this -> id );
2013-08-07 15:08:30 +02:00
2021-02-25 22:38:35 +01:00
if ( $this -> db -> query ( $sqlef ) && $this -> db -> query ( $sql )) {
2013-06-20 18:37:23 +02:00
// Delete linked object
$res = $this -> deleteObjectLinked ();
2021-02-25 22:38:35 +01:00
if ( $res < 0 ) {
$error ++ ;
}
2013-08-07 15:08:30 +02:00
2021-09-27 15:41:58 +02:00
// delete extrafields
$res = $this -> deleteExtraFields ();
2021-02-25 22:38:35 +01:00
if ( $res < 0 ) {
$error ++ ;
}
2020-04-23 19:09:05 +02:00
2025-01-28 14:32:09 +01:00
if ( ! $error ) {
// Delete linked contacts
$res = $this -> delete_linked_contact ();
if ( $res < 0 ) {
$error ++ ;
}
}
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2013-06-20 18:37:23 +02:00
$sql = " DELETE FROM " . MAIN_DB_PREFIX . " expedition " ;
2021-08-27 16:33:03 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2013-08-07 15:08:30 +02:00
2021-02-25 22:38:35 +01:00
if ( $this -> db -> query ( $sql )) {
if ( ! empty ( $this -> origin ) && $this -> origin_id > 0 ) {
2017-10-07 13:09:31 +02:00
$this -> fetch_origin ();
2024-10-03 19:40:34 +02:00
$origin_object = $this -> origin_object ;
'@phan-var-force Facture|Commande $origin_object' ;
if ( $origin_object -> statut == Commande :: STATUS_SHIPMENTONPROCESS ) { // If order source of shipment is "shipment in progress"
2017-10-07 13:09:31 +02:00
// Check if there is no more shipment. If not, we can move back status of order to "validated" instead of "shipment in progress"
2024-10-03 19:40:34 +02:00
$origin_object -> loadExpeditions ();
2017-10-07 13:09:31 +02:00
//var_dump($this->$origin->expeditions);exit;
2024-10-03 19:40:34 +02:00
if ( count ( $origin_object -> expeditions ) <= 0 ) {
$origin_object -> setStatut ( Commande :: STATUS_VALIDATED );
2017-10-07 13:09:31 +02:00
}
}
2016-04-01 16:59:08 +02:00
}
2016-09-07 12:41:32 +02:00
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2014-04-26 17:27:59 +02:00
$this -> db -> commit ();
2020-09-12 04:25:54 +02:00
// Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive
2023-11-13 12:24:47 +01:00
$this -> deleteEcmFiles ( 0 ); // Deleting files physically is done later with the dol_delete_dir_recursive
$this -> deleteEcmFiles ( 1 ); // Deleting files physically is done later with the dol_delete_dir_recursive
2020-09-03 12:43:38 +02:00
2014-04-26 17:27:59 +02:00
// We delete PDFs
$ref = dol_sanitizeFileName ( $this -> ref );
2021-02-25 22:38:35 +01:00
if ( ! empty ( $conf -> expedition -> dir_output )) {
2019-11-13 19:37:08 +01:00
$dir = $conf -> expedition -> dir_output . '/sending/' . $ref ;
$file = $dir . '/' . $ref . '.pdf' ;
2021-02-25 22:38:35 +01:00
if ( file_exists ( $file )) {
if ( ! dol_delete_file ( $file )) {
2014-04-26 17:27:59 +02:00
return 0 ;
}
2013-06-20 18:37:23 +02:00
}
2021-02-25 22:38:35 +01:00
if ( file_exists ( $dir )) {
if ( ! dol_delete_dir_recursive ( $dir )) {
2019-11-13 19:37:08 +01:00
$this -> error = $langs -> trans ( " ErrorCanNotDeleteDir " , $dir );
2014-04-26 17:27:59 +02:00
return 0 ;
}
2013-06-20 18:37:23 +02:00
}
2009-04-05 21:30:37 +02:00
}
2013-08-07 15:08:30 +02:00
2014-04-26 17:27:59 +02:00
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2014-04-26 17:27:59 +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 () . " - sql= $sql " ;
2013-06-20 18:37:23 +02:00
$this -> db -> rollback ();
return - 3 ;
2008-05-26 23:27:50 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
2009-04-05 21:30:37 +02:00
$this -> db -> rollback ();
2013-06-20 18:37:23 +02:00
return - 2 ;
2009-04-05 21:30:37 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
2008-05-26 23:27:50 +02:00
$this -> db -> rollback ();
2013-06-20 18:37:23 +02:00
return - 1 ;
2008-05-26 23:27:50 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2008-05-26 23:27:50 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2009-11-12 14:33:55 +01:00
/**
2011-09-29 22:32:28 +02:00
* Load lines
2009-11-12 14:33:55 +01:00
*
2011-12-16 15:29:58 +01:00
* @ return int > 0 if OK , Otherwise if KO
2009-11-12 14:33:55 +01:00
*/
2019-02-24 23:32:09 +01:00
public function fetch_lines ()
2006-08-26 16:13:37 +02:00
{
2020-10-28 17:49:52 +01:00
// phpcs:enable
2024-04-29 11:04:19 +02:00
global $mysoc ;
2022-03-28 13:50:47 +02:00
2020-03-12 12:45:44 +01:00
$this -> lines = array ();
2010-09-07 00:31:36 +02:00
2022-03-28 13:50:47 +02:00
// NOTE: This fetch_lines is special because it groups all lines with the same origin_line_id into one line.
// TODO: See if we can restore a common fetch_lines (one line = one record)
2020-03-31 10:54:14 +02:00
$sql = " SELECT cd.rowid, cd.fk_product, cd.label as custom_label, cd.description, cd.qty as qty_asked, cd.product_type, cd.fk_unit " ;
2020-03-12 12:45:44 +01:00
$sql .= " , cd.total_ht, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.total_tva " ;
2024-05-24 18:44:02 +02:00
$sql .= " , cd.fk_remise_except, cd.fk_product_fournisseur_price as fk_fournprice " ;
2020-03-12 12:45:44 +01:00
$sql .= " , cd.vat_src_code, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.info_bits, cd.price, cd.subprice, cd.remise_percent,cd.buy_price_ht as pa_ht " ;
2024-05-24 18:44:02 +02:00
$sql .= " , cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc, cd.rang, cd.date_start, cd.date_end " ;
2024-04-29 11:04:19 +02:00
$sql .= " , ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_element, ed.fk_elementdet, ed.element_type, ed.fk_entrepot " ;
2023-10-30 03:13:12 +01:00
$sql .= " , p.ref as product_ref, p.label as product_label, p.fk_product_type, p.barcode as product_barcode " ;
2024-02-03 00:04:54 +01:00
$sql .= " , p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tosell as product_tosell, p.tobuy as product_tobuy, p.tobatch as product_tobatch " ;
2020-03-12 12:45:44 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " expeditiondet as ed, " . MAIN_DB_PREFIX . " commandedet as cd " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " product as p ON p.rowid = cd.fk_product " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE ed.fk_expedition = " . (( int ) $this -> id );
2024-04-08 12:44:49 +02:00
$sql .= " AND ed.fk_elementdet = cd.rowid " ;
$sql .= " ORDER BY cd.rang, ed.fk_elementdet " ; // We need after a break on fk_elementdet but when there is no break on fk_elementdet, cd.rang is same so we can add it as first order criteria.
2008-05-26 23:27:50 +02:00
2014-06-12 11:31:53 +02:00
dol_syslog ( get_class ( $this ) . " ::fetch_lines " , LOG_DEBUG );
2006-08-26 16:13:37 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
2012-08-23 02:04:35 +02:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php' ;
2012-03-14 14:00:20 +01:00
2006-08-26 16:13:37 +02:00
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
2025-01-27 19:55:39 +01:00
$line = new ExpeditionLigne ( $this -> db );
2014-10-03 12:20:02 +02:00
$lineindex = 0 ;
$originline = 0 ;
2012-03-14 14:00:20 +01:00
2012-07-02 19:30:37 +02:00
$this -> total_ht = 0 ;
$this -> total_tva = 0 ;
$this -> total_ttc = 0 ;
$this -> total_localtax1 = 0 ;
2012-03-08 22:30:45 +01:00
$this -> total_localtax2 = 0 ;
2012-03-14 14:00:20 +01:00
2023-11-16 14:59:07 +01:00
$this -> multicurrency_total_ht = 0 ;
$this -> multicurrency_total_tva = 0 ;
$this -> multicurrency_total_ttc = 0 ;
2021-09-27 15:41:58 +02:00
$shipmentlinebatch = new ExpeditionLineBatch ( $this -> db );
2019-06-12 22:05:10 +02:00
2021-02-25 22:38:35 +01:00
while ( $i < $num ) {
2014-10-18 16:27:15 +02:00
$obj = $this -> db -> fetch_object ( $resql );
2023-09-13 01:39:57 +02:00
2024-04-08 12:44:49 +02:00
if ( $originline > 0 && $originline == $obj -> fk_elementdet ) {
2024-02-21 18:14:29 +01:00
'@phan-var-force ExpeditionLigne $line' ; // $line from previous loop
2019-11-13 19:37:08 +01:00
$line -> entrepot_id = 0 ; // entrepod_id in details_entrepot
$line -> qty_shipped += $obj -> qty_shipped ;
2014-10-03 12:20:02 +02:00
} else {
2023-09-13 01:39:57 +02:00
$line = new ExpeditionLigne ( $this -> db ); // new group to start
2025-01-27 19:55:39 +01:00
$line -> entrepot_id = $obj -> fk_entrepot ; // this is a property of a shipment line
$line -> qty_shipped = $obj -> qty_shipped ; // this is a property of a shipment line
2014-10-03 12:20:02 +02:00
}
2014-10-18 16:27:15 +02:00
2022-03-28 13:50:47 +02:00
$detail_entrepot = new stdClass ();
2014-10-03 12:20:02 +02:00
$detail_entrepot -> entrepot_id = $obj -> fk_entrepot ;
$detail_entrepot -> qty_shipped = $obj -> qty_shipped ;
2017-10-23 22:16:00 +02:00
$detail_entrepot -> line_id = $obj -> line_id ;
2014-10-03 12:20:02 +02:00
$line -> details_entrepot [] = $detail_entrepot ;
2014-10-18 16:27:15 +02:00
2024-04-29 11:04:19 +02:00
$line -> line_id = $obj -> line_id ; // TODO deprecated
2019-11-13 19:37:08 +01:00
$line -> rowid = $obj -> line_id ; // TODO deprecated
2017-10-07 13:09:31 +02:00
$line -> id = $obj -> line_id ;
2017-06-27 16:41:57 +02:00
2024-04-29 11:04:19 +02:00
$line -> fk_origin = 'orderline' ; // TODO deprecated, we already have element_type that can be use to guess type of line
$line -> fk_element = $obj -> fk_element ;
$line -> origin_id = $obj -> fk_element ;
2024-04-08 12:44:49 +02:00
$line -> fk_elementdet = $obj -> fk_elementdet ;
2024-04-29 11:04:19 +02:00
$line -> origin_line_id = $obj -> fk_elementdet ;
2024-04-08 12:44:49 +02:00
$line -> element_type = $obj -> element_type ;
2017-06-27 16:41:57 +02:00
2019-11-13 19:37:08 +01:00
$line -> fk_expedition = $this -> id ; // id of parent
2017-06-27 16:41:57 +02:00
2016-06-20 02:34:00 +02:00
$line -> product_type = $obj -> product_type ;
2010-03-13 16:52:30 +01:00
$line -> fk_product = $obj -> fk_product ;
$line -> fk_product_type = $obj -> fk_product_type ;
2019-11-13 19:37:08 +01:00
$line -> ref = $obj -> product_ref ; // TODO deprecated
$line -> product_ref = $obj -> product_ref ;
$line -> product_label = $obj -> product_label ;
$line -> libelle = $obj -> product_label ; // TODO deprecated
2025-01-27 19:55:39 +01:00
$line -> product_barcode = $obj -> product_barcode ; // Barcode number product
2020-11-16 16:31:05 +01:00
$line -> product_tosell = $obj -> product_tosell ;
$line -> product_tobuy = $obj -> product_tobuy ;
2019-11-13 19:37:08 +01:00
$line -> product_tobatch = $obj -> product_tobatch ;
2024-05-24 18:44:02 +02:00
$line -> fk_fournprice = $obj -> fk_fournprice ;
2019-11-13 19:37:08 +01:00
$line -> label = $obj -> custom_label ;
2010-03-13 16:52:30 +01:00
$line -> description = $obj -> description ;
$line -> qty_asked = $obj -> qty_asked ;
2020-03-12 12:45:44 +01:00
$line -> rang = $obj -> rang ;
2010-03-13 16:52:30 +01:00
$line -> weight = $obj -> weight ;
$line -> weight_units = $obj -> weight_units ;
2012-11-18 16:21:38 +01:00
$line -> length = $obj -> length ;
$line -> length_units = $obj -> length_units ;
2024-02-03 00:04:54 +01:00
$line -> width = $obj -> width ;
$line -> width_units = $obj -> width_units ;
$line -> height = $obj -> height ;
$line -> height_units = $obj -> height_units ;
2012-11-18 16:21:38 +01:00
$line -> surface = $obj -> surface ;
2019-11-13 19:37:08 +01:00
$line -> surface_units = $obj -> surface_units ;
2010-03-13 16:52:30 +01:00
$line -> volume = $obj -> volume ;
$line -> volume_units = $obj -> volume_units ;
2020-04-10 10:59:32 +02:00
$line -> fk_unit = $obj -> fk_unit ;
2012-03-14 14:00:20 +01:00
2019-11-13 19:37:08 +01:00
$line -> pa_ht = $obj -> pa_ht ;
2016-09-07 12:41:32 +02:00
2017-10-18 12:10:00 +02:00
// Local taxes
2024-03-11 17:39:28 +01:00
$localtax_array = array ( 0 => $obj -> localtax1_type , 1 => $obj -> localtax1_tx , 2 => $obj -> localtax2_type , 3 => $obj -> localtax2_tx );
2017-10-18 12:10:00 +02:00
$localtax1_tx = get_localtax ( $obj -> tva_tx , 1 , $this -> thirdparty );
$localtax2_tx = get_localtax ( $obj -> tva_tx , 2 , $this -> thirdparty );
2017-06-23 11:12:17 +02:00
2013-02-17 18:40:09 +01:00
// For invoicing
2019-11-13 19:37:08 +01:00
$tabprice = calcul_price_total ( $obj -> qty_shipped , $obj -> subprice , $obj -> remise_percent , $obj -> tva_tx , $localtax1_tx , $localtax2_tx , 0 , 'HT' , $obj -> info_bits , $obj -> fk_product_type , $mysoc , $localtax_array ); // We force type to 0
$line -> desc = $obj -> description ; // We need ->desc because some code into CommonObject use desc (property defined for other elements)
$line -> qty = $line -> qty_shipped ;
2024-11-04 12:32:13 +01:00
$line -> total_ht = ( float ) $tabprice [ 0 ];
$line -> total_localtax1 = ( float ) $tabprice [ 9 ];
$line -> total_localtax2 = ( float ) $tabprice [ 10 ];
$line -> total_ttc = ( float ) $tabprice [ 2 ];
$line -> total_tva = ( float ) $tabprice [ 1 ];
2019-11-13 19:37:08 +01:00
$line -> vat_src_code = $obj -> vat_src_code ;
$line -> tva_tx = $obj -> tva_tx ;
2012-03-08 22:30:45 +01:00
$line -> localtax1_tx = $obj -> localtax1_tx ;
$line -> localtax2_tx = $obj -> localtax2_tx ;
2019-11-13 19:37:08 +01:00
$line -> info_bits = $obj -> info_bits ;
$line -> price = $obj -> price ;
$line -> subprice = $obj -> subprice ;
2024-05-24 18:44:02 +02:00
$line -> fk_remise_except = $obj -> fk_remise_except ;
2019-11-13 19:37:08 +01:00
$line -> remise_percent = $obj -> remise_percent ;
2012-03-14 14:00:20 +01:00
2019-11-13 19:37:08 +01:00
$this -> total_ht += $tabprice [ 0 ];
$this -> total_tva += $tabprice [ 1 ];
$this -> total_ttc += $tabprice [ 2 ];
$this -> total_localtax1 += $tabprice [ 9 ];
$this -> total_localtax2 += $tabprice [ 10 ];
2016-09-07 12:41:32 +02:00
2024-05-24 18:44:02 +02:00
$line -> date_start = $this -> db -> jdate ( $obj -> date_start );
$line -> date_end = $this -> db -> jdate ( $obj -> date_end );
2017-06-23 11:12:17 +02:00
// Multicurrency
2019-11-13 19:37:08 +01:00
$this -> fk_multicurrency = $obj -> fk_multicurrency ;
$this -> multicurrency_code = $obj -> multicurrency_code ;
2023-11-16 14:59:07 +01:00
$line -> multicurrency_subprice = $obj -> multicurrency_subprice ;
$line -> multicurrency_total_ht = $obj -> multicurrency_total_ht ;
$line -> multicurrency_total_tva = $obj -> multicurrency_total_tva ;
$line -> multicurrency_total_ttc = $obj -> multicurrency_total_ttc ;
$this -> multicurrency_total_ht += $obj -> multicurrency_total_ht ;
$this -> multicurrency_total_tva += $obj -> multicurrency_total_tva ;
$this -> multicurrency_total_ttc += $obj -> multicurrency_total_ttc ;
2017-06-23 11:12:17 +02:00
2024-04-08 12:44:49 +02:00
if ( $originline != $obj -> fk_elementdet ) {
2015-12-18 18:00:31 +01:00
$line -> detail_batch = array ();
}
2017-12-02 10:43:01 +01:00
// Detail of batch
2022-08-31 21:55:55 +02:00
if ( isModEnabled ( 'productbatch' ) && $obj -> line_id > 0 && $obj -> product_tobatch > 0 ) {
2021-09-27 15:41:58 +02:00
$newdetailbatch = $shipmentlinebatch -> fetchAll ( $obj -> line_id , $obj -> fk_product );
2017-10-07 13:09:31 +02:00
2021-02-25 22:38:35 +01:00
if ( is_array ( $newdetailbatch )) {
2024-04-08 12:44:49 +02:00
if ( $originline != $obj -> fk_elementdet ) {
2017-10-07 13:09:31 +02:00
$line -> detail_batch = $newdetailbatch ;
2020-05-21 15:05:19 +02:00
} else {
2017-10-07 13:09:31 +02:00
$line -> detail_batch = array_merge ( $line -> detail_batch , $newdetailbatch );
}
}
2014-10-03 12:20:02 +02:00
}
2015-07-13 11:22:18 +02:00
2022-03-28 13:50:47 +02:00
$line -> fetch_optionals ();
2024-04-08 12:44:49 +02:00
if ( $originline != $obj -> fk_elementdet ) {
2017-10-07 13:09:31 +02:00
$this -> lines [ $lineindex ] = $line ;
$lineindex ++ ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$line -> total_ht += $tabprice [ 0 ];
2017-10-07 13:09:31 +02:00
$line -> total_localtax1 += $tabprice [ 9 ];
$line -> total_localtax2 += $tabprice [ 10 ];
$line -> total_ttc += $tabprice [ 2 ];
$line -> total_tva += $tabprice [ 1 ];
2014-03-07 11:35:16 +01:00
}
2022-03-28 13:50:47 +02:00
2006-08-26 16:13:37 +02:00
$i ++ ;
2024-04-08 12:44:49 +02:00
$originline = $obj -> fk_elementdet ;
2006-08-26 16:13:37 +02:00
}
$this -> db -> free ( $resql );
2007-05-16 00:47:58 +02:00
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2008-05-26 23:27:50 +02:00
return - 3 ;
}
}
2017-12-21 16:50:18 +01:00
/**
* Delete detail line
*
* @ param User $user User making deletion
* @ param int $lineid Id of line to delete
* @ return int > 0 if OK , < 0 if KO
*/
2024-02-02 23:46:12 +01:00
public function deleteLine ( $user , $lineid )
2017-12-21 16:50:18 +01:00
{
global $user ;
2021-02-25 22:38:35 +01:00
if ( $this -> statut == self :: STATUS_DRAFT ) {
2017-12-21 16:50:18 +01:00
$this -> db -> begin ();
2019-11-13 19:37:08 +01:00
$line = new ExpeditionLigne ( $this -> db );
2017-12-21 16:50:18 +01:00
// For triggers
$line -> fetch ( $lineid );
2021-02-25 22:38:35 +01:00
if ( $line -> delete ( $user ) > 0 ) {
2017-12-21 16:50:18 +01:00
//$this->update_price(1);
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2017-12-21 16:50:18 +01: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 = 'ErrorDeleteLineNotAllowedByObjectStatus' ;
2017-12-21 16:50:18 +01:00
return - 2 ;
}
}
2023-02-13 23:29:10 +01:00
/**
* getTooltipContentArray
2024-09-23 03:24:19 +02:00
* @ param array < string , mixed > $params params to construct tooltip data
2023-02-13 23:29:10 +01:00
* @ since v18
2024-09-23 03:24:19 +02:00
* @ 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-02-13 23:29:10 +01:00
*/
public function getTooltipContentArray ( $params )
{
global $conf , $langs ;
2023-03-29 18:22:36 +02:00
$langs -> load ( 'sendings' );
2023-02-22 01:09:23 +01:00
$nofetch = ! empty ( $params [ 'nofetch' ]);
$datas = array ();
2023-02-13 23:29:10 +01:00
$datas [ 'picto' ] = img_picto ( '' , $this -> picto ) . ' <u class="paddingrightonly">' . $langs -> trans ( " Shipment " ) . '</u>' ;
if ( isset ( $this -> statut )) {
$datas [ 'picto' ] .= ' ' . $this -> getLibStatut ( 5 );
}
$datas [ 'ref' ] = '<br><b>' . $langs -> trans ( 'Ref' ) . ':</b> ' . $this -> ref ;
$datas [ 'refcustomer' ] = '<br><b>' . $langs -> trans ( 'RefCustomer' ) . ':</b> ' . ( $this -> ref_customer ? $this -> ref_customer : $this -> ref_client );
2023-03-29 18:25:53 +02:00
if ( ! $nofetch ) {
$langs -> load ( 'companies' );
if ( empty ( $this -> thirdparty )) {
$this -> fetch_thirdparty ();
}
$datas [ 'customer' ] = '<br><b>' . $langs -> trans ( 'Customer' ) . ':</b> ' . $this -> thirdparty -> getNomUrl ( 1 , '' , 0 , 1 );
}
2023-02-13 23:29:10 +01:00
return $datas ;
}
2010-05-27 00:06:27 +02:00
/**
2024-08-07 01:20:43 +02:00
* Return clickable link of object ( with eventually picto )
2017-10-07 13:09:31 +02:00
*
* @ param int $withpicto Add picto into link
* @ param string $option Where the link point to
* @ param int $max Max length to show
* @ param int $short Use short labels
* @ param int $notooltip 1 = No tooltip
* @ param int $save_lastsearch_value - 1 = Auto , 0 = No save of lastsearch_values when clicking , 1 = Save lastsearch_values whenclicking
* @ return string String with URL
*/
2019-02-24 23:32:09 +01:00
public function getNomUrl ( $withpicto = 0 , $option = '' , $max = 0 , $short = 0 , $notooltip = 0 , $save_lastsearch_value = - 1 )
2010-05-27 00:06:27 +02:00
{
2023-12-19 11:51:48 +01:00
global $langs , $hookmanager ;
2010-05-27 00:06:27 +02:00
2019-11-13 19:37:08 +01:00
$result = '' ;
2023-02-13 23:29:10 +01:00
$params = [
'id' => $this -> id ,
'objecttype' => $this -> element ,
'option' => $option ,
'nofetch' => 1 ,
];
$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-13 23:29:10 +01:00
}
2017-06-23 11:12:17 +02:00
2014-09-18 21:18:25 +02:00
$url = DOL_URL_ROOT . '/expedition/card.php?id=' . $this -> id ;
2011-08-31 16:42:47 +02:00
2021-02-25 22:38:35 +01:00
if ( $short ) {
return $url ;
}
2010-05-27 00:06:27 +02:00
2021-02-25 22:38:35 +01:00
if ( $option !== 'nolink' ) {
2017-10-03 16:00:52 +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-25 22:38:35 +01:00
$add_save_lastsearch_values = 1 ;
}
if ( $add_save_lastsearch_values ) {
$url .= '&save_lastsearch_values=1' ;
}
2017-10-03 16:00:52 +02:00
}
2019-11-13 19:37:08 +01:00
$linkclose = '' ;
2021-02-25 22:38:35 +01:00
if ( empty ( $notooltip )) {
2023-11-27 11:41:05 +01:00
if ( getDolGlobalString ( 'MAIN_OPTIMIZEFORTEXTBROWSER' )) {
2020-04-20 15:57:15 +02:00
$label = $langs -> trans ( " Shipment " );
2025-01-09 02:01:49 +01:00
$linkclose .= ' alt="' . dolPrintHTMLForAttribute ( $label ) . '"' ;
2017-10-07 13:09:31 +02:00
}
2025-01-09 02:01:49 +01:00
$linkclose .= ( $label ? ' title="' . dolPrintHTMLForAttribute ( $label ) . '"' : ' title="tocomplete"' );
2023-04-03 19:51:40 +02:00
$linkclose .= $dataparams . ' class="' . $classfortooltip . '"' ;
2016-11-02 10:29:14 +01:00
}
2017-06-23 11:12:17 +02:00
2020-04-20 15:57:15 +02:00
$linkstart = '<a href="' . $url . '"' ;
$linkstart .= $linkclose . '>' ;
2019-11-13 19:37:08 +01:00
$linkend = '</a>' ;
2010-05-27 00:06:27 +02:00
2017-11-02 15:03:09 +01:00
$result .= $linkstart ;
2021-02-25 22:38:35 +01:00
if ( $withpicto ) {
2023-09-12 10:52:15 +02:00
$result .= img_object (( $notooltip ? '' : $label ), ( $this -> picto ? $this -> picto : 'generic' ), ( $notooltip ? (( $withpicto != 2 ) ? 'class="paddingright"' : '' ) : 'class="' . (( $withpicto != 2 ) ? 'paddingright ' : '' ) . '"' ), 0 , 0 , $notooltip ? 0 : 1 );
2021-02-25 22:38:35 +01:00
}
if ( $withpicto != 2 ) {
$result .= $this -> ref ;
}
2017-11-02 15:03:09 +01:00
$result .= $linkend ;
2022-02-15 11:15:34 +01:00
global $action ;
$hookmanager -> initHooks ( array ( $this -> element . 'dao' ));
2024-03-11 17:39:28 +01:00
$parameters = array ( 'id' => $this -> id , 'getnomurl' => & $result );
2022-02-15 11:15:34 +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 ;
}
2010-05-27 00:06:27 +02:00
return $result ;
}
2012-01-04 23:56:10 +01:00
2008-05-26 23:27:50 +02:00
/**
2017-10-07 13:09:31 +02:00
* Return status label
*
* @ param int $mode 0 = Long label , 1 = Short label , 2 = Picto + Short label , 3 = Picto , 4 = Picto + Long label , 5 = Short label + Picto
2023-04-08 15:08:55 +02:00
* @ return string Label
2017-10-07 13:09:31 +02:00
*/
2019-02-24 23:32:09 +01:00
public function getLibStatut ( $mode = 0 )
2008-05-26 23:27:50 +02:00
{
2019-01-27 11:55:16 +01:00
return $this -> LibStatut ( $this -> statut , $mode );
2006-08-26 16:13:37 +02:00
}
2008-05-26 23:27:50 +02:00
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2006-07-14 15:26:19 +02:00
/**
2011-09-29 22:32:28 +02:00
* Return label of a status
*
2019-11-04 19:28:04 +01:00
* @ param int $status Id statut
* @ 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
2006-07-14 15:26:19 +02:00
*/
2019-11-01 23:58:14 +01:00
public function LibStatut ( $status , $mode )
2008-05-26 23:27:50 +02:00
{
2020-10-28 17:49:52 +01:00
// phpcs:enable
global $langs ;
2006-07-14 15:26:19 +02:00
2023-11-24 10:10:24 +01:00
$labelStatus = $langs -> transnoentitiesnoconv ( $this -> labelStatus [ $status ]);
$labelStatusShort = $langs -> transnoentitiesnoconv ( $this -> labelStatusShort [ $status ]);
2019-11-04 19:28:04 +01:00
$statusType = 'status' . $status ;
2021-02-25 22:38:35 +01:00
if ( $status == self :: STATUS_VALIDATED ) {
$statusType = 'status4' ;
}
if ( $status == self :: STATUS_CLOSED ) {
$statusType = 'status6' ;
}
if ( $status == self :: STATUS_CANCELED ) {
$statusType = 'status9' ;
}
2019-11-04 19:28:04 +01:00
2024-09-13 03:09:53 +02:00
$signed_label = ' (' . $this -> getLibSignedStatus () . ')' ;
$status_label = $this -> signed_status ? $labelStatus . $signed_label : $labelStatus ;
$status_label_short = $this -> signed_status ? $labelStatusShort . $signed_label : $labelStatusShort ;
return dolGetStatus ( $status_label , $status_label_short , '' , $statusType , $mode );
2008-05-26 23:27:50 +02:00
}
2006-08-26 15:47:10 +02:00
2023-12-19 11:51:48 +01:00
/**
2024-08-07 01:20:43 +02:00
* Return clickable link of object ( with eventually picto )
2023-12-19 11:51:48 +01:00
*
2024-08-22 03:31:04 +02:00
* @ param string $option Where point the link ( 0 => main card , 1 , 2 => shipment , 'nolink' => No link )
2025-02-03 11:24:16 +01:00
* @ param ? array < string , mixed > $arraydata Array of data
2024-08-22 03:31:04 +02:00
* @ return string HTML Code for Kanban thumb .
2023-12-19 11:51:48 +01:00
*/
public function getKanbanView ( $option = '' , $arraydata = null )
{
global $langs , $conf ;
$selected = ( empty ( $arraydata [ 'selected' ]) ? 0 : $arraydata [ 'selected' ]);
$return = '<div class="box-flex-item box-flex-grow-zero">' ;
$return .= '<div class="info-box info-box-sm">' ;
$return .= '<div class="info-box-icon bg-infobox-action">' ;
$return .= img_picto ( '' , 'order' );
$return .= '</div>' ;
$return .= '<div class="info-box-content">' ;
$return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . ( method_exists ( $this , 'getNomUrl' ) ? $this -> getNomUrl () : $this -> ref ) . '</span>' ;
if ( $selected >= 0 ) {
$return .= '<input id="cb' . $this -> id . '" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="' . $this -> id . '"' . ( $selected ? ' checked="checked"' : '' ) . '>' ;
}
if ( property_exists ( $this , 'thirdparty' ) && is_object ( $this -> thirdparty )) {
$return .= '<br><div class="info-box-ref tdoverflowmax150">' . $this -> thirdparty -> getNomUrl ( 1 ) . '</div>' ;
}
if ( property_exists ( $this , 'total_ht' )) {
$return .= '<div class="info-box-ref amount">' . price ( $this -> total_ht , 0 , $langs , 0 , - 1 , - 1 , $conf -> currency ) . ' ' . $langs -> trans ( 'HT' ) . '</div>' ;
}
if ( method_exists ( $this , 'getLibStatut' )) {
$return .= '<div class="info-box-status">' . $this -> getLibStatut ( 3 ) . '</div>' ;
}
$return .= '</div>' ;
$return .= '</div>' ;
$return .= '</div>' ;
2023-12-19 12:33:55 +01:00
2023-12-19 11:51:48 +01:00
return $return ;
}
2006-08-26 15:47:10 +02:00
/**
2017-10-07 13:09:31 +02:00
* 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
2006-08-26 15:47:10 +02:00
*/
2019-02-24 23:32:09 +01:00
public function initAsSpecimen ()
2006-08-26 15:47:10 +02:00
{
2016-05-06 22:43:50 +02:00
global $langs ;
2006-08-26 15:47:10 +02:00
2019-11-13 19:37:08 +01:00
$now = dol_now ();
2011-08-31 16:42:47 +02:00
2012-01-04 23:56:10 +01:00
dol_syslog ( get_class ( $this ) . " ::initAsSpecimen " );
2008-10-25 13:16:39 +02:00
2019-11-13 19:37:08 +01:00
$order = new Commande ( $this -> db );
2008-05-17 03:52:24 +02:00
$order -> initAsSpecimen ();
2008-05-26 23:27:50 +02:00
2024-01-13 19:48:41 +01:00
// Initialise parameters
2019-11-13 19:37:08 +01:00
$this -> id = 0 ;
2012-04-22 00:41:13 +02:00
$this -> ref = 'SPECIMEN' ;
2019-11-13 19:37:08 +01:00
$this -> specimen = 1 ;
2019-02-05 11:58:49 +01:00
$this -> statut = self :: STATUS_VALIDATED ;
2011-08-31 16:42:47 +02:00
$this -> livraison_id = 0 ;
$this -> date = $now ;
$this -> date_creation = $now ;
$this -> date_valid = $now ;
2023-01-01 23:50:37 +01:00
$this -> date_delivery = $now + 24 * 3600 ;
2019-11-13 19:37:08 +01:00
$this -> date_expedition = $now + 24 * 3600 ;
2011-08-31 16:42:47 +02:00
2008-05-26 23:27:50 +02:00
$this -> entrepot_id = 0 ;
2009-07-08 12:02:57 +02:00
$this -> fk_delivery_address = 0 ;
2010-09-19 18:25:24 +02:00
$this -> socid = 1 ;
2006-08-26 15:47:10 +02:00
2008-05-17 03:52:24 +02:00
$this -> commande_id = 0 ;
$this -> commande = $order ;
2008-05-26 23:27:50 +02:00
2017-10-07 13:09:31 +02:00
$this -> origin_id = 1 ;
$this -> origin = 'commande' ;
2013-04-11 21:53:41 +02:00
2020-03-12 12:45:44 +01:00
$this -> note_private = 'Private note' ;
$this -> note_public = 'Public note' ;
2010-09-19 18:25:24 +02:00
2024-11-21 19:40:52 +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)
2006-08-26 15:47:10 +02:00
$xnbp = 0 ;
2021-02-25 22:38:35 +01:00
while ( $xnbp < $nbp ) {
2020-03-12 12:45:44 +01:00
$line = new ExpeditionLigne ( $this -> db );
2023-08-06 01:14:36 +02:00
$line -> product_desc = $langs -> trans ( " Description " ) . " " . $xnbp ;
$line -> product_label = $langs -> trans ( " Description " ) . " " . $xnbp ;
2020-03-12 12:45:44 +01:00
$line -> qty = 10 ;
$line -> qty_asked = 5 ;
$line -> qty_shipped = 4 ;
$line -> fk_product = $this -> commande -> lines [ $xnbp ] -> fk_product ;
2024-11-06 12:50:24 +01:00
$line -> weight = 1.123456 ;
$line -> weight_units = 0 ; // kg
$line -> volume = 2.34567 ;
$line -> volume_unit = 0 ;
2020-03-12 12:45:44 +01:00
$this -> lines [] = $line ;
2006-08-26 15:47:10 +02:00
$xnbp ++ ;
}
2024-03-02 16:38:35 +01:00
return 1 ;
2008-05-26 23:27:50 +02:00
}
2009-03-23 18:38:04 +01:00
2020-10-26 16:50:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2010-05-13 01:03:33 +02:00
/**
2020-10-26 16:50:52 +01:00
* Set delivery date
*
* @ param User $user Object user that modify
* @ param int $delivery_date Delivery date
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 )
2020-10-26 16:50:52 +01:00
{
2020-10-26 18:13:25 +01:00
// phpcs:enable
2020-10-26 16:59:25 +01:00
return $this -> setDeliveryDate ( $user , $delivery_date );
2020-10-26 16:50:52 +01:00
}
2020-10-31 14:32:18 +01:00
/**
2011-12-16 15:29:58 +01:00
* Set the planned delivery date
2011-09-29 22:32:28 +02:00
*
2024-01-13 19:48:41 +01:00
* @ param User $user Object user that modify
2020-10-06 11:37:55 +02:00
* @ param integer $delivery_date Date of delivery
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2010-05-13 01:03:33 +02:00
*/
2020-10-26 16:50:52 +01:00
public function setDeliveryDate ( $user , $delivery_date )
2010-05-13 01:03:33 +02:00
{
2023-10-15 18:12:03 +02:00
if ( $user -> hasRight ( 'expedition' , 'creer' )) {
2010-05-13 01:03:33 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . " expedition " ;
2020-10-06 11:37:55 +02:00
$sql .= " SET date_delivery = " . ( $delivery_date ? " ' " . $this -> db -> idate ( $delivery_date ) . " ' " : 'null' );
2021-08-27 16:33:03 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2010-05-13 01:03:33 +02:00
2020-10-26 16:50:52 +01:00
dol_syslog ( get_class ( $this ) . " ::setDeliveryDate " , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
2020-10-06 11:37:55 +02:00
$this -> date_delivery = $delivery_date ;
2010-05-13 01:03:33 +02:00
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> error ();
2010-05-13 01:03:33 +02:00
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2010-05-13 01:03:33 +02:00
return - 2 ;
}
}
2024-11-20 20:06:43 +01:00
/**
* Set the shipping date
*
* @ param User $user Object user that modify
* @ param integer $shipping_date Date of shipping
* @ return int Return integer < 0 if KO , > 0 if OK
*/
public function setShippingDate ( $user , $shipping_date )
{
if ( $user -> hasRight ( 'expedition' , 'creer' )) {
$sql = " UPDATE " . MAIN_DB_PREFIX . " expedition " ;
$sql .= " SET date_expedition = " . ( $shipping_date ? " ' " . $this -> db -> idate ( $shipping_date ) . " ' " : 'null' );
$sql .= " WHERE rowid = " . (( int ) $this -> id );
dol_syslog ( get_class ( $this ) . " ::setShippingDate " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
$this -> date_shipping = $shipping_date ;
return 1 ;
} else {
$this -> error = $this -> db -> error ();
return - 1 ;
}
} else {
return - 2 ;
}
}
2010-05-13 01:03:33 +02:00
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2009-03-23 18:38:04 +01:00
/**
2011-12-16 15:29:58 +01:00
* Fetch deliveries method and return an array . Load array this -> meths ( rowid => label ) .
2011-09-29 22:32:28 +02:00
*
2011-12-16 15:29:58 +01:00
* @ return void
2008-10-25 23:18:53 +02:00
*/
2019-02-24 23:32:09 +01:00
public function fetch_delivery_methods ()
2008-10-25 13:16:39 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2009-03-23 18:38:04 +01:00
global $langs ;
2016-05-06 22:43:50 +02:00
$this -> meths = array ();
2008-10-25 13:16:39 +02:00
2019-11-02 12:59:38 +01:00
$sql = " SELECT em.rowid, em.code, em.libelle as label " ;
2020-03-12 12:45:44 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_shipment_mode as em " ;
$sql .= " WHERE em.active = 1 " ;
$sql .= " ORDER BY em.libelle ASC " ;
2008-10-25 13:16:39 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
while ( $obj = $this -> db -> fetch_object ( $resql )) {
2020-03-12 12:45:44 +01:00
$label = $langs -> trans ( 'SendingMethod' . $obj -> code );
$this -> meths [ $obj -> rowid ] = ( $label != 'SendingMethod' . $obj -> code ? $label : $obj -> label );
2008-10-29 11:51:52 +01:00
}
2008-10-25 13:16:39 +02:00
}
}
2009-01-29 13:39:52 +01:00
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2017-10-07 13:09:31 +02:00
/**
* Fetch all deliveries method and return an array . Load array this -> listmeths .
*
2019-04-04 18:33:12 +02:00
* @ param int $id only this carrier , all if none
2017-10-07 13:09:31 +02:00
* @ return void
*/
2024-03-02 12:41:46 +01:00
public function list_delivery_methods ( $id = 0 )
2017-10-07 13:09:31 +02:00
{
2020-10-28 17:49:52 +01:00
// phpcs:enable
2017-10-07 13:09:31 +02:00
global $langs ;
$this -> listmeths = array ();
2020-03-12 12:45:44 +01:00
$i = 0 ;
2017-10-07 13:09:31 +02:00
2019-11-02 12:59:38 +01:00
$sql = " SELECT em.rowid, em.code, em.libelle as label, em.description, em.tracking, em.active " ;
2020-03-12 12:45:44 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_shipment_mode as em " ;
2024-03-02 12:41:46 +01:00
if ( ! empty ( $id )) {
2021-04-24 20:18:11 +02:00
$sql .= " WHERE em.rowid= " . (( int ) $id );
2021-02-25 22:38:35 +01:00
}
2017-10-07 13:09:31 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
while ( $obj = $this -> db -> fetch_object ( $resql )) {
2017-10-07 13:09:31 +02:00
$this -> listmeths [ $i ][ 'rowid' ] = $obj -> rowid ;
$this -> listmeths [ $i ][ 'code' ] = $obj -> code ;
2020-03-12 12:45:44 +01:00
$label = $langs -> trans ( 'SendingMethod' . $obj -> code );
$this -> listmeths [ $i ][ 'libelle' ] = ( $label != 'SendingMethod' . $obj -> code ? $label : $obj -> label );
2017-10-07 13:09:31 +02:00
$this -> listmeths [ $i ][ 'description' ] = $obj -> description ;
$this -> listmeths [ $i ][ 'tracking' ] = $obj -> tracking ;
$this -> listmeths [ $i ][ 'active' ] = $obj -> active ;
$i ++ ;
}
}
}
2009-02-03 03:39:28 +01:00
/**
2015-01-23 18:33:33 +01:00
* Forge an set tracking url
2012-01-04 23:56:10 +01:00
*
* @ param string $value Value
* @ return void
2008-10-25 23:18:53 +02:00
*/
2019-02-24 23:32:09 +01:00
public function getUrlTrackingStatus ( $value = '' )
2008-10-25 13:16:39 +02:00
{
2021-02-25 22:38:35 +01:00
if ( ! empty ( $this -> shipping_method_id )) {
2013-02-22 14:18:51 +01:00
$sql = " SELECT em.code, em.tracking " ;
2019-11-13 19:37:08 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_shipment_mode as em " ;
2021-06-09 15:36:47 +02:00
$sql .= " WHERE em.rowid = " . (( int ) $this -> shipping_method_id );
2011-06-19 21:47:09 +02:00
2011-05-25 18:53:39 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
if ( $obj = $this -> db -> fetch_object ( $resql )) {
2013-04-19 20:20:10 +02:00
$tracking = $obj -> tracking ;
2011-05-25 18:53:39 +02:00
}
2008-10-29 13:04:37 +01:00
}
2008-10-25 13:16:39 +02:00
}
2021-02-25 22:38:35 +01:00
if ( ! empty ( $tracking ) && ! empty ( $value )) {
2013-04-19 20:20:10 +02:00
$url = str_replace ( '{TRACKID}' , $value , $tracking );
2024-03-17 18:02:51 +01:00
$this -> tracking_url = sprintf ( '<a target="_blank" rel="noopener noreferrer" href="%s">%s</a>' , $url , ( $value ? $value : 'url' ));
2020-05-21 15:05:19 +02:00
} else {
2013-04-19 20:20:10 +02:00
$this -> tracking_url = $value ;
}
}
2012-03-14 14:00:20 +01:00
2012-07-02 19:30:37 +02:00
/**
2024-03-17 18:02:51 +01:00
* Classify the shipping as closed ( this records also the stock movement )
2012-07-02 19:30:37 +02:00
*
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2012-07-02 19:30:37 +02:00
*/
2019-02-24 23:32:09 +01:00
public function setClosed ()
2012-07-02 19:30:37 +02:00
{
2024-04-08 15:13:19 +02:00
global $user ;
2012-07-02 19:30:37 +02:00
2019-11-13 19:37:08 +01:00
$error = 0 ;
2016-09-07 12:41:32 +02:00
2019-12-17 18:05:59 +01:00
// Protection. This avoid to move stock later when we should not
2021-02-25 22:38:35 +01:00
if ( $this -> statut == self :: STATUS_CLOSED ) {
2019-12-23 15:51:23 +01:00
return 0 ;
}
2019-12-17 18:05:59 +01:00
2016-05-23 09:16:47 +02:00
$this -> db -> begin ();
2016-09-07 12:41:32 +02:00
2024-09-05 15:24:33 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . " expedition SET fk_statut = " . self :: STATUS_CLOSED . " , date_expedition = ' " . $this -> db -> escape ( $this -> db -> idate ( dol_now ())) . " ' " ;
2022-04-11 17:34:19 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . " AND fk_statut > 0 " ;
2014-10-18 16:27:15 +02:00
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
2016-06-09 22:40:21 +02:00
// Set order billed if 100% of order is shipped (qty in shipment lines match qty in order lines)
2021-02-25 22:38:35 +01:00
if ( $this -> origin == 'commande' && $this -> origin_id > 0 ) {
2016-06-09 22:40:21 +02:00
$order = new Commande ( $this -> db );
$order -> fetch ( $this -> origin_id );
2016-09-07 12:41:32 +02:00
2019-11-13 19:37:08 +01:00
$order -> loadExpeditions ( self :: STATUS_CLOSED ); // Fill $order->expeditions = array(orderlineid => qty)
2016-09-07 12:41:32 +02:00
2016-06-09 22:40:21 +02:00
$shipments_match_order = 1 ;
2021-02-25 22:38:35 +01:00
foreach ( $order -> lines as $line ) {
2016-06-09 22:40:21 +02:00
$lineid = $line -> id ;
$qty = $line -> qty ;
2023-11-27 11:41:05 +01:00
if (( $line -> product_type == 0 || getDolGlobalString ( 'STOCK_SUPPORTS_SERVICES' )) && $order -> expeditions [ $lineid ] != $qty ) {
2016-06-09 22:40:21 +02:00
$shipments_match_order = 0 ;
2019-11-13 19:37:08 +01:00
$text = 'Qty for order line id ' . $lineid . ' is ' . $qty . '. However in the shipments with status Expedition::STATUS_CLOSED=' . self :: STATUS_CLOSED . ' we have qty = ' . $order -> expeditions [ $lineid ] . ', so we can t close order' ;
2016-06-09 22:40:21 +02:00
dol_syslog ( $text );
break ;
}
}
2021-02-25 22:38:35 +01:00
if ( $shipments_match_order ) {
2022-10-07 22:44:20 +02:00
dol_syslog ( " Qty for the " . count ( $order -> lines ) . " lines of the origin order is same than qty for lines in the shipment we close (shipments_match_order is true), with new status Expedition::STATUS_CLOSED= " . self :: STATUS_CLOSED . ', so we close order' );
// We close the order
$order -> cloture ( $user ); // Note this may also create an invoice if module workflow ask it
2016-06-09 22:40:21 +02:00
}
}
2016-09-07 12:41:32 +02:00
2022-04-11 17:34:19 +02:00
$this -> statut = self :: STATUS_CLOSED ; // Will be revert to STATUS_VALIDATED at end if there is a rollback
$this -> status = self :: STATUS_CLOSED ; // Will be revert to STATUS_VALIDATED at end if there is a rollback
2016-05-14 19:14:39 +02:00
// If stock increment is done on closing
2023-11-27 11:41:05 +01:00
if ( ! $error && isModEnabled ( 'stock' ) && getDolGlobalString ( 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE' )) {
2022-10-14 11:28:49 +02:00
$result = $this -> manageStockMvtOnEvt ( $user );
2024-03-11 17:39:28 +01:00
if ( $result < 0 ) {
2016-06-02 11:23:49 +02:00
$error ++ ;
2016-04-25 18:33:39 +02:00
}
}
2016-09-07 12:41:32 +02:00
2016-05-20 20:03:29 +02:00
// Call trigger
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'SHIPPING_CLOSED' , $user );
2017-10-07 13:09:31 +02:00
if ( $result < 0 ) {
$error ++ ;
}
2016-05-20 20:03:29 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2016-04-26 13:27:32 +02:00
dol_print_error ( $this -> db );
2017-10-07 13:09:31 +02:00
$error ++ ;
2016-05-23 09:16:47 +02:00
}
2016-09-07 12:41:32 +02:00
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2017-10-07 13:09:31 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2019-02-05 11:58:49 +01:00
$this -> statut = self :: STATUS_VALIDATED ;
2022-04-11 17:34:19 +02:00
$this -> status = self :: STATUS_VALIDATED ;
2017-10-07 13:09:31 +02:00
$this -> db -> rollback ();
return - 1 ;
2016-04-26 13:27:32 +02:00
}
}
2022-10-14 11:28:49 +02:00
/**
* Manage Stock MVt onb Close or valid Shipment
2023-09-13 01:39:57 +02:00
*
* @ param User $user Object user that modify
* @ param string $labelmovement Label of movement
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2022-10-14 11:28:49 +02:00
* @ throws Exception
*/
2023-09-13 01:39:57 +02:00
private function manageStockMvtOnEvt ( $user , $labelmovement = 'ShipmentClassifyClosedInDolibarr' )
2022-10-14 11:28:49 +02:00
{
2022-10-14 11:35:44 +02:00
global $langs ;
2024-03-11 17:39:28 +01:00
$error = 0 ;
2022-10-14 11:28:49 +02:00
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php' ;
$langs -> load ( " agenda " );
// Loop on each product line to add a stock movement
$sql = " SELECT cd.fk_product, cd.subprice, " ;
$sql .= " ed.rowid, ed.qty, ed.fk_entrepot, " ;
$sql .= " e.ref, " ;
2023-04-10 13:59:19 +02:00
$sql .= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock, " ;
$sql .= " cd.rowid as cdid, ed.rowid as edid " ;
2022-10-14 11:28:49 +02:00
$sql .= " FROM " . MAIN_DB_PREFIX . " commandedet as cd, " ;
$sql .= " " . MAIN_DB_PREFIX . " expeditiondet as ed " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " expeditiondet_batch as edb on edb.fk_expeditiondet = ed.rowid " ;
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . " expedition as e ON ed.fk_expedition = e.rowid " ;
$sql .= " WHERE ed.fk_expedition = " . (( int ) $this -> id );
2024-04-08 12:44:49 +02:00
$sql .= " AND cd.rowid = ed.fk_elementdet " ;
2022-10-14 11:28:49 +02:00
dol_syslog ( get_class ( $this ) . " ::valid select details " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
$cpt = $this -> db -> num_rows ( $resql );
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
$obj = $this -> db -> fetch_object ( $resql );
if ( empty ( $obj -> edbrowid )) {
$qty = $obj -> qty ;
} else {
$qty = $obj -> edbqty ;
}
2022-11-23 08:26:12 +01:00
if ( $qty <= 0 || ( $qty < 0 && ! getDolGlobalInt ( 'SHIPMENT_ALLOW_NEGATIVE_QTY' ))) {
2022-10-14 11:28:49 +02:00
continue ;
}
dol_syslog ( get_class ( $this ) . " ::valid movement index " . $i . " ed.rowid= " . $obj -> rowid . " edb.rowid= " . $obj -> edbrowid );
$mouvS = new MouvementStock ( $this -> db );
$mouvS -> origin = & $this ;
$mouvS -> setOrigin ( $this -> element , $this -> id , $obj -> cdid , $obj -> edid );
if ( empty ( $obj -> edbrowid )) {
// line without batch detail
// We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record
2023-09-13 01:39:57 +02:00
$result = $mouvS -> livraison ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> subprice , $langs -> trans ( $labelmovement , $obj -> ref ));
2022-10-14 11:28:49 +02:00
if ( $result < 0 ) {
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
$error ++ ;
break ;
}
} else {
// line with batch detail
// We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record
2023-09-13 01:39:57 +02:00
$result = $mouvS -> livraison ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> subprice , $langs -> trans ( $labelmovement , $obj -> ref ), '' , $this -> db -> jdate ( $obj -> eatby ), $this -> db -> jdate ( $obj -> sellby ), $obj -> batch , $obj -> fk_origin_stock );
2022-10-14 11:28:49 +02:00
if ( $result < 0 ) {
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
$error ++ ;
break ;
}
}
// If some stock lines are now 0, we can remove entry into llx_product_stock, but only if there is no child lines into llx_product_batch (detail of batch, because we can imagine
// having a lot1/qty=X and lot2/qty=-X, so 0 but we must not loose repartition of different lot.
2023-04-10 13:59:19 +02:00
$sqldelete = " DELETE FROM " . MAIN_DB_PREFIX . " product_stock WHERE reel = 0 AND rowid NOT IN (SELECT fk_product_stock FROM " . MAIN_DB_PREFIX . " product_batch as pb) " ;
$resqldelete = $this -> db -> query ( $sqldelete );
2022-10-14 11:28:49 +02:00
// We do not test error, it can fails if there is child in batch details
}
} else {
$this -> error = $this -> db -> lasterror ();
$this -> errors [] = $this -> db -> lasterror ();
2024-03-11 17:39:28 +01:00
$error ++ ;
2022-10-14 11:28:49 +02:00
}
2024-11-12 14:25:36 +01:00
if ( ! $error ) {
return 1 ;
} else {
return - 1 ;
}
2022-10-14 11:28:49 +02:00
}
2021-02-09 13:10:11 +01:00
/**
2024-01-13 19:48:41 +01:00
* Classify the shipping as invoiced ( used for example by trigger when WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE is on )
2021-02-09 13:10:11 +01:00
*
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if ko , > 0 if ok
2021-02-09 13:10:11 +01:00
*/
public function setBilled ()
{
2017-10-07 13:09:31 +02:00
global $user ;
2019-11-13 19:37:08 +01:00
$error = 0 ;
2016-09-07 12:41:32 +02:00
2016-05-23 09:16:47 +02:00
$this -> db -> begin ();
2016-04-26 13:27:32 +02:00
2023-09-03 21:38:11 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'expedition SET billed = 1' ;
2021-08-27 23:36:06 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . ' AND fk_statut > 0' ;
2016-04-26 13:27:32 +02:00
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
2019-11-13 19:37:08 +01:00
$this -> billed = 1 ;
2016-09-07 12:41:32 +02:00
2016-05-20 20:03:29 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'SHIPPING_BILLED' , $user );
2016-09-07 12:41:32 +02:00
if ( $result < 0 ) {
2023-09-03 21:38:11 +02:00
$this -> billed = 0 ;
2016-05-23 09:16:47 +02:00
$error ++ ;
2016-05-20 20:03:29 +02:00
}
2016-05-23 09:16:47 +02:00
} else {
$error ++ ;
2019-11-13 19:37:08 +01:00
$this -> errors [] = $this -> db -> lasterror ;
2016-05-23 09:16:47 +02:00
}
2016-09-07 12:41:32 +02:00
2016-05-23 09:16:47 +02:00
if ( empty ( $error )) {
$this -> db -> commit ();
2012-07-02 19:30:37 +02:00
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2016-05-23 09:16:47 +02:00
$this -> db -> rollback ();
2012-07-02 19:30:37 +02:00
return - 1 ;
}
}
2012-03-14 14:00:20 +01:00
2023-04-10 15:55:58 +02:00
/**
* Set draft status
*
* @ param User $user Object user that modify
* @ 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
2023-04-10 15:55:58 +02:00
*/
public function setDraft ( $user , $notrigger = 0 )
{
// Protection
if ( $this -> statut <= self :: STATUS_DRAFT ) {
return 0 ;
}
return $this -> setStatusCommon ( $user , self :: STATUS_DRAFT , $notrigger , 'SHIPMENT_UNVALIDATE' );
}
2016-02-24 13:19:25 +01:00
/**
* Classify the shipping as validated / opened
*
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , 0 if already open , > 0 if OK
2016-02-24 13:19:25 +01:00
*/
2019-02-24 23:32:09 +01:00
public function reOpen ()
2016-02-24 13:19:25 +01:00
{
2024-03-24 06:23:56 +01:00
global $langs , $user ;
2016-02-24 13:19:25 +01:00
2019-11-13 19:37:08 +01:00
$error = 0 ;
2016-09-07 12:41:32 +02:00
2018-02-15 15:27:06 +01:00
// Protection. This avoid to move stock later when we should not
2021-02-25 22:38:35 +01:00
if ( $this -> statut == self :: STATUS_VALIDATED ) {
2018-02-15 15:27:06 +01:00
return 0 ;
}
2016-05-23 09:16:47 +02:00
$this -> db -> begin ();
2016-09-07 12:41:32 +02:00
2019-11-13 19:37:08 +01:00
$oldbilled = $this -> billed ;
2019-02-05 11:58:49 +01:00
2023-04-10 15:55:58 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'expedition SET fk_statut = 1' ;
2021-08-27 23:36:06 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . ' AND fk_statut > 0' ;
2016-02-24 13:19:25 +01:00
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
2019-11-13 19:37:08 +01:00
$this -> statut = self :: STATUS_VALIDATED ;
2024-03-24 06:23:56 +01:00
$this -> status = self :: STATUS_VALIDATED ;
2019-11-13 19:37:08 +01:00
$this -> billed = 0 ;
2016-09-07 12:41:32 +02:00
2016-05-14 19:22:27 +02:00
// If stock increment is done on closing
2023-11-27 11:41:05 +01:00
if ( ! $error && isModEnabled ( 'stock' ) && getDolGlobalString ( 'STOCK_CALCULATE_ON_SHIPMENT_CLOSE' )) {
2016-04-25 18:54:28 +02:00
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php' ;
2016-09-07 12:41:32 +02:00
2016-04-25 18:54:28 +02:00
$langs -> load ( " agenda " );
2016-09-07 12:41:32 +02:00
2016-04-25 18:54:28 +02:00
// Loop on each product line to add a stock movement
// TODO possibilite d'expedier a partir d'une propale ou autre origine
$sql = " SELECT cd.fk_product, cd.subprice, " ;
2019-11-13 19:37:08 +01:00
$sql .= " ed.rowid, ed.qty, ed.fk_entrepot, " ;
$sql .= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " commandedet as cd, " ;
$sql .= " " . MAIN_DB_PREFIX . " expeditiondet as ed " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " expeditiondet_batch as edb on edb.fk_expeditiondet = ed.rowid " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE ed.fk_expedition = " . (( int ) $this -> id );
2024-04-08 12:44:49 +02:00
$sql .= " AND cd.rowid = ed.fk_elementdet " ;
2016-09-07 12:41:32 +02:00
2016-04-25 18:54:28 +02:00
dol_syslog ( get_class ( $this ) . " ::valid select details " , LOG_DEBUG );
2019-11-13 19:37:08 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-25 22:38:35 +01:00
if ( $resql ) {
2016-04-25 18:54:28 +02:00
$cpt = $this -> db -> num_rows ( $resql );
2021-02-25 22:38:35 +01:00
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
2016-04-25 18:54:28 +02:00
$obj = $this -> db -> fetch_object ( $resql );
2021-02-25 22:38:35 +01:00
if ( empty ( $obj -> edbrowid )) {
2016-04-25 18:54:28 +02:00
$qty = $obj -> qty ;
2020-05-21 15:05:19 +02:00
} else {
2016-04-25 18:54:28 +02:00
$qty = $obj -> edbqty ;
}
2021-02-25 22:38:35 +01:00
if ( $qty <= 0 ) {
continue ;
}
2016-04-25 18:54:28 +02:00
dol_syslog ( get_class ( $this ) . " ::reopen expedition movement index " . $i . " ed.rowid= " . $obj -> rowid . " edb.rowid= " . $obj -> edbrowid );
2016-09-07 12:41:32 +02:00
2016-04-25 18:54:28 +02:00
//var_dump($this->lines[$i]);
$mouvS = new MouvementStock ( $this -> db );
$mouvS -> origin = & $this ;
2022-03-22 13:46:55 +01:00
$mouvS -> setOrigin ( $this -> element , $this -> id );
2016-09-07 12:41:32 +02:00
2021-02-25 22:38:35 +01:00
if ( empty ( $obj -> edbrowid )) {
2016-04-25 18:54:28 +02:00
// line without batch detail
2016-09-07 12:41:32 +02:00
2016-04-25 18:54:28 +02:00
// We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record
2023-04-10 14:27:39 +02:00
$result = $mouvS -> livraison ( $user , $obj -> fk_product , $obj -> fk_entrepot , - $qty , $obj -> subprice , $langs -> trans ( " ShipmentUnClassifyCloseddInDolibarr " , $this -> ref ));
2016-04-25 18:54:28 +02:00
if ( $result < 0 ) {
2017-10-07 13:09:31 +02:00
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
2022-06-02 10:15:04 +02:00
$error ++ ;
break ;
2016-04-25 18:54:28 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2016-04-25 18:54:28 +02:00
// line with batch detail
2016-09-07 12:41:32 +02:00
2016-04-25 18:54:28 +02:00
// We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record
2023-04-10 14:27:39 +02:00
$result = $mouvS -> livraison ( $user , $obj -> fk_product , $obj -> fk_entrepot , - $qty , $obj -> subprice , $langs -> trans ( " ShipmentUnClassifyCloseddInDolibarr " , $this -> ref ), '' , $this -> db -> jdate ( $obj -> eatby ), $this -> db -> jdate ( $obj -> sellby ), $obj -> batch , $obj -> fk_origin_stock );
2016-04-25 18:54:28 +02:00
if ( $result < 0 ) {
2017-10-07 13:09:31 +02:00
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
2022-06-02 10:15:04 +02:00
$error ++ ;
break ;
2016-04-25 18:54:28 +02:00
}
}
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> error = $this -> db -> lasterror ();
2016-06-02 11:23:49 +02:00
$error ++ ;
2016-04-25 18:54:28 +02:00
}
2016-05-20 20:03:29 +02:00
}
2016-09-07 12:41:32 +02:00
2020-10-28 17:49:52 +01:00
if ( ! $error ) {
2017-10-07 13:09:31 +02:00
// Call trigger
2019-11-13 19:37:08 +01:00
$result = $this -> call_trigger ( 'SHIPPING_REOPEN' , $user );
2017-10-07 13:09:31 +02:00
if ( $result < 0 ) {
$error ++ ;
}
2020-10-28 17:49:52 +01:00
}
2016-05-23 09:16:47 +02:00
} else {
$error ++ ;
2019-11-13 19:37:08 +01:00
$this -> errors [] = $this -> db -> lasterror ();
2016-05-23 09:16:47 +02:00
}
2016-09-07 12:41:32 +02:00
2021-02-25 22:38:35 +01:00
if ( ! $error ) {
2016-05-23 09:16:47 +02:00
$this -> db -> commit ();
2016-02-24 13:19:25 +01:00
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 19:37:08 +01:00
$this -> statut = self :: STATUS_CLOSED ;
2024-03-24 06:23:56 +01:00
$this -> status = self :: STATUS_CLOSED ;
2019-11-13 19:37:08 +01:00
$this -> billed = $oldbilled ;
2016-05-23 09:16:47 +02:00
$this -> db -> rollback ();
2016-02-24 13:19:25 +01:00
return - 1 ;
}
}
2016-09-07 12:41:32 +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
/**
2015-05-07 13:28:03 +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
*
2015-05-06 23:13:33 +02:00
* @ param string $modele Force the model to using ( '' to not force )
* @ param Translate $outputlangs object lang to use for translations
* @ param int $hidedetails Hide details of lines
* @ param int $hidedesc Hide description
* @ param int $hideref Hide ref
2024-10-03 19:40:34 +02:00
* @ param ? array < string , mixed > $moreparams Array to provide more information
2015-05-06 23:13:33 +02:00
* @ return int 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
{
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-03-12 12:45:44 +01:00
if ( ! dol_strlen ( $modele )) {
2017-01-16 21:16:05 +01:00
$modele = 'rouget' ;
2020-12-13 13:34:21 +01:00
if ( ! empty ( $this -> model_pdf )) {
$modele = $this -> model_pdf ;
2023-11-27 11:41:05 +01:00
} elseif ( getDolGlobalString ( 'EXPEDITION_ADDON_PDF' )) {
2024-01-05 04:18:53 +01:00
$modele = getDolGlobalString ( 'EXPEDITION_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/expedition/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
2014-09-22 00:07:10 +02:00
$this -> fetch_origin ();
2019-01-27 11:55:16 +01: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 (
'expedition'
);
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
}
2003-11-13 18:36:45 +01:00
}