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) {
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->ref_customer =
'';
1298 $object->close_code =
'';
1299 $object->close_note =
'';
1301 $object->note_private =
'';
1302 $object->note_public =
'';
1306 foreach ($object->lines as $i => $line) {
1307 if (($object->lines[$i]->info_bits & 0x02) == 0x02) {
1308 unset($object->lines[$i]);
1314 if (!empty($conf->global->INVOICE_AUTO_NEXT_MONTH_ON_LINES) && !empty($line->date_start) && !empty($line->date_end)) {
1326 if (
dol_mktime(0, 0, 0, $start[
'mon'], $start[
'mday'], $start[
'year'],
'gmt') == $first
1327 &&
dol_mktime(23, 59, 59, $end[
'mon'], $end[
'mday'], $end[
'year'],
'gmt') == $last) {
1331 $object->lines[$i]->date_start = $newFirst;
1332 $object->lines[$i]->date_end = $newLast;
1336 $object->lines[$i]->ref_ext =
'';
1340 $object->context[
'createfromclone'] =
'createfromclone';
1341 $result = $object->create($user);
1344 $this->error = $object->error;
1345 $this->errors = $object->errors;
1348 if ($object->copy_linked_contact($objFrom,
'internal') < 0) {
1350 $this->error = $object->error;
1351 $this->errors = $object->errors;
1352 } elseif ($object->socid == $objFrom->socid) {
1354 if ($object->copy_linked_contact($objFrom,
'external') < 0) {
1356 $this->error = $object->error;
1357 $this->errors = $object->errors;
1364 if (is_object($hookmanager)) {
1365 $parameters = array(
'objFrom'=>$objFrom);
1367 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action);
1375 unset($object->context[
'createfromclone']);
1379 $this->db->commit();
1382 $this->db->rollback();
1396 global $conf, $hookmanager;
1404 $num = count($object->lines);
1405 for ($i = 0; $i < $num; $i++) {
1408 $line->libelle = $object->lines[$i]->libelle;
1409 $line->label = $object->lines[$i]->label;
1410 $line->desc = $object->lines[$i]->desc;
1411 $line->subprice = $object->lines[$i]->subprice;
1412 $line->total_ht = $object->lines[$i]->total_ht;
1413 $line->total_tva = $object->lines[$i]->total_tva;
1414 $line->total_localtax1 = $object->lines[$i]->total_localtax1;
1415 $line->total_localtax2 = $object->lines[$i]->total_localtax2;
1416 $line->total_ttc = $object->lines[$i]->total_ttc;
1417 $line->vat_src_code = $object->lines[$i]->vat_src_code;
1418 $line->tva_tx = $object->lines[$i]->tva_tx;
1419 $line->localtax1_tx = $object->lines[$i]->localtax1_tx;
1420 $line->localtax2_tx = $object->lines[$i]->localtax2_tx;
1421 $line->qty = $object->lines[$i]->qty;
1422 $line->fk_remise_except = $object->lines[$i]->fk_remise_except;
1423 $line->remise_percent = $object->lines[$i]->remise_percent;
1424 $line->fk_product = $object->lines[$i]->fk_product;
1425 $line->info_bits = $object->lines[$i]->info_bits;
1426 $line->product_type = $object->lines[$i]->product_type;
1427 $line->rang = $object->lines[$i]->rang;
1428 $line->special_code = $object->lines[$i]->special_code;
1429 $line->fk_parent_line = $object->lines[$i]->fk_parent_line;
1430 $line->fk_unit = $object->lines[$i]->fk_unit;
1431 $line->date_start = $object->lines[$i]->date_start;
1432 $line->date_end = $object->lines[$i]->date_end;
1435 $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency;
1436 $line->multicurrency_code = $object->lines[$i]->multicurrency_code;
1437 $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice;
1438 $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht;
1439 $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva;
1440 $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc;
1442 $line->fk_fournprice = $object->lines[$i]->fk_fournprice;
1443 $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);
1444 $line->pa_ht = $marginInfos[0];
1447 $object->lines[$i]->fetch_optionals();
1448 foreach ($object->lines[$i]->array_options as $options_key => $value) {
1449 $line->array_options[$options_key] = $value;
1452 $this->lines[$i] = $line;
1455 $this->socid = $object->socid;
1456 $this->fk_project = $object->fk_project;
1457 $this->fk_account = $object->fk_account;
1458 $this->cond_reglement_id = $object->cond_reglement_id;
1459 $this->mode_reglement_id = $object->mode_reglement_id;
1460 $this->availability_id = $object->availability_id;
1461 $this->demand_reason_id = $object->demand_reason_id;
1462 $this->delivery_date = (empty($object->delivery_date) ? $object->date_livraison : $object->delivery_date);
1463 $this->date_livraison = $object->delivery_date;
1464 $this->fk_delivery_address = $object->fk_delivery_address;
1465 $this->contact_id = $object->contact_id;
1466 $this->ref_client = $object->ref_client;
1468 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1469 $this->note_private = $object->note_private;
1470 $this->note_public = $object->note_public;
1473 $this->module_source = $object->module_source;
1474 $this->pos_source = $object->pos_source;
1476 $this->origin = $object->element;
1477 $this->origin_id = $object->id;
1479 $this->fk_user_author = $user->id;
1482 $object->fetch_optionals();
1483 foreach ($object->array_options as $options_key => $value) {
1484 $this->array_options[$options_key] = $value;
1488 $this->linked_objects[$this->origin] = $this->origin_id;
1489 if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) {
1490 $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
1493 $ret = $this->
create($user);
1497 $hookmanager->initHooks(array(
'invoicedao'));
1499 $parameters = array(
'objFrom'=>$object);
1501 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1527 global $conf, $hookmanager;
1535 $use_all_lines = empty($lines);
1536 $num = count($object->lines);
1537 for ($i = 0; $i < $num; $i++) {
1538 if (!$use_all_lines && !in_array($object->lines[$i]->id, $lines)) {
1544 $line->libelle = $object->lines[$i]->libelle;
1545 $line->label = $object->lines[$i]->label;
1546 $line->desc = $object->lines[$i]->desc;
1547 $line->subprice = $object->lines[$i]->subprice;
1548 $line->total_ht = $object->lines[$i]->total_ht;
1549 $line->total_tva = $object->lines[$i]->total_tva;
1550 $line->total_localtax1 = $object->lines[$i]->total_localtax1;
1551 $line->total_localtax2 = $object->lines[$i]->total_localtax2;
1552 $line->total_ttc = $object->lines[$i]->total_ttc;
1553 $line->vat_src_code = $object->lines[$i]->vat_src_code;
1554 $line->tva_tx = $object->lines[$i]->tva_tx;
1555 $line->localtax1_tx = $object->lines[$i]->localtax1_tx;
1556 $line->localtax2_tx = $object->lines[$i]->localtax2_tx;
1557 $line->qty = $object->lines[$i]->qty;
1558 $line->fk_remise_except = $object->lines[$i]->fk_remise_except;
1559 $line->remise_percent = $object->lines[$i]->remise_percent;
1560 $line->fk_product = $object->lines[$i]->fk_product;
1561 $line->info_bits = $object->lines[$i]->info_bits;
1562 $line->product_type = $object->lines[$i]->product_type;
1563 $line->rang = $object->lines[$i]->rang;
1564 $line->special_code = $object->lines[$i]->special_code;
1565 $line->fk_parent_line = $object->lines[$i]->fk_parent_line;
1566 $line->fk_unit = $object->lines[$i]->fk_unit;
1567 $line->date_start = $object->lines[$i]->date_start;
1568 $line->date_end = $object->lines[$i]->date_end;
1571 $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency;
1572 $line->multicurrency_code = $object->lines[$i]->multicurrency_code;
1573 $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice;
1574 $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht;
1575 $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva;
1576 $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc;
1578 $line->fk_fournprice = $object->lines[$i]->fk_fournprice;
1579 $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);
1580 $line->pa_ht = $marginInfos[0];
1583 $object->lines[$i]->fetch_optionals();
1584 foreach ($object->lines[$i]->array_options as $options_key => $value) {
1585 $line->array_options[$options_key] = $value;
1588 $this->lines[$i] = $line;
1591 $this->socid = $object->socid;
1592 $this->fk_project = $object->fk_project;
1593 $this->fk_account = $object->fk_account;
1594 $this->cond_reglement_id = $object->cond_reglement_id;
1595 $this->mode_reglement_id = $object->mode_reglement_id;
1596 $this->availability_id = $object->availability_id;
1597 $this->demand_reason_id = $object->demand_reason_id;
1598 $this->delivery_date = (empty($object->delivery_date) ? $object->date_livraison : $object->delivery_date);
1599 $this->date_livraison = $object->delivery_date;
1600 $this->fk_delivery_address = $object->fk_delivery_address;
1601 $this->contact_id = $object->contact_id;
1602 $this->ref_client = $object->ref_client;
1604 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1605 $this->note_private = $object->note_private;
1606 $this->note_public = $object->note_public;
1609 $this->module_source = $object->module_source;
1610 $this->pos_source = $object->pos_source;
1612 $this->origin = $object->element;
1613 $this->origin_id = $object->id;
1615 $this->fk_user_author = $user->id;
1618 $object->fetch_optionals();
1619 foreach ($object->array_options as $options_key => $value) {
1620 $this->array_options[$options_key] = $value;
1624 $this->linked_objects[$this->origin] = $this->origin_id;
1625 if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) {
1626 $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
1629 $ret = $this->
create($user);
1633 $hookmanager->initHooks(array(
'invoicedao'));
1635 $parameters = array(
'objFrom'=>$object);
1637 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1667 global $conf, $langs, $hookmanager, $action;
1669 if (! in_array($origin->element, array(
'propal',
'commande'))) {
1670 $origin->error =
'ErrorCanOnlyAutomaticallyGenerateADepositFromProposalOrOrder';
1675 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'DateInvoice'));
1679 require_once DOL_DOCUMENT_ROOT .
'/core/lib/date.lib.php';
1681 if ($date > (
dol_get_last_hour(
dol_now(
'tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
1682 $origin->error =
'ErrorDateIsInFuture';
1686 if ($payment_terms_id <= 0) {
1687 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'PaymentConditionsShort'));
1691 $payment_conditions_deposit_percent =
getDictionaryValue(
'c_payment_term',
'deposit_percent', $origin->cond_reglement_id);
1693 if (empty($payment_conditions_deposit_percent)) {
1694 $origin->error =
'ErrorPaymentConditionsNotEligibleToDepositCreation';
1698 if (empty($origin->deposit_percent)) {
1699 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'DepositPercent'));
1703 $deposit =
new self($origin->db);
1704 $deposit->socid = $origin->socid;
1706 $deposit->fk_project = $origin->fk_project;
1707 $deposit->ref_client = $origin->ref_client;
1708 $deposit->date = $date;
1709 $deposit->mode_reglement_id = $origin->mode_reglement_id;
1710 $deposit->cond_reglement_id = $payment_terms_id;
1711 $deposit->availability_id = $origin->availability_id;
1712 $deposit->demand_reason_id = $origin->demand_reason_id;
1713 $deposit->fk_account = $origin->fk_account;
1714 $deposit->fk_incoterms = $origin->fk_incoterms;
1715 $deposit->location_incoterms = $origin->location_incoterms;
1716 $deposit->fk_multicurrency = $origin->fk_multicurrency;
1717 $deposit->multicurrency_code = $origin->multicurrency_code;
1718 $deposit->multicurrency_tx = $origin->multicurrency_tx;
1719 $deposit->module_source = $origin->module_source;
1720 $deposit->pos_source = $origin->pos_source;
1721 $deposit->model_pdf =
'crabe';
1723 $modelByTypeConfName =
'FACTURE_ADDON_PDF_' . $deposit->type;
1725 if (!empty($conf->global->$modelByTypeConfName)) {
1726 $deposit->model_pdf = $conf->global->$modelByTypeConfName;
1727 } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) {
1728 $deposit->model_pdf = $conf->global->FACTURE_ADDON_PDF;
1731 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1732 $deposit->note_private = $origin->note_private;
1733 $deposit->note_public = $origin->note_public;
1736 $deposit->origin = $origin->element;
1737 $deposit->origin_id = $origin->id;
1739 $origin->fetch_optionals();
1741 foreach ($origin->array_options as $extrakey => $value) {
1742 $deposit->array_options[$extrakey] = $value;
1745 $deposit->linked_objects[$deposit->origin] = $deposit->origin_id;
1747 foreach ($overrideFields as $key => $value) {
1748 $deposit->$key = $value;
1751 $deposit->context[
'createdepositfromorigin'] =
'createdepositfromorigin';
1753 $origin->db->begin();
1756 $createReturn = $deposit->create($user, $notrigger);
1758 if ($createReturn <= 0) {
1759 $origin->db->rollback();
1760 $origin->error = $deposit->error;
1761 $origin->errors = $deposit->errors;
1765 $amount_ttc_diff = 0;
1766 $amountdeposit = array();
1767 $descriptions = array();
1769 if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)) {
1770 $amount = $origin->total_ttc * ($origin->deposit_percent / 100);
1772 $TTotalByTva = array();
1773 foreach ($origin->lines as &$line) {
1774 if (!empty($line->special_code)) {
1777 $TTotalByTva[$line->tva_tx] += $line->total_ttc;
1778 $descriptions[$line->tva_tx] .=
'<li>' . (!empty($line->product_ref) ? $line->product_ref .
' - ' :
'');
1779 $descriptions[$line->tva_tx] .= (!empty($line->product_label) ? $line->product_label .
' - ' :
'');
1780 $descriptions[$line->tva_tx] .= $langs->trans(
'Qty') .
' : ' . $line->qty;
1781 $descriptions[$line->tva_tx] .=
' - ' . $langs->trans(
'TotalHT') .
' : ' .
price($line->total_ht) .
'</li>';
1784 foreach ($TTotalByTva as $tva => &$total) {
1785 $coef = $total / $origin->total_ttc;
1786 $am = $amount * $coef;
1787 $amount_ttc_diff += $am;
1788 $amountdeposit[$tva] += $am / (1 + $tva / 100);
1792 $lines = $origin->lines;
1793 $numlines = count($lines);
1794 for ($i = 0; $i < $numlines; $i++) {
1795 if (empty($lines[$i]->qty)) {
1798 if (!empty($lines[$i]->special_code)) {
1802 $totalamount += $lines[$i]->total_ht;
1803 $tva_tx = $lines[$i]->tva_tx;
1804 $amountdeposit[$tva_tx] += ($lines[$i]->total_ht * $origin->deposit_percent) / 100;
1805 $descriptions[$tva_tx] .=
'<li>' . (!empty($lines[$i]->product_ref) ? $lines[$i]->product_ref .
' - ' :
'');
1806 $descriptions[$tva_tx] .= (!empty($lines[$i]->product_label) ? $lines[$i]->product_label .
' - ' :
'');
1807 $descriptions[$tva_tx] .= $langs->trans(
'Qty') .
' : ' . $lines[$i]->qty;
1808 $descriptions[$tva_tx] .=
' - ' . $langs->trans(
'TotalHT') .
' : ' .
price($lines[$i]->total_ht) .
'</li>';
1811 if ($totalamount == 0) {
1812 $amountdeposit[0] = 0;
1815 $amount_ttc_diff = $amountdeposit[0];
1818 foreach ($amountdeposit as $tva => $amount) {
1819 if (empty($amount)) {
1823 $descline =
'(DEPOSIT) ('. $origin->deposit_percent .
'%) - '.$origin->ref;
1826 if (!empty($conf->global->INVOICE_DEPOSIT_VARIABLE_MODE_DETAIL_LINES_IN_DESCRIPTION) && !empty($descriptions[$tva])) {
1827 $descline .=
'<ul>' . $descriptions[$tva] .
'</ul>';
1830 $addlineResult = $deposit->addline(
1837 (empty($conf->global->INVOICE_PRODUCTID_DEPOSIT) ? 0 : $conf->global->INVOICE_PRODUCTID_DEPOSIT),
1857 if ($addlineResult < 0) {
1858 $origin->db->rollback();
1859 $origin->error = $deposit->error;
1860 $origin->errors = $deposit->errors;
1865 $diff = $deposit->total_ttc - $amount_ttc_diff;
1867 if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA) && $diff != 0) {
1868 $deposit->fetch_lines();
1869 $subprice_diff = $deposit->lines[0]->subprice - $diff / (1 + $deposit->lines[0]->tva_tx / 100);
1871 $updatelineResult = $deposit->updateline(
1872 $deposit->lines[0]->id,
1873 $deposit->lines[0]->desc,
1875 $deposit->lines[0]->qty,
1876 $deposit->lines[0]->remise_percent,
1877 $deposit->lines[0]->date_start,
1878 $deposit->lines[0]->date_end,
1879 $deposit->lines[0]->tva_tx,
1883 $deposit->lines[0]->info_bits,
1884 $deposit->lines[0]->product_type,
1888 $deposit->lines[0]->pa_ht,
1889 $deposit->lines[0]->label,
1895 if ($updatelineResult < 0) {
1896 $origin->db->rollback();
1897 $origin->error = $deposit->error;
1898 $origin->errors = $deposit->errors;
1903 $hookmanager->initHooks(array(
'invoicedao'));
1905 $parameters = array(
'objFrom' => $origin);
1906 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $deposit, $action);
1909 $origin->db->rollback();
1910 $origin->error = $hookmanager->error;
1911 $origin->errors = $hookmanager->errors;
1915 if (!empty($autoValidateDeposit)) {
1916 $validateReturn = $deposit->validate($user,
'', 0, $notrigger);
1918 if ($validateReturn < 0) {
1919 $origin->db->rollback();
1920 $origin->error = $deposit->error;
1921 $origin->errors = $deposit->errors;
1926 unset($deposit->context[
'createdepositfromorigin']);
1928 $origin->db->commit();
1942 global $conf, $langs, $mysoc, $user;
1944 $langs->load(
'bills');
1947 $moretitle = $params[
'moretitle'] ??
'';
1948 $picto = $this->picto;
1949 if ($this->
type == self::TYPE_REPLACEMENT) {
1952 if ($this->
type == self::TYPE_CREDIT_NOTE) {
1955 if ($this->
type == self::TYPE_DEPOSIT) {
1959 if ($user->hasRight(
"facture",
"read")) {
1960 $datas[
'picto'] =
img_picto(
'', $picto).
' <u class="paddingrightonly">'.$langs->trans(
"Invoice").
'</u>';
1962 $datas[
'picto'] .=
' '.$this->getLibType(1);
1965 if (!empty($params[
'fromajaxtooltip']) && !isset($this->alreadypaid)) {
1969 if (isset($this->
statut) && isset($this->alreadypaid)) {
1970 $datas[
'picto'] .=
' '.$this->getLibStatut(5, $this->alreadypaid);
1973 $datas[
'picto'] .=
' - '.$moretitle;
1975 if (!empty($this->
ref)) {
1976 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1978 if (!empty($this->ref_customer)) {
1979 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_customer;
1981 if (!empty($this->date)) {
1982 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
1984 if (!empty($this->total_ht)) {
1985 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1987 if (!empty($this->total_tva)) {
1988 $datas[
'amountvat'] =
'<br><b>'.$langs->trans(
'AmountVAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1990 if (!empty($this->revenuestamp) && $this->revenuestamp != 0) {
1991 $datas[
'amountrevenustamp'] =
'<br><b>'.$langs->trans(
'RevenueStamp').
':</b> '.
price($this->revenuestamp, 0, $langs, 0, -1, -1, $conf->currency);
1993 if (!empty($this->total_localtax1) && $this->total_localtax1 != 0) {
1995 $datas[
'amountlt1'] =
'<br><b>'.$langs->transcountry(
'AmountLT1', $mysoc->country_code).
':</b> '.
price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency);
1997 if (!empty($this->total_localtax2) && $this->total_localtax2 != 0) {
1998 $datas[
'amountlt2'] =
'<br><b>'.$langs->transcountry(
'AmountLT2', $mysoc->country_code).
':</b> '.
price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency);
2000 if (!empty($this->total_ttc)) {
2001 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
2022 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $addlinktonotes = 0, $save_lastsearch_value = -1, $target =
'')
2024 global $langs, $conf, $user, $mysoc;
2026 if (!empty($conf->dol_no_mouse_hover)) {
2032 if ($option ==
'withdraw') {
2033 $url = DOL_URL_ROOT.
'/compta/facture/prelevement.php?facid='.$this->id;
2035 $url = DOL_URL_ROOT.
'/compta/facture/card.php?facid='.$this->id;
2038 if (!$user->hasRight(
"facture",
"read")) {
2042 if ($option !==
'nolink') {
2044 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2045 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
2046 $add_save_lastsearch_values = 1;
2048 if ($add_save_lastsearch_values) {
2049 $url .=
'&save_lastsearch_values=1';
2057 $picto = $this->picto;
2058 if ($this->
type == self::TYPE_REPLACEMENT) {
2061 if ($this->
type == self::TYPE_CREDIT_NOTE) {
2064 if ($this->
type == self::TYPE_DEPOSIT) {
2069 'objecttype' => $this->element,
2070 'moretitle' => $moretitle,
2071 'option' => $option,
2073 $classfortooltip =
'classfortooltip';
2076 $classfortooltip =
'classforajaxtooltip';
2077 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
2083 $linkclose = ($target ?
' target="'.$target.
'"' :
'');
2084 if (empty($notooltip) && $user->hasRight(
"facture",
"read")) {
2085 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
2086 $label = $langs->trans(
"Invoice");
2087 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
2089 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
2090 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
2093 $linkstart =
'<a href="'.$url.
'"';
2094 $linkstart .= $linkclose.
'>';
2097 if ($option ==
'nolink') {
2102 $result .= $linkstart;
2104 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
2106 if ($withpicto != 2) {
2107 $result .= ($max ?
dol_trunc($this->
ref, $max) : $this->ref);
2109 $result .= $linkend;
2111 if ($addlinktonotes) {
2112 $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private);
2115 $notetoshow = $langs->trans(
"ViewPrivateNote").
':<br>'.$txttoshow;
2116 $result .=
' <span class="note inline-block">';
2117 $result .=
'<a href="'.DOL_URL_ROOT.
'/compta/facture/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($notetoshow, 1, 1).
'">';
2122 $result .=
'</span>';
2126 global $action, $hookmanager;
2127 $hookmanager->initHooks(array(
'invoicedao'));
2128 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result,
'notooltip' => $notooltip,
'addlinktonotes' => $addlinktonotes,
'save_lastsearch_value'=> $save_lastsearch_value,
'target' => $target);
2129 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
2131 $result = $hookmanager->resPrint;
2133 $result .= $hookmanager->resPrint;
2149 public function fetch($rowid, $ref =
'', $ref_ext =
'', $notused =
'', $fetch_situation =
false)
2151 if (empty($rowid) && empty($ref) && empty($ref_ext)) {
2155 $sql =
'SELECT f.rowid, f.entity, f.ref, f.ref_client, f.ref_ext, f.type, f.fk_soc';
2156 $sql .=
', f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc, f.revenuestamp';
2157 $sql .=
', f.remise_percent, f.remise_absolue, f.remise';
2158 $sql .=
', f.datef as df, f.date_pointoftax';
2159 $sql .=
', f.date_lim_reglement as dlr';
2160 $sql .=
', f.datec as datec';
2161 $sql .=
', f.date_valid as datev';
2162 $sql .=
', f.tms as datem';
2163 $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';
2164 $sql .=
', f.fk_facture_source, f.fk_fac_rec_source';
2165 $sql .=
', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet as fk_project, f.extraparams';
2166 $sql .=
', f.situation_cycle_ref, f.situation_counter, f.situation_final';
2167 $sql .=
', f.fk_account';
2168 $sql .=
", f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc";
2169 $sql .=
', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
2170 $sql .=
', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
2171 $sql .=
', f.fk_incoterms, f.location_incoterms';
2172 $sql .=
', f.module_source, f.pos_source';
2173 $sql .=
", i.libelle as label_incoterms";
2174 $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";
2175 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facture as f';
2176 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
2177 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as p ON f.fk_mode_reglement = p.id';
2178 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON f.fk_incoterms = i.rowid';
2181 $sql .=
" WHERE f.rowid = ".((int) $rowid);
2183 $sql .=
' WHERE f.entity IN ('.getEntity(
'invoice').
')';
2185 $sql .=
" AND f.ref = '".$this->db->escape($ref).
"'";
2188 $sql .=
" AND f.ref_ext = '".$this->db->escape($ref_ext).
"'";
2192 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
2193 $resql = $this->db->query($sql);
2195 if ($this->db->num_rows($resql)) {
2196 $obj = $this->db->fetch_object($resql);
2198 $this->
id = $obj->rowid;
2199 $this->entity = $obj->entity;
2201 $this->
ref = $obj->ref;
2202 $this->ref_client = $obj->ref_client;
2203 $this->ref_customer = $obj->ref_client;
2204 $this->ref_ext = $obj->ref_ext;
2205 $this->
type = $obj->type;
2206 $this->date = $this->db->jdate($obj->df);
2207 $this->date_pointoftax = $this->db->jdate($obj->date_pointoftax);
2208 $this->date_creation = $this->db->jdate($obj->datec);
2209 $this->date_validation = $this->db->jdate($obj->datev);
2210 $this->date_modification = $this->db->jdate($obj->datem);
2211 $this->datem = $this->db->jdate($obj->datem);
2212 $this->remise_percent = $obj->remise_percent;
2213 $this->remise_absolue = $obj->remise_absolue;
2214 $this->total_ht = $obj->total_ht;
2215 $this->total_tva = $obj->total_tva;
2216 $this->total_localtax1 = $obj->localtax1;
2217 $this->total_localtax2 = $obj->localtax2;
2218 $this->total_ttc = $obj->total_ttc;
2219 $this->revenuestamp = $obj->revenuestamp;
2220 $this->paye = $obj->paye;
2221 $this->close_code = $obj->close_code;
2222 $this->close_note = $obj->close_note;
2224 $this->socid = $obj->fk_soc;
2225 $this->thirdparty =
null;
2227 $this->fk_project = $obj->fk_project;
2228 $this->project =
null;
2230 $this->
statut = $obj->fk_statut;
2231 $this->status = $obj->fk_statut;
2233 $this->date_lim_reglement = $this->db->jdate($obj->dlr);
2234 $this->mode_reglement_id = $obj->fk_mode_reglement;
2235 $this->mode_reglement_code = $obj->mode_reglement_code;
2236 $this->mode_reglement = $obj->mode_reglement_libelle;
2237 $this->cond_reglement_id = $obj->fk_cond_reglement;
2238 $this->cond_reglement_code = $obj->cond_reglement_code;
2239 $this->cond_reglement = $obj->cond_reglement_libelle;
2240 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
2241 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
2242 $this->fk_facture_source = $obj->fk_facture_source;
2243 $this->fk_fac_rec_source = $obj->fk_fac_rec_source;
2244 $this->note = $obj->note_private;
2245 $this->note_private = $obj->note_private;
2246 $this->note_public = $obj->note_public;
2247 $this->user_author = $obj->fk_user_author;
2248 $this->user_valid = $obj->fk_user_valid;
2249 $this->user_modification = $obj->fk_user_modif;
2250 $this->fk_user_author = $obj->fk_user_author;
2251 $this->fk_user_valid = $obj->fk_user_valid;
2252 $this->fk_user_modif = $obj->fk_user_modif;
2253 $this->model_pdf = $obj->model_pdf;
2254 $this->modelpdf = $obj->model_pdf;
2255 $this->last_main_doc = $obj->last_main_doc;
2256 $this->situation_cycle_ref = $obj->situation_cycle_ref;
2257 $this->situation_counter = $obj->situation_counter;
2258 $this->situation_final = $obj->situation_final;
2259 $this->retained_warranty = $obj->retained_warranty;
2260 $this->retained_warranty_date_limit = $this->db->jdate($obj->retained_warranty_date_limit);
2261 $this->retained_warranty_fk_cond_reglement = $obj->retained_warranty_fk_cond_reglement;
2263 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
2266 $this->fk_incoterms = $obj->fk_incoterms;
2267 $this->location_incoterms = $obj->location_incoterms;
2268 $this->label_incoterms = $obj->label_incoterms;
2270 $this->module_source = $obj->module_source;
2271 $this->pos_source = $obj->pos_source;
2274 $this->fk_multicurrency = $obj->fk_multicurrency;
2275 $this->multicurrency_code = $obj->multicurrency_code;
2276 $this->multicurrency_tx = $obj->multicurrency_tx;
2277 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
2278 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
2279 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
2281 if (($this->
type == self::TYPE_SITUATION || ($this->
type == self::TYPE_CREDIT_NOTE && $this->situation_cycle_ref > 0)) && $fetch_situation) {
2285 if ($this->status == self::STATUS_DRAFT) {
2286 $this->brouillon = 1;
2294 $this->lines = array();
2298 $this->error = $this->db->error();
2302 $this->db->free($resql);
2306 $this->error =
'Invoice with id='.$rowid.
' or ref='.$ref.
' or ref_ext='.$ref_ext.
' not found';
2308 dol_syslog(__METHOD__.$this->error, LOG_WARNING);
2312 $this->error = $this->db->lasterror();
2327 public function fetch_lines($only_product = 0, $loadalsotranslation = 0)
2330 global $langs, $conf;
2332 $this->lines = array();
2334 $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,';
2335 $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,';
2336 $sql .=
' l.situation_percent, l.fk_prev_id,';
2337 $sql .=
' l.rang, l.special_code,';
2338 $sql .=
' l.date_start as date_start, l.date_end as date_end,';
2339 $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,';
2340 $sql .=
' l.fk_unit,';
2341 $sql .=
' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2342 $sql .=
' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2343 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facturedet as l';
2344 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON l.fk_product = p.rowid';
2345 $sql .=
' WHERE l.fk_facture = '.((int) $this->
id);
2346 $sql .=
' ORDER BY l.rang, l.rowid';
2348 dol_syslog(get_class($this).
'::fetch_lines', LOG_DEBUG);
2349 $result = $this->db->query($sql);
2351 $num = $this->db->num_rows($result);
2354 $objp = $this->db->fetch_object($result);
2357 $line->id = $objp->rowid;
2358 $line->rowid = $objp->rowid;
2359 $line->fk_facture = $objp->fk_facture;
2360 $line->label = $objp->custom_label;
2361 $line->desc = $objp->description;
2362 $line->description = $objp->description;
2363 $line->product_type = $objp->product_type;
2364 $line->ref = $objp->product_ref;
2365 $line->product_ref = $objp->product_ref;
2366 $line->libelle = $objp->product_label;
2367 $line->product_label = $objp->product_label;
2368 $line->product_desc = $objp->product_desc;
2369 $line->fk_product_type = $objp->fk_product_type;
2370 $line->qty = $objp->qty;
2371 $line->subprice = $objp->subprice;
2372 $line->ref_ext = $objp->ref_ext;
2374 $line->vat_src_code = $objp->vat_src_code;
2375 $line->tva_tx = $objp->tva_tx;
2376 $line->localtax1_tx = $objp->localtax1_tx;
2377 $line->localtax2_tx = $objp->localtax2_tx;
2378 $line->localtax1_type = $objp->localtax1_type;
2379 $line->localtax2_type = $objp->localtax2_type;
2380 $line->remise_percent = $objp->remise_percent;
2381 $line->fk_remise_except = $objp->fk_remise_except;
2382 $line->fk_product = $objp->fk_product;
2383 $line->date_start = $this->db->jdate($objp->date_start);
2384 $line->date_end = $this->db->jdate($objp->date_end);
2385 $line->info_bits = $objp->info_bits;
2386 $line->total_ht = $objp->total_ht;
2387 $line->total_tva = $objp->total_tva;
2388 $line->total_localtax1 = $objp->total_localtax1;
2389 $line->total_localtax2 = $objp->total_localtax2;
2390 $line->total_ttc = $objp->total_ttc;
2391 $line->code_ventilation = $objp->fk_code_ventilation;
2392 $line->fk_fournprice = $objp->fk_fournprice;
2393 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
2394 $line->pa_ht = $marginInfos[0];
2395 $line->marge_tx = $marginInfos[1];
2396 $line->marque_tx = $marginInfos[2];
2397 $line->rang = $objp->rang;
2398 $line->special_code = $objp->special_code;
2399 $line->fk_parent_line = $objp->fk_parent_line;
2400 $line->situation_percent = $objp->situation_percent;
2401 $line->fk_prev_id = $objp->fk_prev_id;
2402 $line->fk_unit = $objp->fk_unit;
2405 $line->fk_accounting_account = $objp->fk_code_ventilation;
2408 $line->fk_multicurrency = $objp->fk_multicurrency;
2409 $line->multicurrency_code = $objp->multicurrency_code;
2410 $line->multicurrency_subprice = $objp->multicurrency_subprice;
2411 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
2412 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
2413 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2415 $line->fetch_optionals();
2418 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
2419 $tmpproduct =
new Product($this->db);
2420 $tmpproduct->fetch($objp->fk_product);
2421 $tmpproduct->getMultiLangs();
2423 $line->multilangs = $tmpproduct->multilangs;
2426 $this->lines[$i] = $line;
2430 $this->db->free($result);
2433 $this->error = $this->db->error();
2448 $this->tab_previous_situation_invoice = array();
2449 $this->tab_next_situation_invoice = array();
2451 $sql =
'SELECT rowid, type, situation_cycle_ref, situation_counter FROM '.MAIN_DB_PREFIX.
'facture';
2452 $sql .=
" WHERE rowid <> ".((int) $this->
id);
2453 $sql .=
' AND entity = '.((int) $this->entity);
2454 $sql .=
' AND situation_cycle_ref = '.(int) $this->situation_cycle_ref;
2455 $sql .=
' ORDER BY situation_counter ASC';
2457 dol_syslog(get_class($this).
'::fetchPreviousNextSituationInvoice ', LOG_DEBUG);
2458 $result = $this->db->query($sql);
2459 if ($result && $this->db->num_rows($result) > 0) {
2460 while ($objp = $this->db->fetch_object($result)) {
2461 $invoice =
new Facture($this->db);
2462 if ($invoice->fetch($objp->rowid) > 0) {
2463 if ($objp->situation_counter < $this->situation_counter
2464 || ($objp->situation_counter == $this->situation_counter && $objp->rowid < $this->id)
2466 $this->tab_previous_situation_invoice[] = $invoice;
2468 $this->tab_next_situation_invoice[] = $invoice;
2487 if (empty($this->
type)) {
2490 if (isset($this->
ref)) {
2491 $this->
ref = trim($this->
ref);
2493 if (isset($this->ref_ext)) {
2494 $this->ref_ext = trim($this->ref_ext);
2496 if (isset($this->ref_client)) {
2497 $this->ref_client = trim($this->ref_client);
2499 if (isset($this->increment)) {
2500 $this->increment = trim($this->increment);
2502 if (isset($this->close_code)) {
2503 $this->close_code = trim($this->close_code);
2505 if (isset($this->close_note)) {
2506 $this->close_note = trim($this->close_note);
2508 if (isset($this->note) || isset($this->note_private)) {
2509 $this->note = (isset($this->note) ? trim($this->note) : trim($this->note_private));
2511 if (isset($this->note) || isset($this->note_private)) {
2512 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
2514 if (isset($this->note_public)) {
2515 $this->note_public = trim($this->note_public);
2517 if (isset($this->model_pdf)) {
2518 $this->model_pdf = trim($this->model_pdf);
2520 if (isset($this->import_key)) {
2521 $this->import_key = trim($this->import_key);
2523 if (isset($this->retained_warranty)) {
2524 $this->retained_warranty = floatval($this->retained_warranty);
2526 if (!isset($this->fk_user_author) && isset($this->user_author) ) {
2527 $this->fk_user_author = $this->user_author;
2535 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facture SET";
2536 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
2537 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
2538 $sql .=
" type=".(isset($this->
type) ? $this->db->escape($this->
type) :
"null").
",";
2539 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
2540 $sql .=
" increment=".(isset($this->increment) ?
"'".$this->db->escape($this->increment).
"'" :
"null").
",";
2541 $sql .=
" fk_soc=".(isset($this->socid) ? $this->db->escape($this->socid) :
"null").
",";
2542 $sql .=
" datec=".(strval($this->date_creation) !=
'' ?
"'".$this->db->idate($this->date_creation).
"'" :
'null').
",";
2543 $sql .=
" datef=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
2544 $sql .=
" date_pointoftax=".(strval($this->date_pointoftax) !=
'' ?
"'".$this->db->idate($this->date_pointoftax).
"'" :
'null').
",";
2545 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
2546 $sql .=
" paye=".(isset($this->paye) ? $this->db->escape($this->paye) : 0).
",";
2547 $sql .=
" remise_percent=".(isset($this->remise_percent) ? $this->db->escape($this->remise_percent) :
"null").
",";
2548 $sql .=
" remise_absolue=".(isset($this->remise_absolue) ? $this->db->escape($this->remise_absolue) :
"null").
",";
2549 $sql .=
" close_code=".(isset($this->close_code) ?
"'".$this->db->escape($this->close_code).
"'" :
"null").
",";
2550 $sql .=
" close_note=".(isset($this->close_note) ?
"'".$this->db->escape($this->close_note).
"'" :
"null").
",";
2551 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
2552 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
2553 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
2554 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
2555 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
2556 $sql .=
" revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp !=
'') ? $this->db->escape($this->revenuestamp) :
"null").
",";
2557 $sql .=
" fk_statut=".(isset($this->
statut) ? $this->db->escape($this->
statut) :
"null").
",";
2558 $sql .=
" fk_user_author=".(isset($this->fk_user_author) ? $this->db->escape($this->fk_user_author) :
"null").
",";
2559 $sql .=
" fk_user_valid=".(isset($this->fk_user_valid) ? $this->db->escape($this->fk_user_valid) :
"null").
",";
2560 $sql .=
" fk_facture_source=".(isset($this->fk_facture_source) ? $this->db->escape($this->fk_facture_source) :
"null").
",";
2561 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->db->escape($this->fk_project) :
"null").
",";
2562 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->db->escape($this->cond_reglement_id) :
"null").
",";
2563 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->db->escape($this->mode_reglement_id) :
"null").
",";
2564 $sql .=
" date_lim_reglement=".(strval($this->date_lim_reglement) !=
'' ?
"'".$this->db->idate($this->date_lim_reglement).
"'" :
'null').
",";
2565 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
2566 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
2567 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
2568 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null").
",";
2569 $sql .=
" situation_cycle_ref=".(empty($this->situation_cycle_ref) ?
"null" : $this->db->escape($this->situation_cycle_ref)).
",";
2570 $sql .=
" situation_counter=".(empty($this->situation_counter) ?
"null" : $this->db->escape($this->situation_counter)).
",";
2571 $sql .=
" situation_final=".(empty($this->situation_final) ?
"0" : $this->db->escape($this->situation_final)).
",";
2572 $sql .=
" retained_warranty=".(empty($this->retained_warranty) ?
"0" : $this->db->escape($this->retained_warranty)).
",";
2573 $sql .=
" retained_warranty_date_limit=".(strval($this->retained_warranty_date_limit) !=
'' ?
"'".$this->db->idate($this->retained_warranty_date_limit).
"'" :
'null').
",";
2574 $sql .=
" retained_warranty_fk_cond_reglement=".(isset($this->retained_warranty_fk_cond_reglement) ?intval($this->retained_warranty_fk_cond_reglement) :
"null");
2575 $sql .=
" WHERE rowid=".((int) $this->
id);
2579 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
2580 $resql = $this->db->query($sql);
2583 $this->errors[] =
"Error ".$this->db->lasterror();
2593 if (!$error && !$notrigger) {
2604 foreach ($this->errors as $errmsg) {
2605 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2606 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2608 $this->db->rollback();
2611 $this->db->commit();
2627 global $conf, $langs;
2629 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
2630 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
2635 $result = $remise->fetch($idremise);
2638 if ($remise->fk_facture) {
2639 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
2640 $this->db->rollback();
2645 $facligne->fk_facture = $this->id;
2646 $facligne->fk_remise_except = $remise->id;
2647 $facligne->desc = $remise->description;
2648 $facligne->vat_src_code = $remise->vat_src_code;
2649 $facligne->tva_tx = $remise->tva_tx;
2650 $facligne->subprice = -$remise->amount_ht;
2651 $facligne->fk_product = 0;
2653 $facligne->remise_percent = 0;
2654 $facligne->rang = -1;
2655 $facligne->info_bits = 2;
2657 if (!empty($conf->global->MAIN_ADD_LINE_AT_POSITION)) {
2658 $facligne->rang = 1;
2659 $linecount = count($this->lines);
2660 for ($ii = 1; $ii <= $linecount; $ii++) {
2666 if ($remise->fk_facture_source > 0) {
2667 $srcinvoice =
new Facture($this->db);
2668 $srcinvoice->fetch($remise->fk_facture_source);
2669 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmargin.class.php';
2671 $arraytmp = $formmargin->getMarginInfosArray($srcinvoice,
false);
2672 $facligne->pa_ht = $arraytmp[
'pa_total'];
2675 $facligne->total_ht = -$remise->amount_ht;
2676 $facligne->total_tva = -$remise->amount_tva;
2677 $facligne->total_ttc = -$remise->amount_ttc;
2679 $facligne->multicurrency_subprice = -$remise->multicurrency_subprice;
2680 $facligne->multicurrency_total_ht = -$remise->multicurrency_amount_ht;
2681 $facligne->multicurrency_total_tva = -$remise->multicurrency_amount_tva;
2682 $facligne->multicurrency_total_ttc = -$remise->multicurrency_amount_ttc;
2684 $lineid = $facligne->insert();
2689 $result = $remise->link_to_invoice($lineid, 0);
2691 $this->error = $remise->error;
2692 $this->db->rollback();
2696 $this->db->commit();
2699 $this->error = $facligne->error;
2700 $this->db->rollback();
2704 $this->error = $facligne->error;
2705 $this->db->rollback();
2709 $this->db->rollback();
2731 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
2732 if (empty($ref_client)) {
2733 $sql .=
' SET ref_client = NULL';
2735 $sql .=
' SET ref_client = \''.$this->db->escape($ref_client).
'\'';
2737 $sql .=
" WHERE rowid = ".((int) $this->
id);
2739 dol_syslog(__METHOD__.
' this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2740 $resql = $this->db->query($sql);
2742 $this->errors[] = $this->db->error();
2747 $this->ref_client = $ref_client;
2750 if (!$notrigger && empty($error)) {
2760 $this->ref_client = $ref_client;
2762 $this->db->commit();
2765 foreach ($this->errors as $errmsg) {
2766 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2767 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2769 $this->db->rollback();
2782 public function delete($user, $notrigger = 0, $idwarehouse = -1)
2784 global $langs, $conf;
2785 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2789 dol_syslog(get_class($this).
"::delete rowid=".$rowid.
", ref=".$this->ref.
", thirdparty=".(empty($this->thirdparty) ?
'' : $this->thirdparty->name), LOG_DEBUG);
2802 if (!$error && !$notrigger) {
2816 dol_syslog(get_class($this).
"::delete error deleteExtraFields ".$this->error, LOG_ERR);
2830 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'societe_remise_except';
2831 $sql .=
' WHERE fk_facture_source = '.((int) $rowid);
2832 $sql .=
' AND fk_facture_line IS NULL';
2833 $resql = $this->db->query($sql);
2837 $list_rowid_det = array();
2838 foreach ($this->lines as $key => $invoiceline) {
2839 $list_rowid_det[] = $invoiceline->id;
2843 if (count($list_rowid_det)) {
2844 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
2845 $sql .=
' SET fk_facture = NULL, fk_facture_line = NULL';
2846 $sql .=
' WHERE fk_facture_line IN ('.$this->db->sanitize(join(
',', $list_rowid_det)).
')';
2848 if (!$this->db->query($sql)) {
2849 $this->error = $this->db->error().
" sql=".$sql;
2850 $this->errors[] = $this->error;
2851 $this->db->rollback();
2858 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'eventorganization_conferenceorboothattendee';
2859 $sql .=
' SET fk_invoice = NULL';
2860 $sql .=
' WHERE fk_invoice = '.((int) $rowid);
2862 if (!$this->db->query($sql)) {
2863 $this->error = $this->db->error().
" sql=".$sql;
2864 $this->errors[] = $this->error;
2865 $this->db->rollback();
2869 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'element_time';
2870 $sql .=
' SET invoice_id = NULL, invoice_line_id = NULL';
2871 $sql .=
' WHERE invoice_id = '.((int) $rowid);
2873 if (!$this->db->query($sql)) {
2874 $this->error = $this->db->error().
" sql=".$sql;
2875 $this->errors[] = $this->error;
2876 $this->db->rollback();
2881 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse != -1) {
2882 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
2883 $langs->load(
"agenda");
2885 $num = count($this->lines);
2886 for ($i = 0; $i < $num; $i++) {
2887 if ($this->lines[$i]->fk_product > 0) {
2889 $mouvP->origin = &$this;
2890 $mouvP->setOrigin($this->element, $this->
id);
2892 if ($this->
type == self::TYPE_CREDIT_NOTE) {
2893 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceDeleteDolibarr", $this->ref));
2895 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceDeleteDolibarr", $this->ref));
2902 $main = MAIN_DB_PREFIX.
'facturedet';
2903 $ef = $main.
"_extrafields";
2904 $sqlef =
"DELETE FROM ".$ef.
" WHERE fk_object IN (SELECT rowid FROM ".$main.
" WHERE fk_facture = ".((int) $rowid).
")";
2906 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'facturedet WHERE fk_facture = '.((int) $rowid);
2909 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'facture WHERE rowid = '.((int) $rowid);
2911 $resql = $this->db->query($sql);
2918 if ($conf->facture->dir_output && !empty($this->
ref)) {
2919 $dir = $conf->facture->dir_output.
"/".$ref;
2920 $file = $conf->facture->dir_output.
"/".$ref.
"/".$ref.
".pdf";
2921 if (file_exists($file)) {
2925 $langs->load(
"errors");
2926 $this->error = $langs->trans(
"ErrorFailToDeleteFile", $file);
2927 $this->errors[] = $this->error;
2928 $this->db->rollback();
2932 if (file_exists($dir)) {
2934 $langs->load(
"errors");
2935 $this->error = $langs->trans(
"ErrorFailToDeleteDir", $dir);
2936 $this->errors[] = $this->error;
2937 $this->db->rollback();
2943 $this->db->commit();
2946 $this->error = $this->db->lasterror().
" sql=".$sql;
2947 $this->errors[] = $this->error;
2948 $this->db->rollback();
2952 $this->error = $this->db->lasterror().
" sql=".$sql;
2953 $this->errors[] = $this->error;
2954 $this->db->rollback();
2958 $this->db->rollback();
2975 public function set_paid($user, $close_code =
'', $close_note =
'')
2978 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
2979 return $this->
setPaid($user, $close_code, $close_note);
2991 public function setPaid($user, $close_code =
'', $close_note =
'')
2995 if ($this->paye != 1) {
3000 dol_syslog(get_class($this).
"::setPaid rowid=".((
int) $this->
id), LOG_DEBUG);
3002 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET';
3003 $sql .=
' fk_statut='.self::STATUS_CLOSED;
3008 $sql .=
", close_code='".$this->db->escape($close_code).
"'";
3011 $sql .=
", close_note='".$this->db->escape($close_note).
"'";
3013 $sql .=
', fk_user_closing = '.((int) $user->id);
3014 $sql .=
", date_closing = '".$this->db->idate($now).
"'";
3015 $sql .=
" WHERE rowid = ".((int) $this->
id);
3017 $resql = $this->db->query($sql);
3027 $this->error = $this->db->lasterror();
3031 $this->db->commit();
3034 $this->db->rollback();
3057 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
3075 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
3076 $sql .=
' SET paye=0, fk_statut='.self::STATUS_VALIDATED.
', close_code=null, close_note=null,';
3077 $sql .=
' date_closing=null,';
3078 $sql .=
' fk_user_closing=null';
3079 $sql .=
" WHERE rowid = ".((int) $this->
id);
3081 dol_syslog(get_class($this).
"::setUnpaid", LOG_DEBUG);
3082 $resql = $this->db->query($sql);
3092 $this->error = $this->db->error();
3097 $this->db->commit();
3100 $this->db->rollback();
3122 dol_syslog(get_class($this).
"::set_canceled is deprecated, use setCanceled instead", LOG_NOTICE);
3123 return $this->
setCanceled($user, $close_code, $close_note);
3136 public function setCanceled($user, $close_code =
'', $close_note =
'')
3138 dol_syslog(get_class($this).
"::setCanceled rowid=".((
int) $this->
id), LOG_DEBUG);
3142 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET';
3143 $sql .=
' fk_statut='.self::STATUS_ABANDONED;
3145 $sql .=
", close_code='".$this->db->escape($close_code).
"'";
3148 $sql .=
", close_note='".$this->db->escape($close_note).
"'";
3150 $sql .=
" WHERE rowid = ".((int) $this->
id);
3152 $resql = $this->db->query($sql);
3156 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
3157 $sql .=
' SET fk_facture = NULL';
3158 $sql .=
' WHERE fk_facture = '.((int) $this->
id);
3160 $resql = $this->db->query($sql);
3165 $this->db->rollback();
3170 $this->db->commit();
3173 $this->error = $this->db->error().
" sql=".$sql;
3174 $this->db->rollback();
3178 $this->error = $this->db->error().
" sql=".$sql;
3179 $this->db->rollback();
3195 public function validate($user, $force_number =
'', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0)
3197 global $conf, $langs, $mysoc;
3198 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3200 $productStatic =
null;
3201 $warehouseStatic =
null;
3202 if ($batch_rule > 0) {
3203 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
3204 require_once DOL_DOCUMENT_ROOT.
'/product/class/productbatch.class.php';
3205 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
3206 $productStatic =
new Product($this->db);
3207 $warehouseStatic =
new Entrepot($this->db);
3214 dol_syslog(get_class($this).
'::validate user='.$user->id.
', force_number='.$force_number.
', idwarehouse='.$idwarehouse);
3221 if ($this->
statut != self::STATUS_DRAFT) {
3222 dol_syslog(get_class($this).
"::validate status is not draft. operation canceled.", LOG_WARNING);
3225 if (count($this->lines) <= 0) {
3226 $langs->load(
"errors");
3227 $this->error = $langs->trans(
"ErrorObjectMustHaveLinesToBeValidated", $this->
ref);
3230 if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->creer))
3231 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->invoice_advance->validate))) {
3232 $this->error =
'Permission denied';
3233 dol_syslog(get_class($this).
"::validate ".$this->error.
' MAIN_USE_ADVANCED_PERMS='.$conf->global->MAIN_USE_ADVANCED_PERMS, LOG_ERR);
3236 if ((preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) &&
3237 !empty($conf->global->FAC_FORCE_DATE_VALIDATION)
3242 if (!empty($conf->global-> INVOICE_CHECK_POSTERIOR_DATE)) {
3244 if (!$last_of_type[0]) {
3245 $this->error = $langs->transnoentities(
"ErrorInvoiceIsNotLastOfSameType", $this->
ref,
dol_print_date($this->date,
'day'),
dol_print_date($last_of_type[1],
'day'));
3251 if (!empty($this->thirdparty) && is_object($this->thirdparty)) {
3252 $array_to_check = array(
'IDPROF1',
'IDPROF2',
'IDPROF3',
'IDPROF4',
'IDPROF5',
'IDPROF6',
'EMAIL',
'ACCOUNTANCY_CODE_CUSTOMER');
3253 foreach ($array_to_check as $key) {
3254 $keymin = strtolower($key);
3255 if (!property_exists($this->thirdparty, $keymin)) {
3258 $vallabel = $this->thirdparty->$keymin;
3260 $i = (int) preg_replace(
'/[^0-9]/',
'', $key);
3262 if ($this->thirdparty->isACompany()) {
3264 if ($mysoc->country_id > 0 && $this->thirdparty->country_id == $mysoc->country_id) {
3265 $idprof_mandatory =
'SOCIETE_'.$key.
'_INVOICE_MANDATORY';
3266 if (!$vallabel && !empty($conf->global->$idprof_mandatory)) {
3267 $langs->load(
"errors");
3268 $this->error = $langs->trans(
'ErrorProdIdIsMandatory', $langs->transcountry(
'ProfId'.$i, $this->thirdparty->country_code)).
' ('.$langs->trans(
"ForbiddenBySetupRules").
') ['.$langs->trans(
'Company').
' : '.$this->thirdparty->name.
']';
3269 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3275 if ($key ==
'EMAIL') {
3277 if (!empty($conf->global->SOCIETE_EMAIL_INVOICE_MANDATORY) && !isValidEMail($this->thirdparty->email)) {
3278 $langs->load(
"errors");
3279 $this->error = $langs->trans(
"ErrorBadEMail", $this->thirdparty->email).
' ('.$langs->trans(
"ForbiddenBySetupRules").
') ['.$langs->trans(
'Company').
' : '.$this->thirdparty->name.
']';
3280 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3284 if ($key ==
'ACCOUNTANCY_CODE_CUSTOMER') {
3286 if (!empty($conf->global->SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_INVOICE_MANDATORY) && empty($this->thirdparty->code_compta)) {
3287 $langs->load(
"errors");
3288 $this->error = $langs->trans(
"ErrorAccountancyCodeCustomerIsMandatory", $this->thirdparty->name).
' ('.$langs->trans(
"ForbiddenBySetupRules").
')';
3289 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3298 $array_to_check = array(
'REF_CLIENT'=>
'RefCustomer');
3299 foreach ($array_to_check as $key => $val) {
3300 $keymin = strtolower($key);
3301 $vallabel = $this->$keymin;
3304 $keymandatory =
'INVOICE_'.$key.
'_MANDATORY_FOR_VALIDATION';
3305 if (!$vallabel && !empty($conf->global->$keymandatory)) {
3306 $langs->load(
"errors");
3308 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv($val)),
null,
'errors');
3315 if ($this->
type == self::TYPE_REPLACEMENT) {
3317 if ($this->fk_facture_source <= 0) {
3318 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"InvoiceReplacement"));
3319 $this->db->rollback();
3324 $facreplaced =
new Facture($this->db);
3325 $result = $facreplaced->fetch($this->fk_facture_source);
3327 $this->error = $langs->trans(
"ErrorBadInvoice");
3328 $this->db->rollback();
3333 $idreplacement = $facreplaced->getIdReplacingInvoice(
'validated');
3334 if ($idreplacement && $idreplacement != $this->
id) {
3335 $facreplacement =
new Facture($this->db);
3336 $facreplacement->fetch($idreplacement);
3337 $this->error = $langs->trans(
"ErrorInvoiceAlreadyReplaced", $facreplaced->ref, $facreplacement->ref);
3338 $this->db->rollback();
3342 $result = $facreplaced->setCanceled($user, self::CLOSECODE_REPLACED,
'');
3344 $this->error = $facreplaced->error;
3345 $this->db->rollback();
3351 if ($force_number) {
3352 $num = $force_number;
3353 } elseif (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
3365 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
3366 $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).
"'";
3367 if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
3368 $sql .=
", datef='".$this->db->idate($this->date).
"'";
3369 $sql .=
", date_lim_reglement='".$this->db->idate($this->date_lim_reglement).
"'";
3371 $sql .=
" WHERE rowid = ".((int) $this->
id);
3373 dol_syslog(get_class($this).
"::validate", LOG_DEBUG);
3374 $resql = $this->db->query($sql);
3381 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref))) {
3387 $result = $this->thirdparty->set_as_client();
3390 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse > 0) {
3391 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
3392 $langs->load(
"agenda");
3395 $cpt = count($this->lines);
3396 for ($i = 0; $i < $cpt; $i++) {
3397 if ($this->lines[$i]->fk_product > 0) {
3399 $mouvP->origin = &$this;
3400 $mouvP->setOrigin($this->element, $this->
id);
3402 if ($this->
type == self::TYPE_CREDIT_NOTE) {
3403 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceValidatedInDolibarr", $num));
3406 $this->error = $mouvP->error;
3409 $is_batch_line =
false;
3410 if ($batch_rule > 0) {
3411 $productStatic->fetch($this->lines[$i]->fk_product);
3412 if ($productStatic->hasbatch()) {
3413 $is_batch_line =
true;
3414 $product_qty_remain = $this->lines[$i]->qty;
3420 $sortfield =
'pl.sellby,pl.eatby,pb.qty,pl.rowid';
3421 $sortorder =
'ASC,ASC,ASC,ASC';
3424 $resBatchList = $productbatch->findAllForProduct($productStatic->id, $idwarehouse, (
getDolGlobalInt(
'STOCK_ALLOW_NEGATIVE_TRANSFER') ?
null : 0), $sortfield, $sortorder);
3425 if (!is_array($resBatchList)) {
3427 $this->error = $this->db->lasterror();
3431 $batchList = $resBatchList;
3432 if (empty($batchList)) {
3434 $langs->load(
'errors');
3435 $warehouseStatic->fetch($idwarehouse);
3436 $this->error = $langs->trans(
'ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
3437 dol_syslog(__METHOD__.
' Error: '.$langs->transnoentitiesnoconv(
'ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
3440 foreach ($batchList as $batch) {
3441 if ($batch->qty <= 0) {
3446 if ($batch->qty >= $product_qty_remain) {
3447 $product_batch_qty = $product_qty_remain;
3450 $product_batch_qty = $batch->qty;
3452 $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_batch_qty, $this->lines[$i]->subprice, $langs->trans(
'InvoiceValidatedInDolibarr', $num),
'',
'',
'', $batch->batch);
3455 $this->error = $mouvP->error;
3456 $this->errors = $mouvP->errors;
3460 $product_qty_remain -= $product_batch_qty;
3462 if ($product_qty_remain <= 0) {
3467 if (!$error && $product_qty_remain > 0) {
3470 $batch = $batchList[0];
3471 $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans(
'InvoiceValidatedInDolibarr', $num),
'',
'',
'', $batch->batch);
3474 $this->error = $mouvP->error;
3475 $this->errors = $mouvP->errors;
3479 $langs->load(
'errors');
3480 $warehouseStatic->fetch($idwarehouse);
3481 $this->error = $langs->trans(
'ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
3482 dol_syslog(__METHOD__.
' Error: '.$langs->transnoentitiesnoconv(
'ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
3489 if (!$is_batch_line) {
3490 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceValidatedInDolibarr", $num));
3493 $this->error = $mouvP->error;
3494 $this->errors = $mouvP->errors;
3507 if (!$error && $this->
type == self::TYPE_CREDIT_NOTE && $this->fk_facture_source > 0) {
3508 $invoice_situation =
new Facture($this->db);
3509 $result = $invoice_situation->fetch($this->fk_facture_source);
3510 if ($result > 0 && $invoice_situation->type == self::TYPE_SITUATION && $invoice_situation->situation_final == 1) {
3511 $invoice_situation->situation_final = 0;
3513 $result = $invoice_situation->setFinal($user, 1);
3516 $this->error = $invoice_situation->error;
3517 $this->errors = $invoice_situation->errors;
3523 if (!$error && !$notrigger) {
3533 $this->oldref = $this->ref;
3536 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
3538 $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).
"'";
3539 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'facture/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
3540 $resql = $this->db->query($sql);
3543 $this->error = $this->db->lasterror();
3545 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'facture/".$this->db->escape($this->newref).
"'";
3546 $sql .=
" WHERE filepath = 'facture/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
3547 $resql = $this->db->query($sql);
3549 $error++; $this->error = $this->db->lasterror();
3555 $dirsource = $conf->facture->dir_output.
'/'.$oldref;
3556 $dirdest = $conf->facture->dir_output.
'/'.$newref;
3557 if (!$error && file_exists($dirsource)) {
3558 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
3560 if (@rename($dirsource, $dirdest)) {
3563 $listoffiles =
dol_dir_list($conf->facture->dir_output.
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
3564 foreach ($listoffiles as $fileentry) {
3565 $dirsource = $fileentry[
'name'];
3566 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
3567 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
3568 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
3569 @rename($dirsource, $dirdest);
3587 $this->brouillon = 0;
3588 $this->date_validation = $now;
3591 if (!empty($conf->global->INVOICE_USE_SITUATION)) {
3593 $nboflines = count($this->lines);
3594 while (($i < $nboflines) && $final) {
3595 $final = ($this->lines[$i]->situation_percent == 100);
3599 if (empty($final)) {
3600 $this->situation_final = 0;
3602 $this->situation_final = 1;
3613 $this->db->commit();
3616 $this->db->rollback();
3629 foreach ($this->tab_next_situation_invoice as $next_invoice) {
3630 $is_last = $next_invoice->is_last_in_cycle();
3632 if ($next_invoice->statut == self::STATUS_DRAFT && $is_last != 1) {
3633 $this->error = $langs->trans(
'updatePriceNextInvoiceErrorUpdateline', $next_invoice->ref);
3637 $next_invoice->brouillon = 1;
3639 foreach ($next_invoice->lines as $line) {
3640 $result = $next_invoice->updateline(
3645 $line->remise_percent,
3649 $line->localtax1_tx,
3650 $line->localtax2_tx,
3653 $line->product_type,
3654 $line->fk_parent_line,
3656 $line->fk_fournprice,
3659 $line->special_code,
3660 $line->array_options,
3661 $line->situation_percent,
3666 $this->error = $langs->trans(
'updatePriceNextInvoiceErrorUpdateline', $next_invoice->ref);
3687 global $conf, $langs;
3691 if ($this->
statut == self::STATUS_DRAFT) {
3692 dol_syslog(__METHOD__.
" already draft status", LOG_WARNING);
3700 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facture";
3701 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
3702 $sql .=
" WHERE rowid = ".((int) $this->
id);
3704 $result = $this->db->query($sql);
3707 $this->oldcopy = clone $this;
3711 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
3712 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
3713 $langs->load(
"agenda");
3715 $num = count($this->lines);
3716 for ($i = 0; $i < $num; $i++) {
3717 if ($this->lines[$i]->fk_product > 0) {
3719 $mouvP->origin = &$this;
3720 $mouvP->setOrigin($this->element, $this->
id);
3722 if ($this->
type == self::TYPE_CREDIT_NOTE) {
3723 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceBackToDraftInDolibarr", $this->ref));
3725 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceBackToDraftInDolibarr", $this->ref));
3732 $old_statut = $this->statut;
3733 $this->brouillon = 1;
3738 $result = $this->
call_trigger(
'BILL_UNVALIDATE', $user);
3741 $this->
statut = $old_statut;
3742 $this->status = $old_statut;
3743 $this->brouillon = 0;
3747 $this->db->rollback();
3752 $this->db->commit();
3755 $this->db->rollback();
3759 $this->error = $this->db->error();
3760 $this->db->rollback();
3820 $fk_remise_except =
'',
3821 $price_base_type =
'HT',
3828 $fk_parent_line = 0,
3829 $fk_fournprice =
null,
3833 $situation_percent = 100,
3838 $noupdateafterinsertline = 0
3842 dol_syslog(__METHOD__.
": using line label is deprecated", LOG_WARNING);
3846 global $mysoc, $conf, $langs;
3848 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);
3850 if ($this->
statut == self::STATUS_DRAFT) {
3851 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
3860 if (empty($info_bits)) {
3866 if (empty($ventil)) {
3869 if (empty($txtva)) {
3872 if (empty($txlocaltax1)) {
3875 if (empty($txlocaltax2)) {
3878 if (empty($fk_parent_line) || $fk_parent_line < 0) {
3879 $fk_parent_line = 0;
3881 if (empty($fk_prev_id)) {
3882 $fk_prev_id =
'null';
3884 if (!isset($situation_percent) || $situation_percent > 100 || (
string) $situation_percent ==
'') {
3885 $situation_percent = 100;
3887 if (empty($ref_ext)) {
3894 $pu_ht_devise =
price2num($pu_ht_devise);
3897 if (!preg_match(
'/\((.*)\)/', $txtva)) {
3903 if ($price_base_type ==
'HT') {
3914 if ($date_start && $date_end && $date_start > $date_end) {
3915 $langs->load(
"errors");
3916 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
3922 $product_type = $type;
3923 if (!empty($fk_product) && $fk_product > 0) {
3924 $product =
new Product($this->db);
3925 $result = $product->fetch($fk_product);
3926 $product_type = $product->type;
3928 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) {
3929 $langs->load(
"errors");
3930 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref);
3931 $this->db->rollback();
3941 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
3942 $vat_src_code = $reg[1];
3943 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
3951 $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);
3953 $total_ht = $tabprice[0];
3954 $total_tva = $tabprice[1];
3955 $total_ttc = $tabprice[2];
3956 $total_localtax1 = $tabprice[9];
3957 $total_localtax2 = $tabprice[10];
3958 $pu_ht = $tabprice[3];
3961 $multicurrency_total_ht = $tabprice[16];
3962 $multicurrency_total_tva = $tabprice[17];
3963 $multicurrency_total_ttc = $tabprice[18];
3964 $pu_ht_devise = $tabprice[19];
3968 if ($ranktouse == -1) {
3969 $rangmax = $this->
line_max($fk_parent_line);
3970 $ranktouse = $rangmax + 1;
3976 $this->line->context = $this->context;
3978 $this->line->fk_facture = $this->id;
3979 $this->line->label = $label;
3980 $this->line->desc = $desc;
3981 $this->line->ref_ext = $ref_ext;
3983 $this->line->qty = ($this->
type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty);
3984 $this->line->subprice = ($this->
type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht);
3986 $this->line->vat_src_code = $vat_src_code;
3987 $this->line->tva_tx = $txtva;
3988 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
3989 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
3990 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
3991 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
3993 $this->line->total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht);
3994 $this->line->total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc);
3995 $this->line->total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_tva) : $total_tva);
3996 $this->line->total_localtax1 = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax1) : $total_localtax1);
3997 $this->line->total_localtax2 = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax2) : $total_localtax2);
3999 $this->line->fk_product = $fk_product;
4000 $this->line->product_type = $product_type;
4002 $this->line->date_start = $date_start;
4003 $this->line->date_end = $date_end;
4004 $this->line->ventil = $ventil;
4005 $this->line->rang = $ranktouse;
4006 $this->line->info_bits = $info_bits;
4007 $this->line->fk_remise_except = $fk_remise_except;
4009 $this->line->special_code = $special_code;
4010 $this->line->fk_parent_line = $fk_parent_line;
4011 $this->line->origin = $origin;
4012 $this->line->origin_id = $origin_id;
4013 $this->line->situation_percent = $situation_percent;
4014 $this->line->fk_prev_id = $fk_prev_id;
4015 $this->line->fk_unit = $fk_unit;
4018 $this->line->fk_fournprice = $fk_fournprice;
4019 $this->line->pa_ht = $pa_ht;
4022 $this->line->fk_multicurrency = $this->fk_multicurrency;
4023 $this->line->multicurrency_code = $this->multicurrency_code;
4024 $this->line->multicurrency_subprice = ($this->
type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht_devise) : $pu_ht_devise);
4026 $this->line->multicurrency_total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ht) : $multicurrency_total_ht);
4027 $this->line->multicurrency_total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_tva) : $multicurrency_total_tva);
4028 $this->line->multicurrency_total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ttc) : $multicurrency_total_ttc);
4030 if (is_array($array_options) && count($array_options) > 0) {
4031 $this->line->array_options = $array_options;
4034 $result = $this->line->insert();
4037 if (!empty($fk_parent_line)) {
4039 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
4040 $linecount = count($this->lines);
4041 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
4047 if (empty($noupdateafterinsertline)) {
4052 $this->db->commit();
4053 return $this->line->id;
4055 $this->error = $this->db->lasterror();
4056 $this->db->rollback();
4060 $this->error = $this->line->error;
4061 $this->errors = $this->line->errors;
4062 $this->db->rollback();
4066 $this->errors[]=
'status of invoice must be Draft to allow use of ->addline()';
4067 dol_syslog(get_class($this).
"::addline status of invoice must be Draft to allow use of ->addline()", LOG_ERR);
4103 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)
4105 global $conf, $user;
4108 dol_syslog(__METHOD__.
": using line label is deprecated", LOG_WARNING);
4111 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
4113 global $mysoc, $langs;
4115 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);
4117 if ($this->
statut == self::STATUS_DRAFT) {
4120 if (!$this->error) {
4121 $this->error = $langs->trans(
'invoiceLineProgressError');
4127 if ($date_start && $date_end && $date_start > $date_end) {
4128 $langs->load(
"errors");
4129 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
4139 if (empty($fk_parent_line) || $fk_parent_line < 0) {
4140 $fk_parent_line = 0;
4142 if (empty($special_code) || $special_code == 3) {
4145 if (!isset($situation_percent) || $situation_percent > 100 || (
string) $situation_percent ==
'') {
4146 $situation_percent = 100;
4148 if (empty($ref_ext)) {
4155 $pu_ht_devise =
price2num($pu_ht_devise);
4157 if (!preg_match(
'/\((.*)\)/', $txtva)) {
4177 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
4178 $vat_src_code = $reg[1];
4179 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
4182 $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);
4184 $total_ht = $tabprice[0];
4185 $total_tva = $tabprice[1];
4186 $total_ttc = $tabprice[2];
4187 $total_localtax1 = $tabprice[9];
4188 $total_localtax2 = $tabprice[10];
4189 $pu_ht = $tabprice[3];
4190 $pu_tva = $tabprice[4];
4191 $pu_ttc = $tabprice[5];
4194 $multicurrency_total_ht = $tabprice[16];
4195 $multicurrency_total_tva = $tabprice[17];
4196 $multicurrency_total_ttc = $tabprice[18];
4197 $pu_ht_devise = $tabprice[19];
4204 $price = ($pu - $remise);
4210 $line->fetch($rowid);
4211 $line->fetch_optionals();
4213 if (!empty($line->fk_product)) {
4214 $product =
new Product($this->db);
4215 $result = $product->fetch($line->fk_product);
4216 $product_type = $product->type;
4218 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) {
4219 $langs->load(
"errors");
4220 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref);
4221 $this->db->rollback();
4226 $staticline = clone $line;
4228 $line->oldline = $staticline;
4229 $this->line = $line;
4230 $this->line->context = $this->context;
4231 $this->line->rang = $rang;
4234 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
4235 $rangmax = $this->
line_max($fk_parent_line);
4236 $this->line->rang = $rangmax + 1;
4238 $apply_abs_price_on_credit_note=
false;
4240 $apply_abs_price_on_credit_note =
true;
4244 $this->line->id = $rowid;
4245 $this->line->rowid = $rowid;
4246 $this->line->label = $label;
4247 $this->line->desc = $desc;
4248 $this->line->ref_ext = $ref_ext;
4249 $this->line->qty = ($this->
type == self::TYPE_CREDIT_NOTE ?abs($qty) : $qty);
4251 $this->line->vat_src_code = $vat_src_code;
4252 $this->line->tva_tx = $txtva;
4253 $this->line->localtax1_tx = $txlocaltax1;
4254 $this->line->localtax2_tx = $txlocaltax2;
4255 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
4256 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
4259 $this->line->subprice = ($apply_abs_price_on_credit_note?-abs($pu_ht) : $pu_ht);
4260 $this->line->date_start = $date_start;
4261 $this->line->date_end = $date_end;
4262 $this->line->total_ht = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_ht) : $total_ht);
4263 $this->line->total_tva = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_tva) : $total_tva);
4264 $this->line->total_localtax1 = $total_localtax1;
4265 $this->line->total_localtax2 = $total_localtax2;
4266 $this->line->total_ttc = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_ttc) : $total_ttc);
4267 $this->line->info_bits = $info_bits;
4268 $this->line->special_code = $special_code;
4269 $this->line->product_type = $type;
4270 $this->line->fk_parent_line = $fk_parent_line;
4271 $this->line->skip_update_total = $skip_update_total;
4272 $this->line->situation_percent = $situation_percent;
4273 $this->line->fk_unit = $fk_unit;
4275 $this->line->fk_fournprice = $fk_fournprice;
4276 $this->line->pa_ht = $pa_ht;
4279 $this->line->multicurrency_subprice = ($this->
type == self::TYPE_CREDIT_NOTE ?-abs($pu_ht_devise) : $pu_ht_devise);
4280 $this->line->multicurrency_total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_ht) : $multicurrency_total_ht);
4281 $this->line->multicurrency_total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_tva) : $multicurrency_total_tva);
4282 $this->line->multicurrency_total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_ttc) : $multicurrency_total_ttc);
4284 if (is_array($array_options) && count($array_options) > 0) {
4286 foreach ($array_options as $key => $value) {
4287 $this->line->array_options[$key] = $array_options[$key];
4291 $result = $this->line->update($user, $notrigger);
4294 if (!empty($fk_parent_line)) {
4300 $this->db->commit();
4303 $this->error = $this->line->error;
4304 $this->db->rollback();
4308 $this->error =
"Invoice statut makes operation forbidden";
4322 $sql =
'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.
'facturedet fd
4323 INNER JOIN '.MAIN_DB_PREFIX.
'facture f ON (fd.fk_facture = f.rowid)
4324 WHERE fd.fk_prev_id = '.((int) $idline).
' AND f.fk_statut <> 0';
4326 $result = $this->db->query($sql);
4328 $this->error = $this->db->error();
4332 $obj = $this->db->fetch_object($result);
4334 if ($obj ===
null) {
4337 return ($situation_percent < $obj->situation_percent);
4353 global $mysoc, $user;
4356 if (($line->info_bits & 2) == 2) {
4360 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
4363 if ($percent > 100) {
4366 $line->situation_percent = $percent;
4367 $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);
4368 $line->total_ht = $tabprice[0];
4369 $line->total_tva = $tabprice[1];
4370 $line->total_ttc = $tabprice[2];
4371 $line->total_localtax1 = $tabprice[9];
4372 $line->total_localtax2 = $tabprice[10];
4373 $line->multicurrency_total_ht = $tabprice[16];
4374 $line->multicurrency_total_tva = $tabprice[17];
4375 $line->multicurrency_total_ttc = $tabprice[18];
4376 $line->update($user);
4379 if ($update_price) {
4395 dol_syslog(get_class($this).
"::deleteline rowid=".((
int) $rowid), LOG_DEBUG);
4397 if ($this->
statut != self::STATUS_DRAFT) {
4398 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
4404 $line->context = $this->context;
4407 $result = $line->fetch($rowid);
4408 if (!($result > 0)) {
4413 if ($id > 0 && $line->fk_facture != $id) {
4414 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
4421 $staticline = clone $line;
4422 $line->oldline = $staticline;
4424 if ($line->delete($user) > 0) {
4428 $this->db->commit();
4431 $this->db->rollback();
4432 $this->error = $this->db->lasterror();
4436 $this->db->rollback();
4437 $this->error = $line->error;
4456 dol_syslog(get_class($this).
"::set_remise is deprecated, use setDiscount instead", LOG_NOTICE);
4457 return $this->
setDiscount($user, $remise, $notrigger);
4472 if (empty($remise)) {
4476 if ($user->hasRight(
'facture',
'creer')) {
4483 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
4484 $sql .=
' SET remise_percent = '.((float) $remise);
4485 $sql .=
" WHERE rowid = ".((int) $this->
id);
4486 $sql .=
' AND fk_statut = '.self::STATUS_DRAFT;
4489 $resql = $this->db->query($sql);
4491 $this->errors[] = $this->db->error();
4495 if (!$notrigger && empty($error)) {
4505 $this->remise_percent = $remise;
4508 $this->db->commit();
4511 foreach ($this->errors as $errmsg) {
4512 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
4513 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4515 $this->db->rollback();
4536 if (empty($remise)) {
4540 if ($user->hasRight(
'facture',
'creer')) {
4547 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
4548 $sql .=
' SET remise_absolue = '.((float) $remise);
4549 $sql .=
" WHERE rowid = ".((int) $this->
id);
4550 $sql .=
' AND fk_statut = '.self::STATUS_DRAFT;
4553 $resql = $this->db->query($sql);
4555 $this->errors[] = $this->db->error();
4560 $this->oldcopy = clone $this;
4561 $this->remise_absolue = $remise;
4565 if (!$notrigger && empty($error)) {
4575 $this->db->commit();
4578 foreach ($this->errors as $errmsg) {
4579 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
4580 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4582 $this->db->rollback();
4600 global $conf, $langs;
4602 if ($this->module_source ==
'takepos') {
4603 $langs->load(
'cashdesk');
4605 $moduleName =
'takepos';
4606 $moduleSourceName =
'Takepos';
4607 $addonConstName =
'TAKEPOS_REF_ADDON';
4610 if (empty($conf->global->TAKEPOS_REF_ADDON)) {
4611 $conf->global->TAKEPOS_REF_ADDON =
'mod_takepos_ref_simple';
4614 $addon = $conf->global->TAKEPOS_REF_ADDON;
4616 $langs->load(
'bills');
4618 $moduleName =
'facture';
4619 $moduleSourceName =
'Invoice';
4620 $addonConstName =
'FACTURE_ADDON';
4623 if (empty($conf->global->FACTURE_ADDON)) {
4624 $conf->global->FACTURE_ADDON =
'mod_facture_terre';
4625 } elseif ($conf->global->FACTURE_ADDON ==
'terre') {
4626 $conf->global->FACTURE_ADDON =
'mod_facture_terre';
4627 } elseif ($conf->global->FACTURE_ADDON ==
'mercure') {
4628 $conf->global->FACTURE_ADDON =
'mod_facture_mercure';
4631 $addon = $conf->global->FACTURE_ADDON;
4634 if (!empty($addon)) {
4635 dol_syslog(
"Call getNextNumRef with ".$addonConstName.
" = ".$conf->global->FACTURE_ADDON.
", thirdparty=".$soc->name.
", type=".$soc->typent_code.
", mode=".$mode, LOG_DEBUG);
4639 $file = $addon.
'.php';
4640 $classname = $addon;
4644 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
4645 foreach ($dirmodels as $reldir) {
4646 $dir =
dol_buildpath($reldir.
'core/modules/'.$moduleName.
'/');
4649 if (is_file($dir.$file) && is_readable($dir.$file)) {
4650 $mybool |= include_once $dir.$file;
4656 $file = $addon.
'/'.$addon.
'.modules.php';
4657 $classname =
'mod_'.$moduleName.
'_'.$addon;
4658 $classname = preg_replace(
'/\-.*$/',
'', $classname);
4660 foreach ($conf->file->dol_document_root as $dirroot) {
4661 $dir = $dirroot.
'/core/modules/'.$moduleName.
'/';
4664 if (is_file($dir.$file) && is_readable($dir.$file)) {
4665 $mybool |= include_once $dir.$file;
4675 $obj =
new $classname();
4677 $numref = $obj->getNextValue($soc, $this, $mode);
4684 if ($mode !=
'last' && !$numref) {
4685 $this->error = $obj->error;
4691 $langs->load(
'errors');
4692 print $langs->trans(
'Error').
' '.$langs->trans(
'ErrorModuleSetupNotComplete', $langs->transnoentitiesnoconv($moduleSourceName));
4705 $sql =
'SELECT c.rowid, datec, date_valid as datev, tms as datem,';
4706 $sql .=
' date_closing as dateclosing,';
4707 $sql .=
' fk_user_author, fk_user_valid, fk_user_closing';
4708 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facture as c';
4709 $sql .=
' WHERE c.rowid = '.((int) $id);
4711 $result = $this->db->query($sql);
4713 if ($this->db->num_rows($result)) {
4714 $obj = $this->db->fetch_object($result);
4715 $this->
id = $obj->rowid;
4716 if ($obj->fk_user_author) {
4717 $cuser =
new User($this->db);
4718 $cuser->fetch($obj->fk_user_author);
4719 $this->user_creation = $cuser;
4721 if ($obj->fk_user_valid) {
4722 $vuser =
new User($this->db);
4723 $vuser->fetch($obj->fk_user_valid);
4724 $this->user_validation = $vuser;
4726 if ($obj->fk_user_closing) {
4727 $cluser =
new User($this->db);
4728 $cluser->fetch($obj->fk_user_closing);
4729 $this->user_closing = $cluser;
4732 $this->date_creation = $this->db->jdate($obj->datec);
4733 $this->date_modification = $this->db->jdate($obj->datem);
4734 $this->date_validation = $this->db->jdate($obj->datev);
4735 $this->date_closing = $this->db->jdate($obj->dateclosing);
4737 $this->db->free($result);
4758 public function liste_array($shortlist = 0, $draft = 0, $excluser =
'', $socid = 0, $limit = 0, $offset = 0, $sortfield =
'f.datef,f.rowid', $sortorder =
'DESC')
4761 global $conf, $user;
4765 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
4766 $sql .=
" f.rowid as fid, f.ref as ref, f.datef as df";
4767 if (empty($user->rights->societe->client->voir) && !$socid) {
4768 $sql .=
", sc.fk_soc, sc.fk_user";
4770 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"facture as f";
4771 if (empty($user->rights->societe->client->voir) && !$socid) {
4772 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
4774 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice').
")";
4775 $sql .=
" AND f.fk_soc = s.rowid";
4776 if (empty($user->rights->societe->client->voir) && !$socid) {
4777 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
4780 $sql .=
" AND s.rowid = ".((int) $socid);
4783 $sql .=
" AND f.fk_statut = ".self::STATUS_DRAFT;
4785 if (is_object($excluser)) {
4786 $sql .=
" AND f.fk_user_author <> ".((int) $excluser->id);
4788 $sql .= $this->db->order($sortfield, $sortorder);
4789 $sql .= $this->db->plimit($limit, $offset);
4791 $result = $this->db->query($sql);
4793 $numc = $this->db->num_rows($result);
4796 while ($i < $numc) {
4797 $obj = $this->db->fetch_object($result);
4799 if ($shortlist == 1) {
4800 $ga[$obj->fid] = $obj->ref;
4801 } elseif ($shortlist == 2) {
4802 $ga[$obj->fid] = $obj->ref.
' ('.$obj->name.
')';
4804 $ga[$i][
'id'] = $obj->fid;
4805 $ga[$i][
'ref'] = $obj->ref;
4806 $ga[$i][
'name'] = $obj->name;
4835 $sql =
"SELECT f.rowid as rowid, f.ref, f.fk_statut as status, f.paye as paid,";
4836 $sql .=
" ff.rowid as rowidnext";
4838 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4839 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"paiement_facture as pf ON f.rowid = pf.fk_facture";
4840 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facture as ff ON f.rowid = ff.fk_facture_source";
4841 $sql .=
" WHERE (f.fk_statut = ".self::STATUS_VALIDATED.
" OR (f.fk_statut = ".self::STATUS_ABANDONED.
" AND f.close_code = '".self::CLOSECODE_ABANDONED.
"'))";
4842 $sql .=
" AND f.entity IN (".getEntity(
'invoice').
")";
4843 $sql .=
" AND f.paye = 0";
4844 $sql .=
" AND pf.fk_paiement IS NULL";
4845 $sql .=
" AND ff.fk_statut IS NULL";
4847 $sql .=
" AND f.fk_soc = ".((int) $socid);
4850 $sql .=
" ORDER BY f.ref";
4852 dol_syslog(get_class($this).
"::list_replacable_invoices", LOG_DEBUG);
4853 $resql = $this->db->query($sql);
4855 while ($obj = $this->db->fetch_object($resql)) {
4856 $return[$obj->rowid] = array(
4857 'id' => $obj->rowid,
4859 'status' => $obj->status,
4860 'paid' => $obj->paid,
4867 $this->error = $this->db->error();
4890 $sql =
"SELECT f.rowid as rowid, f.ref, f.fk_statut, f.type, f.paye, pf.fk_paiement";
4891 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4892 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"paiement_facture as pf ON f.rowid = pf.fk_facture";
4893 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=".self::TYPE_REPLACEMENT.
")";
4894 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice').
")";
4895 $sql .=
" AND f.fk_statut in (".self::STATUS_VALIDATED.
",".self::STATUS_CLOSED.
")";
4899 $sql .=
" AND ff.type IS NULL";
4900 $sql .=
" AND f.type <> ".self::TYPE_CREDIT_NOTE;
4902 if (!empty($conf->global->INVOICE_USE_SITUATION_CREDIT_NOTE)) {
4904 $sql .=
" AND (f.type <> ".self::TYPE_SITUATION.
" OR f.rowid IN ";
4905 $sql .=
'(SELECT MAX(fs.rowid)';
4906 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as fs";
4907 $sql .=
" WHERE fs.entity IN (".getEntity(
'invoice').
")";
4908 $sql .=
" AND fs.type = ".self::TYPE_SITUATION;
4909 $sql .=
" AND fs.fk_statut IN (".self::STATUS_VALIDATED.
",".self::STATUS_CLOSED.
")";
4911 $sql .=
" AND fs.fk_soc = ".((int) $socid);
4913 $sql .=
" GROUP BY fs.situation_cycle_ref)";
4916 $sql .=
" AND f.type <> ".self::TYPE_SITUATION;
4920 $sql .=
" AND f.fk_soc = ".((int) $socid);
4922 $sql .=
" ORDER BY f.ref";
4924 dol_syslog(get_class($this).
"::list_qualified_avoir_invoices", LOG_DEBUG);
4925 $resql = $this->db->query($sql);
4927 while ($obj = $this->db->fetch_object($resql)) {
4929 if ($obj->fk_statut == self::STATUS_VALIDATED) {
4932 if ($obj->fk_statut == self::STATUS_CLOSED) {
4937 $paymentornot = ($obj->fk_paiement ? 1 : 0);
4938 $return[$obj->rowid] = array(
'ref'=>$obj->ref,
'status'=>$obj->fk_statut,
'type'=>$obj->type,
'paye'=>$obj->paye,
'paymentornot'=>$paymentornot);
4944 $this->error = $this->db->error();
4960 global $conf, $langs;
4964 $sql =
"SELECT f.rowid, f.date_lim_reglement as datefin, f.fk_statut, f.total_ht";
4965 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4966 if (empty($user->rights->societe->client->voir) && !$user->socid) {
4967 $sql .=
" JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON f.fk_soc = sc.fk_soc";
4968 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
4971 $sql .= $clause.
" f.paye=0";
4972 $sql .=
" AND f.entity IN (".getEntity(
'invoice').
")";
4973 $sql .=
" AND f.fk_statut = ".self::STATUS_VALIDATED;
4975 $sql .=
" AND f.fk_soc = ".((int) $user->socid);
4978 $resql = $this->db->query($sql);
4980 $langs->load(
"bills");
4984 $response->warning_delay = $conf->facture->client->warning_delay / 60 / 60 / 24;
4985 $response->label = $langs->trans(
"CustomerBillsUnpaid");
4986 $response->labelShort = $langs->trans(
"Unpaid");
4987 $response->url = DOL_URL_ROOT.
'/compta/facture/list.php?search_status=1&mainmenu=billing&leftmenu=customers_bills';
4990 $generic_facture =
new Facture($this->db);
4992 while ($obj = $this->db->fetch_object($resql)) {
4993 $generic_facture->date_lim_reglement = $this->db->jdate($obj->datefin);
4994 $generic_facture->statut = $obj->fk_statut;
4996 $response->nbtodo++;
4997 $response->total += $obj->total_ht;
4999 if ($generic_facture->hasDelay()) {
5000 $response->nbtodolate++;
5001 $response->url_late = DOL_URL_ROOT.
'/compta/facture/list.php?search_option=late&mainmenu=billing&leftmenu=customers_bills';
5005 $this->db->free($resql);
5009 $this->error = $this->db->error();
5048 global $conf, $langs, $user;
5052 $nownotime =
dol_mktime(0, 0, 0, $arraynow[
'mon'], $arraynow[
'mday'], $arraynow[
'year']);
5057 $sql =
"SELECT rowid";
5058 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
5059 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
5060 $sql .= $this->db->plimit(100);
5062 $resql = $this->db->query($sql);
5064 $num_prods = $this->db->num_rows($resql);
5066 while ($i < $num_prods) {
5068 $row = $this->db->fetch_row($resql);
5069 $prodids[$i] = $row[0];
5073 if (empty($num_prods)) {
5080 $this->
ref =
'SPECIMEN';
5081 $this->specimen = 1;
5083 $this->date = $nownotime;
5084 $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
5085 $this->cond_reglement_id = 1;
5086 $this->cond_reglement_code =
'RECEP';
5088 $this->mode_reglement_id = 0;
5089 $this->mode_reglement_code =
'';
5091 $this->note_public =
'This is a comment (public)';
5092 $this->note_private =
'This is a comment (private)';
5093 $this->note =
'This is a comment (private)';
5095 $this->fk_user_author = $user->id;
5097 $this->multicurrency_tx = 1;
5098 $this->multicurrency_code = $conf->currency;
5100 $this->fk_incoterms = 0;
5101 $this->location_incoterms =
'';
5103 if (empty($option) || $option !=
'nolines') {
5107 while ($xnbp < $nbp) {
5109 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
5111 $line->subprice = 100;
5112 $line->tva_tx = 19.6;
5113 $line->localtax1_tx = 0;
5114 $line->localtax2_tx = 0;
5115 $line->remise_percent = 0;
5117 $prodid = mt_rand(1, $num_prods);
5118 $line->fk_product = $prodids[$prodid];
5120 $line->total_ht = -100;
5121 $line->total_ttc = -119.6;
5122 $line->total_tva = -19.6;
5123 $line->multicurrency_total_ht = -200;
5124 $line->multicurrency_total_ttc = -239.2;
5125 $line->multicurrency_total_tva = -39.2;
5126 } elseif ($xnbp == 2) {
5127 $line->subprice = -100;
5128 $line->total_ht = -100;
5129 $line->total_ttc = -119.6;
5130 $line->total_tva = -19.6;
5131 $line->remise_percent = 0;
5132 $line->multicurrency_total_ht = -200;
5133 $line->multicurrency_total_ttc = -239.2;
5134 $line->multicurrency_total_tva = -39.2;
5135 } elseif ($xnbp == 3) {
5136 $prodid = mt_rand(1, $num_prods);
5137 $line->fk_product = $prodids[$prodid];
5138 $line->total_ht = 50;
5139 $line->total_ttc = 59.8;
5140 $line->total_tva = 9.8;
5141 $line->multicurrency_total_ht = 100;
5142 $line->multicurrency_total_ttc = 119.6;
5143 $line->multicurrency_total_tva = 19.6;
5144 $line->remise_percent = 50;
5147 $prodid = mt_rand(1, $num_prods);
5148 $line->fk_product = $prodids[$prodid];
5149 $line->total_ht = 100;
5150 $line->total_ttc = 119.6;
5151 $line->total_tva = 19.6;
5152 $line->multicurrency_total_ht = 200;
5153 $line->multicurrency_total_ttc = 239.2;
5154 $line->multicurrency_total_tva = 39.2;
5155 $line->remise_percent = 0;
5158 $this->lines[$xnbp] = $line;
5161 $this->total_ht += $line->total_ht;
5162 $this->total_tva += $line->total_tva;
5163 $this->total_ttc += $line->total_ttc;
5165 $this->multicurrency_total_ht += $line->multicurrency_total_ht;
5166 $this->multicurrency_total_tva += $line->multicurrency_total_tva;
5167 $this->multicurrency_total_ttc += $line->multicurrency_total_ttc;
5171 $this->revenuestamp = 0;
5175 $line->desc = $langs->trans(
"Description").
" (offered line)";
5177 $line->subprice = 100;
5178 $line->tva_tx = 19.6;
5179 $line->localtax1_tx = 0;
5180 $line->localtax2_tx = 0;
5181 $line->remise_percent = 100;
5182 $line->total_ht = 0;
5183 $line->total_ttc = 0;
5184 $line->total_tva = 0;
5185 $line->multicurrency_total_ht = 0;
5186 $line->multicurrency_total_ttc = 0;
5187 $line->multicurrency_total_tva = 0;
5188 $prodid = mt_rand(1, $num_prods);
5189 $line->fk_product = $prodids[$prodid];
5191 $this->lines[$xnbp] = $line;
5205 global $conf, $user;
5207 $this->nb = array();
5211 $sql =
"SELECT count(f.rowid) as nb";
5212 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
5213 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON f.fk_soc = s.rowid";
5214 if (empty($user->rights->societe->client->voir) && !$user->socid) {
5215 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
5216 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
5219 $sql .=
" ".$clause.
" f.entity IN (".
getEntity(
'invoice').
")";
5221 $resql = $this->db->query($sql);
5223 while ($obj = $this->db->fetch_object($resql)) {
5224 $this->nb[
"invoices"] = $obj->nb;
5226 $this->db->free($resql);
5230 $this->error = $this->db->error();
5256 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
5258 global $conf, $langs;
5260 $outputlangs->loadLangs(array(
"bills",
"products"));
5264 $thisTypeConfName =
'FACTURE_ADDON_PDF_'.$this->type;
5266 if (!empty($this->model_pdf)) {
5267 $modele = $this->model_pdf;
5268 } elseif (!empty($this->modelpdf)) {
5269 $modele = $this->modelpdf;
5270 } elseif (!empty($conf->global->$thisTypeConfName)) {
5271 $modele = $conf->global->$thisTypeConfName;
5272 } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) {
5273 $modele = $conf->global->FACTURE_ADDON_PDF;
5277 $modelpath =
"core/modules/facture/doc/";
5279 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
5289 $sql =
'SELECT max(situation_cycle_ref) FROM '.MAIN_DB_PREFIX.
'facture as f';
5290 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice', 0).
")";
5291 $resql = $this->db->query($sql);
5293 if ($this->db->num_rows($resql) > 0) {
5294 $res = $this->db->fetch_array($resql);
5295 $ref = $res[
'max(situation_cycle_ref)'];
5300 $this->db->free($resql);
5303 $this->error = $this->db->lasterror();
5304 dol_syslog(
"Error sql=".$sql.
", error=".$this->error, LOG_ERR);
5318 return ($this->situation_counter == 1);
5332 $sql =
'SELECT rowid FROM '.MAIN_DB_PREFIX.
'facture';
5333 $sql .=
' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref);
5334 $sql .=
' AND situation_counter < '.((int) $this->situation_counter);
5335 $sql .=
' AND entity = '.($this->entity > 0 ? $this->entity : $conf->entity);
5336 $resql = $this->db->query($sql);
5338 if ($resql && $this->db->num_rows($resql) > 0) {
5339 while ($row = $this->db->fetch_object($resql)) {
5341 $situation =
new Facture($this->db);
5342 $situation->fetch($id);
5343 $res[] = $situation;
5346 $this->error = $this->db->error();
5347 dol_syslog(
"Error sql=".$sql.
", error=".$this->error, LOG_ERR);
5367 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET situation_final = '.((int) $this->situation_final).
' WHERE rowid = '.((int) $this->
id);
5370 $resql = $this->db->query($sql);
5372 $this->errors[] = $this->db->error();
5376 if (!$notrigger && empty($error)) {
5386 $this->db->commit();
5389 foreach ($this->errors as $errmsg) {
5390 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
5391 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
5393 $this->db->rollback();
5409 if (!empty($this->situation_cycle_ref)) {
5411 $sql =
'SELECT max(situation_counter) FROM '.MAIN_DB_PREFIX.
'facture';
5412 $sql .=
' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref);
5413 $sql .=
' AND entity = '.($this->entity > 0 ? $this->entity : $conf->entity);
5414 $resql = $this->db->query($sql);
5416 if ($resql && $this->db->num_rows($resql) > 0) {
5417 $res = $this->db->fetch_array($resql);
5418 $last = $res[
'max(situation_counter)'];
5419 return ($last == $this->situation_counter);
5421 $this->error = $this->db->lasterror();
5422 dol_syslog(get_class($this).
"::select Error ".$this->error, LOG_ERR);
5480 $hasDelay = $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay);
5481 if ($hasDelay && !empty($this->retained_warranty) && !empty($this->retained_warranty_date_limit)) {
5483 $totalpaid = floatval($totalpaid);
5485 if ($totalpaid >= 0 && $RetainedWarrantyAmount >= 0) {
5486 if (($totalpaid < $this->total_ttc - $RetainedWarrantyAmount) && $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay)) {
5488 } elseif ($totalpaid < $this->total_ttc && $this->retained_warranty_date_limit < ($now - $conf->facture->client->warning_delay)) {
5511 $displayWarranty =
false;
5512 if (!empty($this->retained_warranty)) {
5513 $displayWarranty =
true;
5517 $displayWarranty =
false;
5518 if (!empty($this->situation_final)) {
5519 $displayWarranty =
true;
5522 $displayWarranty =
true;
5524 foreach ($this->lines as $i => $line) {
5525 if ($line->product_type < 2 && $line->situation_percent < 100) {
5526 $displayWarranty =
false;
5534 return $displayWarranty;
5544 if (empty($this->retained_warranty)) {
5548 $retainedWarrantyAmount = 0;
5552 $displayWarranty =
true;
5554 if (!empty($this->lines)) {
5555 foreach ($this->lines as $i => $line) {
5556 if ($line->product_type < 2 && $line->situation_percent < 100) {
5557 $displayWarranty =
false;
5563 if ($displayWarranty && !empty($this->situation_final)) {
5565 $TPreviousIncoice = $this->tab_previous_situation_invoice;
5568 foreach ($TPreviousIncoice as &$fac) {
5569 $total2BillWT += $fac->total_ttc;
5571 $total2BillWT += $this->total_ttc;
5573 $retainedWarrantyAmount = $total2BillWT * $this->retained_warranty / 100;
5579 $retainedWarrantyAmount = $this->total_ttc * $this->retained_warranty / 100;
5582 if ($rounding < 0) {
5583 $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT);
5586 if ($rounding > 0) {
5587 return round($retainedWarrantyAmount, $rounding);
5590 return $retainedWarrantyAmount;
5601 dol_syslog(get_class($this).
'::setRetainedWarranty('.$value.
')');
5603 if ($this->
statut >= 0) {
5604 $fieldname =
'retained_warranty';
5605 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
5606 $sql .=
" SET ".$fieldname.
" = ".((float) $value);
5607 $sql .=
' WHERE rowid='.((int) $this->
id);
5609 if ($this->db->query($sql)) {
5610 $this->retained_warranty = floatval($value);
5613 dol_syslog(get_class($this).
'::setRetainedWarranty Erreur '.$sql.
' - '.$this->db->error());
5614 $this->error = $this->db->error();
5618 dol_syslog(get_class($this).
'::setRetainedWarranty, status of the object is incompatible');
5619 $this->error =
'Status of the object is incompatible '.$this->statut;
5634 if (!$timestamp && $dateYmd) {
5635 $timestamp = $this->db->jdate($dateYmd);
5639 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit('.$timestamp.
')');
5640 if ($this->
statut >= 0) {
5641 $fieldname =
'retained_warranty_date_limit';
5642 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
5643 $sql .=
" SET ".$fieldname.
" = ".(strval($timestamp) !=
'' ?
"'".$this->db->idate($timestamp).
"'" :
'null');
5644 $sql .=
' WHERE rowid = '.((int) $this->
id);
5646 if ($this->db->query($sql)) {
5647 $this->retained_warranty_date_limit = $timestamp;
5650 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit Erreur '.$sql.
' - '.$this->db->error());
5651 $this->error = $this->db->error();
5655 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit, status of the object is incompatible');
5656 $this->error =
'Status of the object is incompatible '.$this->statut;
5675 global $conf, $langs, $user;
5681 $errorsMsg = array();
5683 $langs->load(
"bills");
5685 if (!isModEnabled(
'facture')) {
5686 $this->output .= $langs->trans(
'ModuleNotEnabled', $langs->transnoentitiesnoconv(
"Facture"));
5689 if (!in_array($datetouse, array(
'duedate',
'invoicedate'))) {
5690 $this->output .=
'Bad value for parameter datetouse. Must be "duedate" or "invoicedate"';
5700 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
5701 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmail.class.php';
5702 require_once DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
5703 $formmail =
new FormMail($this->db);
5708 $tmpinvoice =
new Facture($this->db);
5713 $sql =
"SELECT rowid as id FROM ".MAIN_DB_PREFIX.
"facture as f";
5714 if (!empty($paymentmode) && $paymentmode !=
'all') {
5715 $sql .=
", ".MAIN_DB_PREFIX.
"c_paiement as cp";
5717 $sql .=
" WHERE f.paye = 0";
5718 $sql .=
" AND f.fk_statut = ".self::STATUS_VALIDATED;
5719 if ($datetouse ==
'invoicedate') {
5720 $sql .=
" AND f.datef = '".$this->db->idate($tmpidate,
'gmt').
"'";
5722 $sql .=
" AND f.date_lim_reglement = '".$this->db->idate($tmpidate,
'gmt').
"'";
5724 $sql .=
" AND f.entity IN (".getEntity(
'facture', 0).
")";
5725 if (!empty($paymentmode) && $paymentmode !=
'all') {
5726 $sql .=
" AND f.fk_mode_reglement = cp.id AND cp.code = '".$this->db->escape($paymentmode).
"'";
5729 if ($datetouse ==
'invoicedate') {
5730 $sql .= $this->db->order(
"datef",
"ASC");
5732 $sql .= $this->db->order(
"date_lim_reglement",
"ASC");
5735 $resql = $this->db->query($sql);
5738 if ($datetouse ==
'invoicedate') {
5739 $this->output .= $langs->transnoentitiesnoconv(
"SearchValidatedInvoicesWithDate", $stmpidate);
5741 $this->output .= $langs->transnoentitiesnoconv(
"SearchUnpaidInvoicesWithDueDate", $stmpidate);
5743 if (!empty($paymentmode) && $paymentmode !=
'all') {
5744 $this->output .=
' ('.$langs->transnoentitiesnoconv(
"PaymentMode").
' '.$paymentmode.
')';
5746 $this->output .=
'<br>';
5749 while ($obj = $this->db->fetch_object($resql)) {
5752 $res = $tmpinvoice->fetch($obj->id);
5754 $tmpinvoice->fetch_thirdparty();
5756 $outputlangs =
new Translate(
'', $conf);
5757 if ($tmpinvoice->thirdparty->default_lang) {
5758 $outputlangs->setDefaultLang($tmpinvoice->thirdparty->default_lang);
5759 $outputlangs->loadLangs(array(
"main",
"bills"));
5761 $outputlangs = $langs;
5765 $arraymessage = $formmail->getEMailTemplate($this->db,
'facture_send', $user, $outputlangs, (is_numeric($template) ? $template : 0), 1, (is_numeric($template) ?
'' : $template));
5766 if (is_numeric($arraymessage) && $arraymessage <= 0) {
5767 $langs->load(
"errors");
5768 $this->output .= $langs->trans(
'ErrorFailedToFindEmailTemplate', $template);
5781 $sendTopic =
make_substitutions(empty($arraymessage->topic) ? $outputlangs->transnoentitiesnoconv(
'InformationMessage') : $arraymessage->topic, $substitutionarray, $outputlangs, 1);
5784 $content = $outputlangs->transnoentitiesnoconv($arraymessage->content);
5790 if ($forcerecipient) {
5791 $to = array($forcerecipient);
5793 $res = $tmpinvoice->fetch_thirdparty();
5794 $recipient = $tmpinvoice->thirdparty;
5796 $tmparraycontact = $tmpinvoice->liste_contact(-1,
'external', 0,
'BILLING');
5797 if (is_array($tmparraycontact) && count($tmparraycontact) > 0) {
5798 foreach ($tmparraycontact as $data_email) {
5799 if (!empty($data_email[
'email'])) {
5800 $to[] = $tmpinvoice->thirdparty->contact_get_property($data_email[
'id'],
'email');
5804 if (empty($to) && !empty($recipient->email)) {
5805 $to[] = $recipient->email;
5808 $errormesg =
"Failed to send remind to thirdparty id=".$tmpinvoice->socid.
". No email defined for invoice or customer.";
5812 $errormesg =
"Failed to load recipient with thirdparty id=".$tmpinvoice->socid;
5819 if (!empty($arraymessage->email_from)) {
5820 $from = $arraymessage->email_from;
5823 $errormesg =
"Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
5827 if (!$error && !empty($to)) {
5830 $to = implode(
',', $to);
5831 if (!empty($arraymessage->email_to)) {
5832 $to = $to.
','.$arraymessage->email_to;
5836 $errors_to = $conf->global->MAIN_MAIL_ERRORS_TO;
5838 $trackid =
'inv'.$tmpinvoice->id;
5839 $sendcontext =
'standard';
5842 if (!empty($arraymessage->email_tocc)) {
5843 $email_tocc = $arraymessage->email_tocc;
5847 if (!empty($arraymessage->email_tobcc)) {
5848 $email_tobcc = $arraymessage->email_tobcc;
5855 if ($arraymessage->joinfiles == 1 && !empty($tmpinvoice->last_main_doc)) {
5856 $joinFile[] = DOL_DATA_ROOT.
'/'.$tmpinvoice->last_main_doc;
5857 $joinFileName[] = basename($tmpinvoice->last_main_doc);
5858 $joinFileMime[] =
dol_mimetype(DOL_DATA_ROOT.
'/'.$tmpinvoice->last_main_doc);
5862 $cMailFile =
new CMailFile($sendTopic, $to, $from, $sendContent, $joinFile, $joinFileMime, $joinFileName, $email_tocc, $email_tobcc, 0, 1, $errors_to,
'', $trackid,
'', $sendcontext,
'');
5865 if ($cMailFile->sendfile()) {
5869 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
5874 $actioncomm->type_code =
'AC_OTH_AUTO';
5875 $actioncomm->socid = $tmpinvoice->thirdparty->id;
5876 $actioncomm->contact_id = 0;
5878 $actioncomm->code =
'AC_EMAIL';
5879 $actioncomm->label =
'sendEmailsRemindersOnInvoiceDueDateOK (nbdays='.$nbdays.
' paymentmode='.$paymentmode.
' template='.$template.
' datetouse='.$datetouse.
' forcerecipient='.$forcerecipient.
')';
5880 $actioncomm->note_private = $sendContent;
5881 $actioncomm->fk_project = $tmpinvoice->fk_project;
5882 $actioncomm->datep =
dol_now();
5883 $actioncomm->datef = $actioncomm->datep;
5884 $actioncomm->percentage = -1;
5885 $actioncomm->authorid = $user->id;
5886 $actioncomm->userownerid = $user->id;
5888 $actioncomm->email_msgid = $cMailFile->msgid;
5889 $actioncomm->email_subject = $sendTopic;
5890 $actioncomm->email_from = $from;
5891 $actioncomm->email_sender =
'';
5892 $actioncomm->email_to = $to;
5896 $actioncomm->errors_to = $errors_to;
5898 $actioncomm->elementtype =
'invoice';
5899 $actioncomm->fk_element = $tmpinvoice->id;
5903 $actioncomm->create($user);
5905 $errormesg = $cMailFile->error.
' : '.$to;
5909 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
5914 $actioncomm->type_code =
'AC_OTH_AUTO';
5915 $actioncomm->socid = $tmpinvoice->thirdparty->id;
5916 $actioncomm->contact_id = 0;
5918 $actioncomm->code =
'AC_EMAIL';
5919 $actioncomm->label =
'sendEmailsRemindersOnInvoiceDueDateKO';
5920 $actioncomm->note_private = $errormesg;
5921 $actioncomm->fk_project = $tmpinvoice->fk_project;
5922 $actioncomm->datep =
dol_now();
5923 $actioncomm->datef = $actioncomm->datep;
5924 $actioncomm->percentage = -1;
5925 $actioncomm->authorid = $user->id;
5926 $actioncomm->userownerid = $user->id;
5928 $actioncomm->email_msgid = $cMailFile->msgid;
5929 $actioncomm->email_from = $from;
5930 $actioncomm->email_sender =
'';
5931 $actioncomm->email_to = $to;
5935 $actioncomm->errors_to = $errors_to;
5939 $actioncomm->create($user);
5942 $this->db->commit();
5946 $errorsMsg[] = $errormesg;
5949 $errorsMsg[] =
'Failed to fetch record invoice with ID = '.$obj->id;
5959 $this->output .=
'Nb of emails sent : '.$nbMailSend;
5961 dol_syslog(__METHOD__.
" end - ".$this->output, LOG_INFO);
5965 $this->error =
'Nb of emails sent : '.$nbMailSend.
', '.(!empty($errorsMsg)) ? join(
', ', $errorsMsg) : $error;
5967 dol_syslog(__METHOD__.
" end - ".$this->error, LOG_INFO);
5982 $sql =
"SELECT datef";
5983 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
5984 $sql .=
" WHERE type = " . (int) $this->
type ;
5985 $sql .=
" AND date_valid IS NOT NULL";
5986 $sql .=
" AND entity IN (".getEntity(
'invoice').
")";
5987 $sql .=
" ORDER BY datef DESC LIMIT 1";
5989 $result = $this->db->query($sql);
5992 if ($this->db->num_rows($result)) {
5993 $obj = $this->db->fetch_object($result);
5994 $last_date = $this->db->jdate($obj->datef);
5995 $invoice_date = $this->date;
5997 $is_last_of_same_type = $invoice_date >= $last_date;
5998 if ($allow_validated_drafts) {
5999 $is_last_of_same_type = $is_last_of_same_type || (!strpos($this->
ref,
'PROV') && $this->status ==
self::STATUS_DRAFT);
6002 return array($is_last_of_same_type, $last_date);
6023 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
6025 $return =
'<div class="box-flex-item box-flex-grow-zero">';
6026 $return .=
'<div class="info-box info-box-sm">';
6027 $return .=
'<span class="info-box-icon bg-infobox-action">';
6030 $return .=
'</span>';
6031 $return .=
'<div class="info-box-content">';
6032 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
6033 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
6034 if (property_exists($this,
'socid')) {
6035 $return .=
'<br><span class="info-box-label">'.$this->socid.
'</span>';
6037 if (property_exists($this,
'fk_user_author')) {
6038 $return .=
'<br><span class="info-box-label">'.$this->fk_user_author.
'</span>';
6040 if (method_exists($this,
'getLibStatut')) {
6041 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).
'</div>';
6043 $return .=
'</div>';
6044 $return .=
'</div>';
6045 $return .=
'</div>';
6059 public $element =
'facturedet';
6064 public $table_element =
'facturedet';
6081 public $localtax1_type;
6082 public $localtax2_type;
6083 public $fk_remise_except;
6086 public $fk_fournprice;
6091 public $remise_percent;
6093 public $special_code;
6101 public $fk_code_ventilation = 0;
6106 public $skip_update_total;
6111 public $situation_percent;
6119 public $fk_multicurrency;
6120 public $multicurrency_code;
6121 public $multicurrency_subprice;
6122 public $multicurrency_total_ht;
6123 public $multicurrency_total_tva;
6124 public $multicurrency_total_ttc;
6144 $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,';
6145 $sql .=
' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice, fd.ref_ext,';
6146 $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,';
6147 $sql .=
' fd.info_bits, fd.special_code, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,';
6148 $sql .=
' fd.fk_code_ventilation,';
6149 $sql .=
' fd.fk_unit, fd.fk_user_author, fd.fk_user_modif,';
6150 $sql .=
' fd.situation_percent, fd.fk_prev_id,';
6151 $sql .=
' fd.multicurrency_subprice,';
6152 $sql .=
' fd.multicurrency_total_ht,';
6153 $sql .=
' fd.multicurrency_total_tva,';
6154 $sql .=
' fd.multicurrency_total_ttc,';
6155 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc';
6156 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facturedet as fd';
6157 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON fd.fk_product = p.rowid';
6158 $sql .=
' WHERE fd.rowid = '.((int) $rowid);
6160 $result = $this->db->query($sql);
6162 $objp = $this->db->fetch_object($result);
6165 $this->error =
'InvoiceLine with id '. $rowid .
' not found sql='.$sql;
6169 $this->
rowid = $objp->rowid;
6170 $this->
id = $objp->rowid;
6171 $this->fk_facture = $objp->fk_facture;
6172 $this->fk_parent_line = $objp->fk_parent_line;
6173 $this->label = $objp->custom_label;
6174 $this->desc = $objp->description;
6175 $this->qty = $objp->qty;
6176 $this->subprice = $objp->subprice;
6177 $this->ref_ext = $objp->ref_ext;
6178 $this->vat_src_code = $objp->vat_src_code;
6179 $this->tva_tx = $objp->tva_tx;
6180 $this->localtax1_tx = $objp->localtax1_tx;
6181 $this->localtax2_tx = $objp->localtax2_tx;
6182 $this->remise_percent = $objp->remise_percent;
6183 $this->fk_remise_except = $objp->fk_remise_except;
6184 $this->fk_product = $objp->fk_product;
6185 $this->product_type = $objp->product_type;
6186 $this->date_start = $this->db->jdate($objp->date_start);
6187 $this->date_end = $this->db->jdate($objp->date_end);
6188 $this->info_bits = $objp->info_bits;
6189 $this->tva_npr = ($objp->info_bits & 1 == 1) ? 1 : 0;
6190 $this->special_code = $objp->special_code;
6191 $this->total_ht = $objp->total_ht;
6192 $this->total_tva = $objp->total_tva;
6193 $this->total_localtax1 = $objp->total_localtax1;
6194 $this->total_localtax2 = $objp->total_localtax2;
6195 $this->total_ttc = $objp->total_ttc;
6196 $this->fk_code_ventilation = $objp->fk_code_ventilation;
6197 $this->rang = $objp->rang;
6198 $this->fk_fournprice = $objp->fk_fournprice;
6199 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
6200 $this->pa_ht = $marginInfos[0];
6201 $this->marge_tx = $marginInfos[1];
6202 $this->marque_tx = $marginInfos[2];
6204 $this->
ref = $objp->product_ref;
6206 $this->product_ref = $objp->product_ref;
6207 $this->product_label = $objp->product_label;
6208 $this->product_desc = $objp->product_desc;
6210 $this->fk_unit = $objp->fk_unit;
6211 $this->fk_user_modif = $objp->fk_user_modif;
6212 $this->fk_user_author = $objp->fk_user_author;
6214 $this->situation_percent = $objp->situation_percent;
6215 $this->fk_prev_id = $objp->fk_prev_id;
6217 $this->multicurrency_subprice = $objp->multicurrency_subprice;
6218 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
6219 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
6220 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
6224 $this->db->free($result);
6228 $this->error = $this->db->lasterror();
6240 public function insert($notrigger = 0, $noerrorifdiscountalreadylinked = 0)
6242 global $langs, $user, $conf;
6246 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
6248 dol_syslog(get_class($this).
"::insert rang=".$this->rang, LOG_DEBUG);
6251 $this->desc = trim($this->desc);
6252 if (empty($this->tva_tx)) {
6255 if (empty($this->localtax1_tx)) {
6256 $this->localtax1_tx = 0;
6258 if (empty($this->localtax2_tx)) {
6259 $this->localtax2_tx = 0;
6261 if (empty($this->localtax1_type)) {
6262 $this->localtax1_type = 0;
6264 if (empty($this->localtax2_type)) {
6265 $this->localtax2_type = 0;
6267 if (empty($this->total_localtax1)) {
6268 $this->total_localtax1 = 0;
6270 if (empty($this->total_localtax2)) {
6271 $this->total_localtax2 = 0;
6273 if (empty($this->rang)) {
6276 if (empty($this->remise_percent)) {
6277 $this->remise_percent = 0;
6279 if (empty($this->info_bits)) {
6280 $this->info_bits = 0;
6282 if (empty($this->subprice)) {
6283 $this->subprice = 0;
6285 if (empty($this->ref_ext)) {
6286 $this->ref_ext =
'';
6288 if (empty($this->special_code)) {
6289 $this->special_code = 0;
6291 if (empty($this->fk_parent_line)) {
6292 $this->fk_parent_line = 0;
6294 if (empty($this->fk_prev_id)) {
6295 $this->fk_prev_id = 0;
6297 if (!isset($this->situation_percent) || $this->situation_percent > 100 || (
string) $this->situation_percent ==
'') {
6298 $this->situation_percent = 100;
6301 if (empty($this->pa_ht)) {
6304 if (empty($this->multicurrency_subprice)) {
6305 $this->multicurrency_subprice = 0;
6307 if (empty($this->multicurrency_total_ht)) {
6308 $this->multicurrency_total_ht = 0;
6310 if (empty($this->multicurrency_total_tva)) {
6311 $this->multicurrency_total_tva = 0;
6313 if (empty($this->multicurrency_total_ttc)) {
6314 $this->multicurrency_total_ttc = 0;
6318 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
6319 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
6322 $this->pa_ht = $result;
6327 if ($this->product_type < 0) {
6328 $this->error =
'ErrorProductTypeMustBe0orMore';
6331 if (!empty($this->fk_product) && $this->fk_product > 0) {
6335 $this->error =
'ErrorProductIdDoesNotExists';
6336 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6344 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'facturedet';
6345 $sql .=
' (fk_facture, fk_parent_line, label, description, qty,';
6346 $sql .=
' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
6347 $sql .=
' fk_product, product_type, remise_percent, subprice, ref_ext, fk_remise_except,';
6348 $sql .=
' date_start, date_end, fk_code_ventilation, ';
6349 $sql .=
' rang, special_code, fk_product_fournisseur_price, buy_price_ht,';
6350 $sql .=
' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2,';
6351 $sql .=
' situation_percent, fk_prev_id,';
6352 $sql .=
' fk_unit, fk_user_author, fk_user_modif,';
6353 $sql .=
' fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
6355 $sql .=
" VALUES (".$this->fk_facture.
",";
6356 $sql .=
" ".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null").
",";
6357 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
6358 $sql .=
" '".$this->db->escape($this->desc).
"',";
6359 $sql .=
" ".price2num($this->qty).
",";
6360 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
6361 $sql .=
" ".price2num($this->tva_tx).
",";
6362 $sql .=
" ".price2num($this->localtax1_tx).
",";
6363 $sql .=
" ".price2num($this->localtax2_tx).
",";
6364 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
6365 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
6366 $sql .=
' '.((!empty($this->fk_product) && $this->fk_product > 0) ? $this->fk_product :
"null").
',';
6367 $sql .=
" ".((int) $this->product_type).
",";
6368 $sql .=
" ".price2num($this->remise_percent).
",";
6369 $sql .=
" ".price2num($this->subprice).
",";
6370 $sql .=
" '".$this->db->escape($this->ref_ext).
"',";
6371 $sql .=
' '.(!empty($this->fk_remise_except) ? $this->fk_remise_except :
"null").
',';
6372 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
",";
6373 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null").
",";
6374 $sql .=
' '.((int) $this->fk_code_ventilation).
',';
6375 $sql .=
' '.((int) $this->rang).
',';
6376 $sql .=
' '.((int) $this->special_code).
',';
6377 $sql .=
' '.(!empty($this->fk_fournprice) ? $this->fk_fournprice :
"null").
',';
6378 $sql .=
' '.price2num($this->pa_ht).
',';
6379 $sql .=
" '".$this->db->escape($this->info_bits).
"',";
6380 $sql .=
" ".price2num($this->total_ht).
",";
6381 $sql .=
" ".price2num($this->total_tva).
",";
6382 $sql .=
" ".price2num($this->total_ttc).
",";
6383 $sql .=
" ".price2num($this->total_localtax1).
",";
6384 $sql .=
" ".price2num($this->total_localtax2);
6385 $sql .=
", ".((float) $this->situation_percent);
6386 $sql .=
", ".(!empty($this->fk_prev_id) ? $this->fk_prev_id :
"null");
6387 $sql .=
", ".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
6388 $sql .=
", ".((int) $user->id);
6389 $sql .=
", ".((int) $user->id);
6390 $sql .=
", ".(int) $this->fk_multicurrency;
6391 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
6392 $sql .=
", ".price2num($this->multicurrency_subprice);
6393 $sql .=
", ".price2num($this->multicurrency_total_ht);
6394 $sql .=
", ".price2num($this->multicurrency_total_tva);
6395 $sql .=
", ".price2num($this->multicurrency_total_ttc);
6398 dol_syslog(get_class($this).
"::insert", LOG_DEBUG);
6399 $resql = $this->db->query($sql);
6401 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'facturedet');
6402 $this->
rowid = $this->id;
6413 if ($this->fk_remise_except && empty($error)) {
6415 $result = $discount->fetch($this->fk_remise_except);
6420 if ($discount->fk_facture_line > 0) {
6421 if (empty($noerrorifdiscountalreadylinked)) {
6422 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed", $discount->id);
6423 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6424 $this->db->rollback();
6428 $result = $discount->link_to_invoice($this->
rowid, 0);
6430 $this->error = $discount->error;
6431 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6432 $this->db->rollback();
6437 $this->error = $langs->trans(
"ErrorADiscountThatHasBeenRemovedIsIncluded");
6438 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6439 $this->db->rollback();
6443 $this->error = $discount->error;
6444 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6445 $this->db->rollback();
6450 if (!$notrigger && empty($error)) {
6452 $result = $this->
call_trigger(
'LINEBILL_INSERT', $user);
6454 $this->db->rollback();
6461 $this->db->commit();
6465 foreach ($this->errors as $errmsg) {
6466 dol_syslog(get_class($this).
"::insert ".$errmsg, LOG_ERR);
6467 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
6469 $this->db->rollback();
6472 $this->error = $this->db->lasterror();
6473 $this->db->rollback();
6485 public function update($user =
'', $notrigger = 0)
6487 global $user, $conf;
6491 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
6494 $this->desc = trim($this->desc);
6495 if (empty($this->ref_ext)) {
6496 $this->ref_ext =
'';
6498 if (empty($this->tva_tx)) {
6501 if (empty($this->localtax1_tx)) {
6502 $this->localtax1_tx = 0;
6504 if (empty($this->localtax2_tx)) {
6505 $this->localtax2_tx = 0;
6507 if (empty($this->localtax1_type)) {
6508 $this->localtax1_type = 0;
6510 if (empty($this->localtax2_type)) {
6511 $this->localtax2_type = 0;
6513 if (empty($this->total_localtax1)) {
6514 $this->total_localtax1 = 0;
6516 if (empty($this->total_localtax2)) {
6517 $this->total_localtax2 = 0;
6519 if (empty($this->remise_percent)) {
6520 $this->remise_percent = 0;
6522 if (empty($this->info_bits)) {
6523 $this->info_bits = 0;
6525 if (empty($this->special_code)) {
6526 $this->special_code = 0;
6528 if (empty($this->product_type)) {
6529 $this->product_type = 0;
6531 if (empty($this->fk_parent_line)) {
6532 $this->fk_parent_line = 0;
6534 if (!isset($this->situation_percent) || $this->situation_percent > 100 || (
string) $this->situation_percent ==
'') {
6535 $this->situation_percent = 100;
6537 if (empty($this->pa_ht)) {
6541 if (empty($this->multicurrency_subprice)) {
6542 $this->multicurrency_subprice = 0;
6544 if (empty($this->multicurrency_total_ht)) {
6545 $this->multicurrency_total_ht = 0;
6547 if (empty($this->multicurrency_total_tva)) {
6548 $this->multicurrency_total_tva = 0;
6550 if (empty($this->multicurrency_total_ttc)) {
6551 $this->multicurrency_total_ttc = 0;
6555 if ($this->product_type < 0) {
6560 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
6562 $result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product);
6566 $this->pa_ht = $result;
6573 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facturedet SET";
6574 $sql .=
" description='".$this->db->escape($this->desc).
"'";
6575 $sql .=
", ref_ext='".$this->db->escape($this->ref_ext).
"'";
6576 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
6577 $sql .=
", subprice=".price2num($this->subprice);
6578 $sql .=
", remise_percent=".price2num($this->remise_percent);
6579 if ($this->fk_remise_except) {
6580 $sql .=
", fk_remise_except=".$this->fk_remise_except;
6582 $sql .=
", fk_remise_except=null";
6584 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->db->escape($this->vat_src_code)).
"'";
6585 $sql .=
", tva_tx=".price2num($this->tva_tx);
6586 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
6587 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
6588 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
6589 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
6590 $sql .=
", qty=".price2num($this->qty);
6591 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
6592 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
6593 $sql .=
", product_type=".$this->product_type;
6594 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
6595 $sql .=
", special_code='".$this->db->escape($this->special_code).
"'";
6596 if (empty($this->skip_update_total)) {
6597 $sql .=
", total_ht=".price2num($this->total_ht);
6598 $sql .=
", total_tva=".price2num($this->total_tva);
6599 $sql .=
", total_ttc=".price2num($this->total_ttc);
6600 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
6601 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
6603 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
6604 $sql .=
", buy_price_ht=".(($this->pa_ht || (string) $this->pa_ht ===
'0') ?
price2num($this->pa_ht) :
"null");
6605 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null");
6606 if (!empty($this->rang)) {
6607 $sql .=
", rang=".((int) $this->rang);
6609 $sql .=
", situation_percent = ".((float) $this->situation_percent);
6610 $sql .=
", fk_unit = ".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
6611 $sql .=
", fk_user_modif = ".((int) $user->id);
6614 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
6615 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
6616 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
6617 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
6619 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
6621 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
6622 $resql = $this->db->query($sql);
6625 $this->
id = $this->rowid;
6632 if (!$error && !$notrigger) {
6634 $result = $this->
call_trigger(
'LINEBILL_MODIFY', $user);
6636 $this->db->rollback();
6643 $this->db->commit();
6647 foreach ($this->errors as $errmsg) {
6648 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
6649 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
6651 $this->db->rollback();
6654 $this->error = $this->db->error();
6655 $this->db->rollback();
6667 public function delete($tmpuser =
null, $notrigger =
false)
6674 if (empty($notrigger)) {
6675 $result = $this->
call_trigger(
'LINEBILL_DELETE', $user);
6677 $this->db->rollback();
6686 $this->db->rollback();
6691 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
6692 $sql .=
' SET fk_facture_line = NULL';
6693 $sql .=
' WHERE fk_facture_line = '.((int) $this->
id);
6695 dol_syslog(get_class($this).
"::deleteline", LOG_DEBUG);
6696 $result = $this->db->query($sql);
6698 $this->error = $this->db->error();
6699 $this->errors[] = $this->error;
6700 $this->db->rollback();
6704 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'element_time';
6705 $sql .=
' SET invoice_id = NULL, invoice_line_id = NULL';
6706 $sql .=
' WHERE invoice_line_id = '.((int) $this->
id);
6707 if (!$this->db->query($sql)) {
6708 $this->error = $this->db->error().
" sql=".$sql;
6709 $this->errors[] = $this->error;
6710 $this->db->rollback();
6714 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"facturedet WHERE rowid = ".((int) $this->
id);
6716 if ($this->db->query($sql)) {
6717 $this->db->commit();
6720 $this->error = $this->db->error().
" sql=".$sql;
6721 $this->errors[] = $this->error;
6722 $this->db->rollback();
6738 dol_syslog(get_class($this).
"::update_total", LOG_DEBUG);
6741 if (empty($this->total_localtax1)) {
6742 $this->total_localtax1 = 0;
6744 if (empty($this->total_localtax2)) {
6745 $this->total_localtax2 = 0;
6749 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facturedet SET";
6750 $sql .=
" total_ht=".price2num($this->total_ht);
6751 $sql .=
",total_tva=".price2num($this->total_tva);
6752 $sql .=
",total_localtax1=".price2num($this->total_localtax1);
6753 $sql .=
",total_localtax2=".price2num($this->total_localtax2);
6754 $sql .=
",total_ttc=".price2num($this->total_ttc);
6755 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
6757 dol_syslog(get_class($this).
"::update_total", LOG_DEBUG);
6759 $resql = $this->db->query($sql);
6761 $this->db->commit();
6764 $this->error = $this->db->error();
6765 $this->db->rollback();
6782 global $invoicecache;
6784 if (is_null($this->fk_prev_id) || empty($this->fk_prev_id) || $this->fk_prev_id ==
"") {
6788 if (!isset($invoicecache[$invoiceid])) {
6789 $invoicecache[$invoiceid] =
new Facture($this->db);
6790 $invoicecache[$invoiceid]->fetch($invoiceid);
6796 $sql =
"SELECT situation_percent FROM ".MAIN_DB_PREFIX.
"facturedet WHERE rowid = ".((int) $this->fk_prev_id);
6797 $resql = $this->db->query($sql);
6798 if ($resql && $this->db->num_rows($resql) > 0) {
6799 $res = $this->db->fetch_array($resql);
6801 $returnPercent = floatval($res[
'situation_percent']);
6803 if ($include_credit_note) {
6804 $sql =
'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.
'facturedet fd';
6805 $sql .=
' JOIN '.MAIN_DB_PREFIX.
'facture f ON (f.rowid = fd.fk_facture) ';
6806 $sql .=
" WHERE fd.fk_prev_id = ".((int) $this->fk_prev_id);
6807 $sql .=
" AND f.situation_cycle_ref = ".((int) $invoicecache[$invoiceid]->situation_cycle_ref);
6808 $sql .=
" AND f.type = ".Facture::TYPE_CREDIT_NOTE;
6810 $res = $this->db->query($sql);
6812 while ($obj = $this->db->fetch_object($res)) {
6813 $returnPercent = $returnPercent + floatval($obj->situation_percent);
6820 return $returnPercent;
6822 $this->error = $this->db->error();
6823 dol_syslog(get_class($this).
"::select Error ".$this->error, LOG_ERR);
6824 $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