2018-10-03 12:22:41 +02:00
< ? php
/* Copyright ( C ) 2003 - 2008 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
* Copyright ( C ) 2005 - 2012 Regis Houssin < regis . houssin @ capnetworks . com >
* Copyright ( C ) 2007 Franky Van Liedekerke < franky . van . liedekerke @ telenet . be >
* Copyright ( C ) 2006 - 2012 Laurent Destailleur < eldy @ users . sourceforge . net >
* Copyright ( C ) 2011 - 2017 Juanjo Menent < jmenent @ 2 byte . es >
* Copyright ( C ) 2013 Florian Henry < florian . henry @ open - concept . pro >
* Copyright ( C ) 2014 Cedric GROSS < c . gross @ kreiz - it . fr >
* Copyright ( C ) 2014 - 2015 Marcos García < marcosgdf @ gmail . com >
2020-11-05 14:30:30 +01:00
* Copyright ( C ) 2014 - 2020 Francis Appels < francis . appels @ yahoo . com >
2018-10-03 12:22:41 +02:00
* Copyright ( C ) 2015 Claudio Aschieri < c . aschieri @ 19. coop >
2022-03-22 13:46:55 +01:00
* Copyright ( C ) 2016 - 2022 Ferran Marcet < fmarcet @ 2 byte . es >
2018-10-10 17:30:44 +02:00
* Copyright ( C ) 2018 Quentin Vial - Gouteyron < quentin . vial - gouteyron @ atm - consulting . fr >
2018-10-03 12:22:41 +02: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
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2018-10-03 12:22:41 +02:00
*/
/**
* \file htdocs / reception / class / reception . class . php
* \ingroup reception
* \brief Fichier de la classe de gestion des receptions
*/
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php' ;
require_once DOL_DOCUMENT_ROOT . " /core/class/commonobjectline.class.php " ;
2020-09-16 02:50:18 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonincoterm.class.php' ;
2021-02-26 20:53:03 +01:00
if ( ! empty ( $conf -> propal -> enabled )) {
require_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php' ;
}
if ( ! empty ( $conf -> commande -> enabled )) {
require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php' ;
}
2018-10-03 12:22:41 +02:00
/**
* Class to manage receptions
*/
class Reception extends CommonObject
{
2020-09-16 02:50:18 +02:00
use CommonIncoterm ;
2020-12-05 23:53:55 +01:00
/**
* @ var string element name
*/
2019-11-13 18:32:11 +01:00
public $element = " reception " ;
2020-12-05 23:53:55 +01:00
/**
* @ var string Fieldname with ID of parent key if this field has a parent
*/
2019-11-13 18:32:11 +01:00
public $fk_element = " fk_reception " ;
public $table_element = " reception " ;
public $table_element_line = " commande_fournisseur_dispatch " ;
2020-03-22 11:45:40 +01:00
public $ismultientitymanaged = 1 ; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
2019-10-30 10:10:12 +01:00
2019-10-30 10:09:08 +01: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 = 'dollyrevert' ;
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
public $socid ;
public $ref_supplier ;
2020-03-06 14:38:06 +01:00
2020-10-28 17:49:52 +01:00
/**
* @ var int Ref int
* @ deprecated
*/
public $ref_int ;
public $brouillon ;
public $entrepot_id ;
public $tracking_number ;
public $tracking_url ;
public $billed ;
public $model_pdf ;
public $trueWeight ;
public $weight_units ;
public $trueWidth ;
public $width_units ;
public $trueHeight ;
public $height_units ;
public $trueDepth ;
public $depth_units ;
2018-10-03 12:22:41 +02:00
// A denormalized value
2020-10-28 17:49:52 +01:00
public $trueSize ;
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
public $date_delivery ; // Date delivery planed
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
/**
2019-11-10 12:14:39 +01:00
* @ var integer | string Effective delivery date
2018-10-03 12:22:41 +02:00
*/
public $date_reception ;
2019-11-02 10:39:05 +01:00
2019-11-02 10:35:43 +01:00
/**
* @ var integer | string date_creation
*/
public $date_creation ;
2019-11-02 10:39:05 +01:00
2019-11-10 12:14:39 +01:00
/**
* @ var integer | string date_validation
*/
2019-11-02 10:35:43 +01:00
public $date_valid ;
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
public $meths ;
public $listmeths ; // List of carriers
2018-10-03 12:22:41 +02:00
2020-11-28 14:47:39 +01:00
public $lines = array ();
2018-10-03 12:22:41 +02:00
const STATUS_DRAFT = 0 ;
const STATUS_VALIDATED = 1 ;
const STATUS_CLOSED = 2 ;
/**
* Constructor
*
* @ param DoliDB $db Database handler
*/
2020-10-28 17:49:52 +01:00
public function __construct ( $db )
2018-10-03 12:22:41 +02:00
{
$this -> db = $db ;
// List of long language codes for status
$this -> statuts = array ();
$this -> statuts [ - 1 ] = 'StatusReceptionCanceled' ;
$this -> statuts [ 0 ] = 'StatusReceptionDraft' ;
2021-11-19 13:46:30 +01:00
// product to receive if stock increase is on close or already received if stock increase is on validation
2018-10-03 12:22:41 +02:00
$this -> statuts [ 1 ] = 'StatusReceptionValidated' ;
2021-11-19 13:46:30 +01:00
if ( getDolGlobalInt ( " STOCK_CALCULATE_ON_RECEPTION " )) {
$this -> statuts [ 1 ] = 'StatusReceptionValidatedReceived' ;
}
if ( getDolGlobalInt ( " STOCK_CALCULATE_ON_RECEPTION_CLOSE " )) {
$this -> statuts [ 1 ] = 'StatusReceptionValidatedToReceive' ;
}
2018-10-03 12:22:41 +02:00
$this -> statuts [ 2 ] = 'StatusReceptionProcessed' ;
2019-11-04 19:28:04 +01:00
// List of short language codes for status
$this -> statutshorts = array ();
$this -> statutshorts [ - 1 ] = 'StatusReceptionCanceledShort' ;
$this -> statutshorts [ 0 ] = 'StatusReceptionDraftShort' ;
$this -> statutshorts [ 1 ] = 'StatusReceptionValidatedShort' ;
$this -> statutshorts [ 2 ] = 'StatusReceptionProcessedShort' ;
2018-10-03 12:22:41 +02:00
}
/**
* Return next contract ref
*
* @ param Societe $soc Thirdparty object
* @ return string Free reference for contract
*/
2020-10-28 17:49:52 +01:00
public function getNextNumRef ( $soc )
2018-10-03 12:22:41 +02:00
{
global $langs , $conf ;
$langs -> load ( " receptions " );
2021-02-26 20:53:03 +01:00
if ( ! empty ( $conf -> global -> RECEPTION_ADDON_NUMBER )) {
2018-10-03 12:22:41 +02:00
$mybool = false ;
$file = $conf -> global -> RECEPTION_ADDON_NUMBER . " .php " ;
$classname = $conf -> global -> RECEPTION_ADDON_NUMBER ;
2020-10-28 17:49:52 +01:00
// Include file with class
$dirmodels = array_merge ( array ( '/' ), ( array ) $conf -> modules_parts [ 'models' ]);
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
foreach ( $dirmodels as $reldir ) {
$dir = dol_buildpath ( $reldir . " core/modules/reception/ " );
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
// Load file with numbering class (if found)
$mybool |= @ include_once $dir . $file ;
}
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( ! $mybool ) {
2020-10-28 17:49:52 +01:00
dol_print_error ( '' , " Failed to include file " . $file );
return '' ;
}
2018-10-03 12:22:41 +02:00
$obj = new $classname ();
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
$numref = " " ;
2019-01-27 11:55:16 +01:00
$numref = $obj -> getNextValue ( $soc , $this );
2018-12-15 13:58:39 +01:00
2021-02-26 20:53:03 +01:00
if ( $numref != " " ) {
2018-10-03 12:22:41 +02: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 );
2018-10-03 12:22:41 +02:00
return " " ;
}
2020-10-28 17:49:52 +01:00
} else {
print $langs -> trans ( " Error " ) . " " . $langs -> trans ( " Error_RECEPTION_ADDON_NUMBER_NotDefined " );
return " " ;
}
2018-10-03 12:22:41 +02:00
}
/**
* Create reception en base
*
* @ param User $user Objet du user qui cree
2018-10-17 11:56:32 +02:00
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2018-10-03 12:22:41 +02:00
* @ return int < 0 si erreur , id reception creee si ok
*/
2020-10-28 17:49:52 +01:00
public function create ( $user , $notrigger = 0 )
2018-10-03 12:22:41 +02:00
{
global $conf , $hookmanager ;
2019-11-13 18:32:11 +01:00
$now = dol_now ();
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php' ;
2018-10-03 12:22:41 +02:00
$error = 0 ;
// Clean parameters
$this -> brouillon = 1 ;
$this -> tracking_number = dol_sanitizeFileName ( $this -> tracking_number );
2021-02-26 20:53:03 +01:00
if ( empty ( $this -> fk_project )) {
$this -> fk_project = 0 ;
}
if ( empty ( $this -> weight_units )) {
$this -> weight_units = 0 ;
}
if ( empty ( $this -> size_units )) {
$this -> size_units = 0 ;
}
2018-10-03 12:22:41 +02:00
$this -> user = $user ;
$this -> db -> begin ();
$sql = " INSERT INTO " . MAIN_DB_PREFIX . " reception ( " ;
2019-11-13 18:32:11 +01:00
$sql .= " ref " ;
$sql .= " , entity " ;
$sql .= " , ref_supplier " ;
$sql .= " , date_creation " ;
$sql .= " , fk_user_author " ;
$sql .= " , date_reception " ;
$sql .= " , date_delivery " ;
$sql .= " , fk_soc " ;
$sql .= " , fk_projet " ;
$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 " ;
$sql .= " ) VALUES ( " ;
$sql .= " '(PROV)' " ;
2021-09-03 21:25:17 +02:00
$sql .= " , " . (( int ) $conf -> entity );
2019-11-13 18:32:11 +01:00
$sql .= " , " . ( $this -> ref_supplier ? " ' " . $this -> db -> escape ( $this -> ref_supplier ) . " ' " : " null " );
$sql .= " , ' " . $this -> db -> idate ( $now ) . " ' " ;
2021-09-03 21:25:17 +02:00
$sql .= " , " . (( int ) $user -> id );
2019-11-13 18:32:11 +01:00
$sql .= " , " . ( $this -> date_reception > 0 ? " ' " . $this -> db -> idate ( $this -> date_reception ) . " ' " : " null " );
$sql .= " , " . ( $this -> date_delivery > 0 ? " ' " . $this -> db -> idate ( $this -> date_delivery ) . " ' " : " null " );
2021-09-03 21:25:17 +02:00
$sql .= " , " . (( int ) $this -> socid );
$sql .= " , " . (( int ) $this -> fk_project );
$sql .= " , " . ( $this -> shipping_method_id > 0 ? (( int ) $this -> shipping_method_id ) : " null " );
2019-11-13 18:32:11 +01:00
$sql .= " , ' " . $this -> db -> escape ( $this -> tracking_number ) . " ' " ;
2022-03-17 18:53:50 +01:00
$sql .= " , " . ( is_null ( $this -> weight ) ? " NULL " : (( double ) $this -> weight ));
2022-05-22 01:19:00 +02:00
$sql .= " , " . ( is_null ( $this -> trueDepth ) ? " NULL " : (( double ) $this -> trueDepth ));
$sql .= " , " . ( is_null ( $this -> trueWidth ) ? " NULL " : (( double ) $this -> trueWidth ));
$sql .= " , " . ( is_null ( $this -> trueHeight ) ? " NULL " : (( double ) $this -> trueHeight ));
2022-03-17 18:53:50 +01:00
$sql .= " , " . ( is_null ( $this -> weight_units ) ? " NULL " : (( double ) $this -> weight_units ));
$sql .= " , " . ( is_null ( $this -> size_units ) ? " NULL " : (( double ) $this -> size_units ));
2019-11-13 18:32:11 +01:00
$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 " );
2020-10-28 17:49:52 +01:00
$sql .= " , " . ( int ) $this -> fk_incoterms ;
$sql .= " , ' " . $this -> db -> escape ( $this -> location_incoterms ) . " ' " ;
2019-11-13 18:32:11 +01:00
$sql .= " ) " ;
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::create " , LOG_DEBUG );
2018-12-15 13:58:39 +01:00
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2018-12-15 13:58:39 +01:00
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2018-10-03 12:22:41 +02:00
$this -> id = $this -> db -> last_insert_id ( MAIN_DB_PREFIX . " reception " );
$sql = " UPDATE " . MAIN_DB_PREFIX . " reception " ;
2019-11-13 18:32:11 +01:00
$sql .= " SET ref = '(PROV " . $this -> id . " )' " ;
2021-08-27 16:33:03 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::create " , LOG_DEBUG );
2021-02-26 20:53:03 +01:00
if ( $this -> db -> query ( $sql )) {
2019-06-29 16:29:32 +02:00
// Insert of lines
2019-11-13 18:32:11 +01:00
$num = count ( $this -> lines );
2021-02-26 20:53:03 +01:00
for ( $i = 0 ; $i < $num ; $i ++ ) {
2018-10-17 15:36:47 +02:00
$this -> lines [ $i ] -> fk_reception = $this -> id ;
2018-12-15 13:58:39 +01:00
2021-02-26 20:53:03 +01:00
if ( ! $this -> lines [ $i ] -> create ( $user ) > 0 ) {
2018-10-17 15:36:47 +02:00
$error ++ ;
2018-10-03 12:22:41 +02:00
}
}
2021-02-26 20:53:03 +01:00
if ( ! $error && $this -> id && $this -> origin_id ) {
2018-10-03 12:22:41 +02:00
$ret = $this -> add_object_linked ();
2021-02-26 20:53:03 +01:00
if ( ! $ret ) {
2018-10-03 12:22:41 +02:00
$error ++ ;
}
}
2020-04-23 12:54:28 +02:00
// Create extrafields
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2020-04-25 13:52:07 +02:00
$result = $this -> insertExtraFields ();
2021-02-26 20:53:03 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-10-03 12:22:41 +02:00
}
2021-02-26 20:53:03 +01:00
if ( ! $error && ! $notrigger ) {
2020-10-28 17:49:52 +01:00
// Call trigger
$result = $this -> call_trigger ( 'RECEPTION_CREATE' , $user );
2021-02-26 20:53:03 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2020-10-28 17:49:52 +01:00
// End call triggers
2020-04-23 12:54:28 +02:00
}
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2020-04-23 12:54:28 +02:00
$this -> db -> commit ();
return $this -> id ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-26 20:53:03 +01:00
foreach ( $this -> errors as $errmsg ) {
2020-04-23 12:54:28 +02:00
dol_syslog ( get_class ( $this ) . " ::create " . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
2020-04-23 12:54:28 +02:00
return - 1 * $error ;
2018-10-03 12:22:41 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$error ++ ;
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
return - 2 ;
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$error ++ ;
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> error () . " - sql= $sql " ;
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
/**
* Get object and lines from database
*
* @ param int $id Id of object to load
* @ param string $ref Ref of object
* @ param string $ref_ext External reference of object
2020-10-28 17:49:52 +01:00
* @ param string $notused Internal reference of other object
2018-10-03 12:22:41 +02:00
* @ return int > 0 if OK , 0 if not found , < 0 if KO
*/
2020-10-28 17:49:52 +01:00
public function fetch ( $id , $ref = '' , $ref_ext = '' , $notused = '' )
2018-10-03 12:22:41 +02:00
{
global $conf ;
// Check parameters
2021-02-26 20:53:03 +01:00
if ( empty ( $id ) && empty ( $ref ) && empty ( $ref_ext )) {
return - 1 ;
}
2018-10-03 12:22:41 +02:00
2020-11-05 14:30:30 +01:00
$sql = " SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_supplier, e.ref_ext, e.fk_user_author, e.fk_statut " ;
2019-11-13 18:32:11 +01:00
$sql .= " , e.weight, e.weight_units, e.size, e.size_units, e.width, e.height " ;
$sql .= " , e.date_reception as date_reception, e.model_pdf, e.date_delivery " ;
$sql .= " , e.fk_shipping_method, e.tracking_number " ;
$sql .= " , el.fk_source as origin_id, el.sourcetype as origin " ;
$sql .= " , e.note_private, e.note_public " ;
2020-10-28 17:49:52 +01:00
$sql .= ', e.fk_incoterms, e.location_incoterms' ;
$sql .= ', i.libelle as label_incoterms' ;
2019-11-13 18:32:11 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " reception 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 .= " WHERE e.entity IN ( " . getEntity ( 'reception' ) . " ) " ;
2021-02-26 20:53:03 +01:00
if ( $id ) {
2021-04-24 20:18:11 +02:00
$sql .= " AND e.rowid= " . (( int ) $id );
2021-02-26 20:53:03 +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 ) . " ' " ;
}
if ( $notused ) {
$sql .= " AND e.ref_int=' " . $this -> db -> escape ( $notused ) . " ' " ;
}
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::fetch " , LOG_DEBUG );
$result = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $result ) {
if ( $this -> db -> num_rows ( $result )) {
2018-10-03 12:22:41 +02:00
$obj = $this -> db -> fetch_object ( $result );
$this -> id = $obj -> rowid ;
$this -> ref = $obj -> ref ;
$this -> socid = $obj -> socid ;
2019-11-13 18:32:11 +01:00
$this -> ref_supplier = $obj -> ref_supplier ;
2020-12-01 02:41:19 +01:00
$this -> ref_ext = $obj -> ref_ext ;
2018-10-03 12:22:41 +02:00
$this -> statut = $obj -> fk_statut ;
$this -> user_author_id = $obj -> fk_user_author ;
$this -> date_creation = $this -> db -> jdate ( $obj -> date_creation );
2019-11-13 18:32:11 +01:00
$this -> date = $this -> db -> jdate ( $obj -> date_reception ); // TODO deprecated
$this -> date_reception = $this -> db -> jdate ( $obj -> date_reception ); // TODO deprecated
$this -> date_reception = $this -> db -> jdate ( $obj -> date_reception ); // Date real
$this -> date_delivery = $this -> db -> jdate ( $obj -> date_delivery ); // Date planed
2020-08-18 14:48:38 +02:00
$this -> model_pdf = $obj -> model_pdf ;
2020-10-31 14:32:18 +01:00
$this -> modelpdf = $obj -> model_pdf ; // deprecated
2019-11-13 18:32:11 +01:00
$this -> shipping_method_id = $obj -> fk_shipping_method ;
2018-10-03 12:22:41 +02:00
$this -> tracking_number = $obj -> tracking_number ;
2019-11-13 18:32:11 +01:00
$this -> origin = ( $obj -> origin ? $obj -> origin : 'commande' ); // For compatibility
2018-10-03 12:22:41 +02:00
$this -> origin_id = $obj -> origin_id ;
2019-11-13 18:32:11 +01:00
$this -> billed = ( $obj -> fk_statut == 2 ? 1 : 0 );
2018-10-03 12:22:41 +02: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 ;
$this -> note_public = $obj -> note_public ;
$this -> note_private = $obj -> note_private ;
// A denormalized value
2019-11-13 18:32:11 +01:00
$this -> trueSize = $obj -> size . " x " . $obj -> width . " x " . $obj -> height ;
$this -> size_units = $obj -> size_units ;
2018-10-03 12:22:41 +02:00
//Incoterms
$this -> fk_incoterms = $obj -> fk_incoterms ;
$this -> location_incoterms = $obj -> location_incoterms ;
2019-06-25 13:00:02 +02:00
$this -> label_incoterms = $obj -> label_incoterms ;
2018-10-03 12:22:41 +02:00
$this -> db -> free ( $result );
2021-02-26 20:53:03 +01:00
if ( $this -> statut == 0 ) {
$this -> brouillon = 1 ;
}
2018-10-03 12:22:41 +02:00
2022-09-21 01:13:53 +02:00
//$file = $conf->reception->dir_output."/".get_exdir(0, 0, 0, 1, $this, 'reception')."/".$this->id.".pdf";
//$this->pdf_filename = $file;
2018-10-03 12:22:41 +02:00
// Tracking url
2018-12-15 18:30:35 +01:00
$this -> getUrlTrackingStatus ( $obj -> tracking_number );
2018-10-03 12:22:41 +02:00
/*
2019-01-17 15:57:17 +01:00
* Thirdparty
2018-10-03 12:22:41 +02:00
*/
2019-11-13 18:32:11 +01:00
$result = $this -> fetch_thirdparty ();
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
// Retrieve all extrafields for reception
// fetch optionals attributes and labels
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php' ;
2019-11-13 18:32:11 +01:00
$extrafields = new ExtraFields ( $this -> db );
2019-10-06 14:41:52 +02:00
$extrafields -> fetch_name_optionals_label ( $this -> table_element , true );
2020-03-27 16:02:58 +01:00
$this -> fetch_optionals ();
2018-10-03 12:22:41 +02:00
/*
* Lines
*/
2019-11-13 18:32:11 +01:00
$result = $this -> fetch_lines ();
2021-02-26 20:53:03 +01:00
if ( $result < 0 ) {
2018-10-03 12:22:41 +02:00
return - 3 ;
}
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . '::Fetch no reception found' , LOG_ERR );
2019-11-13 18:32:11 +01:00
$this -> error = 'Delivery with id ' . $id . ' not found' ;
2018-10-03 12:22:41 +02:00
return 0 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> error ();
2018-10-03 12:22:41 +02:00
return - 1 ;
}
}
/**
* Validate object and update stock if option enabled
*
* @ param User $user Object user that validate
2020-10-28 17:49:52 +01:00
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2018-10-03 12:22:41 +02:00
* @ return int < 0 if OK , > 0 if KO
*/
2020-10-28 17:49:52 +01:00
public function valid ( $user , $notrigger = 0 )
2018-10-03 12:22:41 +02:00
{
global $conf , $langs ;
2020-10-28 17:49:52 +01:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid " );
// Protection
2021-02-26 20:53:03 +01:00
if ( $this -> statut ) {
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid no draft status " , LOG_WARNING );
return 0 ;
}
2020-10-28 17:49:52 +01:00
if ( ! (( empty ( $conf -> global -> MAIN_USE_ADVANCED_PERMS ) && ! empty ( $user -> rights -> reception -> creer ))
2021-02-26 20:53:03 +01:00
|| ( ! empty ( $conf -> global -> MAIN_USE_ADVANCED_PERMS ) && ! empty ( $user -> rights -> reception -> reception_advance -> validate )))) {
2019-11-13 18:32:11 +01:00
$this -> error = 'Permission denied' ;
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid " . $this -> error , LOG_ERR );
return - 1 ;
}
$this -> db -> begin ();
$error = 0 ;
// Define new ref
$soc = new Societe ( $this -> db );
$soc -> fetch ( $this -> socid );
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
// Define new ref
2021-02-26 20:53:03 +01:00
if ( ! $error && ( preg_match ( '/^[\(]?PROV/i' , $this -> ref ) || empty ( $this -> ref ))) { // empty should not happened, but when it occurs, the test save life
2018-10-03 12:22:41 +02:00
$numref = $this -> getNextNumRef ( $soc );
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$numref = $this -> ref ;
}
2018-12-15 13:58:39 +01:00
2020-10-28 17:49:52 +01:00
$this -> newref = dol_sanitizeFileName ( $numref );
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
$now = dol_now ();
2018-10-03 12:22:41 +02:00
// Validate
$sql = " UPDATE " . MAIN_DB_PREFIX . " reception SET " ;
2019-11-13 18:32:11 +01:00
$sql .= " ref=' " . $this -> db -> escape ( $numref ) . " ' " ;
$sql .= " , fk_statut = 1 " ;
$sql .= " , date_valid = ' " . $this -> db -> idate ( $now ) . " ' " ;
$sql .= " , fk_user_valid = " . $user -> id ;
2021-08-27 16:33:03 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid update reception " , LOG_DEBUG );
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( ! $resql ) {
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> lasterror ();
2018-10-03 12:22:41 +02:00
$error ++ ;
}
// If stock increment is done on reception (recommanded choice)
2021-02-26 20:53:03 +01:00
if ( ! $error && ! empty ( $conf -> stock -> enabled ) && ! empty ( $conf -> global -> STOCK_CALCULATE_ON_RECEPTION )) {
2018-10-03 12:22:41 +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
// TODO in future, reception lines may not be linked to order line
2022-03-22 11:17:27 +01:00
$sql = " SELECT cd.fk_product, cd.subprice, cd.remise_percent, " ;
2019-11-13 18:32:11 +01:00
$sql .= " ed.rowid, ed.qty, ed.fk_entrepot, " ;
2021-09-28 13:22:44 +02:00
$sql .= " ed.eatby, ed.sellby, ed.batch, " ;
$sql .= " ed.cost_price " ;
2019-11-13 18:32:11 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " commande_fournisseurdet as cd, " ;
$sql .= " " . MAIN_DB_PREFIX . " commande_fournisseur_dispatch as ed " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE ed.fk_reception = " . (( int ) $this -> id );
2019-11-13 18:32:11 +01:00
$sql .= " AND cd.rowid = ed.fk_commandefourndet " ;
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid select details " , LOG_DEBUG );
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2018-10-03 12:22:41 +02:00
$cpt = $this -> db -> num_rows ( $resql );
2021-02-26 20:53:03 +01:00
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
2018-10-03 12:22:41 +02:00
$obj = $this -> db -> fetch_object ( $resql );
2018-12-15 13:58:39 +01:00
2018-10-09 11:33:41 +02:00
$qty = $obj -> qty ;
2018-12-15 13:58:39 +01:00
2022-11-05 15:39:31 +01:00
if ( $qty == 0 || ( $qty < 0 && ! getDolGlobalInt ( 'RECEPTION_ALLOW_NEGATIVE_QTY' ))) {
2021-02-26 20:53:03 +01:00
continue ;
}
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid movement index " . $i . " ed.rowid= " . $obj -> rowid . " edb.rowid= " . $obj -> edbrowid );
//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 );
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( empty ( $obj -> batch )) {
2018-10-03 12:22:41 +02:00
// 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.
2021-11-19 13:46:30 +01:00
$inventorycode = '' ;
2022-06-08 18:27:47 +02:00
$result = $mouvS -> reception ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> cost_price , $langs -> trans ( " ReceptionValidatedInDolibarr " , $numref ), '' , '' , '' , '' , 0 , $inventorycode );
2022-03-23 17:04:31 +01:00
2022-06-23 11:55:20 +02:00
if ( intval ( $result ) < 0 ) {
2018-10-03 12:22:41 +02:00
$error ++ ;
2019-11-13 18:32:11 +01:00
$this -> errors [] = $mouvS -> error ;
2018-10-03 12:22:41 +02:00
$this -> errors = array_merge ( $this -> errors , $mouvS -> errors );
break ;
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
// 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.
2020-10-28 17:49:52 +01:00
// Note: ->fk_origin_stock = id into table llx_product_batch (may be rename into llx_product_stock_batch in another version)
2021-11-19 13:46:30 +01:00
$inventorycode = '' ;
2022-06-08 18:27:47 +02:00
$result = $mouvS -> reception ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> cost_price , $langs -> trans ( " ReceptionValidatedInDolibarr " , $numref ), $this -> db -> jdate ( $obj -> eatby ), $this -> db -> jdate ( $obj -> sellby ), $obj -> batch , '' , 0 , $inventorycode );
2022-03-23 17:04:31 +01:00
2022-06-23 11:55:20 +02:00
if ( intval ( $result ) < 0 ) {
2018-10-03 12:22:41 +02:00
$error ++ ;
2019-11-13 18:32:11 +01:00
$this -> errors [] = $mouvS -> error ;
2018-10-03 12:22:41 +02:00
$this -> errors = array_merge ( $this -> errors , $mouvS -> errors );
break ;
}
}
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> error ();
2018-10-03 12:22:41 +02:00
return - 2 ;
}
}
2018-12-15 13:58:39 +01:00
2022-02-14 18:07:18 +01:00
// Change status of order to "reception in process" or "totally received"
$status = $this -> getStatusDispatch ();
if ( $status < 0 ) {
2020-10-28 17:49:52 +01:00
$error ++ ;
2022-02-14 18:07:18 +01:00
} else {
2022-02-15 09:54:40 +01:00
$trigger_key = '' ;
if ( $status == CommandeFournisseur :: STATUS_RECEIVED_COMPLETELY ) {
$ret = $this -> commandeFournisseur -> Livraison ( $user , dol_now (), 'tot' , '' );
if ( $ret < 0 ) {
$error ++ ;
$this -> errors = array_merge ( $this -> errors , $this -> commandeFournisseur -> errors );
}
} else {
$ret = $this -> setStatut ( $status , $this -> origin_id , 'commande_fournisseur' , $trigger_key );
if ( $ret < 0 ) {
$error ++ ;
}
2022-02-14 18:07:18 +01:00
}
2018-10-03 12:22:41 +02:00
}
2021-02-26 20:53:03 +01:00
if ( ! $error && ! $notrigger ) {
2020-10-28 17:49:52 +01:00
// Call trigger
$result = $this -> call_trigger ( 'RECEPTION_VALIDATE' , $user );
2021-02-26 20:53:03 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2020-10-28 17:49:52 +01:00
// End call triggers
2018-10-03 12:22:41 +02:00
}
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2020-10-28 17:49:52 +01:00
$this -> oldref = $this -> ref ;
2018-10-03 12:22:41 +02:00
// Rename directory if dir was a temporary ref
2021-02-26 20:53:03 +01:00
if ( preg_match ( '/^[\(]?PROV/i' , $this -> ref )) {
2019-07-28 22:26:55 +02:00
// Now we rename also files into index
2019-11-13 18:32:11 +01:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . " ecm_files set filename = CONCAT(' " . $this -> db -> escape ( $this -> newref ) . " ', SUBSTR(filename, " . ( strlen ( $this -> ref ) + 1 ) . " )), filepath = 'reception/ " . $this -> db -> escape ( $this -> newref ) . " ' " ;
2022-01-03 18:15:19 +01:00
$sql .= " WHERE filename LIKE ' " . $this -> db -> escape ( $this -> ref ) . " %' AND filepath = 'reception/ " . $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-26 20:53:03 +01:00
if ( ! $resql ) {
$error ++ ; $this -> error = $this -> db -> lasterror ();
}
2019-07-28 22:26:55 +02:00
// We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
2018-10-03 12:22:41 +02:00
$oldref = dol_sanitizeFileName ( $this -> ref );
$newref = dol_sanitizeFileName ( $numref );
2018-10-09 11:33:41 +02:00
$dirsource = $conf -> reception -> dir_output . '/' . $oldref ;
$dirdest = $conf -> reception -> dir_output . '/' . $newref ;
2021-02-26 20:53:03 +01:00
if ( ! $error && file_exists ( $dirsource )) {
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid rename dir " . $dirsource . " into " . $dirdest );
2021-02-26 20:53:03 +01:00
if ( @ rename ( $dirsource , $dirdest )) {
2020-10-28 17:49:52 +01:00
dol_syslog ( " Rename ok " );
// Rename docs starting with $oldref with $newref
$listoffiles = dol_dir_list ( $conf -> reception -> dir_output . '/' . $newref , 'files' , 1 , '^' . preg_quote ( $oldref , '/' ));
2021-02-26 20:53:03 +01:00
foreach ( $listoffiles as $fileentry ) {
2020-10-28 17:49:52 +01:00
$dirsource = $fileentry [ 'name' ];
$dirdest = preg_replace ( '/^' . preg_quote ( $oldref , '/' ) . '/' , $newref , $dirsource );
$dirsource = $fileentry [ 'path' ] . '/' . $dirsource ;
$dirdest = $fileentry [ 'path' ] . '/' . $dirdest ;
@ rename ( $dirsource , $dirdest );
}
2018-10-03 12:22:41 +02:00
}
}
}
}
// Set new ref and current status
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2018-10-03 12:22:41 +02:00
$this -> ref = $numref ;
$this -> statut = 1 ;
}
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2018-10-03 12:22:41 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-26 20:53:03 +01:00
foreach ( $this -> errors as $errmsg ) {
2020-10-28 17:49:52 +01:00
dol_syslog ( get_class ( $this ) . " ::valid " . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-10-03 12:22:41 +02:00
}
$this -> db -> rollback ();
2019-11-13 18:32:11 +01:00
return - 1 * $error ;
2018-10-03 12:22:41 +02:00
}
}
2022-02-14 18:07:18 +01:00
/**
* Get status from all dispatched lines
*
2022-02-16 20:50:27 +01:00
* @ return int < 0 if KO , Status of reception if OK
2022-02-14 18:07:18 +01:00
*/
public function getStatusDispatch ()
{
global $conf ;
require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.commande.class.php' ;
require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.commande.dispatch.class.php' ;
$status = CommandeFournisseur :: STATUS_RECEIVED_PARTIALLY ;
if ( ! empty ( $this -> origin ) && $this -> origin_id > 0 && ( $this -> origin == 'order_supplier' || $this -> origin == 'commandeFournisseur' )) {
if ( empty ( $this -> commandeFournisseur )) {
$this -> fetch_origin ();
if ( empty ( $this -> commandeFournisseur -> lines )) {
$res = $this -> commandeFournisseur -> fetch_lines ();
if ( $res < 0 ) return $res ;
}
}
$qty_received = array ();
$qty_wished = array ();
$supplierorderdispatch = new CommandeFournisseurDispatch ( $this -> db );
$filter = array ( 't.fk_commande' => $this -> origin_id );
if ( ! empty ( $conf -> global -> SUPPLIER_ORDER_USE_DISPATCH_STATUS )) {
$filter [ 't.status' ] = 1 ; // Restrict to lines with status validated
}
$ret = $supplierorderdispatch -> fetchAll ( '' , '' , 0 , 0 , $filter );
if ( $ret < 0 ) {
$this -> error = $supplierorderdispatch -> error ;
$this -> errors = $supplierorderdispatch -> errors ;
return $ret ;
} else {
// build array with quantity received by product in all supplier orders (origin)
foreach ( $supplierorderdispatch -> lines as $dispatch_line ) {
$qty_received [ $dispatch_line -> fk_product ] += $dispatch_line -> qty ;
}
2018-10-03 12:22:41 +02:00
2022-02-14 18:07:18 +01:00
// qty wished in order supplier (origin)
foreach ( $this -> commandeFournisseur -> lines as $origin_line ) {
// exclude lines not qualified for reception
if ( empty ( $conf -> global -> STOCK_SUPPORTS_SERVICES ) && $origin_line -> product_type > 0 ) {
continue ;
}
$qty_wished [ $origin_line -> fk_product ] += $origin_line -> qty ;
}
// compare array
$diff_array = array_diff_assoc ( $qty_received , $qty_wished ); // Warning: $diff_array is done only on common keys.
$keys_in_wished_not_in_received = array_diff ( array_keys ( $qty_wished ), array_keys ( $qty_received ));
$keys_in_received_not_in_wished = array_diff ( array_keys ( $qty_received ), array_keys ( $qty_wished ));
if ( count ( $diff_array ) == 0 && count ( $keys_in_wished_not_in_received ) == 0 && count ( $keys_in_received_not_in_wished ) == 0 ) { // no diff => mean everything is received
$status = CommandeFournisseur :: STATUS_RECEIVED_COMPLETELY ;
} elseif ( ! empty ( $conf -> global -> SUPPLIER_ORDER_MORE_THAN_WISHED )) {
// set totally received if more products received than ordered
$close = 0 ;
if ( count ( $diff_array ) > 0 ) {
// there are some difference between the two arrays
// scan the array of results
foreach ( $diff_array as $key => $value ) {
// if the quantity delivered is greater or equal to ordered quantity
if ( $qty_received [ $key ] >= $qty_wished [ $key ]) {
$close ++ ;
}
}
}
if ( $close == count ( $diff_array )) {
// all the products are received equal or more than the ordered quantity
$status = CommandeFournisseur :: STATUS_RECEIVED_COMPLETELY ;
}
}
}
}
return $status ;
}
2018-10-03 12:22:41 +02:00
/**
* Add an reception line .
* If STOCK_WAREHOUSE_NOT_REQUIRED_FOR_RECEPTIONS is set , you can add a reception line , with no stock source defined
* If STOCK_MUST_BE_ENOUGH_FOR_RECEPTION is not set , you can add a reception line , even if not enough into stock
*
2018-10-04 17:32:50 +02:00
* @ param int $entrepot_id Id of warehouse
* @ param int $id Id of source line ( supplier order line )
* @ param int $qty Quantity
* @ param array $array_options extrafields array
* @ param string $comment Comment for stock movement
2019-04-04 18:33:12 +02:00
* @ param integer $eatby eat - by date
* @ param integer $sellby sell - by date
2018-10-04 17:32:50 +02:00
* @ param string $batch Lot number
2021-09-22 14:56:44 +02:00
* @ param double $cost_price Line cost
2020-11-04 17:44:02 +01:00
* @ return int < 0 if KO , index of line if OK
2018-10-03 12:22:41 +02:00
*/
2021-09-22 14:56:44 +02:00
public function addline ( $entrepot_id , $id , $qty , $array_options = 0 , $comment = '' , $eatby = '' , $sellby = '' , $batch = '' , $cost_price = 0 )
2018-10-03 12:22:41 +02:00
{
2018-10-04 17:32:50 +02:00
global $conf , $langs , $user ;
2018-10-03 12:22:41 +02:00
$num = count ( $this -> lines );
2018-10-04 17:32:50 +02:00
$line = new CommandeFournisseurDispatch ( $this -> db );
2018-10-03 12:22:41 +02:00
2018-10-04 17:32:50 +02:00
$line -> fk_entrepot = $entrepot_id ;
$line -> fk_commandefourndet = $id ;
2018-10-03 12:22:41 +02:00
$line -> qty = $qty ;
2018-10-04 17:32:50 +02:00
$supplierorderline = new CommandeFournisseurLigne ( $this -> db );
2022-03-17 18:53:50 +01:00
$result = $supplierorderline -> fetch ( $id );
if ( $result <= 0 ) {
$this -> error = $supplierorderline -> error ;
$this -> errors = $supplierorderline -> errors ;
return - 1 ;
}
2018-12-15 13:58:39 +01:00
2022-03-17 18:53:50 +01:00
$fk_product = 0 ;
2021-02-26 20:53:03 +01:00
if ( ! empty ( $conf -> stock -> enabled ) && ! empty ( $supplierorderline -> fk_product )) {
2018-10-04 17:32:50 +02:00
$fk_product = $supplierorderline -> fk_product ;
2018-12-15 13:58:39 +01:00
2021-02-26 20:53:03 +01:00
if ( ! ( $entrepot_id > 0 ) && empty ( $conf -> global -> STOCK_WAREHOUSE_NOT_REQUIRED_FOR_RECEPTIONS )) {
2020-10-28 17:49:52 +01:00
$langs -> load ( " errors " );
2019-11-13 18:32:11 +01:00
$this -> error = $langs -> trans ( " ErrorWarehouseRequiredIntoReceptionLine " );
2018-10-03 12:22:41 +02:00
return - 1 ;
}
}
2022-07-08 15:30:31 +02:00
// Check batch is set
$product = new Product ( $this -> db );
$product -> fetch ( $fk_product );
if ( ! empty ( $conf -> productbatch -> enabled )) {
$langs -> load ( " errors " );
if ( ! empty ( $product -> status_batch ) && empty ( $batch )) {
$this -> error = $langs -> trans ( 'ErrorProductNeedBatchNumber' , $product -> ref );
return - 1 ;
} elseif ( empty ( $product -> status_batch ) && ! empty ( $batch )) {
$this -> error = $langs -> trans ( 'ErrorProductDoesNotNeedBatchNumber' , $product -> ref );
return - 1 ;
}
}
2022-07-08 15:53:41 +02:00
unset ( $product );
2022-07-08 15:30:31 +02:00
2018-10-03 12:22:41 +02:00
// extrafields
2020-04-24 18:58:47 +02:00
$line -> array_options = $supplierorderline -> array_options ;
2021-02-26 20:53:03 +01:00
if ( empty ( $conf -> global -> MAIN_EXTRAFIELDS_DISABLED ) && is_array ( $array_options ) && count ( $array_options ) > 0 ) {
2020-04-23 19:29:52 +02:00
foreach ( $array_options as $key => $value ) {
$line -> array_options [ $key ] = $value ;
}
}
2018-12-15 13:58:39 +01:00
2018-10-04 17:32:50 +02:00
$line -> fk_product = $fk_product ;
2019-11-13 18:32:11 +01:00
$line -> fk_commande = $supplierorderline -> fk_commande ;
$line -> fk_user = $user -> id ;
2018-10-04 17:32:50 +02:00
$line -> comment = $comment ;
$line -> batch = $batch ;
$line -> eatby = $eatby ;
$line -> sellby = $sellby ;
2019-11-13 18:32:11 +01:00
$line -> status = 1 ;
2021-09-22 14:56:44 +02:00
$line -> cost_price = $cost_price ;
2019-11-13 18:32:11 +01:00
$line -> fk_reception = $this -> id ;
2022-07-10 18:35:23 +02:00
2018-10-03 12:22:41 +02:00
$this -> lines [ $num ] = $line ;
2020-11-04 17:44:02 +01:00
return $num ;
2018-10-03 12:22:41 +02:00
}
2020-10-28 17:49:52 +01:00
/**
* Update database
*
* @ param User $user User that modify
* @ param int $notrigger 0 = launch triggers after , 1 = disable triggers
* @ return int < 0 if KO , > 0 if OK
*/
public function update ( $user = null , $notrigger = 0 )
{
global $conf ;
2019-11-13 18:32:11 +01:00
$error = 0 ;
2018-10-03 12:22:41 +02:00
// Clean parameters
2021-02-26 20:53:03 +01:00
if ( isset ( $this -> ref )) {
$this -> ref = trim ( $this -> ref );
}
if ( isset ( $this -> entity )) {
$this -> entity = trim ( $this -> entity );
}
if ( isset ( $this -> ref_supplier )) {
$this -> ref_supplier = trim ( $this -> ref_supplier );
}
if ( isset ( $this -> socid )) {
$this -> socid = trim ( $this -> socid );
}
if ( isset ( $this -> fk_user_author )) {
$this -> fk_user_author = trim ( $this -> fk_user_author );
}
if ( isset ( $this -> fk_user_valid )) {
$this -> fk_user_valid = trim ( $this -> fk_user_valid );
}
if ( isset ( $this -> shipping_method_id )) {
$this -> shipping_method_id = trim ( $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 )) {
$this -> weight_units = trim ( $this -> weight_units );
}
if ( isset ( $this -> trueWeight )) {
$this -> weight = trim ( $this -> trueWeight );
}
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 );
}
2018-10-03 12:22:41 +02:00
// Check parameters
// Put here code to add control on parameters values
2020-10-28 17:49:52 +01:00
// Update request
$sql = " UPDATE " . MAIN_DB_PREFIX . " reception SET " ;
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
$sql .= " ref= " . ( isset ( $this -> ref ) ? " ' " . $this -> db -> escape ( $this -> ref ) . " ' " : " null " ) . " , " ;
$sql .= " ref_supplier= " . ( isset ( $this -> ref_supplier ) ? " ' " . $this -> db -> escape ( $this -> ref_supplier ) . " ' " : " 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 " ) . " , " ;
$sql .= " date_reception= " . ( dol_strlen ( $this -> date_reception ) != 0 ? " ' " . $this -> db -> idate ( $this -> date_reception ) . " ' " : 'null' ) . " , " ;
$sql .= " date_delivery= " . ( dol_strlen ( $this -> date_delivery ) != 0 ? " ' " . $this -> db -> idate ( $this -> date_delivery ) . " ' " : '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 .= " 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 " ) . " , " ;
2022-01-03 18:15:19 +01:00
$sql .= " model_pdf= " . ( isset ( $this -> model_pdf ) ? " ' " . $this -> db -> escape ( $this -> model_pdf ) . " ' " : " null " ) . " , " ;
$sql .= " entity = " . (( int ) $conf -> entity );
2021-03-14 12:20:23 +01:00
$sql .= " WHERE rowid= " . (( int ) $this -> id );
2018-10-03 12:22:41 +02:00
$this -> db -> begin ();
dol_syslog ( get_class ( $this ) . " ::update " , LOG_DEBUG );
2020-10-28 17:49:52 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( ! $resql ) {
$error ++ ; $this -> errors [] = " Error " . $this -> db -> lasterror ();
}
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
if ( ! $notrigger ) {
2020-10-28 17:49:52 +01:00
// Call trigger
$result = $this -> call_trigger ( 'RECEPTION_MODIFY' , $user );
2021-02-26 20:53:03 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2020-10-28 17:49:52 +01:00
// End call triggers
}
2018-10-03 12:22:41 +02:00
}
2020-10-28 17:49:52 +01:00
// Commit or rollback
2021-02-26 20:53:03 +01:00
if ( $error ) {
foreach ( $this -> errors as $errmsg ) {
2020-10-28 17:49:52 +01:00
dol_syslog ( get_class ( $this ) . " ::update " . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
2018-10-03 12:22:41 +02:00
}
$this -> db -> rollback ();
2019-11-13 18:32:11 +01:00
return - 1 * $error ;
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$this -> db -> commit ();
return 1 ;
}
2018-12-15 15:43:30 +01:00
}
2018-10-03 12:22:41 +02:00
/**
* Delete reception .
*
2018-12-15 16:37:00 +01:00
* @ param User $user Object user
* @ return int > 0 if OK , 0 if deletion done but failed to delete files , < 0 if KO
2018-10-03 12:22:41 +02:00
*/
2020-10-28 17:49:52 +01:00
public function delete ( User $user )
2018-10-03 12:22:41 +02:00
{
global $conf , $langs , $user ;
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2018-12-15 13:58:39 +01:00
2019-11-13 18:32:11 +01:00
$error = 0 ;
$this -> error = '' ;
2018-10-03 12:22:41 +02:00
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
$this -> db -> begin ();
2018-12-15 15:43:30 +01:00
2018-10-03 12:22:41 +02:00
// Stock control
2021-02-26 20:53:03 +01:00
if ( $conf -> stock -> enabled && $conf -> global -> STOCK_CALCULATE_ON_RECEPTION && $this -> statut > 0 ) {
2018-12-15 15:43:30 +01:00
require_once DOL_DOCUMENT_ROOT . " /product/stock/class/mouvementstock.class.php " ;
2018-10-03 12:22:41 +02:00
$langs -> load ( " agenda " );
// Loop on each product line to add a stock movement
2018-10-09 11:33:41 +02:00
$sql = " SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot, ed.eatby, ed.sellby, ed.batch, ed.rowid as commande_fournisseur_dispatch_id " ;
2019-11-13 18:32:11 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " commande_fournisseurdet as cd, " ;
$sql .= " " . MAIN_DB_PREFIX . " commande_fournisseur_dispatch as ed " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE ed.fk_reception = " . (( int ) $this -> id );
2019-11-13 18:32:11 +01:00
$sql .= " AND cd.rowid = ed.fk_commandefourndet " ;
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::delete select details " , LOG_DEBUG );
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2018-10-03 12:22:41 +02:00
$cpt = $this -> db -> num_rows ( $resql );
2021-02-26 20:53:03 +01:00
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
2018-10-03 12:22:41 +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
$mouvS -> origin = null ;
2018-12-15 13:58:39 +01:00
2019-11-13 18:32:11 +01:00
$result = $mouvS -> livraison ( $user , $obj -> fk_product , $obj -> fk_entrepot , $obj -> qty , 0 , $langs -> trans ( " ReceptionDeletedInDolibarr " , $this -> ref ), '' , $obj -> eatby , $obj -> sellby , $obj -> batch ); // Price is set to 0, because we don't want to see WAP changed
2018-10-03 12:22:41 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 18:32:11 +01:00
$error ++ ; $this -> errors [] = " Error " . $this -> db -> lasterror ();
2018-10-03 12:22:41 +02:00
}
}
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2021-09-30 15:59:47 +02:00
$main = MAIN_DB_PREFIX . 'commande_fournisseur_dispatch' ;
$ef = $main . " _extrafields " ;
$sqlef = " DELETE FROM " . $ef . " WHERE fk_object IN (SELECT rowid FROM " . $main . " WHERE fk_reception = " . (( int ) $this -> id ) . " ) " ;
2020-04-23 19:22:25 +02:00
2018-10-05 16:21:50 +02:00
$sql = " DELETE FROM " . MAIN_DB_PREFIX . " commande_fournisseur_dispatch " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE fk_reception = " . (( int ) $this -> id );
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( $this -> db -> query ( $sqlef ) && $this -> db -> query ( $sql )) {
2018-10-03 12:22:41 +02:00
// Delete linked object
$res = $this -> deleteObjectLinked ();
2021-02-26 20:53:03 +01:00
if ( $res < 0 ) {
$error ++ ;
}
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2018-10-03 12:22:41 +02:00
$sql = " DELETE FROM " . MAIN_DB_PREFIX . " reception " ;
2021-08-27 16:33:03 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( $this -> db -> query ( $sql )) {
2018-10-03 12:22:41 +02:00
// Call trigger
2019-11-13 18:32:11 +01:00
$result = $this -> call_trigger ( 'RECEPTION_DELETE' , $user );
2021-02-26 20:53:03 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2018-10-03 12:22:41 +02:00
// End call triggers
2021-02-26 20:53:03 +01:00
if ( ! empty ( $this -> origin ) && $this -> origin_id > 0 ) {
2020-10-28 17:49:52 +01:00
$this -> fetch_origin ();
$origin = $this -> origin ;
2021-02-26 20:53:03 +01:00
if ( $this -> $origin -> statut == 4 ) { // If order source of reception is "partially received"
2020-10-28 17:49:52 +01:00
// Check if there is no more reception. If not, we can move back status of order to "validated" instead of "reception in progress"
$this -> $origin -> loadReceptions ();
//var_dump($this->$origin->receptions);exit;
2021-02-26 20:53:03 +01:00
if ( count ( $this -> $origin -> receptions ) <= 0 ) {
2020-10-28 17:49:52 +01:00
$this -> $origin -> setStatut ( 3 ); // ordered
}
}
2018-10-03 12:22:41 +02:00
}
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2018-10-03 12:22:41 +02:00
$this -> db -> commit ();
// We delete PDFs
$ref = dol_sanitizeFileName ( $this -> ref );
2021-02-26 20:53:03 +01:00
if ( ! empty ( $conf -> reception -> dir_output )) {
2019-11-13 18:32:11 +01:00
$dir = $conf -> reception -> dir_output . '/' . $ref ;
$file = $dir . '/' . $ref . '.pdf' ;
2021-02-26 20:53:03 +01:00
if ( file_exists ( $file )) {
if ( ! dol_delete_file ( $file )) {
2018-10-03 12:22:41 +02:00
return 0 ;
}
}
2021-02-26 20:53:03 +01:00
if ( file_exists ( $dir )) {
if ( ! dol_delete_dir_recursive ( $dir )) {
2019-11-13 18:32:11 +01:00
$this -> error = $langs -> trans ( " ErrorCanNotDeleteDir " , $dir );
2018-10-03 12:22:41 +02:00
return 0 ;
}
}
}
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
return - 3 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
return - 2 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> lasterror () . " - sql= $sql " ;
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
2018-12-15 15:43:30 +01:00
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-10-03 12:22:41 +02:00
/**
* Load lines
*
* @ return int > 0 if OK , Otherwise if KO
*/
2020-10-28 17:49:52 +01:00
public function fetch_lines ()
2018-10-03 12:22:41 +02:00
{
2018-10-23 14:31:58 +02:00
// phpcs:enable
2022-03-28 13:50:47 +02:00
$this -> lines = array ();
require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.commande.dispatch.class.php' ;
2021-09-30 15:59:47 +02:00
$sql = " SELECT rowid FROM " . MAIN_DB_PREFIX . " commande_fournisseur_dispatch WHERE fk_reception = " . (( int ) $this -> id );
2020-09-20 03:32:43 +02:00
$resql = $this -> db -> query ( $sql );
2018-12-15 13:58:39 +01:00
2019-11-13 18:32:11 +01:00
if ( ! empty ( $resql )) {
2020-10-26 18:30:32 +01:00
while ( $obj = $this -> db -> fetch_object ( $resql )) {
2020-09-20 03:32:43 +02:00
$line = new CommandeFournisseurDispatch ( $this -> db );
2022-03-28 13:50:47 +02:00
2018-10-05 16:21:50 +02:00
$line -> fetch ( $obj -> rowid );
2022-09-21 01:13:53 +02:00
// TODO Remove or keep this ?
2018-10-05 16:21:50 +02:00
$line -> fetch_product ();
2022-03-28 13:50:47 +02:00
2021-05-10 11:53:19 +02:00
$sql_commfourndet = 'SELECT qty, ref, label, description, tva_tx, vat_src_code, subprice, multicurrency_subprice, remise_percent' ;
$sql_commfourndet .= ' FROM ' . MAIN_DB_PREFIX . 'commande_fournisseurdet' ;
$sql_commfourndet .= ' WHERE rowid = ' . (( int ) $line -> fk_commandefourndet );
2022-03-15 14:59:26 +01:00
$sql_commfourndet .= ' ORDER BY rang' ;
2022-03-28 13:50:47 +02:00
2020-10-26 18:30:32 +01:00
$resql_commfourndet = $this -> db -> query ( $sql_commfourndet );
2019-11-13 18:32:11 +01:00
if ( ! empty ( $resql_commfourndet )) {
2020-09-20 03:32:43 +02:00
$obj = $this -> db -> fetch_object ( $resql_commfourndet );
2018-10-08 12:15:17 +02:00
$line -> qty_asked = $obj -> qty ;
2021-05-10 11:53:19 +02:00
$line -> description = $obj -> description ;
$line -> desc = $obj -> description ;
2018-10-09 16:26:40 +02:00
$line -> tva_tx = $obj -> tva_tx ;
$line -> vat_src_code = $obj -> vat_src_code ;
$line -> subprice = $obj -> subprice ;
$line -> multicurrency_subprice = $obj -> multicurrency_subprice ;
$line -> remise_percent = $obj -> remise_percent ;
2019-11-13 18:32:11 +01:00
$line -> label = ! empty ( $obj -> label ) ? $obj -> label : $line -> product -> label ;
2018-10-22 14:32:50 +02:00
$line -> ref_supplier = $obj -> ref ;
2019-11-13 18:32:11 +01:00
} else {
2018-10-08 12:15:17 +02:00
$line -> qty_asked = 0 ;
2018-10-08 16:54:33 +02:00
$line -> description = '' ;
2021-05-10 11:53:19 +02:00
$line -> desc = '' ;
2018-10-08 16:54:33 +02:00
$line -> label = $obj -> label ;
2018-10-08 12:15:17 +02:00
}
2018-12-15 13:58:39 +01:00
2019-11-13 18:32:11 +01:00
$pu_ht = ( $line -> subprice * $line -> qty ) * ( 100 - $line -> remise_percent ) / 100 ;
$tva = $pu_ht * $line -> tva_tx / 100 ;
2018-10-09 16:26:40 +02:00
$this -> total_ht += $pu_ht ;
2019-11-13 18:32:11 +01:00
$this -> total_tva += $pu_ht * $line -> tva_tx / 100 ;
2018-12-15 13:58:39 +01:00
2019-11-13 18:32:11 +01:00
$this -> total_ttc += $pu_ht + $tva ;
2018-12-15 13:58:39 +01:00
2019-11-13 18:32:11 +01:00
$this -> lines [] = $line ;
2018-10-03 12:22:41 +02:00
}
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-10-05 16:21:50 +02:00
return - 1 ;
2018-10-03 12:22:41 +02:00
}
}
/**
2020-10-28 17:49:52 +01:00
* Return clicable link of object ( with eventually picto )
*
* @ param int $withpicto Add picto into link
* @ param int $option Where point the link
* @ param int $max Max length to show
* @ param int $short Use short labels
* @ param int $notooltip 1 = No tooltip
* @ return string String with URL
*/
public function getNomUrl ( $withpicto = 0 , $option = 0 , $max = 0 , $short = 0 , $notooltip = 0 )
2018-10-03 12:22:41 +02:00
{
2021-11-22 19:57:26 +01:00
global $conf , $langs , $hookmanager ;
2019-11-13 18:32:11 +01:00
$result = '' ;
2020-09-11 13:32:40 +02:00
$label = img_picto ( '' , $this -> picto ) . ' <u>' . $langs -> trans ( " Reception " ) . '</u>' ;
2020-10-28 17:49:52 +01:00
$label .= '<br><b>' . $langs -> trans ( 'Ref' ) . ':</b> ' . $this -> ref ;
2021-12-01 15:40:53 +01:00
$label .= '<br><b>' . $langs -> trans ( 'RefSupplier' ) . ':</b> ' . ( $this -> ref_supplier ? $this -> ref_supplier : '' );
2018-10-03 12:22:41 +02:00
$url = DOL_URL_ROOT . '/reception/card.php?id=' . $this -> id ;
2021-02-26 20:53:03 +01:00
if ( $short ) {
return $url ;
}
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
$linkclose = '' ;
2021-02-26 20:53:03 +01:00
if ( empty ( $notooltip )) {
if ( ! empty ( $conf -> global -> MAIN_OPTIMIZEFORTEXTBROWSER )) {
2020-10-28 17:49:52 +01:00
$label = $langs -> trans ( " Reception " );
$linkclose .= ' alt="' . dol_escape_htmltag ( $label , 1 ) . '"' ;
}
$linkclose .= ' title="' . dol_escape_htmltag ( $label , 1 ) . '"' ;
$linkclose .= ' class="classfortooltip"' ;
2018-10-03 12:22:41 +02:00
}
2020-10-28 17:49:52 +01:00
$linkstart = '<a href="' . $url . '"' ;
$linkstart .= $linkclose . '>' ;
2019-11-13 18:32:11 +01:00
$linkend = '</a>' ;
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( $withpicto ) {
$result .= ( $linkstart . img_object (( $notooltip ? '' : $label ), $this -> picto , ( $notooltip ? '' : 'class="classfortooltip"' ), 0 , 0 , $notooltip ? 0 : 1 ) . $linkend );
}
if ( $withpicto && $withpicto != 2 ) {
$result .= ' ' ;
}
2019-11-13 18:32:11 +01:00
$result .= $linkstart . $this -> ref . $linkend ;
2021-11-22 19:57:26 +01:00
global $action ;
2022-02-15 19:04:18 +01:00
$hookmanager -> initHooks ( array ( $this -> element . 'dao' ));
2021-11-22 19:57:26 +01:00
$parameters = array ( 'id' => $this -> id , 'getnomurl' => & $result );
$reshook = $hookmanager -> executeHooks ( 'getNomUrl' , $parameters , $this , $action ); // Note that $action and $object may have been modified by some hooks
if ( $reshook > 0 ) {
$result = $hookmanager -> resPrint ;
} else {
$result .= $hookmanager -> resPrint ;
}
2018-10-03 12:22:41 +02:00
return $result ;
}
/**
2020-10-28 17:49:52 +01: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
* @ return string Libelle
*/
public function getLibStatut ( $mode = 0 )
{
return $this -> LibStatut ( $this -> statut , $mode );
}
2018-10-03 12:22:41 +02:00
2019-03-01 23:08:57 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-10-03 12:22:41 +02:00
/**
* Return label of a status
*
2019-11-01 23:58:14 +01:00
* @ param int $status Id status
2018-10-03 12:22:41 +02:00
* @ param int $mode 0 = Long label , 1 = Short label , 2 = Picto + Short label , 3 = Picto , 4 = Picto + Long label , 5 = Short label + Picto
* @ return string Label of status
*/
2020-10-28 17:49:52 +01:00
public function LibStatut ( $status , $mode )
{
// phpcs:enable
global $langs ;
2019-11-04 19:28:04 +01:00
2021-10-16 19:37:57 +02:00
$labelStatus = $langs -> transnoentitiesnoconv ( $this -> statuts [ $status ]);
$labelStatusShort = $langs -> transnoentitiesnoconv ( $this -> statutshorts [ $status ]);
2019-11-04 19:28:04 +01:00
2020-10-28 17:49:52 +01:00
$statusType = 'status' . $status ;
2021-02-26 20:53:03 +01:00
if ( $status == self :: STATUS_VALIDATED ) {
$statusType = 'status4' ;
}
if ( $status == self :: STATUS_CLOSED ) {
$statusType = 'status6' ;
}
2019-11-04 19:28:04 +01:00
2020-10-28 17:49:52 +01:00
return dolGetStatus ( $labelStatus , $labelStatusShort , '' , $statusType , $mode );
2018-10-03 12:22:41 +02:00
}
/**
2020-10-28 17:49:52 +01:00
* Initialise an instance with random values .
* Used to build previews or test instances .
* id must be 0 if object instance is a specimen .
*
* @ return void
*/
public function initAsSpecimen ()
{
2018-10-03 12:22:41 +02:00
global $langs ;
2019-05-09 17:16:35 +02:00
include_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.commande.class.php' ;
include_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.commande.dispatch.class.php' ;
2019-11-13 18:32:11 +01:00
$now = dol_now ();
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::initAsSpecimen " );
2020-10-28 17:49:52 +01:00
// Load array of products prodids
2018-10-03 12:22:41 +02:00
$num_prods = 0 ;
$prodids = array ();
$sql = " SELECT rowid " ;
2019-11-13 18:32:11 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " product " ;
$sql .= " WHERE entity IN ( " . getEntity ( 'product' ) . " ) " ;
2020-08-19 01:43:48 +02:00
$sql .= $this -> db -> plimit ( 100 );
2018-10-03 12:22:41 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2018-10-03 12:22:41 +02:00
$num_prods = $this -> db -> num_rows ( $resql );
$i = 0 ;
2021-02-26 20:53:03 +01:00
while ( $i < $num_prods ) {
2018-10-03 12:22:41 +02:00
$i ++ ;
$row = $this -> db -> fetch_row ( $resql );
$prodids [ $i ] = $row [ 0 ];
}
}
2019-11-13 18:32:11 +01:00
$order = new CommandeFournisseur ( $this -> db );
2018-10-03 12:22:41 +02:00
$order -> initAsSpecimen ();
// Initialise parametres
2019-11-13 18:32:11 +01:00
$this -> id = 0 ;
2018-10-03 12:22:41 +02:00
$this -> ref = 'SPECIMEN' ;
2019-11-13 18:32:11 +01:00
$this -> specimen = 1 ;
2018-10-03 12:22:41 +02:00
$this -> statut = 1 ;
$this -> livraison_id = 0 ;
$this -> date = $now ;
$this -> date_creation = $now ;
$this -> date_valid = $now ;
$this -> date_delivery = $now ;
2019-11-13 18:32:11 +01:00
$this -> date_reception = $now + 24 * 3600 ;
2018-10-03 12:22:41 +02:00
$this -> entrepot_id = 0 ;
$this -> socid = 1 ;
$this -> commande_id = 0 ;
$this -> commande = $order ;
2020-10-28 17:49:52 +01:00
$this -> origin_id = 1 ;
$this -> origin = 'commande' ;
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
$this -> note_private = 'Private note' ;
$this -> note_public = 'Public note' ;
2018-10-03 12:22:41 +02:00
$nbp = 5 ;
$xnbp = 0 ;
2021-02-26 20:53:03 +01:00
while ( $xnbp < $nbp ) {
2019-11-13 18:32:11 +01:00
$line = new CommandeFournisseurDispatch ( $this -> db );
$line -> desc = $langs -> trans ( " Description " ) . " " . $xnbp ;
$line -> libelle = $langs -> trans ( " Description " ) . " " . $xnbp ;
$line -> qty = 10 ;
2018-12-15 13:58:39 +01:00
2019-11-13 18:32:11 +01:00
$line -> fk_product = $this -> commande -> lines [ $xnbp ] -> fk_product ;
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
$this -> lines [] = $line ;
2018-10-03 12:22:41 +02:00
$xnbp ++ ;
}
}
2018-12-15 13:58:39 +01:00
2020-10-31 14:32:18 +01:00
/**
2018-10-03 12:22:41 +02:00
* Set the planned delivery date
*
* @ param User $user Objet utilisateur qui modifie
2020-10-06 11:37:55 +02:00
* @ param integer $delivery_date Delivery date
2018-10-03 12:22:41 +02:00
* @ return int < 0 if KO , > 0 if OK
*/
2020-10-31 14:32:18 +01:00
public function setDeliveryDate ( $user , $delivery_date )
2018-10-03 12:22:41 +02:00
{
2018-10-23 14:31:58 +02:00
// phpcs:enable
2021-02-26 20:53:03 +01:00
if ( $user -> rights -> reception -> creer ) {
2018-10-03 12:22:41 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . " reception " ;
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 );
2018-10-03 12:22:41 +02:00
2020-10-26 16:50:52 +01:00
dol_syslog ( get_class ( $this ) . " ::setDeliveryDate " , LOG_DEBUG );
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2020-10-06 11:37:55 +02:00
$this -> date_delivery = $delivery_date ;
2018-10-03 12:22:41 +02:00
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> error ();
2018-10-03 12:22:41 +02:00
return - 1 ;
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
return - 2 ;
}
}
2018-12-15 15:01:49 +01:00
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-10-03 12:22:41 +02:00
/**
* Fetch deliveries method and return an array . Load array this -> meths ( rowid => label ) .
*
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function fetch_delivery_methods ()
2018-10-03 12:22:41 +02:00
{
2018-10-23 14:31:58 +02:00
// phpcs:enable
2018-10-03 12:22:41 +02:00
global $langs ;
$this -> meths = array ();
$sql = " SELECT em.rowid, em.code, em.libelle " ;
2019-11-13 18:32:11 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_shipment_mode as em " ;
$sql .= " WHERE em.active = 1 " ;
$sql .= " ORDER BY em.libelle ASC " ;
2018-10-03 12:22:41 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
while ( $obj = $this -> db -> fetch_object ( $resql )) {
2019-11-13 18:32:11 +01:00
$label = $langs -> trans ( 'ReceptionMethod' . $obj -> code );
$this -> meths [ $obj -> rowid ] = ( $label != 'ReceptionMethod' . $obj -> code ? $label : $obj -> libelle );
2018-10-03 12:22:41 +02:00
}
}
}
2018-12-15 15:01:49 +01:00
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Fetch all deliveries method and return an array . Load array this -> listmeths .
*
* @ param int $id only this carrier , all if none
* @ return void
*/
public function list_delivery_methods ( $id = '' )
{
2018-10-23 14:31:58 +02:00
// phpcs:enable
2020-10-28 17:49:52 +01:00
global $langs ;
$this -> listmeths = array ();
$i = 0 ;
$sql = " SELECT em.rowid, em.code, em.libelle, em.description, em.tracking, em.active " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " c_shipment_mode as em " ;
2021-02-26 20:53:03 +01:00
if ( $id != '' ) {
2021-04-25 15:55:36 +02:00
$sql .= " WHERE em.rowid = " . (( int ) $id );
2021-02-26 20:53:03 +01:00
}
2020-10-28 17:49:52 +01:00
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
while ( $obj = $this -> db -> fetch_object ( $resql )) {
$this -> listmeths [ $i ][ 'rowid' ] = $obj -> rowid ;
$this -> listmeths [ $i ][ 'code' ] = $obj -> code ;
$label = $langs -> trans ( 'ReceptionMethod' . $obj -> code );
$this -> listmeths [ $i ][ 'libelle' ] = ( $label != 'ReceptionMethod' . $obj -> code ? $label : $obj -> libelle );
$this -> listmeths [ $i ][ 'description' ] = $obj -> description ;
$this -> listmeths [ $i ][ 'tracking' ] = $obj -> tracking ;
$this -> listmeths [ $i ][ 'active' ] = $obj -> active ;
$i ++ ;
}
}
}
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
/**
* Forge an set tracking url
*
* @ param string $value Value
* @ return void
*/
2020-10-28 17:49:52 +01:00
public function getUrlTrackingStatus ( $value = '' )
2018-10-03 12:22:41 +02:00
{
2021-02-26 20:53:03 +01:00
if ( ! empty ( $this -> shipping_method_id )) {
2018-10-03 12:22:41 +02:00
$sql = " SELECT em.code, em.tracking " ;
2019-11-13 18:32:11 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_shipment_mode as em " ;
2021-03-30 19:12:07 +02:00
$sql .= " WHERE em.rowid = " . (( int ) $this -> shipping_method_id );
2018-10-03 12:22:41 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
if ( $obj = $this -> db -> fetch_object ( $resql )) {
2018-10-03 12:22:41 +02:00
$tracking = $obj -> tracking ;
}
}
}
2021-02-26 20:53:03 +01:00
if ( ! empty ( $tracking ) && ! empty ( $value )) {
2018-10-03 12:22:41 +02:00
$url = str_replace ( '{TRACKID}' , $value , $tracking );
2021-11-22 02:35:55 +01:00
$this -> tracking_url = sprintf ( '<a target="_blank" rel="noopener noreferrer" href="%s">' . ( $value ? $value : 'url' ) . '</a>' , $url , $url );
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$this -> tracking_url = $value ;
}
}
/**
2021-11-19 13:46:30 +01:00
* Classify the reception as closed ( this record also the stock movement )
2018-10-03 12:22:41 +02:00
*
* @ return int < 0 if KO , > 0 if OK
*/
2020-10-28 17:49:52 +01:00
public function setClosed ()
2018-10-03 12:22:41 +02:00
{
2019-11-13 18:32:11 +01:00
global $conf , $langs , $user ;
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
$error = 0 ;
2018-10-03 12:22:41 +02:00
$this -> db -> begin ();
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'reception SET fk_statut=' . self :: STATUS_CLOSED ;
2021-08-27 23:36:06 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . ' AND fk_statut > 0' ;
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2018-10-17 11:56:32 +02:00
// Set order billed if 100% of order is received (qty in reception lines match qty in order lines)
2021-02-26 20:53:03 +01:00
if ( $this -> origin == 'order_supplier' && $this -> origin_id > 0 ) {
2018-10-09 11:33:41 +02:00
$order = new CommandeFournisseur ( $this -> db );
2018-10-03 12:22:41 +02:00
$order -> fetch ( $this -> origin_id );
2019-11-13 18:32:11 +01:00
$order -> loadReceptions ( self :: STATUS_CLOSED ); // Fill $order->receptions = array(orderlineid => qty)
2018-10-03 12:22:41 +02:00
$receptions_match_order = 1 ;
2021-02-26 20:53:03 +01:00
foreach ( $order -> lines as $line ) {
2018-10-03 12:22:41 +02:00
$lineid = $line -> id ;
$qty = $line -> qty ;
2021-02-26 20:53:03 +01:00
if (( $line -> product_type == 0 || ! empty ( $conf -> global -> STOCK_SUPPORTS_SERVICES )) && $order -> receptions [ $lineid ] < $qty ) {
2018-10-03 12:22:41 +02:00
$receptions_match_order = 0 ;
2019-11-13 18:32:11 +01:00
$text = 'Qty for order line id ' . $lineid . ' is ' . $qty . '. However in the receptions with status Reception::STATUS_CLOSED=' . self :: STATUS_CLOSED . ' we have qty = ' . $order -> receptions [ $lineid ] . ', so we can t close order' ;
2018-10-03 12:22:41 +02:00
dol_syslog ( $text );
break ;
}
}
2021-02-26 20:53:03 +01:00
if ( $receptions_match_order ) {
2018-10-03 12:22:41 +02:00
dol_syslog ( " Qty for the " . count ( $order -> lines ) . " lines of order have same value for receptions with status Reception::STATUS_CLOSED= " . self :: STATUS_CLOSED . ', so we close order' );
2018-10-09 11:33:41 +02:00
$order -> Livraison ( $user , dol_now (), 'tot' , 'Reception ' . $this -> ref );
2018-10-03 12:22:41 +02:00
}
}
2019-11-13 18:32:11 +01:00
$this -> statut = self :: STATUS_CLOSED ;
2018-10-03 12:22:41 +02:00
// If stock increment is done on closing
2021-02-26 20:53:03 +01:00
if ( ! $error && ! empty ( $conf -> stock -> enabled ) && ! empty ( $conf -> global -> STOCK_CALCULATE_ON_RECEPTION_CLOSE )) {
2018-10-03 12:22:41 +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
2018-10-18 15:11:43 +02:00
// TODO possibilite de receptionner a partir d'une propale ou autre origine ?
2018-10-03 12:22:41 +02:00
$sql = " SELECT cd.fk_product, cd.subprice, " ;
2019-11-13 18:32:11 +01:00
$sql .= " ed.rowid, ed.qty, ed.fk_entrepot, " ;
2022-06-08 18:27:47 +02:00
$sql .= " ed.eatby, ed.sellby, ed.batch, " ;
$sql .= " ed.cost_price " ;
2019-11-13 18:32:11 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " commande_fournisseurdet as cd, " ;
$sql .= " " . MAIN_DB_PREFIX . " commande_fournisseur_dispatch as ed " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE ed.fk_reception = " . (( int ) $this -> id );
2019-11-13 18:32:11 +01:00
$sql .= " AND cd.rowid = ed.fk_commandefourndet " ;
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid select details " , LOG_DEBUG );
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2018-12-15 13:58:39 +01:00
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2018-10-03 12:22:41 +02:00
$cpt = $this -> db -> num_rows ( $resql );
2021-02-26 20:53:03 +01:00
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
2018-10-03 12:22:41 +02:00
$obj = $this -> db -> fetch_object ( $resql );
2018-12-15 13:58:39 +01:00
2018-10-09 11:33:41 +02:00
$qty = $obj -> qty ;
2018-12-15 13:58:39 +01:00
2021-02-26 20:53:03 +01:00
if ( $qty <= 0 ) {
continue ;
}
2018-10-03 12:22:41 +02:00
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 ;
2022-03-22 13:46:55 +01:00
$mouvS -> setOrigin ( $this -> element , $this -> id );
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( empty ( $obj -> batch )) {
2018-10-03 12:22:41 +02:00
// 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
2021-11-19 13:46:30 +01:00
$inventorycode = '' ;
2022-06-08 18:27:47 +02:00
$result = $mouvS -> reception ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> cost_price , $langs -> trans ( " ReceptionClassifyClosedInDolibarr " , $this -> ref ), '' , '' , '' , '' , 0 , $inventorycode );
2018-10-03 12:22:41 +02:00
if ( $result < 0 ) {
2020-10-28 17:49:52 +01:00
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
2018-10-03 12:22:41 +02:00
$error ++ ; break ;
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
// 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
2021-11-19 13:46:30 +01:00
$inventorycode = '' ;
2022-06-08 18:27:47 +02:00
$result = $mouvS -> reception ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> cost_price , $langs -> trans ( " ReceptionClassifyClosedInDolibarr " , $this -> ref ), $this -> db -> jdate ( $obj -> eatby ), $this -> db -> jdate ( $obj -> sellby ), $obj -> batch , '' , 0 , $inventorycode );
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
if ( $result < 0 ) {
2020-10-28 17:49:52 +01:00
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
$error ++ ; break ;
2018-10-03 12:22:41 +02:00
}
}
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> lasterror ();
2018-10-03 12:22:41 +02:00
$error ++ ;
}
}
// Call trigger
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2020-10-28 17:49:52 +01:00
$result = $this -> call_trigger ( 'RECEPTION_CLOSED' , $user );
if ( $result < 0 ) {
$error ++ ;
}
2018-10-03 12:22:41 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
dol_print_error ( $this -> db );
2020-10-28 17:49:52 +01:00
$error ++ ;
2018-10-03 12:22:41 +02:00
}
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2020-10-28 17:49:52 +01:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2020-10-28 17:49:52 +01:00
$this -> db -> rollback ();
return - 1 ;
2018-10-03 12:22:41 +02:00
}
}
2018-12-15 15:01:49 +01:00
2020-10-28 17:49:52 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2018-10-03 12:22:41 +02:00
/**
* Classify the reception as invoiced ( used when WORKFLOW_BILL_ON_RECEPTION is on )
*
2021-02-09 13:10:11 +01:00
* @ deprecated
* @ see setBilled ()
2018-10-03 12:22:41 +02:00
* @ return int < 0 if ko , > 0 if ok
*/
2020-10-28 17:49:52 +01:00
public function set_billed ()
2018-10-03 12:22:41 +02:00
{
2018-10-23 14:31:58 +02:00
// phpcs:enable
2021-02-09 13:10:11 +01:00
dol_syslog ( get_class ( $this ) . " ::set_billed is deprecated, use setBilled instead " , LOG_NOTICE );
return $this -> setBilled ();
}
/**
* Classify the reception as invoiced ( used when WORKFLOW_BILL_ON_RECEPTION is on )
*
* @ return int < 0 if ko , > 0 if ok
*/
public function setBilled ()
{
2020-10-28 17:49:52 +01:00
global $user ;
2019-11-13 18:32:11 +01:00
$error = 0 ;
2018-10-03 12:22:41 +02:00
$this -> db -> begin ();
2018-12-15 13:58:39 +01:00
2018-10-10 15:33:35 +02:00
$this -> setClosed ();
2018-10-03 12:22:41 +02:00
2018-12-15 13:58:39 +01:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'reception SET billed=1' ;
2021-08-27 23:36:06 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . ' AND fk_statut > 0' ;
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2019-11-13 18:32:11 +01:00
$this -> statut = 2 ;
$this -> billed = 1 ;
2018-10-03 12:22:41 +02:00
// Call trigger
2019-11-13 18:32:11 +01:00
$result = $this -> call_trigger ( 'RECEPTION_BILLED' , $user );
2018-10-03 12:22:41 +02:00
if ( $result < 0 ) {
$error ++ ;
}
} else {
$error ++ ;
2019-11-13 18:32:11 +01:00
$this -> errors [] = $this -> db -> lasterror ;
2018-10-03 12:22:41 +02:00
}
if ( empty ( $error )) {
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Classify the reception as validated / opened
*
* @ return int < 0 if ko , > 0 if ok
*/
2020-10-28 17:49:52 +01:00
public function reOpen ()
2018-10-03 12:22:41 +02:00
{
2019-11-13 18:32:11 +01:00
global $conf , $langs , $user ;
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
$error = 0 ;
2018-10-03 12:22:41 +02:00
$this -> db -> begin ();
2018-10-10 12:19:57 +02:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'reception SET fk_statut=1, billed=0' ;
2021-08-27 23:36:06 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ) . ' AND fk_statut > 0' ;
2018-10-03 12:22:41 +02:00
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2019-11-13 18:32:11 +01:00
$this -> statut = 1 ;
$this -> billed = 0 ;
2018-10-03 12:22:41 +02:00
// If stock increment is done on closing
2021-02-26 20:53:03 +01:00
if ( ! $error && ! empty ( $conf -> stock -> enabled ) && ! empty ( $conf -> global -> STOCK_CALCULATE_ON_RECEPTION_CLOSE )) {
2018-10-03 12:22:41 +02:00
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php' ;
2018-10-10 15:33:35 +02:00
$numref = $this -> ref ;
2018-10-03 12:22:41 +02:00
$langs -> load ( " agenda " );
// Loop on each product line to add a stock movement
2018-10-18 15:11:43 +02:00
// TODO possibilite de receptionner a partir d'une propale ou autre origine
2018-10-10 15:33:35 +02:00
$sql = " SELECT ed.fk_product, cd.subprice, " ;
2019-11-13 18:32:11 +01:00
$sql .= " ed.rowid, ed.qty, ed.fk_entrepot, " ;
2022-06-08 18:27:47 +02:00
$sql .= " ed.eatby, ed.sellby, ed.batch, " ;
$sql .= " ed.cost_price " ;
2019-11-13 18:32:11 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " commande_fournisseurdet as cd, " ;
$sql .= " " . MAIN_DB_PREFIX . " commande_fournisseur_dispatch as ed " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE ed.fk_reception = " . (( int ) $this -> id );
2019-11-13 18:32:11 +01:00
$sql .= " AND cd.rowid = ed.fk_commandefourndet " ;
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid select details " , LOG_DEBUG );
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2018-10-03 12:22:41 +02:00
$cpt = $this -> db -> num_rows ( $resql );
2021-02-26 20:53:03 +01:00
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
2018-10-03 12:22:41 +02:00
$obj = $this -> db -> fetch_object ( $resql );
2018-12-15 13:58:39 +01:00
2018-10-10 15:33:35 +02:00
$qty = $obj -> qty ;
2018-12-15 13:58:39 +01:00
2021-02-26 20:53:03 +01:00
if ( $qty <= 0 ) {
continue ;
}
2018-12-15 13:58:39 +01:00
2018-10-10 15:33:35 +02:00
dol_syslog ( get_class ( $this ) . " ::reopen reception movement index " . $i . " ed.rowid= " . $obj -> rowid );
2018-10-03 12:22:41 +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 );
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( empty ( $obj -> batch )) {
2018-10-03 12:22:41 +02:00
// 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
2021-11-19 13:46:30 +01:00
$inventorycode = '' ;
2022-06-08 18:27:47 +02:00
$result = $mouvS -> livraison ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> cost_price , $langs -> trans ( " ReceptionUnClassifyCloseddInDolibarr " , $numref ), '' , '' , '' , '' , 0 , $inventorycode );
2021-11-19 14:01:31 +01:00
2018-10-03 12:22:41 +02:00
if ( $result < 0 ) {
2020-10-28 17:49:52 +01:00
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
2018-10-03 12:22:41 +02:00
$error ++ ; break ;
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
// 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
2021-11-19 13:46:30 +01:00
$inventorycode = '' ;
2022-12-12 10:44:34 +01:00
$result = $mouvS -> livraison ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> cost_price , $langs -> trans ( " ReceptionUnClassifyCloseddInDolibarr " , $numref ), '' , $this -> db -> jdate ( $obj -> eatby ), $this -> db -> jdate ( $obj -> sellby ), $obj -> batch , $obj -> fk_origin_stock , $inventorycode );
2018-10-03 12:22:41 +02:00
if ( $result < 0 ) {
2020-10-28 17:49:52 +01:00
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
$error ++ ; break ;
2018-10-03 12:22:41 +02:00
}
}
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> lasterror ();
2018-10-03 12:22:41 +02:00
$error ++ ;
}
}
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2020-10-28 17:49:52 +01:00
// Call trigger
$result = $this -> call_trigger ( 'RECEPTION_REOPEN' , $user );
if ( $result < 0 ) {
$error ++ ;
}
2021-02-26 20:53:03 +01:00
}
2018-12-15 13:58:39 +01:00
2021-11-19 14:01:31 +01:00
if ( ! $error && $this -> origin == 'order_supplier' ) {
2018-10-11 10:00:07 +02:00
$commande = new CommandeFournisseur ( $this -> db );
$commande -> fetch ( $this -> origin_id );
2021-11-19 14:01:31 +01:00
$result = $commande -> setStatus ( $user , 4 );
if ( $result < 0 ) {
$error ++ ;
$this -> error = $commande -> error ;
$this -> errors = $commande -> errors ;
}
2018-10-11 10:00:07 +02:00
}
2018-10-03 12:22:41 +02:00
} else {
$error ++ ;
2019-11-13 18:32:11 +01:00
$this -> errors [] = $this -> db -> lasterror ();
2018-10-03 12:22:41 +02:00
}
2021-02-26 20:53:03 +01:00
if ( ! $error ) {
2018-10-03 12:22:41 +02:00
$this -> db -> commit ();
return 1 ;
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
/**
2020-10-28 17:49:52 +01:00
* Set draft status
*
* @ param User $user Object user that modify
* @ return int < 0 if KO , > 0 if OK
*/
public function setDraft ( $user )
{
2018-10-23 14:31:58 +02:00
// phpcs:enable
2020-10-28 17:49:52 +01:00
global $conf , $langs ;
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
$error = 0 ;
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
// Protection
2021-02-26 20:53:03 +01:00
if ( $this -> statut <= self :: STATUS_DRAFT ) {
2020-10-28 17:49:52 +01:00
return 0 ;
}
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
if ( ! (( empty ( $conf -> global -> MAIN_USE_ADVANCED_PERMS ) && ! empty ( $user -> rights -> reception -> creer ))
2021-02-26 20:53:03 +01:00
|| ( ! empty ( $conf -> global -> MAIN_USE_ADVANCED_PERMS ) && ! empty ( $user -> rights -> reception -> reception_advance -> validate )))) {
2020-10-28 17:49:52 +01:00
$this -> error = 'Permission denied' ;
return - 1 ;
}
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
$this -> db -> begin ();
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
$sql = " UPDATE " . MAIN_DB_PREFIX . " reception " ;
$sql .= " SET fk_statut = " . self :: STATUS_DRAFT ;
2021-08-27 16:33:03 +02:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2018-10-03 12:22:41 +02:00
2020-10-28 17:49:52 +01:00
dol_syslog ( __METHOD__ , LOG_DEBUG );
2021-02-26 20:53:03 +01:00
if ( $this -> db -> query ( $sql )) {
2020-10-28 17:49:52 +01:00
// If stock increment is done on closing
2021-02-26 20:53:03 +01:00
if ( ! $error && ! empty ( $conf -> stock -> enabled ) && ! empty ( $conf -> global -> STOCK_CALCULATE_ON_RECEPTION )) {
2018-10-03 12:22:41 +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
2018-10-18 15:11:43 +02:00
// TODO possibilite de receptionner a partir d'une propale ou autre origine
2018-10-03 12:22:41 +02:00
$sql = " SELECT cd.fk_product, cd.subprice, " ;
2019-11-13 18:32:11 +01:00
$sql .= " ed.rowid, ed.qty, ed.fk_entrepot, " ;
2022-06-08 18:27:47 +02:00
$sql .= " ed.eatby, ed.sellby, ed.batch, " ;
$sql .= " ed.cost_price " ;
2019-11-13 18:32:11 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " commande_fournisseurdet as cd, " ;
$sql .= " " . MAIN_DB_PREFIX . " commande_fournisseur_dispatch as ed " ;
2021-08-23 19:33:24 +02:00
$sql .= " WHERE ed.fk_reception = " . (( int ) $this -> id );
2019-11-13 18:32:11 +01:00
$sql .= " AND cd.rowid = ed.fk_commandefourndet " ;
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::valid select details " , LOG_DEBUG );
2019-11-13 18:32:11 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-26 20:53:03 +01:00
if ( $resql ) {
2018-10-03 12:22:41 +02:00
$cpt = $this -> db -> num_rows ( $resql );
2021-02-26 20:53:03 +01:00
for ( $i = 0 ; $i < $cpt ; $i ++ ) {
2018-10-03 12:22:41 +02:00
$obj = $this -> db -> fetch_object ( $resql );
2018-12-15 13:58:39 +01:00
2018-10-09 11:33:41 +02:00
$qty = $obj -> qty ;
2018-12-15 13:58:39 +01:00
2021-02-26 20:53:03 +01:00
if ( $qty <= 0 ) {
continue ;
}
2018-10-03 12:22:41 +02:00
dol_syslog ( get_class ( $this ) . " ::reopen reception movement index " . $i . " ed.rowid= " . $obj -> rowid . " edb.rowid= " . $obj -> edbrowid );
//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 );
2018-10-03 12:22:41 +02:00
2021-02-26 20:53:03 +01:00
if ( empty ( $obj -> batch )) {
2018-10-03 12:22:41 +02:00
// 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
2021-11-19 13:46:30 +01:00
$inventorycode = '' ;
2022-06-08 18:27:47 +02:00
$result = $mouvS -> livraison ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> cost_price , $langs -> trans ( " ReceptionBackToDraftInDolibarr " , $this -> ref ), '' , '' , '' , '' , 0 , $inventorycode );
2018-10-03 12:22:41 +02:00
if ( $result < 0 ) {
2020-10-28 17:49:52 +01:00
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
2018-12-15 16:37:00 +01:00
$error ++ ;
break ;
2018-10-03 12:22:41 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2018-10-03 12:22:41 +02:00
// 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
2021-11-19 13:46:30 +01:00
$inventorycode = '' ;
2022-12-12 10:39:24 +01:00
$result = $mouvS -> livraison ( $user , $obj -> fk_product , $obj -> fk_entrepot , $qty , $obj -> cost_price , $langs -> trans ( " ReceptionBackToDraftInDolibarr " , $this -> ref ), '' , $this -> db -> jdate ( $obj -> eatby ), $this -> db -> jdate ( $obj -> sellby ), $obj -> batch , 0 , $inventorycode );
2018-10-03 12:22:41 +02:00
if ( $result < 0 ) {
2020-10-28 17:49:52 +01:00
$this -> error = $mouvS -> error ;
$this -> errors = $mouvS -> errors ;
$error ++ ; break ;
2018-10-03 12:22:41 +02:00
}
}
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-13 18:32:11 +01:00
$this -> error = $this -> db -> lasterror ();
2018-10-03 12:22:41 +02:00
$error ++ ;
}
}
2018-12-15 13:58:39 +01:00
2020-10-28 17:49:52 +01:00
if ( ! $error ) {
// Call trigger
$result = $this -> call_trigger ( 'RECEPTION_UNVALIDATE' , $user );
2021-02-26 20:53:03 +01:00
if ( $result < 0 ) {
$error ++ ;
}
2020-10-28 17:49:52 +01:00
}
2021-02-26 20:53:03 +01:00
if ( $this -> origin == 'order_supplier' ) {
if ( ! empty ( $this -> origin ) && $this -> origin_id > 0 ) {
2018-10-23 09:22:13 +02:00
$this -> fetch_origin ();
$origin = $this -> origin ;
2021-02-26 20:53:03 +01:00
if ( $this -> $origin -> statut == 4 ) { // If order source of reception is "partially received"
2018-12-15 13:58:39 +01:00
// Check if there is no more reception validated.
2018-10-23 09:22:13 +02:00
$this -> $origin -> fetchObjectLinked ();
$setStatut = 1 ;
2021-02-26 20:53:03 +01:00
if ( ! empty ( $this -> $origin -> linkedObjects [ 'reception' ])) {
foreach ( $this -> $origin -> linkedObjects [ 'reception' ] as $rcption ) {
if ( $rcption -> statut > 0 ) {
2018-10-23 09:22:13 +02:00
$setStatut = 0 ;
break ;
}
}
//var_dump($this->$origin->receptions);exit;
2021-02-26 20:53:03 +01:00
if ( $setStatut ) {
2018-10-23 09:22:13 +02:00
$this -> $origin -> setStatut ( 3 ); // ordered
}
}
}
}
2018-10-03 12:22:41 +02:00
}
2020-10-28 17:49:52 +01:00
if ( ! $error ) {
$this -> statut = self :: STATUS_DRAFT ;
$this -> db -> commit ();
return 1 ;
} else {
$this -> db -> rollback ();
return - 1 ;
}
} else {
$this -> error = $this -> db -> error ();
$this -> db -> rollback ();
return - 1 ;
}
}
2018-10-03 12:22:41 +02:00
/**
* Create a document onto disk according to template module .
*
* @ 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
* @ return int 0 if KO , 1 if OK
*/
2019-01-27 15:20:16 +01:00
public function generateDocument ( $modele , $outputlangs , $hidedetails = 0 , $hidedesc = 0 , $hideref = 0 )
2018-10-03 12:22:41 +02:00
{
2019-11-13 18:32:11 +01:00
global $conf , $langs ;
2018-10-03 12:22:41 +02:00
$langs -> load ( " receptions " );
2021-02-26 20:53:03 +01:00
if ( ! dol_strlen ( $modele )) {
2018-10-08 16:54:33 +02:00
$modele = 'squille' ;
2018-10-03 12:22:41 +02:00
2020-09-10 01:49:09 +02:00
if ( $this -> model_pdf ) {
$modele = $this -> model_pdf ;
2019-11-13 18:32:11 +01:00
} elseif ( ! empty ( $conf -> global -> RECEPTION_ADDON_PDF )) {
2018-10-03 12:22:41 +02:00
$modele = $conf -> global -> RECEPTION_ADDON_PDF ;
}
}
$modelpath = " core/modules/reception/doc/ " ;
$this -> fetch_origin ();
2018-12-15 13:58:39 +01:00
2018-10-03 12:22:41 +02:00
return $this -> commonGenerateDocument ( $modelpath , $modele , $outputlangs , $hidedetails , $hidedesc , $hideref );
}
/**
* Function used to replace a thirdparty id with another one .
*
* @ param DoliDB $db Database handler
* @ param int $origin_id Old thirdparty id
* @ param int $dest_id New thirdparty id
* @ return bool
*/
public static function replaceThirdparty ( DoliDB $db , $origin_id , $dest_id )
{
2018-12-15 15:43:30 +01:00
$tables = array ( 'reception' );
2018-10-03 12:22:41 +02:00
return CommonObject :: commonReplaceThirdparty ( $db , $origin_id , $dest_id , $tables );
}
2021-11-23 22:02:55 +01:00
/**
* Function used to replace a product id with another one .
*
* @ param DoliDB $db Database handler
* @ param int $origin_id Old product id
* @ param int $dest_id New product id
* @ return bool
*/
public static function replaceProduct ( DoliDB $db , $origin_id , $dest_id )
{
$tables = array (
'commande_fournisseur_dispatch'
);
return CommonObject :: commonReplaceProduct ( $db , $origin_id , $dest_id , $tables );
}
2019-02-03 15:21:21 +01:00
}