43require_once DOL_DOCUMENT_ROOT.
'/core/class/commoninvoice.class.php';
44require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
45require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
46require_once DOL_DOCUMENT_ROOT.
'/societe/class/client.class.php';
47require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
48require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
50if (isModEnabled(
'accounting')) {
51 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formaccounting.class.php';
53if (isModEnabled(
'accounting')) {
54 require_once DOL_DOCUMENT_ROOT.
'/accountancy/class/accountingaccount.class.php';
65 public $element =
'facture';
70 public $table_element =
'facture';
75 public $table_element_line =
'facturedet';
80 public $fk_element =
'fk_facture';
85 public $picto =
'bill';
91 public $ismultientitymanaged = 1;
97 public $restrictiononfksoc = 1;
127 public $fk_user_author;
139 public $fk_user_valid;
146 public $user_modification;
151 public $fk_user_modif;
161 public $date_livraison;
166 public $delivery_date;
178 public $ref_customer;
182 public $remise_absolue;
191 public $total_localtax1;
192 public $total_localtax2;
194 public $revenuestamp;
224 public $linked_objects = array();
226 public $date_lim_reglement;
227 public $cond_reglement_code;
228 public $cond_reglement_doc;
229 public $mode_reglement_code;
239 public $lines = array();
245 public $extraparams = array();
252 public $date_pointoftax;
258 public $fk_multicurrency;
260 public $multicurrency_code;
261 public $multicurrency_tx;
262 public $multicurrency_total_ht;
263 public $multicurrency_total_tva;
264 public $multicurrency_total_ttc;
265 public $multicurrency_total_localtax1;
266 public $multicurrency_total_localtax2;
271 public $situation_cycle_ref;
276 public $situation_counter;
281 public $situation_final;
286 public $tab_previous_situation_invoice = array();
291 public $tab_next_situation_invoice = array();
298 public $retained_warranty;
303 public $retained_warranty_date_limit;
308 public $retained_warranty_fk_cond_reglement;
340 public $fields = array(
341 'rowid' =>array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>1),
342 'ref' =>array(
'type'=>
'varchar(30)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>5),
343 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>20,
'index'=>1),
344 'ref_client' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefCustomer',
'enabled'=>1,
'visible'=>-1,
'position'=>10),
345 'ref_ext' =>array(
'type'=>
'varchar(255)',
'label'=>
'Ref ext',
'enabled'=>1,
'visible'=>0,
'position'=>12),
346 'type' =>array(
'type'=>
'smallint(6)',
'label'=>
'Type',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>15),
348 'fk_soc' =>array(
'type'=>
'integer:Societe:societe/class/societe.class.php',
'label'=>
'ThirdParty',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>50),
349 'datef' =>array(
'type'=>
'date',
'label'=>
'DateInvoice',
'enabled'=>1,
'visible'=>1,
'position'=>20),
350 'date_valid' =>array(
'type'=>
'date',
'label'=>
'DateValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>22),
351 'date_lim_reglement' =>array(
'type'=>
'date',
'label'=>
'DateDue',
'enabled'=>1,
'visible'=>1,
'position'=>25),
352 'date_closing' =>array(
'type'=>
'datetime',
'label'=>
'Date closing',
'enabled'=>1,
'visible'=>-1,
'position'=>30),
353 'paye' =>array(
'type'=>
'smallint(6)',
'label'=>
'InvoicePaidCompletely',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>80),
356 'remise_absolue' =>array(
'type'=>
'double',
'label'=>
'CustomerRelativeDiscount',
'enabled'=>1,
'visible'=>-1,
'position'=>91),
358 'close_code' =>array(
'type'=>
'varchar(16)',
'label'=>
'EarlyClosingReason',
'enabled'=>1,
'visible'=>-1,
'position'=>92),
359 'close_note' =>array(
'type'=>
'varchar(128)',
'label'=>
'EarlyClosingComment',
'enabled'=>1,
'visible'=>-1,
'position'=>93),
360 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'AmountHT',
'enabled'=>1,
'visible'=>1,
'position'=>95,
'isameasure'=>1),
361 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'AmountVAT',
'enabled'=>1,
'visible'=>-1,
'position'=>100,
'isameasure'=>1),
362 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'LT1',
'enabled'=>1,
'visible'=>-1,
'position'=>110,
'isameasure'=>1),
363 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'LT2',
'enabled'=>1,
'visible'=>-1,
'position'=>120,
'isameasure'=>1),
364 'revenuestamp' =>array(
'type'=>
'double(24,8)',
'label'=>
'RevenueStamp',
'enabled'=>1,
'visible'=>-1,
'position'=>115,
'isameasure'=>1),
365 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'AmountTTC',
'enabled'=>1,
'visible'=>1,
'position'=>130,
'isameasure'=>1),
366 'fk_facture_source' =>array(
'type'=>
'integer',
'label'=>
'SourceInvoice',
'enabled'=>1,
'visible'=>-1,
'position'=>170),
367 'fk_projet' =>array(
'type'=>
'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)',
'label'=>
'Project',
'enabled'=>1,
'visible'=>-1,
'position'=>175),
368 'fk_account' =>array(
'type'=>
'integer',
'label'=>
'Fk account',
'enabled'=>1,
'visible'=>-1,
'position'=>180),
369 'fk_currency' =>array(
'type'=>
'varchar(3)',
'label'=>
'CurrencyCode',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
370 'fk_cond_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentTerm',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>190),
371 'fk_mode_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentMode',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
372 'note_private' =>array(
'type'=>
'html',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>205),
373 'note_public' =>array(
'type'=>
'html',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>210),
374 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'Model pdf',
'enabled'=>1,
'visible'=>0,
'position'=>215),
375 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>225),
376 'situation_cycle_ref' =>array(
'type'=>
'smallint(6)',
'label'=>
'Situation cycle ref',
'enabled'=>
'$conf->global->INVOICE_USE_SITUATION',
'visible'=>-1,
'position'=>230),
377 'situation_counter' =>array(
'type'=>
'smallint(6)',
'label'=>
'Situation counter',
'enabled'=>
'$conf->global->INVOICE_USE_SITUATION',
'visible'=>-1,
'position'=>235),
378 'situation_final' =>array(
'type'=>
'smallint(6)',
'label'=>
'Situation final',
'enabled'=>
'empty($conf->global->INVOICE_USE_SITUATION) ? 0 : 1',
'visible'=>-1,
'position'=>240),
379 'retained_warranty' =>array(
'type'=>
'double',
'label'=>
'Retained warranty',
'enabled'=>
'$conf->global->INVOICE_USE_RETAINED_WARRANTY',
'visible'=>-1,
'position'=>245),
380 'retained_warranty_date_limit' =>array(
'type'=>
'date',
'label'=>
'Retained warranty date limit',
'enabled'=>
'$conf->global->INVOICE_USE_RETAINED_WARRANTY',
'visible'=>-1,
'position'=>250),
381 'retained_warranty_fk_cond_reglement' =>array(
'type'=>
'integer',
'label'=>
'Retained warranty fk cond reglement',
'enabled'=>
'$conf->global->INVOICE_USE_RETAINED_WARRANTY',
'visible'=>-1,
'position'=>255),
382 'fk_incoterms' =>array(
'type'=>
'integer',
'label'=>
'IncotermCode',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>260),
383 'location_incoterms' =>array(
'type'=>
'varchar(255)',
'label'=>
'IncotermLabel',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>265),
384 'date_pointoftax' =>array(
'type'=>
'date',
'label'=>
'DatePointOfTax',
'enabled'=>
'$conf->global->INVOICE_POINTOFTAX_DATE',
'visible'=>-1,
'position'=>270),
385 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'MulticurrencyID',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>275),
386 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'Currency',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>280),
387 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'CurrencyRate',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>285,
'isameasure'=>1),
388 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountHT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>290,
'isameasure'=>1),
389 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountVAT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>291,
'isameasure'=>1),
390 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountTTC',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>292,
'isameasure'=>1),
391 'fk_fac_rec_source' =>array(
'type'=>
'integer',
'label'=>
'RecurringInvoiceSource',
'enabled'=>1,
'visible'=>-1,
'position'=>305),
392 'last_main_doc' =>array(
'type'=>
'varchar(255)',
'label'=>
'LastMainDoc',
'enabled'=>1,
'visible'=>-1,
'position'=>310),
393 'module_source' =>array(
'type'=>
'varchar(32)',
'label'=>
'POSModule',
'enabled'=>
"(isModEnabled('cashdesk') || isModEnabled('takepos') || getDolGlobalInt('INVOICE_SHOW_POS'))",
'visible'=>-1,
'position'=>315),
394 'pos_source' =>array(
'type'=>
'varchar(32)',
'label'=>
'POSTerminal',
'enabled'=>
"(isModEnabled('cashdesk') || isModEnabled('takepos') || getDolGlobalInt('INVOICE_SHOW_POS'))",
'visible'=>-1,
'position'=>320),
395 'datec' =>array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'enabled'=>1,
'visible'=>-1,
'position'=>500),
396 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'DateModificationShort',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>502),
397 'fk_user_author' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserAuthor',
'enabled'=>1,
'visible'=>-1,
'position'=>506),
398 'fk_user_modif' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserModif',
'enabled'=>1,
'visible'=>-1,
'notnull'=>-1,
'position'=>508),
399 'fk_user_valid' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>510),
400 'fk_user_closing' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserClosing',
'enabled'=>1,
'visible'=>-1,
'position'=>512),
401 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>900),
402 'fk_statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Status',
'enabled'=>1,
'visible'=>1,
'notnull'=>1,
'position'=>1000,
'arrayofkeyval'=>array(0=>
'Draft', 1=>
'Validated', 2=>
'Paid', 3=>
'Abandonned')),
464 const CLOSECODE_DISCOUNTVAT =
'discount_vat';
465 const CLOSECODE_BADDEBT =
'badcustomer';
466 const CLOSECODE_BANKCHARGE =
'bankcharge';
467 const CLOSECODE_OTHER =
'other';
469 const CLOSECODE_ABANDONED =
'abandon';
470 const CLOSECODE_REPLACED =
'replaced';
493 public function create(
User $user, $notrigger = 0, $forceduedate = 0)
495 global $langs, $conf, $mysoc, $hookmanager;
499 if (empty($this->
type)) {
503 $this->ref_client = trim($this->ref_client);
505 $this->note = (isset($this->note) ? trim($this->note) : trim($this->note_private));
506 $this->note_private = (isset($this->note_private) ? trim($this->note_private) :
'');
507 $this->note_public = (isset($this->note_public) ? trim($this->note_public) :
'');
508 if (!$this->cond_reglement_id) {
509 $this->cond_reglement_id = 0;
511 if (!$this->mode_reglement_id) {
512 $this->mode_reglement_id = 0;
514 $this->brouillon = 1;
518 if (!empty($this->multicurrency_code)) {
520 if (empty($this->multicurrency_tx)) {
528 $this->fk_multicurrency = 0;
530 if (empty($this->fk_multicurrency)) {
531 $this->multicurrency_code = $conf->currency;
532 $this->fk_multicurrency = 0;
533 $this->multicurrency_tx = 1;
536 dol_syslog(get_class($this).
"::create user=".$user->id.
" date=".$this->date);
539 if (empty($this->date)) {
540 $this->error =
"Try to create an invoice with an empty parameter (date)";
541 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
545 $result = $soc->fetch($this->socid);
547 $this->error =
"Failed to fetch company: ".$soc->error;
548 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
553 $this->date_creation = $now;
557 $originaldatewhen =
null;
558 $nextdatewhen =
null;
559 $previousdaynextdatewhen =
null;
562 if ($this->fac_rec > 0) {
563 $this->fk_fac_rec_source = $this->fac_rec;
565 require_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture-rec.class.php';
567 $result = $_facrec->fetch($this->fac_rec);
568 $result = $_facrec->fetchObjectLinked(
null,
'',
null,
'',
'OR', 1,
'sourcetype', 0);
571 $originaldatewhen = $_facrec->date_when;
572 $nextdatewhen =
null; $previousdaynextdatewhen =
null;
573 if ($originaldatewhen) {
574 $nextdatewhen =
dol_time_plus_duree($originaldatewhen, $_facrec->frequency, $_facrec->unit_frequency);
578 if (!empty($_facrec->frequency)) {
579 $this->socid = $_facrec->socid;
581 $this->entity = $_facrec->entity;
584 $this->fk_project =
GETPOST(
'projectid',
'int') > 0 ? ((int)
GETPOST(
'projectid',
'int')) : $_facrec->fk_project;
585 $this->note_public = GETPOSTISSET(
'note_public') ?
GETPOST(
'note_public',
'restricthtml') : $_facrec->note_public;
586 $this->note_private = GETPOSTISSET(
'note_private') ?
GETPOST(
'note_private',
'restricthtml') : $_facrec->note_private;
587 $this->model_pdf = GETPOSTISSET(
'model') ?
GETPOST(
'model',
'alpha') : $_facrec->model_pdf;
588 $this->cond_reglement_id =
GETPOST(
'cond_reglement_id',
'int') > 0 ? ((int)
GETPOST(
'cond_reglement_id',
'int')) : $_facrec->cond_reglement_id;
589 $this->mode_reglement_id =
GETPOST(
'mode_reglement_id',
'int') > 0 ? ((int)
GETPOST(
'mode_reglement_id',
'int')) : $_facrec->mode_reglement_id;
590 $this->fk_account =
GETPOST(
'fk_account') > 0 ? ((int)
GETPOST(
'fk_account')) : $_facrec->fk_account;
593 $this->total_ht = $_facrec->total_ht;
594 $this->total_ttc = $_facrec->total_ttc;
597 $this->remise_absolue = $_facrec->remise_absolue;
598 $this->remise_percent = $_facrec->remise_percent;
599 $this->fk_incoterms = $_facrec->fk_incoterms;
600 $this->location_incoterms = $_facrec->location_incoterms;
606 $this->ref_client = trim($this->ref_client);
607 $this->ref_customer = trim($this->ref_customer);
608 $this->note_public = trim($this->note_public);
609 $this->note_private = trim($this->note_private);
610 $this->note_private =
dol_concatdesc($this->note_private, $langs->trans(
"GeneratedFromRecurringInvoice", $_facrec->ref));
612 $this->array_options = $_facrec->array_options;
614 if (!$this->mode_reglement_id) {
615 $this->mode_reglement_id = 0;
617 $this->brouillon = 1;
621 $this->linked_objects = $_facrec->linkedObjectsIds;
626 if ($_facrec->frequency > 0) {
627 dol_syslog(
"This is a recurring invoice so we set date_last_gen and next date_when");
628 if (empty($_facrec->date_when)) {
629 $_facrec->date_when = $now;
631 $next_date = $_facrec->getNextDate();
632 $result = $_facrec->setValueFrom(
'date_last_gen', $now,
'',
null,
'date',
'', $user,
'');
634 $result = $_facrec->setNextDate($next_date, 1);
638 $outputlangs = $langs;
641 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && empty($newlang) && isset($this->thirdparty->default_lang)) {
642 $newlang = $this->thirdparty->default_lang;
644 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && empty($newlang) && isset($this->default_lang)) {
645 $newlang = $this->default_lang;
647 if (!empty($newlang)) {
649 $outputlangs->setDefaultLang($newlang);
655 $substitutionarray[
'__INVOICE_MONTH__'] =
dol_print_date($this->date,
'%m');
658 $substitutionarray[
'__INVOICE_MONTH_TEXT__'] =
dol_print_date($this->date,
'%B');
661 $substitutionarray[
'__INVOICE_YEAR__'] =
dol_print_date($this->date,
'%Y');
664 $substitutionarray[
'__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = (isset($originaldatewhen) ?
dol_print_date($originaldatewhen,
'dayhour') :
'');
665 $substitutionarray[
'__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = (isset($nextdatewhen) ?
dol_print_date($nextdatewhen,
'dayhour') :
'');
666 $substitutionarray[
'__INVOICE_PREVIOUS_DATE_NEXT_INVOICE_AFTER_GEN__'] = (isset($previousdaynextdatewhen) ?
dol_print_date($previousdaynextdatewhen,
'dayhour') :
'');
667 $substitutionarray[
'__INVOICE_COUNTER_CURRENT__'] = $_facrec->nb_gen_done;
668 $substitutionarray[
'__INVOICE_COUNTER_MAX__'] = $_facrec->nb_gen_max;
679 if (empty($forceduedate)) {
685 $this->date_lim_reglement = $duedate;
687 $this->date_lim_reglement = $forceduedate;
691 $socid = $this->socid;
693 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"facture (";
700 $sql .=
", remise_absolue";
701 $sql .=
", remise_percent";
703 $sql .=
", date_pointoftax";
704 $sql .=
", note_private";
705 $sql .=
", note_public";
706 $sql .=
", ref_client";
707 $sql .=
", fk_account";
708 $sql .=
", module_source, pos_source, fk_fac_rec_source, fk_facture_source, fk_user_author, fk_projet";
709 $sql .=
", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf";
710 $sql .=
", situation_cycle_ref, situation_counter, situation_final";
711 $sql .=
", fk_incoterms, location_incoterms";
712 $sql .=
", fk_multicurrency";
713 $sql .=
", multicurrency_code";
714 $sql .=
", multicurrency_tx";
715 $sql .=
", retained_warranty";
716 $sql .=
", retained_warranty_date_limit";
717 $sql .=
", retained_warranty_fk_cond_reglement";
721 $sql .=
", ".setEntity($this);
722 $sql .=
", ".($this->ref_ext ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null");
723 $sql .=
", '".$this->db->escape($this->
type).
"'";
724 $sql .=
", ".((int) $socid);
725 $sql .=
", '".$this->db->idate($this->date_creation).
"'";
726 $sql .=
", ".($this->remise_absolue > 0 ? $this->remise_absolue :
'NULL');
727 $sql .=
", ".($this->remise_percent > 0 ? $this->remise_percent :
'NULL');
728 $sql .=
", '".$this->db->idate($this->date).
"'";
729 $sql .=
", ".(empty($this->date_pointoftax) ?
"null" :
"'".$this->db->idate($this->date_pointoftax).
"'");
730 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
731 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
732 $sql .=
", ".($this->ref_customer ?
"'".$this->db->escape($this->ref_customer).
"'" : ($this->ref_client ?
"'".$this->db->escape($this->ref_client).
"'" :
"null"));
733 $sql .=
", ".($this->fk_account > 0 ? $this->fk_account :
'NULL');
734 $sql .=
", ".($this->module_source ?
"'".$this->db->escape($this->module_source).
"'" :
"null");
735 $sql .=
", ".($this->pos_source !=
'' ?
"'".$this->db->escape($this->pos_source).
"'" :
"null");
736 $sql .=
", ".($this->fk_fac_rec_source ?
"'".$this->db->escape($this->fk_fac_rec_source).
"'" :
"null");
737 $sql .=
", ".($this->fk_facture_source ?
"'".$this->db->escape($this->fk_facture_source).
"'" :
"null");
738 $sql .=
", ".($user->id > 0 ? (int) $user->id :
"null");
739 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
740 $sql .=
", ".((int) $this->cond_reglement_id);
741 $sql .=
", ".((int) $this->mode_reglement_id);
742 $sql .=
", '".$this->db->idate($this->date_lim_reglement).
"'";
743 $sql .=
", ".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null");
744 $sql .=
", ".($this->situation_cycle_ref ?
"'".$this->db->escape($this->situation_cycle_ref).
"'" :
"null");
745 $sql .=
", ".($this->situation_counter ?
"'".$this->db->escape($this->situation_counter).
"'" :
"null");
746 $sql .=
", ".($this->situation_final ? $this->situation_final : 0);
747 $sql .=
", ".(int) $this->fk_incoterms;
748 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
749 $sql .=
", ".(int) $this->fk_multicurrency;
750 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
751 $sql .=
", ".(double) $this->multicurrency_tx;
752 $sql .=
", ".(empty($this->retained_warranty) ?
"0" : $this->db->escape($this->retained_warranty));
753 $sql .=
", ".(!empty($this->retained_warranty_date_limit) ?
"'".$this->db->idate($this->retained_warranty_date_limit).
"'" :
'NULL');
754 $sql .=
", ".(int) $this->retained_warranty_fk_cond_reglement;
757 $resql = $this->db->query($sql);
759 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'facture');
762 $this->
ref =
'(PROV'.$this->id.
')';
763 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"facture SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
765 $resql = $this->db->query($sql);
770 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
771 $this->linked_objects = $this->linkedObjectsIds;
775 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
776 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
777 if (is_array($tmp_origin_id)) {
778 foreach ($tmp_origin_id as $origin_id) {
781 $this->error = $this->db->lasterror();
787 $origin_id = $tmp_origin_id;
790 $this->error = $this->db->lasterror();
798 if (!$error && $this->
id && !empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN) && !empty($this->origin) && !empty($this->origin_id)) {
799 $originforcontact = $this->origin;
800 $originidforcontact = $this->origin_id;
801 if ($originforcontact ==
'shipping') {
802 require_once DOL_DOCUMENT_ROOT.
'/expedition/class/expedition.class.php';
804 $exp->fetch($this->origin_id);
805 $exp->fetchObjectLinked(
null,
'',
null,
'',
'OR', 1,
'sourcetype', 0);
806 if (count($exp->linkedObjectsIds[
'commande']) > 0) {
807 foreach ($exp->linkedObjectsIds[
'commande'] as $key => $value) {
808 $originforcontact =
'commande';
809 if (is_object($value)) {
810 $originidforcontact = $value->id;
812 $originidforcontact = $value;
819 $sqlcontact =
"SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX.
"element_contact as ec, ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
820 $sqlcontact .=
" WHERE element_id = ".((int) $originidforcontact).
" AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$this->db->escape($originforcontact).
"'";
822 $resqlcontact = $this->db->query($sqlcontact);
824 while ($objcontact = $this->db->fetch_object($resqlcontact)) {
826 $this->
add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);
836 if (!$error && empty($this->fac_rec) && count($this->lines) && is_object($this->lines[0])) {
839 dol_syslog(
"There is ".count($this->lines).
" lines that are invoice lines objects");
840 foreach ($this->lines as $i => $val) {
841 $newinvoiceline = $this->lines[$i];
843 $newinvoiceline->context = $this->context;
845 $newinvoiceline->fk_facture = $this->id;
847 $newinvoiceline->origin = $this->lines[$i]->element;
848 $newinvoiceline->origin_id = $this->lines[$i]->id;
851 if ($this->lines[$i]->date_start_fill == 1 && $originaldatewhen) {
852 $newinvoiceline->date_start = $originaldatewhen;
854 if ($this->lines[$i]->date_end_fill == 1 && $previousdaynextdatewhen) {
855 $newinvoiceline->date_end = $previousdaynextdatewhen;
860 if (($newinvoiceline->product_type != 9 && empty($newinvoiceline->fk_parent_line)) || $newinvoiceline->product_type == 9) {
865 $vatrate = $newinvoiceline->tva_tx;
866 if ($newinvoiceline->vat_src_code && ! preg_match(
'/\(.*\)/', $vatrate)) $vatrate.=
' ('.$newinvoiceline->vat_src_code.
')';
868 $newinvoiceline->fk_parent_line = $fk_parent_line;
872 $discount->fetch($newinvoiceline->fk_remise_except);
874 $discountId = $soc->set_remise_except($discount->amount_ht, $user, $discount->description, $discount->tva_tx);
875 $newinvoiceline->fk_remise_except = $discountId;
879 $newinvoiceline->desc,
880 $newinvoiceline->subprice,
881 $newinvoiceline->qty,
883 $newinvoiceline->localtax1_tx,
884 $newinvoiceline->localtax2_tx,
885 $newinvoiceline->fk_product,
886 $newinvoiceline->remise_percent,
887 $newinvoiceline->date_start,
888 $newinvoiceline->date_end,
889 $newinvoiceline->fk_code_ventilation,
890 $newinvoiceline->info_bits,
891 $newinvoiceline->fk_remise_except,
894 $newinvoiceline->product_type,
895 $newinvoiceline->rang,
896 $newinvoiceline->special_code,
897 $newinvoiceline->element,
900 $newinvoiceline->fk_fournprice,
901 $newinvoiceline->pa_ht,
902 $newinvoiceline->label,
903 $newinvoiceline->array_options,
904 $newinvoiceline->situation_percent,
905 $newinvoiceline->fk_prev_id,
906 $newinvoiceline->fk_unit,
907 $newinvoiceline->multicurrency_subprice,
908 $newinvoiceline->ref_ext,
913 if ($result > 0 && $newinvoiceline->product_type == 9) {
914 $fk_parent_line = $result;
918 $this->error = $newinvoiceline->error;
919 $this->errors = $newinvoiceline->errors;
924 } elseif (!$error && empty($this->fac_rec)) {
927 dol_syslog(
"There is ".count($this->lines).
" lines that are array lines");
929 foreach ($this->lines as $i => $val) {
930 $line = $this->lines[$i];
934 if (!is_object($line)) {
935 $line = (object) $line;
940 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
945 $vatrate = $line->tva_tx;
946 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
947 $vatrate .=
' ('.$line->vat_src_code.
')';
950 if (!empty($conf->global->MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION)) {
951 $originid = $line->origin_id;
952 $origintype = $line->origin;
954 $originid = $line->id;
955 $origintype = $this->element;
959 if (empty($line->ref_ext)) {
971 $line->remise_percent,
974 $line->fk_code_ventilation,
976 $line->fk_remise_except,
985 $line->fk_fournprice,
988 $line->array_options,
989 $line->situation_percent,
992 $line->multicurrency_subprice,
997 $this->error = $this->db->lasterror();
999 $this->db->rollback();
1004 if ($result > 0 && $line->product_type == 9) {
1005 $fk_parent_line = $result;
1014 if (!$error && $this->fac_rec > 0) {
1015 foreach ($_facrec->lines as $i => $val) {
1016 if ($_facrec->lines[$i]->fk_product) {
1017 $prod =
new Product($this->db);
1018 $res = $prod->fetch($_facrec->lines[$i]->fk_product);
1029 $tva_tx = $_facrec->lines[$i]->tva_tx.($_facrec->lines[$i]->vat_src_code ?
'('.$_facrec->lines[$i]->vat_src_code.
')' :
'');
1030 $tva_npr = $_facrec->lines[$i]->info_bits;
1031 if (empty($tva_tx)) {
1034 $localtax1_tx = $_facrec->lines[$i]->localtax1_tx;
1035 $localtax2_tx = $_facrec->lines[$i]->localtax2_tx;
1037 $fk_product_fournisseur_price = empty($_facrec->lines[$i]->fk_product_fournisseur_price) ? null : $_facrec->lines[$i]->fk_product_fournisseur_price;
1038 $buyprice = empty($_facrec->lines[$i]->buyprice) ? 0 : $_facrec->lines[$i]->buyprice;
1041 if (!$buyprice && $_facrec->lines[$i]->fk_product > 0) {
1042 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.product.class.php';
1044 $producttmp->fetch($_facrec->lines[$i]->fk_product);
1049 if ($conf->global->MARGIN_TYPE ==
'costprice' && !empty($producttmp->cost_price)) {
1050 $buyprice = $producttmp->cost_price;
1051 } elseif (isModEnabled(
'stock') && ($conf->global->MARGIN_TYPE ==
'costprice' || $conf->global->MARGIN_TYPE ==
'pmp') && !empty($producttmp->pmp)) {
1052 $buyprice = $producttmp->pmp;
1054 if ($producttmp->find_min_price_product_fournisseur($_facrec->lines[$i]->fk_product) > 0) {
1055 if ($producttmp->product_fourn_price_id > 0) {
1056 $buyprice =
price2num($producttmp->fourn_unitprice * (1 - $producttmp->fourn_remise_percent / 100) + $producttmp->fourn_remise,
'MU');
1062 $result_insert = $this->
addline(
1063 $_facrec->lines[$i]->desc,
1064 $_facrec->lines[$i]->subprice,
1065 $_facrec->lines[$i]->qty,
1069 $_facrec->lines[$i]->fk_product,
1070 $_facrec->lines[$i]->remise_percent,
1071 ($_facrec->lines[$i]->date_start_fill == 1 && $originaldatewhen) ? $originaldatewhen :
'',
1072 ($_facrec->lines[$i]->date_end_fill == 1 && $previousdaynextdatewhen) ? $previousdaynextdatewhen :
'',
1078 $_facrec->lines[$i]->product_type,
1079 $_facrec->lines[$i]->rang,
1080 $_facrec->lines[$i]->special_code,
1084 $fk_product_fournisseur_price,
1086 $_facrec->lines[$i]->label,
1087 empty($_facrec->lines[$i]->array_options) ?
null:$_facrec->lines[$i]->array_options,
1090 $_facrec->lines[$i]->fk_unit,
1091 $_facrec->lines[$i]->multicurrency_subprice,
1092 $_facrec->lines[$i]->ref_ext,
1096 if ($result_insert < 0) {
1098 $this->error = $this->db->error();
1117 if (!$error && !$notrigger) {
1127 $this->db->commit();
1130 $this->db->rollback();
1134 $this->error = $langs->trans(
'FailedToUpdatePrice');
1135 $this->db->rollback();
1139 dol_syslog(get_class($this).
"::create error ".$this->error, LOG_ERR);
1140 $this->db->rollback();
1144 $this->error = $this->db->error();
1145 $this->db->rollback();
1163 $facture =
new Facture($this->db);
1169 if (!empty($this->array_options)) {
1170 $facture->array_options = $this->array_options;
1173 foreach ($this->lines as &$line) {
1174 $line->fetch_optionals();
1178 $facture->type = $this->type;
1179 $facture->socid = $this->socid;
1180 $facture->date = $this->date;
1181 $facture->date_pointoftax = $this->date_pointoftax;
1182 $facture->note_public = $this->note_public;
1183 $facture->note_private = $this->note_private;
1184 $facture->ref_client = $this->ref_client;
1185 $facture->modelpdf = $this->model_pdf;
1186 $facture->model_pdf = $this->model_pdf;
1187 $facture->fk_project = $this->fk_project;
1188 $facture->cond_reglement_id = $this->cond_reglement_id;
1189 $facture->mode_reglement_id = $this->mode_reglement_id;
1190 $facture->remise_absolue = $this->remise_absolue;
1193 $facture->origin = $this->origin;
1194 $facture->origin_id = $this->origin_id;
1195 $facture->fk_account = $this->fk_account;
1197 $facture->lines = $this->lines;
1198 $facture->situation_counter = $this->situation_counter;
1199 $facture->situation_cycle_ref = $this->situation_cycle_ref;
1200 $facture->situation_final = $this->situation_final;
1202 $facture->retained_warranty = $this->retained_warranty;
1203 $facture->retained_warranty_fk_cond_reglement = $this->retained_warranty_fk_cond_reglement;
1204 $facture->retained_warranty_date_limit = $this->retained_warranty_date_limit;
1206 $facture->fk_user_author = $user->id;
1210 foreach ($facture->lines as $i => $tmpline) {
1211 $facture->lines[$i]->fk_prev_id = $this->lines[$i]->rowid;
1212 if ($invertdetail) {
1213 $facture->lines[$i]->subprice = -$facture->lines[$i]->subprice;
1214 $facture->lines[$i]->total_ht = -$facture->lines[$i]->total_ht;
1215 $facture->lines[$i]->total_tva = -$facture->lines[$i]->total_tva;
1216 $facture->lines[$i]->total_localtax1 = -$facture->lines[$i]->total_localtax1;
1217 $facture->lines[$i]->total_localtax2 = -$facture->lines[$i]->total_localtax2;
1218 $facture->lines[$i]->total_ttc = -$facture->lines[$i]->total_ttc;
1219 $facture->lines[$i]->ref_ext =
'';
1223 dol_syslog(get_class($this).
"::createFromCurrent invertdetail=".$invertdetail.
" socid=".$this->socid.
" nboflines=".count($facture->lines));
1225 $facid = $facture->create($user);
1227 $this->error = $facture->error;
1228 $this->errors = $facture->errors;
1229 } elseif ($this->
type == self::TYPE_SITUATION && !empty($conf->global->INVOICE_USE_SITUATION)) {
1232 foreach ($this->linkedObjectsIds as $typeObject => $Tfk_object) {
1233 foreach ($Tfk_object as $fk_object) {
1234 $facture->add_object_linked($typeObject, $fk_object);
1238 $facture->add_object_linked(
'facture', $this->fk_facture_source);
1254 global $conf, $hookmanager;
1258 $object =
new Facture($this->db);
1262 $object->fetch($fromid);
1265 $objFrom = clone $object;
1268 if (!empty($this->socid) && $this->socid != $object->socid) {
1269 $objsoc =
new Societe($this->db);
1271 if ($objsoc->fetch($this->socid) > 0) {
1272 $object->socid = $objsoc->id;
1273 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1274 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1275 $object->fk_project =
'';
1276 $object->fk_delivery_address =
'';
1287 $object->date = (empty($this->date) ?
dol_now() : $this->date);
1288 $object->user_author = $user->id;
1289 $object->user_valid =
null;
1290 $object->fk_user_author = $user->id;
1291 $object->fk_user_valid =
null;
1292 $object->fk_facture_source = 0;
1293 $object->date_creation =
'';
1294 $object->date_modification =
'';
1295 $object->date_validation =
'';
1296 $object->ref_client =
'';
1297 $object->close_code =
'';
1298 $object->close_note =
'';
1300 $object->note_private =
'';
1301 $object->note_public =
'';
1305 foreach ($object->lines as $i => $line) {
1306 if (($object->lines[$i]->info_bits & 0x02) == 0x02) {
1307 unset($object->lines[$i]);
1313 if (!empty($conf->global->INVOICE_AUTO_NEXT_MONTH_ON_LINES) && !empty($line->date_start) && !empty($line->date_end)) {
1325 if (
dol_mktime(0, 0, 0, $start[
'mon'], $start[
'mday'], $start[
'year'],
'gmt') == $first
1326 &&
dol_mktime(23, 59, 59, $end[
'mon'], $end[
'mday'], $end[
'year'],
'gmt') == $last) {
1330 $object->lines[$i]->date_start = $newFirst;
1331 $object->lines[$i]->date_end = $newLast;
1335 $object->lines[$i]->ref_ext =
'';
1339 $object->context[
'createfromclone'] =
'createfromclone';
1340 $result = $object->create($user);
1343 $this->error = $object->error;
1344 $this->errors = $object->errors;
1347 if ($object->copy_linked_contact($objFrom,
'internal') < 0) {
1349 $this->error = $object->error;
1350 $this->errors = $object->errors;
1351 } elseif ($object->socid == $objFrom->socid) {
1353 if ($object->copy_linked_contact($objFrom,
'external') < 0) {
1355 $this->error = $object->error;
1356 $this->errors = $object->errors;
1363 if (is_object($hookmanager)) {
1364 $parameters = array(
'objFrom'=>$objFrom);
1366 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action);
1374 unset($object->context[
'createfromclone']);
1378 $this->db->commit();
1381 $this->db->rollback();
1395 global $conf, $hookmanager;
1403 $num = count($object->lines);
1404 for ($i = 0; $i < $num; $i++) {
1407 $line->libelle = $object->lines[$i]->libelle;
1408 $line->label = $object->lines[$i]->label;
1409 $line->desc = $object->lines[$i]->desc;
1410 $line->subprice = $object->lines[$i]->subprice;
1411 $line->total_ht = $object->lines[$i]->total_ht;
1412 $line->total_tva = $object->lines[$i]->total_tva;
1413 $line->total_localtax1 = $object->lines[$i]->total_localtax1;
1414 $line->total_localtax2 = $object->lines[$i]->total_localtax2;
1415 $line->total_ttc = $object->lines[$i]->total_ttc;
1416 $line->vat_src_code = $object->lines[$i]->vat_src_code;
1417 $line->tva_tx = $object->lines[$i]->tva_tx;
1418 $line->localtax1_tx = $object->lines[$i]->localtax1_tx;
1419 $line->localtax2_tx = $object->lines[$i]->localtax2_tx;
1420 $line->qty = $object->lines[$i]->qty;
1421 $line->fk_remise_except = $object->lines[$i]->fk_remise_except;
1422 $line->remise_percent = $object->lines[$i]->remise_percent;
1423 $line->fk_product = $object->lines[$i]->fk_product;
1424 $line->info_bits = $object->lines[$i]->info_bits;
1425 $line->product_type = $object->lines[$i]->product_type;
1426 $line->rang = $object->lines[$i]->rang;
1427 $line->special_code = $object->lines[$i]->special_code;
1428 $line->fk_parent_line = $object->lines[$i]->fk_parent_line;
1429 $line->fk_unit = $object->lines[$i]->fk_unit;
1430 $line->date_start = $object->lines[$i]->date_start;
1431 $line->date_end = $object->lines[$i]->date_end;
1434 $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency;
1435 $line->multicurrency_code = $object->lines[$i]->multicurrency_code;
1436 $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice;
1437 $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht;
1438 $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva;
1439 $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc;
1441 $line->fk_fournprice = $object->lines[$i]->fk_fournprice;
1442 $marginInfos =
getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht);
1443 $line->pa_ht = $marginInfos[0];
1446 $object->lines[$i]->fetch_optionals();
1447 foreach ($object->lines[$i]->array_options as $options_key => $value) {
1448 $line->array_options[$options_key] = $value;
1451 $this->lines[$i] = $line;
1454 $this->socid = $object->socid;
1455 $this->fk_project = $object->fk_project;
1456 $this->fk_account = $object->fk_account;
1457 $this->cond_reglement_id = $object->cond_reglement_id;
1458 $this->mode_reglement_id = $object->mode_reglement_id;
1459 $this->availability_id = $object->availability_id;
1460 $this->demand_reason_id = $object->demand_reason_id;
1461 $this->delivery_date = (empty($object->delivery_date) ? $object->date_livraison : $object->delivery_date);
1462 $this->date_livraison = $object->delivery_date;
1463 $this->fk_delivery_address = $object->fk_delivery_address;
1464 $this->contact_id = $object->contact_id;
1465 $this->ref_client = $object->ref_client;
1467 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1468 $this->note_private = $object->note_private;
1469 $this->note_public = $object->note_public;
1472 $this->module_source = $object->module_source;
1473 $this->pos_source = $object->pos_source;
1475 $this->origin = $object->element;
1476 $this->origin_id = $object->id;
1478 $this->fk_user_author = $user->id;
1481 $object->fetch_optionals();
1482 foreach ($object->array_options as $options_key => $value) {
1483 $this->array_options[$options_key] = $value;
1487 $this->linked_objects[$this->origin] = $this->origin_id;
1488 if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) {
1489 $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
1492 $ret = $this->
create($user);
1496 $hookmanager->initHooks(array(
'invoicedao'));
1498 $parameters = array(
'objFrom'=>$object);
1500 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1526 global $conf, $hookmanager;
1534 $use_all_lines = empty($lines);
1535 $num = count($object->lines);
1536 for ($i = 0; $i < $num; $i++) {
1537 if (!$use_all_lines && !in_array($object->lines[$i]->id, $lines)) {
1543 $line->libelle = $object->lines[$i]->libelle;
1544 $line->label = $object->lines[$i]->label;
1545 $line->desc = $object->lines[$i]->desc;
1546 $line->subprice = $object->lines[$i]->subprice;
1547 $line->total_ht = $object->lines[$i]->total_ht;
1548 $line->total_tva = $object->lines[$i]->total_tva;
1549 $line->total_localtax1 = $object->lines[$i]->total_localtax1;
1550 $line->total_localtax2 = $object->lines[$i]->total_localtax2;
1551 $line->total_ttc = $object->lines[$i]->total_ttc;
1552 $line->vat_src_code = $object->lines[$i]->vat_src_code;
1553 $line->tva_tx = $object->lines[$i]->tva_tx;
1554 $line->localtax1_tx = $object->lines[$i]->localtax1_tx;
1555 $line->localtax2_tx = $object->lines[$i]->localtax2_tx;
1556 $line->qty = $object->lines[$i]->qty;
1557 $line->fk_remise_except = $object->lines[$i]->fk_remise_except;
1558 $line->remise_percent = $object->lines[$i]->remise_percent;
1559 $line->fk_product = $object->lines[$i]->fk_product;
1560 $line->info_bits = $object->lines[$i]->info_bits;
1561 $line->product_type = $object->lines[$i]->product_type;
1562 $line->rang = $object->lines[$i]->rang;
1563 $line->special_code = $object->lines[$i]->special_code;
1564 $line->fk_parent_line = $object->lines[$i]->fk_parent_line;
1565 $line->fk_unit = $object->lines[$i]->fk_unit;
1566 $line->date_start = $object->lines[$i]->date_start;
1567 $line->date_end = $object->lines[$i]->date_end;
1570 $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency;
1571 $line->multicurrency_code = $object->lines[$i]->multicurrency_code;
1572 $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice;
1573 $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht;
1574 $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva;
1575 $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc;
1577 $line->fk_fournprice = $object->lines[$i]->fk_fournprice;
1578 $marginInfos =
getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht);
1579 $line->pa_ht = $marginInfos[0];
1582 $object->lines[$i]->fetch_optionals();
1583 foreach ($object->lines[$i]->array_options as $options_key => $value) {
1584 $line->array_options[$options_key] = $value;
1587 $this->lines[$i] = $line;
1590 $this->socid = $object->socid;
1591 $this->fk_project = $object->fk_project;
1592 $this->fk_account = $object->fk_account;
1593 $this->cond_reglement_id = $object->cond_reglement_id;
1594 $this->mode_reglement_id = $object->mode_reglement_id;
1595 $this->availability_id = $object->availability_id;
1596 $this->demand_reason_id = $object->demand_reason_id;
1597 $this->delivery_date = (empty($object->delivery_date) ? $object->date_livraison : $object->delivery_date);
1598 $this->date_livraison = $object->delivery_date;
1599 $this->fk_delivery_address = $object->fk_delivery_address;
1600 $this->contact_id = $object->contact_id;
1601 $this->ref_client = $object->ref_client;
1603 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1604 $this->note_private = $object->note_private;
1605 $this->note_public = $object->note_public;
1608 $this->module_source = $object->module_source;
1609 $this->pos_source = $object->pos_source;
1611 $this->origin = $object->element;
1612 $this->origin_id = $object->id;
1614 $this->fk_user_author = $user->id;
1617 $object->fetch_optionals();
1618 foreach ($object->array_options as $options_key => $value) {
1619 $this->array_options[$options_key] = $value;
1623 $this->linked_objects[$this->origin] = $this->origin_id;
1624 if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) {
1625 $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
1628 $ret = $this->
create($user);
1632 $hookmanager->initHooks(array(
'invoicedao'));
1634 $parameters = array(
'objFrom'=>$object);
1636 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1666 global $conf, $langs, $hookmanager, $action;
1668 if (! in_array($origin->element, array(
'propal',
'commande'))) {
1669 $origin->error =
'ErrorCanOnlyAutomaticallyGenerateADepositFromProposalOrOrder';
1674 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'DateInvoice'));
1678 require_once DOL_DOCUMENT_ROOT .
'/core/lib/date.lib.php';
1680 if ($date > (
dol_get_last_hour(
dol_now(
'tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
1681 $origin->error =
'ErrorDateIsInFuture';
1685 if ($payment_terms_id <= 0) {
1686 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'PaymentConditionsShort'));
1690 $payment_conditions_deposit_percent =
getDictionaryValue(
'c_payment_term',
'deposit_percent', $origin->cond_reglement_id);
1692 if (empty($payment_conditions_deposit_percent)) {
1693 $origin->error =
'ErrorPaymentConditionsNotEligibleToDepositCreation';
1697 if (empty($origin->deposit_percent)) {
1698 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'DepositPercent'));
1702 $deposit =
new self($origin->db);
1703 $deposit->socid = $origin->socid;
1705 $deposit->fk_project = $origin->fk_project;
1706 $deposit->ref_client = $origin->ref_client;
1707 $deposit->date = $date;
1708 $deposit->mode_reglement_id = $origin->mode_reglement_id;
1709 $deposit->cond_reglement_id = $payment_terms_id;
1710 $deposit->availability_id = $origin->availability_id;
1711 $deposit->demand_reason_id = $origin->demand_reason_id;
1712 $deposit->fk_account = $origin->fk_account;
1713 $deposit->fk_incoterms = $origin->fk_incoterms;
1714 $deposit->location_incoterms = $origin->location_incoterms;
1715 $deposit->fk_multicurrency = $origin->fk_multicurrency;
1716 $deposit->multicurrency_code = $origin->multicurrency_code;
1717 $deposit->multicurrency_tx = $origin->multicurrency_tx;
1718 $deposit->module_source = $origin->module_source;
1719 $deposit->pos_source = $origin->pos_source;
1720 $deposit->model_pdf =
'crabe';
1722 $modelByTypeConfName =
'FACTURE_ADDON_PDF_' . $deposit->type;
1724 if (!empty($conf->global->$modelByTypeConfName)) {
1725 $deposit->model_pdf = $conf->global->$modelByTypeConfName;
1726 } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) {
1727 $deposit->model_pdf = $conf->global->FACTURE_ADDON_PDF;
1730 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1731 $deposit->note_private = $origin->note_private;
1732 $deposit->note_public = $origin->note_public;
1735 $deposit->origin = $origin->element;
1736 $deposit->origin_id = $origin->id;
1738 $origin->fetch_optionals();
1740 foreach ($origin->array_options as $extrakey => $value) {
1741 $deposit->array_options[$extrakey] = $value;
1744 $deposit->linked_objects[$deposit->origin] = $deposit->origin_id;
1746 foreach ($overrideFields as $key => $value) {
1747 $deposit->$key = $value;
1750 $deposit->context[
'createdepositfromorigin'] =
'createdepositfromorigin';
1752 $origin->db->begin();
1755 $createReturn = $deposit->create($user, $notrigger);
1757 if ($createReturn <= 0) {
1758 $origin->db->rollback();
1759 $origin->error = $deposit->error;
1760 $origin->errors = $deposit->errors;
1764 $amount_ttc_diff = 0;
1765 $amountdeposit = array();
1766 $descriptions = array();
1768 if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)) {
1769 $amount = $origin->total_ttc * ($origin->deposit_percent / 100);
1771 $TTotalByTva = array();
1772 foreach ($origin->lines as &$line) {
1773 if (!empty($line->special_code)) {
1776 $TTotalByTva[$line->tva_tx] += $line->total_ttc;
1777 $descriptions[$line->tva_tx] .=
'<li>' . (!empty($line->product_ref) ? $line->product_ref .
' - ' :
'');
1778 $descriptions[$line->tva_tx] .= (!empty($line->product_label) ? $line->product_label .
' - ' :
'');
1779 $descriptions[$line->tva_tx] .= $langs->trans(
'Qty') .
' : ' . $line->qty;
1780 $descriptions[$line->tva_tx] .=
' - ' . $langs->trans(
'TotalHT') .
' : ' .
price($line->total_ht) .
'</li>';
1783 foreach ($TTotalByTva as $tva => &$total) {
1784 $coef = $total / $origin->total_ttc;
1785 $am = $amount * $coef;
1786 $amount_ttc_diff += $am;
1787 $amountdeposit[$tva] += $am / (1 + $tva / 100);
1791 $lines = $origin->lines;
1792 $numlines = count($lines);
1793 for ($i = 0; $i < $numlines; $i++) {
1794 if (empty($lines[$i]->qty)) {
1797 if (!empty($lines[$i]->special_code)) {
1801 $totalamount += $lines[$i]->total_ht;
1802 $tva_tx = $lines[$i]->tva_tx;
1803 $amountdeposit[$tva_tx] += ($lines[$i]->total_ht * $origin->deposit_percent) / 100;
1804 $descriptions[$tva_tx] .=
'<li>' . (!empty($lines[$i]->product_ref) ? $lines[$i]->product_ref .
' - ' :
'');
1805 $descriptions[$tva_tx] .= (!empty($lines[$i]->product_label) ? $lines[$i]->product_label .
' - ' :
'');
1806 $descriptions[$tva_tx] .= $langs->trans(
'Qty') .
' : ' . $lines[$i]->qty;
1807 $descriptions[$tva_tx] .=
' - ' . $langs->trans(
'TotalHT') .
' : ' .
price($lines[$i]->total_ht) .
'</li>';
1810 if ($totalamount == 0) {
1811 $amountdeposit[0] = 0;
1814 $amount_ttc_diff = $amountdeposit[0];
1817 foreach ($amountdeposit as $tva => $amount) {
1818 if (empty($amount)) {
1822 $descline =
'(DEPOSIT) ('. $origin->deposit_percent .
'%) - '.$origin->ref;
1825 if (!empty($conf->global->INVOICE_DEPOSIT_VARIABLE_MODE_DETAIL_LINES_IN_DESCRIPTION) && !empty($descriptions[$tva])) {
1826 $descline .=
'<ul>' . $descriptions[$tva] .
'</ul>';
1829 $addlineResult = $deposit->addline(
1836 (empty($conf->global->INVOICE_PRODUCTID_DEPOSIT) ? 0 : $conf->global->INVOICE_PRODUCTID_DEPOSIT),
1856 if ($addlineResult < 0) {
1857 $origin->db->rollback();
1858 $origin->error = $deposit->error;
1859 $origin->errors = $deposit->errors;
1864 $diff = $deposit->total_ttc - $amount_ttc_diff;
1866 if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA) && $diff != 0) {
1867 $deposit->fetch_lines();
1868 $subprice_diff = $deposit->lines[0]->subprice - $diff / (1 + $deposit->lines[0]->tva_tx / 100);
1870 $updatelineResult = $deposit->updateline(
1871 $deposit->lines[0]->id,
1872 $deposit->lines[0]->desc,
1874 $deposit->lines[0]->qty,
1875 $deposit->lines[0]->remise_percent,
1876 $deposit->lines[0]->date_start,
1877 $deposit->lines[0]->date_end,
1878 $deposit->lines[0]->tva_tx,
1882 $deposit->lines[0]->info_bits,
1883 $deposit->lines[0]->product_type,
1887 $deposit->lines[0]->pa_ht,
1888 $deposit->lines[0]->label,
1894 if ($updatelineResult < 0) {
1895 $origin->db->rollback();
1896 $origin->error = $deposit->error;
1897 $origin->errors = $deposit->errors;
1902 $hookmanager->initHooks(array(
'invoicedao'));
1904 $parameters = array(
'objFrom' => $origin);
1905 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $deposit, $action);
1908 $origin->db->rollback();
1909 $origin->error = $hookmanager->error;
1910 $origin->errors = $hookmanager->errors;
1914 if (!empty($autoValidateDeposit)) {
1915 $validateReturn = $deposit->validate($user,
'', 0, $notrigger);
1917 if ($validateReturn < 0) {
1918 $origin->db->rollback();
1919 $origin->error = $deposit->error;
1920 $origin->errors = $deposit->errors;
1925 unset($deposit->context[
'createdepositfromorigin']);
1927 $origin->db->commit();
1941 global $conf, $langs, $mysoc, $user;
1943 $langs->load(
'bills');
1946 $moretitle = $params[
'moretitle'] ??
'';
1947 $picto = $this->picto;
1948 if ($this->
type == self::TYPE_REPLACEMENT) {
1951 if ($this->
type == self::TYPE_CREDIT_NOTE) {
1954 if ($this->
type == self::TYPE_DEPOSIT) {
1958 if ($user->hasRight(
"facture",
"read")) {
1959 $datas[
'picto'] =
img_picto(
'', $picto).
' <u class="paddingrightonly">'.$langs->trans(
"Invoice").
'</u>';
1961 $datas[
'picto'] .=
' '.$this->getLibType(1);
1964 if (!empty($params[
'fromajaxtooltip']) && !isset($this->alreadypaid)) {
1968 if (isset($this->
statut) && isset($this->alreadypaid)) {
1969 $datas[
'picto'] .=
' '.$this->getLibStatut(5, $this->alreadypaid);
1972 $datas[
'picto'] .=
' - '.$moretitle;
1974 if (!empty($this->
ref)) {
1975 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1977 if (!empty($this->ref_customer)) {
1978 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_customer;
1980 if (!empty($this->date)) {
1981 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
1983 if (!empty($this->total_ht)) {
1984 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1986 if (!empty($this->total_tva)) {
1987 $datas[
'amountvat'] =
'<br><b>'.$langs->trans(
'AmountVAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1989 if (!empty($this->revenuestamp) && $this->revenuestamp != 0) {
1990 $datas[
'amountrevenustamp'] =
'<br><b>'.$langs->trans(
'RevenueStamp').
':</b> '.
price($this->revenuestamp, 0, $langs, 0, -1, -1, $conf->currency);
1992 if (!empty($this->total_localtax1) && $this->total_localtax1 != 0) {
1994 $datas[
'amountlt1'] =
'<br><b>'.$langs->transcountry(
'AmountLT1', $mysoc->country_code).
':</b> '.
price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency);
1996 if (!empty($this->total_localtax2) && $this->total_localtax2 != 0) {
1997 $datas[
'amountlt2'] =
'<br><b>'.$langs->transcountry(
'AmountLT2', $mysoc->country_code).
':</b> '.
price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency);
1999 if (!empty($this->total_ttc)) {
2000 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
2021 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $addlinktonotes = 0, $save_lastsearch_value = -1, $target =
'')
2023 global $langs, $conf, $user, $mysoc;
2025 if (!empty($conf->dol_no_mouse_hover)) {
2031 if ($option ==
'withdraw') {
2032 $url = DOL_URL_ROOT.
'/compta/facture/prelevement.php?facid='.$this->id;
2034 $url = DOL_URL_ROOT.
'/compta/facture/card.php?facid='.$this->id;
2037 if (!$user->hasRight(
"facture",
"read")) {
2041 if ($option !==
'nolink') {
2043 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2044 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
2045 $add_save_lastsearch_values = 1;
2047 if ($add_save_lastsearch_values) {
2048 $url .=
'&save_lastsearch_values=1';
2056 $picto = $this->picto;
2057 if ($this->
type == self::TYPE_REPLACEMENT) {
2060 if ($this->
type == self::TYPE_CREDIT_NOTE) {
2063 if ($this->
type == self::TYPE_DEPOSIT) {
2068 'objecttype' => $this->element,
2069 'moretitle' => $moretitle,
2070 'option' => $option,
2072 $classfortooltip =
'classfortooltip';
2075 $classfortooltip =
'classforajaxtooltip';
2076 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
2082 $linkclose = ($target ?
' target="'.$target.
'"' :
'');
2083 if (empty($notooltip) && $user->hasRight(
"facture",
"read")) {
2084 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
2085 $label = $langs->trans(
"Invoice");
2086 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
2088 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
2089 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
2092 $linkstart =
'<a href="'.$url.
'"';
2093 $linkstart .= $linkclose.
'>';
2096 if ($option ==
'nolink') {
2101 $result .= $linkstart;
2103 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
2105 if ($withpicto != 2) {
2106 $result .= ($max ?
dol_trunc($this->
ref, $max) : $this->ref);
2108 $result .= $linkend;
2110 if ($addlinktonotes) {
2111 $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private);
2114 $notetoshow = $langs->trans(
"ViewPrivateNote").
':<br>'.$txttoshow;
2115 $result .=
' <span class="note inline-block">';
2116 $result .=
'<a href="'.DOL_URL_ROOT.
'/compta/facture/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($notetoshow, 1, 1).
'">';
2121 $result .=
'</span>';
2125 global $action, $hookmanager;
2126 $hookmanager->initHooks(array(
'invoicedao'));
2127 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result,
'notooltip' => $notooltip,
'addlinktonotes' => $addlinktonotes,
'save_lastsearch_value'=> $save_lastsearch_value,
'target' => $target);
2128 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
2130 $result = $hookmanager->resPrint;
2132 $result .= $hookmanager->resPrint;
2148 public function fetch($rowid, $ref =
'', $ref_ext =
'', $notused =
'', $fetch_situation =
false)
2150 if (empty($rowid) && empty($ref) && empty($ref_ext)) {
2154 $sql =
'SELECT f.rowid, f.entity, f.ref, f.ref_client, f.ref_ext, f.type, f.fk_soc';
2155 $sql .=
', f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc, f.revenuestamp';
2156 $sql .=
', f.remise_percent, f.remise_absolue, f.remise';
2157 $sql .=
', f.datef as df, f.date_pointoftax';
2158 $sql .=
', f.date_lim_reglement as dlr';
2159 $sql .=
', f.datec as datec';
2160 $sql .=
', f.date_valid as datev';
2161 $sql .=
', f.tms as datem';
2162 $sql .=
', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.fk_user_modif, f.model_pdf, f.last_main_doc';
2163 $sql .=
', f.fk_facture_source, f.fk_fac_rec_source';
2164 $sql .=
', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet as fk_project, f.extraparams';
2165 $sql .=
', f.situation_cycle_ref, f.situation_counter, f.situation_final';
2166 $sql .=
', f.fk_account';
2167 $sql .=
", f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc";
2168 $sql .=
', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
2169 $sql .=
', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
2170 $sql .=
', f.fk_incoterms, f.location_incoterms';
2171 $sql .=
', f.module_source, f.pos_source';
2172 $sql .=
", i.libelle as label_incoterms";
2173 $sql .=
", f.retained_warranty as retained_warranty, f.retained_warranty_date_limit as retained_warranty_date_limit, f.retained_warranty_fk_cond_reglement as retained_warranty_fk_cond_reglement";
2174 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facture as f';
2175 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
2176 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as p ON f.fk_mode_reglement = p.id';
2177 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON f.fk_incoterms = i.rowid';
2180 $sql .=
" WHERE f.rowid = ".((int) $rowid);
2182 $sql .=
' WHERE f.entity IN ('.getEntity(
'invoice').
')';
2184 $sql .=
" AND f.ref = '".$this->db->escape($ref).
"'";
2187 $sql .=
" AND f.ref_ext = '".$this->db->escape($ref_ext).
"'";
2191 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
2192 $resql = $this->db->query($sql);
2194 if ($this->db->num_rows($resql)) {
2195 $obj = $this->db->fetch_object($resql);
2197 $this->
id = $obj->rowid;
2198 $this->entity = $obj->entity;
2200 $this->
ref = $obj->ref;
2201 $this->ref_client = $obj->ref_client;
2202 $this->ref_customer = $obj->ref_client;
2203 $this->ref_ext = $obj->ref_ext;
2204 $this->
type = $obj->type;
2205 $this->date = $this->db->jdate($obj->df);
2206 $this->date_pointoftax = $this->db->jdate($obj->date_pointoftax);
2207 $this->date_creation = $this->db->jdate($obj->datec);
2208 $this->date_validation = $this->db->jdate($obj->datev);
2209 $this->date_modification = $this->db->jdate($obj->datem);
2210 $this->datem = $this->db->jdate($obj->datem);
2211 $this->remise_percent = $obj->remise_percent;
2212 $this->remise_absolue = $obj->remise_absolue;
2213 $this->total_ht = $obj->total_ht;
2214 $this->total_tva = $obj->total_tva;
2215 $this->total_localtax1 = $obj->localtax1;
2216 $this->total_localtax2 = $obj->localtax2;
2217 $this->total_ttc = $obj->total_ttc;
2218 $this->revenuestamp = $obj->revenuestamp;
2219 $this->paye = $obj->paye;
2220 $this->close_code = $obj->close_code;
2221 $this->close_note = $obj->close_note;
2223 $this->socid = $obj->fk_soc;
2224 $this->thirdparty =
null;
2226 $this->fk_project = $obj->fk_project;
2227 $this->project =
null;
2229 $this->
statut = $obj->fk_statut;
2230 $this->status = $obj->fk_statut;
2232 $this->date_lim_reglement = $this->db->jdate($obj->dlr);
2233 $this->mode_reglement_id = $obj->fk_mode_reglement;
2234 $this->mode_reglement_code = $obj->mode_reglement_code;
2235 $this->mode_reglement = $obj->mode_reglement_libelle;
2236 $this->cond_reglement_id = $obj->fk_cond_reglement;
2237 $this->cond_reglement_code = $obj->cond_reglement_code;
2238 $this->cond_reglement = $obj->cond_reglement_libelle;
2239 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
2240 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
2241 $this->fk_facture_source = $obj->fk_facture_source;
2242 $this->fk_fac_rec_source = $obj->fk_fac_rec_source;
2243 $this->note = $obj->note_private;
2244 $this->note_private = $obj->note_private;
2245 $this->note_public = $obj->note_public;
2246 $this->user_author = $obj->fk_user_author;
2247 $this->user_valid = $obj->fk_user_valid;
2248 $this->user_modification = $obj->fk_user_modif;
2249 $this->fk_user_author = $obj->fk_user_author;
2250 $this->fk_user_valid = $obj->fk_user_valid;
2251 $this->fk_user_modif = $obj->fk_user_modif;
2252 $this->model_pdf = $obj->model_pdf;
2253 $this->modelpdf = $obj->model_pdf;
2254 $this->last_main_doc = $obj->last_main_doc;
2255 $this->situation_cycle_ref = $obj->situation_cycle_ref;
2256 $this->situation_counter = $obj->situation_counter;
2257 $this->situation_final = $obj->situation_final;
2258 $this->retained_warranty = $obj->retained_warranty;
2259 $this->retained_warranty_date_limit = $this->db->jdate($obj->retained_warranty_date_limit);
2260 $this->retained_warranty_fk_cond_reglement = $obj->retained_warranty_fk_cond_reglement;
2262 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
2265 $this->fk_incoterms = $obj->fk_incoterms;
2266 $this->location_incoterms = $obj->location_incoterms;
2267 $this->label_incoterms = $obj->label_incoterms;
2269 $this->module_source = $obj->module_source;
2270 $this->pos_source = $obj->pos_source;
2273 $this->fk_multicurrency = $obj->fk_multicurrency;
2274 $this->multicurrency_code = $obj->multicurrency_code;
2275 $this->multicurrency_tx = $obj->multicurrency_tx;
2276 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
2277 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
2278 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
2280 if (($this->
type == self::TYPE_SITUATION || ($this->
type == self::TYPE_CREDIT_NOTE && $this->situation_cycle_ref > 0)) && $fetch_situation) {
2284 if ($this->status == self::STATUS_DRAFT) {
2285 $this->brouillon = 1;
2293 $this->lines = array();
2297 $this->error = $this->db->error();
2301 $this->db->free($resql);
2305 $this->error =
'Invoice with id='.$rowid.
' or ref='.$ref.
' or ref_ext='.$ref_ext.
' not found';
2307 dol_syslog(__METHOD__.$this->error, LOG_WARNING);
2311 $this->error = $this->db->lasterror();
2326 public function fetch_lines($only_product = 0, $loadalsotranslation = 0)
2329 global $langs, $conf;
2331 $this->lines = array();
2333 $sql =
'SELECT l.rowid, l.fk_facture, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx,';
2334 $sql .=
' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice, l.ref_ext,';
2335 $sql .=
' l.situation_percent, l.fk_prev_id,';
2336 $sql .=
' l.rang, l.special_code,';
2337 $sql .=
' l.date_start as date_start, l.date_end as date_end,';
2338 $sql .=
' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
2339 $sql .=
' l.fk_unit,';
2340 $sql .=
' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2341 $sql .=
' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2342 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facturedet as l';
2343 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON l.fk_product = p.rowid';
2344 $sql .=
' WHERE l.fk_facture = '.((int) $this->
id);
2345 $sql .=
' ORDER BY l.rang, l.rowid';
2347 dol_syslog(get_class($this).
'::fetch_lines', LOG_DEBUG);
2348 $result = $this->db->query($sql);
2350 $num = $this->db->num_rows($result);
2353 $objp = $this->db->fetch_object($result);
2356 $line->id = $objp->rowid;
2357 $line->rowid = $objp->rowid;
2358 $line->fk_facture = $objp->fk_facture;
2359 $line->label = $objp->custom_label;
2360 $line->desc = $objp->description;
2361 $line->description = $objp->description;
2362 $line->product_type = $objp->product_type;
2363 $line->ref = $objp->product_ref;
2364 $line->product_ref = $objp->product_ref;
2365 $line->libelle = $objp->product_label;
2366 $line->product_label = $objp->product_label;
2367 $line->product_desc = $objp->product_desc;
2368 $line->fk_product_type = $objp->fk_product_type;
2369 $line->qty = $objp->qty;
2370 $line->subprice = $objp->subprice;
2371 $line->ref_ext = $objp->ref_ext;
2373 $line->vat_src_code = $objp->vat_src_code;
2374 $line->tva_tx = $objp->tva_tx;
2375 $line->localtax1_tx = $objp->localtax1_tx;
2376 $line->localtax2_tx = $objp->localtax2_tx;
2377 $line->localtax1_type = $objp->localtax1_type;
2378 $line->localtax2_type = $objp->localtax2_type;
2379 $line->remise_percent = $objp->remise_percent;
2380 $line->fk_remise_except = $objp->fk_remise_except;
2381 $line->fk_product = $objp->fk_product;
2382 $line->date_start = $this->db->jdate($objp->date_start);
2383 $line->date_end = $this->db->jdate($objp->date_end);
2384 $line->info_bits = $objp->info_bits;
2385 $line->total_ht = $objp->total_ht;
2386 $line->total_tva = $objp->total_tva;
2387 $line->total_localtax1 = $objp->total_localtax1;
2388 $line->total_localtax2 = $objp->total_localtax2;
2389 $line->total_ttc = $objp->total_ttc;
2390 $line->code_ventilation = $objp->fk_code_ventilation;
2391 $line->fk_fournprice = $objp->fk_fournprice;
2392 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
2393 $line->pa_ht = $marginInfos[0];
2394 $line->marge_tx = $marginInfos[1];
2395 $line->marque_tx = $marginInfos[2];
2396 $line->rang = $objp->rang;
2397 $line->special_code = $objp->special_code;
2398 $line->fk_parent_line = $objp->fk_parent_line;
2399 $line->situation_percent = $objp->situation_percent;
2400 $line->fk_prev_id = $objp->fk_prev_id;
2401 $line->fk_unit = $objp->fk_unit;
2404 $line->fk_accounting_account = $objp->fk_code_ventilation;
2407 $line->fk_multicurrency = $objp->fk_multicurrency;
2408 $line->multicurrency_code = $objp->multicurrency_code;
2409 $line->multicurrency_subprice = $objp->multicurrency_subprice;
2410 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
2411 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
2412 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2414 $line->fetch_optionals();
2417 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
2418 $tmpproduct =
new Product($this->db);
2419 $tmpproduct->fetch($objp->fk_product);
2420 $tmpproduct->getMultiLangs();
2422 $line->multilangs = $tmpproduct->multilangs;
2425 $this->lines[$i] = $line;
2429 $this->db->free($result);
2432 $this->error = $this->db->error();
2447 $this->tab_previous_situation_invoice = array();
2448 $this->tab_next_situation_invoice = array();
2450 $sql =
'SELECT rowid, type, situation_cycle_ref, situation_counter FROM '.MAIN_DB_PREFIX.
'facture';
2451 $sql .=
" WHERE rowid <> ".((int) $this->
id);
2452 $sql .=
' AND entity = '.((int) $this->entity);
2453 $sql .=
' AND situation_cycle_ref = '.(int) $this->situation_cycle_ref;
2454 $sql .=
' ORDER BY situation_counter ASC';
2456 dol_syslog(get_class($this).
'::fetchPreviousNextSituationInvoice ', LOG_DEBUG);
2457 $result = $this->db->query($sql);
2458 if ($result && $this->db->num_rows($result) > 0) {
2459 while ($objp = $this->db->fetch_object($result)) {
2460 $invoice =
new Facture($this->db);
2461 if ($invoice->fetch($objp->rowid) > 0) {
2462 if ($objp->situation_counter < $this->situation_counter
2463 || ($objp->situation_counter == $this->situation_counter && $objp->rowid < $this->id)
2465 $this->tab_previous_situation_invoice[] = $invoice;
2467 $this->tab_next_situation_invoice[] = $invoice;
2486 if (empty($this->
type)) {
2489 if (isset($this->
ref)) {
2490 $this->
ref = trim($this->
ref);
2492 if (isset($this->ref_ext)) {
2493 $this->ref_ext = trim($this->ref_ext);
2495 if (isset($this->ref_client)) {
2496 $this->ref_client = trim($this->ref_client);
2498 if (isset($this->increment)) {
2499 $this->increment = trim($this->increment);
2501 if (isset($this->close_code)) {
2502 $this->close_code = trim($this->close_code);
2504 if (isset($this->close_note)) {
2505 $this->close_note = trim($this->close_note);
2507 if (isset($this->note) || isset($this->note_private)) {
2508 $this->note = (isset($this->note) ? trim($this->note) : trim($this->note_private));
2510 if (isset($this->note) || isset($this->note_private)) {
2511 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
2513 if (isset($this->note_public)) {
2514 $this->note_public = trim($this->note_public);
2516 if (isset($this->model_pdf)) {
2517 $this->model_pdf = trim($this->model_pdf);
2519 if (isset($this->import_key)) {
2520 $this->import_key = trim($this->import_key);
2522 if (isset($this->retained_warranty)) {
2523 $this->retained_warranty = floatval($this->retained_warranty);
2525 if (!isset($this->fk_user_author) && isset($this->user_author) ) {
2526 $this->fk_user_author = $this->user_author;
2534 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facture SET";
2535 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
2536 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
2537 $sql .=
" type=".(isset($this->
type) ? $this->db->escape($this->
type) :
"null").
",";
2538 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
2539 $sql .=
" increment=".(isset($this->increment) ?
"'".$this->db->escape($this->increment).
"'" :
"null").
",";
2540 $sql .=
" fk_soc=".(isset($this->socid) ? $this->db->escape($this->socid) :
"null").
",";
2541 $sql .=
" datec=".(strval($this->date_creation) !=
'' ?
"'".$this->db->idate($this->date_creation).
"'" :
'null').
",";
2542 $sql .=
" datef=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
2543 $sql .=
" date_pointoftax=".(strval($this->date_pointoftax) !=
'' ?
"'".$this->db->idate($this->date_pointoftax).
"'" :
'null').
",";
2544 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
2545 $sql .=
" paye=".(isset($this->paye) ? $this->db->escape($this->paye) : 0).
",";
2546 $sql .=
" remise_percent=".(isset($this->remise_percent) ? $this->db->escape($this->remise_percent) :
"null").
",";
2547 $sql .=
" remise_absolue=".(isset($this->remise_absolue) ? $this->db->escape($this->remise_absolue) :
"null").
",";
2548 $sql .=
" close_code=".(isset($this->close_code) ?
"'".$this->db->escape($this->close_code).
"'" :
"null").
",";
2549 $sql .=
" close_note=".(isset($this->close_note) ?
"'".$this->db->escape($this->close_note).
"'" :
"null").
",";
2550 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
2551 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
2552 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
2553 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
2554 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
2555 $sql .=
" revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp !=
'') ? $this->db->escape($this->revenuestamp) :
"null").
",";
2556 $sql .=
" fk_statut=".(isset($this->
statut) ? $this->db->escape($this->
statut) :
"null").
",";
2557 $sql .=
" fk_user_author=".(isset($this->fk_user_author) ? $this->db->escape($this->fk_user_author) :
"null").
",";
2558 $sql .=
" fk_user_valid=".(isset($this->fk_user_valid) ? $this->db->escape($this->fk_user_valid) :
"null").
",";
2559 $sql .=
" fk_facture_source=".(isset($this->fk_facture_source) ? $this->db->escape($this->fk_facture_source) :
"null").
",";
2560 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->db->escape($this->fk_project) :
"null").
",";
2561 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->db->escape($this->cond_reglement_id) :
"null").
",";
2562 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->db->escape($this->mode_reglement_id) :
"null").
",";
2563 $sql .=
" date_lim_reglement=".(strval($this->date_lim_reglement) !=
'' ?
"'".$this->db->idate($this->date_lim_reglement).
"'" :
'null').
",";
2564 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
2565 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
2566 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
2567 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null").
",";
2568 $sql .=
" situation_cycle_ref=".(empty($this->situation_cycle_ref) ?
"null" : $this->db->escape($this->situation_cycle_ref)).
",";
2569 $sql .=
" situation_counter=".(empty($this->situation_counter) ?
"null" : $this->db->escape($this->situation_counter)).
",";
2570 $sql .=
" situation_final=".(empty($this->situation_final) ?
"0" : $this->db->escape($this->situation_final)).
",";
2571 $sql .=
" retained_warranty=".(empty($this->retained_warranty) ?
"0" : $this->db->escape($this->retained_warranty)).
",";
2572 $sql .=
" retained_warranty_date_limit=".(strval($this->retained_warranty_date_limit) !=
'' ?
"'".$this->db->idate($this->retained_warranty_date_limit).
"'" :
'null').
",";
2573 $sql .=
" retained_warranty_fk_cond_reglement=".(isset($this->retained_warranty_fk_cond_reglement) ?intval($this->retained_warranty_fk_cond_reglement) :
"null");
2574 $sql .=
" WHERE rowid=".((int) $this->
id);
2578 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
2579 $resql = $this->db->query($sql);
2582 $this->errors[] =
"Error ".$this->db->lasterror();
2592 if (!$error && !$notrigger) {
2603 foreach ($this->errors as $errmsg) {
2604 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2605 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2607 $this->db->rollback();
2610 $this->db->commit();
2626 global $conf, $langs;
2628 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
2629 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
2634 $result = $remise->fetch($idremise);
2637 if ($remise->fk_facture) {
2638 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
2639 $this->db->rollback();
2644 $facligne->fk_facture = $this->id;
2645 $facligne->fk_remise_except = $remise->id;
2646 $facligne->desc = $remise->description;
2647 $facligne->vat_src_code = $remise->vat_src_code;
2648 $facligne->tva_tx = $remise->tva_tx;
2649 $facligne->subprice = -$remise->amount_ht;
2650 $facligne->fk_product = 0;
2652 $facligne->remise_percent = 0;
2653 $facligne->rang = -1;
2654 $facligne->info_bits = 2;
2656 if (!empty($conf->global->MAIN_ADD_LINE_AT_POSITION)) {
2657 $facligne->rang = 1;
2658 $linecount = count($this->lines);
2659 for ($ii = 1; $ii <= $linecount; $ii++) {
2665 if ($remise->fk_facture_source > 0) {
2666 $srcinvoice =
new Facture($this->db);
2667 $srcinvoice->fetch($remise->fk_facture_source);
2668 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmargin.class.php';
2670 $arraytmp = $formmargin->getMarginInfosArray($srcinvoice,
false);
2671 $facligne->pa_ht = $arraytmp[
'pa_total'];
2674 $facligne->total_ht = -$remise->amount_ht;
2675 $facligne->total_tva = -$remise->amount_tva;
2676 $facligne->total_ttc = -$remise->amount_ttc;
2678 $facligne->multicurrency_subprice = -$remise->multicurrency_subprice;
2679 $facligne->multicurrency_total_ht = -$remise->multicurrency_amount_ht;
2680 $facligne->multicurrency_total_tva = -$remise->multicurrency_amount_tva;
2681 $facligne->multicurrency_total_ttc = -$remise->multicurrency_amount_ttc;
2683 $lineid = $facligne->insert();
2688 $result = $remise->link_to_invoice($lineid, 0);
2690 $this->error = $remise->error;
2691 $this->db->rollback();
2695 $this->db->commit();
2698 $this->error = $facligne->error;
2699 $this->db->rollback();
2703 $this->error = $facligne->error;
2704 $this->db->rollback();
2708 $this->db->rollback();
2730 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
2731 if (empty($ref_client)) {
2732 $sql .=
' SET ref_client = NULL';
2734 $sql .=
' SET ref_client = \''.$this->db->escape($ref_client).
'\'';
2736 $sql .=
" WHERE rowid = ".((int) $this->
id);
2738 dol_syslog(__METHOD__.
' this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2739 $resql = $this->db->query($sql);
2741 $this->errors[] = $this->db->error();
2746 $this->ref_client = $ref_client;
2749 if (!$notrigger && empty($error)) {
2759 $this->ref_client = $ref_client;
2761 $this->db->commit();
2764 foreach ($this->errors as $errmsg) {
2765 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2766 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2768 $this->db->rollback();
2781 public function delete($user, $notrigger = 0, $idwarehouse = -1)
2783 global $langs, $conf;
2784 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2788 dol_syslog(get_class($this).
"::delete rowid=".$rowid.
", ref=".$this->ref.
", thirdparty=".(empty($this->thirdparty) ?
'' : $this->thirdparty->name), LOG_DEBUG);
2801 if (!$error && !$notrigger) {
2815 dol_syslog(get_class($this).
"::delete error deleteExtraFields ".$this->error, LOG_ERR);
2829 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'societe_remise_except';
2830 $sql .=
' WHERE fk_facture_source = '.((int) $rowid);
2831 $sql .=
' AND fk_facture_line IS NULL';
2832 $resql = $this->db->query($sql);
2836 $list_rowid_det = array();
2837 foreach ($this->lines as $key => $invoiceline) {
2838 $list_rowid_det[] = $invoiceline->id;
2842 if (count($list_rowid_det)) {
2843 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
2844 $sql .=
' SET fk_facture = NULL, fk_facture_line = NULL';
2845 $sql .=
' WHERE fk_facture_line IN ('.$this->db->sanitize(join(
',', $list_rowid_det)).
')';
2847 if (!$this->db->query($sql)) {
2848 $this->error = $this->db->error().
" sql=".$sql;
2849 $this->errors[] = $this->error;
2850 $this->db->rollback();
2857 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'eventorganization_conferenceorboothattendee';
2858 $sql .=
' SET fk_invoice = NULL';
2859 $sql .=
' WHERE fk_invoice = '.((int) $rowid);
2861 if (!$this->db->query($sql)) {
2862 $this->error = $this->db->error().
" sql=".$sql;
2863 $this->errors[] = $this->error;
2864 $this->db->rollback();
2868 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'element_time';
2869 $sql .=
' SET invoice_id = NULL, invoice_line_id = NULL';
2870 $sql .=
' WHERE invoice_id = '.((int) $rowid);
2872 if (!$this->db->query($sql)) {
2873 $this->error = $this->db->error().
" sql=".$sql;
2874 $this->errors[] = $this->error;
2875 $this->db->rollback();
2880 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse != -1) {
2881 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
2882 $langs->load(
"agenda");
2884 $num = count($this->lines);
2885 for ($i = 0; $i < $num; $i++) {
2886 if ($this->lines[$i]->fk_product > 0) {
2888 $mouvP->origin = &$this;
2889 $mouvP->setOrigin($this->element, $this->
id);
2891 if ($this->
type == self::TYPE_CREDIT_NOTE) {
2892 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceDeleteDolibarr", $this->ref));
2894 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceDeleteDolibarr", $this->ref));
2901 $main = MAIN_DB_PREFIX.
'facturedet';
2902 $ef = $main.
"_extrafields";
2903 $sqlef =
"DELETE FROM ".$ef.
" WHERE fk_object IN (SELECT rowid FROM ".$main.
" WHERE fk_facture = ".((int) $rowid).
")";
2905 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'facturedet WHERE fk_facture = '.((int) $rowid);
2908 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'facture WHERE rowid = '.((int) $rowid);
2910 $resql = $this->db->query($sql);
2917 if ($conf->facture->dir_output && !empty($this->
ref)) {
2918 $dir = $conf->facture->dir_output.
"/".$ref;
2919 $file = $conf->facture->dir_output.
"/".$ref.
"/".$ref.
".pdf";
2920 if (file_exists($file)) {
2924 $langs->load(
"errors");
2925 $this->error = $langs->trans(
"ErrorFailToDeleteFile", $file);
2926 $this->errors[] = $this->error;
2927 $this->db->rollback();
2931 if (file_exists($dir)) {
2933 $langs->load(
"errors");
2934 $this->error = $langs->trans(
"ErrorFailToDeleteDir", $dir);
2935 $this->errors[] = $this->error;
2936 $this->db->rollback();
2942 $this->db->commit();
2945 $this->error = $this->db->lasterror().
" sql=".$sql;
2946 $this->errors[] = $this->error;
2947 $this->db->rollback();
2951 $this->error = $this->db->lasterror().
" sql=".$sql;
2952 $this->errors[] = $this->error;
2953 $this->db->rollback();
2957 $this->db->rollback();
2974 public function set_paid($user, $close_code =
'', $close_note =
'')
2977 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
2978 return $this->
setPaid($user, $close_code, $close_note);
2990 public function setPaid($user, $close_code =
'', $close_note =
'')
2994 if ($this->paye != 1) {
2999 dol_syslog(get_class($this).
"::setPaid rowid=".((
int) $this->
id), LOG_DEBUG);
3001 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET';
3002 $sql .=
' fk_statut='.self::STATUS_CLOSED;
3007 $sql .=
", close_code='".$this->db->escape($close_code).
"'";
3010 $sql .=
", close_note='".$this->db->escape($close_note).
"'";
3012 $sql .=
', fk_user_closing = '.((int) $user->id);
3013 $sql .=
", date_closing = '".$this->db->idate($now).
"'";
3014 $sql .=
" WHERE rowid = ".((int) $this->
id);
3016 $resql = $this->db->query($sql);
3026 $this->error = $this->db->lasterror();
3030 $this->db->commit();
3033 $this->db->rollback();
3056 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
3074 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
3075 $sql .=
' SET paye=0, fk_statut='.self::STATUS_VALIDATED.
', close_code=null, close_note=null,';
3076 $sql .=
' date_closing=null,';
3077 $sql .=
' fk_user_closing=null';
3078 $sql .=
" WHERE rowid = ".((int) $this->
id);
3080 dol_syslog(get_class($this).
"::setUnpaid", LOG_DEBUG);
3081 $resql = $this->db->query($sql);
3091 $this->error = $this->db->error();
3096 $this->db->commit();
3099 $this->db->rollback();
3121 dol_syslog(get_class($this).
"::set_canceled is deprecated, use setCanceled instead", LOG_NOTICE);
3122 return $this->
setCanceled($user, $close_code, $close_note);
3135 public function setCanceled($user, $close_code =
'', $close_note =
'')
3137 dol_syslog(get_class($this).
"::setCanceled rowid=".((
int) $this->
id), LOG_DEBUG);
3141 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET';
3142 $sql .=
' fk_statut='.self::STATUS_ABANDONED;
3144 $sql .=
", close_code='".$this->db->escape($close_code).
"'";
3147 $sql .=
", close_note='".$this->db->escape($close_note).
"'";
3149 $sql .=
" WHERE rowid = ".((int) $this->
id);
3151 $resql = $this->db->query($sql);
3155 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
3156 $sql .=
' SET fk_facture = NULL';
3157 $sql .=
' WHERE fk_facture = '.((int) $this->
id);
3159 $resql = $this->db->query($sql);
3164 $this->db->rollback();
3169 $this->db->commit();
3172 $this->error = $this->db->error().
" sql=".$sql;
3173 $this->db->rollback();
3177 $this->error = $this->db->error().
" sql=".$sql;
3178 $this->db->rollback();
3194 public function validate($user, $force_number =
'', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0)
3196 global $conf, $langs, $mysoc;
3197 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3199 $productStatic =
null;
3200 $warehouseStatic =
null;
3201 if ($batch_rule > 0) {
3202 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
3203 require_once DOL_DOCUMENT_ROOT.
'/product/class/productbatch.class.php';
3204 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
3205 $productStatic =
new Product($this->db);
3206 $warehouseStatic =
new Entrepot($this->db);
3213 dol_syslog(get_class($this).
'::validate user='.$user->id.
', force_number='.$force_number.
', idwarehouse='.$idwarehouse);
3220 if ($this->
statut != self::STATUS_DRAFT) {
3221 dol_syslog(get_class($this).
"::validate status is not draft. operation canceled.", LOG_WARNING);
3224 if (count($this->lines) <= 0) {
3225 $langs->load(
"errors");
3226 $this->error = $langs->trans(
"ErrorObjectMustHaveLinesToBeValidated", $this->
ref);
3229 if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->creer))
3230 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->invoice_advance->validate))) {
3231 $this->error =
'Permission denied';
3232 dol_syslog(get_class($this).
"::validate ".$this->error.
' MAIN_USE_ADVANCED_PERMS='.$conf->global->MAIN_USE_ADVANCED_PERMS, LOG_ERR);
3235 if ((preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) &&
3236 !empty($conf->global->FAC_FORCE_DATE_VALIDATION)
3241 if (!empty($conf->global-> INVOICE_CHECK_POSTERIOR_DATE)) {
3243 if (!$last_of_type[0]) {
3244 $this->error = $langs->transnoentities(
"ErrorInvoiceIsNotLastOfSameType", $this->
ref,
dol_print_date($this->date,
'day'),
dol_print_date($last_of_type[1],
'day'));
3250 if (!empty($this->thirdparty) && is_object($this->thirdparty)) {
3251 $array_to_check = array(
'IDPROF1',
'IDPROF2',
'IDPROF3',
'IDPROF4',
'IDPROF5',
'IDPROF6',
'EMAIL',
'ACCOUNTANCY_CODE_CUSTOMER');
3252 foreach ($array_to_check as $key) {
3253 $keymin = strtolower($key);
3254 if (!property_exists($this->thirdparty, $keymin)) {
3257 $vallabel = $this->thirdparty->$keymin;
3259 $i = (int) preg_replace(
'/[^0-9]/',
'', $key);
3261 if ($this->thirdparty->isACompany()) {
3263 if ($mysoc->country_id > 0 && $this->thirdparty->country_id == $mysoc->country_id) {
3264 $idprof_mandatory =
'SOCIETE_'.$key.
'_INVOICE_MANDATORY';
3265 if (!$vallabel && !empty($conf->global->$idprof_mandatory)) {
3266 $langs->load(
"errors");
3267 $this->error = $langs->trans(
'ErrorProdIdIsMandatory', $langs->transcountry(
'ProfId'.$i, $this->thirdparty->country_code)).
' ('.$langs->trans(
"ForbiddenBySetupRules").
') ['.$langs->trans(
'Company').
' : '.$this->thirdparty->name.
']';
3268 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3274 if ($key ==
'EMAIL') {
3276 if (!empty($conf->global->SOCIETE_EMAIL_INVOICE_MANDATORY) && !isValidEMail($this->thirdparty->email)) {
3277 $langs->load(
"errors");
3278 $this->error = $langs->trans(
"ErrorBadEMail", $this->thirdparty->email).
' ('.$langs->trans(
"ForbiddenBySetupRules").
') ['.$langs->trans(
'Company').
' : '.$this->thirdparty->name.
']';
3279 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3283 if ($key ==
'ACCOUNTANCY_CODE_CUSTOMER') {
3285 if (!empty($conf->global->SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_INVOICE_MANDATORY) && empty($this->thirdparty->code_compta)) {
3286 $langs->load(
"errors");
3287 $this->error = $langs->trans(
"ErrorAccountancyCodeCustomerIsMandatory", $this->thirdparty->name).
' ('.$langs->trans(
"ForbiddenBySetupRules").
')';
3288 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3297 $array_to_check = array(
'REF_CLIENT'=>
'RefCustomer');
3298 foreach ($array_to_check as $key => $val) {
3299 $keymin = strtolower($key);
3300 $vallabel = $this->$keymin;
3303 $keymandatory =
'INVOICE_'.$key.
'_MANDATORY_FOR_VALIDATION';
3304 if (!$vallabel && !empty($conf->global->$keymandatory)) {
3305 $langs->load(
"errors");
3307 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv($val)),
null,
'errors');
3314 if ($this->
type == self::TYPE_REPLACEMENT) {
3316 if ($this->fk_facture_source <= 0) {
3317 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"InvoiceReplacement"));
3318 $this->db->rollback();
3323 $facreplaced =
new Facture($this->db);
3324 $result = $facreplaced->fetch($this->fk_facture_source);
3326 $this->error = $langs->trans(
"ErrorBadInvoice");
3327 $this->db->rollback();
3332 $idreplacement = $facreplaced->getIdReplacingInvoice(
'validated');
3333 if ($idreplacement && $idreplacement != $this->
id) {
3334 $facreplacement =
new Facture($this->db);
3335 $facreplacement->fetch($idreplacement);
3336 $this->error = $langs->trans(
"ErrorInvoiceAlreadyReplaced", $facreplaced->ref, $facreplacement->ref);
3337 $this->db->rollback();
3341 $result = $facreplaced->setCanceled($user, self::CLOSECODE_REPLACED,
'');
3343 $this->error = $facreplaced->error;
3344 $this->db->rollback();
3350 if ($force_number) {
3351 $num = $force_number;
3352 } elseif (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
3364 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
3365 $sql .=
" SET ref = '".$this->db->escape($num).
"', fk_statut = ".self::STATUS_VALIDATED.
", fk_user_valid = ".($user->id > 0 ? $user->id :
"null").
", date_valid = '".$this->db->idate($now).
"'";
3366 if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
3367 $sql .=
", datef='".$this->db->idate($this->date).
"'";
3368 $sql .=
", date_lim_reglement='".$this->db->idate($this->date_lim_reglement).
"'";
3370 $sql .=
" WHERE rowid = ".((int) $this->
id);
3372 dol_syslog(get_class($this).
"::validate", LOG_DEBUG);
3373 $resql = $this->db->query($sql);
3380 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref))) {
3386 $result = $this->thirdparty->set_as_client();
3389 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse > 0) {
3390 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
3391 $langs->load(
"agenda");
3394 $cpt = count($this->lines);
3395 for ($i = 0; $i < $cpt; $i++) {
3396 if ($this->lines[$i]->fk_product > 0) {
3398 $mouvP->origin = &$this;
3399 $mouvP->setOrigin($this->element, $this->
id);
3401 if ($this->
type == self::TYPE_CREDIT_NOTE) {
3402 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceValidatedInDolibarr", $num));
3405 $this->error = $mouvP->error;
3408 $is_batch_line =
false;
3409 if ($batch_rule > 0) {
3410 $productStatic->fetch($this->lines[$i]->fk_product);
3411 if ($productStatic->hasbatch()) {
3412 $is_batch_line =
true;
3413 $product_qty_remain = $this->lines[$i]->qty;
3419 $sortfield =
'pl.sellby,pl.eatby,pb.qty,pl.rowid';
3420 $sortorder =
'ASC,ASC,ASC,ASC';
3423 $resBatchList = $productbatch->findAllForProduct($productStatic->id, $idwarehouse, (
getDolGlobalInt(
'STOCK_ALLOW_NEGATIVE_TRANSFER') ?
null : 0), $sortfield, $sortorder);
3424 if (!is_array($resBatchList)) {
3426 $this->error = $this->db->lasterror();
3430 $batchList = $resBatchList;
3431 if (empty($batchList)) {
3433 $langs->load(
'errors');
3434 $warehouseStatic->fetch($idwarehouse);
3435 $this->error = $langs->trans(
'ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
3436 dol_syslog(__METHOD__.
' Error: '.$langs->transnoentitiesnoconv(
'ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
3439 foreach ($batchList as $batch) {
3440 if ($batch->qty <= 0) {
3445 if ($batch->qty >= $product_qty_remain) {
3446 $product_batch_qty = $product_qty_remain;
3449 $product_batch_qty = $batch->qty;
3451 $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_batch_qty, $this->lines[$i]->subprice, $langs->trans(
'InvoiceValidatedInDolibarr', $num),
'',
'',
'', $batch->batch);
3454 $this->error = $mouvP->error;
3455 $this->errors = $mouvP->errors;
3459 $product_qty_remain -= $product_batch_qty;
3461 if ($product_qty_remain <= 0) {
3466 if (!$error && $product_qty_remain > 0) {
3469 $batch = $batchList[0];
3470 $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans(
'InvoiceValidatedInDolibarr', $num),
'',
'',
'', $batch->batch);
3473 $this->error = $mouvP->error;
3474 $this->errors = $mouvP->errors;
3478 $langs->load(
'errors');
3479 $warehouseStatic->fetch($idwarehouse);
3480 $this->error = $langs->trans(
'ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
3481 dol_syslog(__METHOD__.
' Error: '.$langs->transnoentitiesnoconv(
'ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
3488 if (!$is_batch_line) {
3489 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceValidatedInDolibarr", $num));
3492 $this->error = $mouvP->error;
3493 $this->errors = $mouvP->errors;
3506 if (!$error && $this->
type == self::TYPE_CREDIT_NOTE && $this->fk_facture_source > 0) {
3507 $invoice_situation =
new Facture($this->db);
3508 $result = $invoice_situation->fetch($this->fk_facture_source);
3509 if ($result > 0 && $invoice_situation->type == self::TYPE_SITUATION && $invoice_situation->situation_final == 1) {
3510 $invoice_situation->situation_final = 0;
3512 $result = $invoice_situation->setFinal($user, 1);
3515 $this->error = $invoice_situation->error;
3516 $this->errors = $invoice_situation->errors;
3522 if (!$error && !$notrigger) {
3532 $this->oldref = $this->ref;
3535 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
3537 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'facture/".$this->db->escape($this->newref).
"'";
3538 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'facture/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
3539 $resql = $this->db->query($sql);
3542 $this->error = $this->db->lasterror();
3544 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'facture/".$this->db->escape($this->newref).
"'";
3545 $sql .=
" WHERE filepath = 'facture/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
3546 $resql = $this->db->query($sql);
3548 $error++; $this->error = $this->db->lasterror();
3554 $dirsource = $conf->facture->dir_output.
'/'.$oldref;
3555 $dirdest = $conf->facture->dir_output.
'/'.$newref;
3556 if (!$error && file_exists($dirsource)) {
3557 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
3559 if (@rename($dirsource, $dirdest)) {
3562 $listoffiles =
dol_dir_list($conf->facture->dir_output.
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
3563 foreach ($listoffiles as $fileentry) {
3564 $dirsource = $fileentry[
'name'];
3565 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
3566 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
3567 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
3568 @rename($dirsource, $dirdest);
3586 $this->brouillon = 0;
3587 $this->date_validation = $now;
3590 if (!empty($conf->global->INVOICE_USE_SITUATION)) {
3592 $nboflines = count($this->lines);
3593 while (($i < $nboflines) && $final) {
3594 $final = ($this->lines[$i]->situation_percent == 100);
3598 if (empty($final)) {
3599 $this->situation_final = 0;
3601 $this->situation_final = 1;
3612 $this->db->commit();
3615 $this->db->rollback();
3628 foreach ($this->tab_next_situation_invoice as $next_invoice) {
3629 $is_last = $next_invoice->is_last_in_cycle();
3631 if ($next_invoice->statut == self::STATUS_DRAFT && $is_last != 1) {
3632 $this->error = $langs->trans(
'updatePriceNextInvoiceErrorUpdateline', $next_invoice->ref);
3636 $next_invoice->brouillon = 1;
3638 foreach ($next_invoice->lines as $line) {
3639 $result = $next_invoice->updateline(
3644 $line->remise_percent,
3648 $line->localtax1_tx,
3649 $line->localtax2_tx,
3652 $line->product_type,
3653 $line->fk_parent_line,
3655 $line->fk_fournprice,
3658 $line->special_code,
3659 $line->array_options,
3660 $line->situation_percent,
3665 $this->error = $langs->trans(
'updatePriceNextInvoiceErrorUpdateline', $next_invoice->ref);
3686 global $conf, $langs;
3690 if ($this->
statut == self::STATUS_DRAFT) {
3691 dol_syslog(__METHOD__.
" already draft status", LOG_WARNING);
3699 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facture";
3700 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
3701 $sql .=
" WHERE rowid = ".((int) $this->
id);
3703 $result = $this->db->query($sql);
3706 $this->oldcopy = clone $this;
3710 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
3711 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
3712 $langs->load(
"agenda");
3714 $num = count($this->lines);
3715 for ($i = 0; $i < $num; $i++) {
3716 if ($this->lines[$i]->fk_product > 0) {
3718 $mouvP->origin = &$this;
3719 $mouvP->setOrigin($this->element, $this->
id);
3721 if ($this->
type == self::TYPE_CREDIT_NOTE) {
3722 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceBackToDraftInDolibarr", $this->ref));
3724 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceBackToDraftInDolibarr", $this->ref));
3731 $old_statut = $this->statut;
3732 $this->brouillon = 1;
3737 $result = $this->
call_trigger(
'BILL_UNVALIDATE', $user);
3740 $this->
statut = $old_statut;
3741 $this->status = $old_statut;
3742 $this->brouillon = 0;
3746 $this->db->rollback();
3751 $this->db->commit();
3754 $this->db->rollback();
3758 $this->error = $this->db->error();
3759 $this->db->rollback();
3819 $fk_remise_except =
'',
3820 $price_base_type =
'HT',
3827 $fk_parent_line = 0,
3828 $fk_fournprice =
null,
3832 $situation_percent = 100,
3837 $noupdateafterinsertline = 0
3841 dol_syslog(__METHOD__.
": using line label is deprecated", LOG_WARNING);
3845 global $mysoc, $conf, $langs;
3847 dol_syslog(get_class($this).
"::addline id=$this->id, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product, remise_percent=$remise_percent, date_start=$date_start, date_end=$date_end, ventil=$ventil, info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, type=$type, fk_unit=$fk_unit, desc=".
dol_trunc($desc, 25), LOG_DEBUG);
3849 if ($this->
statut == self::STATUS_DRAFT) {
3850 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
3859 if (empty($info_bits)) {
3865 if (empty($ventil)) {
3868 if (empty($txtva)) {
3871 if (empty($txlocaltax1)) {
3874 if (empty($txlocaltax2)) {
3877 if (empty($fk_parent_line) || $fk_parent_line < 0) {
3878 $fk_parent_line = 0;
3880 if (empty($fk_prev_id)) {
3881 $fk_prev_id =
'null';
3883 if (!isset($situation_percent) || $situation_percent > 100 || (
string) $situation_percent ==
'') {
3884 $situation_percent = 100;
3886 if (empty($ref_ext)) {
3893 $pu_ht_devise =
price2num($pu_ht_devise);
3896 if (!preg_match(
'/\((.*)\)/', $txtva)) {
3902 if ($price_base_type ==
'HT') {
3913 if ($date_start && $date_end && $date_start > $date_end) {
3914 $langs->load(
"errors");
3915 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
3921 $product_type = $type;
3922 if (!empty($fk_product) && $fk_product > 0) {
3923 $product =
new Product($this->db);
3924 $result = $product->fetch($fk_product);
3925 $product_type = $product->type;
3927 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) {
3928 $langs->load(
"errors");
3929 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref);
3930 $this->db->rollback();
3940 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
3941 $vat_src_code = $reg[1];
3942 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
3950 $tabprice =
calcul_price_total($qty, $pu,
$remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, $situation_percent, $this->multicurrency_tx, $pu_ht_devise);
3952 $total_ht = $tabprice[0];
3953 $total_tva = $tabprice[1];
3954 $total_ttc = $tabprice[2];
3955 $total_localtax1 = $tabprice[9];
3956 $total_localtax2 = $tabprice[10];
3957 $pu_ht = $tabprice[3];
3960 $multicurrency_total_ht = $tabprice[16];
3961 $multicurrency_total_tva = $tabprice[17];
3962 $multicurrency_total_ttc = $tabprice[18];
3963 $pu_ht_devise = $tabprice[19];
3967 if ($ranktouse == -1) {
3968 $rangmax = $this->
line_max($fk_parent_line);
3969 $ranktouse = $rangmax + 1;
3975 $this->line->context = $this->context;
3977 $this->line->fk_facture = $this->id;
3978 $this->line->label = $label;
3979 $this->line->desc = $desc;
3980 $this->line->ref_ext = $ref_ext;
3982 $this->line->qty = ($this->
type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty);
3983 $this->line->subprice = ($this->
type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht);
3985 $this->line->vat_src_code = $vat_src_code;
3986 $this->line->tva_tx = $txtva;
3987 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
3988 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
3989 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
3990 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
3992 $this->line->total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht);
3993 $this->line->total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc);
3994 $this->line->total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_tva) : $total_tva);
3995 $this->line->total_localtax1 = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax1) : $total_localtax1);
3996 $this->line->total_localtax2 = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax2) : $total_localtax2);
3998 $this->line->fk_product = $fk_product;
3999 $this->line->product_type = $product_type;
4001 $this->line->date_start = $date_start;
4002 $this->line->date_end = $date_end;
4003 $this->line->ventil = $ventil;
4004 $this->line->rang = $ranktouse;
4005 $this->line->info_bits = $info_bits;
4006 $this->line->fk_remise_except = $fk_remise_except;
4008 $this->line->special_code = $special_code;
4009 $this->line->fk_parent_line = $fk_parent_line;
4010 $this->line->origin = $origin;
4011 $this->line->origin_id = $origin_id;
4012 $this->line->situation_percent = $situation_percent;
4013 $this->line->fk_prev_id = $fk_prev_id;
4014 $this->line->fk_unit = $fk_unit;
4017 $this->line->fk_fournprice = $fk_fournprice;
4018 $this->line->pa_ht = $pa_ht;
4021 $this->line->fk_multicurrency = $this->fk_multicurrency;
4022 $this->line->multicurrency_code = $this->multicurrency_code;
4023 $this->line->multicurrency_subprice = ($this->
type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht_devise) : $pu_ht_devise);
4025 $this->line->multicurrency_total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ht) : $multicurrency_total_ht);
4026 $this->line->multicurrency_total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_tva) : $multicurrency_total_tva);
4027 $this->line->multicurrency_total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ttc) : $multicurrency_total_ttc);
4029 if (is_array($array_options) && count($array_options) > 0) {
4030 $this->line->array_options = $array_options;
4033 $result = $this->line->insert();
4036 if (!empty($fk_parent_line)) {
4038 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
4039 $linecount = count($this->lines);
4040 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
4046 if (empty($noupdateafterinsertline)) {
4051 $this->db->commit();
4052 return $this->line->id;
4054 $this->error = $this->db->lasterror();
4055 $this->db->rollback();
4059 $this->error = $this->line->error;
4060 $this->errors = $this->line->errors;
4061 $this->db->rollback();
4065 $this->errors[]=
'status of invoice must be Draft to allow use of ->addline()';
4066 dol_syslog(get_class($this).
"::addline status of invoice must be Draft to allow use of ->addline()", LOG_ERR);
4102 public function updateline($rowid, $desc, $pu, $qty,
$remise_percent, $date_start, $date_end, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type =
'HT', $info_bits = 0, $type = self::TYPE_STANDARD, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice =
null, $pa_ht = 0, $label =
'', $special_code = 0, $array_options = 0, $situation_percent = 100, $fk_unit =
null, $pu_ht_devise = 0, $notrigger = 0, $ref_ext =
'', $rang = 0)
4104 global $conf, $user;
4107 dol_syslog(__METHOD__.
": using line label is deprecated", LOG_WARNING);
4110 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
4112 global $mysoc, $langs;
4114 dol_syslog(get_class($this).
"::updateline rowid=$rowid, desc=$desc, pu=$pu, qty=$qty, remise_percent=$remise_percent, date_start=$date_start, date_end=$date_end, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, price_base_type=$price_base_type, info_bits=$info_bits, type=$type, fk_parent_line=$fk_parent_line pa_ht=$pa_ht, special_code=$special_code, fk_unit=$fk_unit, pu_ht_devise=$pu_ht_devise", LOG_DEBUG);
4116 if ($this->
statut == self::STATUS_DRAFT) {
4119 if (!$this->error) {
4120 $this->error = $langs->trans(
'invoiceLineProgressError');
4126 if ($date_start && $date_end && $date_start > $date_end) {
4127 $langs->load(
"errors");
4128 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
4138 if (empty($fk_parent_line) || $fk_parent_line < 0) {
4139 $fk_parent_line = 0;
4141 if (empty($special_code) || $special_code == 3) {
4144 if (!isset($situation_percent) || $situation_percent > 100 || (
string) $situation_percent ==
'') {
4145 $situation_percent = 100;
4147 if (empty($ref_ext)) {
4154 $pu_ht_devise =
price2num($pu_ht_devise);
4156 if (!preg_match(
'/\((.*)\)/', $txtva)) {
4176 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
4177 $vat_src_code = $reg[1];
4178 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
4181 $tabprice =
calcul_price_total($qty, $pu,
$remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, $situation_percent, $this->multicurrency_tx, $pu_ht_devise);
4183 $total_ht = $tabprice[0];
4184 $total_tva = $tabprice[1];
4185 $total_ttc = $tabprice[2];
4186 $total_localtax1 = $tabprice[9];
4187 $total_localtax2 = $tabprice[10];
4188 $pu_ht = $tabprice[3];
4189 $pu_tva = $tabprice[4];
4190 $pu_ttc = $tabprice[5];
4193 $multicurrency_total_ht = $tabprice[16];
4194 $multicurrency_total_tva = $tabprice[17];
4195 $multicurrency_total_ttc = $tabprice[18];
4196 $pu_ht_devise = $tabprice[19];
4203 $price = ($pu - $remise);
4209 $line->fetch($rowid);
4210 $line->fetch_optionals();
4212 if (!empty($line->fk_product)) {
4213 $product =
new Product($this->db);
4214 $result = $product->fetch($line->fk_product);
4215 $product_type = $product->type;
4217 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) {
4218 $langs->load(
"errors");
4219 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref);
4220 $this->db->rollback();
4225 $staticline = clone $line;
4227 $line->oldline = $staticline;
4228 $this->line = $line;
4229 $this->line->context = $this->context;
4230 $this->line->rang = $rang;
4233 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
4234 $rangmax = $this->
line_max($fk_parent_line);
4235 $this->line->rang = $rangmax + 1;
4238 $this->line->id = $rowid;
4239 $this->line->rowid = $rowid;
4240 $this->line->label = $label;
4241 $this->line->desc = $desc;
4242 $this->line->ref_ext = $ref_ext;
4243 $this->line->qty = ($this->
type == self::TYPE_CREDIT_NOTE ?abs($qty) : $qty);
4245 $this->line->vat_src_code = $vat_src_code;
4246 $this->line->tva_tx = $txtva;
4247 $this->line->localtax1_tx = $txlocaltax1;
4248 $this->line->localtax2_tx = $txlocaltax2;
4249 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
4250 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
4253 $this->line->subprice = ($this->
type == self::TYPE_CREDIT_NOTE ?-abs($pu_ht) : $pu_ht);
4254 $this->line->date_start = $date_start;
4255 $this->line->date_end = $date_end;
4256 $this->line->total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ht) : $total_ht);
4257 $this->line->total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_tva) : $total_tva);
4258 $this->line->total_localtax1 = $total_localtax1;
4259 $this->line->total_localtax2 = $total_localtax2;
4260 $this->line->total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ttc) : $total_ttc);
4261 $this->line->info_bits = $info_bits;
4262 $this->line->special_code = $special_code;
4263 $this->line->product_type = $type;
4264 $this->line->fk_parent_line = $fk_parent_line;
4265 $this->line->skip_update_total = $skip_update_total;
4266 $this->line->situation_percent = $situation_percent;
4267 $this->line->fk_unit = $fk_unit;
4269 $this->line->fk_fournprice = $fk_fournprice;
4270 $this->line->pa_ht = $pa_ht;
4273 $this->line->multicurrency_subprice = ($this->
type == self::TYPE_CREDIT_NOTE ?-abs($pu_ht_devise) : $pu_ht_devise);
4274 $this->line->multicurrency_total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_ht) : $multicurrency_total_ht);
4275 $this->line->multicurrency_total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_tva) : $multicurrency_total_tva);
4276 $this->line->multicurrency_total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_ttc) : $multicurrency_total_ttc);
4278 if (is_array($array_options) && count($array_options) > 0) {
4280 foreach ($array_options as $key => $value) {
4281 $this->line->array_options[$key] = $array_options[$key];
4285 $result = $this->line->update($user, $notrigger);
4288 if (!empty($fk_parent_line)) {
4294 $this->db->commit();
4297 $this->error = $this->line->error;
4298 $this->db->rollback();
4302 $this->error =
"Invoice statut makes operation forbidden";
4316 $sql =
'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.
'facturedet fd
4317 INNER JOIN '.MAIN_DB_PREFIX.
'facture f ON (fd.fk_facture = f.rowid)
4318 WHERE fd.fk_prev_id = '.((int) $idline).
' AND f.fk_statut <> 0';
4320 $result = $this->db->query($sql);
4322 $this->error = $this->db->error();
4326 $obj = $this->db->fetch_object($result);
4328 if ($obj ===
null) {
4331 return ($situation_percent < $obj->situation_percent);
4347 global $mysoc, $user;
4350 if (($line->info_bits & 2) == 2) {
4354 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
4357 if ($percent > 100) {
4360 $line->situation_percent = $percent;
4361 $tabprice =
calcul_price_total($line->qty, $line->subprice, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 0,
'HT', 0, $line->product_type, $mysoc,
'', $percent);
4362 $line->total_ht = $tabprice[0];
4363 $line->total_tva = $tabprice[1];
4364 $line->total_ttc = $tabprice[2];
4365 $line->total_localtax1 = $tabprice[9];
4366 $line->total_localtax2 = $tabprice[10];
4367 $line->multicurrency_total_ht = $tabprice[16];
4368 $line->multicurrency_total_tva = $tabprice[17];
4369 $line->multicurrency_total_ttc = $tabprice[18];
4370 $line->update($user);
4373 if ($update_price) {
4389 dol_syslog(get_class($this).
"::deleteline rowid=".((
int) $rowid), LOG_DEBUG);
4391 if ($this->
statut != self::STATUS_DRAFT) {
4392 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
4398 $line->context = $this->context;
4401 $result = $line->fetch($rowid);
4402 if (!($result > 0)) {
4407 if ($id > 0 && $line->fk_facture != $id) {
4408 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
4415 $staticline = clone $line;
4416 $line->oldline = $staticline;
4418 if ($line->delete($user) > 0) {
4422 $this->db->commit();
4425 $this->db->rollback();
4426 $this->error = $this->db->lasterror();
4430 $this->db->rollback();
4431 $this->error = $line->error;
4450 dol_syslog(get_class($this).
"::set_remise is deprecated, use setDiscount instead", LOG_NOTICE);
4451 return $this->
setDiscount($user, $remise, $notrigger);
4466 if (empty($remise)) {
4470 if ($user->hasRight(
'facture',
'creer')) {
4477 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
4478 $sql .=
' SET remise_percent = '.((float) $remise);
4479 $sql .=
" WHERE rowid = ".((int) $this->
id);
4480 $sql .=
' AND fk_statut = '.self::STATUS_DRAFT;
4483 $resql = $this->db->query($sql);
4485 $this->errors[] = $this->db->error();
4489 if (!$notrigger && empty($error)) {
4499 $this->remise_percent = $remise;
4502 $this->db->commit();
4505 foreach ($this->errors as $errmsg) {
4506 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
4507 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4509 $this->db->rollback();
4530 if (empty($remise)) {
4534 if ($user->hasRight(
'facture',
'creer')) {
4541 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
4542 $sql .=
' SET remise_absolue = '.((float) $remise);
4543 $sql .=
" WHERE rowid = ".((int) $this->
id);
4544 $sql .=
' AND fk_statut = '.self::STATUS_DRAFT;
4547 $resql = $this->db->query($sql);
4549 $this->errors[] = $this->db->error();
4554 $this->oldcopy = clone $this;
4555 $this->remise_absolue = $remise;
4559 if (!$notrigger && empty($error)) {
4569 $this->db->commit();
4572 foreach ($this->errors as $errmsg) {
4573 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
4574 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4576 $this->db->rollback();
4594 global $conf, $langs;
4596 if ($this->module_source ==
'takepos') {
4597 $langs->load(
'cashdesk');
4599 $moduleName =
'takepos';
4600 $moduleSourceName =
'Takepos';
4601 $addonConstName =
'TAKEPOS_REF_ADDON';
4604 if (empty($conf->global->TAKEPOS_REF_ADDON)) {
4605 $conf->global->TAKEPOS_REF_ADDON =
'mod_takepos_ref_simple';
4608 $addon = $conf->global->TAKEPOS_REF_ADDON;
4610 $langs->load(
'bills');
4612 $moduleName =
'facture';
4613 $moduleSourceName =
'Invoice';
4614 $addonConstName =
'FACTURE_ADDON';
4617 if (empty($conf->global->FACTURE_ADDON)) {
4618 $conf->global->FACTURE_ADDON =
'mod_facture_terre';
4619 } elseif ($conf->global->FACTURE_ADDON ==
'terre') {
4620 $conf->global->FACTURE_ADDON =
'mod_facture_terre';
4621 } elseif ($conf->global->FACTURE_ADDON ==
'mercure') {
4622 $conf->global->FACTURE_ADDON =
'mod_facture_mercure';
4625 $addon = $conf->global->FACTURE_ADDON;
4628 if (!empty($addon)) {
4629 dol_syslog(
"Call getNextNumRef with ".$addonConstName.
" = ".$conf->global->FACTURE_ADDON.
", thirdparty=".$soc->name.
", type=".$soc->typent_code.
", mode=".$mode, LOG_DEBUG);
4633 $file = $addon.
'.php';
4634 $classname = $addon;
4638 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
4639 foreach ($dirmodels as $reldir) {
4640 $dir =
dol_buildpath($reldir.
'core/modules/'.$moduleName.
'/');
4643 if (is_file($dir.$file) && is_readable($dir.$file)) {
4644 $mybool |= include_once $dir.$file;
4650 $file = $addon.
'/'.$addon.
'.modules.php';
4651 $classname =
'mod_'.$moduleName.
'_'.$addon;
4652 $classname = preg_replace(
'/\-.*$/',
'', $classname);
4654 foreach ($conf->file->dol_document_root as $dirroot) {
4655 $dir = $dirroot.
'/core/modules/'.$moduleName.
'/';
4658 if (is_file($dir.$file) && is_readable($dir.$file)) {
4659 $mybool |= include_once $dir.$file;
4669 $obj =
new $classname();
4671 $numref = $obj->getNextValue($soc, $this, $mode);
4678 if ($mode !=
'last' && !$numref) {
4679 $this->error = $obj->error;
4685 $langs->load(
'errors');
4686 print $langs->trans(
'Error').
' '.$langs->trans(
'ErrorModuleSetupNotComplete', $langs->transnoentitiesnoconv($moduleSourceName));
4699 $sql =
'SELECT c.rowid, datec, date_valid as datev, tms as datem,';
4700 $sql .=
' date_closing as dateclosing,';
4701 $sql .=
' fk_user_author, fk_user_valid, fk_user_closing';
4702 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facture as c';
4703 $sql .=
' WHERE c.rowid = '.((int) $id);
4705 $result = $this->db->query($sql);
4707 if ($this->db->num_rows($result)) {
4708 $obj = $this->db->fetch_object($result);
4709 $this->
id = $obj->rowid;
4710 if ($obj->fk_user_author) {
4711 $cuser =
new User($this->db);
4712 $cuser->fetch($obj->fk_user_author);
4713 $this->user_creation = $cuser;
4715 if ($obj->fk_user_valid) {
4716 $vuser =
new User($this->db);
4717 $vuser->fetch($obj->fk_user_valid);
4718 $this->user_validation = $vuser;
4720 if ($obj->fk_user_closing) {
4721 $cluser =
new User($this->db);
4722 $cluser->fetch($obj->fk_user_closing);
4723 $this->user_closing = $cluser;
4726 $this->date_creation = $this->db->jdate($obj->datec);
4727 $this->date_modification = $this->db->jdate($obj->datem);
4728 $this->date_validation = $this->db->jdate($obj->datev);
4729 $this->date_closing = $this->db->jdate($obj->dateclosing);
4731 $this->db->free($result);
4752 public function liste_array($shortlist = 0, $draft = 0, $excluser =
'', $socid = 0, $limit = 0, $offset = 0, $sortfield =
'f.datef,f.rowid', $sortorder =
'DESC')
4755 global $conf, $user;
4759 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
4760 $sql .=
" f.rowid as fid, f.ref as ref, f.datef as df";
4761 if (empty($user->rights->societe->client->voir) && !$socid) {
4762 $sql .=
", sc.fk_soc, sc.fk_user";
4764 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"facture as f";
4765 if (empty($user->rights->societe->client->voir) && !$socid) {
4766 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
4768 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice').
")";
4769 $sql .=
" AND f.fk_soc = s.rowid";
4770 if (empty($user->rights->societe->client->voir) && !$socid) {
4771 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
4774 $sql .=
" AND s.rowid = ".((int) $socid);
4777 $sql .=
" AND f.fk_statut = ".self::STATUS_DRAFT;
4779 if (is_object($excluser)) {
4780 $sql .=
" AND f.fk_user_author <> ".((int) $excluser->id);
4782 $sql .= $this->db->order($sortfield, $sortorder);
4783 $sql .= $this->db->plimit($limit, $offset);
4785 $result = $this->db->query($sql);
4787 $numc = $this->db->num_rows($result);
4790 while ($i < $numc) {
4791 $obj = $this->db->fetch_object($result);
4793 if ($shortlist == 1) {
4794 $ga[$obj->fid] = $obj->ref;
4795 } elseif ($shortlist == 2) {
4796 $ga[$obj->fid] = $obj->ref.
' ('.$obj->name.
')';
4798 $ga[$i][
'id'] = $obj->fid;
4799 $ga[$i][
'ref'] = $obj->ref;
4800 $ga[$i][
'name'] = $obj->name;
4829 $sql =
"SELECT f.rowid as rowid, f.ref, f.fk_statut as status, f.paye as paid,";
4830 $sql .=
" ff.rowid as rowidnext";
4832 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4833 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"paiement_facture as pf ON f.rowid = pf.fk_facture";
4834 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facture as ff ON f.rowid = ff.fk_facture_source";
4835 $sql .=
" WHERE (f.fk_statut = ".self::STATUS_VALIDATED.
" OR (f.fk_statut = ".self::STATUS_ABANDONED.
" AND f.close_code = '".self::CLOSECODE_ABANDONED.
"'))";
4836 $sql .=
" AND f.entity IN (".getEntity(
'invoice').
")";
4837 $sql .=
" AND f.paye = 0";
4838 $sql .=
" AND pf.fk_paiement IS NULL";
4839 $sql .=
" AND ff.fk_statut IS NULL";
4841 $sql .=
" AND f.fk_soc = ".((int) $socid);
4844 $sql .=
" ORDER BY f.ref";
4846 dol_syslog(get_class($this).
"::list_replacable_invoices", LOG_DEBUG);
4847 $resql = $this->db->query($sql);
4849 while ($obj = $this->db->fetch_object($resql)) {
4850 $return[$obj->rowid] = array(
4851 'id' => $obj->rowid,
4853 'status' => $obj->status,
4854 'paid' => $obj->paid,
4861 $this->error = $this->db->error();
4884 $sql =
"SELECT f.rowid as rowid, f.ref, f.fk_statut, f.type, f.paye, pf.fk_paiement";
4885 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4886 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"paiement_facture as pf ON f.rowid = pf.fk_facture";
4887 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=".self::TYPE_REPLACEMENT.
")";
4888 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice').
")";
4889 $sql .=
" AND f.fk_statut in (".self::STATUS_VALIDATED.
",".self::STATUS_CLOSED.
")";
4893 $sql .=
" AND ff.type IS NULL";
4894 $sql .=
" AND f.type <> ".self::TYPE_CREDIT_NOTE;
4896 if (!empty($conf->global->INVOICE_USE_SITUATION_CREDIT_NOTE)) {
4898 $sql .=
" AND (f.type <> ".self::TYPE_SITUATION.
" OR f.rowid IN ";
4899 $sql .=
'(SELECT MAX(fs.rowid)';
4900 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as fs";
4901 $sql .=
" WHERE fs.entity IN (".getEntity(
'invoice').
")";
4902 $sql .=
" AND fs.type = ".self::TYPE_SITUATION;
4903 $sql .=
" AND fs.fk_statut IN (".self::STATUS_VALIDATED.
",".self::STATUS_CLOSED.
")";
4905 $sql .=
" AND fs.fk_soc = ".((int) $socid);
4907 $sql .=
" GROUP BY fs.situation_cycle_ref)";
4910 $sql .=
" AND f.type <> ".self::TYPE_SITUATION;
4914 $sql .=
" AND f.fk_soc = ".((int) $socid);
4916 $sql .=
" ORDER BY f.ref";
4918 dol_syslog(get_class($this).
"::list_qualified_avoir_invoices", LOG_DEBUG);
4919 $resql = $this->db->query($sql);
4921 while ($obj = $this->db->fetch_object($resql)) {
4923 if ($obj->fk_statut == self::STATUS_VALIDATED) {
4926 if ($obj->fk_statut == self::STATUS_CLOSED) {
4931 $paymentornot = ($obj->fk_paiement ? 1 : 0);
4932 $return[$obj->rowid] = array(
'ref'=>$obj->ref,
'status'=>$obj->fk_statut,
'type'=>$obj->type,
'paye'=>$obj->paye,
'paymentornot'=>$paymentornot);
4938 $this->error = $this->db->error();
4954 global $conf, $langs;
4958 $sql =
"SELECT f.rowid, f.date_lim_reglement as datefin, f.fk_statut, f.total_ht";
4959 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4960 if (empty($user->rights->societe->client->voir) && !$user->socid) {
4961 $sql .=
" JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON f.fk_soc = sc.fk_soc";
4962 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
4965 $sql .= $clause.
" f.paye=0";
4966 $sql .=
" AND f.entity IN (".getEntity(
'invoice').
")";
4967 $sql .=
" AND f.fk_statut = ".self::STATUS_VALIDATED;
4969 $sql .=
" AND f.fk_soc = ".((int) $user->socid);
4972 $resql = $this->db->query($sql);
4974 $langs->load(
"bills");
4978 $response->warning_delay = $conf->facture->client->warning_delay / 60 / 60 / 24;
4979 $response->label = $langs->trans(
"CustomerBillsUnpaid");
4980 $response->labelShort = $langs->trans(
"Unpaid");
4981 $response->url = DOL_URL_ROOT.
'/compta/facture/list.php?search_status=1&mainmenu=billing&leftmenu=customers_bills';
4984 $generic_facture =
new Facture($this->db);
4986 while ($obj = $this->db->fetch_object($resql)) {
4987 $generic_facture->date_lim_reglement = $this->db->jdate($obj->datefin);
4988 $generic_facture->statut = $obj->fk_statut;
4990 $response->nbtodo++;
4991 $response->total += $obj->total_ht;
4993 if ($generic_facture->hasDelay()) {
4994 $response->nbtodolate++;
4995 $response->url_late = DOL_URL_ROOT.
'/compta/facture/list.php?search_option=late&mainmenu=billing&leftmenu=customers_bills';
4999 $this->db->free($resql);
5003 $this->error = $this->db->error();
5042 global $conf, $langs, $user;
5046 $nownotime =
dol_mktime(0, 0, 0, $arraynow[
'mon'], $arraynow[
'mday'], $arraynow[
'year']);
5051 $sql =
"SELECT rowid";
5052 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
5053 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
5054 $sql .= $this->db->plimit(100);
5056 $resql = $this->db->query($sql);
5058 $num_prods = $this->db->num_rows($resql);
5060 while ($i < $num_prods) {
5062 $row = $this->db->fetch_row($resql);
5063 $prodids[$i] = $row[0];
5067 if (empty($num_prods)) {
5074 $this->
ref =
'SPECIMEN';
5075 $this->specimen = 1;
5077 $this->date = $nownotime;
5078 $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
5079 $this->cond_reglement_id = 1;
5080 $this->cond_reglement_code =
'RECEP';
5082 $this->mode_reglement_id = 0;
5083 $this->mode_reglement_code =
'';
5085 $this->note_public =
'This is a comment (public)';
5086 $this->note_private =
'This is a comment (private)';
5087 $this->note =
'This is a comment (private)';
5089 $this->fk_user_author = $user->id;
5091 $this->multicurrency_tx = 1;
5092 $this->multicurrency_code = $conf->currency;
5094 $this->fk_incoterms = 0;
5095 $this->location_incoterms =
'';
5097 if (empty($option) || $option !=
'nolines') {
5101 while ($xnbp < $nbp) {
5103 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
5105 $line->subprice = 100;
5106 $line->tva_tx = 19.6;
5107 $line->localtax1_tx = 0;
5108 $line->localtax2_tx = 0;
5109 $line->remise_percent = 0;
5111 $prodid = mt_rand(1, $num_prods);
5112 $line->fk_product = $prodids[$prodid];
5114 $line->total_ht = -100;
5115 $line->total_ttc = -119.6;
5116 $line->total_tva = -19.6;
5117 $line->multicurrency_total_ht = -200;
5118 $line->multicurrency_total_ttc = -239.2;
5119 $line->multicurrency_total_tva = -39.2;
5120 } elseif ($xnbp == 2) {
5121 $line->subprice = -100;
5122 $line->total_ht = -100;
5123 $line->total_ttc = -119.6;
5124 $line->total_tva = -19.6;
5125 $line->remise_percent = 0;
5126 $line->multicurrency_total_ht = -200;
5127 $line->multicurrency_total_ttc = -239.2;
5128 $line->multicurrency_total_tva = -39.2;
5129 } elseif ($xnbp == 3) {
5130 $prodid = mt_rand(1, $num_prods);
5131 $line->fk_product = $prodids[$prodid];
5132 $line->total_ht = 50;
5133 $line->total_ttc = 59.8;
5134 $line->total_tva = 9.8;
5135 $line->multicurrency_total_ht = 100;
5136 $line->multicurrency_total_ttc = 119.6;
5137 $line->multicurrency_total_tva = 19.6;
5138 $line->remise_percent = 50;
5141 $prodid = mt_rand(1, $num_prods);
5142 $line->fk_product = $prodids[$prodid];
5143 $line->total_ht = 100;
5144 $line->total_ttc = 119.6;
5145 $line->total_tva = 19.6;
5146 $line->multicurrency_total_ht = 200;
5147 $line->multicurrency_total_ttc = 239.2;
5148 $line->multicurrency_total_tva = 39.2;
5149 $line->remise_percent = 0;
5152 $this->lines[$xnbp] = $line;
5155 $this->total_ht += $line->total_ht;
5156 $this->total_tva += $line->total_tva;
5157 $this->total_ttc += $line->total_ttc;
5159 $this->multicurrency_total_ht += $line->multicurrency_total_ht;
5160 $this->multicurrency_total_tva += $line->multicurrency_total_tva;
5161 $this->multicurrency_total_ttc += $line->multicurrency_total_ttc;
5165 $this->revenuestamp = 0;
5169 $line->desc = $langs->trans(
"Description").
" (offered line)";
5171 $line->subprice = 100;
5172 $line->tva_tx = 19.6;
5173 $line->localtax1_tx = 0;
5174 $line->localtax2_tx = 0;
5175 $line->remise_percent = 100;
5176 $line->total_ht = 0;
5177 $line->total_ttc = 0;
5178 $line->total_tva = 0;
5179 $line->multicurrency_total_ht = 0;
5180 $line->multicurrency_total_ttc = 0;
5181 $line->multicurrency_total_tva = 0;
5182 $prodid = mt_rand(1, $num_prods);
5183 $line->fk_product = $prodids[$prodid];
5185 $this->lines[$xnbp] = $line;
5199 global $conf, $user;
5201 $this->nb = array();
5205 $sql =
"SELECT count(f.rowid) as nb";
5206 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
5207 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON f.fk_soc = s.rowid";
5208 if (empty($user->rights->societe->client->voir) && !$user->socid) {
5209 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
5210 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
5213 $sql .=
" ".$clause.
" f.entity IN (".
getEntity(
'invoice').
")";
5215 $resql = $this->db->query($sql);
5217 while ($obj = $this->db->fetch_object($resql)) {
5218 $this->nb[
"invoices"] = $obj->nb;
5220 $this->db->free($resql);
5224 $this->error = $this->db->error();
5250 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
5252 global $conf, $langs;
5254 $outputlangs->loadLangs(array(
"bills",
"products"));
5258 $thisTypeConfName =
'FACTURE_ADDON_PDF_'.$this->type;
5260 if (!empty($this->model_pdf)) {
5261 $modele = $this->model_pdf;
5262 } elseif (!empty($this->modelpdf)) {
5263 $modele = $this->modelpdf;
5264 } elseif (!empty($conf->global->$thisTypeConfName)) {
5265 $modele = $conf->global->$thisTypeConfName;
5266 } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) {
5267 $modele = $conf->global->FACTURE_ADDON_PDF;
5271 $modelpath =
"core/modules/facture/doc/";
5273 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
5283 $sql =
'SELECT max(situation_cycle_ref) FROM '.MAIN_DB_PREFIX.
'facture as f';
5284 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice', 0).
")";
5285 $resql = $this->db->query($sql);
5287 if ($this->db->num_rows($resql) > 0) {
5288 $res = $this->db->fetch_array($resql);
5289 $ref = $res[
'max(situation_cycle_ref)'];
5294 $this->db->free($resql);
5297 $this->error = $this->db->lasterror();
5298 dol_syslog(
"Error sql=".$sql.
", error=".$this->error, LOG_ERR);
5312 return ($this->situation_counter == 1);
5326 $sql =
'SELECT rowid FROM '.MAIN_DB_PREFIX.
'facture';
5327 $sql .=
' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref);
5328 $sql .=
' AND situation_counter < '.((int) $this->situation_counter);
5329 $sql .=
' AND entity = '.($this->entity > 0 ? $this->entity : $conf->entity);
5330 $resql = $this->db->query($sql);
5332 if ($resql && $this->db->num_rows($resql) > 0) {
5333 while ($row = $this->db->fetch_object($resql)) {
5335 $situation =
new Facture($this->db);
5336 $situation->fetch($id);
5337 $res[] = $situation;
5340 $this->error = $this->db->error();
5341 dol_syslog(
"Error sql=".$sql.
", error=".$this->error, LOG_ERR);
5361 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET situation_final = '.((int) $this->situation_final).
' WHERE rowid = '.((int) $this->
id);
5364 $resql = $this->db->query($sql);
5366 $this->errors[] = $this->db->error();
5370 if (!$notrigger && empty($error)) {
5380 $this->db->commit();
5383 foreach ($this->errors as $errmsg) {
5384 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
5385 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
5387 $this->db->rollback();
5403 if (!empty($this->situation_cycle_ref)) {
5405 $sql =
'SELECT max(situation_counter) FROM '.MAIN_DB_PREFIX.
'facture';
5406 $sql .=
' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref);
5407 $sql .=
' AND entity = '.($this->entity > 0 ? $this->entity : $conf->entity);
5408 $resql = $this->db->query($sql);
5410 if ($resql && $this->db->num_rows($resql) > 0) {
5411 $res = $this->db->fetch_array($resql);
5412 $last = $res[
'max(situation_counter)'];
5413 return ($last == $this->situation_counter);
5415 $this->error = $this->db->lasterror();
5416 dol_syslog(get_class($this).
"::select Error ".$this->error, LOG_ERR);
5474 $hasDelay = $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay);
5475 if ($hasDelay && !empty($this->retained_warranty) && !empty($this->retained_warranty_date_limit)) {
5477 $totalpaid = floatval($totalpaid);
5479 if ($totalpaid >= 0 && $RetainedWarrantyAmount >= 0) {
5480 if (($totalpaid < $this->total_ttc - $RetainedWarrantyAmount) && $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay)) {
5482 } elseif ($totalpaid < $this->total_ttc && $this->retained_warranty_date_limit < ($now - $conf->facture->client->warning_delay)) {
5505 $displayWarranty =
false;
5506 if (!empty($this->retained_warranty)) {
5507 $displayWarranty =
true;
5511 $displayWarranty =
false;
5512 if (!empty($this->situation_final)) {
5513 $displayWarranty =
true;
5516 $displayWarranty =
true;
5518 foreach ($this->lines as $i => $line) {
5519 if ($line->product_type < 2 && $line->situation_percent < 100) {
5520 $displayWarranty =
false;
5528 return $displayWarranty;
5538 if (empty($this->retained_warranty)) {
5542 $retainedWarrantyAmount = 0;
5546 $displayWarranty =
true;
5548 if (!empty($this->lines)) {
5549 foreach ($this->lines as $i => $line) {
5550 if ($line->product_type < 2 && $line->situation_percent < 100) {
5551 $displayWarranty =
false;
5557 if ($displayWarranty && !empty($this->situation_final)) {
5559 $TPreviousIncoice = $this->tab_previous_situation_invoice;
5562 foreach ($TPreviousIncoice as &$fac) {
5563 $total2BillWT += $fac->total_ttc;
5565 $total2BillWT += $this->total_ttc;
5567 $retainedWarrantyAmount = $total2BillWT * $this->retained_warranty / 100;
5573 $retainedWarrantyAmount = $this->total_ttc * $this->retained_warranty / 100;
5576 if ($rounding < 0) {
5577 $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT);
5580 if ($rounding > 0) {
5581 return round($retainedWarrantyAmount, $rounding);
5584 return $retainedWarrantyAmount;
5595 dol_syslog(get_class($this).
'::setRetainedWarranty('.$value.
')');
5597 if ($this->
statut >= 0) {
5598 $fieldname =
'retained_warranty';
5599 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
5600 $sql .=
" SET ".$fieldname.
" = ".((float) $value);
5601 $sql .=
' WHERE rowid='.((int) $this->
id);
5603 if ($this->db->query($sql)) {
5604 $this->retained_warranty = floatval($value);
5607 dol_syslog(get_class($this).
'::setRetainedWarranty Erreur '.$sql.
' - '.$this->db->error());
5608 $this->error = $this->db->error();
5612 dol_syslog(get_class($this).
'::setRetainedWarranty, status of the object is incompatible');
5613 $this->error =
'Status of the object is incompatible '.$this->statut;
5628 if (!$timestamp && $dateYmd) {
5629 $timestamp = $this->db->jdate($dateYmd);
5633 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit('.$timestamp.
')');
5634 if ($this->
statut >= 0) {
5635 $fieldname =
'retained_warranty_date_limit';
5636 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
5637 $sql .=
" SET ".$fieldname.
" = ".(strval($timestamp) !=
'' ?
"'".$this->db->idate($timestamp).
"'" :
'null');
5638 $sql .=
' WHERE rowid = '.((int) $this->
id);
5640 if ($this->db->query($sql)) {
5641 $this->retained_warranty_date_limit = $timestamp;
5644 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit Erreur '.$sql.
' - '.$this->db->error());
5645 $this->error = $this->db->error();
5649 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit, status of the object is incompatible');
5650 $this->error =
'Status of the object is incompatible '.$this->statut;
5669 global $conf, $langs, $user;
5675 $errorsMsg = array();
5677 $langs->load(
"bills");
5679 if (!isModEnabled(
'facture')) {
5680 $this->output .= $langs->trans(
'ModuleNotEnabled', $langs->transnoentitiesnoconv(
"Facture"));
5683 if (!in_array($datetouse, array(
'duedate',
'invoicedate'))) {
5684 $this->output .=
'Bad value for parameter datetouse. Must be "duedate" or "invoicedate"';
5694 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
5695 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmail.class.php';
5696 require_once DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
5697 $formmail =
new FormMail($this->db);
5702 $tmpinvoice =
new Facture($this->db);
5707 $sql =
"SELECT rowid as id FROM ".MAIN_DB_PREFIX.
"facture as f";
5708 if (!empty($paymentmode) && $paymentmode !=
'all') {
5709 $sql .=
", ".MAIN_DB_PREFIX.
"c_paiement as cp";
5711 $sql .=
" WHERE f.paye = 0";
5712 $sql .=
" AND f.fk_statut = ".self::STATUS_VALIDATED;
5713 if ($datetouse ==
'invoicedate') {
5714 $sql .=
" AND f.datef = '".$this->db->idate($tmpidate,
'gmt').
"'";
5716 $sql .=
" AND f.date_lim_reglement = '".$this->db->idate($tmpidate,
'gmt').
"'";
5718 $sql .=
" AND f.entity IN (".getEntity(
'facture', 0).
")";
5719 if (!empty($paymentmode) && $paymentmode !=
'all') {
5720 $sql .=
" AND f.fk_mode_reglement = cp.id AND cp.code = '".$this->db->escape($paymentmode).
"'";
5723 if ($datetouse ==
'invoicedate') {
5724 $sql .= $this->db->order(
"datef",
"ASC");
5726 $sql .= $this->db->order(
"date_lim_reglement",
"ASC");
5729 $resql = $this->db->query($sql);
5732 if ($datetouse ==
'invoicedate') {
5733 $this->output .= $langs->transnoentitiesnoconv(
"SearchValidatedInvoicesWithDate", $stmpidate);
5735 $this->output .= $langs->transnoentitiesnoconv(
"SearchUnpaidInvoicesWithDueDate", $stmpidate);
5737 if (!empty($paymentmode) && $paymentmode !=
'all') {
5738 $this->output .=
' ('.$langs->transnoentitiesnoconv(
"PaymentMode").
' '.$paymentmode.
')';
5740 $this->output .=
'<br>';
5743 while ($obj = $this->db->fetch_object($resql)) {
5746 $res = $tmpinvoice->fetch($obj->id);
5748 $tmpinvoice->fetch_thirdparty();
5750 $outputlangs =
new Translate(
'', $conf);
5751 if ($tmpinvoice->thirdparty->default_lang) {
5752 $outputlangs->setDefaultLang($tmpinvoice->thirdparty->default_lang);
5753 $outputlangs->loadLangs(array(
"main",
"bills"));
5755 $outputlangs = $langs;
5759 $arraymessage = $formmail->getEMailTemplate($this->db,
'facture_send', $user, $outputlangs, (is_numeric($template) ? $template : 0), 1, (is_numeric($template) ?
'' : $template));
5760 if (is_numeric($arraymessage) && $arraymessage <= 0) {
5761 $langs->load(
"errors");
5762 $this->output .= $langs->trans(
'ErrorFailedToFindEmailTemplate', $template);
5775 $sendTopic =
make_substitutions(empty($arraymessage->topic) ? $outputlangs->transnoentitiesnoconv(
'InformationMessage') : $arraymessage->topic, $substitutionarray, $outputlangs, 1);
5778 $content = $outputlangs->transnoentitiesnoconv($arraymessage->content);
5784 if ($forcerecipient) {
5785 $to = array($forcerecipient);
5787 $res = $tmpinvoice->fetch_thirdparty();
5788 $recipient = $tmpinvoice->thirdparty;
5790 $tmparraycontact = $tmpinvoice->liste_contact(-1,
'external', 0,
'BILLING');
5791 if (is_array($tmparraycontact) && count($tmparraycontact) > 0) {
5792 foreach ($tmparraycontact as $data_email) {
5793 if (!empty($data_email[
'email'])) {
5794 $to[] = $tmpinvoice->thirdparty->contact_get_property($data_email[
'id'],
'email');
5798 if (empty($to) && !empty($recipient->email)) {
5799 $to[] = $recipient->email;
5802 $errormesg =
"Failed to send remind to thirdparty id=".$tmpinvoice->socid.
". No email defined for invoice or customer.";
5806 $errormesg =
"Failed to load recipient with thirdparty id=".$tmpinvoice->socid;
5813 if (!empty($arraymessage->email_from)) {
5814 $from = $arraymessage->email_from;
5817 $errormesg =
"Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
5821 if (!$error && !empty($to)) {
5824 $to = implode(
',', $to);
5825 if (!empty($arraymessage->email_to)) {
5826 $to = $to.
','.$arraymessage->email_to;
5830 $errors_to = $conf->global->MAIN_MAIL_ERRORS_TO;
5832 $trackid =
'inv'.$tmpinvoice->id;
5833 $sendcontext =
'standard';
5836 if (!empty($arraymessage->email_tocc)) {
5837 $email_tocc = $arraymessage->email_tocc;
5841 if (!empty($arraymessage->email_tobcc)) {
5842 $email_tobcc = $arraymessage->email_tobcc;
5849 if ($arraymessage->joinfiles == 1 && !empty($tmpinvoice->last_main_doc)) {
5850 $joinFile[] = DOL_DATA_ROOT.
'/'.$tmpinvoice->last_main_doc;
5851 $joinFileName[] = basename($tmpinvoice->last_main_doc);
5852 $joinFileMime[] =
dol_mimetype(DOL_DATA_ROOT.
'/'.$tmpinvoice->last_main_doc);
5856 $cMailFile =
new CMailFile($sendTopic, $to, $from, $sendContent, $joinFile, $joinFileMime, $joinFileName, $email_tocc, $email_tobcc, 0, 1, $errors_to,
'', $trackid,
'', $sendcontext,
'');
5859 if ($cMailFile->sendfile()) {
5863 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
5868 $actioncomm->type_code =
'AC_OTH_AUTO';
5869 $actioncomm->socid = $tmpinvoice->thirdparty->id;
5870 $actioncomm->contact_id = 0;
5872 $actioncomm->code =
'AC_EMAIL';
5873 $actioncomm->label =
'sendEmailsRemindersOnInvoiceDueDateOK (nbdays='.$nbdays.
' paymentmode='.$paymentmode.
' template='.$template.
' datetouse='.$datetouse.
' forcerecipient='.$forcerecipient.
')';
5874 $actioncomm->note_private = $sendContent;
5875 $actioncomm->fk_project = $tmpinvoice->fk_project;
5876 $actioncomm->datep =
dol_now();
5877 $actioncomm->datef = $actioncomm->datep;
5878 $actioncomm->percentage = -1;
5879 $actioncomm->authorid = $user->id;
5880 $actioncomm->userownerid = $user->id;
5882 $actioncomm->email_msgid = $cMailFile->msgid;
5883 $actioncomm->email_subject = $sendTopic;
5884 $actioncomm->email_from = $from;
5885 $actioncomm->email_sender =
'';
5886 $actioncomm->email_to = $to;
5890 $actioncomm->errors_to = $errors_to;
5892 $actioncomm->elementtype =
'invoice';
5893 $actioncomm->fk_element = $tmpinvoice->id;
5897 $actioncomm->create($user);
5899 $errormesg = $cMailFile->error.
' : '.$to;
5903 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
5908 $actioncomm->type_code =
'AC_OTH_AUTO';
5909 $actioncomm->socid = $tmpinvoice->thirdparty->id;
5910 $actioncomm->contact_id = 0;
5912 $actioncomm->code =
'AC_EMAIL';
5913 $actioncomm->label =
'sendEmailsRemindersOnInvoiceDueDateKO';
5914 $actioncomm->note_private = $errormesg;
5915 $actioncomm->fk_project = $tmpinvoice->fk_project;
5916 $actioncomm->datep =
dol_now();
5917 $actioncomm->datef = $actioncomm->datep;
5918 $actioncomm->percentage = -1;
5919 $actioncomm->authorid = $user->id;
5920 $actioncomm->userownerid = $user->id;
5922 $actioncomm->email_msgid = $cMailFile->msgid;
5923 $actioncomm->email_from = $from;
5924 $actioncomm->email_sender =
'';
5925 $actioncomm->email_to = $to;
5929 $actioncomm->errors_to = $errors_to;
5933 $actioncomm->create($user);
5936 $this->db->commit();
5940 $errorsMsg[] = $errormesg;
5943 $errorsMsg[] =
'Failed to fetch record invoice with ID = '.$obj->id;
5953 $this->output .=
'Nb of emails sent : '.$nbMailSend;
5955 dol_syslog(__METHOD__.
" end - ".$this->output, LOG_INFO);
5959 $this->error =
'Nb of emails sent : '.$nbMailSend.
', '.(!empty($errorsMsg)) ? join(
', ', $errorsMsg) : $error;
5961 dol_syslog(__METHOD__.
" end - ".$this->error, LOG_INFO);
5976 $sql =
"SELECT datef";
5977 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
5978 $sql .=
" WHERE type = " . (int) $this->
type ;
5979 $sql .=
" AND date_valid IS NOT NULL";
5980 $sql .=
" AND entity IN (".getEntity(
'invoice').
")";
5981 $sql .=
" ORDER BY datef DESC LIMIT 1";
5983 $result = $this->db->query($sql);
5986 if ($this->db->num_rows($result)) {
5987 $obj = $this->db->fetch_object($result);
5988 $last_date = $this->db->jdate($obj->datef);
5989 $invoice_date = $this->date;
5991 $is_last_of_same_type = $invoice_date >= $last_date;
5992 if ($allow_validated_drafts) {
5993 $is_last_of_same_type = $is_last_of_same_type || (!strpos($this->
ref,
'PROV') && $this->status ==
self::STATUS_DRAFT);
5996 return array($is_last_of_same_type, $last_date);
6017 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
6019 $return =
'<div class="box-flex-item box-flex-grow-zero">';
6020 $return .=
'<div class="info-box info-box-sm">';
6021 $return .=
'<span class="info-box-icon bg-infobox-action">';
6024 $return .=
'</span>';
6025 $return .=
'<div class="info-box-content">';
6026 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
6027 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
6028 if (property_exists($this,
'socid')) {
6029 $return .=
'<br><span class="info-box-label">'.$this->socid.
'</span>';
6031 if (property_exists($this,
'fk_user_author')) {
6032 $return .=
'<br><span class="info-box-label">'.$this->fk_user_author.
'</span>';
6034 if (method_exists($this,
'getLibStatut')) {
6035 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).
'</div>';
6037 $return .=
'</div>';
6038 $return .=
'</div>';
6039 $return .=
'</div>';
6053 public $element =
'facturedet';
6058 public $table_element =
'facturedet';
6075 public $localtax1_type;
6076 public $localtax2_type;
6077 public $fk_remise_except;
6080 public $fk_fournprice;
6085 public $remise_percent;
6087 public $special_code;
6095 public $fk_code_ventilation = 0;
6100 public $skip_update_total;
6105 public $situation_percent;
6113 public $fk_multicurrency;
6114 public $multicurrency_code;
6115 public $multicurrency_subprice;
6116 public $multicurrency_total_ht;
6117 public $multicurrency_total_tva;
6118 public $multicurrency_total_ttc;
6138 $sql =
'SELECT fd.rowid, fd.fk_facture, fd.fk_parent_line, fd.fk_product, fd.product_type, fd.label as custom_label, fd.description, fd.price, fd.qty, fd.vat_src_code, fd.tva_tx,';
6139 $sql .=
' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice, fd.ref_ext,';
6140 $sql .=
' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,';
6141 $sql .=
' fd.info_bits, fd.special_code, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,';
6142 $sql .=
' fd.fk_code_ventilation,';
6143 $sql .=
' fd.fk_unit, fd.fk_user_author, fd.fk_user_modif,';
6144 $sql .=
' fd.situation_percent, fd.fk_prev_id,';
6145 $sql .=
' fd.multicurrency_subprice,';
6146 $sql .=
' fd.multicurrency_total_ht,';
6147 $sql .=
' fd.multicurrency_total_tva,';
6148 $sql .=
' fd.multicurrency_total_ttc,';
6149 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc';
6150 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facturedet as fd';
6151 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON fd.fk_product = p.rowid';
6152 $sql .=
' WHERE fd.rowid = '.((int) $rowid);
6154 $result = $this->db->query($sql);
6156 $objp = $this->db->fetch_object($result);
6159 $this->error =
'InvoiceLine with id '. $rowid .
' not found sql='.$sql;
6163 $this->
rowid = $objp->rowid;
6164 $this->
id = $objp->rowid;
6165 $this->fk_facture = $objp->fk_facture;
6166 $this->fk_parent_line = $objp->fk_parent_line;
6167 $this->label = $objp->custom_label;
6168 $this->desc = $objp->description;
6169 $this->qty = $objp->qty;
6170 $this->subprice = $objp->subprice;
6171 $this->ref_ext = $objp->ref_ext;
6172 $this->vat_src_code = $objp->vat_src_code;
6173 $this->tva_tx = $objp->tva_tx;
6174 $this->localtax1_tx = $objp->localtax1_tx;
6175 $this->localtax2_tx = $objp->localtax2_tx;
6176 $this->remise_percent = $objp->remise_percent;
6177 $this->fk_remise_except = $objp->fk_remise_except;
6178 $this->fk_product = $objp->fk_product;
6179 $this->product_type = $objp->product_type;
6180 $this->date_start = $this->db->jdate($objp->date_start);
6181 $this->date_end = $this->db->jdate($objp->date_end);
6182 $this->info_bits = $objp->info_bits;
6183 $this->tva_npr = ($objp->info_bits & 1 == 1) ? 1 : 0;
6184 $this->special_code = $objp->special_code;
6185 $this->total_ht = $objp->total_ht;
6186 $this->total_tva = $objp->total_tva;
6187 $this->total_localtax1 = $objp->total_localtax1;
6188 $this->total_localtax2 = $objp->total_localtax2;
6189 $this->total_ttc = $objp->total_ttc;
6190 $this->fk_code_ventilation = $objp->fk_code_ventilation;
6191 $this->rang = $objp->rang;
6192 $this->fk_fournprice = $objp->fk_fournprice;
6193 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
6194 $this->pa_ht = $marginInfos[0];
6195 $this->marge_tx = $marginInfos[1];
6196 $this->marque_tx = $marginInfos[2];
6198 $this->
ref = $objp->product_ref;
6200 $this->product_ref = $objp->product_ref;
6201 $this->product_label = $objp->product_label;
6202 $this->product_desc = $objp->product_desc;
6204 $this->fk_unit = $objp->fk_unit;
6205 $this->fk_user_modif = $objp->fk_user_modif;
6206 $this->fk_user_author = $objp->fk_user_author;
6208 $this->situation_percent = $objp->situation_percent;
6209 $this->fk_prev_id = $objp->fk_prev_id;
6211 $this->multicurrency_subprice = $objp->multicurrency_subprice;
6212 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
6213 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
6214 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
6218 $this->db->free($result);
6222 $this->error = $this->db->lasterror();
6234 public function insert($notrigger = 0, $noerrorifdiscountalreadylinked = 0)
6236 global $langs, $user, $conf;
6240 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
6242 dol_syslog(get_class($this).
"::insert rang=".$this->rang, LOG_DEBUG);
6245 $this->desc = trim($this->desc);
6246 if (empty($this->tva_tx)) {
6249 if (empty($this->localtax1_tx)) {
6250 $this->localtax1_tx = 0;
6252 if (empty($this->localtax2_tx)) {
6253 $this->localtax2_tx = 0;
6255 if (empty($this->localtax1_type)) {
6256 $this->localtax1_type = 0;
6258 if (empty($this->localtax2_type)) {
6259 $this->localtax2_type = 0;
6261 if (empty($this->total_localtax1)) {
6262 $this->total_localtax1 = 0;
6264 if (empty($this->total_localtax2)) {
6265 $this->total_localtax2 = 0;
6267 if (empty($this->rang)) {
6270 if (empty($this->remise_percent)) {
6271 $this->remise_percent = 0;
6273 if (empty($this->info_bits)) {
6274 $this->info_bits = 0;
6276 if (empty($this->subprice)) {
6277 $this->subprice = 0;
6279 if (empty($this->ref_ext)) {
6280 $this->ref_ext =
'';
6282 if (empty($this->special_code)) {
6283 $this->special_code = 0;
6285 if (empty($this->fk_parent_line)) {
6286 $this->fk_parent_line = 0;
6288 if (empty($this->fk_prev_id)) {
6289 $this->fk_prev_id = 0;
6291 if (!isset($this->situation_percent) || $this->situation_percent > 100 || (
string) $this->situation_percent ==
'') {
6292 $this->situation_percent = 100;
6295 if (empty($this->pa_ht)) {
6298 if (empty($this->multicurrency_subprice)) {
6299 $this->multicurrency_subprice = 0;
6301 if (empty($this->multicurrency_total_ht)) {
6302 $this->multicurrency_total_ht = 0;
6304 if (empty($this->multicurrency_total_tva)) {
6305 $this->multicurrency_total_tva = 0;
6307 if (empty($this->multicurrency_total_ttc)) {
6308 $this->multicurrency_total_ttc = 0;
6312 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
6313 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
6316 $this->pa_ht = $result;
6321 if ($this->product_type < 0) {
6322 $this->error =
'ErrorProductTypeMustBe0orMore';
6325 if (!empty($this->fk_product) && $this->fk_product > 0) {
6329 $this->error =
'ErrorProductIdDoesNotExists';
6330 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6338 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'facturedet';
6339 $sql .=
' (fk_facture, fk_parent_line, label, description, qty,';
6340 $sql .=
' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
6341 $sql .=
' fk_product, product_type, remise_percent, subprice, ref_ext, fk_remise_except,';
6342 $sql .=
' date_start, date_end, fk_code_ventilation, ';
6343 $sql .=
' rang, special_code, fk_product_fournisseur_price, buy_price_ht,';
6344 $sql .=
' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2,';
6345 $sql .=
' situation_percent, fk_prev_id,';
6346 $sql .=
' fk_unit, fk_user_author, fk_user_modif,';
6347 $sql .=
' fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
6349 $sql .=
" VALUES (".$this->fk_facture.
",";
6350 $sql .=
" ".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null").
",";
6351 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
6352 $sql .=
" '".$this->db->escape($this->desc).
"',";
6353 $sql .=
" ".price2num($this->qty).
",";
6354 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
6355 $sql .=
" ".price2num($this->tva_tx).
",";
6356 $sql .=
" ".price2num($this->localtax1_tx).
",";
6357 $sql .=
" ".price2num($this->localtax2_tx).
",";
6358 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
6359 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
6360 $sql .=
' '.((!empty($this->fk_product) && $this->fk_product > 0) ? $this->fk_product :
"null").
',';
6361 $sql .=
" ".((int) $this->product_type).
",";
6362 $sql .=
" ".price2num($this->remise_percent).
",";
6363 $sql .=
" ".price2num($this->subprice).
",";
6364 $sql .=
" '".$this->db->escape($this->ref_ext).
"',";
6365 $sql .=
' '.(!empty($this->fk_remise_except) ? $this->fk_remise_except :
"null").
',';
6366 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
",";
6367 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null").
",";
6368 $sql .=
' '.((int) $this->fk_code_ventilation).
',';
6369 $sql .=
' '.((int) $this->rang).
',';
6370 $sql .=
' '.((int) $this->special_code).
',';
6371 $sql .=
' '.(!empty($this->fk_fournprice) ? $this->fk_fournprice :
"null").
',';
6372 $sql .=
' '.price2num($this->pa_ht).
',';
6373 $sql .=
" '".$this->db->escape($this->info_bits).
"',";
6374 $sql .=
" ".price2num($this->total_ht).
",";
6375 $sql .=
" ".price2num($this->total_tva).
",";
6376 $sql .=
" ".price2num($this->total_ttc).
",";
6377 $sql .=
" ".price2num($this->total_localtax1).
",";
6378 $sql .=
" ".price2num($this->total_localtax2);
6379 $sql .=
", ".((float) $this->situation_percent);
6380 $sql .=
", ".(!empty($this->fk_prev_id) ? $this->fk_prev_id :
"null");
6381 $sql .=
", ".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
6382 $sql .=
", ".((int) $user->id);
6383 $sql .=
", ".((int) $user->id);
6384 $sql .=
", ".(int) $this->fk_multicurrency;
6385 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
6386 $sql .=
", ".price2num($this->multicurrency_subprice);
6387 $sql .=
", ".price2num($this->multicurrency_total_ht);
6388 $sql .=
", ".price2num($this->multicurrency_total_tva);
6389 $sql .=
", ".price2num($this->multicurrency_total_ttc);
6392 dol_syslog(get_class($this).
"::insert", LOG_DEBUG);
6393 $resql = $this->db->query($sql);
6395 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'facturedet');
6396 $this->
rowid = $this->id;
6407 if ($this->fk_remise_except) {
6409 $result = $discount->fetch($this->fk_remise_except);
6414 if ($discount->fk_facture_line > 0) {
6415 if (empty($noerrorifdiscountalreadylinked)) {
6416 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed", $discount->id);
6417 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6418 $this->db->rollback();
6422 $result = $discount->link_to_invoice($this->
rowid, 0);
6424 $this->error = $discount->error;
6425 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6426 $this->db->rollback();
6431 $this->error = $langs->trans(
"ErrorADiscountThatHasBeenRemovedIsIncluded");
6432 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6433 $this->db->rollback();
6437 $this->error = $discount->error;
6438 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6439 $this->db->rollback();
6446 $result = $this->
call_trigger(
'LINEBILL_INSERT', $user);
6448 $this->db->rollback();
6454 $this->db->commit();
6457 $this->error = $this->db->lasterror();
6458 $this->db->rollback();
6470 public function update($user =
'', $notrigger = 0)
6472 global $user, $conf;
6476 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
6479 $this->desc = trim($this->desc);
6480 if (empty($this->ref_ext)) {
6481 $this->ref_ext =
'';
6483 if (empty($this->tva_tx)) {
6486 if (empty($this->localtax1_tx)) {
6487 $this->localtax1_tx = 0;
6489 if (empty($this->localtax2_tx)) {
6490 $this->localtax2_tx = 0;
6492 if (empty($this->localtax1_type)) {
6493 $this->localtax1_type = 0;
6495 if (empty($this->localtax2_type)) {
6496 $this->localtax2_type = 0;
6498 if (empty($this->total_localtax1)) {
6499 $this->total_localtax1 = 0;
6501 if (empty($this->total_localtax2)) {
6502 $this->total_localtax2 = 0;
6504 if (empty($this->remise_percent)) {
6505 $this->remise_percent = 0;
6507 if (empty($this->info_bits)) {
6508 $this->info_bits = 0;
6510 if (empty($this->special_code)) {
6511 $this->special_code = 0;
6513 if (empty($this->product_type)) {
6514 $this->product_type = 0;
6516 if (empty($this->fk_parent_line)) {
6517 $this->fk_parent_line = 0;
6519 if (!isset($this->situation_percent) || $this->situation_percent > 100 || (
string) $this->situation_percent ==
'') {
6520 $this->situation_percent = 100;
6522 if (empty($this->pa_ht)) {
6526 if (empty($this->multicurrency_subprice)) {
6527 $this->multicurrency_subprice = 0;
6529 if (empty($this->multicurrency_total_ht)) {
6530 $this->multicurrency_total_ht = 0;
6532 if (empty($this->multicurrency_total_tva)) {
6533 $this->multicurrency_total_tva = 0;
6535 if (empty($this->multicurrency_total_ttc)) {
6536 $this->multicurrency_total_ttc = 0;
6540 if ($this->product_type < 0) {
6545 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
6547 $result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product);
6551 $this->pa_ht = $result;
6558 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facturedet SET";
6559 $sql .=
" description='".$this->db->escape($this->desc).
"'";
6560 $sql .=
", ref_ext='".$this->db->escape($this->ref_ext).
"'";
6561 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
6562 $sql .=
", subprice=".price2num($this->subprice);
6563 $sql .=
", remise_percent=".price2num($this->remise_percent);
6564 if ($this->fk_remise_except) {
6565 $sql .=
", fk_remise_except=".$this->fk_remise_except;
6567 $sql .=
", fk_remise_except=null";
6569 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->db->escape($this->vat_src_code)).
"'";
6570 $sql .=
", tva_tx=".price2num($this->tva_tx);
6571 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
6572 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
6573 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
6574 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
6575 $sql .=
", qty=".price2num($this->qty);
6576 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
6577 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
6578 $sql .=
", product_type=".$this->product_type;
6579 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
6580 $sql .=
", special_code='".$this->db->escape($this->special_code).
"'";
6581 if (empty($this->skip_update_total)) {
6582 $sql .=
", total_ht=".price2num($this->total_ht);
6583 $sql .=
", total_tva=".price2num($this->total_tva);
6584 $sql .=
", total_ttc=".price2num($this->total_ttc);
6585 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
6586 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
6588 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
6589 $sql .=
", buy_price_ht=".(($this->pa_ht || (string) $this->pa_ht ===
'0') ?
price2num($this->pa_ht) :
"null");
6590 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null");
6591 if (!empty($this->rang)) {
6592 $sql .=
", rang=".((int) $this->rang);
6594 $sql .=
", situation_percent = ".((float) $this->situation_percent);
6595 $sql .=
", fk_unit = ".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
6596 $sql .=
", fk_user_modif = ".((int) $user->id);
6599 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
6600 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
6601 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
6602 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
6604 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
6606 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
6607 $resql = $this->db->query($sql);
6610 $this->
id = $this->rowid;
6617 if (!$error && !$notrigger) {
6619 $result = $this->
call_trigger(
'LINEBILL_MODIFY', $user);
6621 $this->db->rollback();
6626 $this->db->commit();
6629 $this->error = $this->db->error();
6630 $this->db->rollback();
6642 public function delete($tmpuser =
null, $notrigger =
false)
6649 if (empty($notrigger)) {
6650 $result = $this->
call_trigger(
'LINEBILL_DELETE', $user);
6652 $this->db->rollback();
6661 $this->db->rollback();
6666 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
6667 $sql .=
' SET fk_facture_line = NULL';
6668 $sql .=
' WHERE fk_facture_line = '.((int) $this->
id);
6670 dol_syslog(get_class($this).
"::deleteline", LOG_DEBUG);
6671 $result = $this->db->query($sql);
6673 $this->error = $this->db->error();
6674 $this->errors[] = $this->error;
6675 $this->db->rollback();
6679 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'element_time';
6680 $sql .=
' SET invoice_id = NULL, invoice_line_id = NULL';
6681 $sql .=
' WHERE invoice_line_id = '.((int) $this->
id);
6682 if (!$this->db->query($sql)) {
6683 $this->error = $this->db->error().
" sql=".$sql;
6684 $this->errors[] = $this->error;
6685 $this->db->rollback();
6689 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"facturedet WHERE rowid = ".((int) $this->
id);
6691 if ($this->db->query($sql)) {
6692 $this->db->commit();
6695 $this->error = $this->db->error().
" sql=".$sql;
6696 $this->errors[] = $this->error;
6697 $this->db->rollback();
6713 dol_syslog(get_class($this).
"::update_total", LOG_DEBUG);
6716 if (empty($this->total_localtax1)) {
6717 $this->total_localtax1 = 0;
6719 if (empty($this->total_localtax2)) {
6720 $this->total_localtax2 = 0;
6724 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facturedet SET";
6725 $sql .=
" total_ht=".price2num($this->total_ht);
6726 $sql .=
",total_tva=".price2num($this->total_tva);
6727 $sql .=
",total_localtax1=".price2num($this->total_localtax1);
6728 $sql .=
",total_localtax2=".price2num($this->total_localtax2);
6729 $sql .=
",total_ttc=".price2num($this->total_ttc);
6730 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
6732 dol_syslog(get_class($this).
"::update_total", LOG_DEBUG);
6734 $resql = $this->db->query($sql);
6736 $this->db->commit();
6739 $this->error = $this->db->error();
6740 $this->db->rollback();
6757 global $invoicecache;
6759 if (is_null($this->fk_prev_id) || empty($this->fk_prev_id) || $this->fk_prev_id ==
"") {
6763 if (!isset($invoicecache[$invoiceid])) {
6764 $invoicecache[$invoiceid] =
new Facture($this->db);
6765 $invoicecache[$invoiceid]->fetch($invoiceid);
6771 $sql =
"SELECT situation_percent FROM ".MAIN_DB_PREFIX.
"facturedet WHERE rowid = ".((int) $this->fk_prev_id);
6772 $resql = $this->db->query($sql);
6773 if ($resql && $this->db->num_rows($resql) > 0) {
6774 $res = $this->db->fetch_array($resql);
6776 $returnPercent = floatval($res[
'situation_percent']);
6778 if ($include_credit_note) {
6779 $sql =
'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.
'facturedet fd';
6780 $sql .=
' JOIN '.MAIN_DB_PREFIX.
'facture f ON (f.rowid = fd.fk_facture) ';
6781 $sql .=
" WHERE fd.fk_prev_id = ".((int) $this->fk_prev_id);
6782 $sql .=
" AND f.situation_cycle_ref = ".((int) $invoicecache[$invoiceid]->situation_cycle_ref);
6783 $sql .=
" AND f.type = ".Facture::TYPE_CREDIT_NOTE;
6785 $res = $this->db->query($sql);
6787 while ($obj = $this->db->fetch_object($res)) {
6788 $returnPercent = $returnPercent + floatval($obj->situation_percent);
6795 return $returnPercent;
6797 $this->error = $this->db->error();
6798 dol_syslog(get_class($this).
"::select Error ".$this->error, LOG_ERR);
6799 $this->db->rollback();
Class to manage agenda events (actions)
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Superclass for invoices classes.
getSommePaiement($multicurrency=0)
Return amount of payments already done.
calculate_date_lim_reglement($cond_reglement=0)
Returns an invoice payment deadline based on the invoice settlement conditions and billing date.
is_erasable()
Return if an invoice can be deleted Rule is: If invoice is draft and has a temporary ref -> yes (1) I...
Parent class of all other business classes for details of elements (invoices, contracts,...
Parent class of all other business classes (invoices, contracts, proposals, 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.
defineBuyPrice($unitPrice=0.0, $discountPercent=0.0, $fk_product=0)
Get buy price to use for margin calculation.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
getIdContact($source, $code, $status=0)
Return id of contacts for a source and a contact code.
setErrorsFromObject($object)
setErrorsFromObject
static isExistingObject($element, $id, $ref='', $ref_ext='')
Check an object id/ref exists If you don't need/want to instantiate object and just need to know if o...
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.
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 $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
static commonReplaceProduct(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a product 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.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
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.
Class to manage absolute discounts.
Class to manage Dolibarr database access.
Class to manage warehouses.
Class to manage shipments.
Class to manage invoices.
createFromClone(User $user, $fromid=0)
Load an object from its id and create a new one in database.
setDraft($user, $idwarehouse=-1)
Set draft status.
$fk_facture_source
id of source invoice if replacement invoice or credit note
getIdShippingContact()
Retourne id des contacts clients de livraison.
setFinal(User $user, $notrigger=0)
Sets the invoice as a final situation.
setCanceled($user, $close_code='', $close_note='')
Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never rece...
static createDepositFromOrigin(CommonObject $origin, $date, $payment_terms_id, User $user, $notrigger=0, $autoValidateDeposit=false, $overrideFields=array())
Creates a deposit from a proposal or an order by grouping lines by VAT rates.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
fetch($rowid, $ref='', $ref_ext='', $notused='', $fetch_situation=false)
Get object from database.
list_replacable_invoices($socid=0)
Return list of invoices qualified to be replaced by another invoice.
insert_discount($idremise)
Add a discount line into an invoice (as an invoice line) using an existing absolute discount (Consume...
createFromOrder($object, User $user)
Load an object from an order and create a new invoice into database.
load_state_board()
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
willBeLastOfSameType($allow_validated_drafts=false)
See if current invoice date is posterior to the last invoice date among validated invoices of same ty...
update_percent($line, $percent, $update_price=true)
Update invoice line with percentage.
const TYPE_REPLACEMENT
Replacement invoice.
validate($user, $force_number='', $idwarehouse=0, $notrigger=0, $batch_rule=0)
Tag invoice as validated + call trigger BILL_VALIDATE Object must have lines loaded with fetch_lines.
deleteline($rowid, $id=0)
Delete line in database.
update(User $user, $notrigger=0)
Update database.
fetch_lines($only_product=0, $loadalsotranslation=0)
Load all detailed lines into this->lines.
$fk_fac_rec_source
id of template invoice when generated from a template invoice
getIdBillingContact()
Retourne id des contacts clients de facturation.
__construct(DoliDB $db)
Constructor.
const STATUS_DRAFT
Draft status.
setRetainedWarrantyDateLimit($timestamp, $dateYmd=false)
Change the retained_warranty_date_limit.
getNomUrl($withpicto=0, $option='', $max=0, $short=0, $moretitle='', $notooltip=0, $addlinktonotes=0, $save_lastsearch_value=-1, $target='')
Return clicable link of object (with eventually picto)
load_board($user)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
fetchPreviousNextSituationInvoice()
Fetch previous and next situations invoices.
const TYPE_STANDARD
Standard invoice.
const TYPE_SITUATION
Situation invoice.
$paye
1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code)
updatePriceNextInvoice(&$langs)
Update price of next invoice.
static replaceProduct(DoliDB $db, $origin_id, $dest_id)
Function used to replace a product id with another one.
$pos_source
key of pos source ('0', '1', ...)
sendEmailsRemindersOnInvoiceDueDate($nbdays=0, $paymentmode='all', $template='', $datetouse='duedate', $forcerecipient='')
Send reminders by emails for invoices validated that are due.
info($id)
Load miscellaneous information for tab "Info".
const TYPE_PROFORMA
Proforma invoice (should not be used.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
setRetainedWarranty($value)
Change the retained warranty.
get_prev_sits()
Returns an array containing the previous situations as Facture objects.
set_remise_absolue($user, $remise, $notrigger=0)
Set absolute discount.
list_qualified_avoir_invoices($socid=0)
Return list of invoices qualified to be corrected by a credit note.
set_canceled($user, $close_code='', $close_note='')
Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never rece...
updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=self::TYPE_STANDARD, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_options=0, $situation_percent=100, $fk_unit=null, $pu_ht_devise=0, $notrigger=0, $ref_ext='', $rang=0)
Update a detail line.
newCycle()
Gets the smallest reference available for a new cycle.
liste_array($shortlist=0, $draft=0, $excluser='', $socid=0, $limit=0, $offset=0, $sortfield='f.datef, f.rowid', $sortorder='DESC')
Return list of invoices (eventually filtered on a user) into an array.
setDiscount($user, $remise, $notrigger=0)
Set percent discount.
set_ref_client($ref_client, $notrigger=0)
Set customer ref.
is_first()
Checks if the invoice is the first of a cycle.
set_remise($user, $remise, $notrigger=0)
Set percent discount.
getTooltipContentArray($params)
getTooltipContentArray
getNextNumRef($soc, $mode='next')
Return next reference of customer invoice not already used (or last reference) according to numbering...
checkProgressLine($idline, $situation_percent)
Check if the percent edited is lower of next invoice line.
addline( $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_options=0, $situation_percent=100, $fk_prev_id=0, $fk_unit=null, $pu_ht_devise=0, $ref_ext='', $noupdateafterinsertline=0)
Add an invoice line into database (linked to product/service or not).
const STATUS_VALIDATED
Validated (need to be paid)
hasDelay()
Is the customer invoice delayed?
getLinesArray()
Create an array of invoice lines.
set_unpaid($user)
Tag la facture comme non payee completement + appel trigger BILL_UNPAYED Fonction utilisee quand un p...
const TYPE_DEPOSIT
Deposit invoice.
set_paid($user, $close_code='', $close_note='')
Tag the invoice as paid completely (if close_code is filled) => this->fk_statut=2,...
const STATUS_ABANDONED
Classified abandoned and no payment done.
createFromCurrent(User $user, $invertdetail=0)
Create a new invoice in database from current invoice.
setPaid($user, $close_code='', $close_note='')
Tag the invoice as paid completely (if close_code is filled) => this->fk_statut=2,...
displayRetainedWarranty()
Currently used for documents generation : to know if retained warranty need to be displayed.
const TYPE_CREDIT_NOTE
Credit note invoice.
is_last_in_cycle()
Checks if the invoice is the last in its cycle.
initAsSpecimen($option='')
Initialise an instance with random values.
getRetainedWarrantyAmount($rounding=-1)
create(User $user, $notrigger=0, $forceduedate=0)
Create invoice in database.
$module_source
key of module source when invoice generated from a dedicated module ('cashdesk', 'takepos',...
setUnpaid($user)
Tag la facture comme non payee completement + appel trigger BILL_UNPAYED Fonction utilisee quand un p...
const STATUS_CLOSED
Classified paid.
createFromContract($object, User $user, $lines=array())
Load an object from an order and create a new invoice into database.
Class to manage invoice lines.
$fk_parent_line
Id parent line.
insert($notrigger=0, $noerrorifdiscountalreadylinked=0)
Insert line into database.
get_prev_progress($invoiceid, $include_credit_note=true)
Returns situation_percent of the previous line.
fetch($rowid)
Load invoice line from database.
update($user='', $notrigger=0)
Update line into database.
$fk_facture
From llx_facturedet Id facture.
__construct($db)
Constructor.
update_total()
Update DB line fields total_xxx Used by migration.
Class to manage invoice templates.
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.
Manage record for batch number management.
const BATCH_RULE_SELLBY_EATBY_DATES_FIRST
Batches rules.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
print $langs trans("Ref").' m m m statut
dol_get_first_hour($date, $gm='tzserver')
Return GMT time for first hour of a given GMT date (it removes hours, min and second part)
dol_get_last_hour($date, $gm='tzserver')
Return GMT time for last hour of a given GMT date (it replaces hours, min and second part to 23:59:59...
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
dol_get_next_month($month, $year)
Return next month.
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
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_delete_preview($object)
Delete all preview files linked to object instance.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
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)
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.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
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...
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages 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.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
getDictionaryValue($tablename, $field, $id, $checkentity=false, $rowidfield='rowid')
Return the value of a filed into a dictionary for the record $id.
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.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.
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.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type