PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/expedition/class/expedition.class.php

https://github.com/asterix14/dolibarr
PHP | 1203 lines | 868 code | 149 blank | 186 comment | 136 complexity | 0a1b33e713926a7f77439f0de4999940 MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /* Copyright (C) 2003-2008 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2005-2011 Regis Houssin <regis@dolibarr.fr>
  4. * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
  5. * Copyright (C) 2006-2008 Laurent Destailleur <eldy@users.sourceforge.net>
  6. * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * \file htdocs/expedition/class/expedition.class.php
  23. * \ingroup expedition
  24. * \brief Fichier de la classe de gestion des expeditions
  25. */
  26. require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
  27. if ($conf->propal->enabled) require_once(DOL_DOCUMENT_ROOT."/comm/propal/class/propal.class.php");
  28. if ($conf->commande->enabled) require_once(DOL_DOCUMENT_ROOT."/commande/class/commande.class.php");
  29. /**
  30. * \class Expedition
  31. * \brief Class to manage shippings
  32. */
  33. class Expedition extends CommonObject
  34. {
  35. public $element="shipping";
  36. public $fk_element="fk_expedition";
  37. public $table_element="expedition";
  38. var $id;
  39. var $socid;
  40. var $ref_customer;
  41. var $ref_ext;
  42. var $ref_int;
  43. var $brouillon;
  44. var $entrepot_id;
  45. var $modelpdf;
  46. var $origin;
  47. var $origin_id;
  48. var $lines=array();
  49. var $expedition_method_id; // TODO deprecated
  50. var $shipping_method_id;
  51. var $tracking_number;
  52. var $tracking_url;
  53. var $statut;
  54. var $trueWeight;
  55. var $weight_units;
  56. var $trueWidth;
  57. var $width_units;
  58. var $trueHeight;
  59. var $height_units;
  60. var $trueDepth;
  61. var $depth_units;
  62. // A denormalized value
  63. var $trueSize;
  64. var $date_delivery; // Date delivery planed
  65. var $date_expedition; // Date delivery real
  66. var $date_creation;
  67. var $date_valid;
  68. /**
  69. * Constructor
  70. *
  71. * @param DoliDB $DB Database handler
  72. */
  73. function Expedition($DB)
  74. {
  75. $this->db = $DB;
  76. $this->lines = array();
  77. $this->products = array();
  78. // List of long language codes for status
  79. $this->statuts[-1] = 'StatusSendingCanceled';
  80. $this->statuts[0] = 'StatusSendingDraft';
  81. $this->statuts[1] = 'StatusSendingValidated';
  82. }
  83. /**
  84. * Return next contract ref
  85. *
  86. * @param Societe $soc Objet society
  87. * @return string Free reference for contract
  88. */
  89. function getNextNumRef($soc)
  90. {
  91. global $db, $langs, $conf;
  92. $langs->load("sendings");
  93. $dir = DOL_DOCUMENT_ROOT . "/core/modules/expedition";
  94. if (empty($conf->global->EXPEDITION_ADDON_NUMBER))
  95. {
  96. $conf->global->EXPEDITION_ADDON_NUMBER='mod_expedition_safor';
  97. }
  98. $file = $conf->global->EXPEDITION_ADDON_NUMBER.".php";
  99. // Chargement de la classe de numerotation
  100. $classname = $conf->global->EXPEDITION_ADDON_NUMBER;
  101. $result=include_once($dir.'/'.$file);
  102. if ($result)
  103. {
  104. $obj = new $classname();
  105. $numref = "";
  106. $numref = $obj->getNextValue($soc,$this);
  107. if ( $numref != "")
  108. {
  109. return $numref;
  110. }
  111. else
  112. {
  113. dol_print_error($db,"Expedition::getNextNumRef ".$obj->error);
  114. return "";
  115. }
  116. }
  117. else
  118. {
  119. print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined");
  120. return "";
  121. }
  122. }
  123. /**
  124. * Create expedition en base
  125. *
  126. * @param User $user Objet du user qui cree
  127. * @return int <0 si erreur, id expedition creee si ok
  128. */
  129. function create($user)
  130. {
  131. global $conf, $langs;
  132. require_once DOL_DOCUMENT_ROOT ."/product/stock/class/mouvementstock.class.php";
  133. $error = 0;
  134. // Clean parameters
  135. $this->brouillon = 1;
  136. $this->tracking_number = dol_sanitizeFileName($this->tracking_number);
  137. $this->user = $user;
  138. $this->db->begin();
  139. $sql = "INSERT INTO ".MAIN_DB_PREFIX."expedition (";
  140. $sql.= "ref";
  141. $sql.= ", entity";
  142. $sql.= ", ref_customer";
  143. $sql.= ", ref_int";
  144. $sql.= ", date_creation";
  145. $sql.= ", fk_user_author";
  146. $sql.= ", date_expedition";
  147. $sql.= ", date_delivery";
  148. $sql.= ", fk_soc";
  149. $sql.= ", fk_address";
  150. $sql.= ", fk_expedition_methode";
  151. $sql.= ", tracking_number";
  152. $sql.= ", weight";
  153. $sql.= ", size";
  154. $sql.= ", width";
  155. $sql.= ", height";
  156. $sql.= ", weight_units";
  157. $sql.= ", size_units";
  158. $sql.= ") VALUES (";
  159. $sql.= "'(PROV)'";
  160. $sql.= ", ".$conf->entity;
  161. $sql.= ", ".($this->ref_customer?"'".$this->ref_customer."'":"null");
  162. $sql.= ", ".($this->ref_int?"'".$this->ref_int."'":"null");
  163. $sql.= ", '".$this->db->idate(gmmktime())."'";
  164. $sql.= ", ".$user->id;
  165. $sql.= ", ".($this->date_expedition>0?"'".$this->db->idate($this->date_expedition)."'":"null");
  166. $sql.= ", ".($this->date_delivery>0?"'".$this->db->idate($this->date_delivery)."'":"null");
  167. $sql.= ", ".$this->socid;
  168. $sql.= ", ".($this->fk_delivery_address>0?$this->fk_delivery_address:"null");
  169. $sql.= ", ".($this->expedition_method_id>0?$this->expedition_method_id:"null");
  170. $sql.= ", '".$this->db->escape($this->tracking_number)."'";
  171. $sql.= ", ".$this->weight;
  172. $sql.= ", ".$this->sizeS; // TODO Should use this->trueDepth
  173. $sql.= ", ".$this->sizeW; // TODO Should use this->trueWidth
  174. $sql.= ", ".$this->sizeH; // TODO Should use this->trueHeight
  175. $sql.= ", ".$this->weight_units;
  176. $sql.= ", ".$this->size_units;
  177. $sql.= ")";
  178. $resql=$this->db->query($sql);
  179. if ($resql)
  180. {
  181. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."expedition");
  182. $sql = "UPDATE ".MAIN_DB_PREFIX."expedition";
  183. $sql.= " SET ref = '(PROV".$this->id.")'";
  184. $sql.= " WHERE rowid = ".$this->id;
  185. dol_syslog("Expedition::create sql=".$sql, LOG_DEBUG);
  186. if ($this->db->query($sql))
  187. {
  188. // Insertion des lignes
  189. $num=count($this->lines);
  190. for ($i = 0; $i < $num; $i++)
  191. {
  192. if (! $this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty) > 0)
  193. {
  194. $error++;
  195. }
  196. }
  197. if (! $error && $this->id && $this->origin_id)
  198. {
  199. $ret = $this->add_object_linked();
  200. if (!$ret)
  201. {
  202. $error++;
  203. }
  204. // TODO uniformiser les statuts
  205. $ret = $this->setStatut(2,$this->origin_id,$this->origin);
  206. if (! $ret)
  207. {
  208. $error++;
  209. }
  210. }
  211. if (! $error)
  212. {
  213. // Appel des triggers
  214. include_once(DOL_DOCUMENT_ROOT."/core/class/interfaces.class.php");
  215. $interface=new Interfaces($this->db);
  216. $result=$interface->run_triggers('SHIPPING_CREATE',$this,$user,$langs,$conf);
  217. if ($result < 0) { $error++; $this->errors=$interface->errors; }
  218. // Fin appel triggers
  219. $this->db->commit();
  220. return $this->id;
  221. }
  222. else
  223. {
  224. $error++;
  225. $this->error=$this->db->lasterror()." - sql=$sql";
  226. $this->db->rollback();
  227. return -3;
  228. }
  229. }
  230. else
  231. {
  232. $error++;
  233. $this->error=$this->db->lasterror()." - sql=$sql";
  234. $this->db->rollback();
  235. return -2;
  236. }
  237. }
  238. else
  239. {
  240. $error++;
  241. $this->error=$this->db->error()." - sql=$sql";
  242. $this->db->rollback();
  243. return -1;
  244. }
  245. }
  246. /**
  247. *
  248. *
  249. */
  250. function create_line($entrepot_id, $origin_line_id, $qty)
  251. {
  252. $error = 0;
  253. $sql = "INSERT INTO ".MAIN_DB_PREFIX."expeditiondet (";
  254. $sql.= "fk_expedition";
  255. $sql.= ", fk_entrepot";
  256. $sql.= ", fk_origin_line";
  257. $sql.= ", qty";
  258. $sql.= ") VALUES (";
  259. $sql.= $this->id;
  260. $sql.= ", ".($entrepot_id?$entrepot_id:'null');
  261. $sql.= ", ".$origin_line_id;
  262. $sql.= ", ".$qty;
  263. $sql.= ")";
  264. if (! $this->db->query($sql))
  265. {
  266. $error++;
  267. }
  268. if (! $error) return 1;
  269. else return -1;
  270. }
  271. /**
  272. * Get object and lines from database
  273. *
  274. * @param int $id Id of object to load
  275. * @param string $ref Ref of object
  276. * @param string $ref_ext External reference of object
  277. * @param string $ref_int Internal reference of other object
  278. * @return int >0 if OK, <0 if KO
  279. */
  280. function fetch($id, $ref='', $ref_ext='', $ref_int='')
  281. {
  282. global $conf;
  283. // Check parameters
  284. if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1;
  285. $sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut";
  286. $sql.= ", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height";
  287. $sql.= ", e.date_expedition as date_expedition, e.model_pdf, e.fk_address, e.date_delivery";
  288. $sql.= ", e.fk_expedition_methode, e.tracking_number";
  289. $sql.= ", el.fk_source as origin_id, el.sourcetype as origin";
  290. $sql.= " FROM ".MAIN_DB_PREFIX."expedition as e";
  291. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->element."'";
  292. $sql.= " WHERE e.entity = ".$conf->entity;
  293. if ($id) $sql.= " AND e.rowid=".$id;
  294. if ($ref) $sql.= " AND e.ref='".$this->db->escape($ref)."'";
  295. if ($ref_ext) $sql.= " AND e.ref_ext='".$this->db->escape($ref_ext)."'";
  296. if ($ref_int) $sql.= " AND e.ref_int='".$this->db->escape($ref_int)."'";
  297. dol_syslog("Expedition::fetch sql=".$sql);
  298. $result = $this->db->query($sql);
  299. if ($result)
  300. {
  301. if ($this->db->num_rows($result))
  302. {
  303. $obj = $this->db->fetch_object($result);
  304. $this->id = $obj->rowid;
  305. $this->ref = $obj->ref;
  306. $this->socid = $obj->socid;
  307. $this->ref_customer = $obj->ref_customer;
  308. $this->ref_ext = $obj->ref_ext;
  309. $this->ref_int = $obj->ref_int;
  310. $this->statut = $obj->fk_statut;
  311. $this->user_author_id = $obj->fk_user_author;
  312. $this->date_creation = $this->db->jdate($obj->date_creation);
  313. $this->date = $this->db->jdate($obj->date_expedition); // TODO obsolete
  314. $this->date_expedition = $this->db->jdate($obj->date_expedition); // TODO obsolete
  315. $this->date_shipping = $this->db->jdate($obj->date_expedition); // Date real
  316. $this->date_delivery = $this->db->jdate($obj->date_delivery); // Date planed
  317. $this->fk_delivery_address = $obj->fk_address;
  318. $this->modelpdf = $obj->model_pdf;
  319. $this->expedition_method_id = $obj->fk_expedition_methode; // TODO deprecated
  320. $this->shipping_method_id = $obj->fk_expedition_methode;
  321. $this->tracking_number = $obj->tracking_number;
  322. $this->origin = ($obj->origin?$obj->origin:'commande'); // For compatibility
  323. $this->origin_id = $obj->origin_id;
  324. $this->trueWeight = $obj->weight;
  325. $this->weight_units = $obj->weight_units;
  326. $this->trueWidth = $obj->width;
  327. $this->width_units = $obj->size_units;
  328. $this->trueHeight = $obj->height;
  329. $this->height_units = $obj->size_units;
  330. $this->trueDepth = $obj->size;
  331. $this->depth_units = $obj->size_units;
  332. // A denormalized value
  333. $this->trueSize = $obj->size."x".$obj->width."x".$obj->height;
  334. $this->size_units = $obj->size_units;
  335. $this->db->free($result);
  336. if ($this->statut == 0) $this->brouillon = 1;
  337. $file = $conf->expedition->dir_output . "/" .get_exdir($expedition->id,2) . "/" . $this->id.".pdf";
  338. $this->pdf_filename = $file;
  339. // Tracking url
  340. $this->GetUrlTrackingStatus($obj->tracking_number);
  341. /*
  342. * Lines
  343. */
  344. $result=$this->fetch_lines();
  345. if ($result < 0)
  346. {
  347. return -3;
  348. }
  349. return 1;
  350. }
  351. else
  352. {
  353. dol_syslog('Expedition::Fetch Error rowid='.$rowid.' numrows=0 sql='.$sql);
  354. $this->error='Delivery with id '.$rowid.' not found sql='.$sql;
  355. return -2;
  356. }
  357. }
  358. else
  359. {
  360. dol_syslog('Expedition::Fetch Error rowid='.$rowid.' Erreur dans fetch de l\'expedition');
  361. $this->error=$this->db->error();
  362. return -1;
  363. }
  364. }
  365. /**
  366. * Validate object and update stock if option enabled
  367. *
  368. * @param User $user Object user that validate
  369. * @return int <0 if OK, >0 if KO
  370. */
  371. function valid($user)
  372. {
  373. global $conf, $langs;
  374. require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
  375. dol_syslog("Expedition::valid");
  376. // Protection
  377. if ($this->statut)
  378. {
  379. dol_syslog("Expedition::valid no draft status", LOG_WARNING);
  380. return 0;
  381. }
  382. if (! $user->rights->expedition->valider)
  383. {
  384. $this->error='Permission denied';
  385. dol_syslog("Expedition::valid ".$this->error, LOG_ERR);
  386. return -1;
  387. }
  388. $this->db->begin();
  389. $error = 0;
  390. // Define new ref
  391. $soc = new Societe($this->db);
  392. $soc->fetch($this->socid);
  393. // Class of company linked to order
  394. $result=$soc->set_as_client();
  395. // Define new ref
  396. if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref)))
  397. {
  398. $numref = $this->getNextNumRef($soc);
  399. }
  400. else
  401. {
  402. $numref = "EXP".$this->id;
  403. }
  404. $now=dol_now();
  405. // Validate
  406. $sql = "UPDATE ".MAIN_DB_PREFIX."expedition SET";
  407. $sql.= " ref='".$numref."'";
  408. $sql.= ", fk_statut = 1";
  409. $sql.= ", date_valid = '".$this->db->idate($now)."'";
  410. $sql.= ", fk_user_valid = ".$user->id;
  411. $sql.= " WHERE rowid = ".$this->id;
  412. dol_syslog("Expedition::valid update expedition sql=".$sql);
  413. $resql=$this->db->query($sql);
  414. if (! $resql)
  415. {
  416. dol_syslog("Expedition::valid Echec update - 10 - sql=".$sql, LOG_ERR);
  417. $this->error=$this->db->lasterror();
  418. $error++;
  419. }
  420. // If stock increment is done on sending (recommanded choice)
  421. if (! $error && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT)
  422. {
  423. require_once DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php";
  424. $langs->load("agenda");
  425. // Loop on each product line to add a stock movement
  426. // TODO possibilite d'expedier a partir d'une propale ou autre origine
  427. $sql = "SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot";
  428. $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,";
  429. $sql.= " ".MAIN_DB_PREFIX."expeditiondet as ed";
  430. $sql.= " WHERE ed.fk_expedition = ".$this->id;
  431. $sql.= " AND cd.rowid = ed.fk_origin_line";
  432. dol_syslog("Expedition::valid select details sql=".$sql);
  433. $resql=$this->db->query($sql);
  434. if ($resql)
  435. {
  436. $cpt = $this->db->num_rows($resql);
  437. for ($i = 0; $i < $cpt; $i++)
  438. {
  439. dol_syslog("Expedition::valid movement index ".$i);
  440. $obj = $this->db->fetch_object($resql);
  441. //var_dump($this->lines[$i]);
  442. $mouvS = new MouvementStock($this->db);
  443. // We decrement stock of product (and sub-products)
  444. // We use warehouse selected for each line
  445. $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref));
  446. if ($result < 0) { $error++; break; }
  447. $i++;
  448. }
  449. }
  450. else
  451. {
  452. $this->db->rollback();
  453. $this->error=$this->db->error();
  454. dol_syslog("Expedition::valid ".$this->error, LOG_ERR);
  455. return -2;
  456. }
  457. }
  458. if (! $error)
  459. {
  460. // On efface le repertoire de pdf provisoire
  461. $expeditionref = dol_sanitizeFileName($this->ref);
  462. if ($conf->expedition->dir_output)
  463. {
  464. $dir = $conf->expedition->dir_output . "/" . $expeditionref;
  465. $file = $dir . "/" . $expeditionref . ".pdf";
  466. if (file_exists($file))
  467. {
  468. if (!dol_delete_file($file))
  469. {
  470. $this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
  471. }
  472. }
  473. if (file_exists($dir))
  474. {
  475. if (!dol_delete_dir($dir))
  476. {
  477. $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
  478. }
  479. }
  480. }
  481. }
  482. // Set new ref and current status
  483. if (! $error)
  484. {
  485. $this->ref = $numref;
  486. $this->statut = 1;
  487. }
  488. if (! $error)
  489. {
  490. // Appel des triggers
  491. include_once(DOL_DOCUMENT_ROOT."/core/class/interfaces.class.php");
  492. $interface=new Interfaces($this->db);
  493. $result=$interface->run_triggers('SHIPPING_VALIDATE',$this,$user,$langs,$conf);
  494. if ($result < 0) { $error++; $this->errors=$interface->errors; }
  495. // Fin appel triggers
  496. }
  497. if (! $error)
  498. {
  499. $this->db->commit();
  500. return 1;
  501. }
  502. else
  503. {
  504. foreach($this->errors as $errmsg)
  505. {
  506. dol_syslog(get_class($this)."::valid ".$errmsg, LOG_ERR);
  507. $this->error.=($this->error?', '.$errmsg:$errmsg);
  508. }
  509. $this->db->rollback();
  510. return -1*$error;
  511. }
  512. }
  513. /**
  514. * Cree un bon de livraison a partir de l'expedition
  515. *
  516. * @param User $user Utilisateur
  517. * @return int <0 if KO, >=0 if OK
  518. */
  519. function create_delivery($user)
  520. {
  521. global $conf;
  522. if ($conf->livraison_bon->enabled)
  523. {
  524. if ($this->statut == 1)
  525. {
  526. // Expedition validee
  527. include_once(DOL_DOCUMENT_ROOT."/livraison/class/livraison.class.php");
  528. $delivery = new Livraison($this->db);
  529. $result=$delivery->create_from_sending($user, $this->id);
  530. if ($result > 0)
  531. {
  532. return $result;
  533. }
  534. else
  535. {
  536. $this->error=$delivery->error;
  537. return $result;
  538. }
  539. }
  540. else return 0;
  541. }
  542. else return 0;
  543. }
  544. /**
  545. * Ajoute une ligne
  546. *
  547. */
  548. function addline( $entrepot_id, $id, $qty )
  549. {
  550. $num = count($this->lines);
  551. $line = new ExpeditionLigne($this->db);
  552. $line->entrepot_id = $entrepot_id;
  553. $line->origin_line_id = $id;
  554. $line->qty = $qty;
  555. $this->lines[$num] = $line;
  556. }
  557. /**
  558. *
  559. *
  560. */
  561. function deleteline($lineid)
  562. {
  563. if ($this->statut == 0)
  564. {
  565. $sql = "DELETE FROM ".MAIN_DB_PREFIX."commandedet";
  566. $sql.= " WHERE rowid = ".$lineid;
  567. if ($this->db->query($sql) )
  568. {
  569. $this->update_price();
  570. return 1;
  571. }
  572. else
  573. {
  574. return 0;
  575. }
  576. }
  577. }
  578. /**
  579. * Update database
  580. *
  581. * @param User $user User that modify
  582. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  583. * @return int <0 if KO, >0 if OK
  584. */
  585. function update($user=0, $notrigger=0)
  586. {
  587. global $conf, $langs;
  588. $error=0;
  589. // Clean parameters
  590. if (isset($this->ref)) $this->ref=trim($this->ref);
  591. if (isset($this->entity)) $this->entity=trim($this->entity);
  592. if (isset($this->ref_customer)) $this->ref_customer=trim($this->ref_customer);
  593. if (isset($this->socid)) $this->socid=trim($this->socid);
  594. if (isset($this->fk_user_author)) $this->fk_user_author=trim($this->fk_user_author);
  595. if (isset($this->fk_user_valid)) $this->fk_user_valid=trim($this->fk_user_valid);
  596. if (isset($this->fk_adresse_livraison)) $this->fk_adresse_livraison=trim($this->fk_adresse_livraison);
  597. if (isset($this->expedition_method_id)) $this->expedition_method_id=trim($this->expedition_method_id);
  598. if (isset($this->tracking_number)) $this->tracking_number=trim($this->tracking_number);
  599. if (isset($this->statut)) $this->statut=trim($this->statut);
  600. if (isset($this->trueDepth)) $this->trueDepth=trim($this->trueDepth);
  601. if (isset($this->trueWidth)) $this->trueWidth=trim($this->trueWidth);
  602. if (isset($this->trueHeight)) $this->trueHeight=trim($this->trueHeight);
  603. if (isset($this->size_units)) $this->size_units=trim($this->size_units);
  604. if (isset($this->weight_units)) $this->weight_units=trim($this->weight_units);
  605. if (isset($this->trueWeight)) $this->weight=trim($this->trueWeight);
  606. if (isset($this->note)) $this->note=trim($this->note);
  607. if (isset($this->model_pdf)) $this->model_pdf=trim($this->model_pdf);
  608. // Check parameters
  609. // Put here code to add control on parameters values
  610. // Update request
  611. $sql = "UPDATE ".MAIN_DB_PREFIX."expedition SET";
  612. $sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
  613. $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").",";
  614. $sql.= " ref_customer=".(isset($this->ref_customer)?"'".$this->db->escape($this->ref_customer)."'":"null").",";
  615. $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").",";
  616. $sql.= " date_creation=".(dol_strlen($this->date_creation)!=0 ? "'".$this->db->idate($this->date_creation)."'" : 'null').",";
  617. $sql.= " fk_user_author=".(isset($this->fk_user_author)?$this->fk_user_author:"null").",";
  618. $sql.= " date_valid=".(dol_strlen($this->date_valid)!=0 ? "'".$this->db->idate($this->date_valid)."'" : 'null').",";
  619. $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").",";
  620. $sql.= " date_expedition=".(dol_strlen($this->date_expedition)!=0 ? "'".$this->db->idate($this->date_expedition)."'" : 'null').",";
  621. $sql.= " date_delivery=".(dol_strlen($this->date_delivery)!=0 ? "'".$this->db->idate($this->date_delivery)."'" : 'null').",";
  622. $sql.= " fk_address=".(isset($this->fk_adresse_livraison)?$this->fk_adresse_livraison:"null").",";
  623. $sql.= " fk_expedition_methode=".((isset($this->expedition_method_id) && $this->expedition_method_id > 0)?$this->expedition_method_id:"null").",";
  624. $sql.= " tracking_number=".(isset($this->tracking_number)?"'".$this->db->escape($this->tracking_number)."'":"null").",";
  625. $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").",";
  626. $sql.= " height=".(isset($this->trueHeight)?$this->trueHeight:"null").",";
  627. $sql.= " width=".(isset($this->trueWidth)?$this->trueWidth:"null").",";
  628. $sql.= " size_units=".(isset($this->size_units)?$this->size_units:"null").",";
  629. $sql.= " size=".(isset($this->trueDepth)?$this->trueDepth:"null").",";
  630. $sql.= " weight_units=".(isset($this->weight_units)?$this->weight_units:"null").",";
  631. $sql.= " weight=".(isset($this->trueWeight)?$this->trueWeight:"null").",";
  632. $sql.= " note=".(isset($this->note)?"'".$this->db->escape($this->note)."'":"null").",";
  633. $sql.= " model_pdf=".(isset($this->model_pdf)?"'".$this->db->escape($this->model_pdf)."'":"null").",";
  634. $sql.= " entity=".$conf->entity;
  635. $sql.= " WHERE rowid=".$this->id;
  636. $this->db->begin();
  637. dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
  638. $resql = $this->db->query($sql);
  639. if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
  640. if (! $error)
  641. {
  642. if (! $notrigger)
  643. {
  644. // Call triggers
  645. include_once(DOL_DOCUMENT_ROOT."/core/class/interfaces.class.php");
  646. $interface=new Interfaces($this->db);
  647. $result=$interface->run_triggers('SHIPPING_MODIFY',$this,$user,$langs,$conf);
  648. if ($result < 0) { $error++; $this->errors=$interface->errors; }
  649. // End call triggers
  650. }
  651. }
  652. // Commit or rollback
  653. if ($error)
  654. {
  655. foreach($this->errors as $errmsg)
  656. {
  657. dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
  658. $this->error.=($this->error?', '.$errmsg:$errmsg);
  659. }
  660. $this->db->rollback();
  661. return -1*$error;
  662. }
  663. else
  664. {
  665. $this->db->commit();
  666. return 1;
  667. }
  668. }
  669. /**
  670. * Delete shipping
  671. *
  672. * @return void
  673. */
  674. function delete()
  675. {
  676. global $conf, $langs, $user;
  677. require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
  678. $this->db->begin();
  679. $sql = "DELETE FROM ".MAIN_DB_PREFIX."expeditiondet";
  680. $sql.= " WHERE fk_expedition = ".$this->id;
  681. if ( $this->db->query($sql) )
  682. {
  683. $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_element";
  684. $sql.= " WHERE fk_target = ".$this->id;
  685. $sql.= " AND targettype = '".$this->element."'";
  686. if ( $this->db->query($sql) )
  687. {
  688. $sql = "DELETE FROM ".MAIN_DB_PREFIX."expedition";
  689. $sql.= " WHERE rowid = ".$this->id;
  690. if ( $this->db->query($sql) )
  691. {
  692. $this->db->commit();
  693. // On efface le repertoire de pdf provisoire
  694. $expref = dol_sanitizeFileName($this->ref);
  695. if ($conf->expedition->dir_output)
  696. {
  697. $dir = $conf->expedition->dir_output . "/" . $expref ;
  698. $file = $conf->expedition->dir_output . "/" . $expref . "/" . $expref . ".pdf";
  699. if (file_exists($file))
  700. {
  701. if (!dol_delete_file($file))
  702. {
  703. $this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
  704. return 0;
  705. }
  706. }
  707. if (file_exists($dir))
  708. {
  709. if (!dol_delete_dir($dir))
  710. {
  711. $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
  712. return 0;
  713. }
  714. }
  715. }
  716. // Call triggers
  717. include_once(DOL_DOCUMENT_ROOT."/core/class/interfaces.class.php");
  718. $interface=new Interfaces($this->db);
  719. $result=$interface->run_triggers('SHIPPING_DELETE',$this,$user,$langs,$conf);
  720. if ($result < 0) { $error++; $this->errors=$interface->errors; }
  721. // End call triggers
  722. // TODO il faut incrementer le stock si on supprime une expedition validee
  723. return 1;
  724. }
  725. else
  726. {
  727. $this->error=$this->db->lasterror()." - sql=$sql";
  728. $this->db->rollback();
  729. return -3;
  730. }
  731. }
  732. else
  733. {
  734. $this->error=$this->db->lasterror()." - sql=$sql";
  735. $this->db->rollback();
  736. return -2;
  737. }
  738. }
  739. else
  740. {
  741. $this->error=$this->db->lasterror()." - sql=$sql";
  742. $this->db->rollback();
  743. return -1;
  744. }
  745. }
  746. /**
  747. * Load lines
  748. *
  749. * @return void
  750. */
  751. function fetch_lines()
  752. {
  753. // TODO: recuperer les champs du document associe a part
  754. $sql = "SELECT cd.rowid, cd.fk_product, cd.description, cd.qty as qty_asked";
  755. $sql.= ", ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot";
  756. $sql.= ", p.ref as product_ref, p.fk_product_type, p.label, p.weight, p.weight_units, p.volume, p.volume_units";
  757. $sql.= " FROM (".MAIN_DB_PREFIX."expeditiondet as ed,";
  758. $sql.= " ".MAIN_DB_PREFIX."commandedet as cd)";
  759. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = cd.fk_product";
  760. $sql.= " WHERE ed.fk_expedition = ".$this->id;
  761. $sql.= " AND ed.fk_origin_line = cd.rowid";
  762. dol_syslog("Expedition::fetch_lines sql=".$sql);
  763. $resql = $this->db->query($sql);
  764. if ($resql)
  765. {
  766. $num = $this->db->num_rows($resql);
  767. $i = 0;
  768. while ($i < $num)
  769. {
  770. $line = new ExpeditionLigne($this->db);
  771. $obj = $this->db->fetch_object($resql);
  772. $line->fk_origin_line = $obj->fk_origin_line;
  773. $line->origin_line_id = $obj->fk_origin_line; // TODO deprecated
  774. $line->entrepot_id = $obj->fk_entrepot;
  775. $line->fk_product = $obj->fk_product;
  776. $line->fk_product_type = $obj->fk_product_type;
  777. $line->ref = $obj->product_ref; // TODO deprecated
  778. $line->product_ref = $obj->product_ref;
  779. $line->label = $obj->label;
  780. $line->libelle = $obj->label; // TODO deprecated
  781. $line->description = $obj->description;
  782. $line->qty_asked = $obj->qty_asked;
  783. $line->qty_shipped = $obj->qty_shipped;
  784. $line->weight = $obj->weight;
  785. $line->weight_units = $obj->weight_units;
  786. $line->volume = $obj->volume;
  787. $line->volume_units = $obj->volume_units;
  788. $this->lines[$i] = $line;
  789. $i++;
  790. }
  791. $this->db->free($resql);
  792. return 1;
  793. }
  794. else
  795. {
  796. $this->error=$this->db->error();
  797. dol_syslog('Expedition::fetch_lines: Error '.$this->error, LOG_ERR);
  798. return -3;
  799. }
  800. }
  801. /**
  802. * Renvoie nom clicable (avec eventuellement le picto)
  803. *
  804. * @param int $withpicto 0=Pas de picto, 1=Inclut le picto dans le lien, 2=Picto seul
  805. * @return string Chaine avec URL
  806. */
  807. function getNomUrl($withpicto=0,$option=0,$max=0,$short=0)
  808. {
  809. global $langs;
  810. $result='';
  811. $url = DOL_URL_ROOT.'/expedition/fiche.php?id='.$this->id;
  812. if ($short) return $url;
  813. $linkstart = '<a href="'.$url.'">';
  814. $linkend='</a>';
  815. $picto='sending';
  816. $label=$langs->trans("ShowSending").': '.$this->ref;
  817. if ($withpicto) $result.=($linkstart.img_object($label,$picto).$linkend);
  818. if ($withpicto && $withpicto != 2) $result.=' ';
  819. $result.=$linkstart.$this->ref.$linkend;
  820. return $result;
  821. }
  822. /**
  823. * Retourne le libelle du statut d'une expedition
  824. *
  825. * @return string Libelle
  826. */
  827. function getLibStatut($mode=0)
  828. {
  829. return $this->LibStatut($this->statut,$mode);
  830. }
  831. /**
  832. * Return label of a status
  833. *
  834. * @param int $statut Id statut
  835. * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto
  836. * @return string Label of status
  837. */
  838. function LibStatut($statut,$mode)
  839. {
  840. global $langs;
  841. if ($mode==0)
  842. {
  843. if ($statut==0) return $langs->trans($this->statuts[$statut]);
  844. if ($statut==1) return $langs->trans($this->statuts[$statut]);
  845. }
  846. if ($mode==1)
  847. {
  848. if ($statut==0) return $langs->trans('StatusSendingDraftShort');
  849. if ($statut==1) return $langs->trans('StatusSendingValidatedShort');
  850. }
  851. if ($mode == 3)
  852. {
  853. if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0');
  854. if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4');
  855. }
  856. if ($mode == 4)
  857. {
  858. if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
  859. if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
  860. }
  861. if ($mode == 5)
  862. {
  863. if ($statut==0) return $langs->trans('StatusSendingDraftShort').' '.img_picto($langs->trans($this->statuts[$statut]),'statut0');
  864. if ($statut==1) return $langs->trans('StatusSendingValidatedShort').' '.img_picto($langs->trans($this->statuts[$statut]),'statut4');
  865. }
  866. }
  867. /**
  868. * Initialise an instance with random values.
  869. * Used to build previews or test instances.
  870. * id must be 0 if object instance is a specimen.
  871. *
  872. * @return void
  873. */
  874. function initAsSpecimen()
  875. {
  876. global $user,$langs,$conf;
  877. $now=dol_now();
  878. dol_syslog("Expedition::initAsSpecimen");
  879. // Charge tableau des produits prodids
  880. $prodids = array();
  881. $sql = "SELECT rowid";
  882. $sql.= " FROM ".MAIN_DB_PREFIX."product";
  883. $sql.= " WHERE entity = ".$conf->entity;
  884. $resql = $this->db->query($sql);
  885. if ($resql)
  886. {
  887. $num_prods = $this->db->num_rows($resql);
  888. $i = 0;
  889. while ($i < $num_prods)
  890. {
  891. $i++;
  892. $row = $this->db->fetch_row($resql);
  893. $prodids[$i] = $row[0];
  894. }
  895. }
  896. $order=new Commande($this->db);
  897. $order->initAsSpecimen();
  898. // Initialise parametres
  899. $this->id=0;
  900. $this->ref = 'SPECIMEN_SHIP';
  901. $this->specimen=1;
  902. $this->statut = 1;
  903. $this->livraison_id = 0;
  904. $this->date = $now;
  905. $this->date_creation = $now;
  906. $this->date_valid = $now;
  907. $this->date_delivery = $now;
  908. $this->date_expedition = $now + 24*3600;
  909. $this->entrepot_id = 0;
  910. $this->fk_delivery_address = 0;
  911. $this->socid = 1;
  912. $this->commande_id = 0;
  913. $this->commande = $order;
  914. $this->origin_id = 1;
  915. $this->origin = 'commande';
  916. $nbp = 5;
  917. $xnbp = 0;
  918. while ($xnbp < $nbp)
  919. {
  920. $line=new ExpeditionLigne($this->db);
  921. $line->desc=$langs->trans("Description")." ".$xnbp;
  922. $line->libelle=$langs->trans("Description")." ".$xnbp;
  923. $line->qty=10;
  924. $line->qty_asked=5;
  925. $line->qty_shipped=4;
  926. $line->fk_product=$this->commande->lines[$xnbp]->fk_product;
  927. $this->lines[]=$line;
  928. $xnbp++;
  929. }
  930. }
  931. /**
  932. * Set the planned delivery date
  933. *
  934. * @param user Objet utilisateur qui modifie
  935. * @param date_livraison Date de livraison
  936. * @return int <0 si ko, >0 si ok
  937. */
  938. function set_date_livraison($user, $date_livraison)
  939. {
  940. if ($user->rights->expedition->creer)
  941. {
  942. $sql = "UPDATE ".MAIN_DB_PREFIX."expedition";
  943. $sql.= " SET date_delivery = ".($date_livraison ? "'".$this->db->idate($date_livraison)."'" : 'null');
  944. $sql.= " WHERE rowid = ".$this->id;
  945. dol_syslog("Expedition::set_date_livraison sql=".$sql,LOG_DEBUG);
  946. $resql=$this->db->query($sql);
  947. if ($resql)
  948. {
  949. $this->date_delivery = $date_livraison;
  950. return 1;
  951. }
  952. else
  953. {
  954. $this->error=$this->db->error();
  955. dol_syslog("Commande::set_date_livraison ".$this->error,LOG_ERR);
  956. return -1;
  957. }
  958. }
  959. else
  960. {
  961. return -2;
  962. }
  963. }
  964. /**
  965. * Fetch deliveries method and return an array. Load array this->meths(rowid=>label).
  966. *
  967. * @return void
  968. */
  969. function fetch_delivery_methods()
  970. {
  971. global $langs;
  972. $meths = array();
  973. $sql = "SELECT em.rowid, em.code, em.libelle";
  974. $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em";
  975. $sql.= " WHERE em.active = 1";
  976. $sql.= " ORDER BY em.libelle ASC";
  977. $resql = $this->db->query($sql);
  978. if ($resql)
  979. {
  980. while ($obj = $this->db->fetch_object($resql))
  981. {
  982. $label=$langs->trans('SendingMethod'.$obj->code);
  983. $this->meths[$obj->rowid] = ($label != 'SendingMethod'.$obj->code?$label:$obj->libelle);
  984. }
  985. }
  986. }
  987. /**
  988. * Get tracking url status
  989. *
  990. * @return void
  991. */
  992. function GetUrlTrackingStatus($value='')
  993. {
  994. $code='';
  995. if (! empty($this->expedition_method_id))
  996. {
  997. $sql = "SELECT em.code";
  998. $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em";
  999. $sql.= " WHERE em.rowid = ".$this->expedition_method_id;
  1000. $resql = $this->db->query($sql);
  1001. if ($resql)
  1002. {
  1003. if ($obj = $this->db->fetch_object($resql))
  1004. {
  1005. $code = $obj->code;
  1006. }
  1007. }
  1008. }
  1009. if ($code)
  1010. {
  1011. $classname = "methode_expedition_".strtolower($code);
  1012. $url='';
  1013. if (file_exists(DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($code).".modules.php") && ! empty($this->tracking_number))
  1014. {
  1015. require_once(DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($code).".modules.php");
  1016. $shipmethod = new $classname();
  1017. $url = $shipmethod->provider_url_status($this->tracking_number);
  1018. }
  1019. if ($url)
  1020. {
  1021. $this->tracking_url = sprintf('<a target="_blank" href="%s">'.($value?$value:'url').'</a>',$url,$url);
  1022. }
  1023. else
  1024. {
  1025. $this->tracking_url = $value;
  1026. }
  1027. }
  1028. else
  1029. {
  1030. $this->tracking_url = $value;
  1031. }
  1032. }
  1033. }
  1034. /**
  1035. * Classe de gestion des lignes de bons d'expedition
  1036. */
  1037. class ExpeditionLigne
  1038. {
  1039. var $db;
  1040. // From llx_expeditiondet
  1041. var $qty;
  1042. var $qty_shipped;
  1043. var $fk_product;
  1044. // From llx_commandedet or llx_propaldet
  1045. var $qty_asked;
  1046. var $libelle; // Label produit
  1047. var $product_desc; // Description produit
  1048. var $ref;
  1049. function ExpeditionLigne($DB)
  1050. {
  1051. $this->db=$DB;
  1052. }
  1053. }
  1054. ?>