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 =
null;
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->fk_fac_rec_source =
null;
1294 $object->date_creation =
'';
1295 $object->date_modification =
'';
1296 $object->date_validation =
'';
1297 $object->ref_client =
'';
1298 $object->ref_customer =
'';
1299 $object->close_code =
'';
1300 $object->close_note =
'';
1302 $object->note_private =
'';
1303 $object->note_public =
'';
1307 foreach ($object->lines as $i => $line) {
1308 if (($object->lines[$i]->info_bits & 0x02) == 0x02) {
1309 unset($object->lines[$i]);
1315 if (!empty($conf->global->INVOICE_AUTO_NEXT_MONTH_ON_LINES) && !empty($line->date_start) && !empty($line->date_end)) {
1327 if (
dol_mktime(0, 0, 0, $start[
'mon'], $start[
'mday'], $start[
'year'],
'gmt') == $first
1328 &&
dol_mktime(23, 59, 59, $end[
'mon'], $end[
'mday'], $end[
'year'],
'gmt') == $last) {
1332 $object->lines[$i]->date_start = $newFirst;
1333 $object->lines[$i]->date_end = $newLast;
1337 $object->lines[$i]->ref_ext =
'';
1341 $object->context[
'createfromclone'] =
'createfromclone';
1342 $result = $object->create($user);
1345 $this->error = $object->error;
1346 $this->errors = $object->errors;
1349 if ($object->copy_linked_contact($objFrom,
'internal') < 0) {
1351 $this->error = $object->error;
1352 $this->errors = $object->errors;
1353 } elseif ($object->socid == $objFrom->socid) {
1355 if ($object->copy_linked_contact($objFrom,
'external') < 0) {
1357 $this->error = $object->error;
1358 $this->errors = $object->errors;
1365 if (is_object($hookmanager)) {
1366 $parameters = array(
'objFrom'=>$objFrom);
1368 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action);
1376 unset($object->context[
'createfromclone']);
1380 $this->db->commit();
1383 $this->db->rollback();
1397 global $conf, $hookmanager;
1405 $num = count($object->lines);
1406 for ($i = 0; $i < $num; $i++) {
1409 $line->libelle = $object->lines[$i]->libelle;
1410 $line->label = $object->lines[$i]->label;
1411 $line->desc = $object->lines[$i]->desc;
1412 $line->subprice = $object->lines[$i]->subprice;
1413 $line->total_ht = $object->lines[$i]->total_ht;
1414 $line->total_tva = $object->lines[$i]->total_tva;
1415 $line->total_localtax1 = $object->lines[$i]->total_localtax1;
1416 $line->total_localtax2 = $object->lines[$i]->total_localtax2;
1417 $line->total_ttc = $object->lines[$i]->total_ttc;
1418 $line->vat_src_code = $object->lines[$i]->vat_src_code;
1419 $line->tva_tx = $object->lines[$i]->tva_tx;
1420 $line->localtax1_tx = $object->lines[$i]->localtax1_tx;
1421 $line->localtax2_tx = $object->lines[$i]->localtax2_tx;
1422 $line->qty = $object->lines[$i]->qty;
1423 $line->fk_remise_except = $object->lines[$i]->fk_remise_except;
1424 $line->remise_percent = $object->lines[$i]->remise_percent;
1425 $line->fk_product = $object->lines[$i]->fk_product;
1426 $line->info_bits = $object->lines[$i]->info_bits;
1427 $line->product_type = $object->lines[$i]->product_type;
1428 $line->rang = $object->lines[$i]->rang;
1429 $line->special_code = $object->lines[$i]->special_code;
1430 $line->fk_parent_line = $object->lines[$i]->fk_parent_line;
1431 $line->fk_unit = $object->lines[$i]->fk_unit;
1432 $line->date_start = $object->lines[$i]->date_start;
1433 $line->date_end = $object->lines[$i]->date_end;
1436 $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency;
1437 $line->multicurrency_code = $object->lines[$i]->multicurrency_code;
1438 $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice;
1439 $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht;
1440 $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva;
1441 $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc;
1443 $line->fk_fournprice = $object->lines[$i]->fk_fournprice;
1444 $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);
1445 $line->pa_ht = $marginInfos[0];
1448 $object->lines[$i]->fetch_optionals();
1449 foreach ($object->lines[$i]->array_options as $options_key => $value) {
1450 $line->array_options[$options_key] = $value;
1453 $this->lines[$i] = $line;
1456 $this->socid = $object->socid;
1457 $this->fk_project = $object->fk_project;
1458 $this->fk_account = $object->fk_account;
1459 $this->cond_reglement_id = $object->cond_reglement_id;
1460 $this->mode_reglement_id = $object->mode_reglement_id;
1461 $this->availability_id = $object->availability_id;
1462 $this->demand_reason_id = $object->demand_reason_id;
1463 $this->delivery_date = (empty($object->delivery_date) ? $object->date_livraison : $object->delivery_date);
1464 $this->date_livraison = $object->delivery_date;
1465 $this->fk_delivery_address = $object->fk_delivery_address;
1466 $this->contact_id = $object->contact_id;
1467 $this->ref_client = $object->ref_client;
1469 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1470 $this->note_private = $object->note_private;
1471 $this->note_public = $object->note_public;
1474 $this->module_source = $object->module_source;
1475 $this->pos_source = $object->pos_source;
1477 $this->origin = $object->element;
1478 $this->origin_id = $object->id;
1480 $this->fk_user_author = $user->id;
1483 $object->fetch_optionals();
1484 foreach ($object->array_options as $options_key => $value) {
1485 $this->array_options[$options_key] = $value;
1489 $this->linked_objects[$this->origin] = $this->origin_id;
1490 if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) {
1491 $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
1494 $ret = $this->
create($user);
1498 $hookmanager->initHooks(array(
'invoicedao'));
1500 $parameters = array(
'objFrom'=>$object);
1502 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1528 global $conf, $hookmanager;
1536 $use_all_lines = empty($lines);
1537 $num = count($object->lines);
1538 for ($i = 0; $i < $num; $i++) {
1539 if (!$use_all_lines && !in_array($object->lines[$i]->id, $lines)) {
1545 $line->libelle = $object->lines[$i]->libelle;
1546 $line->label = $object->lines[$i]->label;
1547 $line->desc = $object->lines[$i]->desc;
1548 $line->subprice = $object->lines[$i]->subprice;
1549 $line->total_ht = $object->lines[$i]->total_ht;
1550 $line->total_tva = $object->lines[$i]->total_tva;
1551 $line->total_localtax1 = $object->lines[$i]->total_localtax1;
1552 $line->total_localtax2 = $object->lines[$i]->total_localtax2;
1553 $line->total_ttc = $object->lines[$i]->total_ttc;
1554 $line->vat_src_code = $object->lines[$i]->vat_src_code;
1555 $line->tva_tx = $object->lines[$i]->tva_tx;
1556 $line->localtax1_tx = $object->lines[$i]->localtax1_tx;
1557 $line->localtax2_tx = $object->lines[$i]->localtax2_tx;
1558 $line->qty = $object->lines[$i]->qty;
1559 $line->fk_remise_except = $object->lines[$i]->fk_remise_except;
1560 $line->remise_percent = $object->lines[$i]->remise_percent;
1561 $line->fk_product = $object->lines[$i]->fk_product;
1562 $line->info_bits = $object->lines[$i]->info_bits;
1563 $line->product_type = $object->lines[$i]->product_type;
1564 $line->rang = $object->lines[$i]->rang;
1565 $line->special_code = $object->lines[$i]->special_code;
1566 $line->fk_parent_line = $object->lines[$i]->fk_parent_line;
1567 $line->fk_unit = $object->lines[$i]->fk_unit;
1568 $line->date_start = $object->lines[$i]->date_start;
1569 $line->date_end = $object->lines[$i]->date_end;
1572 $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency;
1573 $line->multicurrency_code = $object->lines[$i]->multicurrency_code;
1574 $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice;
1575 $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht;
1576 $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva;
1577 $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc;
1579 $line->fk_fournprice = $object->lines[$i]->fk_fournprice;
1580 $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);
1581 $line->pa_ht = $marginInfos[0];
1584 $object->lines[$i]->fetch_optionals();
1585 foreach ($object->lines[$i]->array_options as $options_key => $value) {
1586 $line->array_options[$options_key] = $value;
1589 $this->lines[$i] = $line;
1592 $this->socid = $object->socid;
1593 $this->fk_project = $object->fk_project;
1594 $this->fk_account = $object->fk_account;
1595 $this->cond_reglement_id = $object->cond_reglement_id;
1596 $this->mode_reglement_id = $object->mode_reglement_id;
1597 $this->availability_id = $object->availability_id;
1598 $this->demand_reason_id = $object->demand_reason_id;
1599 $this->delivery_date = (empty($object->delivery_date) ? $object->date_livraison : $object->delivery_date);
1600 $this->date_livraison = $object->delivery_date;
1601 $this->fk_delivery_address = $object->fk_delivery_address;
1602 $this->contact_id = $object->contact_id;
1603 $this->ref_client = $object->ref_client;
1605 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1606 $this->note_private = $object->note_private;
1607 $this->note_public = $object->note_public;
1610 $this->module_source = $object->module_source;
1611 $this->pos_source = $object->pos_source;
1613 $this->origin = $object->element;
1614 $this->origin_id = $object->id;
1616 $this->fk_user_author = $user->id;
1619 $object->fetch_optionals();
1620 foreach ($object->array_options as $options_key => $value) {
1621 $this->array_options[$options_key] = $value;
1625 $this->linked_objects[$this->origin] = $this->origin_id;
1626 if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) {
1627 $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
1630 $ret = $this->
create($user);
1634 $hookmanager->initHooks(array(
'invoicedao'));
1636 $parameters = array(
'objFrom'=>$object);
1638 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1668 global $conf, $langs, $hookmanager, $action;
1670 if (! in_array($origin->element, array(
'propal',
'commande'))) {
1671 $origin->error =
'ErrorCanOnlyAutomaticallyGenerateADepositFromProposalOrOrder';
1676 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'DateInvoice'));
1680 require_once DOL_DOCUMENT_ROOT .
'/core/lib/date.lib.php';
1682 if ($date > (
dol_get_last_hour(
dol_now(
'tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
1683 $origin->error =
'ErrorDateIsInFuture';
1687 if ($payment_terms_id <= 0) {
1688 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'PaymentConditionsShort'));
1692 $payment_conditions_deposit_percent =
getDictionaryValue(
'c_payment_term',
'deposit_percent', $origin->cond_reglement_id);
1694 if (empty($payment_conditions_deposit_percent)) {
1695 $origin->error =
'ErrorPaymentConditionsNotEligibleToDepositCreation';
1699 if (empty($origin->deposit_percent)) {
1700 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'DepositPercent'));
1704 $deposit =
new self($origin->db);
1705 $deposit->socid = $origin->socid;
1707 $deposit->fk_project = $origin->fk_project;
1708 $deposit->ref_client = $origin->ref_client;
1709 $deposit->date = $date;
1710 $deposit->mode_reglement_id = $origin->mode_reglement_id;
1711 $deposit->cond_reglement_id = $payment_terms_id;
1712 $deposit->availability_id = $origin->availability_id;
1713 $deposit->demand_reason_id = $origin->demand_reason_id;
1714 $deposit->fk_account = $origin->fk_account;
1715 $deposit->fk_incoterms = $origin->fk_incoterms;
1716 $deposit->location_incoterms = $origin->location_incoterms;
1717 $deposit->fk_multicurrency = $origin->fk_multicurrency;
1718 $deposit->multicurrency_code = $origin->multicurrency_code;
1719 $deposit->multicurrency_tx = $origin->multicurrency_tx;
1720 $deposit->module_source = $origin->module_source;
1721 $deposit->pos_source = $origin->pos_source;
1722 $deposit->model_pdf =
'crabe';
1724 $modelByTypeConfName =
'FACTURE_ADDON_PDF_' . $deposit->type;
1726 if (!empty($conf->global->$modelByTypeConfName)) {
1727 $deposit->model_pdf = $conf->global->$modelByTypeConfName;
1728 } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) {
1729 $deposit->model_pdf = $conf->global->FACTURE_ADDON_PDF;
1732 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1733 $deposit->note_private = $origin->note_private;
1734 $deposit->note_public = $origin->note_public;
1737 $deposit->origin = $origin->element;
1738 $deposit->origin_id = $origin->id;
1740 $origin->fetch_optionals();
1742 foreach ($origin->array_options as $extrakey => $value) {
1743 $deposit->array_options[$extrakey] = $value;
1746 $deposit->linked_objects[$deposit->origin] = $deposit->origin_id;
1748 foreach ($overrideFields as $key => $value) {
1749 $deposit->$key = $value;
1752 $deposit->context[
'createdepositfromorigin'] =
'createdepositfromorigin';
1754 $origin->db->begin();
1757 $createReturn = $deposit->create($user, $notrigger);
1759 if ($createReturn <= 0) {
1760 $origin->db->rollback();
1761 $origin->error = $deposit->error;
1762 $origin->errors = $deposit->errors;
1766 $amount_ttc_diff = 0;
1767 $amountdeposit = array();
1768 $descriptions = array();
1770 if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)) {
1771 $amount = $origin->total_ttc * ($origin->deposit_percent / 100);
1773 $TTotalByTva = array();
1774 foreach ($origin->lines as &$line) {
1775 if (!empty($line->special_code)) {
1778 $TTotalByTva[$line->tva_tx] += $line->total_ttc;
1779 $descriptions[$line->tva_tx] .=
'<li>' . (!empty($line->product_ref) ? $line->product_ref .
' - ' :
'');
1780 $descriptions[$line->tva_tx] .= (!empty($line->product_label) ? $line->product_label .
' - ' :
'');
1781 $descriptions[$line->tva_tx] .= $langs->trans(
'Qty') .
' : ' . $line->qty;
1782 $descriptions[$line->tva_tx] .=
' - ' . $langs->trans(
'TotalHT') .
' : ' .
price($line->total_ht) .
'</li>';
1785 foreach ($TTotalByTva as $tva => &$total) {
1786 $coef = $total / $origin->total_ttc;
1787 $am = $amount * $coef;
1788 $amount_ttc_diff += $am;
1789 $amountdeposit[$tva] += $am / (1 + $tva / 100);
1793 $lines = $origin->lines;
1794 $numlines = count($lines);
1795 for ($i = 0; $i < $numlines; $i++) {
1796 if (empty($lines[$i]->qty)) {
1799 if (!empty($lines[$i]->special_code)) {
1803 $totalamount += $lines[$i]->total_ht;
1804 $tva_tx = $lines[$i]->tva_tx;
1805 $amountdeposit[$tva_tx] += ($lines[$i]->total_ht * $origin->deposit_percent) / 100;
1806 $descriptions[$tva_tx] .=
'<li>' . (!empty($lines[$i]->product_ref) ? $lines[$i]->product_ref .
' - ' :
'');
1807 $descriptions[$tva_tx] .= (!empty($lines[$i]->product_label) ? $lines[$i]->product_label .
' - ' :
'');
1808 $descriptions[$tva_tx] .= $langs->trans(
'Qty') .
' : ' . $lines[$i]->qty;
1809 $descriptions[$tva_tx] .=
' - ' . $langs->trans(
'TotalHT') .
' : ' .
price($lines[$i]->total_ht) .
'</li>';
1812 if ($totalamount == 0) {
1813 $amountdeposit[0] = 0;
1816 $amount_ttc_diff = $amountdeposit[0];
1819 foreach ($amountdeposit as $tva => $amount) {
1820 if (empty($amount)) {
1824 $descline =
'(DEPOSIT) ('. $origin->deposit_percent .
'%) - '.$origin->ref;
1827 if (!empty($conf->global->INVOICE_DEPOSIT_VARIABLE_MODE_DETAIL_LINES_IN_DESCRIPTION) && !empty($descriptions[$tva])) {
1828 $descline .=
'<ul>' . $descriptions[$tva] .
'</ul>';
1831 $addlineResult = $deposit->addline(
1838 (empty($conf->global->INVOICE_PRODUCTID_DEPOSIT) ? 0 : $conf->global->INVOICE_PRODUCTID_DEPOSIT),
1858 if ($addlineResult < 0) {
1859 $origin->db->rollback();
1860 $origin->error = $deposit->error;
1861 $origin->errors = $deposit->errors;
1866 $diff = $deposit->total_ttc - $amount_ttc_diff;
1868 if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA) && $diff != 0) {
1869 $deposit->fetch_lines();
1870 $subprice_diff = $deposit->lines[0]->subprice - $diff / (1 + $deposit->lines[0]->tva_tx / 100);
1872 $updatelineResult = $deposit->updateline(
1873 $deposit->lines[0]->id,
1874 $deposit->lines[0]->desc,
1876 $deposit->lines[0]->qty,
1877 $deposit->lines[0]->remise_percent,
1878 $deposit->lines[0]->date_start,
1879 $deposit->lines[0]->date_end,
1880 $deposit->lines[0]->tva_tx,
1884 $deposit->lines[0]->info_bits,
1885 $deposit->lines[0]->product_type,
1889 $deposit->lines[0]->pa_ht,
1890 $deposit->lines[0]->label,
1896 if ($updatelineResult < 0) {
1897 $origin->db->rollback();
1898 $origin->error = $deposit->error;
1899 $origin->errors = $deposit->errors;
1904 $hookmanager->initHooks(array(
'invoicedao'));
1906 $parameters = array(
'objFrom' => $origin);
1907 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $deposit, $action);
1910 $origin->db->rollback();
1911 $origin->error = $hookmanager->error;
1912 $origin->errors = $hookmanager->errors;
1916 if (!empty($autoValidateDeposit)) {
1917 $validateReturn = $deposit->validate($user,
'', 0, $notrigger);
1919 if ($validateReturn < 0) {
1920 $origin->db->rollback();
1921 $origin->error = $deposit->error;
1922 $origin->errors = $deposit->errors;
1927 unset($deposit->context[
'createdepositfromorigin']);
1929 $origin->db->commit();
1943 global $conf, $langs, $mysoc, $user;
1945 $langs->load(
'bills');
1948 $moretitle = $params[
'moretitle'] ??
'';
1949 $picto = $this->picto;
1950 if ($this->
type == self::TYPE_REPLACEMENT) {
1953 if ($this->
type == self::TYPE_CREDIT_NOTE) {
1956 if ($this->
type == self::TYPE_DEPOSIT) {
1960 if ($user->hasRight(
"facture",
"read")) {
1961 $datas[
'picto'] =
img_picto(
'', $picto).
' <u class="paddingrightonly">'.$langs->trans(
"Invoice").
'</u>';
1963 $datas[
'picto'] .=
' '.$this->getLibType(1);
1966 if (!empty($params[
'fromajaxtooltip']) && !isset($this->alreadypaid)) {
1970 if (isset($this->
statut) && isset($this->alreadypaid)) {
1971 $datas[
'picto'] .=
' '.$this->getLibStatut(5, $this->alreadypaid);
1974 $datas[
'picto'] .=
' - '.$moretitle;
1976 if (!empty($this->
ref)) {
1977 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1979 if (!empty($this->ref_customer)) {
1980 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_customer;
1982 if (!empty($this->date)) {
1983 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
1985 if (!empty($this->total_ht)) {
1986 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1988 if (!empty($this->total_tva)) {
1989 $datas[
'amountvat'] =
'<br><b>'.$langs->trans(
'AmountVAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1991 if (!empty($this->revenuestamp) && $this->revenuestamp != 0) {
1992 $datas[
'amountrevenustamp'] =
'<br><b>'.$langs->trans(
'RevenueStamp').
':</b> '.
price($this->revenuestamp, 0, $langs, 0, -1, -1, $conf->currency);
1994 if (!empty($this->total_localtax1) && $this->total_localtax1 != 0) {
1996 $datas[
'amountlt1'] =
'<br><b>'.$langs->transcountry(
'AmountLT1', $mysoc->country_code).
':</b> '.
price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency);
1998 if (!empty($this->total_localtax2) && $this->total_localtax2 != 0) {
1999 $datas[
'amountlt2'] =
'<br><b>'.$langs->transcountry(
'AmountLT2', $mysoc->country_code).
':</b> '.
price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency);
2001 if (!empty($this->total_ttc)) {
2002 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
2023 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $addlinktonotes = 0, $save_lastsearch_value = -1, $target =
'')
2025 global $langs, $conf, $user, $mysoc;
2027 if (!empty($conf->dol_no_mouse_hover)) {
2033 if ($option ==
'withdraw') {
2034 $url = DOL_URL_ROOT.
'/compta/facture/prelevement.php?facid='.$this->id;
2036 $url = DOL_URL_ROOT.
'/compta/facture/card.php?facid='.$this->id;
2039 if (!$user->hasRight(
"facture",
"read")) {
2043 if ($option !==
'nolink') {
2045 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2046 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
2047 $add_save_lastsearch_values = 1;
2049 if ($add_save_lastsearch_values) {
2050 $url .=
'&save_lastsearch_values=1';
2058 $picto = $this->picto;
2059 if ($this->
type == self::TYPE_REPLACEMENT) {
2062 if ($this->
type == self::TYPE_CREDIT_NOTE) {
2065 if ($this->
type == self::TYPE_DEPOSIT) {
2070 'objecttype' => $this->element,
2071 'moretitle' => $moretitle,
2072 'option' => $option,
2074 $classfortooltip =
'classfortooltip';
2077 $classfortooltip =
'classforajaxtooltip';
2078 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
2084 $linkclose = ($target ?
' target="'.$target.
'"' :
'');
2085 if (empty($notooltip) && $user->hasRight(
"facture",
"read")) {
2086 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
2087 $label = $langs->trans(
"Invoice");
2088 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
2090 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
2091 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
2094 $linkstart =
'<a href="'.$url.
'"';
2095 $linkstart .= $linkclose.
'>';
2098 if ($option ==
'nolink') {
2103 $result .= $linkstart;
2105 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
2107 if ($withpicto != 2) {
2108 $result .= ($max ?
dol_trunc($this->
ref, $max) : $this->ref);
2110 $result .= $linkend;
2112 if ($addlinktonotes) {
2113 $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private);
2116 $notetoshow = $langs->trans(
"ViewPrivateNote").
':<br>'.$txttoshow;
2117 $result .=
' <span class="note inline-block">';
2118 $result .=
'<a href="'.DOL_URL_ROOT.
'/compta/facture/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($notetoshow, 1, 1).
'">';
2123 $result .=
'</span>';
2127 global $action, $hookmanager;
2128 $hookmanager->initHooks(array(
'invoicedao'));
2129 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result,
'notooltip' => $notooltip,
'addlinktonotes' => $addlinktonotes,
'save_lastsearch_value'=> $save_lastsearch_value,
'target' => $target);
2130 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
2132 $result = $hookmanager->resPrint;
2134 $result .= $hookmanager->resPrint;
2150 public function fetch($rowid, $ref =
'', $ref_ext =
'', $notused =
'', $fetch_situation =
false)
2152 if (empty($rowid) && empty($ref) && empty($ref_ext)) {
2156 $sql =
'SELECT f.rowid, f.entity, f.ref, f.ref_client, f.ref_ext, f.type, f.fk_soc';
2157 $sql .=
', f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc, f.revenuestamp';
2158 $sql .=
', f.remise_percent, f.remise_absolue, f.remise';
2159 $sql .=
', f.datef as df, f.date_pointoftax';
2160 $sql .=
', f.date_lim_reglement as dlr';
2161 $sql .=
', f.datec as datec';
2162 $sql .=
', f.date_valid as datev';
2163 $sql .=
', f.tms as datem';
2164 $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';
2165 $sql .=
', f.fk_facture_source, f.fk_fac_rec_source';
2166 $sql .=
', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet as fk_project, f.extraparams';
2167 $sql .=
', f.situation_cycle_ref, f.situation_counter, f.situation_final';
2168 $sql .=
', f.fk_account';
2169 $sql .=
", f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc";
2170 $sql .=
', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
2171 $sql .=
', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
2172 $sql .=
', f.fk_incoterms, f.location_incoterms';
2173 $sql .=
', f.module_source, f.pos_source';
2174 $sql .=
", i.libelle as label_incoterms";
2175 $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";
2176 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facture as f';
2177 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
2178 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as p ON f.fk_mode_reglement = p.id';
2179 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON f.fk_incoterms = i.rowid';
2182 $sql .=
" WHERE f.rowid = ".((int) $rowid);
2184 $sql .=
' WHERE f.entity IN ('.getEntity(
'invoice').
')';
2186 $sql .=
" AND f.ref = '".$this->db->escape($ref).
"'";
2189 $sql .=
" AND f.ref_ext = '".$this->db->escape($ref_ext).
"'";
2193 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
2194 $resql = $this->db->query($sql);
2196 if ($this->db->num_rows($resql)) {
2197 $obj = $this->db->fetch_object($resql);
2199 $this->
id = $obj->rowid;
2200 $this->entity = $obj->entity;
2202 $this->
ref = $obj->ref;
2203 $this->ref_client = $obj->ref_client;
2204 $this->ref_customer = $obj->ref_client;
2205 $this->ref_ext = $obj->ref_ext;
2206 $this->
type = $obj->type;
2207 $this->date = $this->db->jdate($obj->df);
2208 $this->date_pointoftax = $this->db->jdate($obj->date_pointoftax);
2209 $this->date_creation = $this->db->jdate($obj->datec);
2210 $this->date_validation = $this->db->jdate($obj->datev);
2211 $this->date_modification = $this->db->jdate($obj->datem);
2212 $this->datem = $this->db->jdate($obj->datem);
2213 $this->remise_percent = $obj->remise_percent;
2214 $this->remise_absolue = $obj->remise_absolue;
2215 $this->total_ht = $obj->total_ht;
2216 $this->total_tva = $obj->total_tva;
2217 $this->total_localtax1 = $obj->localtax1;
2218 $this->total_localtax2 = $obj->localtax2;
2219 $this->total_ttc = $obj->total_ttc;
2220 $this->revenuestamp = $obj->revenuestamp;
2221 $this->paye = $obj->paye;
2222 $this->close_code = $obj->close_code;
2223 $this->close_note = $obj->close_note;
2225 $this->socid = $obj->fk_soc;
2226 $this->thirdparty =
null;
2228 $this->fk_project = $obj->fk_project;
2229 $this->project =
null;
2231 $this->
statut = $obj->fk_statut;
2232 $this->status = $obj->fk_statut;
2234 $this->date_lim_reglement = $this->db->jdate($obj->dlr);
2235 $this->mode_reglement_id = $obj->fk_mode_reglement;
2236 $this->mode_reglement_code = $obj->mode_reglement_code;
2237 $this->mode_reglement = $obj->mode_reglement_libelle;
2238 $this->cond_reglement_id = $obj->fk_cond_reglement;
2239 $this->cond_reglement_code = $obj->cond_reglement_code;
2240 $this->cond_reglement = $obj->cond_reglement_libelle;
2241 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
2242 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
2243 $this->fk_facture_source = $obj->fk_facture_source;
2244 $this->fk_fac_rec_source = $obj->fk_fac_rec_source;
2245 $this->note = $obj->note_private;
2246 $this->note_private = $obj->note_private;
2247 $this->note_public = $obj->note_public;
2248 $this->user_author = $obj->fk_user_author;
2249 $this->user_valid = $obj->fk_user_valid;
2250 $this->user_modification = $obj->fk_user_modif;
2251 $this->fk_user_author = $obj->fk_user_author;
2252 $this->fk_user_valid = $obj->fk_user_valid;
2253 $this->fk_user_modif = $obj->fk_user_modif;
2254 $this->model_pdf = $obj->model_pdf;
2255 $this->modelpdf = $obj->model_pdf;
2256 $this->last_main_doc = $obj->last_main_doc;
2257 $this->situation_cycle_ref = $obj->situation_cycle_ref;
2258 $this->situation_counter = $obj->situation_counter;
2259 $this->situation_final = $obj->situation_final;
2260 $this->retained_warranty = $obj->retained_warranty;
2261 $this->retained_warranty_date_limit = $this->db->jdate($obj->retained_warranty_date_limit);
2262 $this->retained_warranty_fk_cond_reglement = $obj->retained_warranty_fk_cond_reglement;
2264 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
2267 $this->fk_incoterms = $obj->fk_incoterms;
2268 $this->location_incoterms = $obj->location_incoterms;
2269 $this->label_incoterms = $obj->label_incoterms;
2271 $this->module_source = $obj->module_source;
2272 $this->pos_source = $obj->pos_source;
2275 $this->fk_multicurrency = $obj->fk_multicurrency;
2276 $this->multicurrency_code = $obj->multicurrency_code;
2277 $this->multicurrency_tx = $obj->multicurrency_tx;
2278 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
2279 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
2280 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
2282 if (($this->
type == self::TYPE_SITUATION || ($this->
type == self::TYPE_CREDIT_NOTE && $this->situation_cycle_ref > 0)) && $fetch_situation) {
2286 if ($this->status == self::STATUS_DRAFT) {
2287 $this->brouillon = 1;
2295 $this->lines = array();
2299 $this->error = $this->db->error();
2303 $this->db->free($resql);
2307 $this->error =
'Invoice with id='.$rowid.
' or ref='.$ref.
' or ref_ext='.$ref_ext.
' not found';
2309 dol_syslog(__METHOD__.$this->error, LOG_WARNING);
2313 $this->error = $this->db->lasterror();
2328 public function fetch_lines($only_product = 0, $loadalsotranslation = 0)
2331 global $langs, $conf;
2333 $this->lines = array();
2335 $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,';
2336 $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,';
2337 $sql .=
' l.situation_percent, l.fk_prev_id,';
2338 $sql .=
' l.rang, l.special_code,';
2339 $sql .=
' l.date_start as date_start, l.date_end as date_end,';
2340 $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,';
2341 $sql .=
' l.fk_unit,';
2342 $sql .=
' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2343 $sql .=
' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2344 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facturedet as l';
2345 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON l.fk_product = p.rowid';
2346 $sql .=
' WHERE l.fk_facture = '.((int) $this->
id);
2347 $sql .=
' ORDER BY l.rang, l.rowid';
2349 dol_syslog(get_class($this).
'::fetch_lines', LOG_DEBUG);
2350 $result = $this->db->query($sql);
2352 $num = $this->db->num_rows($result);
2355 $objp = $this->db->fetch_object($result);
2358 $line->id = $objp->rowid;
2359 $line->rowid = $objp->rowid;
2360 $line->fk_facture = $objp->fk_facture;
2361 $line->label = $objp->custom_label;
2362 $line->desc = $objp->description;
2363 $line->description = $objp->description;
2364 $line->product_type = $objp->product_type;
2365 $line->ref = $objp->product_ref;
2366 $line->product_ref = $objp->product_ref;
2367 $line->libelle = $objp->product_label;
2368 $line->product_label = $objp->product_label;
2369 $line->product_desc = $objp->product_desc;
2370 $line->fk_product_type = $objp->fk_product_type;
2371 $line->qty = $objp->qty;
2372 $line->subprice = $objp->subprice;
2373 $line->ref_ext = $objp->ref_ext;
2375 $line->vat_src_code = $objp->vat_src_code;
2376 $line->tva_tx = $objp->tva_tx;
2377 $line->localtax1_tx = $objp->localtax1_tx;
2378 $line->localtax2_tx = $objp->localtax2_tx;
2379 $line->localtax1_type = $objp->localtax1_type;
2380 $line->localtax2_type = $objp->localtax2_type;
2381 $line->remise_percent = $objp->remise_percent;
2382 $line->fk_remise_except = $objp->fk_remise_except;
2383 $line->fk_product = $objp->fk_product;
2384 $line->date_start = $this->db->jdate($objp->date_start);
2385 $line->date_end = $this->db->jdate($objp->date_end);
2386 $line->info_bits = $objp->info_bits;
2387 $line->total_ht = $objp->total_ht;
2388 $line->total_tva = $objp->total_tva;
2389 $line->total_localtax1 = $objp->total_localtax1;
2390 $line->total_localtax2 = $objp->total_localtax2;
2391 $line->total_ttc = $objp->total_ttc;
2392 $line->code_ventilation = $objp->fk_code_ventilation;
2393 $line->fk_fournprice = $objp->fk_fournprice;
2394 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
2395 $line->pa_ht = $marginInfos[0];
2396 $line->marge_tx = $marginInfos[1];
2397 $line->marque_tx = $marginInfos[2];
2398 $line->rang = $objp->rang;
2399 $line->special_code = $objp->special_code;
2400 $line->fk_parent_line = $objp->fk_parent_line;
2401 $line->situation_percent = $objp->situation_percent;
2402 $line->fk_prev_id = $objp->fk_prev_id;
2403 $line->fk_unit = $objp->fk_unit;
2406 $line->fk_accounting_account = $objp->fk_code_ventilation;
2409 $line->fk_multicurrency = $objp->fk_multicurrency;
2410 $line->multicurrency_code = $objp->multicurrency_code;
2411 $line->multicurrency_subprice = $objp->multicurrency_subprice;
2412 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
2413 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
2414 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2416 $line->fetch_optionals();
2419 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
2420 $tmpproduct =
new Product($this->db);
2421 $tmpproduct->fetch($objp->fk_product);
2422 $tmpproduct->getMultiLangs();
2424 $line->multilangs = $tmpproduct->multilangs;
2427 $this->lines[$i] = $line;
2431 $this->db->free($result);
2434 $this->error = $this->db->error();
2449 $this->tab_previous_situation_invoice = array();
2450 $this->tab_next_situation_invoice = array();
2452 $sql =
'SELECT rowid, type, situation_cycle_ref, situation_counter FROM '.MAIN_DB_PREFIX.
'facture';
2453 $sql .=
" WHERE rowid <> ".((int) $this->
id);
2454 $sql .=
' AND entity = '.((int) $this->entity);
2455 $sql .=
' AND situation_cycle_ref = '.(int) $this->situation_cycle_ref;
2456 $sql .=
' ORDER BY situation_counter ASC';
2458 dol_syslog(get_class($this).
'::fetchPreviousNextSituationInvoice ', LOG_DEBUG);
2459 $result = $this->db->query($sql);
2460 if ($result && $this->db->num_rows($result) > 0) {
2461 while ($objp = $this->db->fetch_object($result)) {
2462 $invoice =
new Facture($this->db);
2463 if ($invoice->fetch($objp->rowid) > 0) {
2464 if ($objp->situation_counter < $this->situation_counter
2465 || ($objp->situation_counter == $this->situation_counter && $objp->rowid < $this->id)
2467 $this->tab_previous_situation_invoice[] = $invoice;
2469 $this->tab_next_situation_invoice[] = $invoice;
2488 if (empty($this->
type)) {
2491 if (isset($this->
ref)) {
2492 $this->
ref = trim($this->
ref);
2494 if (isset($this->ref_ext)) {
2495 $this->ref_ext = trim($this->ref_ext);
2497 if (isset($this->ref_client)) {
2498 $this->ref_client = trim($this->ref_client);
2500 if (isset($this->increment)) {
2501 $this->increment = trim($this->increment);
2503 if (isset($this->close_code)) {
2504 $this->close_code = trim($this->close_code);
2506 if (isset($this->close_note)) {
2507 $this->close_note = trim($this->close_note);
2509 if (isset($this->note) || isset($this->note_private)) {
2510 $this->note = (isset($this->note) ? trim($this->note) : trim($this->note_private));
2512 if (isset($this->note) || isset($this->note_private)) {
2513 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
2515 if (isset($this->note_public)) {
2516 $this->note_public = trim($this->note_public);
2518 if (isset($this->model_pdf)) {
2519 $this->model_pdf = trim($this->model_pdf);
2521 if (isset($this->import_key)) {
2522 $this->import_key = trim($this->import_key);
2524 if (isset($this->retained_warranty)) {
2525 $this->retained_warranty = floatval($this->retained_warranty);
2527 if (!isset($this->fk_user_author) && isset($this->user_author) ) {
2528 $this->fk_user_author = $this->user_author;
2536 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facture SET";
2537 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
2538 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
2539 $sql .=
" type=".(isset($this->
type) ? $this->db->escape($this->
type) :
"null").
",";
2540 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
2541 $sql .=
" increment=".(isset($this->increment) ?
"'".$this->db->escape($this->increment).
"'" :
"null").
",";
2542 $sql .=
" fk_soc=".(isset($this->socid) ? $this->db->escape($this->socid) :
"null").
",";
2543 $sql .=
" datec=".(strval($this->date_creation) !=
'' ?
"'".$this->db->idate($this->date_creation).
"'" :
'null').
",";
2544 $sql .=
" datef=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
2545 $sql .=
" date_pointoftax=".(strval($this->date_pointoftax) !=
'' ?
"'".$this->db->idate($this->date_pointoftax).
"'" :
'null').
",";
2546 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
2547 $sql .=
" paye=".(isset($this->paye) ? $this->db->escape($this->paye) : 0).
",";
2548 $sql .=
" remise_percent=".(isset($this->remise_percent) ? $this->db->escape($this->remise_percent) :
"null").
",";
2549 $sql .=
" remise_absolue=".(isset($this->remise_absolue) ? $this->db->escape($this->remise_absolue) :
"null").
",";
2550 $sql .=
" close_code=".(isset($this->close_code) ?
"'".$this->db->escape($this->close_code).
"'" :
"null").
",";
2551 $sql .=
" close_note=".(isset($this->close_note) ?
"'".$this->db->escape($this->close_note).
"'" :
"null").
",";
2552 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
2553 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
2554 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
2555 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
2556 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
2557 $sql .=
" revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp !=
'') ? $this->db->escape($this->revenuestamp) :
"null").
",";
2558 $sql .=
" fk_statut=".(isset($this->
statut) ? $this->db->escape($this->
statut) :
"null").
",";
2559 $sql .=
" fk_user_author=".(isset($this->fk_user_author) ? $this->db->escape($this->fk_user_author) :
"null").
",";
2560 $sql .=
" fk_user_valid=".(isset($this->fk_user_valid) ? $this->db->escape($this->fk_user_valid) :
"null").
",";
2561 $sql .=
" fk_facture_source=".(isset($this->fk_facture_source) ? $this->db->escape($this->fk_facture_source) :
"null").
",";
2562 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->db->escape($this->fk_project) :
"null").
",";
2563 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->db->escape($this->cond_reglement_id) :
"null").
",";
2564 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->db->escape($this->mode_reglement_id) :
"null").
",";
2565 $sql .=
" date_lim_reglement=".(strval($this->date_lim_reglement) !=
'' ?
"'".$this->db->idate($this->date_lim_reglement).
"'" :
'null').
",";
2566 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
2567 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
2568 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
2569 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null").
",";
2570 $sql .=
" situation_cycle_ref=".(empty($this->situation_cycle_ref) ?
"null" : $this->db->escape($this->situation_cycle_ref)).
",";
2571 $sql .=
" situation_counter=".(empty($this->situation_counter) ?
"null" : $this->db->escape($this->situation_counter)).
",";
2572 $sql .=
" situation_final=".(empty($this->situation_final) ?
"0" : $this->db->escape($this->situation_final)).
",";
2573 $sql .=
" retained_warranty=".(empty($this->retained_warranty) ?
"0" : $this->db->escape($this->retained_warranty)).
",";
2574 $sql .=
" retained_warranty_date_limit=".(strval($this->retained_warranty_date_limit) !=
'' ?
"'".$this->db->idate($this->retained_warranty_date_limit).
"'" :
'null').
",";
2575 $sql .=
" retained_warranty_fk_cond_reglement=".(isset($this->retained_warranty_fk_cond_reglement) ?intval($this->retained_warranty_fk_cond_reglement) :
"null");
2576 $sql .=
" WHERE rowid=".((int) $this->
id);
2580 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
2581 $resql = $this->db->query($sql);
2584 $this->errors[] =
"Error ".$this->db->lasterror();
2594 if (!$error && !$notrigger) {
2605 foreach ($this->errors as $errmsg) {
2606 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2607 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2609 $this->db->rollback();
2612 $this->db->commit();
2628 global $conf, $langs;
2630 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
2631 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
2636 $result = $remise->fetch($idremise);
2639 if ($remise->fk_facture) {
2640 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
2641 $this->db->rollback();
2646 $facligne->fk_facture = $this->id;
2647 $facligne->fk_remise_except = $remise->id;
2648 $facligne->desc = $remise->description;
2649 $facligne->vat_src_code = $remise->vat_src_code;
2650 $facligne->tva_tx = $remise->tva_tx;
2651 $facligne->subprice = -$remise->amount_ht;
2652 $facligne->fk_product = 0;
2654 $facligne->remise_percent = 0;
2655 $facligne->rang = -1;
2656 $facligne->info_bits = 2;
2658 if (!empty($conf->global->MAIN_ADD_LINE_AT_POSITION)) {
2659 $facligne->rang = 1;
2660 $linecount = count($this->lines);
2661 for ($ii = 1; $ii <= $linecount; $ii++) {
2667 if ($remise->fk_facture_source > 0) {
2668 $srcinvoice =
new Facture($this->db);
2669 $srcinvoice->fetch($remise->fk_facture_source);
2670 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmargin.class.php';
2672 $arraytmp = $formmargin->getMarginInfosArray($srcinvoice,
false);
2673 $facligne->pa_ht = $arraytmp[
'pa_total'];
2676 $facligne->total_ht = -$remise->amount_ht;
2677 $facligne->total_tva = -$remise->amount_tva;
2678 $facligne->total_ttc = -$remise->amount_ttc;
2680 $facligne->multicurrency_subprice = -$remise->multicurrency_subprice;
2681 $facligne->multicurrency_total_ht = -$remise->multicurrency_amount_ht;
2682 $facligne->multicurrency_total_tva = -$remise->multicurrency_amount_tva;
2683 $facligne->multicurrency_total_ttc = -$remise->multicurrency_amount_ttc;
2685 $lineid = $facligne->insert();
2690 $result = $remise->link_to_invoice($lineid, 0);
2692 $this->error = $remise->error;
2693 $this->db->rollback();
2697 $this->db->commit();
2700 $this->error = $facligne->error;
2701 $this->db->rollback();
2705 $this->error = $facligne->error;
2706 $this->db->rollback();
2710 $this->db->rollback();
2732 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
2733 if (empty($ref_client)) {
2734 $sql .=
' SET ref_client = NULL';
2736 $sql .=
' SET ref_client = \''.$this->db->escape($ref_client).
'\'';
2738 $sql .=
" WHERE rowid = ".((int) $this->
id);
2740 dol_syslog(__METHOD__.
' this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2741 $resql = $this->db->query($sql);
2743 $this->errors[] = $this->db->error();
2748 $this->ref_client = $ref_client;
2751 if (!$notrigger && empty($error)) {
2761 $this->ref_client = $ref_client;
2763 $this->db->commit();
2766 foreach ($this->errors as $errmsg) {
2767 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2768 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2770 $this->db->rollback();
2783 public function delete($user, $notrigger = 0, $idwarehouse = -1)
2785 global $langs, $conf;
2786 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2790 dol_syslog(get_class($this).
"::delete rowid=".$rowid.
", ref=".$this->ref.
", thirdparty=".(empty($this->thirdparty) ?
'' : $this->thirdparty->name), LOG_DEBUG);
2803 if (!$error && !$notrigger) {
2817 dol_syslog(get_class($this).
"::delete error deleteExtraFields ".$this->error, LOG_ERR);
2831 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'societe_remise_except';
2832 $sql .=
' WHERE fk_facture_source = '.((int) $rowid);
2833 $sql .=
' AND fk_facture_line IS NULL';
2834 $resql = $this->db->query($sql);
2838 $list_rowid_det = array();
2839 foreach ($this->lines as $key => $invoiceline) {
2840 $list_rowid_det[] = $invoiceline->id;
2844 if (count($list_rowid_det)) {
2845 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
2846 $sql .=
' SET fk_facture = NULL, fk_facture_line = NULL';
2847 $sql .=
' WHERE fk_facture_line IN ('.$this->db->sanitize(join(
',', $list_rowid_det)).
')';
2849 if (!$this->db->query($sql)) {
2850 $this->error = $this->db->error().
" sql=".$sql;
2851 $this->errors[] = $this->error;
2852 $this->db->rollback();
2859 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'eventorganization_conferenceorboothattendee';
2860 $sql .=
' SET fk_invoice = NULL';
2861 $sql .=
' WHERE fk_invoice = '.((int) $rowid);
2863 if (!$this->db->query($sql)) {
2864 $this->error = $this->db->error().
" sql=".$sql;
2865 $this->errors[] = $this->error;
2866 $this->db->rollback();
2870 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'element_time';
2871 $sql .=
' SET invoice_id = NULL, invoice_line_id = NULL';
2872 $sql .=
' WHERE invoice_id = '.((int) $rowid);
2874 if (!$this->db->query($sql)) {
2875 $this->error = $this->db->error().
" sql=".$sql;
2876 $this->errors[] = $this->error;
2877 $this->db->rollback();
2882 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse != -1) {
2883 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
2884 $langs->load(
"agenda");
2886 $num = count($this->lines);
2887 for ($i = 0; $i < $num; $i++) {
2888 if ($this->lines[$i]->fk_product > 0) {
2890 $mouvP->origin = &$this;
2891 $mouvP->setOrigin($this->element, $this->
id);
2893 if ($this->
type == self::TYPE_CREDIT_NOTE) {
2894 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceDeleteDolibarr", $this->ref));
2896 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceDeleteDolibarr", $this->ref));
2903 $main = MAIN_DB_PREFIX.
'facturedet';
2904 $ef = $main.
"_extrafields";
2905 $sqlef =
"DELETE FROM ".$ef.
" WHERE fk_object IN (SELECT rowid FROM ".$main.
" WHERE fk_facture = ".((int) $rowid).
")";
2907 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'facturedet WHERE fk_facture = '.((int) $rowid);
2910 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'facture WHERE rowid = '.((int) $rowid);
2912 $resql = $this->db->query($sql);
2919 if ($conf->facture->dir_output && !empty($this->
ref)) {
2920 $dir = $conf->facture->dir_output.
"/".$ref;
2921 $file = $conf->facture->dir_output.
"/".$ref.
"/".$ref.
".pdf";
2922 if (file_exists($file)) {
2926 $langs->load(
"errors");
2927 $this->error = $langs->trans(
"ErrorFailToDeleteFile", $file);
2928 $this->errors[] = $this->error;
2929 $this->db->rollback();
2933 if (file_exists($dir)) {
2935 $langs->load(
"errors");
2936 $this->error = $langs->trans(
"ErrorFailToDeleteDir", $dir);
2937 $this->errors[] = $this->error;
2938 $this->db->rollback();
2944 $this->db->commit();
2947 $this->error = $this->db->lasterror().
" sql=".$sql;
2948 $this->errors[] = $this->error;
2949 $this->db->rollback();
2953 $this->error = $this->db->lasterror().
" sql=".$sql;
2954 $this->errors[] = $this->error;
2955 $this->db->rollback();
2959 $this->db->rollback();
2976 public function set_paid($user, $close_code =
'', $close_note =
'')
2979 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
2980 return $this->
setPaid($user, $close_code, $close_note);
2992 public function setPaid($user, $close_code =
'', $close_note =
'')
2996 if ($this->paye != 1) {
3001 dol_syslog(get_class($this).
"::setPaid rowid=".((
int) $this->
id), LOG_DEBUG);
3003 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET';
3004 $sql .=
' fk_statut='.self::STATUS_CLOSED;
3009 $sql .=
", close_code='".$this->db->escape($close_code).
"'";
3012 $sql .=
", close_note='".$this->db->escape($close_note).
"'";
3014 $sql .=
', fk_user_closing = '.((int) $user->id);
3015 $sql .=
", date_closing = '".$this->db->idate($now).
"'";
3016 $sql .=
" WHERE rowid = ".((int) $this->
id);
3018 $resql = $this->db->query($sql);
3028 $this->error = $this->db->lasterror();
3032 $this->db->commit();
3035 $this->db->rollback();
3058 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
3076 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
3077 $sql .=
' SET paye=0, fk_statut='.self::STATUS_VALIDATED.
', close_code=null, close_note=null,';
3078 $sql .=
' date_closing=null,';
3079 $sql .=
' fk_user_closing=null';
3080 $sql .=
" WHERE rowid = ".((int) $this->
id);
3082 dol_syslog(get_class($this).
"::setUnpaid", LOG_DEBUG);
3083 $resql = $this->db->query($sql);
3093 $this->error = $this->db->error();
3098 $this->db->commit();
3101 $this->db->rollback();
3123 dol_syslog(get_class($this).
"::set_canceled is deprecated, use setCanceled instead", LOG_NOTICE);
3124 return $this->
setCanceled($user, $close_code, $close_note);
3137 public function setCanceled($user, $close_code =
'', $close_note =
'')
3139 dol_syslog(get_class($this).
"::setCanceled rowid=".((
int) $this->
id), LOG_DEBUG);
3143 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET';
3144 $sql .=
' fk_statut='.self::STATUS_ABANDONED;
3146 $sql .=
", close_code='".$this->db->escape($close_code).
"'";
3149 $sql .=
", close_note='".$this->db->escape($close_note).
"'";
3151 $sql .=
" WHERE rowid = ".((int) $this->
id);
3153 $resql = $this->db->query($sql);
3157 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
3158 $sql .=
' SET fk_facture = NULL';
3159 $sql .=
' WHERE fk_facture = '.((int) $this->
id);
3161 $resql = $this->db->query($sql);
3166 $this->db->rollback();
3171 $this->db->commit();
3174 $this->error = $this->db->error().
" sql=".$sql;
3175 $this->db->rollback();
3179 $this->error = $this->db->error().
" sql=".$sql;
3180 $this->db->rollback();
3196 public function validate($user, $force_number =
'', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0)
3198 global $conf, $langs, $mysoc;
3199 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3201 $productStatic =
null;
3202 $warehouseStatic =
null;
3203 if ($batch_rule > 0) {
3204 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
3205 require_once DOL_DOCUMENT_ROOT.
'/product/class/productbatch.class.php';
3206 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
3207 $productStatic =
new Product($this->db);
3208 $warehouseStatic =
new Entrepot($this->db);
3215 dol_syslog(get_class($this).
'::validate user='.$user->id.
', force_number='.$force_number.
', idwarehouse='.$idwarehouse);
3222 if ($this->
statut != self::STATUS_DRAFT) {
3223 dol_syslog(get_class($this).
"::validate status is not draft. operation canceled.", LOG_WARNING);
3226 if (count($this->lines) <= 0) {
3227 $langs->load(
"errors");
3228 $this->error = $langs->trans(
"ErrorObjectMustHaveLinesToBeValidated", $this->
ref);
3231 if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->creer))
3232 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->invoice_advance->validate))) {
3233 $this->error =
'Permission denied';
3234 dol_syslog(get_class($this).
"::validate ".$this->error.
' MAIN_USE_ADVANCED_PERMS='.$conf->global->MAIN_USE_ADVANCED_PERMS, LOG_ERR);
3237 if ((preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) &&
3238 !empty($conf->global->FAC_FORCE_DATE_VALIDATION)
3243 if (!empty($conf->global-> INVOICE_CHECK_POSTERIOR_DATE)) {
3245 if (!$last_of_type[0]) {
3246 $this->error = $langs->transnoentities(
"ErrorInvoiceIsNotLastOfSameType", $this->
ref,
dol_print_date($this->date,
'day'),
dol_print_date($last_of_type[1],
'day'));
3252 if (!empty($this->thirdparty) && is_object($this->thirdparty)) {
3253 $array_to_check = array(
'IDPROF1',
'IDPROF2',
'IDPROF3',
'IDPROF4',
'IDPROF5',
'IDPROF6',
'EMAIL',
'ACCOUNTANCY_CODE_CUSTOMER');
3254 foreach ($array_to_check as $key) {
3255 $keymin = strtolower($key);
3256 if (!property_exists($this->thirdparty, $keymin)) {
3259 $vallabel = $this->thirdparty->$keymin;
3261 $i = (int) preg_replace(
'/[^0-9]/',
'', $key);
3263 if ($this->thirdparty->isACompany()) {
3265 if ($mysoc->country_id > 0 && $this->thirdparty->country_id == $mysoc->country_id) {
3266 $idprof_mandatory =
'SOCIETE_'.$key.
'_INVOICE_MANDATORY';
3267 if (!$vallabel && !empty($conf->global->$idprof_mandatory)) {
3268 $langs->load(
"errors");
3269 $this->error = $langs->trans(
'ErrorProdIdIsMandatory', $langs->transcountry(
'ProfId'.$i, $this->thirdparty->country_code)).
' ('.$langs->trans(
"ForbiddenBySetupRules").
') ['.$langs->trans(
'Company').
' : '.$this->thirdparty->name.
']';
3270 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3276 if ($key ==
'EMAIL') {
3278 if (!empty($conf->global->SOCIETE_EMAIL_INVOICE_MANDATORY) && !isValidEMail($this->thirdparty->email)) {
3279 $langs->load(
"errors");
3280 $this->error = $langs->trans(
"ErrorBadEMail", $this->thirdparty->email).
' ('.$langs->trans(
"ForbiddenBySetupRules").
') ['.$langs->trans(
'Company').
' : '.$this->thirdparty->name.
']';
3281 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3285 if ($key ==
'ACCOUNTANCY_CODE_CUSTOMER') {
3287 if (!empty($conf->global->SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_INVOICE_MANDATORY) && empty($this->thirdparty->code_compta)) {
3288 $langs->load(
"errors");
3289 $this->error = $langs->trans(
"ErrorAccountancyCodeCustomerIsMandatory", $this->thirdparty->name).
' ('.$langs->trans(
"ForbiddenBySetupRules").
')';
3290 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3299 $array_to_check = array(
'REF_CLIENT'=>
'RefCustomer');
3300 foreach ($array_to_check as $key => $val) {
3301 $keymin = strtolower($key);
3302 $vallabel = $this->$keymin;
3305 $keymandatory =
'INVOICE_'.$key.
'_MANDATORY_FOR_VALIDATION';
3306 if (!$vallabel && !empty($conf->global->$keymandatory)) {
3307 $langs->load(
"errors");
3309 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv($val)),
null,
'errors');
3316 if ($this->
type == self::TYPE_REPLACEMENT) {
3318 if ($this->fk_facture_source <= 0) {
3319 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"InvoiceReplacement"));
3320 $this->db->rollback();
3325 $facreplaced =
new Facture($this->db);
3326 $result = $facreplaced->fetch($this->fk_facture_source);
3328 $this->error = $langs->trans(
"ErrorBadInvoice");
3329 $this->db->rollback();
3334 $idreplacement = $facreplaced->getIdReplacingInvoice(
'validated');
3335 if ($idreplacement && $idreplacement != $this->
id) {
3336 $facreplacement =
new Facture($this->db);
3337 $facreplacement->fetch($idreplacement);
3338 $this->error = $langs->trans(
"ErrorInvoiceAlreadyReplaced", $facreplaced->ref, $facreplacement->ref);
3339 $this->db->rollback();
3343 $result = $facreplaced->setCanceled($user, self::CLOSECODE_REPLACED,
'');
3345 $this->error = $facreplaced->error;
3346 $this->db->rollback();
3352 if ($force_number) {
3353 $num = $force_number;
3354 } elseif (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
3366 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
3367 $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).
"'";
3368 if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
3369 $sql .=
", datef='".$this->db->idate($this->date).
"'";
3370 $sql .=
", date_lim_reglement='".$this->db->idate($this->date_lim_reglement).
"'";
3372 $sql .=
" WHERE rowid = ".((int) $this->
id);
3374 dol_syslog(get_class($this).
"::validate", LOG_DEBUG);
3375 $resql = $this->db->query($sql);
3382 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref))) {
3388 $result = $this->thirdparty->set_as_client();
3391 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse > 0) {
3392 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
3393 $langs->load(
"agenda");
3396 $cpt = count($this->lines);
3397 for ($i = 0; $i < $cpt; $i++) {
3398 if ($this->lines[$i]->fk_product > 0) {
3400 $mouvP->origin = &$this;
3401 $mouvP->setOrigin($this->element, $this->
id);
3403 if ($this->
type == self::TYPE_CREDIT_NOTE) {
3404 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceValidatedInDolibarr", $num));
3407 $this->error = $mouvP->error;
3410 $is_batch_line =
false;
3411 if ($batch_rule > 0) {
3412 $productStatic->fetch($this->lines[$i]->fk_product);
3413 if ($productStatic->hasbatch()) {
3414 $is_batch_line =
true;
3415 $product_qty_remain = $this->lines[$i]->qty;
3421 $sortfield =
'pl.sellby,pl.eatby,pb.qty,pl.rowid';
3422 $sortorder =
'ASC,ASC,ASC,ASC';
3425 $resBatchList = $productbatch->findAllForProduct($productStatic->id, $idwarehouse, (
getDolGlobalInt(
'STOCK_ALLOW_NEGATIVE_TRANSFER') ?
null : 0), $sortfield, $sortorder);
3426 if (!is_array($resBatchList)) {
3428 $this->error = $this->db->lasterror();
3432 $batchList = $resBatchList;
3433 if (empty($batchList)) {
3435 $langs->load(
'errors');
3436 $warehouseStatic->fetch($idwarehouse);
3437 $this->error = $langs->trans(
'ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
3438 dol_syslog(__METHOD__.
' Error: '.$langs->transnoentitiesnoconv(
'ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
3441 foreach ($batchList as $batch) {
3442 if ($batch->qty <= 0) {
3447 if ($batch->qty >= $product_qty_remain) {
3448 $product_batch_qty = $product_qty_remain;
3451 $product_batch_qty = $batch->qty;
3453 $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_batch_qty, $this->lines[$i]->subprice, $langs->trans(
'InvoiceValidatedInDolibarr', $num),
'',
'',
'', $batch->batch);
3456 $this->error = $mouvP->error;
3457 $this->errors = $mouvP->errors;
3461 $product_qty_remain -= $product_batch_qty;
3463 if ($product_qty_remain <= 0) {
3468 if (!$error && $product_qty_remain > 0) {
3471 $batch = $batchList[0];
3472 $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans(
'InvoiceValidatedInDolibarr', $num),
'',
'',
'', $batch->batch);
3475 $this->error = $mouvP->error;
3476 $this->errors = $mouvP->errors;
3480 $langs->load(
'errors');
3481 $warehouseStatic->fetch($idwarehouse);
3482 $this->error = $langs->trans(
'ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
3483 dol_syslog(__METHOD__.
' Error: '.$langs->transnoentitiesnoconv(
'ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
3490 if (!$is_batch_line) {
3491 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceValidatedInDolibarr", $num));
3494 $this->error = $mouvP->error;
3495 $this->errors = $mouvP->errors;
3508 if (!$error && $this->
type == self::TYPE_CREDIT_NOTE && $this->fk_facture_source > 0) {
3509 $invoice_situation =
new Facture($this->db);
3510 $result = $invoice_situation->fetch($this->fk_facture_source);
3511 if ($result > 0 && $invoice_situation->type == self::TYPE_SITUATION && $invoice_situation->situation_final == 1) {
3512 $invoice_situation->situation_final = 0;
3514 $result = $invoice_situation->setFinal($user, 1);
3517 $this->error = $invoice_situation->error;
3518 $this->errors = $invoice_situation->errors;
3524 if (!$error && !$notrigger) {
3534 $this->oldref = $this->ref;
3537 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
3539 $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).
"'";
3540 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'facture/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
3541 $resql = $this->db->query($sql);
3544 $this->error = $this->db->lasterror();
3546 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'facture/".$this->db->escape($this->newref).
"'";
3547 $sql .=
" WHERE filepath = 'facture/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
3548 $resql = $this->db->query($sql);
3550 $error++; $this->error = $this->db->lasterror();
3556 $dirsource = $conf->facture->dir_output.
'/'.$oldref;
3557 $dirdest = $conf->facture->dir_output.
'/'.$newref;
3558 if (!$error && file_exists($dirsource)) {
3559 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
3561 if (@rename($dirsource, $dirdest)) {
3564 $listoffiles =
dol_dir_list($conf->facture->dir_output.
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
3565 foreach ($listoffiles as $fileentry) {
3566 $dirsource = $fileentry[
'name'];
3567 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
3568 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
3569 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
3570 @rename($dirsource, $dirdest);
3588 $this->brouillon = 0;
3589 $this->date_validation = $now;
3592 if (!empty($conf->global->INVOICE_USE_SITUATION)) {
3594 $nboflines = count($this->lines);
3595 while (($i < $nboflines) && $final) {
3596 $final = ($this->lines[$i]->situation_percent == 100);
3600 if (empty($final)) {
3601 $this->situation_final = 0;
3603 $this->situation_final = 1;
3614 $this->db->commit();
3617 $this->db->rollback();
3630 foreach ($this->tab_next_situation_invoice as $next_invoice) {
3631 $is_last = $next_invoice->is_last_in_cycle();
3633 if ($next_invoice->statut == self::STATUS_DRAFT && $is_last != 1) {
3634 $this->error = $langs->trans(
'updatePriceNextInvoiceErrorUpdateline', $next_invoice->ref);
3638 $next_invoice->brouillon = 1;
3640 foreach ($next_invoice->lines as $line) {
3641 $result = $next_invoice->updateline(
3646 $line->remise_percent,
3650 $line->localtax1_tx,
3651 $line->localtax2_tx,
3654 $line->product_type,
3655 $line->fk_parent_line,
3657 $line->fk_fournprice,
3660 $line->special_code,
3661 $line->array_options,
3662 $line->situation_percent,
3667 $this->error = $langs->trans(
'updatePriceNextInvoiceErrorUpdateline', $next_invoice->ref);
3688 global $conf, $langs;
3692 if ($this->
statut == self::STATUS_DRAFT) {
3693 dol_syslog(__METHOD__.
" already draft status", LOG_WARNING);
3701 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facture";
3702 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
3703 $sql .=
" WHERE rowid = ".((int) $this->
id);
3705 $result = $this->db->query($sql);
3708 $this->oldcopy = clone $this;
3712 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
3713 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
3714 $langs->load(
"agenda");
3716 $num = count($this->lines);
3717 for ($i = 0; $i < $num; $i++) {
3718 if ($this->lines[$i]->fk_product > 0) {
3720 $mouvP->origin = &$this;
3721 $mouvP->setOrigin($this->element, $this->
id);
3723 if ($this->
type == self::TYPE_CREDIT_NOTE) {
3724 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceBackToDraftInDolibarr", $this->ref));
3726 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceBackToDraftInDolibarr", $this->ref));
3733 $old_statut = $this->statut;
3734 $this->brouillon = 1;
3739 $result = $this->
call_trigger(
'BILL_UNVALIDATE', $user);
3742 $this->
statut = $old_statut;
3743 $this->status = $old_statut;
3744 $this->brouillon = 0;
3748 $this->db->rollback();
3753 $this->db->commit();
3756 $this->db->rollback();
3760 $this->error = $this->db->error();
3761 $this->db->rollback();
3821 $fk_remise_except =
'',
3822 $price_base_type =
'HT',
3829 $fk_parent_line = 0,
3830 $fk_fournprice =
null,
3834 $situation_percent = 100,
3839 $noupdateafterinsertline = 0
3843 dol_syslog(__METHOD__.
": using line label is deprecated", LOG_WARNING);
3847 global $mysoc, $conf, $langs;
3849 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);
3851 if ($this->
statut == self::STATUS_DRAFT) {
3852 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
3861 if (empty($info_bits)) {
3867 if (empty($ventil)) {
3870 if (empty($txtva)) {
3873 if (empty($txlocaltax1)) {
3876 if (empty($txlocaltax2)) {
3879 if (empty($fk_parent_line) || $fk_parent_line < 0) {
3880 $fk_parent_line = 0;
3882 if (empty($fk_prev_id)) {
3883 $fk_prev_id =
'null';
3885 if (!isset($situation_percent) || $situation_percent > 100 || (
string) $situation_percent ==
'') {
3886 $situation_percent = 100;
3888 if (empty($ref_ext)) {
3895 $pu_ht_devise =
price2num($pu_ht_devise);
3898 if (!preg_match(
'/\((.*)\)/', $txtva)) {
3904 if ($price_base_type ==
'HT') {
3915 if ($date_start && $date_end && $date_start > $date_end) {
3916 $langs->load(
"errors");
3917 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
3923 $product_type = $type;
3924 if (!empty($fk_product) && $fk_product > 0) {
3925 $product =
new Product($this->db);
3926 $result = $product->fetch($fk_product);
3927 $product_type = $product->type;
3929 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) {
3930 $langs->load(
"errors");
3931 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref);
3932 $this->db->rollback();
3942 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
3943 $vat_src_code = $reg[1];
3944 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
3952 $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);
3954 $total_ht = $tabprice[0];
3955 $total_tva = $tabprice[1];
3956 $total_ttc = $tabprice[2];
3957 $total_localtax1 = $tabprice[9];
3958 $total_localtax2 = $tabprice[10];
3959 $pu_ht = $tabprice[3];
3962 $multicurrency_total_ht = $tabprice[16];
3963 $multicurrency_total_tva = $tabprice[17];
3964 $multicurrency_total_ttc = $tabprice[18];
3965 $pu_ht_devise = $tabprice[19];
3969 if ($ranktouse == -1) {
3970 $rangmax = $this->
line_max($fk_parent_line);
3971 $ranktouse = $rangmax + 1;
3977 $this->line->context = $this->context;
3979 $this->line->fk_facture = $this->id;
3980 $this->line->label = $label;
3981 $this->line->desc = $desc;
3982 $this->line->ref_ext = $ref_ext;
3984 $this->line->qty = ($this->
type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty);
3985 $this->line->subprice = ($this->
type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht);
3987 $this->line->vat_src_code = $vat_src_code;
3988 $this->line->tva_tx = $txtva;
3989 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
3990 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
3991 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
3992 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
3994 $this->line->total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht);
3995 $this->line->total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc);
3996 $this->line->total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_tva) : $total_tva);
3997 $this->line->total_localtax1 = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax1) : $total_localtax1);
3998 $this->line->total_localtax2 = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax2) : $total_localtax2);
4000 $this->line->fk_product = $fk_product;
4001 $this->line->product_type = $product_type;
4003 $this->line->date_start = $date_start;
4004 $this->line->date_end = $date_end;
4005 $this->line->ventil = $ventil;
4006 $this->line->rang = $ranktouse;
4007 $this->line->info_bits = $info_bits;
4008 $this->line->fk_remise_except = $fk_remise_except;
4010 $this->line->special_code = $special_code;
4011 $this->line->fk_parent_line = $fk_parent_line;
4012 $this->line->origin = $origin;
4013 $this->line->origin_id = $origin_id;
4014 $this->line->situation_percent = $situation_percent;
4015 $this->line->fk_prev_id = $fk_prev_id;
4016 $this->line->fk_unit = $fk_unit;
4019 $this->line->fk_fournprice = $fk_fournprice;
4020 $this->line->pa_ht = $pa_ht;
4023 $this->line->fk_multicurrency = $this->fk_multicurrency;
4024 $this->line->multicurrency_code = $this->multicurrency_code;
4025 $this->line->multicurrency_subprice = ($this->
type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht_devise) : $pu_ht_devise);
4027 $this->line->multicurrency_total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ht) : $multicurrency_total_ht);
4028 $this->line->multicurrency_total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_tva) : $multicurrency_total_tva);
4029 $this->line->multicurrency_total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ttc) : $multicurrency_total_ttc);
4031 if (is_array($array_options) && count($array_options) > 0) {
4032 $this->line->array_options = $array_options;
4035 $result = $this->line->insert();
4038 if (!empty($fk_parent_line)) {
4040 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
4041 $linecount = count($this->lines);
4042 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
4048 if (empty($noupdateafterinsertline)) {
4053 $this->db->commit();
4054 return $this->line->id;
4056 $this->error = $this->db->lasterror();
4057 $this->db->rollback();
4061 $this->error = $this->line->error;
4062 $this->errors = $this->line->errors;
4063 $this->db->rollback();
4067 $this->errors[]=
'status of invoice must be Draft to allow use of ->addline()';
4068 dol_syslog(get_class($this).
"::addline status of invoice must be Draft to allow use of ->addline()", LOG_ERR);
4104 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)
4106 global $conf, $user;
4109 dol_syslog(__METHOD__.
": using line label is deprecated", LOG_WARNING);
4112 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
4114 global $mysoc, $langs;
4116 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);
4118 if ($this->
statut == self::STATUS_DRAFT) {
4121 if (!$this->error) {
4122 $this->error = $langs->trans(
'invoiceLineProgressError');
4128 if ($date_start && $date_end && $date_start > $date_end) {
4129 $langs->load(
"errors");
4130 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
4140 if (empty($fk_parent_line) || $fk_parent_line < 0) {
4141 $fk_parent_line = 0;
4143 if (empty($special_code) || $special_code == 3) {
4146 if (!isset($situation_percent) || $situation_percent > 100 || (
string) $situation_percent ==
'') {
4147 $situation_percent = 100;
4149 if (empty($ref_ext)) {
4156 $pu_ht_devise =
price2num($pu_ht_devise);
4158 if (!preg_match(
'/\((.*)\)/', $txtva)) {
4178 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
4179 $vat_src_code = $reg[1];
4180 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
4183 $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);
4185 $total_ht = $tabprice[0];
4186 $total_tva = $tabprice[1];
4187 $total_ttc = $tabprice[2];
4188 $total_localtax1 = $tabprice[9];
4189 $total_localtax2 = $tabprice[10];
4190 $pu_ht = $tabprice[3];
4191 $pu_tva = $tabprice[4];
4192 $pu_ttc = $tabprice[5];
4195 $multicurrency_total_ht = $tabprice[16];
4196 $multicurrency_total_tva = $tabprice[17];
4197 $multicurrency_total_ttc = $tabprice[18];
4198 $pu_ht_devise = $tabprice[19];
4205 $price = ($pu - $remise);
4211 $line->fetch($rowid);
4212 $line->fetch_optionals();
4214 if (!empty($line->fk_product)) {
4215 $product =
new Product($this->db);
4216 $result = $product->fetch($line->fk_product);
4217 $product_type = $product->type;
4219 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) {
4220 $langs->load(
"errors");
4221 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref);
4222 $this->db->rollback();
4227 $staticline = clone $line;
4229 $line->oldline = $staticline;
4230 $this->line = $line;
4231 $this->line->context = $this->context;
4232 $this->line->rang = $rang;
4235 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
4236 $rangmax = $this->
line_max($fk_parent_line);
4237 $this->line->rang = $rangmax + 1;
4239 $apply_abs_price_on_credit_note=
false;
4241 $apply_abs_price_on_credit_note =
true;
4245 $this->line->id = $rowid;
4246 $this->line->rowid = $rowid;
4247 $this->line->label = $label;
4248 $this->line->desc = $desc;
4249 $this->line->ref_ext = $ref_ext;
4250 $this->line->qty = ($this->
type == self::TYPE_CREDIT_NOTE ?abs($qty) : $qty);
4252 $this->line->vat_src_code = $vat_src_code;
4253 $this->line->tva_tx = $txtva;
4254 $this->line->localtax1_tx = $txlocaltax1;
4255 $this->line->localtax2_tx = $txlocaltax2;
4256 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
4257 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
4260 $this->line->subprice = ($apply_abs_price_on_credit_note?-abs($pu_ht) : $pu_ht);
4261 $this->line->date_start = $date_start;
4262 $this->line->date_end = $date_end;
4263 $this->line->total_ht = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_ht) : $total_ht);
4264 $this->line->total_tva = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_tva) : $total_tva);
4265 $this->line->total_localtax1 = $total_localtax1;
4266 $this->line->total_localtax2 = $total_localtax2;
4267 $this->line->total_ttc = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_ttc) : $total_ttc);
4268 $this->line->info_bits = $info_bits;
4269 $this->line->special_code = $special_code;
4270 $this->line->product_type = $type;
4271 $this->line->fk_parent_line = $fk_parent_line;
4272 $this->line->skip_update_total = $skip_update_total;
4273 $this->line->situation_percent = $situation_percent;
4274 $this->line->fk_unit = $fk_unit;
4276 $this->line->fk_fournprice = $fk_fournprice;
4277 $this->line->pa_ht = $pa_ht;
4280 $this->line->multicurrency_subprice = ($this->
type == self::TYPE_CREDIT_NOTE ?-abs($pu_ht_devise) : $pu_ht_devise);
4281 $this->line->multicurrency_total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_ht) : $multicurrency_total_ht);
4282 $this->line->multicurrency_total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_tva) : $multicurrency_total_tva);
4283 $this->line->multicurrency_total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_ttc) : $multicurrency_total_ttc);
4285 if (is_array($array_options) && count($array_options) > 0) {
4287 foreach ($array_options as $key => $value) {
4288 $this->line->array_options[$key] = $array_options[$key];
4292 $result = $this->line->update($user, $notrigger);
4295 if (!empty($fk_parent_line)) {
4301 $this->db->commit();
4304 $this->error = $this->line->error;
4305 $this->db->rollback();
4309 $this->error =
"Invoice statut makes operation forbidden";
4323 $sql =
'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.
'facturedet fd
4324 INNER JOIN '.MAIN_DB_PREFIX.
'facture f ON (fd.fk_facture = f.rowid)
4325 WHERE fd.fk_prev_id = '.((int) $idline).
' AND f.fk_statut <> 0';
4327 $result = $this->db->query($sql);
4329 $this->error = $this->db->error();
4333 $obj = $this->db->fetch_object($result);
4335 if ($obj ===
null) {
4338 return ($situation_percent < $obj->situation_percent);
4354 global $mysoc, $user;
4357 if (($line->info_bits & 2) == 2) {
4361 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
4364 if ($percent > 100) {
4367 $line->situation_percent = $percent;
4368 $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);
4369 $line->total_ht = $tabprice[0];
4370 $line->total_tva = $tabprice[1];
4371 $line->total_ttc = $tabprice[2];
4372 $line->total_localtax1 = $tabprice[9];
4373 $line->total_localtax2 = $tabprice[10];
4374 $line->multicurrency_total_ht = $tabprice[16];
4375 $line->multicurrency_total_tva = $tabprice[17];
4376 $line->multicurrency_total_ttc = $tabprice[18];
4377 $line->update($user);
4380 if ($update_price) {
4396 dol_syslog(get_class($this).
"::deleteline rowid=".((
int) $rowid), LOG_DEBUG);
4398 if ($this->
statut != self::STATUS_DRAFT) {
4399 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
4405 $line->context = $this->context;
4408 $result = $line->fetch($rowid);
4409 if (!($result > 0)) {
4414 if ($id > 0 && $line->fk_facture != $id) {
4415 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
4422 $staticline = clone $line;
4423 $line->oldline = $staticline;
4425 if ($line->delete($user) > 0) {
4429 $this->db->commit();
4432 $this->db->rollback();
4433 $this->error = $this->db->lasterror();
4437 $this->db->rollback();
4438 $this->error = $line->error;
4457 dol_syslog(get_class($this).
"::set_remise is deprecated, use setDiscount instead", LOG_NOTICE);
4458 return $this->
setDiscount($user, $remise, $notrigger);
4473 if (empty($remise)) {
4477 if ($user->hasRight(
'facture',
'creer')) {
4484 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
4485 $sql .=
' SET remise_percent = '.((float) $remise);
4486 $sql .=
" WHERE rowid = ".((int) $this->
id);
4487 $sql .=
' AND fk_statut = '.self::STATUS_DRAFT;
4490 $resql = $this->db->query($sql);
4492 $this->errors[] = $this->db->error();
4496 if (!$notrigger && empty($error)) {
4506 $this->remise_percent = $remise;
4509 $this->db->commit();
4512 foreach ($this->errors as $errmsg) {
4513 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
4514 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4516 $this->db->rollback();
4537 if (empty($remise)) {
4541 if ($user->hasRight(
'facture',
'creer')) {
4548 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
4549 $sql .=
' SET remise_absolue = '.((float) $remise);
4550 $sql .=
" WHERE rowid = ".((int) $this->
id);
4551 $sql .=
' AND fk_statut = '.self::STATUS_DRAFT;
4554 $resql = $this->db->query($sql);
4556 $this->errors[] = $this->db->error();
4561 $this->oldcopy = clone $this;
4562 $this->remise_absolue = $remise;
4566 if (!$notrigger && empty($error)) {
4576 $this->db->commit();
4579 foreach ($this->errors as $errmsg) {
4580 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
4581 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4583 $this->db->rollback();
4601 global $conf, $langs;
4603 if ($this->module_source ==
'takepos') {
4604 $langs->load(
'cashdesk');
4606 $moduleName =
'takepos';
4607 $moduleSourceName =
'Takepos';
4608 $addonConstName =
'TAKEPOS_REF_ADDON';
4611 if (empty($conf->global->TAKEPOS_REF_ADDON)) {
4612 $conf->global->TAKEPOS_REF_ADDON =
'mod_takepos_ref_simple';
4615 $addon = $conf->global->TAKEPOS_REF_ADDON;
4617 $langs->load(
'bills');
4619 $moduleName =
'facture';
4620 $moduleSourceName =
'Invoice';
4621 $addonConstName =
'FACTURE_ADDON';
4624 if (empty($conf->global->FACTURE_ADDON)) {
4625 $conf->global->FACTURE_ADDON =
'mod_facture_terre';
4626 } elseif ($conf->global->FACTURE_ADDON ==
'terre') {
4627 $conf->global->FACTURE_ADDON =
'mod_facture_terre';
4628 } elseif ($conf->global->FACTURE_ADDON ==
'mercure') {
4629 $conf->global->FACTURE_ADDON =
'mod_facture_mercure';
4632 $addon = $conf->global->FACTURE_ADDON;
4635 if (!empty($addon)) {
4636 dol_syslog(
"Call getNextNumRef with ".$addonConstName.
" = ".$conf->global->FACTURE_ADDON.
", thirdparty=".$soc->name.
", type=".$soc->typent_code.
", mode=".$mode, LOG_DEBUG);
4640 $file = $addon.
'.php';
4641 $classname = $addon;
4645 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
4646 foreach ($dirmodels as $reldir) {
4647 $dir =
dol_buildpath($reldir.
'core/modules/'.$moduleName.
'/');
4650 if (is_file($dir.$file) && is_readable($dir.$file)) {
4651 $mybool |= include_once $dir.$file;
4657 $file = $addon.
'/'.$addon.
'.modules.php';
4658 $classname =
'mod_'.$moduleName.
'_'.$addon;
4659 $classname = preg_replace(
'/\-.*$/',
'', $classname);
4661 foreach ($conf->file->dol_document_root as $dirroot) {
4662 $dir = $dirroot.
'/core/modules/'.$moduleName.
'/';
4665 if (is_file($dir.$file) && is_readable($dir.$file)) {
4666 $mybool |= include_once $dir.$file;
4676 $obj =
new $classname();
4678 $numref = $obj->getNextValue($soc, $this, $mode);
4685 if ($mode !=
'last' && !$numref) {
4686 $this->error = $obj->error;
4692 $langs->load(
'errors');
4693 print $langs->trans(
'Error').
' '.$langs->trans(
'ErrorModuleSetupNotComplete', $langs->transnoentitiesnoconv($moduleSourceName));
4706 $sql =
'SELECT c.rowid, datec, date_valid as datev, tms as datem,';
4707 $sql .=
' date_closing as dateclosing,';
4708 $sql .=
' fk_user_author, fk_user_valid, fk_user_closing';
4709 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facture as c';
4710 $sql .=
' WHERE c.rowid = '.((int) $id);
4712 $result = $this->db->query($sql);
4714 if ($this->db->num_rows($result)) {
4715 $obj = $this->db->fetch_object($result);
4716 $this->
id = $obj->rowid;
4717 if ($obj->fk_user_author) {
4718 $cuser =
new User($this->db);
4719 $cuser->fetch($obj->fk_user_author);
4720 $this->user_creation = $cuser;
4722 if ($obj->fk_user_valid) {
4723 $vuser =
new User($this->db);
4724 $vuser->fetch($obj->fk_user_valid);
4725 $this->user_validation = $vuser;
4727 if ($obj->fk_user_closing) {
4728 $cluser =
new User($this->db);
4729 $cluser->fetch($obj->fk_user_closing);
4730 $this->user_closing = $cluser;
4733 $this->date_creation = $this->db->jdate($obj->datec);
4734 $this->date_modification = $this->db->jdate($obj->datem);
4735 $this->date_validation = $this->db->jdate($obj->datev);
4736 $this->date_closing = $this->db->jdate($obj->dateclosing);
4738 $this->db->free($result);
4759 public function liste_array($shortlist = 0, $draft = 0, $excluser =
'', $socid = 0, $limit = 0, $offset = 0, $sortfield =
'f.datef,f.rowid', $sortorder =
'DESC')
4762 global $conf, $user;
4766 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
4767 $sql .=
" f.rowid as fid, f.ref as ref, f.datef as df";
4768 if (empty($user->rights->societe->client->voir) && !$socid) {
4769 $sql .=
", sc.fk_soc, sc.fk_user";
4771 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"facture as f";
4772 if (empty($user->rights->societe->client->voir) && !$socid) {
4773 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
4775 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice').
")";
4776 $sql .=
" AND f.fk_soc = s.rowid";
4777 if (empty($user->rights->societe->client->voir) && !$socid) {
4778 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
4781 $sql .=
" AND s.rowid = ".((int) $socid);
4784 $sql .=
" AND f.fk_statut = ".self::STATUS_DRAFT;
4786 if (is_object($excluser)) {
4787 $sql .=
" AND f.fk_user_author <> ".((int) $excluser->id);
4789 $sql .= $this->db->order($sortfield, $sortorder);
4790 $sql .= $this->db->plimit($limit, $offset);
4792 $result = $this->db->query($sql);
4794 $numc = $this->db->num_rows($result);
4797 while ($i < $numc) {
4798 $obj = $this->db->fetch_object($result);
4800 if ($shortlist == 1) {
4801 $ga[$obj->fid] = $obj->ref;
4802 } elseif ($shortlist == 2) {
4803 $ga[$obj->fid] = $obj->ref.
' ('.$obj->name.
')';
4805 $ga[$i][
'id'] = $obj->fid;
4806 $ga[$i][
'ref'] = $obj->ref;
4807 $ga[$i][
'name'] = $obj->name;
4836 $sql =
"SELECT f.rowid as rowid, f.ref, f.fk_statut as status, f.paye as paid,";
4837 $sql .=
" ff.rowid as rowidnext";
4839 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4840 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"paiement_facture as pf ON f.rowid = pf.fk_facture";
4841 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facture as ff ON f.rowid = ff.fk_facture_source";
4842 $sql .=
" WHERE (f.fk_statut = ".self::STATUS_VALIDATED.
" OR (f.fk_statut = ".self::STATUS_ABANDONED.
" AND f.close_code = '".self::CLOSECODE_ABANDONED.
"'))";
4843 $sql .=
" AND f.entity IN (".getEntity(
'invoice').
")";
4844 $sql .=
" AND f.paye = 0";
4845 $sql .=
" AND pf.fk_paiement IS NULL";
4846 $sql .=
" AND ff.fk_statut IS NULL";
4848 $sql .=
" AND f.fk_soc = ".((int) $socid);
4851 $sql .=
" ORDER BY f.ref";
4853 dol_syslog(get_class($this).
"::list_replacable_invoices", LOG_DEBUG);
4854 $resql = $this->db->query($sql);
4856 while ($obj = $this->db->fetch_object($resql)) {
4857 $return[$obj->rowid] = array(
4858 'id' => $obj->rowid,
4860 'status' => $obj->status,
4861 'paid' => $obj->paid,
4868 $this->error = $this->db->error();
4891 $sql =
"SELECT f.rowid as rowid, f.ref, f.fk_statut, f.type, f.paye, pf.fk_paiement";
4892 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4893 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"paiement_facture as pf ON f.rowid = pf.fk_facture";
4894 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=".self::TYPE_REPLACEMENT.
")";
4895 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice').
")";
4896 $sql .=
" AND f.fk_statut in (".self::STATUS_VALIDATED.
",".self::STATUS_CLOSED.
")";
4900 $sql .=
" AND ff.type IS NULL";
4901 $sql .=
" AND f.type <> ".self::TYPE_CREDIT_NOTE;
4903 if (!empty($conf->global->INVOICE_USE_SITUATION_CREDIT_NOTE)) {
4905 $sql .=
" AND (f.type <> ".self::TYPE_SITUATION.
" OR f.rowid IN ";
4906 $sql .=
'(SELECT MAX(fs.rowid)';
4907 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as fs";
4908 $sql .=
" WHERE fs.entity IN (".getEntity(
'invoice').
")";
4909 $sql .=
" AND fs.type = ".self::TYPE_SITUATION;
4910 $sql .=
" AND fs.fk_statut IN (".self::STATUS_VALIDATED.
",".self::STATUS_CLOSED.
")";
4912 $sql .=
" AND fs.fk_soc = ".((int) $socid);
4914 $sql .=
" GROUP BY fs.situation_cycle_ref)";
4917 $sql .=
" AND f.type <> ".self::TYPE_SITUATION;
4921 $sql .=
" AND f.fk_soc = ".((int) $socid);
4923 $sql .=
" ORDER BY f.ref";
4925 dol_syslog(get_class($this).
"::list_qualified_avoir_invoices", LOG_DEBUG);
4926 $resql = $this->db->query($sql);
4928 while ($obj = $this->db->fetch_object($resql)) {
4930 if ($obj->fk_statut == self::STATUS_VALIDATED) {
4933 if ($obj->fk_statut == self::STATUS_CLOSED) {
4938 $paymentornot = ($obj->fk_paiement ? 1 : 0);
4939 $return[$obj->rowid] = array(
'ref'=>$obj->ref,
'status'=>$obj->fk_statut,
'type'=>$obj->type,
'paye'=>$obj->paye,
'paymentornot'=>$paymentornot);
4945 $this->error = $this->db->error();
4961 global $conf, $langs;
4965 $sql =
"SELECT f.rowid, f.date_lim_reglement as datefin, f.fk_statut, f.total_ht";
4966 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4967 if (empty($user->rights->societe->client->voir) && !$user->socid) {
4968 $sql .=
" JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON f.fk_soc = sc.fk_soc";
4969 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
4972 $sql .= $clause.
" f.paye=0";
4973 $sql .=
" AND f.entity IN (".getEntity(
'invoice').
")";
4974 $sql .=
" AND f.fk_statut = ".self::STATUS_VALIDATED;
4976 $sql .=
" AND f.fk_soc = ".((int) $user->socid);
4979 $resql = $this->db->query($sql);
4981 $langs->load(
"bills");
4985 $response->warning_delay = $conf->facture->client->warning_delay / 60 / 60 / 24;
4986 $response->label = $langs->trans(
"CustomerBillsUnpaid");
4987 $response->labelShort = $langs->trans(
"Unpaid");
4988 $response->url = DOL_URL_ROOT.
'/compta/facture/list.php?search_status=1&mainmenu=billing&leftmenu=customers_bills';
4991 $generic_facture =
new Facture($this->db);
4993 while ($obj = $this->db->fetch_object($resql)) {
4994 $generic_facture->date_lim_reglement = $this->db->jdate($obj->datefin);
4995 $generic_facture->statut = $obj->fk_statut;
4997 $response->nbtodo++;
4998 $response->total += $obj->total_ht;
5000 if ($generic_facture->hasDelay()) {
5001 $response->nbtodolate++;
5002 $response->url_late = DOL_URL_ROOT.
'/compta/facture/list.php?search_option=late&mainmenu=billing&leftmenu=customers_bills';
5006 $this->db->free($resql);
5010 $this->error = $this->db->error();
5049 global $conf, $langs, $user;
5053 $nownotime =
dol_mktime(0, 0, 0, $arraynow[
'mon'], $arraynow[
'mday'], $arraynow[
'year']);
5058 $sql =
"SELECT rowid";
5059 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
5060 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
5061 $sql .= $this->db->plimit(100);
5063 $resql = $this->db->query($sql);
5065 $num_prods = $this->db->num_rows($resql);
5067 while ($i < $num_prods) {
5069 $row = $this->db->fetch_row($resql);
5070 $prodids[$i] = $row[0];
5074 if (empty($num_prods)) {
5081 $this->
ref =
'SPECIMEN';
5082 $this->specimen = 1;
5084 $this->date = $nownotime;
5085 $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
5086 $this->cond_reglement_id = 1;
5087 $this->cond_reglement_code =
'RECEP';
5089 $this->mode_reglement_id = 0;
5090 $this->mode_reglement_code =
'';
5092 $this->note_public =
'This is a comment (public)';
5093 $this->note_private =
'This is a comment (private)';
5094 $this->note =
'This is a comment (private)';
5096 $this->fk_user_author = $user->id;
5098 $this->multicurrency_tx = 1;
5099 $this->multicurrency_code = $conf->currency;
5101 $this->fk_incoterms = 0;
5102 $this->location_incoterms =
'';
5104 if (empty($option) || $option !=
'nolines') {
5108 while ($xnbp < $nbp) {
5110 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
5112 $line->subprice = 100;
5113 $line->tva_tx = 19.6;
5114 $line->localtax1_tx = 0;
5115 $line->localtax2_tx = 0;
5116 $line->remise_percent = 0;
5118 $prodid = mt_rand(1, $num_prods);
5119 $line->fk_product = $prodids[$prodid];
5121 $line->total_ht = -100;
5122 $line->total_ttc = -119.6;
5123 $line->total_tva = -19.6;
5124 $line->multicurrency_total_ht = -200;
5125 $line->multicurrency_total_ttc = -239.2;
5126 $line->multicurrency_total_tva = -39.2;
5127 } elseif ($xnbp == 2) {
5128 $line->subprice = -100;
5129 $line->total_ht = -100;
5130 $line->total_ttc = -119.6;
5131 $line->total_tva = -19.6;
5132 $line->remise_percent = 0;
5133 $line->multicurrency_total_ht = -200;
5134 $line->multicurrency_total_ttc = -239.2;
5135 $line->multicurrency_total_tva = -39.2;
5136 } elseif ($xnbp == 3) {
5137 $prodid = mt_rand(1, $num_prods);
5138 $line->fk_product = $prodids[$prodid];
5139 $line->total_ht = 50;
5140 $line->total_ttc = 59.8;
5141 $line->total_tva = 9.8;
5142 $line->multicurrency_total_ht = 100;
5143 $line->multicurrency_total_ttc = 119.6;
5144 $line->multicurrency_total_tva = 19.6;
5145 $line->remise_percent = 50;
5148 $prodid = mt_rand(1, $num_prods);
5149 $line->fk_product = $prodids[$prodid];
5150 $line->total_ht = 100;
5151 $line->total_ttc = 119.6;
5152 $line->total_tva = 19.6;
5153 $line->multicurrency_total_ht = 200;
5154 $line->multicurrency_total_ttc = 239.2;
5155 $line->multicurrency_total_tva = 39.2;
5156 $line->remise_percent = 0;
5159 $this->lines[$xnbp] = $line;
5162 $this->total_ht += $line->total_ht;
5163 $this->total_tva += $line->total_tva;
5164 $this->total_ttc += $line->total_ttc;
5166 $this->multicurrency_total_ht += $line->multicurrency_total_ht;
5167 $this->multicurrency_total_tva += $line->multicurrency_total_tva;
5168 $this->multicurrency_total_ttc += $line->multicurrency_total_ttc;
5172 $this->revenuestamp = 0;
5176 $line->desc = $langs->trans(
"Description").
" (offered line)";
5178 $line->subprice = 100;
5179 $line->tva_tx = 19.6;
5180 $line->localtax1_tx = 0;
5181 $line->localtax2_tx = 0;
5182 $line->remise_percent = 100;
5183 $line->total_ht = 0;
5184 $line->total_ttc = 0;
5185 $line->total_tva = 0;
5186 $line->multicurrency_total_ht = 0;
5187 $line->multicurrency_total_ttc = 0;
5188 $line->multicurrency_total_tva = 0;
5189 $prodid = mt_rand(1, $num_prods);
5190 $line->fk_product = $prodids[$prodid];
5192 $this->lines[$xnbp] = $line;
5206 global $conf, $user;
5208 $this->nb = array();
5212 $sql =
"SELECT count(f.rowid) as nb";
5213 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
5214 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON f.fk_soc = s.rowid";
5215 if (empty($user->rights->societe->client->voir) && !$user->socid) {
5216 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
5217 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
5220 $sql .=
" ".$clause.
" f.entity IN (".
getEntity(
'invoice').
")";
5222 $resql = $this->db->query($sql);
5224 while ($obj = $this->db->fetch_object($resql)) {
5225 $this->nb[
"invoices"] = $obj->nb;
5227 $this->db->free($resql);
5231 $this->error = $this->db->error();
5257 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
5259 global $conf, $langs;
5261 $outputlangs->loadLangs(array(
"bills",
"products"));
5265 $thisTypeConfName =
'FACTURE_ADDON_PDF_'.$this->type;
5267 if (!empty($this->model_pdf)) {
5268 $modele = $this->model_pdf;
5269 } elseif (!empty($this->modelpdf)) {
5270 $modele = $this->modelpdf;
5271 } elseif (!empty($conf->global->$thisTypeConfName)) {
5272 $modele = $conf->global->$thisTypeConfName;
5273 } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) {
5274 $modele = $conf->global->FACTURE_ADDON_PDF;
5278 $modelpath =
"core/modules/facture/doc/";
5280 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
5290 $sql =
'SELECT max(situation_cycle_ref) FROM '.MAIN_DB_PREFIX.
'facture as f';
5291 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice', 0).
")";
5292 $resql = $this->db->query($sql);
5294 if ($this->db->num_rows($resql) > 0) {
5295 $res = $this->db->fetch_array($resql);
5296 $ref = $res[
'max(situation_cycle_ref)'];
5301 $this->db->free($resql);
5304 $this->error = $this->db->lasterror();
5305 dol_syslog(
"Error sql=".$sql.
", error=".$this->error, LOG_ERR);
5319 return ($this->situation_counter == 1);
5333 $sql =
'SELECT rowid FROM '.MAIN_DB_PREFIX.
'facture';
5334 $sql .=
' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref);
5335 $sql .=
' AND situation_counter < '.((int) $this->situation_counter);
5336 $sql .=
' AND entity = '.($this->entity > 0 ? $this->entity : $conf->entity);
5337 $resql = $this->db->query($sql);
5339 if ($resql && $this->db->num_rows($resql) > 0) {
5340 while ($row = $this->db->fetch_object($resql)) {
5342 $situation =
new Facture($this->db);
5343 $situation->fetch($id);
5344 $res[] = $situation;
5347 $this->error = $this->db->error();
5348 dol_syslog(
"Error sql=".$sql.
", error=".$this->error, LOG_ERR);
5368 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET situation_final = '.((int) $this->situation_final).
' WHERE rowid = '.((int) $this->
id);
5371 $resql = $this->db->query($sql);
5373 $this->errors[] = $this->db->error();
5377 if (!$notrigger && empty($error)) {
5387 $this->db->commit();
5390 foreach ($this->errors as $errmsg) {
5391 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
5392 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
5394 $this->db->rollback();
5410 if (!empty($this->situation_cycle_ref)) {
5412 $sql =
'SELECT max(situation_counter) FROM '.MAIN_DB_PREFIX.
'facture';
5413 $sql .=
' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref);
5414 $sql .=
' AND entity = '.($this->entity > 0 ? $this->entity : $conf->entity);
5415 $resql = $this->db->query($sql);
5417 if ($resql && $this->db->num_rows($resql) > 0) {
5418 $res = $this->db->fetch_array($resql);
5419 $last = $res[
'max(situation_counter)'];
5420 return ($last == $this->situation_counter);
5422 $this->error = $this->db->lasterror();
5423 dol_syslog(get_class($this).
"::select Error ".$this->error, LOG_ERR);
5481 $hasDelay = $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay);
5482 if ($hasDelay && !empty($this->retained_warranty) && !empty($this->retained_warranty_date_limit)) {
5484 $totalpaid = floatval($totalpaid);
5486 if ($totalpaid >= 0 && $RetainedWarrantyAmount >= 0) {
5487 if (($totalpaid < $this->total_ttc - $RetainedWarrantyAmount) && $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay)) {
5489 } elseif ($totalpaid < $this->total_ttc && $this->retained_warranty_date_limit < ($now - $conf->facture->client->warning_delay)) {
5512 $displayWarranty =
false;
5513 if (!empty($this->retained_warranty)) {
5514 $displayWarranty =
true;
5518 $displayWarranty =
false;
5519 if (!empty($this->situation_final)) {
5520 $displayWarranty =
true;
5523 $displayWarranty =
true;
5525 foreach ($this->lines as $i => $line) {
5526 if ($line->product_type < 2 && $line->situation_percent < 100) {
5527 $displayWarranty =
false;
5535 return $displayWarranty;
5545 if (empty($this->retained_warranty)) {
5549 $retainedWarrantyAmount = 0;
5553 $displayWarranty =
true;
5555 if (!empty($this->lines)) {
5556 foreach ($this->lines as $i => $line) {
5557 if ($line->product_type < 2 && $line->situation_percent < 100) {
5558 $displayWarranty =
false;
5564 if ($displayWarranty && !empty($this->situation_final)) {
5566 $TPreviousIncoice = $this->tab_previous_situation_invoice;
5569 foreach ($TPreviousIncoice as &$fac) {
5570 $total2BillWT += $fac->total_ttc;
5572 $total2BillWT += $this->total_ttc;
5574 $retainedWarrantyAmount = $total2BillWT * $this->retained_warranty / 100;
5580 $retainedWarrantyAmount = $this->total_ttc * $this->retained_warranty / 100;
5583 if ($rounding < 0) {
5584 $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT);
5587 if ($rounding > 0) {
5588 return round($retainedWarrantyAmount, $rounding);
5591 return $retainedWarrantyAmount;
5602 dol_syslog(get_class($this).
'::setRetainedWarranty('.$value.
')');
5604 if ($this->
statut >= 0) {
5605 $fieldname =
'retained_warranty';
5606 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
5607 $sql .=
" SET ".$fieldname.
" = ".((float) $value);
5608 $sql .=
' WHERE rowid='.((int) $this->
id);
5610 if ($this->db->query($sql)) {
5611 $this->retained_warranty = floatval($value);
5614 dol_syslog(get_class($this).
'::setRetainedWarranty Erreur '.$sql.
' - '.$this->db->error());
5615 $this->error = $this->db->error();
5619 dol_syslog(get_class($this).
'::setRetainedWarranty, status of the object is incompatible');
5620 $this->error =
'Status of the object is incompatible '.$this->statut;
5635 if (!$timestamp && $dateYmd) {
5636 $timestamp = $this->db->jdate($dateYmd);
5640 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit('.$timestamp.
')');
5641 if ($this->
statut >= 0) {
5642 $fieldname =
'retained_warranty_date_limit';
5643 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
5644 $sql .=
" SET ".$fieldname.
" = ".(strval($timestamp) !=
'' ?
"'".$this->db->idate($timestamp).
"'" :
'null');
5645 $sql .=
' WHERE rowid = '.((int) $this->
id);
5647 if ($this->db->query($sql)) {
5648 $this->retained_warranty_date_limit = $timestamp;
5651 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit Erreur '.$sql.
' - '.$this->db->error());
5652 $this->error = $this->db->error();
5656 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit, status of the object is incompatible');
5657 $this->error =
'Status of the object is incompatible '.$this->statut;
5676 global $conf, $langs, $user;
5682 $errorsMsg = array();
5684 $langs->load(
"bills");
5686 if (!isModEnabled(
'facture')) {
5687 $this->output .= $langs->trans(
'ModuleNotEnabled', $langs->transnoentitiesnoconv(
"Facture"));
5690 if (!in_array($datetouse, array(
'duedate',
'invoicedate'))) {
5691 $this->output .=
'Bad value for parameter datetouse. Must be "duedate" or "invoicedate"';
5701 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
5702 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmail.class.php';
5703 require_once DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
5704 $formmail =
new FormMail($this->db);
5709 $tmpinvoice =
new Facture($this->db);
5714 $sql =
"SELECT rowid as id FROM ".MAIN_DB_PREFIX.
"facture as f";
5715 if (!empty($paymentmode) && $paymentmode !=
'all') {
5716 $sql .=
", ".MAIN_DB_PREFIX.
"c_paiement as cp";
5718 $sql .=
" WHERE f.paye = 0";
5719 $sql .=
" AND f.fk_statut = ".self::STATUS_VALIDATED;
5720 if ($datetouse ==
'invoicedate') {
5721 $sql .=
" AND f.datef = '".$this->db->idate($tmpidate,
'gmt').
"'";
5723 $sql .=
" AND f.date_lim_reglement = '".$this->db->idate($tmpidate,
'gmt').
"'";
5725 $sql .=
" AND f.entity IN (".getEntity(
'facture', 0).
")";
5726 if (!empty($paymentmode) && $paymentmode !=
'all') {
5727 $sql .=
" AND f.fk_mode_reglement = cp.id AND cp.code = '".$this->db->escape($paymentmode).
"'";
5730 if ($datetouse ==
'invoicedate') {
5731 $sql .= $this->db->order(
"datef",
"ASC");
5733 $sql .= $this->db->order(
"date_lim_reglement",
"ASC");
5736 $resql = $this->db->query($sql);
5739 if ($datetouse ==
'invoicedate') {
5740 $this->output .= $langs->transnoentitiesnoconv(
"SearchValidatedInvoicesWithDate", $stmpidate);
5742 $this->output .= $langs->transnoentitiesnoconv(
"SearchUnpaidInvoicesWithDueDate", $stmpidate);
5744 if (!empty($paymentmode) && $paymentmode !=
'all') {
5745 $this->output .=
' ('.$langs->transnoentitiesnoconv(
"PaymentMode").
' '.$paymentmode.
')';
5747 $this->output .=
'<br>';
5750 while ($obj = $this->db->fetch_object($resql)) {
5755 $res = $tmpinvoice->fetch($obj->id);
5757 $tmpinvoice->fetch_thirdparty();
5759 $outputlangs =
new Translate(
'', $conf);
5760 if ($tmpinvoice->thirdparty->default_lang) {
5761 $outputlangs->setDefaultLang($tmpinvoice->thirdparty->default_lang);
5762 $outputlangs->loadLangs(array(
"main",
"bills"));
5764 $outputlangs = $langs;
5768 $arraymessage = $formmail->getEMailTemplate($this->db,
'facture_send', $user, $outputlangs, (is_numeric($template) ? $template : 0), 1, (is_numeric($template) ?
'' : $template));
5769 if (is_numeric($arraymessage) && $arraymessage <= 0) {
5770 $langs->load(
"errors");
5771 $this->output .= $langs->trans(
'ErrorFailedToFindEmailTemplate', $template);
5784 $sendTopic =
make_substitutions(empty($arraymessage->topic) ? $outputlangs->transnoentitiesnoconv(
'InformationMessage') : $arraymessage->topic, $substitutionarray, $outputlangs, 1);
5787 $content = $outputlangs->transnoentitiesnoconv($arraymessage->content);
5793 if ($forcerecipient) {
5794 $to = array($forcerecipient);
5796 $res = $tmpinvoice->fetch_thirdparty();
5797 $recipient = $tmpinvoice->thirdparty;
5799 $tmparraycontact = $tmpinvoice->liste_contact(-1,
'external', 0,
'BILLING');
5800 if (is_array($tmparraycontact) && count($tmparraycontact) > 0) {
5801 foreach ($tmparraycontact as $data_email) {
5802 if (!empty($data_email[
'email'])) {
5803 $to[] = $tmpinvoice->thirdparty->contact_get_property($data_email[
'id'],
'email');
5807 if (empty($to) && !empty($recipient->email)) {
5808 $to[] = $recipient->email;
5811 $errormesg =
"Failed to send remind to thirdparty id=".$tmpinvoice->socid.
". No email defined for invoice or customer.";
5815 $errormesg =
"Failed to load recipient with thirdparty id=".$tmpinvoice->socid;
5822 if (!empty($arraymessage->email_from)) {
5823 $from = $arraymessage->email_from;
5826 $errormesg =
"Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
5830 if (!$loopError && !empty($to)) {
5833 $to = implode(
',', $to);
5834 if (!empty($arraymessage->email_to)) {
5835 $to = $to.
','.$arraymessage->email_to;
5839 $errors_to = $conf->global->MAIN_MAIL_ERRORS_TO;
5841 $trackid =
'inv'.$tmpinvoice->id;
5842 $sendcontext =
'standard';
5845 if (!empty($arraymessage->email_tocc)) {
5846 $email_tocc = $arraymessage->email_tocc;
5850 if (!empty($arraymessage->email_tobcc)) {
5851 $email_tobcc = $arraymessage->email_tobcc;
5858 if ($arraymessage->joinfiles == 1 && !empty($tmpinvoice->last_main_doc)) {
5859 $joinFile[] = DOL_DATA_ROOT.
'/'.$tmpinvoice->last_main_doc;
5860 $joinFileName[] = basename($tmpinvoice->last_main_doc);
5861 $joinFileMime[] =
dol_mimetype(DOL_DATA_ROOT.
'/'.$tmpinvoice->last_main_doc);
5865 $cMailFile =
new CMailFile($sendTopic, $to, $from, $sendContent, $joinFile, $joinFileMime, $joinFileName, $email_tocc, $email_tobcc, 0, 1, $errors_to,
'', $trackid,
'', $sendcontext,
'');
5868 if ($cMailFile->sendfile()) {
5872 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
5877 $actioncomm->type_code =
'AC_OTH_AUTO';
5878 $actioncomm->socid = $tmpinvoice->thirdparty->id;
5879 $actioncomm->contact_id = 0;
5881 $actioncomm->code =
'AC_EMAIL';
5882 $actioncomm->label =
'sendEmailsRemindersOnInvoiceDueDateOK (nbdays='.$nbdays.
' paymentmode='.$paymentmode.
' template='.$template.
' datetouse='.$datetouse.
' forcerecipient='.$forcerecipient.
')';
5883 $actioncomm->note_private = $sendContent;
5884 $actioncomm->fk_project = $tmpinvoice->fk_project;
5885 $actioncomm->datep =
dol_now();
5886 $actioncomm->datef = $actioncomm->datep;
5887 $actioncomm->percentage = -1;
5888 $actioncomm->authorid = $user->id;
5889 $actioncomm->userownerid = $user->id;
5891 $actioncomm->email_msgid = $cMailFile->msgid;
5892 $actioncomm->email_subject = $sendTopic;
5893 $actioncomm->email_from = $from;
5894 $actioncomm->email_sender =
'';
5895 $actioncomm->email_to = $to;
5899 $actioncomm->errors_to = $errors_to;
5901 $actioncomm->elementtype =
'invoice';
5902 $actioncomm->fk_element = $tmpinvoice->id;
5906 $actioncomm->create($user);
5908 $errormesg = $cMailFile->error.
' : '.$to;
5912 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
5917 $actioncomm->type_code =
'AC_OTH_AUTO';
5918 $actioncomm->socid = $tmpinvoice->thirdparty->id;
5919 $actioncomm->contact_id = 0;
5921 $actioncomm->code =
'AC_EMAIL';
5922 $actioncomm->label =
'sendEmailsRemindersOnInvoiceDueDateKO';
5923 $actioncomm->note_private = $errormesg;
5924 $actioncomm->fk_project = $tmpinvoice->fk_project;
5925 $actioncomm->datep =
dol_now();
5926 $actioncomm->datef = $actioncomm->datep;
5927 $actioncomm->percentage = -1;
5928 $actioncomm->authorid = $user->id;
5929 $actioncomm->userownerid = $user->id;
5931 $actioncomm->email_msgid = $cMailFile->msgid;
5932 $actioncomm->email_from = $from;
5933 $actioncomm->email_sender =
'';
5934 $actioncomm->email_to = $to;
5938 $actioncomm->errors_to = $errors_to;
5942 $actioncomm->create($user);
5945 $this->db->commit();
5949 $errorsMsg[] = $errormesg;
5952 $errorsMsg[] =
'Failed to fetch record invoice with ID = '.$obj->id;
5956 $error += $loopError;
5963 $this->output .=
'Nb of emails sent : '.$nbMailSend;
5965 dol_syslog(__METHOD__.
" end - ".$this->output, LOG_INFO);
5969 $this->error =
'Nb of emails sent : '.$nbMailSend.
', '.(!empty($errorsMsg)) ? join(
', ', $errorsMsg) : $error;
5971 dol_syslog(__METHOD__.
" end - ".$this->error, LOG_INFO);
5986 $sql =
"SELECT datef";
5987 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
5988 $sql .=
" WHERE type = " . (int) $this->
type ;
5989 $sql .=
" AND date_valid IS NOT NULL";
5990 $sql .=
" AND entity IN (".getEntity(
'invoice').
")";
5991 $sql .=
" ORDER BY datef DESC LIMIT 1";
5993 $result = $this->db->query($sql);
5996 if ($this->db->num_rows($result)) {
5997 $obj = $this->db->fetch_object($result);
5998 $last_date = $this->db->jdate($obj->datef);
5999 $invoice_date = $this->date;
6001 $is_last_of_same_type = $invoice_date >= $last_date;
6002 if ($allow_validated_drafts) {
6003 $is_last_of_same_type = $is_last_of_same_type || (!strpos($this->
ref,
'PROV') && $this->status ==
self::STATUS_DRAFT);
6006 return array($is_last_of_same_type, $last_date);
6027 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
6029 $return =
'<div class="box-flex-item box-flex-grow-zero">';
6030 $return .=
'<div class="info-box info-box-sm">';
6031 $return .=
'<span class="info-box-icon bg-infobox-action">';
6034 $return .=
'</span>';
6035 $return .=
'<div class="info-box-content">';
6036 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
6037 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
6038 if (property_exists($this,
'socid')) {
6039 $return .=
'<br><span class="info-box-label">'.$this->socid.
'</span>';
6041 if (property_exists($this,
'fk_user_author')) {
6042 $return .=
'<br><span class="info-box-label">'.$this->fk_user_author.
'</span>';
6044 if (method_exists($this,
'getLibStatut')) {
6045 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).
'</div>';
6047 $return .=
'</div>';
6048 $return .=
'</div>';
6049 $return .=
'</div>';
6063 public $element =
'facturedet';
6068 public $table_element =
'facturedet';
6085 public $localtax1_type;
6086 public $localtax2_type;
6087 public $fk_remise_except;
6090 public $fk_fournprice;
6095 public $remise_percent;
6097 public $special_code;
6105 public $fk_code_ventilation = 0;
6110 public $skip_update_total;
6115 public $situation_percent;
6123 public $fk_multicurrency;
6124 public $multicurrency_code;
6125 public $multicurrency_subprice;
6126 public $multicurrency_total_ht;
6127 public $multicurrency_total_tva;
6128 public $multicurrency_total_ttc;
6148 $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,';
6149 $sql .=
' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice, fd.ref_ext,';
6150 $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,';
6151 $sql .=
' fd.info_bits, fd.special_code, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,';
6152 $sql .=
' fd.fk_code_ventilation,';
6153 $sql .=
' fd.fk_unit, fd.fk_user_author, fd.fk_user_modif,';
6154 $sql .=
' fd.situation_percent, fd.fk_prev_id,';
6155 $sql .=
' fd.multicurrency_subprice,';
6156 $sql .=
' fd.multicurrency_total_ht,';
6157 $sql .=
' fd.multicurrency_total_tva,';
6158 $sql .=
' fd.multicurrency_total_ttc,';
6159 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc';
6160 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facturedet as fd';
6161 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON fd.fk_product = p.rowid';
6162 $sql .=
' WHERE fd.rowid = '.((int) $rowid);
6164 $result = $this->db->query($sql);
6166 $objp = $this->db->fetch_object($result);
6169 $this->error =
'InvoiceLine with id '. $rowid .
' not found sql='.$sql;
6173 $this->
rowid = $objp->rowid;
6174 $this->
id = $objp->rowid;
6175 $this->fk_facture = $objp->fk_facture;
6176 $this->fk_parent_line = $objp->fk_parent_line;
6177 $this->label = $objp->custom_label;
6178 $this->desc = $objp->description;
6179 $this->qty = $objp->qty;
6180 $this->subprice = $objp->subprice;
6181 $this->ref_ext = $objp->ref_ext;
6182 $this->vat_src_code = $objp->vat_src_code;
6183 $this->tva_tx = $objp->tva_tx;
6184 $this->localtax1_tx = $objp->localtax1_tx;
6185 $this->localtax2_tx = $objp->localtax2_tx;
6186 $this->remise_percent = $objp->remise_percent;
6187 $this->fk_remise_except = $objp->fk_remise_except;
6188 $this->fk_product = $objp->fk_product;
6189 $this->product_type = $objp->product_type;
6190 $this->date_start = $this->db->jdate($objp->date_start);
6191 $this->date_end = $this->db->jdate($objp->date_end);
6192 $this->info_bits = $objp->info_bits;
6193 $this->tva_npr = ($objp->info_bits & 1 == 1) ? 1 : 0;
6194 $this->special_code = $objp->special_code;
6195 $this->total_ht = $objp->total_ht;
6196 $this->total_tva = $objp->total_tva;
6197 $this->total_localtax1 = $objp->total_localtax1;
6198 $this->total_localtax2 = $objp->total_localtax2;
6199 $this->total_ttc = $objp->total_ttc;
6200 $this->fk_code_ventilation = $objp->fk_code_ventilation;
6201 $this->rang = $objp->rang;
6202 $this->fk_fournprice = $objp->fk_fournprice;
6203 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
6204 $this->pa_ht = $marginInfos[0];
6205 $this->marge_tx = $marginInfos[1];
6206 $this->marque_tx = $marginInfos[2];
6208 $this->
ref = $objp->product_ref;
6210 $this->product_ref = $objp->product_ref;
6211 $this->product_label = $objp->product_label;
6212 $this->product_desc = $objp->product_desc;
6214 $this->fk_unit = $objp->fk_unit;
6215 $this->fk_user_modif = $objp->fk_user_modif;
6216 $this->fk_user_author = $objp->fk_user_author;
6218 $this->situation_percent = $objp->situation_percent;
6219 $this->fk_prev_id = $objp->fk_prev_id;
6221 $this->multicurrency_subprice = $objp->multicurrency_subprice;
6222 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
6223 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
6224 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
6228 $this->db->free($result);
6232 $this->error = $this->db->lasterror();
6244 public function insert($notrigger = 0, $noerrorifdiscountalreadylinked = 0)
6246 global $langs, $user, $conf;
6250 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
6252 dol_syslog(get_class($this).
"::insert rang=".$this->rang, LOG_DEBUG);
6255 $this->desc = trim($this->desc);
6256 if (empty($this->tva_tx)) {
6259 if (empty($this->localtax1_tx)) {
6260 $this->localtax1_tx = 0;
6262 if (empty($this->localtax2_tx)) {
6263 $this->localtax2_tx = 0;
6265 if (empty($this->localtax1_type)) {
6266 $this->localtax1_type = 0;
6268 if (empty($this->localtax2_type)) {
6269 $this->localtax2_type = 0;
6271 if (empty($this->total_localtax1)) {
6272 $this->total_localtax1 = 0;
6274 if (empty($this->total_localtax2)) {
6275 $this->total_localtax2 = 0;
6277 if (empty($this->rang)) {
6280 if (empty($this->remise_percent)) {
6281 $this->remise_percent = 0;
6283 if (empty($this->info_bits)) {
6284 $this->info_bits = 0;
6286 if (empty($this->subprice)) {
6287 $this->subprice = 0;
6289 if (empty($this->ref_ext)) {
6290 $this->ref_ext =
'';
6292 if (empty($this->special_code)) {
6293 $this->special_code = 0;
6295 if (empty($this->fk_parent_line)) {
6296 $this->fk_parent_line = 0;
6298 if (empty($this->fk_prev_id)) {
6299 $this->fk_prev_id = 0;
6301 if (!isset($this->situation_percent) || $this->situation_percent > 100 || (
string) $this->situation_percent ==
'') {
6302 $this->situation_percent = 100;
6305 if (empty($this->pa_ht)) {
6308 if (empty($this->multicurrency_subprice)) {
6309 $this->multicurrency_subprice = 0;
6311 if (empty($this->multicurrency_total_ht)) {
6312 $this->multicurrency_total_ht = 0;
6314 if (empty($this->multicurrency_total_tva)) {
6315 $this->multicurrency_total_tva = 0;
6317 if (empty($this->multicurrency_total_ttc)) {
6318 $this->multicurrency_total_ttc = 0;
6322 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
6323 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
6326 $this->pa_ht = $result;
6331 if ($this->product_type < 0) {
6332 $this->error =
'ErrorProductTypeMustBe0orMore';
6335 if (!empty($this->fk_product) && $this->fk_product > 0) {
6339 $this->error =
'ErrorProductIdDoesNotExists';
6340 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6348 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'facturedet';
6349 $sql .=
' (fk_facture, fk_parent_line, label, description, qty,';
6350 $sql .=
' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
6351 $sql .=
' fk_product, product_type, remise_percent, subprice, ref_ext, fk_remise_except,';
6352 $sql .=
' date_start, date_end, fk_code_ventilation, ';
6353 $sql .=
' rang, special_code, fk_product_fournisseur_price, buy_price_ht,';
6354 $sql .=
' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2,';
6355 $sql .=
' situation_percent, fk_prev_id,';
6356 $sql .=
' fk_unit, fk_user_author, fk_user_modif,';
6357 $sql .=
' fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
6359 $sql .=
" VALUES (".$this->fk_facture.
",";
6360 $sql .=
" ".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null").
",";
6361 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
6362 $sql .=
" '".$this->db->escape($this->desc).
"',";
6363 $sql .=
" ".price2num($this->qty).
",";
6364 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
6365 $sql .=
" ".price2num($this->tva_tx).
",";
6366 $sql .=
" ".price2num($this->localtax1_tx).
",";
6367 $sql .=
" ".price2num($this->localtax2_tx).
",";
6368 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
6369 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
6370 $sql .=
' '.((!empty($this->fk_product) && $this->fk_product > 0) ? $this->fk_product :
"null").
',';
6371 $sql .=
" ".((int) $this->product_type).
",";
6372 $sql .=
" ".price2num($this->remise_percent).
",";
6373 $sql .=
" ".price2num($this->subprice).
",";
6374 $sql .=
" '".$this->db->escape($this->ref_ext).
"',";
6375 $sql .=
' '.(!empty($this->fk_remise_except) ? $this->fk_remise_except :
"null").
',';
6376 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
",";
6377 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null").
",";
6378 $sql .=
' '.((int) $this->fk_code_ventilation).
',';
6379 $sql .=
' '.((int) $this->rang).
',';
6380 $sql .=
' '.((int) $this->special_code).
',';
6381 $sql .=
' '.(!empty($this->fk_fournprice) ? $this->fk_fournprice :
"null").
',';
6382 $sql .=
' '.price2num($this->pa_ht).
',';
6383 $sql .=
" '".$this->db->escape($this->info_bits).
"',";
6384 $sql .=
" ".price2num($this->total_ht).
",";
6385 $sql .=
" ".price2num($this->total_tva).
",";
6386 $sql .=
" ".price2num($this->total_ttc).
",";
6387 $sql .=
" ".price2num($this->total_localtax1).
",";
6388 $sql .=
" ".price2num($this->total_localtax2);
6389 $sql .=
", ".((float) $this->situation_percent);
6390 $sql .=
", ".(!empty($this->fk_prev_id) ? $this->fk_prev_id :
"null");
6391 $sql .=
", ".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
6392 $sql .=
", ".((int) $user->id);
6393 $sql .=
", ".((int) $user->id);
6394 $sql .=
", ".(int) $this->fk_multicurrency;
6395 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
6396 $sql .=
", ".price2num($this->multicurrency_subprice);
6397 $sql .=
", ".price2num($this->multicurrency_total_ht);
6398 $sql .=
", ".price2num($this->multicurrency_total_tva);
6399 $sql .=
", ".price2num($this->multicurrency_total_ttc);
6402 dol_syslog(get_class($this).
"::insert", LOG_DEBUG);
6403 $resql = $this->db->query($sql);
6405 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'facturedet');
6406 $this->
rowid = $this->id;
6417 if ($this->fk_remise_except && empty($error)) {
6419 $result = $discount->fetch($this->fk_remise_except);
6424 if ($discount->fk_facture_line > 0) {
6425 if (empty($noerrorifdiscountalreadylinked)) {
6426 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed", $discount->id);
6427 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6428 $this->db->rollback();
6432 $result = $discount->link_to_invoice($this->
rowid, 0);
6434 $this->error = $discount->error;
6435 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6436 $this->db->rollback();
6441 $this->error = $langs->trans(
"ErrorADiscountThatHasBeenRemovedIsIncluded");
6442 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6443 $this->db->rollback();
6447 $this->error = $discount->error;
6448 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6449 $this->db->rollback();
6454 if (!$notrigger && empty($error)) {
6456 $result = $this->
call_trigger(
'LINEBILL_INSERT', $user);
6458 $this->db->rollback();
6465 $this->db->commit();
6469 foreach ($this->errors as $errmsg) {
6470 dol_syslog(get_class($this).
"::insert ".$errmsg, LOG_ERR);
6471 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
6473 $this->db->rollback();
6476 $this->error = $this->db->lasterror();
6477 $this->db->rollback();
6489 public function update($user =
'', $notrigger = 0)
6491 global $user, $conf;
6495 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
6498 $this->desc = trim($this->desc);
6499 if (empty($this->ref_ext)) {
6500 $this->ref_ext =
'';
6502 if (empty($this->tva_tx)) {
6505 if (empty($this->localtax1_tx)) {
6506 $this->localtax1_tx = 0;
6508 if (empty($this->localtax2_tx)) {
6509 $this->localtax2_tx = 0;
6511 if (empty($this->localtax1_type)) {
6512 $this->localtax1_type = 0;
6514 if (empty($this->localtax2_type)) {
6515 $this->localtax2_type = 0;
6517 if (empty($this->total_localtax1)) {
6518 $this->total_localtax1 = 0;
6520 if (empty($this->total_localtax2)) {
6521 $this->total_localtax2 = 0;
6523 if (empty($this->remise_percent)) {
6524 $this->remise_percent = 0;
6526 if (empty($this->info_bits)) {
6527 $this->info_bits = 0;
6529 if (empty($this->special_code)) {
6530 $this->special_code = 0;
6532 if (empty($this->product_type)) {
6533 $this->product_type = 0;
6535 if (empty($this->fk_parent_line)) {
6536 $this->fk_parent_line = 0;
6538 if (!isset($this->situation_percent) || $this->situation_percent > 100 || (
string) $this->situation_percent ==
'') {
6539 $this->situation_percent = 100;
6541 if (empty($this->pa_ht)) {
6545 if (empty($this->multicurrency_subprice)) {
6546 $this->multicurrency_subprice = 0;
6548 if (empty($this->multicurrency_total_ht)) {
6549 $this->multicurrency_total_ht = 0;
6551 if (empty($this->multicurrency_total_tva)) {
6552 $this->multicurrency_total_tva = 0;
6554 if (empty($this->multicurrency_total_ttc)) {
6555 $this->multicurrency_total_ttc = 0;
6559 if ($this->product_type < 0) {
6564 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
6566 $result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product);
6570 $this->pa_ht = $result;
6577 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facturedet SET";
6578 $sql .=
" description='".$this->db->escape($this->desc).
"'";
6579 $sql .=
", ref_ext='".$this->db->escape($this->ref_ext).
"'";
6580 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
6581 $sql .=
", subprice=".price2num($this->subprice);
6582 $sql .=
", remise_percent=".price2num($this->remise_percent);
6583 if ($this->fk_remise_except) {
6584 $sql .=
", fk_remise_except=".$this->fk_remise_except;
6586 $sql .=
", fk_remise_except=null";
6588 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->db->escape($this->vat_src_code)).
"'";
6589 $sql .=
", tva_tx=".price2num($this->tva_tx);
6590 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
6591 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
6592 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
6593 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
6594 $sql .=
", qty=".price2num($this->qty);
6595 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
6596 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
6597 $sql .=
", product_type=".$this->product_type;
6598 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
6599 $sql .=
", special_code='".$this->db->escape($this->special_code).
"'";
6600 if (empty($this->skip_update_total)) {
6601 $sql .=
", total_ht=".price2num($this->total_ht);
6602 $sql .=
", total_tva=".price2num($this->total_tva);
6603 $sql .=
", total_ttc=".price2num($this->total_ttc);
6604 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
6605 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
6607 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
6608 $sql .=
", buy_price_ht=".(($this->pa_ht || (string) $this->pa_ht ===
'0') ?
price2num($this->pa_ht) :
"null");
6609 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null");
6610 if (!empty($this->rang)) {
6611 $sql .=
", rang=".((int) $this->rang);
6613 $sql .=
", situation_percent = ".((float) $this->situation_percent);
6614 $sql .=
", fk_unit = ".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
6615 $sql .=
", fk_user_modif = ".((int) $user->id);
6618 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
6619 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
6620 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
6621 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
6623 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
6625 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
6626 $resql = $this->db->query($sql);
6629 $this->
id = $this->rowid;
6636 if (!$error && !$notrigger) {
6638 $result = $this->
call_trigger(
'LINEBILL_MODIFY', $user);
6640 $this->db->rollback();
6647 $this->db->commit();
6651 foreach ($this->errors as $errmsg) {
6652 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
6653 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
6655 $this->db->rollback();
6658 $this->error = $this->db->error();
6659 $this->db->rollback();
6671 public function delete($tmpuser =
null, $notrigger =
false)
6678 if (empty($notrigger)) {
6679 $result = $this->
call_trigger(
'LINEBILL_DELETE', $user);
6681 $this->db->rollback();
6690 $this->db->rollback();
6695 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
6696 $sql .=
' SET fk_facture_line = NULL';
6697 $sql .=
' WHERE fk_facture_line = '.((int) $this->
id);
6699 dol_syslog(get_class($this).
"::deleteline", LOG_DEBUG);
6700 $result = $this->db->query($sql);
6702 $this->error = $this->db->error();
6703 $this->errors[] = $this->error;
6704 $this->db->rollback();
6708 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'element_time';
6709 $sql .=
' SET invoice_id = NULL, invoice_line_id = NULL';
6710 $sql .=
' WHERE invoice_line_id = '.((int) $this->
id);
6711 if (!$this->db->query($sql)) {
6712 $this->error = $this->db->error().
" sql=".$sql;
6713 $this->errors[] = $this->error;
6714 $this->db->rollback();
6718 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"facturedet WHERE rowid = ".((int) $this->
id);
6720 if ($this->db->query($sql)) {
6721 $this->db->commit();
6724 $this->error = $this->db->error().
" sql=".$sql;
6725 $this->errors[] = $this->error;
6726 $this->db->rollback();
6742 dol_syslog(get_class($this).
"::update_total", LOG_DEBUG);
6745 if (empty($this->total_localtax1)) {
6746 $this->total_localtax1 = 0;
6748 if (empty($this->total_localtax2)) {
6749 $this->total_localtax2 = 0;
6753 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facturedet SET";
6754 $sql .=
" total_ht=".price2num($this->total_ht);
6755 $sql .=
",total_tva=".price2num($this->total_tva);
6756 $sql .=
",total_localtax1=".price2num($this->total_localtax1);
6757 $sql .=
",total_localtax2=".price2num($this->total_localtax2);
6758 $sql .=
",total_ttc=".price2num($this->total_ttc);
6759 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
6761 dol_syslog(get_class($this).
"::update_total", LOG_DEBUG);
6763 $resql = $this->db->query($sql);
6765 $this->db->commit();
6768 $this->error = $this->db->error();
6769 $this->db->rollback();
6786 global $invoicecache;
6788 if (is_null($this->fk_prev_id) || empty($this->fk_prev_id) || $this->fk_prev_id ==
"") {
6792 if (!isset($invoicecache[$invoiceid])) {
6793 $invoicecache[$invoiceid] =
new Facture($this->db);
6794 $invoicecache[$invoiceid]->fetch($invoiceid);
6800 $sql =
"SELECT situation_percent FROM ".MAIN_DB_PREFIX.
"facturedet WHERE rowid = ".((int) $this->fk_prev_id);
6801 $resql = $this->db->query($sql);
6802 if ($resql && $this->db->num_rows($resql) > 0) {
6803 $res = $this->db->fetch_array($resql);
6805 $returnPercent = floatval($res[
'situation_percent']);
6807 if ($include_credit_note) {
6808 $sql =
'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.
'facturedet fd';
6809 $sql .=
' JOIN '.MAIN_DB_PREFIX.
'facture f ON (f.rowid = fd.fk_facture) ';
6810 $sql .=
" WHERE fd.fk_prev_id = ".((int) $this->fk_prev_id);
6811 $sql .=
" AND f.situation_cycle_ref = ".((int) $invoicecache[$invoiceid]->situation_cycle_ref);
6812 $sql .=
" AND f.type = ".Facture::TYPE_CREDIT_NOTE;
6814 $res = $this->db->query($sql);
6816 while ($obj = $this->db->fetch_object($res)) {
6817 $returnPercent = $returnPercent + floatval($obj->situation_percent);
6824 return $returnPercent;
6826 $this->error = $this->db->error();
6827 dol_syslog(get_class($this).
"::select Error ".$this->error, LOG_ERR);
6828 $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