37 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonorder.class.php';
38 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.product.class.php';
39 require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
41 require_once DOL_DOCUMENT_ROOT.
'/product/class/productbatch.class.php';
53 public $element =
'order_supplier';
58 public $table_element =
'commande_fournisseur';
63 public $table_element_line =
'commande_fournisseurdet';
68 public $fk_element =
'fk_commande';
73 public $picto =
'supplier_order';
79 public $ismultientitymanaged = 1;
85 public $restrictiononfksoc = 1;
103 public $ref_supplier;
117 public $date_creation;
119 public $date_approve;
120 public $date_approve2;
121 public $date_commande;
127 public $date_livraison;
132 public $delivery_date;
136 public $total_localtax1;
137 public $total_localtax2;
146 public $cond_reglement_id;
147 public $cond_reglement_code;
148 public $cond_reglement_label;
149 public $cond_reglement_doc;
156 public $mode_reglement_id;
157 public $mode_reglement_code;
158 public $user_author_id;
159 public $user_valid_id;
160 public $user_approve_id;
161 public $user_approve_id2;
165 public $extraparams = array();
170 public $lines = array();
175 public $linked_objects = array();
181 public $fk_multicurrency;
183 public $multicurrency_code;
184 public $multicurrency_tx;
185 public $multicurrency_total_ht;
186 public $multicurrency_total_tva;
187 public $multicurrency_total_ttc;
218 'rowid' =>array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>1,
'visible'=>0,
'notnull'=>1,
'position'=>10),
219 'ref' =>array(
'type'=>
'varchar(255)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>1,
'showoncombobox'=>1,
'position'=>25,
'searchall'=>1),
220 'ref_ext' =>array(
'type'=>
'varchar(255)',
'label'=>
'Ref ext',
'enabled'=>1,
'visible'=>0,
'position'=>35),
221 'ref_supplier' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefOrderSupplierShort',
'enabled'=>1,
'visible'=>1,
'position'=>40,
'searchall'=>1),
222 'fk_projet' =>array(
'type'=>
'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)',
'label'=>
'Project',
'enabled'=>
"isModEnabled('project')",
'visible'=>-1,
'position'=>45),
223 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'DateValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>60),
224 'date_approve' =>array(
'type'=>
'datetime',
'label'=>
'DateApprove',
'enabled'=>1,
'visible'=>-1,
'position'=>62),
225 'date_approve2' =>array(
'type'=>
'datetime',
'label'=>
'DateApprove2',
'enabled'=>1,
'visible'=>3,
'position'=>64),
226 'date_commande' =>array(
'type'=>
'date',
'label'=>
'OrderDateShort',
'enabled'=>1,
'visible'=>1,
'position'=>70),
227 'date_livraison' =>array(
'type'=>
'datetime',
'label'=>
'DeliveryDate',
'enabled'=>
'empty($conf->global->ORDER_DISABLE_DELIVERY_DATE)',
'visible'=>1,
'position'=>74),
228 'fk_user_author' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserAuthor',
'enabled'=>1,
'visible'=>3,
'position'=>75),
229 'fk_user_modif' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserModif',
'enabled'=>1,
'visible'=>3,
'notnull'=>-1,
'position'=>80),
230 'fk_user_valid' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserValidation',
'enabled'=>1,
'visible'=>3,
'position'=>85),
231 'fk_user_approve' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserApproval',
'enabled'=>1,
'visible'=>3,
'position'=>90),
232 'fk_user_approve2' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserApproval2',
'enabled'=>1,
'visible'=>3,
'position'=>95),
233 'source' =>array(
'type'=>
'smallint(6)',
'label'=>
'Source',
'enabled'=>1,
'visible'=>3,
'notnull'=>1,
'position'=>100),
234 'billed' =>array(
'type'=>
'smallint(6)',
'label'=>
'Billed',
'enabled'=>1,
'visible'=>1,
'position'=>110),
235 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'Tva',
'enabled'=>1,
'visible'=>1,
'position'=>130,
'isameasure'=>1),
236 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax1',
'enabled'=>1,
'visible'=>3,
'position'=>135,
'isameasure'=>1),
237 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'Localtax2',
'enabled'=>1,
'visible'=>3,
'position'=>140,
'isameasure'=>1),
238 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalHT',
'enabled'=>1,
'visible'=>1,
'position'=>145,
'isameasure'=>1),
239 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalTTC',
'enabled'=>1,
'visible'=>-1,
'position'=>150,
'isameasure'=>1),
240 'note_public' =>array(
'type'=>
'text',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>155,
'searchall'=>1),
241 'note_private' =>array(
'type'=>
'text',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>160,
'searchall'=>1),
242 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'ModelPDF',
'enabled'=>1,
'visible'=>0,
'position'=>165),
243 'fk_input_method' =>array(
'type'=>
'integer',
'label'=>
'OrderMode',
'enabled'=>1,
'visible'=>3,
'position'=>170),
244 'fk_cond_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentTerm',
'enabled'=>1,
'visible'=>3,
'position'=>175),
245 'fk_mode_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentMode',
'enabled'=>1,
'visible'=>3,
'position'=>180),
246 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>0,
'position'=>190),
247 'fk_account' =>array(
'type'=>
'integer',
'label'=>
'BankAccount',
'enabled'=>
'$conf->banque->enabled',
'visible'=>3,
'position'=>200),
248 'fk_incoterms' =>array(
'type'=>
'integer',
'label'=>
'IncotermCode',
'enabled'=>1,
'visible'=>3,
'position'=>205),
249 'location_incoterms' =>array(
'type'=>
'varchar(255)',
'label'=>
'IncotermLocation',
'enabled'=>1,
'visible'=>3,
'position'=>210),
250 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'Fk multicurrency',
'enabled'=>1,
'visible'=>0,
'position'=>215),
251 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'Currency',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>220),
252 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'CurrencyRate',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>225),
253 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountHT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>230),
254 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountVAT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>235),
255 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountTTC',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>240),
256 'date_creation' =>array(
'type'=>
'datetime',
'label'=>
'Date creation',
'enabled'=>1,
'visible'=>-1,
'position'=>500),
257 'fk_soc' =>array(
'type'=>
'integer:Societe:societe/class/societe.class.php',
'label'=>
'ThirdParty',
'enabled'=>
'$conf->societe->enabled',
'visible'=>1,
'notnull'=>1,
'position'=>46),
258 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>0,
'notnull'=>1,
'position'=>1000,
'index'=>1),
259 'tms'=>array(
'type'=>
'datetime',
'label'=>
"DateModificationShort",
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>501),
260 'last_main_doc' =>array(
'type'=>
'varchar(255)',
'label'=>
'LastMainDoc',
'enabled'=>1,
'visible'=>0,
'position'=>700),
261 'fk_statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Status',
'enabled'=>1,
'visible'=>1,
'position'=>701),
262 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>0,
'position'=>900),
337 public function fetch($id, $ref =
'')
342 if (empty($id) && empty($ref)) {
346 $sql =
"SELECT c.rowid, c.entity, c.ref, ref_supplier, c.fk_soc, c.fk_statut, c.amount_ht, c.total_ht, c.total_ttc, c.total_tva,";
347 $sql .=
" c.localtax1, c.localtax2, ";
348 $sql .=
" c.date_creation, c.date_valid, c.date_approve, c.date_approve2,";
349 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_approve, c.fk_user_approve2,";
350 $sql .=
" c.date_commande as date_commande, c.date_livraison as delivery_date, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_projet as fk_project, c.remise_percent, c.source, c.fk_input_method,";
351 $sql .=
" c.fk_account,";
352 $sql .=
" c.note_private, c.note_public, c.model_pdf, c.extraparams, c.billed,";
353 $sql .=
" c.fk_multicurrency, c.multicurrency_code, c.multicurrency_tx, c.multicurrency_total_ht, c.multicurrency_total_tva, c.multicurrency_total_ttc,";
354 $sql .=
" cm.libelle as methode_commande,";
355 $sql .=
" cr.code as cond_reglement_code, cr.libelle as cond_reglement_label, cr.libelle_facture as cond_reglement_doc,";
356 $sql .=
" p.code as mode_reglement_code, p.libelle as mode_reglement_libelle";
357 $sql .=
', c.fk_incoterms, c.location_incoterms';
358 $sql .=
', i.libelle as label_incoterms';
359 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commande_fournisseur as c";
360 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_payment_term as cr ON c.fk_cond_reglement = cr.rowid";
361 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_paiement as p ON c.fk_mode_reglement = p.id";
362 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_input_method as cm ON cm.rowid = c.fk_input_method";
363 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON c.fk_incoterms = i.rowid';
366 $sql .=
" WHERE c.entity IN (".getEntity(
'supplier_order').
")";
368 $sql .=
" WHERE c.rowid=".((int) $id);
372 $sql .=
" AND c.ref='".$this->db->escape($ref).
"'";
375 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
378 $obj = $this->
db->fetch_object(
$resql);
380 $this->error =
'Bill with id '.$id.
' not found';
381 dol_syslog(get_class($this).
'::fetch '.$this->error);
385 $this->
id = $obj->rowid;
386 $this->entity = $obj->entity;
388 $this->
ref = $obj->ref;
389 $this->ref_supplier = $obj->ref_supplier;
390 $this->socid = $obj->fk_soc;
391 $this->fourn_id = $obj->fk_soc;
392 $this->statut = $obj->fk_statut;
393 $this->status = $obj->fk_statut;
394 $this->billed = $obj->billed;
395 $this->user_author_id = $obj->fk_user_author;
396 $this->user_valid_id = $obj->fk_user_valid;
397 $this->user_approve_id = $obj->fk_user_approve;
398 $this->user_approve_id2 = $obj->fk_user_approve2;
399 $this->total_ht = $obj->total_ht;
400 $this->total_tva = $obj->total_tva;
401 $this->total_localtax1 = $obj->localtax1;
402 $this->total_localtax2 = $obj->localtax2;
403 $this->total_ttc = $obj->total_ttc;
404 $this->date_creation = $this->
db->jdate($obj->date_creation);
405 $this->date_valid = $this->
db->jdate($obj->date_valid);
406 $this->date_approve = $this->
db->jdate($obj->date_approve);
407 $this->date_approve2 = $this->
db->jdate($obj->date_approve2);
408 $this->date_commande = $this->
db->jdate($obj->date_commande);
409 if (isset($obj->date_commande)) {
410 $this->date = $this->date_commande;
412 $this->date = $this->date_creation;
414 $this->date_livraison = $this->
db->jdate($obj->delivery_date);
415 $this->delivery_date = $this->
db->jdate($obj->delivery_date);
416 $this->remise_percent = $obj->remise_percent;
417 $this->methode_commande_id = $obj->fk_input_method;
418 $this->methode_commande = $obj->methode_commande;
420 $this->source = $obj->source;
421 $this->fk_project = $obj->fk_project;
422 $this->cond_reglement_id = $obj->fk_cond_reglement;
423 $this->cond_reglement_code = $obj->cond_reglement_code;
424 $this->cond_reglement = $obj->cond_reglement_label;
425 $this->cond_reglement_label = $obj->cond_reglement_label;
426 $this->cond_reglement_doc = $obj->cond_reglement_doc;
427 $this->fk_account = $obj->fk_account;
428 $this->mode_reglement_id = $obj->fk_mode_reglement;
429 $this->mode_reglement_code = $obj->mode_reglement_code;
430 $this->mode_reglement = $obj->mode_reglement_libelle;
431 $this->note = $obj->note_private;
432 $this->note_private = $obj->note_private;
433 $this->note_public = $obj->note_public;
434 $this->model_pdf = $obj->model_pdf;
435 $this->modelpdf = $obj->model_pdf;
438 $this->fk_incoterms = $obj->fk_incoterms;
439 $this->location_incoterms = $obj->location_incoterms;
440 $this->label_incoterms = $obj->label_incoterms;
443 $this->fk_multicurrency = $obj->fk_multicurrency;
444 $this->multicurrency_code = $obj->multicurrency_code;
445 $this->multicurrency_tx = $obj->multicurrency_tx;
446 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
447 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
448 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
450 $this->extraparams = (array) json_decode($obj->extraparams,
true);
458 if ($this->statut == 0) {
459 $this->brouillon = 1;
473 $this->error = $this->
db->error().
" sql=".$sql;
490 $this->lines = array();
492 $sql =
"SELECT l.rowid, l.fk_commande, l.ref as ref_supplier, l.fk_product, l.product_type, l.label, l.description, l.qty,";
493 $sql .=
" l.vat_src_code, l.tva_tx, l.remise_percent, l.subprice,";
494 $sql .=
" l.localtax1_tx, l. localtax2_tx, l.localtax1_type, l. localtax2_type, l.total_localtax1, l.total_localtax2,";
495 $sql .=
" l.total_ht, l.total_tva, l.total_ttc, l.special_code, l.fk_parent_line, l.rang,";
496 $sql .=
" p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.description as product_desc, p.tobatch as product_tobatch, p.barcode as product_barcode,";
497 $sql .=
" l.fk_unit,";
498 $sql .=
" l.date_start, l.date_end,";
499 $sql .=
' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc';
500 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commande_fournisseurdet as l";
501 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON l.fk_product = p.rowid';
502 $sql .=
" WHERE l.fk_commande = ".((int) $this->
id);
504 $sql .=
' AND p.fk_product_type = 0';
506 $sql .=
" ORDER BY l.rang, l.rowid";
509 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
511 $result = $this->
db->query($sql);
513 $num = $this->
db->num_rows($result);
517 $objp = $this->
db->fetch_object($result);
521 $line->id = $objp->rowid;
522 $line->fk_commande = $objp->fk_commande;
523 $line->desc = $objp->description;
524 $line->description = $objp->description;
525 $line->qty = $objp->qty;
526 $line->tva_tx = $objp->tva_tx;
527 $line->localtax1_tx = $objp->localtax1_tx;
528 $line->localtax2_tx = $objp->localtax2_tx;
529 $line->localtax1_type = $objp->localtax1_type;
530 $line->localtax2_type = $objp->localtax2_type;
531 $line->subprice = $objp->subprice;
532 $line->pu_ht = $objp->subprice;
533 $line->remise_percent = $objp->remise_percent;
535 $line->vat_src_code = $objp->vat_src_code;
536 $line->total_ht = $objp->total_ht;
537 $line->total_tva = $objp->total_tva;
538 $line->total_localtax1 = $objp->total_localtax1;
539 $line->total_localtax2 = $objp->total_localtax2;
540 $line->total_ttc = $objp->total_ttc;
541 $line->product_type = $objp->product_type;
543 $line->fk_product = $objp->fk_product;
545 $line->libelle = $objp->product_label;
546 $line->product_label = $objp->product_label;
547 $line->product_desc = $objp->product_desc;
548 $line->product_tobatch = $objp->product_tobatch;
549 $line->product_barcode = $objp->product_barcode;
551 $line->ref = $objp->product_ref;
552 $line->product_ref = $objp->product_ref;
553 $line->ref_fourn = $objp->ref_supplier;
554 $line->ref_supplier = $objp->ref_supplier;
556 if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) {
561 $sqlsearchpackage =
'SELECT rowid, packaging FROM '.MAIN_DB_PREFIX.
"product_fournisseur_price";
562 $sqlsearchpackage .=
' WHERE entity IN ('.getEntity(
'product_fournisseur_price').
")";
563 $sqlsearchpackage .=
" AND fk_product = ".((int) $objp->fk_product);
564 $sqlsearchpackage .=
" AND ref_fourn = '".$this->db->escape($objp->ref_supplier).
"'";
565 $sqlsearchpackage .=
" AND quantity <= ".((float) $objp->qty);
566 $sqlsearchpackage .=
" AND (packaging IS NULL OR packaging = 0 OR packaging <= ".((float) $objp->qty).
")";
567 $sqlsearchpackage .=
" AND fk_soc = ".((int) $this->socid);
568 $sqlsearchpackage .=
" ORDER BY packaging ASC";
569 $sqlsearchpackage .=
" LIMIT 1";
571 $resqlsearchpackage = $this->
db->query($sqlsearchpackage);
572 if ($resqlsearchpackage) {
573 $objsearchpackage = $this->
db->fetch_object($resqlsearchpackage);
574 if ($objsearchpackage) {
575 $line->fk_fournprice = $objsearchpackage->rowid;
576 $line->packaging = $objsearchpackage->packaging;
579 $this->error = $this->
db->lasterror();
584 $line->date_start = $this->
db->jdate($objp->date_start);
585 $line->date_end = $this->
db->jdate($objp->date_end);
586 $line->fk_unit = $objp->fk_unit;
589 $line->fk_multicurrency = $objp->fk_multicurrency;
590 $line->multicurrency_code = $objp->multicurrency_code;
591 $line->multicurrency_subprice = $objp->multicurrency_subprice;
592 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
593 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
594 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
596 $line->special_code = $objp->special_code;
597 $line->fk_parent_line = $objp->fk_parent_line;
599 $line->rang = $objp->rang;
603 $line->fetch_optionals();
605 $this->lines[$i] = $line;
609 $this->
db->free($result);
613 $this->error = $this->
db->error().
" sql=".$sql;
626 public function valid($user, $idwarehouse = 0, $notrigger = 0)
628 global $langs, $conf;
629 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
635 if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && (!empty($user->rights->fournisseur->commande->creer) || !empty($user->rights->supplier_order->creer)))
636 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->supplier_order_advance->validate))) {
641 $soc->fetch($this->fourn_id);
644 if (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
651 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"commande_fournisseur";
652 $sql .=
" SET ref='".$this->db->escape($num).
"',";
653 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
",";
654 $sql .=
" date_valid='".$this->db->idate(
dol_now()).
"',";
655 $sql .=
" fk_user_valid = ".((int) $user->id);
656 $sql .=
" WHERE rowid = ".((int) $this->
id);
657 $sql .=
" AND fk_statut = ".self::STATUS_DRAFT;
665 if (!$error && !$notrigger) {
667 $result = $this->
call_trigger(
'ORDER_SUPPLIER_VALIDATE', $user);
675 $this->oldref = $this->ref;
678 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
680 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->
db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'fournisseur/commande/".$this->
db->escape($this->newref).
"'";
681 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'fournisseur/commande/".$this->
db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
684 $error++; $this->error = $this->
db->lasterror();
690 $dirsource = $conf->fournisseur->commande->dir_output.
'/'.$oldref;
691 $dirdest = $conf->fournisseur->commande->dir_output.
'/'.$newref;
692 if (!$error && file_exists($dirsource)) {
693 dol_syslog(get_class($this).
"::valid rename dir ".$dirsource.
" into ".$dirdest);
695 if (@rename($dirsource, $dirdest)) {
698 $listoffiles =
dol_dir_list($conf->fournisseur->commande->dir_output.
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
699 foreach ($listoffiles as $fileentry) {
700 $dirsource = $fileentry[
'name'];
701 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
702 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
703 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
704 @rename($dirsource, $dirdest);
721 $this->
db->rollback();
725 $this->error =
'NotAuthorized';
726 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
739 return $this->
LibStatut($this->statut, $mode, $this->billed);
751 public function LibStatut($status, $mode = 0, $billed = 0)
754 global $conf, $langs, $hookmanager;
756 if (empty($this->statuts) || empty($this->statuts_short)) {
757 $langs->load(
'orders');
759 $this->statuts[0] =
'StatusSupplierOrderDraft';
760 $this->statuts[1] =
'StatusSupplierOrderValidated';
761 $this->statuts[2] =
'StatusSupplierOrderApproved';
762 if (empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) {
763 $this->statuts[3] =
'StatusSupplierOrderOnProcess';
765 $this->statuts[3] =
'StatusSupplierOrderOnProcessWithValidation';
767 $this->statuts[4] =
'StatusSupplierOrderReceivedPartially';
768 $this->statuts[5] =
'StatusSupplierOrderReceivedAll';
769 $this->statuts[6] =
'StatusSupplierOrderCanceled';
770 $this->statuts[7] =
'StatusSupplierOrderCanceled';
771 $this->statuts[9] =
'StatusSupplierOrderRefused';
774 $this->statuts_short[0] =
'StatusSupplierOrderDraftShort';
775 $this->statuts_short[1] =
'StatusSupplierOrderValidatedShort';
776 $this->statuts_short[2] =
'StatusSupplierOrderApprovedShort';
777 $this->statuts_short[3] =
'StatusSupplierOrderOnProcessShort';
778 $this->statuts_short[4] =
'StatusSupplierOrderReceivedPartiallyShort';
779 $this->statuts_short[5] =
'StatusSupplierOrderReceivedAllShort';
780 $this->statuts_short[6] =
'StatusSupplierOrderCanceledShort';
781 $this->statuts_short[7] =
'StatusSupplierOrderCanceledShort';
782 $this->statuts_short[9] =
'StatusSupplierOrderRefusedShort';
785 $statustrans = array(
797 $statusClass =
'status0';
798 if (!empty($statustrans[$status])) {
799 $statusClass = $statustrans[$status];
804 $billedtext =
' - '.$langs->trans(
"Billed");
806 if ($status == 5 && $billed) {
807 $statusClass =
'status6';
810 $statusLong = $langs->transnoentitiesnoconv($this->statuts[$status]).$billedtext;
811 $statusShort = $langs->transnoentitiesnoconv($this->statuts_short[$status]);
813 $parameters = array(
'status' => $status,
'mode' => $mode,
'billed' => $billed);
814 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
816 return $hookmanager->resPrint;
819 return dolGetStatus($statusLong, $statusShort,
'', $statusClass, $mode);
833 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0)
835 global $langs, $conf, $user, $hookmanager;
841 if ($user->hasRight(
"fournisseur",
"commande",
"read")) {
842 $label =
'<u class="paddingrightonly">'.$langs->trans(
"SupplierOrder").
'</u>';
843 if (isset($this->statut)) {
844 $label .=
' '.$this->getLibStatut(5);
846 if (!empty($this->
ref)) {
847 $label .=
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
849 if (!empty($this->ref_supplier)) {
850 $label .=
'<br><b>'.$langs->trans(
'RefSupplier').
':</b> '.$this->ref_supplier;
852 if (!empty($this->total_ht)) {
853 $label .=
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
855 if (!empty($this->total_tva)) {
856 $label .=
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
858 if (!empty($this->total_ttc)) {
859 $label .=
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
861 if (!empty($this->date)) {
862 $label .=
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
864 if (!empty($this->delivery_date)) {
865 $label .=
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
870 $url = DOL_URL_ROOT.
'/fourn/commande/card.php?id='.$this->id;
872 if ($option !==
'nolink') {
874 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
875 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
876 $add_save_lastsearch_values = 1;
878 if ($add_save_lastsearch_values) {
879 $url .=
'&save_lastsearch_values=1';
884 if (empty($notooltip)) {
885 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
886 $label = $langs->trans(
"ShowOrder");
887 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
889 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
890 $linkclose .=
' class="classfortooltip"';
893 $linkstart =
'<a href="'.$url.
'"';
894 $linkstart .= $linkclose.
'>';
897 $result .= $linkstart;
899 $result .=
img_object(($notooltip ?
'' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
901 if ($withpicto != 2) {
902 $result .= $this->ref;
906 if ($addlinktonotes) {
907 $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private);
910 $result .=
' <span class="note inline-block">';
911 $result .=
'<a href="'.DOL_URL_ROOT.
'/fourn/commande/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($notetoshow).
'">';
916 $result .=
'</span>';
921 $hookmanager->initHooks(array($this->element .
'dao'));
922 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
923 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
925 $result = $hookmanager->resPrint;
927 $result .= $hookmanager->resPrint;
942 global $db, $langs, $conf;
943 $langs->load(
"orders");
945 if (!empty($conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER)) {
948 $file = $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER.
'.php';
949 $classname = $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER;
952 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
954 foreach ($dirmodels as $reldir) {
955 $dir =
dol_buildpath($reldir.
"core/modules/supplier_order/");
958 $mybool |= @include_once $dir.$file;
961 if ($mybool ===
false) {
966 $obj =
new $classname();
967 $numref = $obj->getNextValue($soc, $this);
972 $this->error = $obj->error;
976 $this->error =
"Error_COMMANDE_SUPPLIER_ADDON_NotDefined";
996 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'commande_fournisseur SET billed = 1';
999 if ($this->
db->query($sql)) {
1002 $result = $this->
call_trigger(
'ORDER_SUPPLIER_CLASSIFY_BILLED', $user);
1012 $this->
db->commit();
1015 $this->
db->rollback();
1021 $this->
db->rollback();
1034 public function approve($user, $idwarehouse = 0, $secondlevel = 0)
1036 global $langs, $conf;
1037 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1043 if ($user->rights->fournisseur->commande->approuver) {
1050 $soc->fetch($this->fourn_id);
1053 if (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
1061 $movetoapprovestatus =
true;
1064 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"commande_fournisseur";
1065 $sql .=
" SET ref='".$this->db->escape($num).
"',";
1066 if (empty($secondlevel)) {
1067 $sql .=
" date_approve='".$this->db->idate($now).
"',";
1068 $sql .=
" fk_user_approve = ".$user->id;
1069 if (!empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) && $this->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) {
1070 if (empty($this->user_approve_id2)) {
1071 $movetoapprovestatus =
false;
1072 $comment =
' (first level)';
1077 $sql .=
" date_approve2='".$this->db->idate($now).
"',";
1078 $sql .=
" fk_user_approve2 = ".((int) $user->id);
1079 if (empty($this->user_approve_id)) {
1080 $movetoapprovestatus =
false;
1082 $comment =
' (second level)';
1085 if ($movetoapprovestatus) {
1086 $sql .=
", fk_statut = ".self::STATUS_ACCEPTED;
1088 $sql .=
", fk_statut = ".self::STATUS_VALIDATED;
1090 $sql .=
" WHERE rowid = ".((int) $this->
id);
1091 $sql .=
" AND fk_statut = ".self::STATUS_VALIDATED;
1093 if ($this->
db->query($sql)) {
1094 if (!empty($conf->global->SUPPLIER_ORDER_AUTOADD_USER_CONTACT)) {
1095 $result = $this->
add_contact($user->id,
'SALESREPFOLL',
'internal', 1);
1096 if ($result < 0 && $result != -2) {
1102 if (!$error && $movetoapprovestatus &&
isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)) {
1103 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
1104 $langs->load(
"agenda");
1106 $cpt = count($this->lines);
1107 for ($i = 0; $i < $cpt; $i++) {
1109 if ($this->lines[$i]->fk_product > 0) {
1110 $this->line = $this->lines[$i];
1112 $mouvP->origin = &$this;
1113 $mouvP->setOrigin($this->element, $this->
id);
1115 $up_ht_disc = $this->lines[$i]->subprice;
1116 if (!empty($this->lines[$i]->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) {
1117 $up_ht_disc =
price2num($up_ht_disc * (100 - $this->lines[$i]->remise_percent) / 100,
'MU');
1119 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans(
"OrderApprovedInDolibarr", $this->ref));
1130 $result = $this->
call_trigger(
'ORDER_SUPPLIER_APPROVE', $user);
1138 $this->
ref = $this->newref;
1140 if ($movetoapprovestatus) {
1145 if (empty($secondlevel)) {
1146 $this->date_approve = $now;
1147 $this->user_approve_id = $user->id;
1150 $this->date_approve2 = $now;
1151 $this->user_approve_id2 = $user->id;
1154 $this->
db->commit();
1157 $this->
db->rollback();
1161 $this->
db->rollback();
1162 $this->error = $this->
db->lasterror();
1166 dol_syslog(get_class($this).
"::approve Not Authorized", LOG_ERR);
1179 global $conf, $langs;
1185 if ($user->rights->fournisseur->commande->approuver) {
1189 $sql .=
" WHERE rowid = ".((int) $this->
id);
1191 if ($this->
db->query($sql)) {
1196 $result = $this->
call_trigger(
'ORDER_SUPPLIER_REFUSE', $user);
1199 $this->
db->rollback();
1201 $this->
db->commit();
1206 $this->
db->rollback();
1207 $this->error = $this->
db->lasterror();
1208 dol_syslog(get_class($this).
"::refuse Error -1");
1212 dol_syslog(get_class($this).
"::refuse Not Authorized");
1226 public function Cancel($user, $idwarehouse = -1)
1229 global $langs, $conf;
1235 if ($user->rights->fournisseur->commande->commander) {
1240 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"commande_fournisseur SET fk_statut = ".((int) $statut);
1241 $sql .=
" WHERE rowid = ".((int) $this->
id);
1242 dol_syslog(get_class($this).
"::cancel", LOG_DEBUG);
1243 if ($this->
db->query($sql)) {
1247 $result = $this->
call_trigger(
'ORDER_SUPPLIER_CANCEL', $user);
1254 $this->
db->commit();
1257 $this->
db->rollback();
1261 $this->
db->rollback();
1262 $this->error = $this->
db->lasterror();
1263 dol_syslog(get_class($this).
"::cancel ".$this->error);
1267 dol_syslog(get_class($this).
"::cancel Not Authorized");
1281 public function commande($user, $date, $methode, $comment =
'')
1286 if ($user->rights->fournisseur->commande->commander) {
1289 $newnoteprivate = $this->note_private;
1291 $newnoteprivate =
dol_concatdesc($newnoteprivate, $langs->trans(
"Comment").
': '.$comment);
1294 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"commande_fournisseur";
1295 $sql .=
" SET fk_statut=".self::STATUS_ORDERSENT.
", fk_input_method=".$methode.
", date_commande='".$this->
db->idate($date).
"', ";
1296 $sql .=
" note_private='".$this->db->escape($newnoteprivate).
"'";
1297 $sql .=
" WHERE rowid=".((int) $this->
id);
1299 dol_syslog(get_class($this).
"::commande", LOG_DEBUG);
1300 if ($this->
db->query($sql)) {
1302 $this->methode_commande_id = $methode;
1303 $this->date_commande = $date;
1304 $this->context = array(
'comments' => $comment);
1307 $result = $this->
call_trigger(
'ORDER_SUPPLIER_SUBMIT', $user);
1314 $this->error = $this->
db->lasterror();
1315 $this->errors[] = $this->
db->lasterror();
1319 $this->
db->commit();
1321 $this->
db->rollback();
1325 $this->error = $langs->trans(
'NotAuthorized');
1326 $this->errors[] = $langs->trans(
'NotAuthorized');
1327 dol_syslog(get_class($this).
"::commande User not Authorized", LOG_WARNING);
1330 return ($error ? -1 : 1);
1340 public function create($user, $notrigger = 0)
1342 global $langs, $conf, $hookmanager;
1350 $date = ($this->date_commande ? $this->date_commande : $this->date);
1354 $delivery_date = empty($this->delivery_date) ? $this->date_livraison : $this->delivery_date;
1357 if (empty($this->source)) {
1362 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1367 if (empty($this->fk_multicurrency)) {
1368 $this->multicurrency_code = $conf->currency;
1369 $this->fk_multicurrency = 0;
1370 $this->multicurrency_tx = 1;
1374 $this->brouillon = 1;
1376 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"commande_fournisseur (";
1378 $sql .=
", ref_supplier";
1379 $sql .=
", note_private";
1380 $sql .=
", note_public";
1383 $sql .=
", fk_projet";
1384 $sql .=
", date_creation";
1385 $sql .=
", date_livraison";
1386 $sql .=
", fk_user_author";
1387 $sql .=
", fk_statut";
1389 $sql .=
", model_pdf";
1390 $sql .=
", fk_mode_reglement";
1391 $sql .=
", fk_cond_reglement";
1392 $sql .=
", fk_account";
1393 $sql .=
", fk_incoterms, location_incoterms";
1394 $sql .=
", fk_multicurrency";
1395 $sql .=
", multicurrency_code";
1396 $sql .=
", multicurrency_tx";
1398 $sql .=
" VALUES (";
1400 $sql .=
", '".$this->db->escape($this->ref_supplier).
"'";
1401 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1402 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1403 $sql .=
", ".setEntity($this);
1404 $sql .=
", ".((int) $this->socid);
1405 $sql .=
", ".($this->fk_project > 0 ? ((int) $this->fk_project) :
"null");
1406 $sql .=
", '".$this->db->idate($date).
"'";
1407 $sql .=
", ".($delivery_date ?
"'".$this->db->idate($delivery_date).
"'" :
"null");
1408 $sql .=
", ".((int) $user->id);
1409 $sql .=
", ".self::STATUS_DRAFT;
1410 $sql .=
", ".((int) $this->source);
1411 $sql .=
", '".$this->db->escape($conf->global->COMMANDE_SUPPLIER_ADDON_PDF).
"'";
1412 $sql .=
", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id :
'null');
1413 $sql .=
", ".($this->cond_reglement_id > 0 ? $this->cond_reglement_id :
'null');
1414 $sql .=
", ".($this->fk_account > 0 ? $this->fk_account :
'NULL');
1415 $sql .=
", ".(int) $this->fk_incoterms;
1416 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1417 $sql .=
", ".(int) $this->fk_multicurrency;
1418 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1419 $sql .=
", ".(double) $this->multicurrency_tx;
1422 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1423 if ($this->
db->query($sql)) {
1424 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"commande_fournisseur");
1427 $num = count($this->lines);
1430 for ($i = 0; $i < $num; $i++) {
1431 $line = $this->lines[$i];
1432 if (!is_object($line)) {
1433 $line = (object) $line;
1445 $line->localtax1_tx,
1446 $line->localtax2_tx,
1450 $line->remise_percent,
1453 $line->product_type,
1458 $line->array_options,
1460 $line->multicurrency_subprice,
1467 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
1468 $this->
db->rollback();
1473 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"commande_fournisseur";
1474 $sql .=
" SET ref='(PROV".$this->id.
")'";
1475 $sql .=
" WHERE rowid=".((int) $this->
id);
1476 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1477 if ($this->
db->query($sql)) {
1480 $this->
ref =
"(PROV".$this->id.
")";
1482 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1483 $this->linked_objects = $this->linkedObjectsIds;
1487 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1488 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1489 if (is_array($tmp_origin_id)) {
1490 foreach ($tmp_origin_id as $origin_id) {
1499 $origin_id = $tmp_origin_id;
1517 if (!$error && !$notrigger) {
1519 $result = $this->
call_trigger(
'ORDER_SUPPLIER_CREATE', $user);
1521 $this->
db->rollback();
1527 $this->
db->commit();
1530 $this->error = $this->
db->lasterror();
1531 $this->
db->rollback();
1536 $this->error = $this->
db->lasterror();
1537 $this->
db->rollback();
1556 if (isset($this->
ref)) {
1557 $this->
ref = trim($this->
ref);
1559 if (isset($this->ref_supplier)) {
1560 $this->ref_supplier = trim($this->ref_supplier);
1562 if (isset($this->note_private)) {
1563 $this->note_private = trim($this->note_private);
1565 if (isset($this->note_public)) {
1566 $this->note_public = trim($this->note_public);
1568 if (isset($this->model_pdf)) {
1569 $this->model_pdf = trim($this->model_pdf);
1571 if (isset($this->import_key)) {
1572 $this->import_key = trim($this->import_key);
1576 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
1578 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1579 $sql .=
" ref_supplier=".(isset($this->ref_supplier) ?
"'".$this->db->escape($this->ref_supplier).
"'" :
"null").
",";
1580 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1581 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1582 $sql .=
" date_commande=".(strval($this->date_commande) !=
'' ?
"'".$this->db->idate($this->date_commande).
"'" :
'null').
",";
1583 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1584 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1585 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1586 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1587 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1588 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1589 $sql .=
" fk_statut=".(isset($this->statut) ? $this->statut :
"null").
",";
1590 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1591 $sql .=
" fk_user_valid=".(isset($this->user_valid) && $this->user_valid > 0 ? $this->user_valid :
"null").
",";
1592 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1593 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1594 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1595 $sql .=
" date_livraison=".(strval($this->delivery_date) !=
'' ?
"'".$this->db->idate($this->delivery_date).
"'" :
'null').
",";
1597 $sql .=
" fk_account=".($this->fk_account > 0 ? $this->fk_account :
"null").
",";
1599 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1600 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1601 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1602 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null").
"";
1604 $sql .=
" WHERE rowid=".((int) $this->
id);
1608 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1612 $this->errors[] =
"Error ".$this->db->lasterror();
1622 if (!$error && !$notrigger) {
1624 $result = $this->
call_trigger(
'ORDER_SUPPLIER_MODIFY', $user);
1633 foreach ($this->errors as $errmsg) {
1634 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1635 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1637 $this->
db->rollback();
1640 $this->
db->commit();
1655 global $conf, $user, $hookmanager;
1662 foreach ($this->lines as $line) {
1663 $line->fetch_optionals();
1667 $objFrom = clone $this;
1670 if (!empty($socid) && $socid != $this->socid) {
1673 if ($objsoc->fetch($socid) > 0) {
1674 $this->socid = $objsoc->id;
1675 $this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1676 $this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1677 $this->fk_project = 0;
1678 $this->fk_delivery_address = 0;
1688 $this->user_author_id = $user->id;
1689 $this->user_valid = 0;
1690 $this->date_creation =
'';
1691 $this->date_validation =
'';
1692 $this->ref_supplier =
'';
1693 $this->user_approve_id =
'';
1694 $this->user_approve_id2 =
'';
1695 $this->date_approve =
'';
1696 $this->date_approve2 =
'';
1699 $this->context[
'createfromclone'] =
'createfromclone';
1700 $result = $this->
create($user, $notrigger);
1707 if (is_object($hookmanager)) {
1708 $parameters = array(
'objFrom'=>$objFrom);
1710 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1712 $this->errors += $hookmanager->errors;
1713 $this->error = $hookmanager->error;
1719 unset($this->context[
'createfromclone']);
1723 $this->
db->commit();
1726 $this->
db->rollback();
1760 public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $fk_prod_fourn_price = 0, $ref_supplier =
'', $remise_percent = 0.0, $price_base_type =
'HT', $pu_ttc = 0.0, $type = 0, $info_bits = 0, $notrigger =
false, $date_start =
null, $date_end =
null, $array_options = 0, $fk_unit =
null, $pu_ht_devise = 0, $origin =
'', $origin_id = 0, $rang = -1, $special_code = 0)
1762 global $langs, $mysoc, $conf;
1764 dol_syslog(get_class($this).
"::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $fk_prod_fourn_price, $ref_supplier, $remise_percent, $price_base_type, $pu_ttc, $type, $info_bits, $notrigger, $date_start, $date_end, $fk_unit, $pu_ht_devise, $origin, $origin_id");
1765 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
1767 if ($this->statut == self::STATUS_DRAFT) {
1768 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
1777 if (empty($txtva)) {
1783 if (empty($txlocaltax1)) {
1786 if (empty($txlocaltax2)) {
1789 if (empty($remise_percent)) {
1790 $remise_percent = 0;
1793 $remise_percent =
price2num($remise_percent);
1796 $pu_ht_devise =
price2num($pu_ht_devise);
1798 if (!preg_match(
'/\((.*)\)/', $txtva)) {
1803 if ($price_base_type ==
'HT') {
1808 $desc = trim($desc);
1811 if ($qty < 0 && !$fk_product) {
1812 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"Product"));
1818 if ($date_start && $date_end && $date_start > $date_end) {
1819 $langs->load(
"errors");
1820 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
1827 $product_type = $type;
1830 if ($fk_product > 0) {
1831 if (!empty($conf->global->SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY)) {
1833 dol_syslog(get_class($this).
"::addline we check supplier prices fk_product=".$fk_product.
" fk_prod_fourn_price=".$fk_prod_fourn_price.
" qty=".$qty.
" ref_supplier=".$ref_supplier);
1835 if ($prod->fetch($fk_product) > 0) {
1836 $product_type = $prod->type;
1837 $label = $prod->label;
1841 $result = $prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product,
'none', (isset($this->fk_soc) ? $this->fk_soc : $this->socid));
1845 if ($result > 0 && ($origin ==
'commande' || $pu ===
'')) {
1846 $pu = $prod->fourn_pu;
1847 $ref_supplier = $prod->ref_supplier;
1849 if ($remise_percent == 0 && $prod->remise_percent != 0) {
1850 $remise_percent = $prod->remise_percent;
1854 $langs->load(
"errors");
1855 $this->error =
"Ref ".$prod->ref.
" ".$langs->trans(
"ErrorQtyTooLowForThisSupplier");
1856 $this->
db->rollback();
1857 dol_syslog(get_class($this).
"::addline we did not found supplier price, so we can't guess unit price");
1862 if ($result == -1) {
1863 $langs->load(
"errors");
1864 $this->error =
"Ref ".$prod->ref.
" ".$langs->trans(
"ErrorQtyTooLowForThisSupplier");
1865 $this->
db->rollback();
1866 dol_syslog(get_class($this).
"::addline result=".$result.
" - ".$this->error, LOG_DEBUG);
1870 $this->error = $prod->error;
1871 $this->
db->rollback();
1872 dol_syslog(get_class($this).
"::addline result=".$result.
" - ".$this->error, LOG_ERR);
1876 $this->error = $prod->error;
1877 $this->
db->rollback();
1883 if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) {
1885 $prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product,
'none', (empty($this->fk_soc) ? $this->socid : $this->fk_soc));
1887 if ($qty < $prod->packaging) {
1888 $qty = $prod->packaging;
1890 if (!empty($prod->packaging) && ($qty % $prod->packaging) > 0) {
1891 $coeff = intval($qty / $prod->packaging) + 1;
1892 $qty = $prod->packaging * $coeff;
1893 setEventMessages($langs->trans(
'QtyRecalculatedWithPackaging'),
null,
'mesgs');
1899 if (
isModEnabled(
"multicurrency") && $pu_ht_devise > 0) {
1908 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
1909 $vat_src_code = $reg[1];
1910 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
1918 $tabprice =
calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
1920 $total_ht = $tabprice[0];
1921 $total_tva = $tabprice[1];
1922 $total_ttc = $tabprice[2];
1923 $total_localtax1 = $tabprice[9];
1924 $total_localtax2 = $tabprice[10];
1925 $pu = $pu_ht = $tabprice[3];
1928 $multicurrency_total_ht = $tabprice[16];
1929 $multicurrency_total_tva = $tabprice[17];
1930 $multicurrency_total_ttc = $tabprice[18];
1931 $pu_ht_devise = $tabprice[19];
1933 $localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
1934 $localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
1938 $rang = $rangmax + 1;
1944 $this->line->context = $this->context;
1946 $this->line->fk_commande = $this->id;
1947 $this->line->label = $label;
1948 $this->line->ref_fourn = $ref_supplier;
1949 $this->line->ref_supplier = $ref_supplier;
1950 $this->line->desc = $desc;
1951 $this->line->qty = $qty;
1952 $this->line->tva_tx = $txtva;
1953 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
1954 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
1955 $this->line->localtax1_type = $localtax1_type;
1956 $this->line->localtax2_type = $localtax2_type;
1957 $this->line->fk_product = $fk_product;
1958 $this->line->product_type = $product_type;
1959 $this->line->remise_percent = $remise_percent;
1960 $this->line->subprice = $pu_ht;
1961 $this->line->rang = $rang;
1962 $this->line->info_bits = $info_bits;
1964 $this->line->vat_src_code = $vat_src_code;
1965 $this->line->total_ht = $total_ht;
1966 $this->line->total_tva = $total_tva;
1967 $this->line->total_localtax1 = $total_localtax1;
1968 $this->line->total_localtax2 = $total_localtax2;
1969 $this->line->total_ttc = $total_ttc;
1970 $this->line->product_type = $type;
1971 $this->line->special_code = (!empty($special_code) ? $special_code : 0);
1972 $this->line->origin = $origin;
1973 $this->line->origin_id = $origin_id;
1974 $this->line->fk_unit = $fk_unit;
1976 $this->line->date_start = $date_start;
1977 $this->line->date_end = $date_end;
1980 $this->line->fk_multicurrency = $this->fk_multicurrency;
1981 $this->line->multicurrency_code = $this->multicurrency_code;
1982 $this->line->multicurrency_subprice = $pu_ht_devise;
1983 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
1984 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
1985 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
1987 $this->line->subprice = $pu_ht;
1988 $this->line->price = $this->line->subprice;
1990 $this->line->remise_percent = $remise_percent;
1992 if (is_array($array_options) && count($array_options) > 0) {
1993 $this->line->array_options = $array_options;
1996 $result = $this->line->insert($notrigger);
1999 if (!empty($fk_parent_line)) {
2001 } elseif ($rang > 0 && $rang <= count($this->lines)) {
2002 $linecount = count($this->lines);
2003 for ($ii = $rang; $ii <= $linecount; $ii++) {
2009 $result = $this->
update_price(1,
'auto', 0, $this->thirdparty);
2011 $this->
db->commit();
2012 return $this->line->id;
2014 $this->
db->rollback();
2018 $this->error = $this->line->error;
2019 $this->errors = $this->line->errors;
2020 dol_syslog(get_class($this).
"::addline error=".$this->error, LOG_ERR);
2021 $this->
db->rollback();
2044 public function dispatchProduct($user, $product, $qty, $entrepot, $price = 0, $comment =
'', $eatby =
'', $sellby =
'', $batch =
'', $fk_commandefourndet = 0, $notrigger = 0)
2046 global $conf, $langs;
2049 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
2052 if ($entrepot <= 0) {
2053 $this->error =
'ErrorBadValueForParameterWarehouse';
2057 $this->error =
'ErrorBadValueForParameterQty';
2061 $dispatchstatus = 1;
2062 if (!empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) {
2063 $dispatchstatus = 0;
2070 if (($this->statut == self::STATUS_ORDERSENT || $this->statut == self::STATUS_RECEIVED_PARTIALLY || $this->statut == self::STATUS_RECEIVED_COMPLETELY)) {
2073 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"commande_fournisseur_dispatch";
2074 $sql .=
" (fk_commande, fk_product, qty, fk_entrepot, fk_user, datec, fk_commandefourndet, status, comment, eatby, sellby, batch) VALUES";
2075 $sql .=
" ('".$this->id.
"','".$product.
"','".$qty.
"',".($entrepot > 0 ?
"'".$entrepot.
"'" :
"null").
",'".$user->id.
"','".$this->db->idate($now).
"','".$fk_commandefourndet.
"', ".$dispatchstatus.
", '".$this->
db->escape($comment).
"', ";
2076 $sql .= ($eatby ?
"'".$this->db->idate($eatby).
"'" :
"null").
", ".($sellby ?
"'".$this->
db->idate($sellby).
"'" :
"null").
", ".($batch ?
"'".$this->
db->escape($batch).
"'" :
"null");
2079 dol_syslog(get_class($this).
"::dispatchProduct", LOG_DEBUG);
2083 global $conf, $langs, $user;
2085 $result = $this->
call_trigger(
'LINEORDER_SUPPLIER_DISPATCH', $user);
2092 $this->error = $this->
db->lasterror();
2097 if (!$error && $entrepot > 0 &&
isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) {
2101 $mouv->origin = &$this;
2102 $mouv->setOrigin($this->element, $this->
id);
2105 if (!empty($conf->global->SUPPLIER_ORDER_ALLOW_NEGATIVE_QTY_FOR_SUPPLIER_ORDER_RETURN) && $qty < 0) {
2106 $result = $mouv->livraison($user, $product, $entrepot, $qty*(-1), $price, $comment, $now, $eatby, $sellby, $batch, 0, $inventorycode);
2108 $result = $mouv->reception($user, $product, $entrepot, $qty, $price, $comment, $eatby, $sellby, $batch,
'', 0, $inventorycode);
2112 $this->error = $mouv->error;
2113 $this->errors = $mouv->errors;
2114 dol_syslog(get_class($this).
"::dispatchProduct ".$this->error.
" ".join(
',', $this->errors), LOG_ERR);
2121 $this->
db->commit();
2124 $this->
db->rollback();
2128 $this->error =
'BadStatusForObject';
2142 if ($this->statut == 0) {
2145 if ($line->fetch($idline) <= 0) {
2149 if ($line->delete($notrigger) > 0) {
2153 $this->error = $line->error;
2154 $this->errors = $line->errors;
2169 public function delete(
User $user, $notrigger = 0)
2171 global $langs, $conf;
2172 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2178 if (empty($notrigger)) {
2180 $result = $this->
call_trigger(
'ORDER_SUPPLIER_DELETE', $user);
2182 $this->errors[] =
'ErrorWhenRunningTrigger';
2183 dol_syslog(get_class($this).
"::delete ".$this->error, LOG_ERR);
2184 $this->
db->rollback();
2192 if (!empty($this->linkedObjects) && array_key_exists(
'reception', $this->linkedObjects)) {
2193 foreach ($this->linkedObjects[
'reception'] as $element) {
2194 if ($element->statut >= 0) {
2195 $this->errors[] = $langs->trans(
'ReceptionExist');
2202 $main = MAIN_DB_PREFIX.
'commande_fournisseurdet';
2203 $ef = $main.
"_extrafields";
2204 $sql =
"DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_commande = ".((int) $this->
id).
")";
2205 dol_syslog(get_class($this).
"::delete extrafields lines", LOG_DEBUG);
2206 if (!$this->
db->query($sql)) {
2207 $this->error = $this->
db->lasterror();
2208 $this->errors[] = $this->
db->lasterror();
2212 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"commande_fournisseurdet WHERE fk_commande =".((int) $this->
id);
2213 dol_syslog(get_class($this).
"::delete", LOG_DEBUG);
2214 if (!$this->
db->query($sql)) {
2215 $this->error = $this->
db->lasterror();
2216 $this->errors[] = $this->
db->lasterror();
2220 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"commande_fournisseur WHERE rowid =".((int) $this->
id);
2221 dol_syslog(get_class($this).
"::delete", LOG_DEBUG);
2222 if (
$resql = $this->
db->query($sql)) {
2223 if ($this->
db->affected_rows(
$resql) < 1) {
2224 $this->error = $this->
db->lasterror();
2225 $this->errors[] = $this->
db->lasterror();
2229 $this->error = $this->
db->lasterror();
2230 $this->errors[] = $this->
db->lasterror();
2238 $this->error =
'FailToDeleteExtraFields';
2239 $this->errors[] =
'FailToDeleteExtraFields';
2241 dol_syslog(get_class($this).
"::delete error -4 ".$this->error, LOG_ERR);
2248 $this->error =
'FailToDeleteObjectLinked';
2249 $this->errors[] =
'FailToDeleteObjectLinked';
2259 if ($conf->fournisseur->commande->dir_output) {
2260 $dir = $conf->fournisseur->commande->dir_output.
"/".$ref;
2261 $file = $dir.
"/".$ref.
".pdf";
2262 if (file_exists($file)) {
2264 $this->error =
'ErrorFailToDeleteFile';
2265 $this->errors[] =
'ErrorFailToDeleteFile';
2269 if (file_exists($dir)) {
2272 $this->error =
'ErrorFailToDeleteDir';
2273 $this->errors[] =
'ErrorFailToDeleteDir';
2281 dol_syslog(get_class($this).
"::delete $this->id by $user->id", LOG_DEBUG);
2282 $this->
db->commit();
2285 dol_syslog(get_class($this).
"::delete ".$this->error, LOG_ERR);
2286 $this->
db->rollback();
2300 $sql =
"SELECT rowid, libelle";
2301 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_input_method";
2302 $sql .=
" WHERE active = 1";
2307 $num = $this->
db->num_rows(
$resql);
2308 $this->methodes_commande = array();
2310 $row = $this->
db->fetch_row(
$resql);
2312 $this->methodes_commande[$row[0]] = $row[1];
2335 $sql =
"SELECT p.ref, p.label,";
2336 $sql .=
" e.rowid as warehouse_id, e.ref as entrepot,";
2337 $sql .=
" cfd.rowid as dispatchedlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status";
2338 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product as p,";
2339 $sql .=
" ".MAIN_DB_PREFIX.
"commande_fournisseur_dispatch as cfd";
2340 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"entrepot as e ON cfd.fk_entrepot = e.rowid";
2341 $sql .=
" WHERE cfd.fk_commande = ".((int) $this->
id);
2342 $sql .=
" AND cfd.fk_product = p.rowid";
2344 $sql .=
" AND cfd.status = ".((int) $status);
2346 $sql .=
" ORDER BY cfd.rowid ASC";
2350 $num = $this->
db->num_rows(
$resql);
2354 $objp = $this->
db->fetch_object(
$resql);
2357 'id' => $objp->dispatchedlineid,
2358 'productid' => $objp->fk_product,
2359 'warehouseid' => $objp->warehouse_id,
2360 'qty' => $objp->qty,
2367 dol_print_error($this->
db,
'Failed to execute request to get dispatched lines');
2386 global $conf, $langs;
2393 $usercanreceive = 0;
2395 $usercanreceive = $user->rights->fournisseur->commande->receptionner;
2397 $usercanreceive = $user->rights->reception->creer;
2400 if ($usercanreceive) {
2402 if ($type ==
'par') {
2404 } elseif ($type ==
'tot') {
2406 } elseif ($type ==
'nev') {
2408 } elseif ($type ==
'can') {
2412 dol_syslog(get_class($this).
"::Livraison Error -2", LOG_ERR);
2417 if (!empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) {
2419 if (!$error && ($type ==
'tot')) {
2421 if (count($dispatchedlinearray) > 0) {
2424 $this->errors[] =
'ErrorCantSetReceptionToTotalDoneWithReceptionToApprove';
2425 dol_syslog(
'ErrorCantSetReceptionToTotalDoneWithReceptionToApprove', LOG_DEBUG);
2428 if (!$error && !empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS_NEED_APPROVE) && ($type ==
'tot')) {
2430 if (count($dispatchedlinearray) > 0) {
2433 $this->errors[] =
'ErrorCantSetReceptionToTotalDoneWithReceptionDenied';
2434 dol_syslog(
'ErrorCantSetReceptionToTotalDoneWithReceptionDenied', LOG_DEBUG);
2441 if (empty($error)) {
2444 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"commande_fournisseur";
2445 $sql .=
" SET fk_statut = ".((int) $statut);
2446 $sql .=
" WHERE rowid = ".((int) $this->
id);
2447 $sql .=
" AND fk_statut IN (".self::STATUS_ORDERSENT.
",".self::STATUS_RECEIVED_PARTIALLY.
")";
2449 dol_syslog(get_class($this).
"::Livraison", LOG_DEBUG);
2453 $old_statut = $this->statut;
2454 $this->statut = $statut;
2455 $this->actionmsg2 = $comment;
2458 $result_trigger = $this->
call_trigger(
'ORDER_SUPPLIER_RECEIVE', $user);
2459 if ($result_trigger < 0) {
2464 if (empty($error)) {
2465 $this->
db->commit();
2467 $this->statut = $old_statut;
2468 $this->
db->rollback();
2469 $this->error = $this->
db->lasterror();
2473 $this->
db->rollback();
2474 $this->error = $this->
db->lasterror();
2479 $this->error = $langs->trans(
'NotAuthorized');
2480 $this->errors[] = $langs->trans(
'NotAuthorized');
2481 dol_syslog(get_class($this).
"::Livraison Not Authorized");
2513 if ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer) {
2518 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"commande_fournisseur";
2519 $sql .=
" SET date_livraison = ".($delivery_date ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2520 $sql .=
" WHERE rowid = ".((int) $this->
id);
2525 $this->errors[] = $this->
db->error();
2530 $this->oldcopy = clone $this;
2531 $this->date_livraison = $delivery_date;
2532 $this->delivery_date = $delivery_date;
2535 if (!$notrigger && empty($error)) {
2537 $result = $this->
call_trigger(
'ORDER_SUPPLIER_MODIFY', $user);
2545 $this->
db->commit();
2548 foreach ($this->errors as $errmsg) {
2549 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2550 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2552 $this->
db->rollback();
2572 if ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer) {
2577 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"commande_fournisseur";
2578 $sql .=
" SET fk_projet = ".($id_projet > 0 ? (int) $id_projet :
'null');
2579 $sql .=
" WHERE rowid = ".((int) $this->
id);
2584 $this->errors[] = $this->
db->error();
2589 $this->oldcopy = clone $this;
2590 $this->fk_projet = $id_projet;
2591 $this->fk_project = $id_projet;
2594 if (!$notrigger && empty($error)) {
2596 $result = $this->
call_trigger(
'ORDER_SUPPLIER_MODIFY', $user);
2604 $this->
db->commit();
2607 foreach ($this->errors as $errmsg) {
2608 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2609 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2611 $this->
db->rollback();
2630 $comclient->fetch($comclientid);
2634 $this->lines = array();
2636 $num = count($comclient->lines);
2637 for ($i = 0; $i < $num; $i++) {
2641 if ($prod->fetch($comclient->lines[$i]->fk_product) > 0) {
2642 $label = $prod->label;
2646 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"commande_fournisseurdet";
2647 $sql .=
" (fk_commande, label, description, fk_product, price, qty, tva_tx, localtax1_tx, localtax2_tx, remise_percent, subprice, remise, ref)";
2648 $sql .=
" VALUES (".((int) $idc).
", '".$this->
db->escape($label).
"', '".$this->
db->escape($comclient->lines[$i]->desc).
"'";
2649 $sql .=
",".$comclient->lines[$i]->fk_product.
", ".
price2num($comclient->lines[$i]->price,
'MU');
2650 $sql .=
", ".price2num($comclient->lines[$i]->qty,
'MS').
", ".
price2num($comclient->lines[$i]->tva_tx, 5).
", ".
price2num($comclient->lines[$i]->localtax1_tx, 5).
", ".
price2num($comclient->lines[$i]->localtax2_tx, 5).
", ".
price2num($comclient->lines[$i]->remise_percent, 3);
2651 $sql .=
", '".price2num($comclient->lines[$i]->subprice,
'MT').
"','0', '".$this->
db->escape($ref).
"');";
2652 if ($this->
db->query($sql)) {
2669 global $conf, $langs;
2674 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'commande_fournisseur';
2675 $sql .=
" SET fk_statut = ".$status;
2676 $sql .=
" WHERE rowid = ".((int) $this->
id);
2678 dol_syslog(get_class($this).
"::setStatus", LOG_DEBUG);
2682 $triggerName = array();
2683 $triggerName[0] =
'DRAFT';
2684 $triggerName[1] =
'VALIDATED';
2685 $triggerName[2] =
'APPROVED';
2686 $triggerName[3] =
'ORDERED';
2687 $triggerName[4] =
'RECEIVED_PARTIALLY';
2688 $triggerName[5] =
'RECEIVED_COMPLETELY';
2689 $triggerName[6] =
'CANCELED';
2690 $triggerName[7] =
'CANCELED';
2691 $triggerName[9] =
'REFUSED';
2694 $result = $this->
call_trigger(
"ORDER_SUPPLIER_STATUS_".$triggerName[$status], $user);
2701 $this->error = $this->
db->lasterror();
2702 dol_syslog(get_class($this).
"::setStatus ".$this->error);
2706 $this->statut = $status;
2707 $this->
db->commit();
2710 $this->
db->rollback();
2738 public function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type =
'HT', $info_bits = 0, $type = 0, $notrigger = 0, $date_start =
'', $date_end =
'', $array_options = 0, $fk_unit =
null, $pu_ht_devise = 0, $ref_supplier =
'')
2740 global $mysoc, $conf, $langs;
2741 dol_syslog(get_class($this).
"::updateline $rowid, $desc, $pu, $qty, $remise_percent, $txtva, $price_base_type, $info_bits, $type, $fk_unit");
2742 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
2746 if ($this->brouillon) {
2751 if (empty($info_bits)) {
2754 if (empty($txtva)) {
2757 if (empty($txlocaltax1)) {
2760 if (empty($txlocaltax2)) {
2763 if (empty($remise)) {
2766 if (empty($remise_percent)) {
2767 $remise_percent = 0;
2770 $remise_percent =
price2num($remise_percent);
2776 $pu_ht_devise =
price2num($pu_ht_devise);
2777 if (!preg_match(
'/\((.*)\)/', $txtva)) {
2787 if ($date_start && $date_end && $date_start > $date_end) {
2788 $langs->load(
"errors");
2789 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
2805 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
2806 $vat_src_code = $reg[1];
2807 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
2810 $tabprice =
calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
2811 $total_ht = $tabprice[0];
2812 $total_tva = $tabprice[1];
2813 $total_ttc = $tabprice[2];
2814 $total_localtax1 = $tabprice[9];
2815 $total_localtax2 = $tabprice[10];
2816 $pu_ht = $tabprice[3];
2817 $pu_tva = $tabprice[4];
2818 $pu_ttc = $tabprice[5];
2821 $multicurrency_total_ht = $tabprice[16];
2822 $multicurrency_total_tva = $tabprice[17];
2823 $multicurrency_total_ttc = $tabprice[18];
2824 $pu_ht_devise = $tabprice[19];
2826 $localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
2827 $localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
2831 $this->line->fetch($rowid);
2833 $oldline = clone $this->line;
2834 $this->line->oldline = $oldline;
2836 $this->line->context = $this->context;
2838 $this->line->fk_commande = $this->id;
2840 $this->line->desc = $desc;
2843 if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) {
2844 if ($qty < $this->line->packaging) {
2845 $qty = $this->line->packaging;
2847 if (!empty($this->line->packaging) && ($qty % $this->line->packaging) > 0) {
2848 $coeff = intval($qty / $this->line->packaging) + 1;
2849 $qty = $this->line->packaging * $coeff;
2850 setEventMessage($langs->trans(
'QtyRecalculatedWithPackaging'),
'mesgs');
2855 $this->line->qty = $qty;
2856 $this->line->ref_supplier = $ref_supplier;
2858 $this->line->vat_src_code = $vat_src_code;
2859 $this->line->tva_tx = $txtva;
2860 $this->line->localtax1_tx = $txlocaltax1;
2861 $this->line->localtax2_tx = $txlocaltax2;
2862 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
2863 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
2864 $this->line->remise_percent = $remise_percent;
2865 $this->line->subprice = $pu_ht;
2866 $this->line->info_bits = $info_bits;
2867 $this->line->total_ht = $total_ht;
2868 $this->line->total_tva = $total_tva;
2869 $this->line->total_localtax1 = $total_localtax1;
2870 $this->line->total_localtax2 = $total_localtax2;
2871 $this->line->total_ttc = $total_ttc;
2872 $this->line->product_type = $type;
2873 $this->line->special_code = $oldline->special_code;
2874 $this->line->rang = $oldline->rang;
2875 $this->line->origin = $this->origin;
2876 $this->line->fk_unit = $fk_unit;
2878 $this->line->date_start = $date_start;
2879 $this->line->date_end = $date_end;
2882 $this->line->fk_multicurrency = $this->fk_multicurrency;
2883 $this->line->multicurrency_code = $this->multicurrency_code;
2884 $this->line->multicurrency_subprice = $pu_ht_devise;
2885 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
2886 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
2887 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
2889 $this->line->subprice = $pu_ht;
2890 $this->line->price = $this->line->subprice;
2892 $this->line->remise_percent = $remise_percent;
2894 if (is_array($array_options) && count($array_options) > 0) {
2896 foreach ($array_options as $key => $value) {
2897 $this->line->array_options[$key] = $array_options[$key];
2901 $result = $this->line->update($notrigger);
2907 $this->
db->commit();
2910 $this->error = $this->
db->lasterror();
2911 $this->
db->rollback();
2915 $this->error =
"Order status makes operation forbidden";
2916 dol_syslog(get_class($this).
"::updateline ".$this->error, LOG_ERR);
2931 global $user, $langs, $conf;
2933 include_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.product.class.php';
2935 dol_syslog(get_class($this).
"::initAsSpecimen");
2942 $sql =
"SELECT rowid";
2943 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
2944 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
2945 $sql .= $this->
db->order(
"rowid",
"ASC");
2946 $sql .= $this->
db->plimit(1);
2949 $obj = $this->
db->fetch_object(
$resql);
2950 $prodid = $obj->rowid;
2955 $this->
ref =
'SPECIMEN';
2956 $this->specimen = 1;
2959 $this->date_commande = $now;
2960 $this->date_lim_reglement = $this->date + 3600 * 24 * 30;
2961 $this->cond_reglement_code =
'RECEP';
2962 $this->mode_reglement_code =
'CHQ';
2964 $this->note_public =
'This is a comment (public)';
2965 $this->note_private =
'This is a comment (private)';
2967 $this->multicurrency_tx = 1;
2968 $this->multicurrency_code = $conf->currency;
2975 while ($xnbp < $nbp) {
2977 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
2979 $line->subprice = 100;
2981 $line->tva_tx = 19.6;
2982 $line->localtax1_tx = 0;
2983 $line->localtax2_tx = 0;
2985 $line->total_ht = 50;
2986 $line->total_ttc = 59.8;
2987 $line->total_tva = 9.8;
2988 $line->remise_percent = 50;
2990 $line->total_ht = 100;
2991 $line->total_ttc = 119.6;
2992 $line->total_tva = 19.6;
2993 $line->remise_percent = 00;
2995 $line->fk_product = $prodid;
2997 $this->lines[$xnbp] = $line;
2999 $this->total_ht += $line->total_ht;
3000 $this->total_tva += $line->total_tva;
3001 $this->total_ttc += $line->total_ttc;
3015 $sql =
'SELECT c.rowid, date_creation as datec, tms as datem, date_valid as date_validation, date_approve as datea, date_approve2 as datea2,';
3016 $sql .=
' fk_user_author, fk_user_modif, fk_user_valid, fk_user_approve, fk_user_approve2';
3017 $sql .=
' FROM '.MAIN_DB_PREFIX.
'commande_fournisseur as c';
3018 $sql .=
' WHERE c.rowid = '.((int) $id);
3020 $result = $this->
db->query($sql);
3022 if ($this->
db->num_rows($result)) {
3023 $obj = $this->
db->fetch_object($result);
3024 $this->
id = $obj->rowid;
3025 if ($obj->fk_user_author) {
3026 $this->user_creation_id = $obj->fk_user_author;
3028 if ($obj->fk_user_valid) {
3029 $this->user_validation_id = $obj->fk_user_valid;
3031 if ($obj->fk_user_modif) {
3032 $this->user_modification_id = $obj->fk_user_modif;
3034 if ($obj->fk_user_approve) {
3035 $this->user_approve_id = $obj->fk_user_approve;
3037 if ($obj->fk_user_approve2) {
3038 $this->user_approve_id2 = $obj->fk_user_approve2;
3041 $this->date_creation = $this->
db->jdate($obj->datec);
3042 $this->date_modification = $this->
db->jdate($obj->datem);
3043 $this->date_approve = $this->
db->jdate($obj->datea);
3044 $this->date_approve2 = $this->
db->jdate($obj->datea2);
3045 $this->date_validation = $this->
db->jdate($obj->date_validation);
3047 $this->
db->free($result);
3062 global $conf, $user;
3064 $this->nb = array();
3067 $sql =
"SELECT count(co.rowid) as nb";
3068 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commande_fournisseur as co";
3069 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON co.fk_soc = s.rowid";
3070 if (empty($user->rights->societe->client->voir) && !$user->socid) {
3071 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
3072 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3075 $sql .=
" ".$clause.
" co.entity IN (".
getEntity(
'supplier_order').
")";
3079 while ($obj = $this->
db->fetch_object(
$resql)) {
3080 $this->nb[
"supplier_orders"] = $obj->nb;
3086 $this->error = $this->
db->error();
3102 global $conf, $langs;
3104 $sql =
"SELECT c.rowid, c.date_creation as datec, c.date_commande, c.fk_statut, c.date_livraison as delivery_date, c.total_ht";
3105 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commande_fournisseur as c";
3106 if (empty($user->rights->societe->client->voir) && !$user->socid) {
3107 $sql .=
" JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
3109 $sql .=
" WHERE c.entity = ".$conf->entity;
3110 if ($mode ===
'awaiting') {
3111 $sql .=
" AND c.fk_statut IN (".self::STATUS_ORDERSENT.
", ".self::STATUS_RECEIVED_PARTIALLY.
")";
3113 $sql .=
" AND c.fk_statut IN (".self::STATUS_VALIDATED.
", ".self::STATUS_ACCEPTED.
")";
3116 $sql .=
" AND c.fk_soc = ".((int) $user->socid);
3124 $response->warning_delay = $conf->commande->fournisseur->warning_delay / 60 / 60 / 24;
3125 $response->label = $langs->trans(
"SuppliersOrdersToProcess");
3126 $response->labelShort = $langs->trans(
"Opened");
3127 $response->url = DOL_URL_ROOT.
'/fourn/commande/list.php?search_status=1,2&mainmenu=commercial&leftmenu=orders_suppliers';
3130 if ($mode ===
'awaiting') {
3131 $response->label = $langs->trans(
"SuppliersOrdersAwaitingReception");
3132 $response->labelShort = $langs->trans(
"AwaitingReception");
3133 $response->url = DOL_URL_ROOT.
'/fourn/commande/list.php?search_status=3,4&mainmenu=commercial&leftmenu=orders_suppliers';
3136 while ($obj = $this->
db->fetch_object(
$resql)) {
3137 $commandestatic->delivery_date = $this->
db->jdate($obj->delivery_date);
3138 $commandestatic->date_commande = $this->
db->jdate($obj->date_commande);
3139 $commandestatic->statut = $obj->fk_statut;
3141 $response->nbtodo++;
3142 $response->total += $obj->total_ht;
3144 if ($commandestatic->hasDelay()) {
3145 $response->nbtodolate++;
3151 $this->error = $this->
db->error();
3166 if ($this->methode_commande_id > 0) {
3167 $sql =
"SELECT rowid, code, libelle as label";
3168 $sql .=
" FROM ".MAIN_DB_PREFIX.
'c_input_method';
3169 $sql .=
" WHERE active=1 AND rowid = ".((int) $this->methode_commande_id);
3174 $obj = $this->
db->fetch_object(
$resql);
3176 $string = $langs->trans($obj->code);
3177 if ($string == $obj->code) {
3178 $string = $obj->label !=
'-' ? $obj->label :
'';
3201 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3203 global $conf, $langs;
3208 if (!empty($this->model_pdf)) {
3209 $modele = $this->model_pdf;
3210 } elseif (!empty($conf->global->COMMANDE_SUPPLIER_ADDON_PDF)) {
3211 $modele = $conf->global->COMMANDE_SUPPLIER_ADDON_PDF;
3215 if (empty($modele)) {
3218 $langs->load(
"suppliers");
3219 $outputlangs->load(
"products");
3221 $modelpath =
"core/modules/supplier_order/doc/";
3222 $result = $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
3235 if (empty($this->lines)) {
3242 foreach ($this->lines as $line) {
3243 if ($line->fk_product > 0) {
3244 $idp = $obj->find_min_price_product_fournisseur($line->fk_product, $line->qty);
3247 if ($obj->delivery_time_days > $nb) {
3248 $nb = $obj->delivery_time_days;
3257 return $nb.
' '.$langs->trans(
'Days');
3269 return $user->rights->fournisseur->commande;
3284 'commande_fournisseur'
3301 'commande_fournisseurdet'
3318 if (empty($this->delivery_date) && !empty($this->date_livraison)) {
3319 $this->delivery_date = $this->date_livraison;
3322 if ($this->statut == self::STATUS_ORDERSENT || $this->statut == self::STATUS_RECEIVED_PARTIALLY) {
3324 if (!empty($this->delivery_date)) {
3325 $date_to_test = $this->delivery_date;
3326 return $date_to_test && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay);
3334 $date_to_test = $this->date_commande;
3336 return ($this->statut > 0 && $this->statut < 5) && $date_to_test && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay);
3349 global $conf, $langs;
3351 if (empty($this->delivery_date) && !empty($this->date_livraison)) {
3352 $this->delivery_date = $this->date_livraison;
3357 if ($this->statut == self::STATUS_ORDERSENT || $this->statut == self::STATUS_RECEIVED_PARTIALLY) {
3358 if (!empty($this->delivery_date)) {
3359 $text = $langs->trans(
"DeliveryDate").
' '.
dol_print_date($this->delivery_date,
'day');
3361 $text = $langs->trans(
"OrderDate").
' '.
dol_print_date($this->date_commande,
'day');
3364 $text = $langs->trans(
"OrderDate").
' '.
dol_print_date($this->date_commande,
'day');
3367 $text .=
' '.($conf->commande->fournisseur->warning_delay > 0 ?
'+' :
'-').
' '.round(abs($conf->commande->fournisseur->warning_delay) / 3600 / 24, 1).
' '.$langs->trans(
"days").
' < '.$langs->trans(
"Today");
3384 global $conf, $langs;
3386 if ((
isModEnabled(
"fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) ||
isModEnabled(
"supplier_order")) {
3387 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.dispatch.class.php';
3389 $qtydelivered = array();
3390 $qtywished = array();
3393 $filter = array(
't.fk_commande'=>$this->
id);
3394 if (!empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) {
3395 $filter[
't.status'] = 1;
3398 $ret = $supplierorderdispatch->fetchAll(
'',
'', 0, 0, $filter);
3400 $this->error = $supplierorderdispatch->error; $this->errors = $supplierorderdispatch->errors;
3403 if (is_array($supplierorderdispatch->lines) && count($supplierorderdispatch->lines) > 0) {
3404 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
3408 foreach ($supplierorderdispatch->lines as $line) {
3409 $qtydelivered[$line->fk_product] += $line->qty;
3411 foreach ($this->lines as $line) {
3413 if (empty($conf->global->STOCK_SUPPORTS_SERVICES) && $line->product_type > 0) {
3416 $qtywished[$line->fk_product] += $line->qty;
3420 $diff_array = array_diff_assoc($qtydelivered, $qtywished);
3421 $keysinwishednotindelivered = array_diff(array_keys($qtywished), array_keys($qtydelivered));
3422 $keysindeliverednotinwished = array_diff(array_keys($qtydelivered), array_keys($qtywished));
3430 if (count($diff_array) == 0 && count($keysinwishednotindelivered) == 0 && count($keysindeliverednotinwished) == 0) {
3431 if ($closeopenorder) {
3433 $ret = $this->
Livraison($user, $date_liv,
'tot', $comment);
3441 $ret = $this->
Livraison($user, $date_liv,
'par', $comment);
3447 } elseif (!empty($conf->global->SUPPLIER_ORDER_MORE_THAN_WISHED)) {
3452 if (count($diff_array) > 0) {
3456 foreach ($diff_array as $key => $value) {
3458 if ($qtydelivered[$key] >= $qtywished[$key]) {
3465 if ($close == count($diff_array)) {
3467 if ($closeopenorder) {
3468 $ret = $this->
Livraison($user, $date_liv,
'tot', $comment);
3475 $ret = $this->
Livraison($user, $date_liv,
'par', $comment);
3483 $ret = $this->
Livraison($user, $date_liv,
'par', $comment);
3491 $ret = $this->
Livraison($user, $date_liv,
'par', $comment);
3513 $this->receptions = array();
3515 dol_syslog(get_class($this).
"::loadReceptions", LOG_DEBUG);
3517 $sql =
'SELECT cd.rowid, cd.fk_product,';
3518 $sql .=
' sum(cfd.qty) as qty';
3519 $sql .=
' FROM '.MAIN_DB_PREFIX.
'commande_fournisseur_dispatch as cfd,';
3520 if ($filtre_statut >= 0) {
3521 $sql .=
' '.MAIN_DB_PREFIX.
'reception as e,';
3523 $sql .=
' '.MAIN_DB_PREFIX.
'commande_fournisseurdet as cd';
3525 if ($filtre_statut >= 0) {
3526 $sql .=
' cfd.fk_reception = e.rowid AND';
3528 $sql .=
' cfd.fk_commandefourndet = cd.rowid';
3529 $sql .=
' AND cd.fk_commande ='.((int) $this->
id);
3530 if ($this->fk_product > 0) {
3531 $sql .=
' AND cd.fk_product = '.((int) $this->fk_product);
3533 if ($filtre_statut >= 0) {
3534 $sql .=
' AND e.fk_statut >= '.((int) $filtre_statut);
3536 $sql .=
' GROUP BY cd.rowid, cd.fk_product';
3540 $num = $this->
db->num_rows(
$resql);
3543 $obj = $this->
db->fetch_object(
$resql);
3544 empty($this->receptions[$obj->rowid]) ? $this->receptions[$obj->rowid] = $obj->qty : $this->receptions[$obj->rowid] += $obj->qty;
3551 $this->error = $this->
db->lasterror();
3567 public $element =
'commande_fournisseurdet';
3572 public $table_element =
'commande_fournisseurdet';
3580 public $fk_commande;
3586 public $fk_parent_line;
3594 public $special_code = 0;
3611 public $ref_supplier;
3635 $sql =
'SELECT cd.rowid, cd.fk_commande, cd.fk_product, cd.product_type, cd.description, cd.qty, cd.tva_tx, cd.special_code,';
3636 $sql .=
' cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.ref as ref_supplier,';
3637 $sql .=
' cd.remise, cd.remise_percent, cd.subprice,';
3638 $sql .=
' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_ttc,';
3639 $sql .=
' cd.total_localtax1, cd.total_localtax2,';
3640 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
3641 $sql .=
' cd.date_start, cd.date_end, cd.fk_unit,';
3642 $sql .=
' cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc,';
3643 $sql .=
' c.fk_soc as socid';
3644 $sql .=
' FROM '.MAIN_DB_PREFIX.
'commande_fournisseur as c, '.MAIN_DB_PREFIX.
'commande_fournisseurdet as cd';
3645 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON cd.fk_product = p.rowid';
3646 $sql .=
' WHERE cd.fk_commande = c.rowid AND cd.rowid = '.((int) $rowid);
3648 $result = $this->
db->query($sql);
3650 $objp = $this->
db->fetch_object($result);
3652 if (!empty($objp)) {
3653 $this->
rowid = $objp->rowid;
3654 $this->
id = $objp->rowid;
3655 $this->fk_commande = $objp->fk_commande;
3656 $this->desc = $objp->description;
3657 $this->qty = $objp->qty;
3658 $this->ref_fourn = $objp->ref_supplier;
3659 $this->ref_supplier = $objp->ref_supplier;
3660 $this->subprice = $objp->subprice;
3661 $this->tva_tx = $objp->tva_tx;
3662 $this->localtax1_tx = $objp->localtax1_tx;
3663 $this->localtax2_tx = $objp->localtax2_tx;
3664 $this->localtax1_type = $objp->localtax1_type;
3665 $this->localtax2_type = $objp->localtax2_type;
3666 $this->remise = $objp->remise;
3667 $this->remise_percent = $objp->remise_percent;
3668 $this->fk_product = $objp->fk_product;
3669 $this->info_bits = $objp->info_bits;
3670 $this->total_ht = $objp->total_ht;
3671 $this->total_tva = $objp->total_tva;
3672 $this->total_localtax1 = $objp->total_localtax1;
3673 $this->total_localtax2 = $objp->total_localtax2;
3674 $this->total_ttc = $objp->total_ttc;
3675 $this->product_type = $objp->product_type;
3676 $this->special_code = $objp->special_code;
3678 $this->
ref = $objp->product_ref;
3680 $this->product_ref = $objp->product_ref;
3681 $this->product_label = $objp->product_label;
3682 $this->product_desc = $objp->product_desc;
3684 if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) {
3689 $sqlsearchpackage =
'SELECT rowid, packaging FROM '.MAIN_DB_PREFIX.
"product_fournisseur_price";
3690 $sqlsearchpackage .=
' WHERE entity IN ('.getEntity(
'product_fournisseur_price').
")";
3691 $sqlsearchpackage .=
" AND fk_product = ".((int) $objp->fk_product);
3692 $sqlsearchpackage .=
" AND ref_fourn = '".$this->db->escape($objp->ref_supplier).
"'";
3693 $sqlsearchpackage .=
" AND quantity <= ".((float) $objp->qty);
3694 $sqlsearchpackage .=
" AND (packaging IS NULL OR packaging = 0 OR packaging <= ".((float) $objp->qty).
")";
3695 $sqlsearchpackage .=
" AND fk_soc = ".((int) $objp->socid);
3696 $sqlsearchpackage .=
" ORDER BY packaging ASC";
3697 $sqlsearchpackage .=
" LIMIT 1";
3699 $resqlsearchpackage = $this->
db->query($sqlsearchpackage);
3700 if ($resqlsearchpackage) {
3701 $objsearchpackage = $this->
db->fetch_object($resqlsearchpackage);
3702 if ($objsearchpackage) {
3703 $this->fk_fournprice = $objsearchpackage->rowid;
3704 $this->packaging = $objsearchpackage->packaging;
3707 $this->error = $this->
db->lasterror();
3712 $this->date_start = $this->
db->jdate($objp->date_start);
3713 $this->date_end = $this->
db->jdate($objp->date_end);
3714 $this->fk_unit = $objp->fk_unit;
3716 $this->multicurrency_subprice = $objp->multicurrency_subprice;
3717 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
3718 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
3719 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
3723 $this->
db->free($result);
3726 $this->error =
'Supplier order line with id='.$rowid.
' not found';
3727 dol_syslog(get_class($this).
"::fetch Error ".$this->error, LOG_ERR);
3744 global $conf, $user;
3748 dol_syslog(get_class($this).
"::insert rang=".$this->rang);
3751 if (empty($this->tva_tx)) {
3754 if (empty($this->localtax1_tx)) {
3755 $this->localtax1_tx = 0;
3757 if (empty($this->localtax2_tx)) {
3758 $this->localtax2_tx = 0;
3760 if (empty($this->localtax1_type)) {
3761 $this->localtax1_type =
'0';
3763 if (empty($this->localtax2_type)) {
3764 $this->localtax2_type =
'0';
3766 if (empty($this->total_localtax1)) {
3767 $this->total_localtax1 = 0;
3769 if (empty($this->total_localtax2)) {
3770 $this->total_localtax2 = 0;
3772 if (empty($this->rang)) {
3775 if (empty($this->remise_percent)) {
3776 $this->remise_percent = 0;
3778 if (empty($this->info_bits)) {
3779 $this->info_bits = 0;
3781 if (empty($this->special_code)) {
3782 $this->special_code = 0;
3784 if (empty($this->fk_parent_line)) {
3785 $this->fk_parent_line = 0;
3787 if (empty($this->pa_ht)) {
3792 if (!empty($this->multicurrency_code)) {
3795 if (empty($this->fk_multicurrency)) {
3796 $this->multicurrency_code = $conf->currency;
3797 $this->fk_multicurrency = 0;
3798 $this->multicurrency_tx = 1;
3802 if ($this->product_type < 0) {
3809 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element;
3810 $sql .=
" (fk_commande, label, description, date_start, date_end,";
3811 $sql .=
" fk_product, product_type, special_code, rang,";
3812 $sql .=
" qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, remise_percent, subprice, ref,";
3813 $sql .=
" total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_unit,";
3814 $sql .=
" fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc";
3816 $sql .=
" VALUES (".$this->fk_commande.
", '".$this->
db->escape($this->label).
"','".$this->
db->escape($this->desc).
"',";
3817 $sql .=
" ".($this->date_start ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
",";
3818 $sql .=
" ".($this->date_end ?
"'".$this->db->idate($this->date_end).
"'" :
"null").
",";
3819 if ($this->fk_product) {
3820 $sql .= $this->fk_product.
",";
3824 $sql .=
"'".$this->db->escape($this->product_type).
"',";
3825 $sql .=
"'".$this->db->escape($this->special_code).
"',";
3826 $sql .=
"'".$this->db->escape($this->rang).
"',";
3827 $sql .=
"'".$this->db->escape($this->qty).
"', ";
3828 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
3829 $sql .=
" ".price2num($this->tva_tx).
", ";
3830 $sql .=
" ".price2num($this->localtax1_tx).
",";
3831 $sql .=
" ".price2num($this->localtax2_tx).
",";
3832 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
3833 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
3834 $sql .=
" ".((float) $this->remise_percent).
", ".
price2num($this->subprice,
'MU').
", '".$this->
db->escape($this->ref_supplier).
"',";
3835 $sql .=
" ".price2num($this->total_ht).
",";
3836 $sql .=
" ".price2num($this->total_tva).
",";
3837 $sql .=
" ".price2num($this->total_localtax1).
",";
3838 $sql .=
" ".price2num($this->total_localtax2).
",";
3839 $sql .=
" ".price2num($this->total_ttc).
",";
3840 $sql .= ($this->fk_unit ?
"'".$this->db->escape($this->fk_unit).
"'" :
"null");
3841 $sql .=
", ".($this->fk_multicurrency ? ((int) $this->fk_multicurrency) :
"null");
3842 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
3843 $sql .=
", ".($this->multicurrency_subprice ?
price2num($this->multicurrency_subprice) :
'0');
3844 $sql .=
", ".($this->multicurrency_total_ht ?
price2num($this->multicurrency_total_ht) :
'0');
3845 $sql .=
", ".($this->multicurrency_total_tva ?
price2num($this->multicurrency_total_tva) :
'0');
3846 $sql .=
", ".($this->multicurrency_total_ttc ?
price2num($this->multicurrency_total_ttc) :
'0');
3849 dol_syslog(get_class($this).
"::insert", LOG_DEBUG);
3852 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
3853 $this->
rowid = $this->id;
3862 if (!$error && !$notrigger) {
3864 $result = $this->
call_trigger(
'LINEORDER_SUPPLIER_CREATE', $user);
3872 $this->
db->commit();
3876 foreach ($this->errors as $errmsg) {
3877 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
3878 $this->errors[] = ($this->errors ?
', '.$errmsg : $errmsg);
3880 $this->
db->rollback();
3883 $this->errors[] = $this->
db->error();
3884 $this->
db->rollback();
3896 global $conf, $user;
3903 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
3904 $sql .=
" description='".$this->db->escape($this->desc).
"'";
3905 $sql .=
", ref='".$this->db->escape($this->ref_supplier).
"'";
3906 $sql .=
", subprice='".price2num($this->subprice).
"'";
3908 $sql .=
", remise_percent='".price2num($this->remise_percent).
"'";
3910 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"'";
3911 $sql .=
", tva_tx='".price2num($this->tva_tx).
"'";
3912 $sql .=
", localtax1_tx='".price2num($this->localtax1_tx).
"'";
3913 $sql .=
", localtax2_tx='".price2num($this->localtax2_tx).
"'";
3914 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
3915 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
3916 $sql .=
", qty='".price2num($this->qty).
"'";
3917 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
3918 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
3919 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
3920 $sql .=
", total_ht='".price2num($this->total_ht).
"'";
3921 $sql .=
", total_tva='".price2num($this->total_tva).
"'";
3922 $sql .=
", total_localtax1='".price2num($this->total_localtax1).
"'";
3923 $sql .=
", total_localtax2='".price2num($this->total_localtax2).
"'";
3924 $sql .=
", total_ttc='".price2num($this->total_ttc).
"'";
3925 $sql .=
", product_type=".$this->product_type;
3926 $sql .=
", special_code=".(!empty($this->special_code) ? $this->special_code : 0);
3927 $sql .= ($this->fk_unit ?
", fk_unit='".$this->db->escape($this->fk_unit).
"'" :
", fk_unit=null");
3930 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice).
"";
3931 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht).
"";
3932 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva).
"";
3933 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc).
"";
3935 $sql .=
" WHERE rowid = ".((int) $this->
id);
3937 dol_syslog(get_class($this).
"::updateline", LOG_DEBUG);
3947 if (!$error && !$notrigger) {
3949 $result = $this->
call_trigger(
'LINEORDER_SUPPLIER_MODIFY', $user);
3951 $this->
db->rollback();
3958 $this->
db->commit();
3961 $this->
db->rollback();
3965 $this->error = $this->
db->lasterror();
3966 $this->
db->rollback();
3977 public function delete($notrigger = 0)
3988 $this->
db->rollback();
3992 $sql1 =
'UPDATE '.MAIN_DB_PREFIX.
"commandedet SET fk_commandefourndet = NULL WHERE rowid=".((int) $this->
id);
3995 $this->
db->rollback();
3999 $sql2 =
'DELETE FROM '.MAIN_DB_PREFIX.
"commande_fournisseurdet WHERE rowid=".((int) $this->
id);
4006 $result = $this->
call_trigger(
'LINEORDER_SUPPLIER_DELETE', $user);
4014 $this->
db->commit();
4018 foreach ($this->errors as $errmsg) {
4019 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
4020 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4022 $this->
db->rollback();
4025 $this->error = $this->
db->lasterror();
Class to manage table commandefournisseurdispatch.
Class to manage predefined suppliers products.
const STATUS_CANCELED_AFTER_ORDER
Order canceled/never received.
const STATUS_RECEIVED_PARTIALLY
Received partially.
setDeliveryDate($user, $delivery_date, $notrigger=0)
Set the planned delivery date.
updateFromCommandeClient($user, $idc, $comclientid)
Update a supplier order from a sales order.
deleteline($idline, $notrigger=0)
Delete line.
load_state_board()
Charge indicateurs this->nb de tableau de bord.
getNomUrl($withpicto=0, $option='', $notooltip=0, $save_lastsearch_value=-1, $addlinktonotes=0)
Return clicable name (with picto eventually)
loadReceptions($filtre_statut=-1)
Load array this->receptions of lines of shipments with nb of products sent for each order line Note: ...
$fields
'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortf...
refuse($user)
Refuse an order.
set_date_livraison($user, $delivery_date, $notrigger=0)
Set delivery date.
info($id)
Charge les informations d'ordre info dans l'objet facture.
const STATUS_CANCELED
Order canceled.
getNextNumRef($soc)
Returns the following order reference not used depending on the numbering model activated defined wit...
fetch_lines($only_product=0)
Load array lines.
getInputMethod()
Returns the translated input method of object (defined if $this->methode_commande_id > 0).
const STATUS_VALIDATED
Validated status.
const STATUS_RECEIVED_COMPLETELY
Received completely.
addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $fk_prod_fourn_price=0, $ref_supplier='', $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $type=0, $info_bits=0, $notrigger=false, $date_start=null, $date_end=null, $array_options=0, $fk_unit=null, $pu_ht_devise=0, $origin='', $origin_id=0, $rang=-1, $special_code=0)
Add order line.
calcAndSetStatusDispatch(User $user, $closeopenorder=1, $comment='')
Calc status regarding to dispatched stock.
updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $notrigger=0, $date_start='', $date_end='', $array_options=0, $fk_unit=null, $pu_ht_devise=0, $ref_supplier='')
Update line.
set_id_projet($user, $id_projet, $notrigger=0)
Set the id projet.
const STATUS_DRAFT
Draft status.
showDelay()
Show the customer delayed info.
approve($user, $idwarehouse=0, $secondlevel=0)
Approve a supplier order.
__construct($db)
Constructor.
Cancel($user, $idwarehouse=-1)
Cancel an approved order.
valid($user, $idwarehouse=0, $notrigger=0)
Validate an order.
create($user, $notrigger=0)
Create order with draft status.
update(User $user, $notrigger=0)
Update Supplier Order.
dispatchProduct($user, $product, $qty, $entrepot, $price=0, $comment='', $eatby='', $sellby='', $batch='', $fk_commandefourndet=0, $notrigger=0)
Save a receiving into the tracking table of receiving (commande_fournisseur_dispatch) and add product...
createFromClone(User $user, $socid=0, $notrigger=0)
Load an object from its id and create a new one in database.
static replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template model.
const STATUS_ACCEPTED
Accepted.
const STATUS_ORDERSENT
Order sent, shipment on process.
commande($user, $date, $methode, $comment='')
Submit a supplier order to supplier.
getRights()
Returns the rights used for this class.
load_board($user, $mode='opened')
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
getMaxDeliveryTimeDay($langs)
Return the max number delivery delay in day.
fetch($id, $ref='')
Get object and lines from database.
Livraison($user, $date, $type, $comment)
Set a delivery in database for this supplier order.
getDispachedLines($status=-1)
Return array of dispatched lines waiting to be approved for this order.
classifyBilled(User $user)
Class invoiced the supplier order.
initAsSpecimen()
Initialise an instance with random values.
static replaceProduct(DoliDB $db, $origin_id, $dest_id)
Function used to replace a product id with another one.
const SOURCE_ID_REPLENISHMENT
The constant used into source field to track the order was generated by the replenishement feature.
setStatus($user, $status)
Tag order with a particular status.
const STATUS_REFUSED
Refused.
getLibStatut($mode=0)
Return label of the status of object.
get_methodes_commande()
Get list of order methods.
hasDelay()
Is the supplier order delayed? We suppose a purchase ordered as late if a the purchase order has been...
LibStatut($status, $mode=0, $billed=0)
Return label of a status.
Class to manage line orders.
update($notrigger=0)
Update the line object into db.
insert($notrigger=0)
Insert line into database.
fetch($rowid)
Load line order.
__construct($db)
Constructor.
Class to manage customers orders.
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true)
Save a new position (field rang) for details lines.
deleteEcmFiles($mode=0)
Delete related files of object in database.
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
updateRangOfLine($rowid, $rang)
Update position of line (rang)
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='', $f_user=null, $notrigger=0)
Delete all links between an object $this.
update_price($exclspec=0, $roundingadjust='none', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
deleteExtraFields()
Delete all extra fields values for the current object.
static commonReplaceProduct(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a product id with another one.
fetchObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $clause='OR', $alsosametype=1, $orderby='sourcetype', $loadalsoobjects=1)
Fetch array of objects linked to current object (object of enabled modules only).
static commonReplaceThirdparty(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
line_max($fk_parent_line=0)
Get max value used for position of line (rang)
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
add_contact($fk_socpeople, $type_contact, $source='external', $notrigger=0)
Add a link between element $this->element and a contact.
Superclass for orders classes.
Superclass for orders classes.
Class to manage Dolibarr database access.
Class to manage stock movements.
static getIdFromCode($dbs, $code)
Get id of currency from code.
static getIdAndTxFromCode($dbs, $code, $date_document='')
Get id and rate of currency from code.
Class to manage predefined suppliers products.
Class to manage products or services.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
setEventMessage($mesgs, $style='mesgs')
Set event message in dol_events session object.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array='', $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.
$conf db
API class for accounts.