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();
493 public function create(
User $user, $notrigger = 0, $forceduedate = 0) {
…}
1163 $facture =
new Facture($this->db);
1169 if (!empty($this->array_options)) {
1170 $facture->array_options = $this->array_options;
1173 foreach ($this->lines as &$line) {
1174 $line->fetch_optionals();
1178 $facture->type = $this->type;
1179 $facture->socid = $this->socid;
1180 $facture->date = $this->date;
1181 $facture->date_pointoftax = $this->date_pointoftax;
1182 $facture->note_public = $this->note_public;
1183 $facture->note_private = $this->note_private;
1184 $facture->ref_client = $this->ref_client;
1185 $facture->modelpdf = $this->model_pdf;
1186 $facture->model_pdf = $this->model_pdf;
1187 $facture->fk_project = $this->fk_project;
1188 $facture->cond_reglement_id = $this->cond_reglement_id;
1189 $facture->mode_reglement_id = $this->mode_reglement_id;
1190 $facture->remise_absolue = $this->remise_absolue;
1193 $facture->origin = $this->origin;
1194 $facture->origin_id = $this->origin_id;
1195 $facture->fk_account = $this->fk_account;
1197 $facture->lines = $this->lines;
1198 $facture->situation_counter = $this->situation_counter;
1199 $facture->situation_cycle_ref = $this->situation_cycle_ref;
1200 $facture->situation_final = $this->situation_final;
1202 $facture->retained_warranty = $this->retained_warranty;
1203 $facture->retained_warranty_fk_cond_reglement = $this->retained_warranty_fk_cond_reglement;
1204 $facture->retained_warranty_date_limit = $this->retained_warranty_date_limit;
1206 $facture->fk_user_author = $user->id;
1210 foreach ($facture->lines as $i => $tmpline) {
1211 $facture->lines[$i]->fk_prev_id = $this->lines[$i]->rowid;
1212 if ($invertdetail) {
1213 $facture->lines[$i]->subprice = -$facture->lines[$i]->subprice;
1214 $facture->lines[$i]->total_ht = -$facture->lines[$i]->total_ht;
1215 $facture->lines[$i]->total_tva = -$facture->lines[$i]->total_tva;
1216 $facture->lines[$i]->total_localtax1 = -$facture->lines[$i]->total_localtax1;
1217 $facture->lines[$i]->total_localtax2 = -$facture->lines[$i]->total_localtax2;
1218 $facture->lines[$i]->total_ttc = -$facture->lines[$i]->total_ttc;
1219 $facture->lines[$i]->ref_ext =
'';
1223 dol_syslog(get_class($this).
"::createFromCurrent invertdetail=".$invertdetail.
" socid=".$this->socid.
" nboflines=".count($facture->lines));
1225 $facid = $facture->create($user);
1227 $this->error = $facture->error;
1228 $this->errors = $facture->errors;
1229 } elseif ($this->
type == self::TYPE_SITUATION && !empty($conf->global->INVOICE_USE_SITUATION)) {
1232 foreach ($this->linkedObjectsIds as $typeObject => $Tfk_object) {
1233 foreach ($Tfk_object as $fk_object) {
1234 $facture->add_object_linked($typeObject, $fk_object);
1238 $facture->add_object_linked(
'facture', $this->fk_facture_source);
1254 global $conf, $hookmanager;
1258 $object =
new Facture($this->db);
1262 $object->fetch($fromid);
1265 $objFrom = clone $object;
1268 if (!empty($this->socid) && $this->socid != $object->socid) {
1269 $objsoc =
new Societe($this->db);
1271 if ($objsoc->fetch($this->socid) > 0) {
1272 $object->socid = $objsoc->id;
1273 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1274 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1275 $object->fk_project =
'';
1276 $object->fk_delivery_address =
'';
1287 $object->date = (empty($this->date) ?
dol_now() : $this->date);
1288 $object->user_author = $user->id;
1289 $object->user_valid =
null;
1290 $object->fk_user_author = $user->id;
1291 $object->fk_user_valid =
null;
1292 $object->fk_facture_source = 0;
1293 $object->date_creation =
'';
1294 $object->date_modification =
'';
1295 $object->date_validation =
'';
1296 $object->ref_client =
'';
1297 $object->close_code =
'';
1298 $object->close_note =
'';
1300 $object->note_private =
'';
1301 $object->note_public =
'';
1305 foreach ($object->lines as $i => $line) {
1306 if (($object->lines[$i]->info_bits & 0x02) == 0x02) {
1307 unset($object->lines[$i]);
1313 if (!empty($conf->global->INVOICE_AUTO_NEXT_MONTH_ON_LINES) && !empty($line->date_start) && !empty($line->date_end)) {
1325 if (
dol_mktime(0, 0, 0, $start[
'mon'], $start[
'mday'], $start[
'year'],
'gmt') == $first
1326 &&
dol_mktime(23, 59, 59, $end[
'mon'], $end[
'mday'], $end[
'year'],
'gmt') == $last) {
1330 $object->lines[$i]->date_start = $newFirst;
1331 $object->lines[$i]->date_end = $newLast;
1335 $object->lines[$i]->ref_ext =
'';
1339 $object->context[
'createfromclone'] =
'createfromclone';
1340 $result = $object->create($user);
1343 $this->error = $object->error;
1344 $this->errors = $object->errors;
1347 if ($object->copy_linked_contact($objFrom,
'internal') < 0) {
1349 $this->error = $object->error;
1350 $this->errors = $object->errors;
1351 } elseif ($object->socid == $objFrom->socid) {
1353 if ($object->copy_linked_contact($objFrom,
'external') < 0) {
1355 $this->error = $object->error;
1356 $this->errors = $object->errors;
1363 if (is_object($hookmanager)) {
1364 $parameters = array(
'objFrom'=>$objFrom);
1366 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action);
1374 unset($object->context[
'createfromclone']);
1378 $this->db->commit();
1381 $this->db->rollback();
1395 global $conf, $hookmanager;
1403 $num = count($object->lines);
1404 for ($i = 0; $i < $num; $i++) {
1407 $line->libelle = $object->lines[$i]->libelle;
1408 $line->label = $object->lines[$i]->label;
1409 $line->desc = $object->lines[$i]->desc;
1410 $line->subprice = $object->lines[$i]->subprice;
1411 $line->total_ht = $object->lines[$i]->total_ht;
1412 $line->total_tva = $object->lines[$i]->total_tva;
1413 $line->total_localtax1 = $object->lines[$i]->total_localtax1;
1414 $line->total_localtax2 = $object->lines[$i]->total_localtax2;
1415 $line->total_ttc = $object->lines[$i]->total_ttc;
1416 $line->vat_src_code = $object->lines[$i]->vat_src_code;
1417 $line->tva_tx = $object->lines[$i]->tva_tx;
1418 $line->localtax1_tx = $object->lines[$i]->localtax1_tx;
1419 $line->localtax2_tx = $object->lines[$i]->localtax2_tx;
1420 $line->qty = $object->lines[$i]->qty;
1421 $line->fk_remise_except = $object->lines[$i]->fk_remise_except;
1422 $line->remise_percent = $object->lines[$i]->remise_percent;
1423 $line->fk_product = $object->lines[$i]->fk_product;
1424 $line->info_bits = $object->lines[$i]->info_bits;
1425 $line->product_type = $object->lines[$i]->product_type;
1426 $line->rang = $object->lines[$i]->rang;
1427 $line->special_code = $object->lines[$i]->special_code;
1428 $line->fk_parent_line = $object->lines[$i]->fk_parent_line;
1429 $line->fk_unit = $object->lines[$i]->fk_unit;
1430 $line->date_start = $object->lines[$i]->date_start;
1431 $line->date_end = $object->lines[$i]->date_end;
1434 $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency;
1435 $line->multicurrency_code = $object->lines[$i]->multicurrency_code;
1436 $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice;
1437 $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht;
1438 $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva;
1439 $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc;
1441 $line->fk_fournprice = $object->lines[$i]->fk_fournprice;
1442 $marginInfos =
getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht);
1443 $line->pa_ht = $marginInfos[0];
1446 $object->lines[$i]->fetch_optionals();
1447 foreach ($object->lines[$i]->array_options as $options_key => $value) {
1448 $line->array_options[$options_key] = $value;
1451 $this->lines[$i] = $line;
1454 $this->socid = $object->socid;
1455 $this->fk_project = $object->fk_project;
1456 $this->fk_account = $object->fk_account;
1457 $this->cond_reglement_id = $object->cond_reglement_id;
1458 $this->mode_reglement_id = $object->mode_reglement_id;
1459 $this->availability_id = $object->availability_id;
1460 $this->demand_reason_id = $object->demand_reason_id;
1461 $this->delivery_date = (empty($object->delivery_date) ? $object->date_livraison : $object->delivery_date);
1462 $this->date_livraison = $object->delivery_date;
1463 $this->fk_delivery_address = $object->fk_delivery_address;
1464 $this->contact_id = $object->contact_id;
1465 $this->ref_client = $object->ref_client;
1467 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1468 $this->note_private = $object->note_private;
1469 $this->note_public = $object->note_public;
1472 $this->module_source = $object->module_source;
1473 $this->pos_source = $object->pos_source;
1475 $this->origin = $object->element;
1476 $this->origin_id = $object->id;
1478 $this->fk_user_author = $user->id;
1481 $object->fetch_optionals();
1482 foreach ($object->array_options as $options_key => $value) {
1483 $this->array_options[$options_key] = $value;
1487 $this->linked_objects[$this->origin] = $this->origin_id;
1488 if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) {
1489 $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
1492 $ret = $this->
create($user);
1496 $hookmanager->initHooks(array(
'invoicedao'));
1498 $parameters = array(
'objFrom'=>$object);
1500 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1526 global $conf, $hookmanager;
1534 $use_all_lines = empty($lines);
1535 $num = count($object->lines);
1536 for ($i = 0; $i < $num; $i++) {
1537 if (!$use_all_lines && !in_array($object->lines[$i]->id, $lines)) {
1543 $line->libelle = $object->lines[$i]->libelle;
1544 $line->label = $object->lines[$i]->label;
1545 $line->desc = $object->lines[$i]->desc;
1546 $line->subprice = $object->lines[$i]->subprice;
1547 $line->total_ht = $object->lines[$i]->total_ht;
1548 $line->total_tva = $object->lines[$i]->total_tva;
1549 $line->total_localtax1 = $object->lines[$i]->total_localtax1;
1550 $line->total_localtax2 = $object->lines[$i]->total_localtax2;
1551 $line->total_ttc = $object->lines[$i]->total_ttc;
1552 $line->vat_src_code = $object->lines[$i]->vat_src_code;
1553 $line->tva_tx = $object->lines[$i]->tva_tx;
1554 $line->localtax1_tx = $object->lines[$i]->localtax1_tx;
1555 $line->localtax2_tx = $object->lines[$i]->localtax2_tx;
1556 $line->qty = $object->lines[$i]->qty;
1557 $line->fk_remise_except = $object->lines[$i]->fk_remise_except;
1558 $line->remise_percent = $object->lines[$i]->remise_percent;
1559 $line->fk_product = $object->lines[$i]->fk_product;
1560 $line->info_bits = $object->lines[$i]->info_bits;
1561 $line->product_type = $object->lines[$i]->product_type;
1562 $line->rang = $object->lines[$i]->rang;
1563 $line->special_code = $object->lines[$i]->special_code;
1564 $line->fk_parent_line = $object->lines[$i]->fk_parent_line;
1565 $line->fk_unit = $object->lines[$i]->fk_unit;
1566 $line->date_start = $object->lines[$i]->date_start;
1567 $line->date_end = $object->lines[$i]->date_end;
1570 $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency;
1571 $line->multicurrency_code = $object->lines[$i]->multicurrency_code;
1572 $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice;
1573 $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht;
1574 $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva;
1575 $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc;
1577 $line->fk_fournprice = $object->lines[$i]->fk_fournprice;
1578 $marginInfos =
getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht);
1579 $line->pa_ht = $marginInfos[0];
1582 $object->lines[$i]->fetch_optionals();
1583 foreach ($object->lines[$i]->array_options as $options_key => $value) {
1584 $line->array_options[$options_key] = $value;
1587 $this->lines[$i] = $line;
1590 $this->socid = $object->socid;
1591 $this->fk_project = $object->fk_project;
1592 $this->fk_account = $object->fk_account;
1593 $this->cond_reglement_id = $object->cond_reglement_id;
1594 $this->mode_reglement_id = $object->mode_reglement_id;
1595 $this->availability_id = $object->availability_id;
1596 $this->demand_reason_id = $object->demand_reason_id;
1597 $this->delivery_date = (empty($object->delivery_date) ? $object->date_livraison : $object->delivery_date);
1598 $this->date_livraison = $object->delivery_date;
1599 $this->fk_delivery_address = $object->fk_delivery_address;
1600 $this->contact_id = $object->contact_id;
1601 $this->ref_client = $object->ref_client;
1603 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1604 $this->note_private = $object->note_private;
1605 $this->note_public = $object->note_public;
1608 $this->module_source = $object->module_source;
1609 $this->pos_source = $object->pos_source;
1611 $this->origin = $object->element;
1612 $this->origin_id = $object->id;
1614 $this->fk_user_author = $user->id;
1617 $object->fetch_optionals();
1618 foreach ($object->array_options as $options_key => $value) {
1619 $this->array_options[$options_key] = $value;
1623 $this->linked_objects[$this->origin] = $this->origin_id;
1624 if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) {
1625 $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
1628 $ret = $this->
create($user);
1632 $hookmanager->initHooks(array(
'invoicedao'));
1634 $parameters = array(
'objFrom'=>$object);
1636 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $this, $action);
1666 global $conf, $langs, $hookmanager, $action;
1668 if (! in_array($origin->element, array(
'propal',
'commande'))) {
1669 $origin->error =
'ErrorCanOnlyAutomaticallyGenerateADepositFromProposalOrOrder';
1674 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'DateInvoice'));
1678 require_once DOL_DOCUMENT_ROOT .
'/core/lib/date.lib.php';
1680 if ($date > (
dol_get_last_hour(
dol_now(
'tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
1681 $origin->error =
'ErrorDateIsInFuture';
1685 if ($payment_terms_id <= 0) {
1686 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'PaymentConditionsShort'));
1690 $payment_conditions_deposit_percent =
getDictionaryValue(
'c_payment_term',
'deposit_percent', $origin->cond_reglement_id);
1692 if (empty($payment_conditions_deposit_percent)) {
1693 $origin->error =
'ErrorPaymentConditionsNotEligibleToDepositCreation';
1697 if (empty($origin->deposit_percent)) {
1698 $origin->error = $langs->trans(
'ErrorFieldRequired', $langs->transnoentities(
'DepositPercent'));
1702 $deposit =
new self($origin->db);
1703 $deposit->socid = $origin->socid;
1705 $deposit->fk_project = $origin->fk_project;
1706 $deposit->ref_client = $origin->ref_client;
1707 $deposit->date = $date;
1708 $deposit->mode_reglement_id = $origin->mode_reglement_id;
1709 $deposit->cond_reglement_id = $payment_terms_id;
1710 $deposit->availability_id = $origin->availability_id;
1711 $deposit->demand_reason_id = $origin->demand_reason_id;
1712 $deposit->fk_account = $origin->fk_account;
1713 $deposit->fk_incoterms = $origin->fk_incoterms;
1714 $deposit->location_incoterms = $origin->location_incoterms;
1715 $deposit->fk_multicurrency = $origin->fk_multicurrency;
1716 $deposit->multicurrency_code = $origin->multicurrency_code;
1717 $deposit->multicurrency_tx = $origin->multicurrency_tx;
1718 $deposit->module_source = $origin->module_source;
1719 $deposit->pos_source = $origin->pos_source;
1720 $deposit->model_pdf =
'crabe';
1722 $modelByTypeConfName =
'FACTURE_ADDON_PDF_' . $deposit->type;
1724 if (!empty($conf->global->$modelByTypeConfName)) {
1725 $deposit->model_pdf = $conf->global->$modelByTypeConfName;
1726 } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) {
1727 $deposit->model_pdf = $conf->global->FACTURE_ADDON_PDF;
1730 if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) {
1731 $deposit->note_private = $origin->note_private;
1732 $deposit->note_public = $origin->note_public;
1735 $deposit->origin = $origin->element;
1736 $deposit->origin_id = $origin->id;
1738 $origin->fetch_optionals();
1740 foreach ($origin->array_options as $extrakey => $value) {
1741 $deposit->array_options[$extrakey] = $value;
1744 $deposit->linked_objects[$deposit->origin] = $deposit->origin_id;
1746 foreach ($overrideFields as $key => $value) {
1747 $deposit->$key = $value;
1750 $deposit->context[
'createdepositfromorigin'] =
'createdepositfromorigin';
1752 $origin->db->begin();
1755 $createReturn = $deposit->create($user, $notrigger);
1757 if ($createReturn <= 0) {
1758 $origin->db->rollback();
1759 $origin->error = $deposit->error;
1760 $origin->errors = $deposit->errors;
1764 $amount_ttc_diff = 0;
1765 $amountdeposit = array();
1766 $descriptions = array();
1768 if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)) {
1769 $amount = $origin->total_ttc * ($origin->deposit_percent / 100);
1771 $TTotalByTva = array();
1772 foreach ($origin->lines as &$line) {
1773 if (!empty($line->special_code)) {
1776 $TTotalByTva[$line->tva_tx] += $line->total_ttc;
1777 $descriptions[$line->tva_tx] .=
'<li>' . (!empty($line->product_ref) ? $line->product_ref .
' - ' :
'');
1778 $descriptions[$line->tva_tx] .= (!empty($line->product_label) ? $line->product_label .
' - ' :
'');
1779 $descriptions[$line->tva_tx] .= $langs->trans(
'Qty') .
' : ' . $line->qty;
1780 $descriptions[$line->tva_tx] .=
' - ' . $langs->trans(
'TotalHT') .
' : ' .
price($line->total_ht) .
'</li>';
1783 foreach ($TTotalByTva as $tva => &$total) {
1784 $coef = $total / $origin->total_ttc;
1785 $am = $amount * $coef;
1786 $amount_ttc_diff += $am;
1787 $amountdeposit[$tva] += $am / (1 + $tva / 100);
1791 $lines = $origin->lines;
1792 $numlines = count($lines);
1793 for ($i = 0; $i < $numlines; $i++) {
1794 if (empty($lines[$i]->qty)) {
1797 if (!empty($lines[$i]->special_code)) {
1801 $totalamount += $lines[$i]->total_ht;
1802 $tva_tx = $lines[$i]->tva_tx;
1803 $amountdeposit[$tva_tx] += ($lines[$i]->total_ht * $origin->deposit_percent) / 100;
1804 $descriptions[$tva_tx] .=
'<li>' . (!empty($lines[$i]->product_ref) ? $lines[$i]->product_ref .
' - ' :
'');
1805 $descriptions[$tva_tx] .= (!empty($lines[$i]->product_label) ? $lines[$i]->product_label .
' - ' :
'');
1806 $descriptions[$tva_tx] .= $langs->trans(
'Qty') .
' : ' . $lines[$i]->qty;
1807 $descriptions[$tva_tx] .=
' - ' . $langs->trans(
'TotalHT') .
' : ' .
price($lines[$i]->total_ht) .
'</li>';
1810 if ($totalamount == 0) {
1811 $amountdeposit[0] = 0;
1814 $amount_ttc_diff = $amountdeposit[0];
1817 foreach ($amountdeposit as $tva => $amount) {
1818 if (empty($amount)) {
1822 $descline =
'(DEPOSIT) ('. $origin->deposit_percent .
'%) - '.$origin->ref;
1825 if (!empty($conf->global->INVOICE_DEPOSIT_VARIABLE_MODE_DETAIL_LINES_IN_DESCRIPTION) && !empty($descriptions[$tva])) {
1826 $descline .=
'<ul>' . $descriptions[$tva] .
'</ul>';
1829 $addlineResult = $deposit->addline(
1836 (empty($conf->global->INVOICE_PRODUCTID_DEPOSIT) ? 0 : $conf->global->INVOICE_PRODUCTID_DEPOSIT),
1856 if ($addlineResult < 0) {
1857 $origin->db->rollback();
1858 $origin->error = $deposit->error;
1859 $origin->errors = $deposit->errors;
1864 $diff = $deposit->total_ttc - $amount_ttc_diff;
1866 if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA) && $diff != 0) {
1867 $deposit->fetch_lines();
1868 $subprice_diff = $deposit->lines[0]->subprice - $diff / (1 + $deposit->lines[0]->tva_tx / 100);
1870 $updatelineResult = $deposit->updateline(
1871 $deposit->lines[0]->id,
1872 $deposit->lines[0]->desc,
1874 $deposit->lines[0]->qty,
1875 $deposit->lines[0]->remise_percent,
1876 $deposit->lines[0]->date_start,
1877 $deposit->lines[0]->date_end,
1878 $deposit->lines[0]->tva_tx,
1882 $deposit->lines[0]->info_bits,
1883 $deposit->lines[0]->product_type,
1887 $deposit->lines[0]->pa_ht,
1888 $deposit->lines[0]->label,
1894 if ($updatelineResult < 0) {
1895 $origin->db->rollback();
1896 $origin->error = $deposit->error;
1897 $origin->errors = $deposit->errors;
1902 $hookmanager->initHooks(array(
'invoicedao'));
1904 $parameters = array(
'objFrom' => $origin);
1905 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $deposit, $action);
1908 $origin->db->rollback();
1909 $origin->error = $hookmanager->error;
1910 $origin->errors = $hookmanager->errors;
1914 if (!empty($autoValidateDeposit)) {
1915 $validateReturn = $deposit->validate($user,
'', 0, $notrigger);
1917 if ($validateReturn < 0) {
1918 $origin->db->rollback();
1919 $origin->error = $deposit->error;
1920 $origin->errors = $deposit->errors;
1925 unset($deposit->context[
'createdepositfromorigin']);
1927 $origin->db->commit();
1941 global $conf, $langs, $mysoc, $user;
1943 $langs->load(
'bills');
1946 $moretitle = $params[
'moretitle'] ??
'';
1947 $picto = $this->picto;
1948 if ($this->
type == self::TYPE_REPLACEMENT) {
1951 if ($this->
type == self::TYPE_CREDIT_NOTE) {
1954 if ($this->
type == self::TYPE_DEPOSIT) {
1958 if ($user->hasRight(
"facture",
"read")) {
1959 $datas[
'picto'] =
img_picto(
'', $picto).
' <u class="paddingrightonly">'.$langs->trans(
"Invoice").
'</u>';
1961 $datas[
'picto'] .=
' '.$this->getLibType(1);
1964 if (!empty($params[
'fromajaxtooltip']) && !isset($this->alreadypaid)) {
1968 if (isset($this->
statut) && isset($this->alreadypaid)) {
1969 $datas[
'picto'] .=
' '.$this->getLibStatut(5, $this->alreadypaid);
1972 $datas[
'picto'] .=
' - '.$moretitle;
1974 if (!empty($this->
ref)) {
1975 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1977 if (!empty($this->ref_customer)) {
1978 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_customer;
1980 if (!empty($this->date)) {
1981 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
1983 if (!empty($this->total_ht)) {
1984 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
1986 if (!empty($this->total_tva)) {
1987 $datas[
'amountvat'] =
'<br><b>'.$langs->trans(
'AmountVAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
1989 if (!empty($this->revenuestamp) && $this->revenuestamp != 0) {
1990 $datas[
'amountrevenustamp'] =
'<br><b>'.$langs->trans(
'RevenueStamp').
':</b> '.
price($this->revenuestamp, 0, $langs, 0, -1, -1, $conf->currency);
1992 if (!empty($this->total_localtax1) && $this->total_localtax1 != 0) {
1994 $datas[
'amountlt1'] =
'<br><b>'.$langs->transcountry(
'AmountLT1', $mysoc->country_code).
':</b> '.
price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency);
1996 if (!empty($this->total_localtax2) && $this->total_localtax2 != 0) {
1997 $datas[
'amountlt2'] =
'<br><b>'.$langs->transcountry(
'AmountLT2', $mysoc->country_code).
':</b> '.
price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency);
1999 if (!empty($this->total_ttc)) {
2000 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
2021 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $addlinktonotes = 0, $save_lastsearch_value = -1, $target =
'')
2023 global $langs, $conf, $user, $mysoc;
2025 if (!empty($conf->dol_no_mouse_hover)) {
2031 if ($option ==
'withdraw') {
2032 $url = DOL_URL_ROOT.
'/compta/facture/prelevement.php?facid='.$this->id;
2034 $url = DOL_URL_ROOT.
'/compta/facture/card.php?facid='.$this->id;
2037 if (!$user->hasRight(
"facture",
"read")) {
2041 if ($option !==
'nolink') {
2043 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
2044 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
2045 $add_save_lastsearch_values = 1;
2047 if ($add_save_lastsearch_values) {
2048 $url .=
'&save_lastsearch_values=1';
2056 $picto = $this->picto;
2057 if ($this->
type == self::TYPE_REPLACEMENT) {
2060 if ($this->
type == self::TYPE_CREDIT_NOTE) {
2063 if ($this->
type == self::TYPE_DEPOSIT) {
2068 'objecttype' => $this->element,
2069 'moretitle' => $moretitle,
2070 'option' => $option,
2072 $classfortooltip =
'classfortooltip';
2075 $classfortooltip =
'classforajaxtooltip';
2076 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
2082 $linkclose = ($target ?
' target="'.$target.
'"' :
'');
2083 if (empty($notooltip) && $user->hasRight(
"facture",
"read")) {
2084 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
2085 $label = $langs->trans(
"Invoice");
2086 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
2088 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
2089 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
2092 $linkstart =
'<a href="'.$url.
'"';
2093 $linkstart .= $linkclose.
'>';
2096 if ($option ==
'nolink') {
2101 $result .= $linkstart;
2103 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'"'), 0, 0, $notooltip ? 0 : 1);
2105 if ($withpicto != 2) {
2106 $result .= ($max ?
dol_trunc($this->
ref, $max) : $this->ref);
2108 $result .= $linkend;
2110 if ($addlinktonotes) {
2111 $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private);
2114 $notetoshow = $langs->trans(
"ViewPrivateNote").
':<br>'.$txttoshow;
2115 $result .=
' <span class="note inline-block">';
2116 $result .=
'<a href="'.DOL_URL_ROOT.
'/compta/facture/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($notetoshow, 1, 1).
'">';
2121 $result .=
'</span>';
2125 global $action, $hookmanager;
2126 $hookmanager->initHooks(array(
'invoicedao'));
2127 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result,
'notooltip' => $notooltip,
'addlinktonotes' => $addlinktonotes,
'save_lastsearch_value'=> $save_lastsearch_value,
'target' => $target);
2128 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
2130 $result = $hookmanager->resPrint;
2132 $result .= $hookmanager->resPrint;
2021 public function getNomUrl($withpicto = 0, $option =
'', $max = 0, $short = 0, $moretitle =
'', $notooltip = 0, $addlinktonotes = 0, $save_lastsearch_value = -1, $target =
'') {
…}
2148 public function fetch($rowid, $ref =
'', $ref_ext =
'', $notused =
'', $fetch_situation =
false)
2150 if (empty($rowid) && empty($ref) && empty($ref_ext)) {
2154 $sql =
'SELECT f.rowid, f.entity, f.ref, f.ref_client, f.ref_ext, f.type, f.fk_soc';
2155 $sql .=
', f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc, f.revenuestamp';
2156 $sql .=
', f.remise_percent, f.remise_absolue, f.remise';
2157 $sql .=
', f.datef as df, f.date_pointoftax';
2158 $sql .=
', f.date_lim_reglement as dlr';
2159 $sql .=
', f.datec as datec';
2160 $sql .=
', f.date_valid as datev';
2161 $sql .=
', f.tms as datem';
2162 $sql .=
', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.fk_user_modif, f.model_pdf, f.last_main_doc';
2163 $sql .=
', f.fk_facture_source, f.fk_fac_rec_source';
2164 $sql .=
', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet as fk_project, f.extraparams';
2165 $sql .=
', f.situation_cycle_ref, f.situation_counter, f.situation_final';
2166 $sql .=
', f.fk_account';
2167 $sql .=
", f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc";
2168 $sql .=
', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
2169 $sql .=
', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
2170 $sql .=
', f.fk_incoterms, f.location_incoterms';
2171 $sql .=
', f.module_source, f.pos_source';
2172 $sql .=
", i.libelle as label_incoterms";
2173 $sql .=
", f.retained_warranty as retained_warranty, f.retained_warranty_date_limit as retained_warranty_date_limit, f.retained_warranty_fk_cond_reglement as retained_warranty_fk_cond_reglement";
2174 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facture as f';
2175 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
2176 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as p ON f.fk_mode_reglement = p.id';
2177 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON f.fk_incoterms = i.rowid';
2180 $sql .=
" WHERE f.rowid = ".((int) $rowid);
2182 $sql .=
' WHERE f.entity IN ('.getEntity(
'invoice').
')';
2184 $sql .=
" AND f.ref = '".$this->db->escape($ref).
"'";
2187 $sql .=
" AND f.ref_ext = '".$this->db->escape($ref_ext).
"'";
2191 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
2192 $resql = $this->db->query($sql);
2194 if ($this->db->num_rows($resql)) {
2195 $obj = $this->db->fetch_object($resql);
2197 $this->
id = $obj->rowid;
2198 $this->entity = $obj->entity;
2200 $this->
ref = $obj->ref;
2201 $this->ref_client = $obj->ref_client;
2202 $this->ref_customer = $obj->ref_client;
2203 $this->ref_ext = $obj->ref_ext;
2204 $this->
type = $obj->type;
2205 $this->date = $this->db->jdate($obj->df);
2206 $this->date_pointoftax = $this->db->jdate($obj->date_pointoftax);
2207 $this->date_creation = $this->db->jdate($obj->datec);
2208 $this->date_validation = $this->db->jdate($obj->datev);
2209 $this->date_modification = $this->db->jdate($obj->datem);
2210 $this->datem = $this->db->jdate($obj->datem);
2211 $this->remise_percent = $obj->remise_percent;
2212 $this->remise_absolue = $obj->remise_absolue;
2213 $this->total_ht = $obj->total_ht;
2214 $this->total_tva = $obj->total_tva;
2215 $this->total_localtax1 = $obj->localtax1;
2216 $this->total_localtax2 = $obj->localtax2;
2217 $this->total_ttc = $obj->total_ttc;
2218 $this->revenuestamp = $obj->revenuestamp;
2219 $this->paye = $obj->paye;
2220 $this->close_code = $obj->close_code;
2221 $this->close_note = $obj->close_note;
2223 $this->socid = $obj->fk_soc;
2224 $this->thirdparty =
null;
2226 $this->fk_project = $obj->fk_project;
2227 $this->project =
null;
2229 $this->
statut = $obj->fk_statut;
2230 $this->status = $obj->fk_statut;
2232 $this->date_lim_reglement = $this->db->jdate($obj->dlr);
2233 $this->mode_reglement_id = $obj->fk_mode_reglement;
2234 $this->mode_reglement_code = $obj->mode_reglement_code;
2235 $this->mode_reglement = $obj->mode_reglement_libelle;
2236 $this->cond_reglement_id = $obj->fk_cond_reglement;
2237 $this->cond_reglement_code = $obj->cond_reglement_code;
2238 $this->cond_reglement = $obj->cond_reglement_libelle;
2239 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
2240 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
2241 $this->fk_facture_source = $obj->fk_facture_source;
2242 $this->fk_fac_rec_source = $obj->fk_fac_rec_source;
2243 $this->note = $obj->note_private;
2244 $this->note_private = $obj->note_private;
2245 $this->note_public = $obj->note_public;
2246 $this->user_author = $obj->fk_user_author;
2247 $this->user_valid = $obj->fk_user_valid;
2248 $this->user_modification = $obj->fk_user_modif;
2249 $this->fk_user_author = $obj->fk_user_author;
2250 $this->fk_user_valid = $obj->fk_user_valid;
2251 $this->fk_user_modif = $obj->fk_user_modif;
2252 $this->model_pdf = $obj->model_pdf;
2253 $this->modelpdf = $obj->model_pdf;
2254 $this->last_main_doc = $obj->last_main_doc;
2255 $this->situation_cycle_ref = $obj->situation_cycle_ref;
2256 $this->situation_counter = $obj->situation_counter;
2257 $this->situation_final = $obj->situation_final;
2258 $this->retained_warranty = $obj->retained_warranty;
2259 $this->retained_warranty_date_limit = $this->db->jdate($obj->retained_warranty_date_limit);
2260 $this->retained_warranty_fk_cond_reglement = $obj->retained_warranty_fk_cond_reglement;
2262 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
2265 $this->fk_incoterms = $obj->fk_incoterms;
2266 $this->location_incoterms = $obj->location_incoterms;
2267 $this->label_incoterms = $obj->label_incoterms;
2269 $this->module_source = $obj->module_source;
2270 $this->pos_source = $obj->pos_source;
2273 $this->fk_multicurrency = $obj->fk_multicurrency;
2274 $this->multicurrency_code = $obj->multicurrency_code;
2275 $this->multicurrency_tx = $obj->multicurrency_tx;
2276 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
2277 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
2278 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
2280 if (($this->
type == self::TYPE_SITUATION || ($this->
type == self::TYPE_CREDIT_NOTE && $this->situation_cycle_ref > 0)) && $fetch_situation) {
2284 if ($this->status == self::STATUS_DRAFT) {
2285 $this->brouillon = 1;
2293 $this->lines = array();
2297 $this->error = $this->db->error();
2301 $this->db->free($resql);
2305 $this->error =
'Invoice with id='.$rowid.
' or ref='.$ref.
' or ref_ext='.$ref_ext.
' not found';
2307 dol_syslog(__METHOD__.$this->error, LOG_WARNING);
2311 $this->error = $this->db->lasterror();
2148 public function fetch($rowid, $ref =
'', $ref_ext =
'', $notused =
'', $fetch_situation =
false) {
…}
2326 public function fetch_lines($only_product = 0, $loadalsotranslation = 0)
2329 global $langs, $conf;
2331 $this->lines = array();
2333 $sql =
'SELECT l.rowid, l.fk_facture, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx,';
2334 $sql .=
' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice, l.ref_ext,';
2335 $sql .=
' l.situation_percent, l.fk_prev_id,';
2336 $sql .=
' l.rang, l.special_code,';
2337 $sql .=
' l.date_start as date_start, l.date_end as date_end,';
2338 $sql .=
' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
2339 $sql .=
' l.fk_unit,';
2340 $sql .=
' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
2341 $sql .=
' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
2342 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facturedet as l';
2343 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON l.fk_product = p.rowid';
2344 $sql .=
' WHERE l.fk_facture = '.((int) $this->
id);
2345 $sql .=
' ORDER BY l.rang, l.rowid';
2347 dol_syslog(get_class($this).
'::fetch_lines', LOG_DEBUG);
2348 $result = $this->db->query($sql);
2350 $num = $this->db->num_rows($result);
2353 $objp = $this->db->fetch_object($result);
2356 $line->id = $objp->rowid;
2357 $line->rowid = $objp->rowid;
2358 $line->fk_facture = $objp->fk_facture;
2359 $line->label = $objp->custom_label;
2360 $line->desc = $objp->description;
2361 $line->description = $objp->description;
2362 $line->product_type = $objp->product_type;
2363 $line->ref = $objp->product_ref;
2364 $line->product_ref = $objp->product_ref;
2365 $line->libelle = $objp->product_label;
2366 $line->product_label = $objp->product_label;
2367 $line->product_desc = $objp->product_desc;
2368 $line->fk_product_type = $objp->fk_product_type;
2369 $line->qty = $objp->qty;
2370 $line->subprice = $objp->subprice;
2371 $line->ref_ext = $objp->ref_ext;
2373 $line->vat_src_code = $objp->vat_src_code;
2374 $line->tva_tx = $objp->tva_tx;
2375 $line->localtax1_tx = $objp->localtax1_tx;
2376 $line->localtax2_tx = $objp->localtax2_tx;
2377 $line->localtax1_type = $objp->localtax1_type;
2378 $line->localtax2_type = $objp->localtax2_type;
2379 $line->remise_percent = $objp->remise_percent;
2380 $line->fk_remise_except = $objp->fk_remise_except;
2381 $line->fk_product = $objp->fk_product;
2382 $line->date_start = $this->db->jdate($objp->date_start);
2383 $line->date_end = $this->db->jdate($objp->date_end);
2384 $line->info_bits = $objp->info_bits;
2385 $line->total_ht = $objp->total_ht;
2386 $line->total_tva = $objp->total_tva;
2387 $line->total_localtax1 = $objp->total_localtax1;
2388 $line->total_localtax2 = $objp->total_localtax2;
2389 $line->total_ttc = $objp->total_ttc;
2390 $line->code_ventilation = $objp->fk_code_ventilation;
2391 $line->fk_fournprice = $objp->fk_fournprice;
2392 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
2393 $line->pa_ht = $marginInfos[0];
2394 $line->marge_tx = $marginInfos[1];
2395 $line->marque_tx = $marginInfos[2];
2396 $line->rang = $objp->rang;
2397 $line->special_code = $objp->special_code;
2398 $line->fk_parent_line = $objp->fk_parent_line;
2399 $line->situation_percent = $objp->situation_percent;
2400 $line->fk_prev_id = $objp->fk_prev_id;
2401 $line->fk_unit = $objp->fk_unit;
2404 $line->fk_accounting_account = $objp->fk_code_ventilation;
2407 $line->fk_multicurrency = $objp->fk_multicurrency;
2408 $line->multicurrency_code = $objp->multicurrency_code;
2409 $line->multicurrency_subprice = $objp->multicurrency_subprice;
2410 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
2411 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
2412 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
2414 $line->fetch_optionals();
2417 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
2418 $tmpproduct =
new Product($this->db);
2419 $tmpproduct->fetch($objp->fk_product);
2420 $tmpproduct->getMultiLangs();
2422 $line->multilangs = $tmpproduct->multilangs;
2425 $this->lines[$i] = $line;
2429 $this->db->free($result);
2432 $this->error = $this->db->error();
2326 public function fetch_lines($only_product = 0, $loadalsotranslation = 0) {
…}
2447 $this->tab_previous_situation_invoice = array();
2448 $this->tab_next_situation_invoice = array();
2450 $sql =
'SELECT rowid, type, situation_cycle_ref, situation_counter FROM '.MAIN_DB_PREFIX.
'facture';
2451 $sql .=
" WHERE rowid <> ".((int) $this->
id);
2452 $sql .=
' AND entity = '.((int) $this->entity);
2453 $sql .=
' AND situation_cycle_ref = '.(int) $this->situation_cycle_ref;
2454 $sql .=
' ORDER BY situation_counter ASC';
2456 dol_syslog(get_class($this).
'::fetchPreviousNextSituationInvoice ', LOG_DEBUG);
2457 $result = $this->db->query($sql);
2458 if ($result && $this->db->num_rows($result) > 0) {
2459 while ($objp = $this->db->fetch_object($result)) {
2460 $invoice =
new Facture($this->db);
2461 if ($invoice->fetch($objp->rowid) > 0) {
2462 if ($objp->situation_counter < $this->situation_counter
2463 || ($objp->situation_counter == $this->situation_counter && $objp->rowid < $this->id)
2465 $this->tab_previous_situation_invoice[] = $invoice;
2467 $this->tab_next_situation_invoice[] = $invoice;
2486 if (empty($this->
type)) {
2489 if (isset($this->
ref)) {
2490 $this->
ref = trim($this->
ref);
2492 if (isset($this->ref_ext)) {
2493 $this->ref_ext = trim($this->ref_ext);
2495 if (isset($this->ref_client)) {
2496 $this->ref_client = trim($this->ref_client);
2498 if (isset($this->increment)) {
2499 $this->increment = trim($this->increment);
2501 if (isset($this->close_code)) {
2502 $this->close_code = trim($this->close_code);
2504 if (isset($this->close_note)) {
2505 $this->close_note = trim($this->close_note);
2507 if (isset($this->note) || isset($this->note_private)) {
2508 $this->note = (isset($this->note) ? trim($this->note) : trim($this->note_private));
2510 if (isset($this->note) || isset($this->note_private)) {
2511 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
2513 if (isset($this->note_public)) {
2514 $this->note_public = trim($this->note_public);
2516 if (isset($this->model_pdf)) {
2517 $this->model_pdf = trim($this->model_pdf);
2519 if (isset($this->import_key)) {
2520 $this->import_key = trim($this->import_key);
2522 if (isset($this->retained_warranty)) {
2523 $this->retained_warranty = floatval($this->retained_warranty);
2525 if (!isset($this->fk_user_author) && isset($this->user_author) ) {
2526 $this->fk_user_author = $this->user_author;
2534 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facture SET";
2535 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
2536 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
2537 $sql .=
" type=".(isset($this->
type) ? $this->db->escape($this->
type) :
"null").
",";
2538 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
2539 $sql .=
" increment=".(isset($this->increment) ?
"'".$this->db->escape($this->increment).
"'" :
"null").
",";
2540 $sql .=
" fk_soc=".(isset($this->socid) ? $this->db->escape($this->socid) :
"null").
",";
2541 $sql .=
" datec=".(strval($this->date_creation) !=
'' ?
"'".$this->db->idate($this->date_creation).
"'" :
'null').
",";
2542 $sql .=
" datef=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
2543 $sql .=
" date_pointoftax=".(strval($this->date_pointoftax) !=
'' ?
"'".$this->db->idate($this->date_pointoftax).
"'" :
'null').
",";
2544 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
2545 $sql .=
" paye=".(isset($this->paye) ? $this->db->escape($this->paye) : 0).
",";
2546 $sql .=
" remise_percent=".(isset($this->remise_percent) ? $this->db->escape($this->remise_percent) :
"null").
",";
2547 $sql .=
" remise_absolue=".(isset($this->remise_absolue) ? $this->db->escape($this->remise_absolue) :
"null").
",";
2548 $sql .=
" close_code=".(isset($this->close_code) ?
"'".$this->db->escape($this->close_code).
"'" :
"null").
",";
2549 $sql .=
" close_note=".(isset($this->close_note) ?
"'".$this->db->escape($this->close_note).
"'" :
"null").
",";
2550 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
2551 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
2552 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
2553 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
2554 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
2555 $sql .=
" revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp !=
'') ? $this->db->escape($this->revenuestamp) :
"null").
",";
2556 $sql .=
" fk_statut=".(isset($this->
statut) ? $this->db->escape($this->
statut) :
"null").
",";
2557 $sql .=
" fk_user_author=".(isset($this->fk_user_author) ? $this->db->escape($this->fk_user_author) :
"null").
",";
2558 $sql .=
" fk_user_valid=".(isset($this->fk_user_valid) ? $this->db->escape($this->fk_user_valid) :
"null").
",";
2559 $sql .=
" fk_facture_source=".(isset($this->fk_facture_source) ? $this->db->escape($this->fk_facture_source) :
"null").
",";
2560 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->db->escape($this->fk_project) :
"null").
",";
2561 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->db->escape($this->cond_reglement_id) :
"null").
",";
2562 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->db->escape($this->mode_reglement_id) :
"null").
",";
2563 $sql .=
" date_lim_reglement=".(strval($this->date_lim_reglement) !=
'' ?
"'".$this->db->idate($this->date_lim_reglement).
"'" :
'null').
",";
2564 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
2565 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
2566 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
2567 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null").
",";
2568 $sql .=
" situation_cycle_ref=".(empty($this->situation_cycle_ref) ?
"null" : $this->db->escape($this->situation_cycle_ref)).
",";
2569 $sql .=
" situation_counter=".(empty($this->situation_counter) ?
"null" : $this->db->escape($this->situation_counter)).
",";
2570 $sql .=
" situation_final=".(empty($this->situation_final) ?
"0" : $this->db->escape($this->situation_final)).
",";
2571 $sql .=
" retained_warranty=".(empty($this->retained_warranty) ?
"0" : $this->db->escape($this->retained_warranty)).
",";
2572 $sql .=
" retained_warranty_date_limit=".(strval($this->retained_warranty_date_limit) !=
'' ?
"'".$this->db->idate($this->retained_warranty_date_limit).
"'" :
'null').
",";
2573 $sql .=
" retained_warranty_fk_cond_reglement=".(isset($this->retained_warranty_fk_cond_reglement) ?intval($this->retained_warranty_fk_cond_reglement) :
"null");
2574 $sql .=
" WHERE rowid=".((int) $this->
id);
2578 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
2579 $resql = $this->db->query($sql);
2582 $this->errors[] =
"Error ".$this->db->lasterror();
2592 if (!$error && !$notrigger) {
2603 foreach ($this->errors as $errmsg) {
2604 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2605 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2607 $this->db->rollback();
2610 $this->db->commit();
2626 global $conf, $langs;
2628 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
2629 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
2634 $result = $remise->fetch($idremise);
2637 if ($remise->fk_facture) {
2638 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
2639 $this->db->rollback();
2644 $facligne->fk_facture = $this->id;
2645 $facligne->fk_remise_except = $remise->id;
2646 $facligne->desc = $remise->description;
2647 $facligne->vat_src_code = $remise->vat_src_code;
2648 $facligne->tva_tx = $remise->tva_tx;
2649 $facligne->subprice = -$remise->amount_ht;
2650 $facligne->fk_product = 0;
2652 $facligne->remise_percent = 0;
2653 $facligne->rang = -1;
2654 $facligne->info_bits = 2;
2656 if (!empty($conf->global->MAIN_ADD_LINE_AT_POSITION)) {
2657 $facligne->rang = 1;
2658 $linecount = count($this->lines);
2659 for ($ii = 1; $ii <= $linecount; $ii++) {
2665 if ($remise->fk_facture_source > 0) {
2666 $srcinvoice =
new Facture($this->db);
2667 $srcinvoice->fetch($remise->fk_facture_source);
2668 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmargin.class.php';
2670 $arraytmp = $formmargin->getMarginInfosArray($srcinvoice,
false);
2671 $facligne->pa_ht = $arraytmp[
'pa_total'];
2674 $facligne->total_ht = -$remise->amount_ht;
2675 $facligne->total_tva = -$remise->amount_tva;
2676 $facligne->total_ttc = -$remise->amount_ttc;
2678 $facligne->multicurrency_subprice = -$remise->multicurrency_subprice;
2679 $facligne->multicurrency_total_ht = -$remise->multicurrency_amount_ht;
2680 $facligne->multicurrency_total_tva = -$remise->multicurrency_amount_tva;
2681 $facligne->multicurrency_total_ttc = -$remise->multicurrency_amount_ttc;
2683 $lineid = $facligne->insert();
2688 $result = $remise->link_to_invoice($lineid, 0);
2690 $this->error = $remise->error;
2691 $this->db->rollback();
2695 $this->db->commit();
2698 $this->error = $facligne->error;
2699 $this->db->rollback();
2703 $this->error = $facligne->error;
2704 $this->db->rollback();
2708 $this->db->rollback();
2730 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
2731 if (empty($ref_client)) {
2732 $sql .=
' SET ref_client = NULL';
2734 $sql .=
' SET ref_client = \''.$this->db->escape($ref_client).
'\'';
2736 $sql .=
" WHERE rowid = ".((int) $this->
id);
2738 dol_syslog(__METHOD__.
' this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2739 $resql = $this->db->query($sql);
2741 $this->errors[] = $this->db->error();
2746 $this->ref_client = $ref_client;
2749 if (!$notrigger && empty($error)) {
2759 $this->ref_client = $ref_client;
2761 $this->db->commit();
2764 foreach ($this->errors as $errmsg) {
2765 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2766 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2768 $this->db->rollback();
2781 public function delete($user, $notrigger = 0, $idwarehouse = -1)
2783 global $langs, $conf;
2784 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2788 dol_syslog(get_class($this).
"::delete rowid=".$rowid.
", ref=".$this->ref.
", thirdparty=".(empty($this->thirdparty) ?
'' : $this->thirdparty->name), LOG_DEBUG);
2801 if (!$error && !$notrigger) {
2815 dol_syslog(get_class($this).
"::delete error deleteExtraFields ".$this->error, LOG_ERR);
2829 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'societe_remise_except';
2830 $sql .=
' WHERE fk_facture_source = '.((int) $rowid);
2831 $sql .=
' AND fk_facture_line IS NULL';
2832 $resql = $this->db->query($sql);
2836 $list_rowid_det = array();
2837 foreach ($this->lines as $key => $invoiceline) {
2838 $list_rowid_det[] = $invoiceline->id;
2842 if (count($list_rowid_det)) {
2843 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
2844 $sql .=
' SET fk_facture = NULL, fk_facture_line = NULL';
2845 $sql .=
' WHERE fk_facture_line IN ('.$this->db->sanitize(join(
',', $list_rowid_det)).
')';
2847 if (!$this->db->query($sql)) {
2848 $this->error = $this->db->error().
" sql=".$sql;
2849 $this->errors[] = $this->error;
2850 $this->db->rollback();
2857 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'eventorganization_conferenceorboothattendee';
2858 $sql .=
' SET fk_invoice = NULL';
2859 $sql .=
' WHERE fk_invoice = '.((int) $rowid);
2861 if (!$this->db->query($sql)) {
2862 $this->error = $this->db->error().
" sql=".$sql;
2863 $this->errors[] = $this->error;
2864 $this->db->rollback();
2868 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'element_time';
2869 $sql .=
' SET invoice_id = NULL, invoice_line_id = NULL';
2870 $sql .=
' WHERE invoice_id = '.((int) $rowid);
2872 if (!$this->db->query($sql)) {
2873 $this->error = $this->db->error().
" sql=".$sql;
2874 $this->errors[] = $this->error;
2875 $this->db->rollback();
2880 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse != -1) {
2881 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
2882 $langs->load(
"agenda");
2884 $num = count($this->lines);
2885 for ($i = 0; $i < $num; $i++) {
2886 if ($this->lines[$i]->fk_product > 0) {
2888 $mouvP->origin = &$this;
2889 $mouvP->setOrigin($this->element, $this->
id);
2891 if ($this->
type == self::TYPE_CREDIT_NOTE) {
2892 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceDeleteDolibarr", $this->ref));
2894 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceDeleteDolibarr", $this->ref));
2901 $main = MAIN_DB_PREFIX.
'facturedet';
2902 $ef = $main.
"_extrafields";
2903 $sqlef =
"DELETE FROM ".$ef.
" WHERE fk_object IN (SELECT rowid FROM ".$main.
" WHERE fk_facture = ".((int) $rowid).
")";
2905 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'facturedet WHERE fk_facture = '.((int) $rowid);
2908 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
'facture WHERE rowid = '.((int) $rowid);
2910 $resql = $this->db->query($sql);
2917 if ($conf->facture->dir_output && !empty($this->
ref)) {
2918 $dir = $conf->facture->dir_output.
"/".$ref;
2919 $file = $conf->facture->dir_output.
"/".$ref.
"/".$ref.
".pdf";
2920 if (file_exists($file)) {
2924 $langs->load(
"errors");
2925 $this->error = $langs->trans(
"ErrorFailToDeleteFile", $file);
2926 $this->errors[] = $this->error;
2927 $this->db->rollback();
2931 if (file_exists($dir)) {
2933 $langs->load(
"errors");
2934 $this->error = $langs->trans(
"ErrorFailToDeleteDir", $dir);
2935 $this->errors[] = $this->error;
2936 $this->db->rollback();
2942 $this->db->commit();
2945 $this->error = $this->db->lasterror().
" sql=".$sql;
2946 $this->errors[] = $this->error;
2947 $this->db->rollback();
2951 $this->error = $this->db->lasterror().
" sql=".$sql;
2952 $this->errors[] = $this->error;
2953 $this->db->rollback();
2957 $this->db->rollback();
2781 public function delete($user, $notrigger = 0, $idwarehouse = -1) {
…}
2974 public function set_paid($user, $close_code =
'', $close_note =
'')
2977 dol_syslog(get_class($this).
"::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
2978 return $this->
setPaid($user, $close_code, $close_note);
2974 public function set_paid($user, $close_code =
'', $close_note =
'') {
…}
2990 public function setPaid($user, $close_code =
'', $close_note =
'')
2994 if ($this->paye != 1) {
2999 dol_syslog(get_class($this).
"::setPaid rowid=".((
int) $this->
id), LOG_DEBUG);
3001 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET';
3002 $sql .=
' fk_statut='.self::STATUS_CLOSED;
3007 $sql .=
", close_code='".$this->db->escape($close_code).
"'";
3010 $sql .=
", close_note='".$this->db->escape($close_note).
"'";
3012 $sql .=
', fk_user_closing = '.((int) $user->id);
3013 $sql .=
", date_closing = '".$this->db->idate($now).
"'";
3014 $sql .=
" WHERE rowid = ".((int) $this->
id);
3016 $resql = $this->db->query($sql);
3026 $this->error = $this->db->lasterror();
3030 $this->db->commit();
3033 $this->db->rollback();
2990 public function setPaid($user, $close_code =
'', $close_note =
'') {
…}
3056 dol_syslog(get_class($this).
"::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE);
3074 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
3075 $sql .=
' SET paye=0, fk_statut='.self::STATUS_VALIDATED.
', close_code=null, close_note=null,';
3076 $sql .=
' date_closing=null,';
3077 $sql .=
' fk_user_closing=null';
3078 $sql .=
" WHERE rowid = ".((int) $this->
id);
3080 dol_syslog(get_class($this).
"::setUnpaid", LOG_DEBUG);
3081 $resql = $this->db->query($sql);
3091 $this->error = $this->db->error();
3096 $this->db->commit();
3099 $this->db->rollback();
3121 dol_syslog(get_class($this).
"::set_canceled is deprecated, use setCanceled instead", LOG_NOTICE);
3122 return $this->
setCanceled($user, $close_code, $close_note);
3135 public function setCanceled($user, $close_code =
'', $close_note =
'')
3137 dol_syslog(get_class($this).
"::setCanceled rowid=".((
int) $this->
id), LOG_DEBUG);
3141 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET';
3142 $sql .=
' fk_statut='.self::STATUS_ABANDONED;
3144 $sql .=
", close_code='".$this->db->escape($close_code).
"'";
3147 $sql .=
", close_note='".$this->db->escape($close_note).
"'";
3149 $sql .=
" WHERE rowid = ".((int) $this->
id);
3151 $resql = $this->db->query($sql);
3155 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
3156 $sql .=
' SET fk_facture = NULL';
3157 $sql .=
' WHERE fk_facture = '.((int) $this->
id);
3159 $resql = $this->db->query($sql);
3164 $this->db->rollback();
3169 $this->db->commit();
3172 $this->error = $this->db->error().
" sql=".$sql;
3173 $this->db->rollback();
3177 $this->error = $this->db->error().
" sql=".$sql;
3178 $this->db->rollback();
3194 public function validate($user, $force_number =
'', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0)
3196 global $conf, $langs, $mysoc;
3197 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3199 $productStatic =
null;
3200 $warehouseStatic =
null;
3201 if ($batch_rule > 0) {
3202 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
3203 require_once DOL_DOCUMENT_ROOT.
'/product/class/productbatch.class.php';
3204 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
3205 $productStatic =
new Product($this->db);
3206 $warehouseStatic =
new Entrepot($this->db);
3213 dol_syslog(get_class($this).
'::validate user='.$user->id.
', force_number='.$force_number.
', idwarehouse='.$idwarehouse);
3220 if ($this->
statut != self::STATUS_DRAFT) {
3221 dol_syslog(get_class($this).
"::validate status is not draft. operation canceled.", LOG_WARNING);
3224 if (count($this->lines) <= 0) {
3225 $langs->load(
"errors");
3226 $this->error = $langs->trans(
"ErrorObjectMustHaveLinesToBeValidated", $this->
ref);
3229 if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->creer))
3230 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->invoice_advance->validate))) {
3231 $this->error =
'Permission denied';
3232 dol_syslog(get_class($this).
"::validate ".$this->error.
' MAIN_USE_ADVANCED_PERMS='.$conf->global->MAIN_USE_ADVANCED_PERMS, LOG_ERR);
3235 if ((preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) &&
3236 !empty($conf->global->FAC_FORCE_DATE_VALIDATION)
3241 if (!empty($conf->global-> INVOICE_CHECK_POSTERIOR_DATE)) {
3243 if (!$last_of_type[0]) {
3244 $this->error = $langs->transnoentities(
"ErrorInvoiceIsNotLastOfSameType", $this->
ref,
dol_print_date($this->date,
'day'),
dol_print_date($last_of_type[1],
'day'));
3250 if (!empty($this->thirdparty) && is_object($this->thirdparty)) {
3251 $array_to_check = array(
'IDPROF1',
'IDPROF2',
'IDPROF3',
'IDPROF4',
'IDPROF5',
'IDPROF6',
'EMAIL',
'ACCOUNTANCY_CODE_CUSTOMER');
3252 foreach ($array_to_check as $key) {
3253 $keymin = strtolower($key);
3254 if (!property_exists($this->thirdparty, $keymin)) {
3257 $vallabel = $this->thirdparty->$keymin;
3259 $i = (int) preg_replace(
'/[^0-9]/',
'', $key);
3261 if ($this->thirdparty->isACompany()) {
3263 if ($mysoc->country_id > 0 && $this->thirdparty->country_id == $mysoc->country_id) {
3264 $idprof_mandatory =
'SOCIETE_'.$key.
'_INVOICE_MANDATORY';
3265 if (!$vallabel && !empty($conf->global->$idprof_mandatory)) {
3266 $langs->load(
"errors");
3267 $this->error = $langs->trans(
'ErrorProdIdIsMandatory', $langs->transcountry(
'ProfId'.$i, $this->thirdparty->country_code)).
' ('.$langs->trans(
"ForbiddenBySetupRules").
') ['.$langs->trans(
'Company').
' : '.$this->thirdparty->name.
']';
3268 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3274 if ($key ==
'EMAIL') {
3276 if (!empty($conf->global->SOCIETE_EMAIL_INVOICE_MANDATORY) && !isValidEMail($this->thirdparty->email)) {
3277 $langs->load(
"errors");
3278 $this->error = $langs->trans(
"ErrorBadEMail", $this->thirdparty->email).
' ('.$langs->trans(
"ForbiddenBySetupRules").
') ['.$langs->trans(
'Company').
' : '.$this->thirdparty->name.
']';
3279 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3283 if ($key ==
'ACCOUNTANCY_CODE_CUSTOMER') {
3285 if (!empty($conf->global->SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_INVOICE_MANDATORY) && empty($this->thirdparty->code_compta)) {
3286 $langs->load(
"errors");
3287 $this->error = $langs->trans(
"ErrorAccountancyCodeCustomerIsMandatory", $this->thirdparty->name).
' ('.$langs->trans(
"ForbiddenBySetupRules").
')';
3288 dol_syslog(__METHOD__.
' '.$this->error, LOG_ERR);
3297 $array_to_check = array(
'REF_CLIENT'=>
'RefCustomer');
3298 foreach ($array_to_check as $key => $val) {
3299 $keymin = strtolower($key);
3300 $vallabel = $this->$keymin;
3303 $keymandatory =
'INVOICE_'.$key.
'_MANDATORY_FOR_VALIDATION';
3304 if (!$vallabel && !empty($conf->global->$keymandatory)) {
3305 $langs->load(
"errors");
3307 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv($val)),
null,
'errors');
3314 if ($this->
type == self::TYPE_REPLACEMENT) {
3316 if ($this->fk_facture_source <= 0) {
3317 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"InvoiceReplacement"));
3318 $this->db->rollback();
3323 $facreplaced =
new Facture($this->db);
3324 $result = $facreplaced->fetch($this->fk_facture_source);
3326 $this->error = $langs->trans(
"ErrorBadInvoice");
3327 $this->db->rollback();
3332 $idreplacement = $facreplaced->getIdReplacingInvoice(
'validated');
3333 if ($idreplacement && $idreplacement != $this->
id) {
3334 $facreplacement =
new Facture($this->db);
3335 $facreplacement->fetch($idreplacement);
3336 $this->error = $langs->trans(
"ErrorInvoiceAlreadyReplaced", $facreplaced->ref, $facreplacement->ref);
3337 $this->db->rollback();
3341 $result = $facreplaced->setCanceled($user, self::CLOSECODE_REPLACED,
'');
3343 $this->error = $facreplaced->error;
3344 $this->db->rollback();
3350 if ($force_number) {
3351 $num = $force_number;
3352 } elseif (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref)) {
3364 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
3365 $sql .=
" SET ref = '".$this->db->escape($num).
"', fk_statut = ".self::STATUS_VALIDATED.
", fk_user_valid = ".($user->id > 0 ? $user->id :
"null").
", date_valid = '".$this->db->idate($now).
"'";
3366 if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
3367 $sql .=
", datef='".$this->db->idate($this->date).
"'";
3368 $sql .=
", date_lim_reglement='".$this->db->idate($this->date_lim_reglement).
"'";
3370 $sql .=
" WHERE rowid = ".((int) $this->
id);
3372 dol_syslog(get_class($this).
"::validate", LOG_DEBUG);
3373 $resql = $this->db->query($sql);
3380 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref))) {
3386 $result = $this->thirdparty->set_as_client();
3389 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse > 0) {
3390 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
3391 $langs->load(
"agenda");
3394 $cpt = count($this->lines);
3395 for ($i = 0; $i < $cpt; $i++) {
3396 if ($this->lines[$i]->fk_product > 0) {
3398 $mouvP->origin = &$this;
3399 $mouvP->setOrigin($this->element, $this->
id);
3401 if ($this->
type == self::TYPE_CREDIT_NOTE) {
3402 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceValidatedInDolibarr", $num));
3405 $this->error = $mouvP->error;
3408 $is_batch_line =
false;
3409 if ($batch_rule > 0) {
3410 $productStatic->fetch($this->lines[$i]->fk_product);
3411 if ($productStatic->hasbatch()) {
3412 $is_batch_line =
true;
3413 $product_qty_remain = $this->lines[$i]->qty;
3419 $sortfield =
'pl.sellby,pl.eatby,pb.qty,pl.rowid';
3420 $sortorder =
'ASC,ASC,ASC,ASC';
3423 $resBatchList = $productbatch->findAllForProduct($productStatic->id, $idwarehouse, (
getDolGlobalInt(
'STOCK_ALLOW_NEGATIVE_TRANSFER') ?
null : 0), $sortfield, $sortorder);
3424 if (!is_array($resBatchList)) {
3426 $this->error = $this->db->lasterror();
3430 $batchList = $resBatchList;
3431 if (empty($batchList)) {
3433 $langs->load(
'errors');
3434 $warehouseStatic->fetch($idwarehouse);
3435 $this->error = $langs->trans(
'ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
3436 dol_syslog(__METHOD__.
' Error: '.$langs->transnoentitiesnoconv(
'ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
3439 foreach ($batchList as $batch) {
3440 if ($batch->qty <= 0) {
3445 if ($batch->qty >= $product_qty_remain) {
3446 $product_batch_qty = $product_qty_remain;
3449 $product_batch_qty = $batch->qty;
3451 $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_batch_qty, $this->lines[$i]->subprice, $langs->trans(
'InvoiceValidatedInDolibarr', $num),
'',
'',
'', $batch->batch);
3454 $this->error = $mouvP->error;
3455 $this->errors = $mouvP->errors;
3459 $product_qty_remain -= $product_batch_qty;
3461 if ($product_qty_remain <= 0) {
3466 if (!$error && $product_qty_remain > 0) {
3469 $batch = $batchList[0];
3470 $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans(
'InvoiceValidatedInDolibarr', $num),
'',
'',
'', $batch->batch);
3473 $this->error = $mouvP->error;
3474 $this->errors = $mouvP->errors;
3478 $langs->load(
'errors');
3479 $warehouseStatic->fetch($idwarehouse);
3480 $this->error = $langs->trans(
'ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
3481 dol_syslog(__METHOD__.
' Error: '.$langs->transnoentitiesnoconv(
'ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
3488 if (!$is_batch_line) {
3489 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceValidatedInDolibarr", $num));
3492 $this->error = $mouvP->error;
3493 $this->errors = $mouvP->errors;
3506 if (!$error && $this->
type == self::TYPE_CREDIT_NOTE && $this->fk_facture_source > 0) {
3507 $invoice_situation =
new Facture($this->db);
3508 $result = $invoice_situation->fetch($this->fk_facture_source);
3509 if ($result > 0 && $invoice_situation->type == self::TYPE_SITUATION && $invoice_situation->situation_final == 1) {
3510 $invoice_situation->situation_final = 0;
3512 $result = $invoice_situation->setFinal($user, 1);
3515 $this->error = $invoice_situation->error;
3516 $this->errors = $invoice_situation->errors;
3522 if (!$error && !$notrigger) {
3532 $this->oldref = $this->ref;
3535 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
3537 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'facture/".$this->db->escape($this->newref).
"'";
3538 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'facture/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
3539 $resql = $this->db->query($sql);
3542 $this->error = $this->db->lasterror();
3544 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'facture/".$this->db->escape($this->newref).
"'";
3545 $sql .=
" WHERE filepath = 'facture/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
3546 $resql = $this->db->query($sql);
3548 $error++; $this->error = $this->db->lasterror();
3554 $dirsource = $conf->facture->dir_output.
'/'.$oldref;
3555 $dirdest = $conf->facture->dir_output.
'/'.$newref;
3556 if (!$error && file_exists($dirsource)) {
3557 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
3559 if (@rename($dirsource, $dirdest)) {
3562 $listoffiles =
dol_dir_list($conf->facture->dir_output.
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
3563 foreach ($listoffiles as $fileentry) {
3564 $dirsource = $fileentry[
'name'];
3565 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
3566 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
3567 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
3568 @rename($dirsource, $dirdest);
3586 $this->brouillon = 0;
3587 $this->date_validation = $now;
3590 if (!empty($conf->global->INVOICE_USE_SITUATION)) {
3592 $nboflines = count($this->lines);
3593 while (($i < $nboflines) && $final) {
3594 $final = ($this->lines[$i]->situation_percent == 100);
3598 if (empty($final)) {
3599 $this->situation_final = 0;
3601 $this->situation_final = 1;
3612 $this->db->commit();
3615 $this->db->rollback();
3194 public function validate($user, $force_number =
'', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0) {
…}
3628 foreach ($this->tab_next_situation_invoice as $next_invoice) {
3629 $is_last = $next_invoice->is_last_in_cycle();
3631 if ($next_invoice->statut == self::STATUS_DRAFT && $is_last != 1) {
3632 $this->error = $langs->trans(
'updatePriceNextInvoiceErrorUpdateline', $next_invoice->ref);
3636 $next_invoice->brouillon = 1;
3638 foreach ($next_invoice->lines as $line) {
3639 $result = $next_invoice->updateline(
3644 $line->remise_percent,
3648 $line->localtax1_tx,
3649 $line->localtax2_tx,
3652 $line->product_type,
3653 $line->fk_parent_line,
3655 $line->fk_fournprice,
3658 $line->special_code,
3659 $line->array_options,
3660 $line->situation_percent,
3665 $this->error = $langs->trans(
'updatePriceNextInvoiceErrorUpdateline', $next_invoice->ref);
3686 global $conf, $langs;
3690 if ($this->
statut == self::STATUS_DRAFT) {
3691 dol_syslog(__METHOD__.
" already draft status", LOG_WARNING);
3699 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facture";
3700 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
3701 $sql .=
" WHERE rowid = ".((int) $this->
id);
3703 $result = $this->db->query($sql);
3706 $this->oldcopy = clone $this;
3710 if ($this->
type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
3711 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
3712 $langs->load(
"agenda");
3714 $num = count($this->lines);
3715 for ($i = 0; $i < $num; $i++) {
3716 if ($this->lines[$i]->fk_product > 0) {
3718 $mouvP->origin = &$this;
3719 $mouvP->setOrigin($this->element, $this->
id);
3721 if ($this->
type == self::TYPE_CREDIT_NOTE) {
3722 $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans(
"InvoiceBackToDraftInDolibarr", $this->ref));
3724 $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans(
"InvoiceBackToDraftInDolibarr", $this->ref));
3731 $old_statut = $this->statut;
3732 $this->brouillon = 1;
3737 $result = $this->
call_trigger(
'BILL_UNVALIDATE', $user);
3740 $this->
statut = $old_statut;
3741 $this->status = $old_statut;
3742 $this->brouillon = 0;
3746 $this->db->rollback();
3751 $this->db->commit();
3754 $this->db->rollback();
3758 $this->error = $this->db->error();
3759 $this->db->rollback();
3819 $fk_remise_except =
'',
3820 $price_base_type =
'HT',
3827 $fk_parent_line = 0,
3828 $fk_fournprice =
null,
3832 $situation_percent = 100,
3837 $noupdateafterinsertline = 0
3841 dol_syslog(__METHOD__.
": using line label is deprecated", LOG_WARNING);
3845 global $mysoc, $conf, $langs;
3847 dol_syslog(get_class($this).
"::addline id=$this->id, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product, remise_percent=$remise_percent, date_start=$date_start, date_end=$date_end, ventil=$ventil, info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, type=$type, fk_unit=$fk_unit, desc=".
dol_trunc($desc, 25), LOG_DEBUG);
3849 if ($this->
statut == self::STATUS_DRAFT) {
3850 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
3859 if (empty($info_bits)) {
3865 if (empty($ventil)) {
3868 if (empty($txtva)) {
3871 if (empty($txlocaltax1)) {
3874 if (empty($txlocaltax2)) {
3877 if (empty($fk_parent_line) || $fk_parent_line < 0) {
3878 $fk_parent_line = 0;
3880 if (empty($fk_prev_id)) {
3881 $fk_prev_id =
'null';
3883 if (!isset($situation_percent) || $situation_percent > 100 || (
string) $situation_percent ==
'') {
3884 $situation_percent = 100;
3886 if (empty($ref_ext)) {
3893 $pu_ht_devise =
price2num($pu_ht_devise);
3896 if (!preg_match(
'/\((.*)\)/', $txtva)) {
3902 if ($price_base_type ==
'HT') {
3913 if ($date_start && $date_end && $date_start > $date_end) {
3914 $langs->load(
"errors");
3915 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
3921 $product_type = $type;
3922 if (!empty($fk_product) && $fk_product > 0) {
3923 $product =
new Product($this->db);
3924 $result = $product->fetch($fk_product);
3925 $product_type = $product->type;
3927 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) {
3928 $langs->load(
"errors");
3929 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref);
3930 $this->db->rollback();
3940 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
3941 $vat_src_code = $reg[1];
3942 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
3950 $tabprice =
calcul_price_total($qty, $pu,
$remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, $situation_percent, $this->multicurrency_tx, $pu_ht_devise);
3952 $total_ht = $tabprice[0];
3953 $total_tva = $tabprice[1];
3954 $total_ttc = $tabprice[2];
3955 $total_localtax1 = $tabprice[9];
3956 $total_localtax2 = $tabprice[10];
3957 $pu_ht = $tabprice[3];
3960 $multicurrency_total_ht = $tabprice[16];
3961 $multicurrency_total_tva = $tabprice[17];
3962 $multicurrency_total_ttc = $tabprice[18];
3963 $pu_ht_devise = $tabprice[19];
3967 if ($ranktouse == -1) {
3968 $rangmax = $this->
line_max($fk_parent_line);
3969 $ranktouse = $rangmax + 1;
3975 $this->line->context = $this->context;
3977 $this->line->fk_facture = $this->id;
3978 $this->line->label = $label;
3979 $this->line->desc = $desc;
3980 $this->line->ref_ext = $ref_ext;
3982 $this->line->qty = ($this->
type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty);
3983 $this->line->subprice = ($this->
type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht);
3985 $this->line->vat_src_code = $vat_src_code;
3986 $this->line->tva_tx = $txtva;
3987 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
3988 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
3989 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
3990 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
3992 $this->line->total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht);
3993 $this->line->total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc);
3994 $this->line->total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_tva) : $total_tva);
3995 $this->line->total_localtax1 = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax1) : $total_localtax1);
3996 $this->line->total_localtax2 = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax2) : $total_localtax2);
3998 $this->line->fk_product = $fk_product;
3999 $this->line->product_type = $product_type;
4001 $this->line->date_start = $date_start;
4002 $this->line->date_end = $date_end;
4003 $this->line->ventil = $ventil;
4004 $this->line->rang = $ranktouse;
4005 $this->line->info_bits = $info_bits;
4006 $this->line->fk_remise_except = $fk_remise_except;
4008 $this->line->special_code = $special_code;
4009 $this->line->fk_parent_line = $fk_parent_line;
4010 $this->line->origin = $origin;
4011 $this->line->origin_id = $origin_id;
4012 $this->line->situation_percent = $situation_percent;
4013 $this->line->fk_prev_id = $fk_prev_id;
4014 $this->line->fk_unit = $fk_unit;
4017 $this->line->fk_fournprice = $fk_fournprice;
4018 $this->line->pa_ht = $pa_ht;
4021 $this->line->fk_multicurrency = $this->fk_multicurrency;
4022 $this->line->multicurrency_code = $this->multicurrency_code;
4023 $this->line->multicurrency_subprice = ($this->
type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht_devise) : $pu_ht_devise);
4025 $this->line->multicurrency_total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ht) : $multicurrency_total_ht);
4026 $this->line->multicurrency_total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_tva) : $multicurrency_total_tva);
4027 $this->line->multicurrency_total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ttc) : $multicurrency_total_ttc);
4029 if (is_array($array_options) && count($array_options) > 0) {
4030 $this->line->array_options = $array_options;
4033 $result = $this->line->insert();
4036 if (!empty($fk_parent_line)) {
4038 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
4039 $linecount = count($this->lines);
4040 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
4046 if (empty($noupdateafterinsertline)) {
4051 $this->db->commit();
4052 return $this->line->id;
4054 $this->error = $this->db->lasterror();
4055 $this->db->rollback();
4059 $this->error = $this->line->error;
4060 $this->errors = $this->line->errors;
4061 $this->db->rollback();
4065 $this->errors[]=
'status of invoice must be Draft to allow use of ->addline()';
4066 dol_syslog(get_class($this).
"::addline status of invoice must be Draft to allow use of ->addline()", LOG_ERR);
4102 public function updateline($rowid, $desc, $pu, $qty,
$remise_percent, $date_start, $date_end, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type =
'HT', $info_bits = 0, $type = self::TYPE_STANDARD, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice =
null, $pa_ht = 0, $label =
'', $special_code = 0, $array_options = 0, $situation_percent = 100, $fk_unit =
null, $pu_ht_devise = 0, $notrigger = 0, $ref_ext =
'', $rang = 0)
4104 global $conf, $user;
4107 dol_syslog(__METHOD__.
": using line label is deprecated", LOG_WARNING);
4110 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
4112 global $mysoc, $langs;
4114 dol_syslog(get_class($this).
"::updateline rowid=$rowid, desc=$desc, pu=$pu, qty=$qty, remise_percent=$remise_percent, date_start=$date_start, date_end=$date_end, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, price_base_type=$price_base_type, info_bits=$info_bits, type=$type, fk_parent_line=$fk_parent_line pa_ht=$pa_ht, special_code=$special_code, fk_unit=$fk_unit, pu_ht_devise=$pu_ht_devise", LOG_DEBUG);
4116 if ($this->
statut == self::STATUS_DRAFT) {
4119 if (!$this->error) {
4120 $this->error = $langs->trans(
'invoiceLineProgressError');
4126 if ($date_start && $date_end && $date_start > $date_end) {
4127 $langs->load(
"errors");
4128 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
4138 if (empty($fk_parent_line) || $fk_parent_line < 0) {
4139 $fk_parent_line = 0;
4141 if (empty($special_code) || $special_code == 3) {
4144 if (!isset($situation_percent) || $situation_percent > 100 || (
string) $situation_percent ==
'') {
4145 $situation_percent = 100;
4147 if (empty($ref_ext)) {
4154 $pu_ht_devise =
price2num($pu_ht_devise);
4156 if (!preg_match(
'/\((.*)\)/', $txtva)) {
4176 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
4177 $vat_src_code = $reg[1];
4178 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
4181 $tabprice =
calcul_price_total($qty, $pu,
$remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, $situation_percent, $this->multicurrency_tx, $pu_ht_devise);
4183 $total_ht = $tabprice[0];
4184 $total_tva = $tabprice[1];
4185 $total_ttc = $tabprice[2];
4186 $total_localtax1 = $tabprice[9];
4187 $total_localtax2 = $tabprice[10];
4188 $pu_ht = $tabprice[3];
4189 $pu_tva = $tabprice[4];
4190 $pu_ttc = $tabprice[5];
4193 $multicurrency_total_ht = $tabprice[16];
4194 $multicurrency_total_tva = $tabprice[17];
4195 $multicurrency_total_ttc = $tabprice[18];
4196 $pu_ht_devise = $tabprice[19];
4203 $price = ($pu - $remise);
4209 $line->fetch($rowid);
4210 $line->fetch_optionals();
4212 if (!empty($line->fk_product)) {
4213 $product =
new Product($this->db);
4214 $result = $product->fetch($line->fk_product);
4215 $product_type = $product->type;
4217 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) {
4218 $langs->load(
"errors");
4219 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref);
4220 $this->db->rollback();
4225 $staticline = clone $line;
4227 $line->oldline = $staticline;
4228 $this->line = $line;
4229 $this->line->context = $this->context;
4230 $this->line->rang = $rang;
4233 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
4234 $rangmax = $this->
line_max($fk_parent_line);
4235 $this->line->rang = $rangmax + 1;
4237 $apply_abs_price_on_credit_note=
false;
4239 $apply_abs_price_on_credit_note =
true;
4243 $this->line->id = $rowid;
4244 $this->line->rowid = $rowid;
4245 $this->line->label = $label;
4246 $this->line->desc = $desc;
4247 $this->line->ref_ext = $ref_ext;
4248 $this->line->qty = ($this->
type == self::TYPE_CREDIT_NOTE ?abs($qty) : $qty);
4250 $this->line->vat_src_code = $vat_src_code;
4251 $this->line->tva_tx = $txtva;
4252 $this->line->localtax1_tx = $txlocaltax1;
4253 $this->line->localtax2_tx = $txlocaltax2;
4254 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
4255 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
4258 $this->line->subprice = ($apply_abs_price_on_credit_note?-abs($pu_ht) : $pu_ht);
4259 $this->line->date_start = $date_start;
4260 $this->line->date_end = $date_end;
4261 $this->line->total_ht = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_ht) : $total_ht);
4262 $this->line->total_tva = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_tva) : $total_tva);
4263 $this->line->total_localtax1 = $total_localtax1;
4264 $this->line->total_localtax2 = $total_localtax2;
4265 $this->line->total_ttc = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_ttc) : $total_ttc);
4266 $this->line->info_bits = $info_bits;
4267 $this->line->special_code = $special_code;
4268 $this->line->product_type = $type;
4269 $this->line->fk_parent_line = $fk_parent_line;
4270 $this->line->skip_update_total = $skip_update_total;
4271 $this->line->situation_percent = $situation_percent;
4272 $this->line->fk_unit = $fk_unit;
4274 $this->line->fk_fournprice = $fk_fournprice;
4275 $this->line->pa_ht = $pa_ht;
4278 $this->line->multicurrency_subprice = ($this->
type == self::TYPE_CREDIT_NOTE ?-abs($pu_ht_devise) : $pu_ht_devise);
4279 $this->line->multicurrency_total_ht = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_ht) : $multicurrency_total_ht);
4280 $this->line->multicurrency_total_tva = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_tva) : $multicurrency_total_tva);
4281 $this->line->multicurrency_total_ttc = (($this->
type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($multicurrency_total_ttc) : $multicurrency_total_ttc);
4283 if (is_array($array_options) && count($array_options) > 0) {
4285 foreach ($array_options as $key => $value) {
4286 $this->line->array_options[$key] = $array_options[$key];
4290 $result = $this->line->update($user, $notrigger);
4293 if (!empty($fk_parent_line)) {
4299 $this->db->commit();
4302 $this->error = $this->line->error;
4303 $this->db->rollback();
4307 $this->error =
"Invoice statut makes operation forbidden";
4102 public function updateline($rowid, $desc, $pu, $qty,
$remise_percent, $date_start, $date_end, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type =
'HT', $info_bits = 0, $type = self::TYPE_STANDARD, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice =
null, $pa_ht = 0, $label =
'', $special_code = 0, $array_options = 0, $situation_percent = 100, $fk_unit =
null, $pu_ht_devise = 0, $notrigger = 0, $ref_ext =
'', $rang = 0) {
…}
4321 $sql =
'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.
'facturedet fd
4322 INNER JOIN '.MAIN_DB_PREFIX.
'facture f ON (fd.fk_facture = f.rowid)
4323 WHERE fd.fk_prev_id = '.((int) $idline).
' AND f.fk_statut <> 0';
4325 $result = $this->db->query($sql);
4327 $this->error = $this->db->error();
4331 $obj = $this->db->fetch_object($result);
4333 if ($obj ===
null) {
4336 return ($situation_percent < $obj->situation_percent);
4352 global $mysoc, $user;
4355 if (($line->info_bits & 2) == 2) {
4359 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
4362 if ($percent > 100) {
4365 $line->situation_percent = $percent;
4366 $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);
4367 $line->total_ht = $tabprice[0];
4368 $line->total_tva = $tabprice[1];
4369 $line->total_ttc = $tabprice[2];
4370 $line->total_localtax1 = $tabprice[9];
4371 $line->total_localtax2 = $tabprice[10];
4372 $line->multicurrency_total_ht = $tabprice[16];
4373 $line->multicurrency_total_tva = $tabprice[17];
4374 $line->multicurrency_total_ttc = $tabprice[18];
4375 $line->update($user);
4378 if ($update_price) {
4394 dol_syslog(get_class($this).
"::deleteline rowid=".((
int) $rowid), LOG_DEBUG);
4396 if ($this->
statut != self::STATUS_DRAFT) {
4397 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
4403 $line->context = $this->context;
4406 $result = $line->fetch($rowid);
4407 if (!($result > 0)) {
4412 if ($id > 0 && $line->fk_facture != $id) {
4413 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
4420 $staticline = clone $line;
4421 $line->oldline = $staticline;
4423 if ($line->delete($user) > 0) {
4427 $this->db->commit();
4430 $this->db->rollback();
4431 $this->error = $this->db->lasterror();
4435 $this->db->rollback();
4436 $this->error = $line->error;
4455 dol_syslog(get_class($this).
"::set_remise is deprecated, use setDiscount instead", LOG_NOTICE);
4456 return $this->
setDiscount($user, $remise, $notrigger);
4471 if (empty($remise)) {
4475 if ($user->hasRight(
'facture',
'creer')) {
4482 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
4483 $sql .=
' SET remise_percent = '.((float) $remise);
4484 $sql .=
" WHERE rowid = ".((int) $this->
id);
4485 $sql .=
' AND fk_statut = '.self::STATUS_DRAFT;
4488 $resql = $this->db->query($sql);
4490 $this->errors[] = $this->db->error();
4494 if (!$notrigger && empty($error)) {
4504 $this->remise_percent = $remise;
4507 $this->db->commit();
4510 foreach ($this->errors as $errmsg) {
4511 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
4512 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4514 $this->db->rollback();
4535 if (empty($remise)) {
4539 if ($user->hasRight(
'facture',
'creer')) {
4546 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture';
4547 $sql .=
' SET remise_absolue = '.((float) $remise);
4548 $sql .=
" WHERE rowid = ".((int) $this->
id);
4549 $sql .=
' AND fk_statut = '.self::STATUS_DRAFT;
4552 $resql = $this->db->query($sql);
4554 $this->errors[] = $this->db->error();
4559 $this->oldcopy = clone $this;
4560 $this->remise_absolue = $remise;
4564 if (!$notrigger && empty($error)) {
4574 $this->db->commit();
4577 foreach ($this->errors as $errmsg) {
4578 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
4579 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4581 $this->db->rollback();
4599 global $conf, $langs;
4601 if ($this->module_source ==
'takepos') {
4602 $langs->load(
'cashdesk');
4604 $moduleName =
'takepos';
4605 $moduleSourceName =
'Takepos';
4606 $addonConstName =
'TAKEPOS_REF_ADDON';
4609 if (empty($conf->global->TAKEPOS_REF_ADDON)) {
4610 $conf->global->TAKEPOS_REF_ADDON =
'mod_takepos_ref_simple';
4613 $addon = $conf->global->TAKEPOS_REF_ADDON;
4615 $langs->load(
'bills');
4617 $moduleName =
'facture';
4618 $moduleSourceName =
'Invoice';
4619 $addonConstName =
'FACTURE_ADDON';
4622 if (empty($conf->global->FACTURE_ADDON)) {
4623 $conf->global->FACTURE_ADDON =
'mod_facture_terre';
4624 } elseif ($conf->global->FACTURE_ADDON ==
'terre') {
4625 $conf->global->FACTURE_ADDON =
'mod_facture_terre';
4626 } elseif ($conf->global->FACTURE_ADDON ==
'mercure') {
4627 $conf->global->FACTURE_ADDON =
'mod_facture_mercure';
4630 $addon = $conf->global->FACTURE_ADDON;
4633 if (!empty($addon)) {
4634 dol_syslog(
"Call getNextNumRef with ".$addonConstName.
" = ".$conf->global->FACTURE_ADDON.
", thirdparty=".$soc->name.
", type=".$soc->typent_code.
", mode=".$mode, LOG_DEBUG);
4638 $file = $addon.
'.php';
4639 $classname = $addon;
4643 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
4644 foreach ($dirmodels as $reldir) {
4645 $dir =
dol_buildpath($reldir.
'core/modules/'.$moduleName.
'/');
4648 if (is_file($dir.$file) && is_readable($dir.$file)) {
4649 $mybool |= include_once $dir.$file;
4655 $file = $addon.
'/'.$addon.
'.modules.php';
4656 $classname =
'mod_'.$moduleName.
'_'.$addon;
4657 $classname = preg_replace(
'/\-.*$/',
'', $classname);
4659 foreach ($conf->file->dol_document_root as $dirroot) {
4660 $dir = $dirroot.
'/core/modules/'.$moduleName.
'/';
4663 if (is_file($dir.$file) && is_readable($dir.$file)) {
4664 $mybool |= include_once $dir.$file;
4674 $obj =
new $classname();
4676 $numref = $obj->getNextValue($soc, $this, $mode);
4683 if ($mode !=
'last' && !$numref) {
4684 $this->error = $obj->error;
4690 $langs->load(
'errors');
4691 print $langs->trans(
'Error').
' '.$langs->trans(
'ErrorModuleSetupNotComplete', $langs->transnoentitiesnoconv($moduleSourceName));
4704 $sql =
'SELECT c.rowid, datec, date_valid as datev, tms as datem,';
4705 $sql .=
' date_closing as dateclosing,';
4706 $sql .=
' fk_user_author, fk_user_valid, fk_user_closing';
4707 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facture as c';
4708 $sql .=
' WHERE c.rowid = '.((int) $id);
4710 $result = $this->db->query($sql);
4712 if ($this->db->num_rows($result)) {
4713 $obj = $this->db->fetch_object($result);
4714 $this->
id = $obj->rowid;
4715 if ($obj->fk_user_author) {
4716 $cuser =
new User($this->db);
4717 $cuser->fetch($obj->fk_user_author);
4718 $this->user_creation = $cuser;
4720 if ($obj->fk_user_valid) {
4721 $vuser =
new User($this->db);
4722 $vuser->fetch($obj->fk_user_valid);
4723 $this->user_validation = $vuser;
4725 if ($obj->fk_user_closing) {
4726 $cluser =
new User($this->db);
4727 $cluser->fetch($obj->fk_user_closing);
4728 $this->user_closing = $cluser;
4731 $this->date_creation = $this->db->jdate($obj->datec);
4732 $this->date_modification = $this->db->jdate($obj->datem);
4733 $this->date_validation = $this->db->jdate($obj->datev);
4734 $this->date_closing = $this->db->jdate($obj->dateclosing);
4736 $this->db->free($result);
4757 public function liste_array($shortlist = 0, $draft = 0, $excluser =
'', $socid = 0, $limit = 0, $offset = 0, $sortfield =
'f.datef,f.rowid', $sortorder =
'DESC')
4760 global $conf, $user;
4764 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
4765 $sql .=
" f.rowid as fid, f.ref as ref, f.datef as df";
4766 if (empty($user->rights->societe->client->voir) && !$socid) {
4767 $sql .=
", sc.fk_soc, sc.fk_user";
4769 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"facture as f";
4770 if (empty($user->rights->societe->client->voir) && !$socid) {
4771 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
4773 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice').
")";
4774 $sql .=
" AND f.fk_soc = s.rowid";
4775 if (empty($user->rights->societe->client->voir) && !$socid) {
4776 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
4779 $sql .=
" AND s.rowid = ".((int) $socid);
4782 $sql .=
" AND f.fk_statut = ".self::STATUS_DRAFT;
4784 if (is_object($excluser)) {
4785 $sql .=
" AND f.fk_user_author <> ".((int) $excluser->id);
4787 $sql .= $this->db->order($sortfield, $sortorder);
4788 $sql .= $this->db->plimit($limit, $offset);
4790 $result = $this->db->query($sql);
4792 $numc = $this->db->num_rows($result);
4795 while ($i < $numc) {
4796 $obj = $this->db->fetch_object($result);
4798 if ($shortlist == 1) {
4799 $ga[$obj->fid] = $obj->ref;
4800 } elseif ($shortlist == 2) {
4801 $ga[$obj->fid] = $obj->ref.
' ('.$obj->name.
')';
4803 $ga[$i][
'id'] = $obj->fid;
4804 $ga[$i][
'ref'] = $obj->ref;
4805 $ga[$i][
'name'] = $obj->name;
4757 public function liste_array($shortlist = 0, $draft = 0, $excluser =
'', $socid = 0, $limit = 0, $offset = 0, $sortfield =
'f.datef,f.rowid', $sortorder =
'DESC') {
…}
4834 $sql =
"SELECT f.rowid as rowid, f.ref, f.fk_statut as status, f.paye as paid,";
4835 $sql .=
" ff.rowid as rowidnext";
4837 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4838 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"paiement_facture as pf ON f.rowid = pf.fk_facture";
4839 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facture as ff ON f.rowid = ff.fk_facture_source";
4840 $sql .=
" WHERE (f.fk_statut = ".self::STATUS_VALIDATED.
" OR (f.fk_statut = ".self::STATUS_ABANDONED.
" AND f.close_code = '".self::CLOSECODE_ABANDONED.
"'))";
4841 $sql .=
" AND f.entity IN (".getEntity(
'invoice').
")";
4842 $sql .=
" AND f.paye = 0";
4843 $sql .=
" AND pf.fk_paiement IS NULL";
4844 $sql .=
" AND ff.fk_statut IS NULL";
4846 $sql .=
" AND f.fk_soc = ".((int) $socid);
4849 $sql .=
" ORDER BY f.ref";
4851 dol_syslog(get_class($this).
"::list_replacable_invoices", LOG_DEBUG);
4852 $resql = $this->db->query($sql);
4854 while ($obj = $this->db->fetch_object($resql)) {
4855 $return[$obj->rowid] = array(
4856 'id' => $obj->rowid,
4858 'status' => $obj->status,
4859 'paid' => $obj->paid,
4866 $this->error = $this->db->error();
4889 $sql =
"SELECT f.rowid as rowid, f.ref, f.fk_statut, f.type, f.paye, pf.fk_paiement";
4890 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4891 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"paiement_facture as pf ON f.rowid = pf.fk_facture";
4892 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=".self::TYPE_REPLACEMENT.
")";
4893 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice').
")";
4894 $sql .=
" AND f.fk_statut in (".self::STATUS_VALIDATED.
",".self::STATUS_CLOSED.
")";
4898 $sql .=
" AND ff.type IS NULL";
4899 $sql .=
" AND f.type <> ".self::TYPE_CREDIT_NOTE;
4901 if (!empty($conf->global->INVOICE_USE_SITUATION_CREDIT_NOTE)) {
4903 $sql .=
" AND (f.type <> ".self::TYPE_SITUATION.
" OR f.rowid IN ";
4904 $sql .=
'(SELECT MAX(fs.rowid)';
4905 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as fs";
4906 $sql .=
" WHERE fs.entity IN (".getEntity(
'invoice').
")";
4907 $sql .=
" AND fs.type = ".self::TYPE_SITUATION;
4908 $sql .=
" AND fs.fk_statut IN (".self::STATUS_VALIDATED.
",".self::STATUS_CLOSED.
")";
4910 $sql .=
" AND fs.fk_soc = ".((int) $socid);
4912 $sql .=
" GROUP BY fs.situation_cycle_ref)";
4915 $sql .=
" AND f.type <> ".self::TYPE_SITUATION;
4919 $sql .=
" AND f.fk_soc = ".((int) $socid);
4921 $sql .=
" ORDER BY f.ref";
4923 dol_syslog(get_class($this).
"::list_qualified_avoir_invoices", LOG_DEBUG);
4924 $resql = $this->db->query($sql);
4926 while ($obj = $this->db->fetch_object($resql)) {
4928 if ($obj->fk_statut == self::STATUS_VALIDATED) {
4931 if ($obj->fk_statut == self::STATUS_CLOSED) {
4936 $paymentornot = ($obj->fk_paiement ? 1 : 0);
4937 $return[$obj->rowid] = array(
'ref'=>$obj->ref,
'status'=>$obj->fk_statut,
'type'=>$obj->type,
'paye'=>$obj->paye,
'paymentornot'=>$paymentornot);
4943 $this->error = $this->db->error();
4959 global $conf, $langs;
4963 $sql =
"SELECT f.rowid, f.date_lim_reglement as datefin, f.fk_statut, f.total_ht";
4964 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
4965 if (empty($user->rights->societe->client->voir) && !$user->socid) {
4966 $sql .=
" JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON f.fk_soc = sc.fk_soc";
4967 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
4970 $sql .= $clause.
" f.paye=0";
4971 $sql .=
" AND f.entity IN (".getEntity(
'invoice').
")";
4972 $sql .=
" AND f.fk_statut = ".self::STATUS_VALIDATED;
4974 $sql .=
" AND f.fk_soc = ".((int) $user->socid);
4977 $resql = $this->db->query($sql);
4979 $langs->load(
"bills");
4983 $response->warning_delay = $conf->facture->client->warning_delay / 60 / 60 / 24;
4984 $response->label = $langs->trans(
"CustomerBillsUnpaid");
4985 $response->labelShort = $langs->trans(
"Unpaid");
4986 $response->url = DOL_URL_ROOT.
'/compta/facture/list.php?search_status=1&mainmenu=billing&leftmenu=customers_bills';
4989 $generic_facture =
new Facture($this->db);
4991 while ($obj = $this->db->fetch_object($resql)) {
4992 $generic_facture->date_lim_reglement = $this->db->jdate($obj->datefin);
4993 $generic_facture->statut = $obj->fk_statut;
4995 $response->nbtodo++;
4996 $response->total += $obj->total_ht;
4998 if ($generic_facture->hasDelay()) {
4999 $response->nbtodolate++;
5000 $response->url_late = DOL_URL_ROOT.
'/compta/facture/list.php?search_option=late&mainmenu=billing&leftmenu=customers_bills';
5004 $this->db->free($resql);
5008 $this->error = $this->db->error();
5047 global $conf, $langs, $user;
5051 $nownotime =
dol_mktime(0, 0, 0, $arraynow[
'mon'], $arraynow[
'mday'], $arraynow[
'year']);
5056 $sql =
"SELECT rowid";
5057 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
5058 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
5059 $sql .= $this->db->plimit(100);
5061 $resql = $this->db->query($sql);
5063 $num_prods = $this->db->num_rows($resql);
5065 while ($i < $num_prods) {
5067 $row = $this->db->fetch_row($resql);
5068 $prodids[$i] = $row[0];
5072 if (empty($num_prods)) {
5079 $this->
ref =
'SPECIMEN';
5080 $this->specimen = 1;
5082 $this->date = $nownotime;
5083 $this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
5084 $this->cond_reglement_id = 1;
5085 $this->cond_reglement_code =
'RECEP';
5087 $this->mode_reglement_id = 0;
5088 $this->mode_reglement_code =
'';
5090 $this->note_public =
'This is a comment (public)';
5091 $this->note_private =
'This is a comment (private)';
5092 $this->note =
'This is a comment (private)';
5094 $this->fk_user_author = $user->id;
5096 $this->multicurrency_tx = 1;
5097 $this->multicurrency_code = $conf->currency;
5099 $this->fk_incoterms = 0;
5100 $this->location_incoterms =
'';
5102 if (empty($option) || $option !=
'nolines') {
5106 while ($xnbp < $nbp) {
5108 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
5110 $line->subprice = 100;
5111 $line->tva_tx = 19.6;
5112 $line->localtax1_tx = 0;
5113 $line->localtax2_tx = 0;
5114 $line->remise_percent = 0;
5116 $prodid = mt_rand(1, $num_prods);
5117 $line->fk_product = $prodids[$prodid];
5119 $line->total_ht = -100;
5120 $line->total_ttc = -119.6;
5121 $line->total_tva = -19.6;
5122 $line->multicurrency_total_ht = -200;
5123 $line->multicurrency_total_ttc = -239.2;
5124 $line->multicurrency_total_tva = -39.2;
5125 } elseif ($xnbp == 2) {
5126 $line->subprice = -100;
5127 $line->total_ht = -100;
5128 $line->total_ttc = -119.6;
5129 $line->total_tva = -19.6;
5130 $line->remise_percent = 0;
5131 $line->multicurrency_total_ht = -200;
5132 $line->multicurrency_total_ttc = -239.2;
5133 $line->multicurrency_total_tva = -39.2;
5134 } elseif ($xnbp == 3) {
5135 $prodid = mt_rand(1, $num_prods);
5136 $line->fk_product = $prodids[$prodid];
5137 $line->total_ht = 50;
5138 $line->total_ttc = 59.8;
5139 $line->total_tva = 9.8;
5140 $line->multicurrency_total_ht = 100;
5141 $line->multicurrency_total_ttc = 119.6;
5142 $line->multicurrency_total_tva = 19.6;
5143 $line->remise_percent = 50;
5146 $prodid = mt_rand(1, $num_prods);
5147 $line->fk_product = $prodids[$prodid];
5148 $line->total_ht = 100;
5149 $line->total_ttc = 119.6;
5150 $line->total_tva = 19.6;
5151 $line->multicurrency_total_ht = 200;
5152 $line->multicurrency_total_ttc = 239.2;
5153 $line->multicurrency_total_tva = 39.2;
5154 $line->remise_percent = 0;
5157 $this->lines[$xnbp] = $line;
5160 $this->total_ht += $line->total_ht;
5161 $this->total_tva += $line->total_tva;
5162 $this->total_ttc += $line->total_ttc;
5164 $this->multicurrency_total_ht += $line->multicurrency_total_ht;
5165 $this->multicurrency_total_tva += $line->multicurrency_total_tva;
5166 $this->multicurrency_total_ttc += $line->multicurrency_total_ttc;
5170 $this->revenuestamp = 0;
5174 $line->desc = $langs->trans(
"Description").
" (offered line)";
5176 $line->subprice = 100;
5177 $line->tva_tx = 19.6;
5178 $line->localtax1_tx = 0;
5179 $line->localtax2_tx = 0;
5180 $line->remise_percent = 100;
5181 $line->total_ht = 0;
5182 $line->total_ttc = 0;
5183 $line->total_tva = 0;
5184 $line->multicurrency_total_ht = 0;
5185 $line->multicurrency_total_ttc = 0;
5186 $line->multicurrency_total_tva = 0;
5187 $prodid = mt_rand(1, $num_prods);
5188 $line->fk_product = $prodids[$prodid];
5190 $this->lines[$xnbp] = $line;
5204 global $conf, $user;
5206 $this->nb = array();
5210 $sql =
"SELECT count(f.rowid) as nb";
5211 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture as f";
5212 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON f.fk_soc = s.rowid";
5213 if (empty($user->rights->societe->client->voir) && !$user->socid) {
5214 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
5215 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
5218 $sql .=
" ".$clause.
" f.entity IN (".
getEntity(
'invoice').
")";
5220 $resql = $this->db->query($sql);
5222 while ($obj = $this->db->fetch_object($resql)) {
5223 $this->nb[
"invoices"] = $obj->nb;
5225 $this->db->free($resql);
5229 $this->error = $this->db->error();
5255 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
5257 global $conf, $langs;
5259 $outputlangs->loadLangs(array(
"bills",
"products"));
5263 $thisTypeConfName =
'FACTURE_ADDON_PDF_'.$this->type;
5265 if (!empty($this->model_pdf)) {
5266 $modele = $this->model_pdf;
5267 } elseif (!empty($this->modelpdf)) {
5268 $modele = $this->modelpdf;
5269 } elseif (!empty($conf->global->$thisTypeConfName)) {
5270 $modele = $conf->global->$thisTypeConfName;
5271 } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) {
5272 $modele = $conf->global->FACTURE_ADDON_PDF;
5276 $modelpath =
"core/modules/facture/doc/";
5278 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
5255 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null) {
…}
5288 $sql =
'SELECT max(situation_cycle_ref) FROM '.MAIN_DB_PREFIX.
'facture as f';
5289 $sql .=
" WHERE f.entity IN (".getEntity(
'invoice', 0).
")";
5290 $resql = $this->db->query($sql);
5292 if ($this->db->num_rows($resql) > 0) {
5293 $res = $this->db->fetch_array($resql);
5294 $ref = $res[
'max(situation_cycle_ref)'];
5299 $this->db->free($resql);
5302 $this->error = $this->db->lasterror();
5303 dol_syslog(
"Error sql=".$sql.
", error=".$this->error, LOG_ERR);
5317 return ($this->situation_counter == 1);
5331 $sql =
'SELECT rowid FROM '.MAIN_DB_PREFIX.
'facture';
5332 $sql .=
' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref);
5333 $sql .=
' AND situation_counter < '.((int) $this->situation_counter);
5334 $sql .=
' AND entity = '.($this->entity > 0 ? $this->entity : $conf->entity);
5335 $resql = $this->db->query($sql);
5337 if ($resql && $this->db->num_rows($resql) > 0) {
5338 while ($row = $this->db->fetch_object($resql)) {
5340 $situation =
new Facture($this->db);
5341 $situation->fetch($id);
5342 $res[] = $situation;
5345 $this->error = $this->db->error();
5346 dol_syslog(
"Error sql=".$sql.
", error=".$this->error, LOG_ERR);
5366 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'facture SET situation_final = '.((int) $this->situation_final).
' WHERE rowid = '.((int) $this->
id);
5369 $resql = $this->db->query($sql);
5371 $this->errors[] = $this->db->error();
5375 if (!$notrigger && empty($error)) {
5385 $this->db->commit();
5388 foreach ($this->errors as $errmsg) {
5389 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
5390 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
5392 $this->db->rollback();
5408 if (!empty($this->situation_cycle_ref)) {
5410 $sql =
'SELECT max(situation_counter) FROM '.MAIN_DB_PREFIX.
'facture';
5411 $sql .=
' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref);
5412 $sql .=
' AND entity = '.($this->entity > 0 ? $this->entity : $conf->entity);
5413 $resql = $this->db->query($sql);
5415 if ($resql && $this->db->num_rows($resql) > 0) {
5416 $res = $this->db->fetch_array($resql);
5417 $last = $res[
'max(situation_counter)'];
5418 return ($last == $this->situation_counter);
5420 $this->error = $this->db->lasterror();
5421 dol_syslog(get_class($this).
"::select Error ".$this->error, LOG_ERR);
5479 $hasDelay = $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay);
5480 if ($hasDelay && !empty($this->retained_warranty) && !empty($this->retained_warranty_date_limit)) {
5482 $totalpaid = floatval($totalpaid);
5484 if ($totalpaid >= 0 && $RetainedWarrantyAmount >= 0) {
5485 if (($totalpaid < $this->total_ttc - $RetainedWarrantyAmount) && $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay)) {
5487 } elseif ($totalpaid < $this->total_ttc && $this->retained_warranty_date_limit < ($now - $conf->facture->client->warning_delay)) {
5510 $displayWarranty =
false;
5511 if (!empty($this->retained_warranty)) {
5512 $displayWarranty =
true;
5516 $displayWarranty =
false;
5517 if (!empty($this->situation_final)) {
5518 $displayWarranty =
true;
5521 $displayWarranty =
true;
5523 foreach ($this->lines as $i => $line) {
5524 if ($line->product_type < 2 && $line->situation_percent < 100) {
5525 $displayWarranty =
false;
5533 return $displayWarranty;
5543 if (empty($this->retained_warranty)) {
5547 $retainedWarrantyAmount = 0;
5551 $displayWarranty =
true;
5553 if (!empty($this->lines)) {
5554 foreach ($this->lines as $i => $line) {
5555 if ($line->product_type < 2 && $line->situation_percent < 100) {
5556 $displayWarranty =
false;
5562 if ($displayWarranty && !empty($this->situation_final)) {
5564 $TPreviousIncoice = $this->tab_previous_situation_invoice;
5567 foreach ($TPreviousIncoice as &$fac) {
5568 $total2BillWT += $fac->total_ttc;
5570 $total2BillWT += $this->total_ttc;
5572 $retainedWarrantyAmount = $total2BillWT * $this->retained_warranty / 100;
5578 $retainedWarrantyAmount = $this->total_ttc * $this->retained_warranty / 100;
5581 if ($rounding < 0) {
5582 $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT);
5585 if ($rounding > 0) {
5586 return round($retainedWarrantyAmount, $rounding);
5589 return $retainedWarrantyAmount;
5600 dol_syslog(get_class($this).
'::setRetainedWarranty('.$value.
')');
5602 if ($this->
statut >= 0) {
5603 $fieldname =
'retained_warranty';
5604 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
5605 $sql .=
" SET ".$fieldname.
" = ".((float) $value);
5606 $sql .=
' WHERE rowid='.((int) $this->
id);
5608 if ($this->db->query($sql)) {
5609 $this->retained_warranty = floatval($value);
5612 dol_syslog(get_class($this).
'::setRetainedWarranty Erreur '.$sql.
' - '.$this->db->error());
5613 $this->error = $this->db->error();
5617 dol_syslog(get_class($this).
'::setRetainedWarranty, status of the object is incompatible');
5618 $this->error =
'Status of the object is incompatible '.$this->statut;
5633 if (!$timestamp && $dateYmd) {
5634 $timestamp = $this->db->jdate($dateYmd);
5638 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit('.$timestamp.
')');
5639 if ($this->
statut >= 0) {
5640 $fieldname =
'retained_warranty_date_limit';
5641 $sql =
'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
5642 $sql .=
" SET ".$fieldname.
" = ".(strval($timestamp) !=
'' ?
"'".$this->db->idate($timestamp).
"'" :
'null');
5643 $sql .=
' WHERE rowid = '.((int) $this->
id);
5645 if ($this->db->query($sql)) {
5646 $this->retained_warranty_date_limit = $timestamp;
5649 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit Erreur '.$sql.
' - '.$this->db->error());
5650 $this->error = $this->db->error();
5654 dol_syslog(get_class($this).
'::setRetainedWarrantyDateLimit, status of the object is incompatible');
5655 $this->error =
'Status of the object is incompatible '.$this->statut;
5674 global $conf, $langs, $user;
5680 $errorsMsg = array();
5682 $langs->load(
"bills");
5684 if (!isModEnabled(
'facture')) {
5685 $this->output .= $langs->trans(
'ModuleNotEnabled', $langs->transnoentitiesnoconv(
"Facture"));
5688 if (!in_array($datetouse, array(
'duedate',
'invoicedate'))) {
5689 $this->output .=
'Bad value for parameter datetouse. Must be "duedate" or "invoicedate"';
5699 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
5700 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmail.class.php';
5701 require_once DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
5702 $formmail =
new FormMail($this->db);
5707 $tmpinvoice =
new Facture($this->db);
5712 $sql =
"SELECT rowid as id FROM ".MAIN_DB_PREFIX.
"facture as f";
5713 if (!empty($paymentmode) && $paymentmode !=
'all') {
5714 $sql .=
", ".MAIN_DB_PREFIX.
"c_paiement as cp";
5716 $sql .=
" WHERE f.paye = 0";
5717 $sql .=
" AND f.fk_statut = ".self::STATUS_VALIDATED;
5718 if ($datetouse ==
'invoicedate') {
5719 $sql .=
" AND f.datef = '".$this->db->idate($tmpidate,
'gmt').
"'";
5721 $sql .=
" AND f.date_lim_reglement = '".$this->db->idate($tmpidate,
'gmt').
"'";
5723 $sql .=
" AND f.entity IN (".getEntity(
'facture', 0).
")";
5724 if (!empty($paymentmode) && $paymentmode !=
'all') {
5725 $sql .=
" AND f.fk_mode_reglement = cp.id AND cp.code = '".$this->db->escape($paymentmode).
"'";
5728 if ($datetouse ==
'invoicedate') {
5729 $sql .= $this->db->order(
"datef",
"ASC");
5731 $sql .= $this->db->order(
"date_lim_reglement",
"ASC");
5734 $resql = $this->db->query($sql);
5737 if ($datetouse ==
'invoicedate') {
5738 $this->output .= $langs->transnoentitiesnoconv(
"SearchValidatedInvoicesWithDate", $stmpidate);
5740 $this->output .= $langs->transnoentitiesnoconv(
"SearchUnpaidInvoicesWithDueDate", $stmpidate);
5742 if (!empty($paymentmode) && $paymentmode !=
'all') {
5743 $this->output .=
' ('.$langs->transnoentitiesnoconv(
"PaymentMode").
' '.$paymentmode.
')';
5745 $this->output .=
'<br>';
5748 while ($obj = $this->db->fetch_object($resql)) {
5751 $res = $tmpinvoice->fetch($obj->id);
5753 $tmpinvoice->fetch_thirdparty();
5755 $outputlangs =
new Translate(
'', $conf);
5756 if ($tmpinvoice->thirdparty->default_lang) {
5757 $outputlangs->setDefaultLang($tmpinvoice->thirdparty->default_lang);
5758 $outputlangs->loadLangs(array(
"main",
"bills"));
5760 $outputlangs = $langs;
5764 $arraymessage = $formmail->getEMailTemplate($this->db,
'facture_send', $user, $outputlangs, (is_numeric($template) ? $template : 0), 1, (is_numeric($template) ?
'' : $template));
5765 if (is_numeric($arraymessage) && $arraymessage <= 0) {
5766 $langs->load(
"errors");
5767 $this->output .= $langs->trans(
'ErrorFailedToFindEmailTemplate', $template);
5780 $sendTopic =
make_substitutions(empty($arraymessage->topic) ? $outputlangs->transnoentitiesnoconv(
'InformationMessage') : $arraymessage->topic, $substitutionarray, $outputlangs, 1);
5783 $content = $outputlangs->transnoentitiesnoconv($arraymessage->content);
5789 if ($forcerecipient) {
5790 $to = array($forcerecipient);
5792 $res = $tmpinvoice->fetch_thirdparty();
5793 $recipient = $tmpinvoice->thirdparty;
5795 $tmparraycontact = $tmpinvoice->liste_contact(-1,
'external', 0,
'BILLING');
5796 if (is_array($tmparraycontact) && count($tmparraycontact) > 0) {
5797 foreach ($tmparraycontact as $data_email) {
5798 if (!empty($data_email[
'email'])) {
5799 $to[] = $tmpinvoice->thirdparty->contact_get_property($data_email[
'id'],
'email');
5803 if (empty($to) && !empty($recipient->email)) {
5804 $to[] = $recipient->email;
5807 $errormesg =
"Failed to send remind to thirdparty id=".$tmpinvoice->socid.
". No email defined for invoice or customer.";
5811 $errormesg =
"Failed to load recipient with thirdparty id=".$tmpinvoice->socid;
5818 if (!empty($arraymessage->email_from)) {
5819 $from = $arraymessage->email_from;
5822 $errormesg =
"Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
5826 if (!$error && !empty($to)) {
5829 $to = implode(
',', $to);
5830 if (!empty($arraymessage->email_to)) {
5831 $to = $to.
','.$arraymessage->email_to;
5835 $errors_to = $conf->global->MAIN_MAIL_ERRORS_TO;
5837 $trackid =
'inv'.$tmpinvoice->id;
5838 $sendcontext =
'standard';
5841 if (!empty($arraymessage->email_tocc)) {
5842 $email_tocc = $arraymessage->email_tocc;
5846 if (!empty($arraymessage->email_tobcc)) {
5847 $email_tobcc = $arraymessage->email_tobcc;
5854 if ($arraymessage->joinfiles == 1 && !empty($tmpinvoice->last_main_doc)) {
5855 $joinFile[] = DOL_DATA_ROOT.
'/'.$tmpinvoice->last_main_doc;
5856 $joinFileName[] = basename($tmpinvoice->last_main_doc);
5857 $joinFileMime[] =
dol_mimetype(DOL_DATA_ROOT.
'/'.$tmpinvoice->last_main_doc);
5861 $cMailFile =
new CMailFile($sendTopic, $to, $from, $sendContent, $joinFile, $joinFileMime, $joinFileName, $email_tocc, $email_tobcc, 0, 1, $errors_to,
'', $trackid,
'', $sendcontext,
'');
5864 if ($cMailFile->sendfile()) {
5868 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
5873 $actioncomm->type_code =
'AC_OTH_AUTO';
5874 $actioncomm->socid = $tmpinvoice->thirdparty->id;
5875 $actioncomm->contact_id = 0;
5877 $actioncomm->code =
'AC_EMAIL';
5878 $actioncomm->label =
'sendEmailsRemindersOnInvoiceDueDateOK (nbdays='.$nbdays.
' paymentmode='.$paymentmode.
' template='.$template.
' datetouse='.$datetouse.
' forcerecipient='.$forcerecipient.
')';
5879 $actioncomm->note_private = $sendContent;
5880 $actioncomm->fk_project = $tmpinvoice->fk_project;
5881 $actioncomm->datep =
dol_now();
5882 $actioncomm->datef = $actioncomm->datep;
5883 $actioncomm->percentage = -1;
5884 $actioncomm->authorid = $user->id;
5885 $actioncomm->userownerid = $user->id;
5887 $actioncomm->email_msgid = $cMailFile->msgid;
5888 $actioncomm->email_subject = $sendTopic;
5889 $actioncomm->email_from = $from;
5890 $actioncomm->email_sender =
'';
5891 $actioncomm->email_to = $to;
5895 $actioncomm->errors_to = $errors_to;
5897 $actioncomm->elementtype =
'invoice';
5898 $actioncomm->fk_element = $tmpinvoice->id;
5902 $actioncomm->create($user);
5904 $errormesg = $cMailFile->error.
' : '.$to;
5908 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
5913 $actioncomm->type_code =
'AC_OTH_AUTO';
5914 $actioncomm->socid = $tmpinvoice->thirdparty->id;
5915 $actioncomm->contact_id = 0;
5917 $actioncomm->code =
'AC_EMAIL';
5918 $actioncomm->label =
'sendEmailsRemindersOnInvoiceDueDateKO';
5919 $actioncomm->note_private = $errormesg;
5920 $actioncomm->fk_project = $tmpinvoice->fk_project;
5921 $actioncomm->datep =
dol_now();
5922 $actioncomm->datef = $actioncomm->datep;
5923 $actioncomm->percentage = -1;
5924 $actioncomm->authorid = $user->id;
5925 $actioncomm->userownerid = $user->id;
5927 $actioncomm->email_msgid = $cMailFile->msgid;
5928 $actioncomm->email_from = $from;
5929 $actioncomm->email_sender =
'';
5930 $actioncomm->email_to = $to;
5934 $actioncomm->errors_to = $errors_to;
5938 $actioncomm->create($user);
5941 $this->db->commit();
5945 $errorsMsg[] = $errormesg;
5948 $errorsMsg[] =
'Failed to fetch record invoice with ID = '.$obj->id;
5958 $this->output .=
'Nb of emails sent : '.$nbMailSend;
5960 dol_syslog(__METHOD__.
" end - ".$this->output, LOG_INFO);
5964 $this->error =
'Nb of emails sent : '.$nbMailSend.
', '.(!empty($errorsMsg)) ? join(
', ', $errorsMsg) : $error;
5966 dol_syslog(__METHOD__.
" end - ".$this->error, LOG_INFO);
5981 $sql =
"SELECT datef";
5982 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
5983 $sql .=
" WHERE type = " . (int) $this->
type ;
5984 $sql .=
" AND date_valid IS NOT NULL";
5985 $sql .=
" AND entity IN (".getEntity(
'invoice').
")";
5986 $sql .=
" ORDER BY datef DESC LIMIT 1";
5988 $result = $this->db->query($sql);
5991 if ($this->db->num_rows($result)) {
5992 $obj = $this->db->fetch_object($result);
5993 $last_date = $this->db->jdate($obj->datef);
5994 $invoice_date = $this->date;
5996 $is_last_of_same_type = $invoice_date >= $last_date;
5997 if ($allow_validated_drafts) {
5998 $is_last_of_same_type = $is_last_of_same_type || (!strpos($this->
ref,
'PROV') && $this->status ==
self::STATUS_DRAFT);
6001 return array($is_last_of_same_type, $last_date);
6022 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
6024 $return =
'<div class="box-flex-item box-flex-grow-zero">';
6025 $return .=
'<div class="info-box info-box-sm">';
6026 $return .=
'<span class="info-box-icon bg-infobox-action">';
6029 $return .=
'</span>';
6030 $return .=
'<div class="info-box-content">';
6031 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
6032 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
6033 if (property_exists($this,
'socid')) {
6034 $return .=
'<br><span class="info-box-label">'.$this->socid.
'</span>';
6036 if (property_exists($this,
'fk_user_author')) {
6037 $return .=
'<br><span class="info-box-label">'.$this->fk_user_author.
'</span>';
6039 if (method_exists($this,
'getLibStatut')) {
6040 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).
'</div>';
6042 $return .=
'</div>';
6043 $return .=
'</div>';
6044 $return .=
'</div>';
6058 public $element =
'facturedet';
6063 public $table_element =
'facturedet';
6080 public $localtax1_type;
6081 public $localtax2_type;
6082 public $fk_remise_except;
6085 public $fk_fournprice;
6090 public $remise_percent;
6092 public $special_code;
6100 public $fk_code_ventilation = 0;
6105 public $skip_update_total;
6110 public $situation_percent;
6118 public $fk_multicurrency;
6119 public $multicurrency_code;
6120 public $multicurrency_subprice;
6121 public $multicurrency_total_ht;
6122 public $multicurrency_total_tva;
6123 public $multicurrency_total_ttc;
6143 $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,';
6144 $sql .=
' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice, fd.ref_ext,';
6145 $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,';
6146 $sql .=
' fd.info_bits, fd.special_code, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,';
6147 $sql .=
' fd.fk_code_ventilation,';
6148 $sql .=
' fd.fk_unit, fd.fk_user_author, fd.fk_user_modif,';
6149 $sql .=
' fd.situation_percent, fd.fk_prev_id,';
6150 $sql .=
' fd.multicurrency_subprice,';
6151 $sql .=
' fd.multicurrency_total_ht,';
6152 $sql .=
' fd.multicurrency_total_tva,';
6153 $sql .=
' fd.multicurrency_total_ttc,';
6154 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc';
6155 $sql .=
' FROM '.MAIN_DB_PREFIX.
'facturedet as fd';
6156 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON fd.fk_product = p.rowid';
6157 $sql .=
' WHERE fd.rowid = '.((int) $rowid);
6159 $result = $this->db->query($sql);
6161 $objp = $this->db->fetch_object($result);
6164 $this->error =
'InvoiceLine with id '. $rowid .
' not found sql='.$sql;
6168 $this->
rowid = $objp->rowid;
6169 $this->
id = $objp->rowid;
6170 $this->fk_facture = $objp->fk_facture;
6171 $this->fk_parent_line = $objp->fk_parent_line;
6172 $this->label = $objp->custom_label;
6173 $this->desc = $objp->description;
6174 $this->qty = $objp->qty;
6175 $this->subprice = $objp->subprice;
6176 $this->ref_ext = $objp->ref_ext;
6177 $this->vat_src_code = $objp->vat_src_code;
6178 $this->tva_tx = $objp->tva_tx;
6179 $this->localtax1_tx = $objp->localtax1_tx;
6180 $this->localtax2_tx = $objp->localtax2_tx;
6181 $this->remise_percent = $objp->remise_percent;
6182 $this->fk_remise_except = $objp->fk_remise_except;
6183 $this->fk_product = $objp->fk_product;
6184 $this->product_type = $objp->product_type;
6185 $this->date_start = $this->db->jdate($objp->date_start);
6186 $this->date_end = $this->db->jdate($objp->date_end);
6187 $this->info_bits = $objp->info_bits;
6188 $this->tva_npr = ($objp->info_bits & 1 == 1) ? 1 : 0;
6189 $this->special_code = $objp->special_code;
6190 $this->total_ht = $objp->total_ht;
6191 $this->total_tva = $objp->total_tva;
6192 $this->total_localtax1 = $objp->total_localtax1;
6193 $this->total_localtax2 = $objp->total_localtax2;
6194 $this->total_ttc = $objp->total_ttc;
6195 $this->fk_code_ventilation = $objp->fk_code_ventilation;
6196 $this->rang = $objp->rang;
6197 $this->fk_fournprice = $objp->fk_fournprice;
6198 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
6199 $this->pa_ht = $marginInfos[0];
6200 $this->marge_tx = $marginInfos[1];
6201 $this->marque_tx = $marginInfos[2];
6203 $this->
ref = $objp->product_ref;
6205 $this->product_ref = $objp->product_ref;
6206 $this->product_label = $objp->product_label;
6207 $this->product_desc = $objp->product_desc;
6209 $this->fk_unit = $objp->fk_unit;
6210 $this->fk_user_modif = $objp->fk_user_modif;
6211 $this->fk_user_author = $objp->fk_user_author;
6213 $this->situation_percent = $objp->situation_percent;
6214 $this->fk_prev_id = $objp->fk_prev_id;
6216 $this->multicurrency_subprice = $objp->multicurrency_subprice;
6217 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
6218 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
6219 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
6223 $this->db->free($result);
6227 $this->error = $this->db->lasterror();
6239 public function insert($notrigger = 0, $noerrorifdiscountalreadylinked = 0)
6241 global $langs, $user, $conf;
6245 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
6247 dol_syslog(get_class($this).
"::insert rang=".$this->rang, LOG_DEBUG);
6250 $this->desc = trim($this->desc);
6251 if (empty($this->tva_tx)) {
6254 if (empty($this->localtax1_tx)) {
6255 $this->localtax1_tx = 0;
6257 if (empty($this->localtax2_tx)) {
6258 $this->localtax2_tx = 0;
6260 if (empty($this->localtax1_type)) {
6261 $this->localtax1_type = 0;
6263 if (empty($this->localtax2_type)) {
6264 $this->localtax2_type = 0;
6266 if (empty($this->total_localtax1)) {
6267 $this->total_localtax1 = 0;
6269 if (empty($this->total_localtax2)) {
6270 $this->total_localtax2 = 0;
6272 if (empty($this->rang)) {
6275 if (empty($this->remise_percent)) {
6276 $this->remise_percent = 0;
6278 if (empty($this->info_bits)) {
6279 $this->info_bits = 0;
6281 if (empty($this->subprice)) {
6282 $this->subprice = 0;
6284 if (empty($this->ref_ext)) {
6285 $this->ref_ext =
'';
6287 if (empty($this->special_code)) {
6288 $this->special_code = 0;
6290 if (empty($this->fk_parent_line)) {
6291 $this->fk_parent_line = 0;
6293 if (empty($this->fk_prev_id)) {
6294 $this->fk_prev_id = 0;
6296 if (!isset($this->situation_percent) || $this->situation_percent > 100 || (
string) $this->situation_percent ==
'') {
6297 $this->situation_percent = 100;
6300 if (empty($this->pa_ht)) {
6303 if (empty($this->multicurrency_subprice)) {
6304 $this->multicurrency_subprice = 0;
6306 if (empty($this->multicurrency_total_ht)) {
6307 $this->multicurrency_total_ht = 0;
6309 if (empty($this->multicurrency_total_tva)) {
6310 $this->multicurrency_total_tva = 0;
6312 if (empty($this->multicurrency_total_ttc)) {
6313 $this->multicurrency_total_ttc = 0;
6317 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
6318 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
6321 $this->pa_ht = $result;
6326 if ($this->product_type < 0) {
6327 $this->error =
'ErrorProductTypeMustBe0orMore';
6330 if (!empty($this->fk_product) && $this->fk_product > 0) {
6334 $this->error =
'ErrorProductIdDoesNotExists';
6335 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6343 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'facturedet';
6344 $sql .=
' (fk_facture, fk_parent_line, label, description, qty,';
6345 $sql .=
' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
6346 $sql .=
' fk_product, product_type, remise_percent, subprice, ref_ext, fk_remise_except,';
6347 $sql .=
' date_start, date_end, fk_code_ventilation, ';
6348 $sql .=
' rang, special_code, fk_product_fournisseur_price, buy_price_ht,';
6349 $sql .=
' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2,';
6350 $sql .=
' situation_percent, fk_prev_id,';
6351 $sql .=
' fk_unit, fk_user_author, fk_user_modif,';
6352 $sql .=
' fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
6354 $sql .=
" VALUES (".$this->fk_facture.
",";
6355 $sql .=
" ".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null").
",";
6356 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
6357 $sql .=
" '".$this->db->escape($this->desc).
"',";
6358 $sql .=
" ".price2num($this->qty).
",";
6359 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
6360 $sql .=
" ".price2num($this->tva_tx).
",";
6361 $sql .=
" ".price2num($this->localtax1_tx).
",";
6362 $sql .=
" ".price2num($this->localtax2_tx).
",";
6363 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
6364 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
6365 $sql .=
' '.((!empty($this->fk_product) && $this->fk_product > 0) ? $this->fk_product :
"null").
',';
6366 $sql .=
" ".((int) $this->product_type).
",";
6367 $sql .=
" ".price2num($this->remise_percent).
",";
6368 $sql .=
" ".price2num($this->subprice).
",";
6369 $sql .=
" '".$this->db->escape($this->ref_ext).
"',";
6370 $sql .=
' '.(!empty($this->fk_remise_except) ? $this->fk_remise_except :
"null").
',';
6371 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
",";
6372 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null").
",";
6373 $sql .=
' '.((int) $this->fk_code_ventilation).
',';
6374 $sql .=
' '.((int) $this->rang).
',';
6375 $sql .=
' '.((int) $this->special_code).
',';
6376 $sql .=
' '.(!empty($this->fk_fournprice) ? $this->fk_fournprice :
"null").
',';
6377 $sql .=
' '.price2num($this->pa_ht).
',';
6378 $sql .=
" '".$this->db->escape($this->info_bits).
"',";
6379 $sql .=
" ".price2num($this->total_ht).
",";
6380 $sql .=
" ".price2num($this->total_tva).
",";
6381 $sql .=
" ".price2num($this->total_ttc).
",";
6382 $sql .=
" ".price2num($this->total_localtax1).
",";
6383 $sql .=
" ".price2num($this->total_localtax2);
6384 $sql .=
", ".((float) $this->situation_percent);
6385 $sql .=
", ".(!empty($this->fk_prev_id) ? $this->fk_prev_id :
"null");
6386 $sql .=
", ".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
6387 $sql .=
", ".((int) $user->id);
6388 $sql .=
", ".((int) $user->id);
6389 $sql .=
", ".(int) $this->fk_multicurrency;
6390 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
6391 $sql .=
", ".price2num($this->multicurrency_subprice);
6392 $sql .=
", ".price2num($this->multicurrency_total_ht);
6393 $sql .=
", ".price2num($this->multicurrency_total_tva);
6394 $sql .=
", ".price2num($this->multicurrency_total_ttc);
6397 dol_syslog(get_class($this).
"::insert", LOG_DEBUG);
6398 $resql = $this->db->query($sql);
6400 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
'facturedet');
6401 $this->
rowid = $this->id;
6412 if ($this->fk_remise_except) {
6414 $result = $discount->fetch($this->fk_remise_except);
6419 if ($discount->fk_facture_line > 0) {
6420 if (empty($noerrorifdiscountalreadylinked)) {
6421 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed", $discount->id);
6422 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6423 $this->db->rollback();
6427 $result = $discount->link_to_invoice($this->
rowid, 0);
6429 $this->error = $discount->error;
6430 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6431 $this->db->rollback();
6436 $this->error = $langs->trans(
"ErrorADiscountThatHasBeenRemovedIsIncluded");
6437 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6438 $this->db->rollback();
6442 $this->error = $discount->error;
6443 dol_syslog(get_class($this).
"::insert Error ".$this->error, LOG_ERR);
6444 $this->db->rollback();
6451 $result = $this->
call_trigger(
'LINEBILL_INSERT', $user);
6453 $this->db->rollback();
6459 $this->db->commit();
6462 $this->error = $this->db->lasterror();
6463 $this->db->rollback();
6239 public function insert($notrigger = 0, $noerrorifdiscountalreadylinked = 0) {
…}
6475 public function update($user =
'', $notrigger = 0)
6477 global $user, $conf;
6481 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
6484 $this->desc = trim($this->desc);
6485 if (empty($this->ref_ext)) {
6486 $this->ref_ext =
'';
6488 if (empty($this->tva_tx)) {
6491 if (empty($this->localtax1_tx)) {
6492 $this->localtax1_tx = 0;
6494 if (empty($this->localtax2_tx)) {
6495 $this->localtax2_tx = 0;
6497 if (empty($this->localtax1_type)) {
6498 $this->localtax1_type = 0;
6500 if (empty($this->localtax2_type)) {
6501 $this->localtax2_type = 0;
6503 if (empty($this->total_localtax1)) {
6504 $this->total_localtax1 = 0;
6506 if (empty($this->total_localtax2)) {
6507 $this->total_localtax2 = 0;
6509 if (empty($this->remise_percent)) {
6510 $this->remise_percent = 0;
6512 if (empty($this->info_bits)) {
6513 $this->info_bits = 0;
6515 if (empty($this->special_code)) {
6516 $this->special_code = 0;
6518 if (empty($this->product_type)) {
6519 $this->product_type = 0;
6521 if (empty($this->fk_parent_line)) {
6522 $this->fk_parent_line = 0;
6524 if (!isset($this->situation_percent) || $this->situation_percent > 100 || (
string) $this->situation_percent ==
'') {
6525 $this->situation_percent = 100;
6527 if (empty($this->pa_ht)) {
6531 if (empty($this->multicurrency_subprice)) {
6532 $this->multicurrency_subprice = 0;
6534 if (empty($this->multicurrency_total_ht)) {
6535 $this->multicurrency_total_ht = 0;
6537 if (empty($this->multicurrency_total_tva)) {
6538 $this->multicurrency_total_tva = 0;
6540 if (empty($this->multicurrency_total_ttc)) {
6541 $this->multicurrency_total_ttc = 0;
6545 if ($this->product_type < 0) {
6550 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
6552 $result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product);
6556 $this->pa_ht = $result;
6563 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facturedet SET";
6564 $sql .=
" description='".$this->db->escape($this->desc).
"'";
6565 $sql .=
", ref_ext='".$this->db->escape($this->ref_ext).
"'";
6566 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
6567 $sql .=
", subprice=".price2num($this->subprice);
6568 $sql .=
", remise_percent=".price2num($this->remise_percent);
6569 if ($this->fk_remise_except) {
6570 $sql .=
", fk_remise_except=".$this->fk_remise_except;
6572 $sql .=
", fk_remise_except=null";
6574 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->db->escape($this->vat_src_code)).
"'";
6575 $sql .=
", tva_tx=".price2num($this->tva_tx);
6576 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
6577 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
6578 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
6579 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
6580 $sql .=
", qty=".price2num($this->qty);
6581 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
6582 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
6583 $sql .=
", product_type=".$this->product_type;
6584 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
6585 $sql .=
", special_code='".$this->db->escape($this->special_code).
"'";
6586 if (empty($this->skip_update_total)) {
6587 $sql .=
", total_ht=".price2num($this->total_ht);
6588 $sql .=
", total_tva=".price2num($this->total_tva);
6589 $sql .=
", total_ttc=".price2num($this->total_ttc);
6590 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
6591 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
6593 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
6594 $sql .=
", buy_price_ht=".(($this->pa_ht || (string) $this->pa_ht ===
'0') ?
price2num($this->pa_ht) :
"null");
6595 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null");
6596 if (!empty($this->rang)) {
6597 $sql .=
", rang=".((int) $this->rang);
6599 $sql .=
", situation_percent = ".((float) $this->situation_percent);
6600 $sql .=
", fk_unit = ".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
6601 $sql .=
", fk_user_modif = ".((int) $user->id);
6604 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
6605 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
6606 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
6607 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
6609 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
6611 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
6612 $resql = $this->db->query($sql);
6615 $this->
id = $this->rowid;
6622 if (!$error && !$notrigger) {
6624 $result = $this->
call_trigger(
'LINEBILL_MODIFY', $user);
6626 $this->db->rollback();
6631 $this->db->commit();
6634 $this->error = $this->db->error();
6635 $this->db->rollback();
6475 public function update($user =
'', $notrigger = 0) {
…}
6647 public function delete($tmpuser =
null, $notrigger =
false)
6654 if (empty($notrigger)) {
6655 $result = $this->
call_trigger(
'LINEBILL_DELETE', $user);
6657 $this->db->rollback();
6666 $this->db->rollback();
6671 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'societe_remise_except';
6672 $sql .=
' SET fk_facture_line = NULL';
6673 $sql .=
' WHERE fk_facture_line = '.((int) $this->
id);
6675 dol_syslog(get_class($this).
"::deleteline", LOG_DEBUG);
6676 $result = $this->db->query($sql);
6678 $this->error = $this->db->error();
6679 $this->errors[] = $this->error;
6680 $this->db->rollback();
6684 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'element_time';
6685 $sql .=
' SET invoice_id = NULL, invoice_line_id = NULL';
6686 $sql .=
' WHERE invoice_line_id = '.((int) $this->
id);
6687 if (!$this->db->query($sql)) {
6688 $this->error = $this->db->error().
" sql=".$sql;
6689 $this->errors[] = $this->error;
6690 $this->db->rollback();
6694 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"facturedet WHERE rowid = ".((int) $this->
id);
6696 if ($this->db->query($sql)) {
6697 $this->db->commit();
6700 $this->error = $this->db->error().
" sql=".$sql;
6701 $this->errors[] = $this->error;
6702 $this->db->rollback();
6647 public function delete($tmpuser =
null, $notrigger =
false) {
…}
6718 dol_syslog(get_class($this).
"::update_total", LOG_DEBUG);
6721 if (empty($this->total_localtax1)) {
6722 $this->total_localtax1 = 0;
6724 if (empty($this->total_localtax2)) {
6725 $this->total_localtax2 = 0;
6729 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"facturedet SET";
6730 $sql .=
" total_ht=".price2num($this->total_ht);
6731 $sql .=
",total_tva=".price2num($this->total_tva);
6732 $sql .=
",total_localtax1=".price2num($this->total_localtax1);
6733 $sql .=
",total_localtax2=".price2num($this->total_localtax2);
6734 $sql .=
",total_ttc=".price2num($this->total_ttc);
6735 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
6737 dol_syslog(get_class($this).
"::update_total", LOG_DEBUG);
6739 $resql = $this->db->query($sql);
6741 $this->db->commit();
6744 $this->error = $this->db->error();
6745 $this->db->rollback();
6762 global $invoicecache;
6764 if (is_null($this->fk_prev_id) || empty($this->fk_prev_id) || $this->fk_prev_id ==
"") {
6768 if (!isset($invoicecache[$invoiceid])) {
6769 $invoicecache[$invoiceid] =
new Facture($this->db);
6770 $invoicecache[$invoiceid]->fetch($invoiceid);
6776 $sql =
"SELECT situation_percent FROM ".MAIN_DB_PREFIX.
"facturedet WHERE rowid = ".((int) $this->fk_prev_id);
6777 $resql = $this->db->query($sql);
6778 if ($resql && $this->db->num_rows($resql) > 0) {
6779 $res = $this->db->fetch_array($resql);
6781 $returnPercent = floatval($res[
'situation_percent']);
6783 if ($include_credit_note) {
6784 $sql =
'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.
'facturedet fd';
6785 $sql .=
' JOIN '.MAIN_DB_PREFIX.
'facture f ON (f.rowid = fd.fk_facture) ';
6786 $sql .=
" WHERE fd.fk_prev_id = ".((int) $this->fk_prev_id);
6787 $sql .=
" AND f.situation_cycle_ref = ".((int) $invoicecache[$invoiceid]->situation_cycle_ref);
6788 $sql .=
" AND f.type = ".Facture::TYPE_CREDIT_NOTE;
6790 $res = $this->db->query($sql);
6792 while ($obj = $this->db->fetch_object($res)) {
6793 $returnPercent = $returnPercent + floatval($obj->situation_percent);
6800 return $returnPercent;
6802 $this->error = $this->db->error();
6803 dol_syslog(get_class($this).
"::select Error ".$this->error, LOG_ERR);
6804 $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