/htdocs/compta/facture/class/facture.class.php
PHP | 3554 lines | 2564 code | 390 blank | 600 comment | 415 complexity | a54f7a268fdc7be3bdb5ef40d040a10a MD5 | raw file
Possible License(s): LGPL-2.0
Large files files are truncated, but you can click here to view the full file
- <?php
- /* Copyright (C) 2002-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
- * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
- * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
- * Copyright (C) 2005-2012 Regis Houssin <regis@dolibarr.fr>
- * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
- * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
- * Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
- * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /**
- * \file htdocs/compta/facture/class/facture.class.php
- * \ingroup facture
- * \brief File of class to manage invoices
- */
- include_once(DOL_DOCUMENT_ROOT."/core/class/commoninvoice.class.php");
- require_once(DOL_DOCUMENT_ROOT ."/product/class/product.class.php");
- require_once(DOL_DOCUMENT_ROOT ."/societe/class/client.class.php");
- require_once(DOL_DOCUMENT_ROOT ."/margin/lib/margins.lib.php");
- /**
- * Class to manage invoices
- */
- class Facture extends CommonInvoice
- {
- public $element='facture';
- public $table_element='facture';
- public $table_element_line = 'facturedet';
- public $fk_element = 'fk_facture';
- protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
- var $id;
- //! Id client
- var $socid;
- //! Objet societe client (to load with fetch_client method)
- var $client;
- var $author;
- var $fk_user_author;
- var $fk_user_valid;
- //! Invoice date
- var $date; // Invoice date
- var $date_creation; // Creation date
- var $date_validation; // Validation date
- var $datem;
- var $ref;
- var $ref_client;
- var $ref_ext;
- var $ref_int;
- //! 0=Standard invoice, 1=Replacement invoice, 2=Credit note invoice, 3=Deposit invoice, 4=Proforma invoice
- var $type=0;
- //var $amount;
- var $remise_absolue;
- var $remise_percent;
- var $total_ht=0;
- var $total_tva=0;
- var $total_ttc=0;
- var $note; // deprecated
- var $note_private;
- var $note_public;
- //! 0=draft,
- //! 1=validated (need to be paid),
- //! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null),
- //! 3=classified abandoned and no payment done (close_code='badcustomer','abandon' or 'replaced')
- var $statut;
- //! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon
- //! Fermeture alors que aucun paiement: replaced (si remplace), abandon
- var $close_code;
- //! Commentaire si mis a paye sans paiement complet
- var $close_note;
- //! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code
- var $paye;
- //! id of source invoice if replacement invoice or credit note
- var $fk_facture_source;
- var $origin;
- var $origin_id;
- var $linked_objects=array();
- var $fk_project;
- var $date_lim_reglement;
- var $cond_reglement_id; // Id in llx_c_paiement
- var $cond_reglement_code; // Code in llx_c_paiement
- var $mode_reglement_id; // Id in llx_c_paiement
- var $mode_reglement_code; // Code in llx_c_paiement
- var $modelpdf;
- var $products=array(); // deprecated
- var $lines=array();
- var $line;
- var $extraparams=array();
- //! Pour board
- var $nbtodo;
- var $nbtodolate;
- var $specimen;
- /**
- * Constructor
- *
- * @param DoliDB $db Database handler
- */
- function __construct($db)
- {
- $this->db = $db;
- }
- /**
- * Create invoice in database
- * Note: this->ref can be set or empty. If empty, we will use "(PROV)"
- *
- * @param User $user Object user that create
- * @param int $notrigger 1=Does not execute triggers, 0 otherwise
- * @param int $forceduedate 1=Do not recalculate due date from payment condition but force it with value
- * @return int <0 if KO, >0 if OK
- */
- function create($user,$notrigger=0,$forceduedate=0)
- {
- global $langs,$conf,$mysoc;
- $error=0;
- // Clean parameters
- if (empty($this->type)) $this->type = 0;
- $this->ref_client=trim($this->ref_client);
- $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated
- $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note));
- $this->note_public=trim($this->note_public);
- if (! $this->cond_reglement_id) $this->cond_reglement_id = 0;
- if (! $this->mode_reglement_id) $this->mode_reglement_id = 0;
- $this->brouillon = 1;
- dol_syslog(get_class($this)."::create user=".$user->id);
- // Check parameters
- if (empty($this->date) || empty($user->id))
- {
- $this->error="ErrorBadParameter";
- dol_syslog(get_class($this)."::create Try to create an invoice with an empty parameter (user, date, ...)", LOG_ERR);
- return -3;
- }
- $soc = new Societe($this->db);
- $result=$soc->fetch($this->socid);
- if ($result < 0)
- {
- $this->error="Failed to fetch company";
- dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
- return -2;
- }
- $now=dol_now();
- $this->db->begin();
- // Create invoice from a predefined invoice
- if ($this->fac_rec > 0)
- {
- require_once(DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php');
- $_facrec = new FactureRec($this->db);
- $result=$_facrec->fetch($this->fac_rec);
- $this->fk_project = $_facrec->fk_project;
- $this->cond_reglement = $_facrec->cond_reglement_id;
- $this->cond_reglement_id = $_facrec->cond_reglement_id;
- $this->mode_reglement = $_facrec->mode_reglement_id;
- $this->mode_reglement_id = $_facrec->mode_reglement_id;
- $this->remise_absolue = $_facrec->remise_absolue;
- $this->remise_percent = $_facrec->remise_percent;
- // Clean parametres
- if (! $this->type) $this->type = 0;
- $this->ref_client=trim($this->ref_client);
- $this->note=trim($this->note);
- $this->note_public=trim($this->note_public);
- //if (! $this->remise) $this->remise = 0;
- if (! $this->mode_reglement_id) $this->mode_reglement_id = 0;
- $this->brouillon = 1;
- }
- // Define due date if not already defined
- $datelim=(empty($forceduedate)?$this->calculate_date_lim_reglement():$forceduedate);
- // Insert into database
- $socid = $this->socid;
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture (";
- $sql.= " facnumber";
- $sql.= ", entity";
- $sql.= ", ref_ext";
- $sql.= ", type";
- $sql.= ", fk_soc";
- $sql.= ", datec";
- $sql.= ", remise_absolue";
- $sql.= ", remise_percent";
- $sql.= ", datef";
- $sql.= ", note";
- $sql.= ", note_public";
- $sql.= ", ref_client, ref_int";
- $sql.= ", fk_facture_source, fk_user_author, fk_projet";
- $sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf";
- $sql.= ")";
- $sql.= " VALUES (";
- $sql.= "'(PROV)'";
- $sql.= ", ".$conf->entity;
- $sql.= ", ".($this->ref_ext?"'".$this->db->escape($this->ref_ext)."'":"null");
- $sql.= ", '".$this->type."'";
- $sql.= ", '".$socid."'";
- $sql.= ", '".$this->db->idate($now)."'";
- $sql.= ",".($this->remise_absolue>0?$this->remise_absolue:'NULL');
- $sql.= ",".($this->remise_percent>0?$this->remise_percent:'NULL');
- $sql.= ", '".$this->db->idate($this->date)."'";
- $sql.= ",".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null");
- $sql.= ",".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null");
- $sql.= ",".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null");
- $sql.= ",".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null");
- $sql.= ",".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null");
- $sql.= ",".($user->id > 0 ? "'".$user->id."'":"null");
- $sql.= ",".($this->fk_project?$this->fk_project:"null");
- $sql.= ','.$this->cond_reglement_id;
- $sql.= ",".$this->mode_reglement_id;
- $sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."')";
- dol_syslog(get_class($this)."::create sql=".$sql);
- $resql=$this->db->query($sql);
- if ($resql)
- {
- $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture');
- // Update ref with new one
- $this->ref='(PROV'.$this->id.')';
- $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET facnumber='".$this->ref."' WHERE rowid=".$this->id;
- dol_syslog(get_class($this)."::create sql=".$sql);
- $resql=$this->db->query($sql);
- if (! $resql) $error++;
- // Add object linked
- if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects))
- {
- foreach($this->linked_objects as $origin => $origin_id)
- {
- $ret = $this->add_object_linked($origin, $origin_id);
- if (! $ret)
- {
- dol_print_error($this->db);
- $error++;
- }
- // TODO mutualiser
- if ($origin == 'commande')
- {
- // On recupere les differents contact interne et externe
- $order = new Commande($this->db);
- $order->id = $origin_id;
- // On recupere le commercial suivi propale
- $this->userid = $order->getIdcontact('internal', 'SALESREPFOLL');
- if ($this->userid)
- {
- //On passe le commercial suivi commande en commercial suivi paiement
- $this->add_contact($this->userid[0], 'SALESREPFOLL', 'internal');
- }
- // On recupere le contact client facturation commande
- $this->contactid = $order->getIdcontact('external', 'BILLING');
- if ($this->contactid)
- {
- //On passe le contact client facturation commande en contact client facturation
- $this->add_contact($this->contactid[0], 'BILLING', 'external');
- }
- }
- }
- }
- /*
- * Insert lines of invoices into database
- */
- if (count($this->lines) && is_object($this->lines[0]))
- {
- $fk_parent_line = 0;
- dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects");
- foreach ($this->lines as $i => $val)
- {
- $newinvoiceline=new FactureLigne($this->db);
- $newinvoiceline=$this->lines[$i];
- $newinvoiceline->fk_facture=$this->id;
- if ($result >= 0 && ($newinvoiceline->info_bits & 0x01) == 0) // We keep only lines with first bit = 0
- {
- // Reset fk_parent_line for no child products and special product
- if (($newinvoiceline->product_type != 9 && empty($newinvoiceline->fk_parent_line)) || $newinvoiceline->product_type == 9) {
- $fk_parent_line = 0;
- }
- $newinvoiceline->fk_parent_line=$fk_parent_line;
- $result=$newinvoiceline->insert();
- // Defined the new fk_parent_line
- if ($result > 0 && $newinvoiceline->product_type == 9) {
- $fk_parent_line = $result;
- }
- }
- if ($result < 0)
- {
- $this->error=$newinvoiceline->error;
- $error++;
- break;
- }
- }
- }
- else
- {
- $fk_parent_line = 0;
- dol_syslog("There is ".count($this->lines)." lines that are array lines");
- foreach ($this->lines as $i => $val)
- {
- if (($this->lines[$i]->info_bits & 0x01) == 0) // We keep only lines with first bit = 0
- {
- // Reset fk_parent_line for no child products and special product
- if (($this->lines[$i]->product_type != 9 && empty($this->lines[$i]->fk_parent_line)) || $this->lines[$i]->product_type == 9) {
- $fk_parent_line = 0;
- }
- $result = $this->addline(
- $this->id,
- $this->lines[$i]->desc,
- $this->lines[$i]->subprice,
- $this->lines[$i]->qty,
- $this->lines[$i]->tva_tx,
- $this->lines[$i]->localtax1_tx,
- $this->lines[$i]->localtax2_tx,
- $this->lines[$i]->fk_product,
- $this->lines[$i]->remise_percent,
- $this->lines[$i]->date_start,
- $this->lines[$i]->date_end,
- $this->lines[$i]->fk_code_ventilation,
- $this->lines[$i]->info_bits,
- $this->lines[$i]->fk_remise_except,
- 'HT',
- 0,
- $this->lines[$i]->product_type,
- $this->lines[$i]->rang,
- $this->lines[$i]->special_code,
- '',
- 0,
- $fk_parent_line,
- $this->lines[$i]->fk_fournprice,
- $this->lines[$i]->pa_ht
- );
- if ($result < 0)
- {
- $this->error=$this->db->lasterror();
- dol_print_error($this->db);
- $this->db->rollback();
- return -1;
- }
- // Defined the new fk_parent_line
- if ($result > 0 && $this->lines[$i]->product_type == 9) {
- $fk_parent_line = $result;
- }
- }
- }
- }
- /*
- * Insert lines of predefined invoices
- */
- if (! $error && $this->fac_rec > 0)
- {
- foreach ($_facrec->lines as $i => $val)
- {
- if ($_facrec->lines[$i]->fk_product)
- {
- $prod = new Product($this->db);
- $res=$prod->fetch($_facrec->lines[$i]->fk_product);
- }
- $tva_tx = get_default_tva($mysoc,$soc,$prod->id);
- $localtax1_tx=get_localtax($tva_tx,1,$soc);
- $localtax2_tx=get_localtax($tva_tx,2,$soc);
- $result_insert = $this->addline(
- $this->id,
- $_facrec->lines[$i]->desc,
- $_facrec->lines[$i]->subprice,
- $_facrec->lines[$i]->qty,
- $tva_tx,
- $localtax1_tx,
- $localtax2_tx,
- $_facrec->lines[$i]->fk_product,
- $_facrec->lines[$i]->remise_percent,
- '','',0,0,'','HT',0,
- $_facrec->lines[$i]->product_type,
- $_facrec->lines[$i]->rang,
- $_facrec->lines[$i]->special_code
- );
- if ( $result_insert < 0)
- {
- $error++;
- $this->error=$this->db->error();
- break;
- }
- }
- }
- if (! $error)
- {
- $result=$this->update_price(1);
- if ($result > 0)
- {
- // Appel des triggers
- include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
- $interface=new Interfaces($this->db);
- $result=$interface->run_triggers('BILL_CREATE',$this,$user,$langs,$conf);
- if ($result < 0) { $error++; $this->errors=$interface->errors; }
- // Fin appel triggers
- if (! $error)
- {
- $this->db->commit();
- return $this->id;
- }
- else
- {
- $this->db->rollback();
- return -4;
- }
- }
- else
- {
- $this->error=$langs->trans('FailedToUpdatePrice');
- $this->db->rollback();
- return -3;
- }
- }
- else
- {
- dol_syslog(get_class($this)."::create error ".$this->error, LOG_ERR);
- $this->db->rollback();
- return -2;
- }
- }
- else
- {
- $this->error=$this->db->error();
- dol_syslog(get_class($this)."::create error ".$this->error." sql=".$sql, LOG_ERR);
- $this->db->rollback();
- return -1;
- }
- }
- /**
- * Create a new invoice in database from current invoice
- *
- * @param User $user Object user that ask creation
- * @param int $invertdetail Reverse sign of amounts for lines
- * @return int <0 if KO, >0 if OK
- */
- function createFromCurrent($user,$invertdetail=0)
- {
- // Charge facture source
- $facture=new Facture($this->db);
- $facture->fk_facture_source = $this->fk_facture_source;
- $facture->type = $this->type;
- $facture->socid = $this->socid;
- $facture->date = $this->date;
- $facture->note_public = $this->note_public;
- $facture->note = $this->note;
- $facture->ref_client = $this->ref_client;
- $facture->modelpdf = $this->modelpdf;
- $facture->fk_project = $this->fk_project;
- $facture->cond_reglement_id = $this->cond_reglement_id;
- $facture->mode_reglement_id = $this->mode_reglement_id;
- $facture->remise_absolue = $this->remise_absolue;
- $facture->remise_percent = $this->remise_percent;
- $facture->lines = $this->lines; // Tableau des lignes de factures
- $facture->products = $this->lines; // Tant que products encore utilise
- // Loop on each line of new invoice
- foreach($facture->lines as $i => $line)
- {
- if ($invertdetail)
- {
- $facture->lines[$i]->subprice = -$facture->lines[$i]->subprice;
- //$facture->lines[$i]->price = -$facture->lines[$i]->price;
- $facture->lines[$i]->total_ht = -$facture->lines[$i]->total_ht;
- $facture->lines[$i]->total_tva = -$facture->lines[$i]->total_tva;
- $facture->lines[$i]->total_localtax1 = -$facture->lines[$i]->total_localtax1;
- $facture->lines[$i]->total_localtax2 = -$facture->lines[$i]->total_localtax2;
- $facture->lines[$i]->total_ttc = -$facture->lines[$i]->total_ttc;
- }
- }
- dol_syslog(get_class($this)."::createFromCurrent invertdetail=".$invertdetail." socid=".$this->socid." nboflines=".count($facture->lines));
- $facid = $facture->create($user);
- if ($facid <= 0)
- {
- $this->error=$facture->error;
- $this->errors=$facture->errors;
- }
- return $facid;
- }
- /**
- * Load an object from its id and create a new one in database
- *
- * @param int $socid Id of thirdparty
- * @param HookManager $hookmanager Hook manager instance
- * @return int New id of clone
- */
- function createFromClone($socid=0,$hookmanager=false)
- {
- global $conf,$user,$langs;
- $error=0;
- $this->db->begin();
- // Load source object
- $objFrom = dol_clone($this);
- // Change socid if needed
- if (! empty($socid) && $socid != $this->socid)
- {
- $objsoc = new Societe($this->db);
- if ($objsoc->fetch($socid)>0)
- {
- $this->socid = $objsoc->id;
- $this->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
- $this->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
- $this->fk_project = '';
- $this->fk_delivery_address = '';
- }
- // TODO Change product price if multi-prices
- }
- $this->id=0;
- $this->statut=0;
- // Clear fields
- $this->user_author = $user->id;
- $this->user_valid = '';
- $this->fk_facture_source = 0;
- $this->date_creation = '';
- $this->date_validation = '';
- $this->ref_client = '';
- $this->close_code = '';
- $this->close_note = '';
- $this->products = $this->lines; // Tant que products encore utilise
- // Loop on each line of new invoice
- foreach($this->lines as $i => $line)
- {
- if (($this->lines[$i]->info_bits & 0x02) == 0x02) // We do not clone line of discounts
- {
- unset($this->lines[$i]);
- unset($this->products[$i]); // Tant que products encore utilise
- }
- }
- // Create clone
- $result=$this->create($user);
- if ($result < 0) $error++;
- if (! $error)
- {
- // Hook of thirdparty module
- if (is_object($hookmanager))
- {
- $parameters=array('objFrom'=>$objFrom);
- $action='';
- $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
- if ($reshook < 0) $error++;
- }
- // Appel des triggers
- include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
- $interface=new Interfaces($this->db);
- $result=$interface->run_triggers('BILL_CLONE',$this,$user,$langs,$conf);
- if ($result < 0) { $error++; $this->errors=$interface->errors; }
- // Fin appel triggers
- }
- // End
- if (! $error)
- {
- $this->db->commit();
- return $this->id;
- }
- else
- {
- $this->db->rollback();
- return -1;
- }
- }
- /**
- * Load an object from an order and create a new invoice into database
- *
- * @param Object $object Object source
- * @return int <0 if KO, 0 if nothing done, 1 if OK
- */
- function createFromOrder($object)
- {
- global $conf,$user,$langs;
- $error=0;
- // Closed order
- $this->date = dol_now();
- $this->source = 0;
- $num=count($object->lines);
- for ($i = 0; $i < $num; $i++)
- {
- $line = new FactureLigne($this->db);
- $line->libelle = $object->lines[$i]->libelle;
- $line->desc = $object->lines[$i]->desc;
- //$line->price = $object->lines[$i]->price;
- $line->subprice = $object->lines[$i]->subprice;
- $line->total_ht = $object->lines[$i]->total_ht;
- $line->total_tva = $object->lines[$i]->total_tva;
- $line->total_ttc = $object->lines[$i]->total_ttc;
- $line->tva_tx = $object->lines[$i]->tva_tx;
- $line->localtax1_tx = $object->lines[$i]->localtax1_tx;
- $line->localtax2_tx = $object->lines[$i]->localtax2_tx;
- $line->qty = $object->lines[$i]->qty;
- $line->fk_remise_except = $object->lines[$i]->fk_remise_except;
- $line->remise_percent = $object->lines[$i]->remise_percent;
- $line->fk_product = $object->lines[$i]->fk_product;
- $line->info_bits = $object->lines[$i]->info_bits;
- $line->product_type = $object->lines[$i]->product_type;
- $line->rang = $object->lines[$i]->rang;
- $line->special_code = $object->lines[$i]->special_code;
- $line->fk_parent_line = $object->lines[$i]->fk_parent_line;
- $this->lines[$i] = $line;
- }
- $this->socid = $object->socid;
- $this->fk_project = $object->fk_project;
- $this->cond_reglement_id = $object->cond_reglement_id;
- $this->mode_reglement_id = $object->mode_reglement_id;
- $this->availability_id = $object->availability_id;
- $this->demand_reason_id = $object->demand_reason_id;
- $this->date_livraison = $object->date_livraison;
- $this->fk_delivery_address = $object->fk_delivery_address;
- $this->contact_id = $object->contactid;
- $this->ref_client = $object->ref_client;
- $this->note = $object->note;
- $this->note_public = $object->note_public;
- $this->origin = $object->element;
- $this->origin_id = $object->id;
- // Possibility to add external linked objects with hooks
- $this->linked_objects[$this->origin] = $this->origin_id;
- if (is_array($object->other_linked_objects) && ! empty($object->other_linked_objects))
- {
- $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
- }
- $ret = $this->create($user);
- if ($ret > 0)
- {
- // Actions hooked (by external module)
- include_once(DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php');
- $hookmanager=new HookManager($this->db);
- $hookmanager->initHooks(array('invoicedao'));
- $parameters=array('objFrom'=>$object);
- $action='';
- $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
- if ($reshook < 0) $error++;
- if (! $error)
- {
- return 1;
- }
- else return -1;
- }
- else return -1;
- }
- /**
- * Return clicable link of object (with eventually picto)
- *
- * @param int $withpicto Add picto into link
- * @param string $option Where point the link
- * @param int $max Maxlength of ref
- * @param int $short 1=Return just URL
- * @param string $moretitle Add more text to title tooltip
- * @return string String with URL
- */
- function getNomUrl($withpicto=0,$option='',$max=0,$short=0,$moretitle='')
- {
- global $langs;
- $result='';
- if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id;
- else $url = DOL_URL_ROOT.'/compta/facture.php?facid='.$this->id;
- if ($short) return $url;
- $picto='bill';
- if ($this->type == 1) $picto.='r'; // Replacement invoice
- if ($this->type == 2) $picto.='a'; // Credit note
- if ($this->type == 3) $picto.='d'; // Deposit invoice
- $label=$langs->trans("ShowInvoice").': '.$this->ref;
- if ($this->type == 1) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref;
- if ($this->type == 2) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref;
- if ($this->type == 3) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref;
- if ($moretitle) $label.=' - '.$moretitle;
- //$linkstart='<a href="'.$url.'" title="'.dol_escape_htmltag($label).'">';
- $linkstart='<a href="'.$url.'">';
- $linkend='</a>';
- if ($withpicto) $result.=($linkstart.img_object(($max?dol_trunc($label,$max):$label),$picto).$linkend);
- if ($withpicto && $withpicto != 2) $result.=' ';
- if ($withpicto != 2) $result.=$linkstart.($max?dol_trunc($this->ref,$max):$this->ref).$linkend;
- return $result;
- }
- /**
- * Get object and lines from database
- *
- * @param int $rowid Id of object to load
- * @param string $ref Reference of invoice
- * @param string $ref_ext External reference of invoice
- * @param int $ref_int Internal reference of other object
- * @return int >0 if OK, <0 if KO, 0 if not found
- */
- function fetch($rowid, $ref='', $ref_ext='', $ref_int='')
- {
- global $conf;
- if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1;
- $sql = 'SELECT f.rowid,f.facnumber,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc,f.amount,f.tva, f.localtax1, f.localtax2, f.total,f.total_ttc,f.remise_percent,f.remise_absolue,f.remise';
- $sql.= ', f.datef as df';
- $sql.= ', f.date_lim_reglement as dlr';
- $sql.= ', f.datec as datec';
- $sql.= ', f.date_valid as datev';
- $sql.= ', f.tms as datem';
- $sql.= ', f.note as 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.model_pdf';
- $sql.= ', f.fk_facture_source';
- $sql.= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet, f.extraparams';
- $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
- $sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
- $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
- $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
- $sql.= ' WHERE f.entity = '.$conf->entity;
- if ($rowid) $sql.= " AND f.rowid=".$rowid;
- if ($ref) $sql.= " AND f.facnumber='".$this->db->escape($ref)."'";
- if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'";
- if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'";
- dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG);
- $result = $this->db->query($sql);
- if ($result)
- {
- if ($this->db->num_rows($result))
- {
- $obj = $this->db->fetch_object($result);
- $this->id = $obj->rowid;
- $this->ref = $obj->facnumber;
- $this->ref_client = $obj->ref_client;
- $this->ref_ext = $obj->ref_ext;
- $this->ref_int = $obj->ref_int;
- $this->type = $obj->type;
- $this->date = $this->db->jdate($obj->df);
- $this->date_creation = $this->db->jdate($obj->datec);
- $this->date_validation = $this->db->jdate($obj->datev);
- $this->datem = $this->db->jdate($obj->datem);
- $this->remise_percent = $obj->remise_percent;
- $this->remise_absolue = $obj->remise_absolue;
- //$this->remise = $obj->remise;
- $this->total_ht = $obj->total;
- $this->total_tva = $obj->tva;
- $this->total_localtax1 = $obj->localtax1;
- $this->total_localtax2 = $obj->localtax2;
- $this->total_ttc = $obj->total_ttc;
- $this->paye = $obj->paye;
- $this->close_code = $obj->close_code;
- $this->close_note = $obj->close_note;
- $this->socid = $obj->fk_soc;
- $this->statut = $obj->fk_statut;
- $this->date_lim_reglement = $this->db->jdate($obj->dlr);
- $this->mode_reglement_id = $obj->fk_mode_reglement;
- $this->mode_reglement_code = $obj->mode_reglement_code;
- $this->mode_reglement = $obj->mode_reglement_libelle;
- $this->cond_reglement_id = $obj->fk_cond_reglement;
- $this->cond_reglement_code = $obj->cond_reglement_code;
- $this->cond_reglement = $obj->cond_reglement_libelle;
- $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
- $this->fk_project = $obj->fk_projet;
- $this->fk_facture_source = $obj->fk_facture_source;
- $this->note = $obj->note_private; // deprecated
- $this->note_private = $obj->note_private;
- $this->note_public = $obj->note_public;
- $this->user_author = $obj->fk_user_author;
- $this->user_valid = $obj->fk_user_valid;
- $this->modelpdf = $obj->model_pdf;
- $this->extraparams = (array) json_decode($obj->extraparams, true);
- if ($this->statut == 0) $this->brouillon = 1;
- /*
- * Lines
- */
- $this->lines = array();
- $result=$this->fetch_lines();
- if ($result < 0)
- {
- $this->error=$this->db->error();
- dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
- return -3;
- }
- return 1;
- }
- else
- {
- $this->error='Bill with id '.$rowid.' or ref '.$ref.' not found sql='.$sql;
- dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
- return 0;
- }
- }
- else
- {
- $this->error=$this->db->error();
- dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
- return -1;
- }
- }
- /**
- * Load all detailed lines into this->lines
- *
- * @return int 1 if OK, < 0 if KO
- */
- function fetch_lines()
- {
- $this->lines=array();
- $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.description, l.product_type, l.price, l.qty, l.tva_tx, ';
- $sql.= ' l.localtax1_tx, l.localtax2_tx, l.remise, l.remise_percent, l.fk_remise_except, l.subprice,';
- $sql.= ' l.rang, l.special_code,';
- $sql.= ' l.date_start as date_start, l.date_end as date_end,';
- $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_export_compta, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
- $sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l';
- $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
- $sql.= ' WHERE l.fk_facture = '.$this->id;
- $sql.= ' ORDER BY l.rang';
- dol_syslog(get_class($this).'::fetch_lines sql='.$sql, LOG_DEBUG);
- $result = $this->db->query($sql);
- if ($result)
- {
- $num = $this->db->num_rows($result);
- $i = 0;
- while ($i < $num)
- {
- $objp = $this->db->fetch_object($result);
- $line = new FactureLigne($this->db);
- $line->rowid = $objp->rowid;
- $line->desc = $objp->description; // Description line
- $line->product_type = $objp->product_type; // Type of line
- $line->product_ref = $objp->product_ref; // Ref product
- $line->libelle = $objp->product_label; // TODO deprecated
- $line->product_label = $objp->product_label; // Label product
- $line->product_desc = $objp->product_desc; // Description product
- $line->fk_product_type = $objp->fk_product_type; // Type of product
- $line->qty = $objp->qty;
- $line->subprice = $objp->subprice;
- $line->tva_tx = $objp->tva_tx;
- $line->localtax1_tx = $objp->localtax1_tx;
- $line->localtax2_tx = $objp->localtax2_tx;
- $line->remise_percent = $objp->remise_percent;
- $line->fk_remise_except = $objp->fk_remise_except;
- $line->fk_product = $objp->fk_product;
- $line->date_start = $this->db->jdate($objp->date_start);
- $line->date_end = $this->db->jdate($objp->date_end);
- $line->date_start = $this->db->jdate($objp->date_start);
- $line->date_end = $this->db->jdate($objp->date_end);
- $line->info_bits = $objp->info_bits;
- $line->total_ht = $objp->total_ht;
- $line->total_tva = $objp->total_tva;
- $line->total_localtax1 = $objp->total_localtax1;
- $line->total_localtax2 = $objp->total_localtax2;
- $line->total_ttc = $objp->total_ttc;
- $line->export_compta = $objp->fk_export_compta;
- $line->code_ventilation = $objp->fk_code_ventilation;
- $line->fk_fournprice = $objp->fk_fournprice;
- $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
- $line->pa_ht = $marginInfos[0];
- $line->marge_tx = $marginInfos[1];
- $line->marque_tx = $marginInfos[2];
- $line->rang = $objp->rang;
- $line->special_code = $objp->special_code;
- $line->fk_parent_line = $objp->fk_parent_line;
- // Ne plus utiliser
- //$line->price = $objp->price;
- //$line->remise = $objp->remise;
- $this->lines[$i] = $line;
- $i++;
- }
- $this->db->free($result);
- return 1;
- }
- else
- {
- $this->error=$this->db->error();
- dol_syslog(get_class($this).'::fetch_lines '.$this->error,LOG_ERR);
- return -3;
- }
- }
- /**
- * Update database
- *
- * @param User $user User that modify
- * @param int $notrigger 0=launch triggers after, 1=disable triggers
- * @return int <0 if KO, >0 if OK
- */
- function update($user=0, $notrigger=0)
- {
- global $conf, $langs;
- $error=0;
- // Clean parameters
- if (empty($this->type)) $this->type=0;
- if (isset($this->facnumber)) $this->facnumber=trim($this->ref);
- if (isset($this->ref_client)) $this->ref_client=trim($this->ref_client);
- if (isset($this->increment)) $this->increment=trim($this->increment);
- if (isset($this->close_code)) $this->close_code=trim($this->close_code);
- if (isset($this->close_note)) $this->close_note=trim($this->close_note);
- if (isset($this->note) || isset($this->note_private)) $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated
- if (isset($this->note) || isset($this->note_private)) $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note));
- if (isset($this->note_public)) $this->note_public=trim($this->note_public);
- if (isset($this->modelpdf)) $this->modelpdf=trim($this->modelpdf);
- if (isset($this->import_key)) $this->import_key=trim($this->import_key);
- // Check parameters
- // Put here code to add control on parameters values
- // Update request
- $sql = "UPDATE ".MAIN_DB_PREFIX."facture SET";
- $sql.= " facnumber=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").",";
- $sql.= " type=".(isset($this->type)?$this->type:"null").",";
- $sql.= " ref_client=".(isset($this->ref_client)?"'".$this->db->escape($this->ref_client)."'":"null").",";
- $sql.= " increment=".(isset($this->increment)?"'".$this->db->escape($this->increment)."'":"null").",";
- $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").",";
- $sql.= " datec=".(strval($this->date_creation)!='' ? "'".$this->db->idate($this->date_creation)."'" : 'null').",";
- $sql.= " datef=".(strval($this->date)!='' ? "'".$this->db->idate($this->date)."'" : 'null').",";
- $sql.= " date_valid=".(strval($this->date_validation)!='' ? "'".$this->db->idate($this->date_validation)."'" : 'null').",";
- $sql.= " paye=".(isset($this->paye)?$this->paye:"null").",";
- $sql.= " remise_percent=".(isset($this->remise_percent)?$this->remise_percent:"null").",";
- $sql.= " remise_absolue=".(isset($this->remise_absolue)?$this->remise_absolue:"null").",";
- //$sql.= " remise=".(isset($this->remise)?$this->remise:"null").",";
- $sql.= " close_code=".(isset($this->close_code)?"'".$this->db->escape($this->close_code)."'":"null").",";
- $sql.= " close_note=".(isset($this->close_note)?"'".$this->db->escape($this->close_note)."'":"null").",";
- $sql.= " tva=".(isset($this->total_tva)?$this->total_tva:"null").",";
- $sql.= " localtax1=".(isset($this->total_localtax1)?$this->total_localtax1:"null").",";
- $sql.= " localtax2=".(isset($this->total_localtax2)?$this->total_localtax2:"null").",";
- $sql.= " total=".(isset($this->total_ht)?$this->total_ht:"null").",";
- $sql.= " total_ttc=".(isset($this->total_ttc)?$this->total_ttc:"null").",";
- $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").",";
- $sql.= " fk_user_author=".(isset($this->user_author)?$this->user_author:"null").",";
- $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").",";
- $sql.= " fk_facture_source=".(isset($this->fk_facture_source)?$this->fk_facture_source:"null").",";
- $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").",";
- $sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").",";
- $sql.= " fk_mode_reglement=".(isset($this->mode_reglement_id)?$this->mode_reglement_id:"null").",";
- $sql.= " date_lim_reglement=".(strval($this->date_lim_reglement)!='' ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'null').",";
- $sql.= " note=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").",";
- $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").",";
- $sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").",";
- $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null")."";
- $sql.= " WHERE rowid=".$this->id;
- $this->db->begin();
- dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
- $resql = $this->db->query($sql);
- if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
- if (! $error)
- {
- if (! $notrigger)
- {
- // Call triggers
- include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
- $interface=new Interfaces($this->db);
- $result=$interface->run_triggers('BILL_MODIFY',$this,$user,$langs,$conf);
- if ($result < 0) { $error++; $this->errors=$interface->errors; }
- // End call triggers
- }
- }
- // Commit or rollback
- if ($error)
- {
- foreach($this->errors as $errmsg)
- {
- dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
- $this->error.=($this->error?', '.$errmsg:$errmsg);
- }
- $this->db->rollback();
- return -1*$error;
- }
- else
- {
- $this->db->commit();
- return 1;
- }
- }
- /**
- * Add a discount line into invoice using an existing absolute discount
- *
- * @param int $idremise Id of absolute discount
- * @return int >0 if OK, <0 if KO
- */
- function insert_discount($idremise)
- {
- global $langs;
- include_once(DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php');
- include_once(DOL_DOCUMENT_ROOT.'/core/class/discount.class.php');
- $this->db->begin();
- $remise=new DiscountAbsolute($this->db);
- $result=$remise->fetch($idremise);
- if ($result > 0)
- {
- if ($remise->fk_facture) // Protection against multiple submission
- {
- $this->error=$langs->trans("ErrorDiscountAlreadyUsed");
- $this->db->rollback();
- return -5;
- }
- $facligne=new FactureLigne($this->db);
- $facligne->fk_facture=$this->id;
- $facligne->fk_remise_except=$remise->id;
- $facligne->desc=$remise->description; // Description ligne
- $facligne->tva_tx=$remise->tva_tx;
- $facligne->subprice=-$remise->amount_ht;
- $facligne->fk_product=0; // Id produit predefini
- $facligne->qty=1;
- $facligne->remise_percent=0;
- $facligne->rang=-1;
- $facligne->info_bits=2;
- $facligne->total_ht = -$remise->amount_ht;
- $facligne->total_tva = -$remise->amount_tva;
- $facligne->total_ttc = -$remise->amount_ttc;
- $lineid=$facligne->insert();
- if ($lineid > 0)
- {
- $result=$this->update_price(1);
- if ($result > 0)
- {
- // Create linke between discount and invoice line
- $result=$remise->link_to_invoice($lineid,0);
- if ($result < 0)
- {
- $this->error=$remise->error;
- $this->db->rollback();
- return -4;
- }
- $this->db->commit();
- return 1;
- }
- else
- {
- $this->error=$facligne->error;
- $this->db->rollback();
- return -1;
- }
- }
- else
- {
- $this->error=$facligne->error;
- $this->db->rollback();
- return -2;
- }
- }
- else
- {
- $this->db->rollback();
- return -3;
- }
- }
- /**
- * Set customer ref
- *
- * @param string $ref_client Customer ref
- * @return int <0 if KO, >0 if OK
- */
- function set_ref_client($ref_client)
- {
- $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
- if (empty($ref_client))
- $sql .= ' SET ref_client = NULL';
- else
- $sql .= ' SET ref_client = \''.$this->db->escape($ref_client).'\'';
- $sql .= ' WHERE rowid = '.$this->id;
- if ($this->db->query($sql))
- {
- $this->ref_client = $ref_client;
- return 1;
- }
- else
- {
- dol_print_error($this->db);
- return -1;
- }
- }
- /**
- * Delete invoice
- *
- * @param int $rowid Id of invoice to delete. If empty, we delete current instance of invoice
- * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
- * @return int <0 if KO, >0 if OK
- */
- function delete($rowid=0, $notrigger=0)
- {
- global $user,$langs,$conf;
- require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
- if (! $rowid) $rowid=$this->id;
- dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG);
- // TODO Test if there is at least on payment. If yes, refuse to delete.
- $error=0;
- $this->db->begin();
- if (! $error && ! $notrigger)
- {
- // Appel des triggers
- include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
- $interface=new Interfaces($this->db);
- $result=$interface->run_triggers('BILL_DELETE',$this,$user,$langs,$conf);
- if ($result < 0) {
- $error++; $this->errors=$interface->errors;
- }
- // Fin appel triggers
- }
- if (! $error)
- {
- // Delete linkeā¦
Large files files are truncated, but you can click here to view the full file