--- /tmp/dsg/dolibarr/htdocs/compta/facture/class/github_19.0.3_api_invoices.class.php +++ /tmp/dsg/dolibarr/htdocs/compta/facture/class/client_api_invoices.class.php @@ -3 +3 @@ - * Copyright (C) 2020 Thibault FOUCART +/* Copyright (C) 2020 Thibault FOUCART @@ -22,2 +21,0 @@ -require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; - @@ -33,41 +31,34 @@ - /** - * - * @var array $FIELDS Mandatory fields, checked when create and update object - */ - public static $FIELDS = array( - 'socid', - ); - - /** - * @var Facture $invoice {@type Facture} - */ - private $invoice; - - /** - * @var FactureRec $templte_invoice {@type FactureRec} - */ - private $template_invoice; - - - /** - * Constructor - */ - public function __construct() - { - global $db, $conf; - $this->db = $db; - $this->invoice = new Facture($this->db); - $this->template_invoice = new FactureRec($this->db); - } - - /** - * Get properties of a invoice object - * - * Return an array with invoice informations - * - * @param int $id ID of invoice - * @param int $contact_list 0:Return array contains all properties, 1:Return array contains just id, -1: Do not return contacts/adddesses - * @return Object Object with cleaned properties - * - * @throws RestException - */ + /** + * + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'socid', + ); + + /** + * @var Facture $invoice {@type Facture} + */ + public $invoice; + + /** + * Constructor + */ + public function __construct() + { + global $db, $conf; + $this->db = $db; + $this->invoice = new Facture($this->db); + } + + /** + * Get properties of a invoice object + * + * Return an array with invoice informations + * + * @param int $id ID of invoice + * @param int $contact_list 0:Return array contains all properties, 1:Return array contains just id + * @return array|mixed data without useless information + * + * @throws RestException + */ @@ -76 +67 @@ - return $this->_fetch($id, '', '', $contact_list); + return $this->_fetch($id, '', '', $contact_list); @@ -79,52 +70,52 @@ - /** - * Get properties of an invoice object by ref - * - * Return an array with invoice informations - * - * @param string $ref Ref of object - * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id, -1: Do not return contacts/adddesses - * @return Object Object with cleaned properties - * - * @url GET ref/{ref} - * - * @throws RestException - */ - public function getByRef($ref, $contact_list = 1) - { - return $this->_fetch('', $ref, '', $contact_list); - } - - /** - * Get properties of an invoice object by ref_ext - * - * Return an array with invoice informations - * - * @param string $ref_ext External reference of object - * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id, -1: Do not return contacts/adddesses - * @return Object Object with cleaned properties - * - * @url GET ref_ext/{ref_ext} - * - * @throws RestException - */ - public function getByRefExt($ref_ext, $contact_list = 1) - { - return $this->_fetch('', '', $ref_ext, $contact_list); - } - - /** - * Get properties of an invoice object - * - * Return an array with invoice informations - * - * @param int $id ID of order - * @param string $ref Ref of object - * @param string $ref_ext External reference of object - * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id, -1: Do not return contacts/adddesses - * @return Object Object with cleaned properties - * - * @throws RestException - */ - private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1) - { - if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) { + /** + * Get properties of an invoice object by ref + * + * Return an array with invoice informations + * + * @param string $ref Ref of object + * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id + * @return array|mixed data without useless information + * + * @url GET ref/{ref} + * + * @throws RestException + */ + public function getByRef($ref, $contact_list = 1) + { + return $this->_fetch('', $ref, '', $contact_list); + } + + /** + * Get properties of an invoice object by ref_ext + * + * Return an array with invoice informations + * + * @param string $ref_ext External reference of object + * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id + * @return array|mixed data without useless information + * + * @url GET ref_ext/{ref_ext} + * + * @throws RestException + */ + public function getByRefExt($ref_ext, $contact_list = 1) + { + return $this->_fetch('', '', $ref_ext, $contact_list); + } + + /** + * Get properties of an invoice object + * + * Return an array with invoice informations + * + * @param int $id ID of order + * @param string $ref Ref of object + * @param string $ref_ext External reference of object + * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id + * @return array|mixed data without useless information + * + * @throws RestException + */ + private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1) + { + if (!DolibarrApiAccess::$user->rights->facture->lire) { @@ -150,6 +141 @@ - if ($contact_list > -1) { - $tmparray = $this->invoice->liste_contact(-1, 'external', $contact_list); - if (is_array($tmparray)) { - $this->invoice->contacts_ids = $tmparray; - } - } + $this->invoice->contacts_ids = $this->invoice->liste_contact(-1, 'external', $contact_list); @@ -158 +143,0 @@ - @@ -160,17 +145,16 @@ - } - - /** - * List invoices - * - * Get a list of invoices - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Limit for list - * @param int $page Page number - * @param string $thirdparty_ids Thirdparty ids to filter orders of (example '1' or '1,2,3') {@pattern /^[0-9,]*$/i} - * @param string $status Filter by invoice status : draft | unpaid | paid | cancelled - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" - * @param string $properties Restrict the data returned to theses properties. Ignored if empty. Comma separated list of properties names - * @return array Array of invoice objects - * + } + + /** + * List invoices + * + * Get a list of invoices + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $thirdparty_ids Thirdparty ids to filter orders of (example '1' or '1,2,3') {@pattern /^[0-9,]*$/i} + * @param string $status Filter by invoice status : draft | unpaid | paid | cancelled + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of invoice objects + * @@ -179,41 +163,25 @@ - */ - public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $status = '', $sqlfilters = '', $properties = '') - { - global $db, $conf; - - if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) { - throw new RestException(401); - } - - $obj_ret = array(); - - // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; - - // If the internal user must only see his customers, force searching by him - $search_sale = 0; - if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) { - $search_sale = DolibarrApiAccess::$user->id; - } - - $sql = "SELECT t.rowid"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) { - $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) - } - $sql .= " FROM ".MAIN_DB_PREFIX."facture AS t LEFT JOIN ".MAIN_DB_PREFIX."facture_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields - - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale - } - - $sql .= ' WHERE t.entity IN ('.getEntity('invoice').')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) { - $sql .= " AND t.fk_soc = sc.fk_soc"; - } - if ($socids) { - $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")"; - } - - if ($search_sale > 0) { - $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - } + */ + public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $status = '', $sqlfilters = '') + { + global $db, $conf; + + $obj_ret = array(); + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid + $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + + // If the internal user must only see his customers, force searching by him + $search_sale = 0; + if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; + + $sql = "SELECT t.rowid"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + $sql .= " FROM ".MAIN_DB_PREFIX."facture as t"; + + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + + $sql .= ' WHERE t.entity IN ('.getEntity('invoice').')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc"; + if ($socids) $sql .= " AND t.fk_soc IN (".$socids.")"; + + if ($search_sale > 0) $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale @@ -222,49 +190,49 @@ - if ($status == 'draft') { - $sql .= " AND t.fk_statut IN (0)"; - } - if ($status == 'unpaid') { - $sql .= " AND t.fk_statut IN (1)"; - } - if ($status == 'paid') { - $sql .= " AND t.fk_statut IN (2)"; - } - if ($status == 'cancelled') { - $sql .= " AND t.fk_statut IN (3)"; - } - // Insert sale filter - if ($search_sale > 0) { - $sql .= " AND sc.fk_user = ".((int) $search_sale); - } - // Add sql filters - if ($sqlfilters) { - $errormessage = ''; - $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); - if ($errormessage) { - throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); - } - } - - $sql .= $this->db->order($sortfield, $sortorder); - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit + 1, $offset); - } - - $result = $this->db->query($sql); - if ($result) { - $i = 0; - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - while ($i < $min) { - $obj = $this->db->fetch_object($result); - $invoice_static = new Facture($this->db); - if ($invoice_static->fetch($obj->rowid)) { - // Get payment details - $invoice_static->totalpaid = $invoice_static->getSommePaiement(); - $invoice_static->totalcreditnotes = $invoice_static->getSumCreditNotesUsed(); - $invoice_static->totaldeposits = $invoice_static->getSumDepositsUsed(); - $invoice_static->remaintopay = price2num($invoice_static->total_ttc - $invoice_static->totalpaid - $invoice_static->totalcreditnotes - $invoice_static->totaldeposits, 'MT'); + if ($status == 'draft') $sql .= " AND t.fk_statut IN (0)"; + if ($status == 'unpaid') $sql .= " AND t.fk_statut IN (1)"; + if ($status == 'paid') $sql .= " AND t.fk_statut IN (2)"; + if ($status == 'cancelled') $sql .= " AND t.fk_statut IN (3)"; + // Insert sale filter + if ($search_sale > 0) + { + $sql .= " AND sc.fk_user = ".$search_sale; + } + // Add sql filters + if ($sqlfilters) + { + if (!DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql .= $db->order($sortfield, $sortorder); + if ($limit) + { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + if ($result) + { + $i = 0; + $num = $db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + while ($i < $min) + { + $obj = $db->fetch_object($result); + $invoice_static = new Facture($db); + if ($invoice_static->fetch($obj->rowid)) + { + // Get payment details + $invoice_static->totalpaid = $invoice_static->getSommePaiement(); + $invoice_static->totalcreditnotes = $invoice_static->getSumCreditNotesUsed(); + $invoice_static->totaldeposits = $invoice_static->getSumDepositsUsed(); + $invoice_static->remaintopay = price2num($invoice_static->total_ttc - $invoice_static->totalpaid - $invoice_static->totalcreditnotes - $invoice_static->totaldeposits, 'MT'); @@ -273,12 +241,13 @@ - $tmparray = $invoice_static->liste_contact(-1, 'external', 1); - if (is_array($tmparray)) { - $invoice_static->contacts_ids = $tmparray; - } - $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($invoice_static), $properties); - } - $i++; - } - } else { - throw new RestException(503, 'Error when retrieve invoice list : '.$this->db->lasterror()); - } - + $invoice_static->contacts_ids = $invoice_static->liste_contact(-1, 'external', 1); + + $obj_ret[] = $this->_cleanObjectDatas($invoice_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve invoice list : '.$db->lasterror()); + } + if (!count($obj_ret)) { + throw new RestException(404, 'No invoice found'); + } @@ -286,11 +255,11 @@ - } - - /** - * Create invoice object - * - * @param array $request_data Request datas - * @return int ID of invoice - */ - public function post($request_data = null) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { + } + + /** + * Create invoice object + * + * @param array $request_data Request datas + * @return int ID of invoice + */ + public function post($request_data = null) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { @@ -299,32 +268,165 @@ - // Check mandatory fields - $result = $this->_validate($request_data); - - foreach ($request_data as $field => $value) { - if ($field === 'caller') { - // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again whith the caller - $this->invoice->context['caller'] = $request_data['caller']; - continue; - } - - $this->invoice->$field = $value; - } - if (!array_key_exists('date', $request_data)) { - $this->invoice->date = dol_now(); - } - /* We keep lines as an array - if (isset($request_data["lines"])) { - $lines = array(); - foreach ($request_data["lines"] as $line) { - array_push($lines, (object) $line); - } - $this->invoice->lines = $lines; - }*/ - - if ($this->invoice->create(DolibarrApiAccess::$user, 0, (empty($request_data["date_lim_reglement"]) ? 0 : $request_data["date_lim_reglement"])) < 0) { - throw new RestException(500, "Error creating invoice", array_merge(array($this->invoice->error), $this->invoice->errors)); - } - return ((int) $this->invoice->id); - } - - /** - * Create an invoice using an existing order. + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach ($request_data as $field => $value) { + $this->invoice->$field = $value; + } + if (!array_key_exists('date', $request_data)) { + $this->invoice->date = dol_now(); + } + /* We keep lines as an array + if (isset($request_data["lines"])) { + $lines = array(); + foreach ($request_data["lines"] as $line) { + array_push($lines, (object) $line); + } + $this->invoice->lines = $lines; + }*/ + + if ($this->invoice->create(DolibarrApiAccess::$user, 0, (empty($request_data["date_lim_reglement"]) ? 0 : $request_data["date_lim_reglement"])) < 0) { + throw new RestException(500, "Error creating invoice", array_merge(array($this->invoice->error), $this->invoice->errors)); + } + return $this->invoice->id; + } + + /** + * Create an invoice using an existing order. + * + * + * @param int $orderid Id of the order + * + * @url POST /createfromorder/{orderid} + * + * @return int + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 + */ + public function createInvoiceFromOrder($orderid) + { + + require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; + + if (!DolibarrApiAccess::$user->rights->commande->lire) { + throw new RestException(401); + } + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + if (empty($orderid)) { + throw new RestException(400, 'Order ID is mandatory'); + } + + $order = new Commande($this->db); + $result = $order->fetch($orderid); + if (!$result) { + throw new RestException(404, 'Order not found'); + } + + $result = $this->invoice->createFromOrder($order, DolibarrApiAccess::$user); + if ($result < 0) { + throw new RestException(405, $this->invoice->error); + } + $this->invoice->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->invoice); + } + + /** + * Get lines of an invoice + * + * @param int $id Id of invoice + * + * @url GET {id}/lines + * + * @return int + */ + public function getLines($id) + { + if (!DolibarrApiAccess::$user->rights->facture->lire) { + throw new RestException(401); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $this->invoice->getLinesArray(); + $result = array(); + foreach ($this->invoice->lines as $line) { + array_push($result, $this->_cleanObjectDatas($line)); + } + return $result; + } + + /** + * Update a line to a given invoice + * + * @param int $id Id of invoice to update + * @param int $lineid Id of line to update + * @param array $request_data InvoiceLine data + * + * @url PUT {id}/lines/{lineid} + * + * @return array + * + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 Invoice not found + */ + public function putLine($id, $lineid, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $request_data = (object) $request_data; + $updateRes = $this->invoice->updateline( + $lineid, + $request_data->desc, + $request_data->subprice, + $request_data->qty, + $request_data->remise_percent, + $request_data->date_start, + $request_data->date_end, + $request_data->tva_tx, + $request_data->localtax1_tx, + $request_data->localtax2_tx, + 'HT', + $request_data->info_bits, + $request_data->product_type, + $request_data->fk_parent_line, + 0, + $request_data->fk_fournprice, + $request_data->pa_ht, + $request_data->label, + $request_data->special_code, + $request_data->array_options, + $request_data->situation_percent, + $request_data->fk_unit, + $request_data->multicurrency_subprice + ); + + if ($updateRes > 0) { + $result = $this->get($id); + unset($result->line); + return $this->_cleanObjectDatas($result); + } else { + throw new RestException(304, $this->invoice->error); + } + } + + /** + * Add a contact type of given invoice @@ -332,2 +434,3 @@ - * @param int $orderid Id of the order - * @return Object Object with cleaned properties + * @param int $id Id of invoice to update + * @param int $contactid Id of contact to add + * @param string $type Type of the contact (BILLING, SHIPPING, CUSTOMER) @@ -335 +438 @@ - * @url POST /createfromorder/{orderid} + * @url POST {id}/contact/{contactid}/{type} @@ -337,4 +440,4 @@ - * @throws RestException 400 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 405 + * @return int + * + * @throws RestException 401 + * @throws RestException 404 @@ -342,43 +445,8 @@ - public function createInvoiceFromOrder($orderid) - { - require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; - - if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) { - throw new RestException(401); - } - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - if (empty($orderid)) { - throw new RestException(400, 'Order ID is mandatory'); - } - - $order = new Commande($this->db); - $result = $order->fetch($orderid); - if (!$result) { - throw new RestException(404, 'Order not found'); - } - - $result = $this->invoice->createFromOrder($order, DolibarrApiAccess::$user); - if ($result < 0) { - throw new RestException(405, $this->invoice->error); - } - $this->invoice->fetchObjectLinked(); - return $this->_cleanObjectDatas($this->invoice); - } - - /** - * Get lines of an invoice - * - * @param int $id Id of invoice - * @return array Array of lines - * - * @url GET {id}/lines - */ - public function getLines($id) - { - if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) { - throw new RestException(401); - } - - $result = $this->invoice->fetch($id); + public function postContact($id, $contactid, $type) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + + $result = $this->invoice->fetch($id); + @@ -388,0 +457,119 @@ + if (!in_array($type, array('BILLING', 'SHIPPING', 'CUSTOMER'), true)) { + throw new RestException(500, 'Availables types: BILLING, SHIPPING OR CUSTOMER'); + } + + if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->add_contact($contactid, $type, 'external'); + + if (!$result) { + throw new RestException(500, 'Error when added the contact'); + } + + return $this->_cleanObjectDatas($this->invoice); + } + + /** + * Delete a contact type of given invoice + * + * @param int $id Id of invoice to update + * @param int $rowid Row key of the contact in the array contact_ids. + * + * @url DELETE {id}/contact/{rowid} + * + * @return array + * + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 + */ + public function deleteContact($id, $rowid) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + + $result = $this->invoice->fetch($id); + + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->delete_contact($rowid); + if ($result < 0) { + throw new RestException(500, 'Error when deleted the contact'); + } + + return $this->_cleanObjectDatas($this->invoice); + } + + /** + * Deletes a line of a given invoice + * + * @param int $id Id of invoice + * @param int $lineid Id of the line to delete + * + * @url DELETE {id}/lines/{lineid} + * + * @return array + * + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 + */ + public function deleteLine($id, $lineid) + { + + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + if (empty($lineid)) { + throw new RestException(400, 'Line ID is mandatory'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + // TODO Check the lineid $lineid is a line of ojbect + + $updateRes = $this->invoice->deleteline($lineid); + if ($updateRes > 0) { + return $this->get($id); + } + else + { + throw new RestException(405, $this->invoice->error); + } + } + + /** + * Update invoice + * + * @param int $id Id of invoice to update + * @param array $request_data Datas + * @return int + */ + public function put($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + @@ -392,25 +579,29 @@ - $this->invoice->getLinesArray(); - $result = array(); - foreach ($this->invoice->lines as $line) { - array_push($result, $this->_cleanObjectDatas($line)); - } - return $result; - } - - /** - * Update a line to a given invoice - * - * @param int $id Id of invoice to update - * @param int $lineid Id of line to update - * @param array $request_data InvoiceLine data - * @return Object Object with cleaned properties - * - * @url PUT {id}/lines/{lineid} - * - * @throws RestException 304 - * @throws RestException 401 - * @throws RestException 404 Invoice not found - */ - public function putLine($id, $lineid, $request_data = null) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { + + foreach ($request_data as $field => $value) { + if ($field == 'id') continue; + $this->invoice->$field = $value; + } + + // update bank account + if (!empty($this->invoice->fk_account)) + { + if ($this->invoice->setBankAccount($this->invoice->fk_account) == 0) { + throw new RestException(400, $this->invoice->error); + } + } + + if ($this->invoice->update(DolibarrApiAccess::$user)) + return $this->get($id); + + return false; + } + + /** + * Delete invoice + * + * @param int $id Invoice ID + * @return array + */ + public function delete($id) + { + if (!DolibarrApiAccess::$user->rights->facture->supprimer) { @@ -419,5 +610,4 @@ - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } @@ -429,45 +619,539 @@ - $request_data = (object) $request_data; - - $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml'); - $request_data->label = sanitizeVal($request_data->label); - - $updateRes = $this->invoice->updateline( - $lineid, - $request_data->desc, - $request_data->subprice, - $request_data->qty, - $request_data->remise_percent, - $request_data->date_start, - $request_data->date_end, - $request_data->tva_tx, - $request_data->localtax1_tx, - $request_data->localtax2_tx, - $request_data->price_base_type ? $request_data->price_base_type : 'HT', - $request_data->info_bits, - $request_data->product_type, - $request_data->fk_parent_line, - 0, - $request_data->fk_fournprice, - $request_data->pa_ht, - $request_data->label, - $request_data->special_code, - $request_data->array_options, - $request_data->situation_percent, - $request_data->fk_unit, - $request_data->multicurrency_subprice, - 0, - $request_data->ref_ext, - $request_data->rang - ); - - if ($updateRes > 0) { - $result = $this->get($id); - unset($result->line); - return $this->_cleanObjectDatas($result); - } else { - throw new RestException(304, $this->invoice->error); - } - } - - /** - * Add a contact type of given invoice + $result = $this->invoice->delete(DolibarrApiAccess::$user); + if ($result < 0) + { + throw new RestException(500); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Invoice deleted' + ) + ); + } + + /** + * Add a line to a given invoice + * + * Exemple of POST query : + * { + * "desc": "Desc", "subprice": "1.00000000", "qty": "1", "tva_tx": "20.000", "localtax1_tx": "0.000", "localtax2_tx": "0.000", + * "fk_product": "1", "remise_percent": "0", "date_start": "", "date_end": "", "fk_code_ventilation": 0, "info_bits": "0", + * "fk_remise_except": null, "product_type": "1", "rang": "-1", "special_code": "0", "fk_parent_line": null, "fk_fournprice": null, + * "pa_ht": "0.00000000", "label": "", "array_options": [], "situation_percent": "100", "fk_prev_id": null, "fk_unit": null + * } + * + * @param int $id Id of invoice + * @param array $request_data InvoiceLine data + * + * @url POST {id}/lines + * + * @return int + * + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 400 + */ + public function postLine($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $request_data = (object) $request_data; + + // Reset fk_parent_line for no child products and special product + if (($request_data->product_type != 9 && empty($request_data->fk_parent_line)) || $request_data->product_type == 9) { + $request_data->fk_parent_line = 0; + } + + // calculate pa_ht + $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht); + $pa_ht = $marginInfos[0]; + + $updateRes = $this->invoice->addline( + $request_data->desc, + $request_data->subprice, + $request_data->qty, + $request_data->tva_tx, + $request_data->localtax1_tx, + $request_data->localtax2_tx, + $request_data->fk_product, + $request_data->remise_percent, + $request_data->date_start, + $request_data->date_end, + $request_data->fk_code_ventilation, + $request_data->info_bits, + $request_data->fk_remise_except, + 'HT', + 0, + $request_data->product_type, + $request_data->rang, + $request_data->special_code, + $request_data->origin, + $request_data->origin_id, + $request_data->fk_parent_line, + empty($request_data->fk_fournprice) ?null:$request_data->fk_fournprice, + $pa_ht, + $request_data->label, + $request_data->array_options, + $request_data->situation_percent, + $request_data->fk_prev_id, + $request_data->fk_unit + ); + + if ($updateRes < 0) { + throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error); + } + + return $updateRes; + } + + /** + * Adds a contact to an invoice + * + * @param int $id Order ID + * @param int $fk_socpeople Id of thirdparty contact (if source = 'external') or id of user (if souce = 'internal') to link + * @param string $type_contact Type of contact (code). Must a code found into table llx_c_type_contact. For example: BILLING + * @param string $source external=Contact extern (llx_socpeople), internal=Contact intern (llx_user) + * @param int $notrigger Disable all triggers + * + * @url POST {id}/contacts + * + * @return array + * + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 + * + */ + public function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger = 0) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->add_contact($fk_socpeople, $type_contact, $source, $notrigger); + if ($result < 0) { + throw new RestException(500, 'Error : '.$this->invoice->error); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + return $this->_cleanObjectDatas($this->invoice); + } + + + + /** + * Sets an invoice as draft + * + * @param int $id Order ID + * @param int $idwarehouse Warehouse ID + * + * @url POST {id}/settodraft + * + * @return array + * + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 + * + */ + public function settodraft($id, $idwarehouse = -1) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->setDraft(DolibarrApiAccess::$user, $idwarehouse); + if ($result == 0) { + throw new RestException(304, 'Nothing done.'); + } + if ($result < 0) { + throw new RestException(500, 'Error : '.$this->invoice->error); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + return $this->_cleanObjectDatas($this->invoice); + } + + + /** + * Validate an invoice + * + * If you get a bad value for param notrigger check that ou provide this in body + * { + * "idwarehouse": 0, + * "notrigger": 0 + * } + * + * @param int $id Invoice ID + * @param int $idwarehouse Warehouse ID + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * + * @url POST {id}/validate + * + * @return array + */ + public function validate($id, $idwarehouse = 0, $notrigger = 0) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); + if ($result == 0) { + throw new RestException(304, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + return $this->_cleanObjectDatas($this->invoice); + } + + /** + * Sets an invoice as paid + * + * @param int $id Order ID + * @param string $close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple) + * @param string $close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple) + * + * @url POST {id}/settopaid + * + * @return array An invoice object + * + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 + */ + public function settopaid($id, $close_code = '', $close_note = '') + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->set_paid(DolibarrApiAccess::$user, $close_code, $close_note); + if ($result == 0) { + throw new RestException(304, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error : '.$this->invoice->error); + } + + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + return $this->_cleanObjectDatas($this->invoice); + } + + + /** + * Sets an invoice as unpaid + * + * @param int $id Order ID + * + * @url POST {id}/settounpaid + * + * @return array An invoice object + * + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 + */ + public function settounpaid($id) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->set_unpaid(DolibarrApiAccess::$user); + if ($result == 0) { + throw new RestException(304, 'Nothing done'); + } + if ($result < 0) { + throw new RestException(500, 'Error : '.$this->invoice->error); + } + + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + return $this->_cleanObjectDatas($this->invoice); + } + + /** + * Create a discount (credit available) for a credit note or a deposit. + * + * @param int $id Invoice ID + * @url POST {id}/markAsCreditAvailable + * + * @return array An invoice object + * + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 + */ + public function markAsCreditAvailable($id) + { + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if ($this->invoice->paye) { + throw new RestException(500, 'Alreay payed'); + } + + $this->invoice->fetch($id); + $this->invoice->fetch_thirdparty(); + + // Check if there is already a discount (protection to avoid duplicate creation when resubmit post) + $discountcheck = new DiscountAbsolute($this->db); + $result = $discountcheck->fetch(0, $this->invoice->id); + + $canconvert = 0; + if ($this->invoice->type == Facture::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert = 1; // we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc) + if (($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_STANDARD) && $this->invoice->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) + if ($canconvert) + { + $this->db->begin(); + + $amount_ht = $amount_tva = $amount_ttc = array(); + $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array(); + + // Loop on each vat rate + $i = 0; + foreach ($this->invoice->lines as $line) + { + if ($line->product_type < 9 && $line->total_ht != 0) // Remove lines with product_type greater than or equal to 9 + { // no need to create discount if amount is null + $amount_ht[$line->tva_tx] += $line->total_ht; + $amount_tva[$line->tva_tx] += $line->total_tva; + $amount_ttc[$line->tva_tx] += $line->total_ttc; + $multicurrency_amount_ht[$line->tva_tx] += $line->multicurrency_total_ht; + $multicurrency_amount_tva[$line->tva_tx] += $line->multicurrency_total_tva; + $multicurrency_amount_ttc[$line->tva_tx] += $line->multicurrency_total_ttc; + $i++; + } + } + + // Insert one discount by VAT rate category + $discount = new DiscountAbsolute($this->db); + if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { + $discount->description = '(CREDIT_NOTE)'; + } + elseif ($this->invoice->type == Facture::TYPE_DEPOSIT) { + $discount->description = '(DEPOSIT)'; + } + elseif ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION) { + $discount->description = '(EXCESS RECEIVED)'; + } + else { + throw new RestException(500, 'Cant convert to reduc an Invoice of this type'); + } + + $discount->fk_soc = $this->invoice->socid; + $discount->fk_facture_source = $this->invoice->id; + + $error = 0; + + if ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION) + { + // If we're on a standard invoice, we have to get excess received to create a discount in TTC without VAT + + // Total payments + $sql = 'SELECT SUM(pf.amount) as total_paiements'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id'; + $sql .= ' WHERE pf.fk_facture = '.$this->invoice->id; + $sql .= ' AND pf.fk_paiement = p.rowid'; + $sql .= ' AND p.entity IN ('.getEntity('invoice').')'; + $resql = $this->db->query($sql); + if (!$resql) dol_print_error($this->db); + + $res = $this->db->fetch_object($resql); + $total_paiements = $res->total_paiements; + + // Total credit note and deposit + $total_creditnote_and_deposit = 0; + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; + $sql .= " re.description, re.fk_facture_source"; + $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re"; + $sql .= " WHERE fk_facture = ".$this->invoice->id; + $resql = $this->db->query($sql); + if (!empty($resql)) { + while ($obj = $this->db->fetch_object($resql)) $total_creditnote_and_deposit += $obj->amount_ttc; + } else dol_print_error($this->db); + + $discount->amount_ht = $discount->amount_ttc = $total_paiements + $total_creditnote_and_deposit - $this->invoice->total_ttc; + $discount->amount_tva = 0; + $discount->tva_tx = 0; + + $result = $discount->create(DolibarrApiAccess::$user); + if ($result < 0) + { + $error++; + } + } + if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_DEPOSIT) + { + foreach ($amount_ht as $tva_tx => $xxx) + { + $discount->amount_ht = abs($amount_ht[$tva_tx]); + $discount->amount_tva = abs($amount_tva[$tva_tx]); + $discount->amount_ttc = abs($amount_ttc[$tva_tx]); + $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]); + $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]); + $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]); + $discount->tva_tx = abs($tva_tx); + + $result = $discount->create(DolibarrApiAccess::$user); + if ($result < 0) + { + $error++; + break; + } + } + } + + if (empty($error)) + { + if ($this->invoice->type != Facture::TYPE_DEPOSIT) { + // Classe facture + $result = $this->invoice->set_paid(DolibarrApiAccess::$user); + if ($result >= 0) + { + $this->db->commit(); + } + else + { + $this->db->rollback(); + throw new RestException(500, 'Could not set paid'); + } + } else { + $this->db->commit(); + } + } + else + { + $this->db->rollback(); + throw new RestException(500, 'Discount creation error'); + } + } + + return $this->_cleanObjectDatas($this->invoice); + } + + /** + * Add a discount line into an invoice (as an invoice line) using an existing absolute discount + * + * Note that this consume the discount. + * + * @param int $id Id of invoice + * @param int $discountid Id of discount + * + * @url POST {id}/usediscount/{discountid} + * + * @return int @@ -475,4 +1159,92 @@ - * @param int $id Id of invoice to update - * @param int $contactid Id of contact to add - * @param string $type Type of the contact (BILLING, SHIPPING, CUSTOMER) - * @return array + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 + */ + public function useDiscount($id, $discountid) + { + + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + if (empty($id)) { + throw new RestException(400, 'Invoice ID is mandatory'); + } + if (empty($discountid)) { + throw new RestException(400, 'Discount ID is mandatory'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + $result = $this->invoice->insert_discount($discountid); + if ($result < 0) { + throw new RestException(405, $this->invoice->error); + } + + return $result; + } + + /** + * Add an available credit note discount to payments of an existing invoice. + * + * Note that this consume the credit note. + * + * @param int $id Id of invoice + * @param int $discountid Id of a discount coming from a credit note + * + * @url POST {id}/usecreditnote/{discountid} + * + * @return int + * + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 + */ + public function useCreditNote($id, $discountid) + { + + require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + if (empty($id)) { + throw new RestException(400, 'Invoice ID is mandatory'); + } + if (empty($discountid)) { + throw new RestException(400, 'Credit ID is mandatory'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $discount = new DiscountAbsolute($this->db); + $result = $discount->fetch($discountid); + if (!$result) { + throw new RestException(404, 'Credit not found'); + } + + $result = $discount->link_to_invoice(0, $id); + if ($result < 0) { + throw new RestException(405, $discount->error); + } + + return $result; + } + + /** + * Get list of payments of a given invoice + * + * @param int $id Id of invoice + * + * @url GET {id}/payments + * + * @return array @@ -480 +1252,49 @@ - * @url POST {id}/contact/{contactid}/{type} + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 + */ + public function getPayments($id) + { + + if (!DolibarrApiAccess::$user->rights->facture->lire) { + throw new RestException(401); + } + if (empty($id)) { + throw new RestException(400, 'Invoice ID is mandatory'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + $result = $this->invoice->getListOfPayments(); + if ($result < 0) { + throw new RestException(405, $this->invoice->error); + } + + return $result; + } + + + /** + * Add payment line to a specific invoice with the remain to pay as amount. + * + * @param int $id Id of invoice + * @param string $datepaye {@from body} Payment date {@type timestamp} + * @param int $paiementid {@from body} Payment mode Id {@min 1} + * @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no} + * @param int $accountid {@from body} Account Id {@min 1} + * @param string $num_paiement {@from body} Payment number (optional) + * @param string $comment {@from body} Note (optional) + * @param string $chqemetteur {@from body} Payment issuer (mandatory if paiementcode = 'CHQ') + * @param string $chqbank {@from body} Issuer bank name (optional) + * + * @url POST {id}/payments + * + * @return int Payment ID @@ -482,39 +1302,119 @@ - * @throws RestException 401 - * @throws RestException 404 - */ - public function postContact($id, $contactid, $type) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - - $result = $this->invoice->fetch($id); - - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!in_array($type, array('BILLING', 'SHIPPING', 'CUSTOMER'), true)) { - throw new RestException(500, 'Availables types: BILLING, SHIPPING OR CUSTOMER'); - } - - if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->add_contact($contactid, $type, 'external'); - - if (!$result) { - throw new RestException(500, 'Error when added the contact'); - } - - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Contact linked to the invoice' - ) - ); - } - - /** - * Delete a contact type of given invoice + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + */ + public function addPayment($id, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement = '', $comment = '', $chqemetteur = '', $chqbank = '') + { + global $conf; + + require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; + + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(403); + } + if (empty($id)) { + throw new RestException(400, 'Invoice ID is mandatory'); + } + + if (!DolibarrApi::_checkAccessToResource('facture', $id)) { + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if (!empty($conf->banque->enabled)) { + if (empty($accountid)) { + throw new RestException(400, 'Account ID is mandatory'); + } + } + + if (empty($paiementid)) { + throw new RestException(400, 'Paiement ID or Paiement Code is mandatory'); + } + + + $result = $this->invoice->fetch($id); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + // Calculate amount to pay + $totalpaye = $this->invoice->getSommePaiement(); + $totalcreditnotes = $this->invoice->getSumCreditNotesUsed(); + $totaldeposits = $this->invoice->getSumDepositsUsed(); + $resteapayer = price2num($this->invoice->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + + $this->db->begin(); + + $amounts = array(); + $multicurrency_amounts = array(); + + // Clean parameters amount if payment is for a credit note + if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { + $resteapayer = price2num($resteapayer, 'MT'); + $amounts[$id] = -$resteapayer; + // Multicurrency + $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT'); + $multicurrency_amounts[$id] = -$newvalue; + } else { + $resteapayer = price2num($resteapayer, 'MT'); + $amounts[$id] = $resteapayer; + // Multicurrency + $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT'); + $multicurrency_amounts[$id] = $newvalue; + } + + + // Creation of payment line + $paiement = new Paiement($this->db); + $paiement->datepaye = $datepaye; + $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id + $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching + $paiement->paiementid = $paiementid; + $paiement->paiementcode = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->num_paiement = $num_paiement; + $paiement->note = $comment; + + $paiement_id = $paiement->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices + if ($paiement_id < 0) + { + $this->db->rollback(); + throw new RestException(400, 'Payment error : '.$paiement->error); + } + + if (!empty($conf->banque->enabled)) { + $label = '(CustomerInvoicePayment)'; + + if ($paiement->paiementcode == 'CHQ' && empty($chqemetteur)) { + throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paiement->paiementcode); + } + if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note + $result = $paiement->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank); + if ($result < 0) + { + $this->db->rollback(); + throw new RestException(400, 'Add payment to bank error : '.$paiement->error); + } + } + + $this->db->commit(); + + return $paiement_id; + } + + /** + * Add a payment to pay partially or completely one or several invoices. + * Warning: Take care that all invoices are owned by the same customer. + * Example of value for parameter arrayofamounts: {"1": "99.99", "2": "10"} + * + * @param array $arrayofamounts {@from body} Array with id of invoices with amount to pay for each invoice + * @param string $datepaye {@from body} Payment date {@type timestamp} + * @param int $paiementid {@from body} Payment mode Id {@min 1} + * @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no} + * @param int $accountid {@from body} Account Id {@min 1} + * @param string $num_paiement {@from body} Payment number (optional) + * @param string $comment {@from body} Note (optional) + * @param string $chqemetteur {@from body} Payment issuer (mandatory if paiementcode = 'CHQ') + * @param string $chqbank {@from body} Issuer bank name (optional) + * + * @url POST /paymentsdistributed + * + * @return int Payment ID @@ -522,1280 +1422,151 @@ - * @param int $id Id of invoice to update - * @param int $contactid Row key of the contact in the array contact_ids. - * @param string $type Type of the contact (BILLING, SHIPPING, CUSTOMER). - * @return Object Object with cleaned properties - * - * @url DELETE {id}/contact/{contactid}/{type} - * - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 500 System error - */ - public function deleteContact($id, $contactid, $type) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - - $result = $this->invoice->fetch($id); - - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $contacts = $this->invoice->liste_contact(); - - foreach ($contacts as $contact) { - if ($contact['id'] == $contactid && $contact['code'] == $type) { - $result = $this->invoice->delete_contact($contact['rowid']); - - if (!$result) { - throw new RestException(500, 'Error when deleted the contact'); - } - } - } - - return $this->_cleanObjectDatas($this->invoice); - } - - /** - * Deletes a line of a given invoice - * - * @param int $id Id of invoice - * @param int $lineid Id of the line to delete - * @return Object Object with cleaned properties - * - * @url DELETE {id}/lines/{lineid} - * - * @throws RestException 400 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 405 - */ - public function deleteLine($id, $lineid) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - if (empty($lineid)) { - throw new RestException(400, 'Line ID is mandatory'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - $updateRes = $this->invoice->deleteline($lineid, $id); - if ($updateRes > 0) { - return $this->get($id); - } else { - throw new RestException(405, $this->invoice->error); - } - } - - /** - * Update invoice - * - * @param int $id Id of invoice to update - * @param array $request_data Datas - * @return Object|false Object with cleaned properties - */ - public function put($id, $request_data = null) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - foreach ($request_data as $field => $value) { - if ($field == 'id') { - continue; - } - if ($field === 'caller') { - // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again whith the caller - $this->invoice->context['caller'] = $request_data['caller']; - continue; - } - - $this->invoice->$field = $value; - } - - // update bank account - if (!empty($this->invoice->fk_account)) { - if ($this->invoice->setBankAccount($this->invoice->fk_account) == 0) { - throw new RestException(400, $this->invoice->error); - } - } - - if ($this->invoice->update(DolibarrApiAccess::$user)) { - return $this->get($id); - } - - return false; - } - - /** - * Delete invoice - * - * @param int $id Invoice ID - * @return array - */ - public function delete($id) - { - if (!DolibarrApiAccess::$user->hasRight('facture', 'supprimer')) { - throw new RestException(401); - } - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->delete(DolibarrApiAccess::$user); - if ($result < 0) { - throw new RestException(500, 'Error when deleting invoice'); - } elseif ($result == 0) { - throw new RestException(403, 'Invoice not erasable'); - } - - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Invoice deleted' - ) - ); - } - - /** - * Add a line to a given invoice - * - * Exemple of POST query : - * { - * "desc": "Desc", "subprice": "1.00000000", "qty": "1", "tva_tx": "20.000", "localtax1_tx": "0.000", "localtax2_tx": "0.000", - * "fk_product": "1", "remise_percent": "0", "date_start": "", "date_end": "", "fk_code_ventilation": 0, "info_bits": "0", - * "fk_remise_except": null, "product_type": "1", "rang": "-1", "special_code": "0", "fk_parent_line": null, "fk_fournprice": null, - * "pa_ht": "0.00000000", "label": "", "array_options": [], "situation_percent": "100", "fk_prev_id": null, "fk_unit": null - * } - * - * @param int $id Id of invoice - * @param array $request_data InvoiceLine data - * - * @url POST {id}/lines - * - * @return int - * - * @throws RestException 304 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 400 - */ - public function postLine($id, $request_data = null) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $request_data = (object) $request_data; - - $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml'); - $request_data->label = sanitizeVal($request_data->label); - - // Reset fk_parent_line for no child products and special product - if (($request_data->product_type != 9 && empty($request_data->fk_parent_line)) || $request_data->product_type == 9) { - $request_data->fk_parent_line = 0; - } - - // calculate pa_ht - $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht); - $pa_ht = $marginInfos[0]; - - $updateRes = $this->invoice->addline( - $request_data->desc, - $request_data->subprice, - $request_data->qty, - $request_data->tva_tx, - $request_data->localtax1_tx, - $request_data->localtax2_tx, - $request_data->fk_product, - $request_data->remise_percent, - $request_data->date_start, - $request_data->date_end, - $request_data->fk_code_ventilation, - $request_data->info_bits, - $request_data->fk_remise_except, - $request_data->price_base_type ? $request_data->price_base_type : 'HT', - $request_data->subprice, - $request_data->product_type, - $request_data->rang, - $request_data->special_code, - $request_data->origin, - $request_data->origin_id, - $request_data->fk_parent_line, - empty($request_data->fk_fournprice) ? null : $request_data->fk_fournprice, - $pa_ht, - $request_data->label, - $request_data->array_options, - $request_data->situation_percent, - $request_data->fk_prev_id, - $request_data->fk_unit, - 0, - $request_data->ref_ext - ); - - if ($updateRes < 0) { - throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error); - } - - return $updateRes; - } - - /** - * Adds a contact to an invoice - * - * @param int $id Order ID - * @param int $fk_socpeople Id of thirdparty contact (if source = 'external') or id of user (if souce = 'internal') to link - * @param string $type_contact Type of contact (code). Must a code found into table llx_c_type_contact. For example: BILLING - * @param string $source external=Contact extern (llx_socpeople), internal=Contact intern (llx_user) - * @param int $notrigger Disable all triggers - * - * @url POST {id}/contacts - * - * @return object - * - * @throws RestException 304 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 500 System error - * - */ - public function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger = 0) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->add_contact($fk_socpeople, $type_contact, $source, $notrigger); - if ($result < 0) { - throw new RestException(500, 'Error : '.$this->invoice->error); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - return $this->_cleanObjectDatas($this->invoice); - } - - - - /** - * Sets an invoice as draft - * - * @param int $id Order ID - * @param int $idwarehouse Warehouse ID - * @return Object Object with cleaned properties - * - * @url POST {id}/settodraft - * - * @throws RestException 304 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 500 System error - * - */ - public function settodraft($id, $idwarehouse = -1) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->setDraft(DolibarrApiAccess::$user, $idwarehouse); - if ($result == 0) { - throw new RestException(304, 'Nothing done.'); - } - if ($result < 0) { - throw new RestException(500, 'Error : '.$this->invoice->error); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - return $this->_cleanObjectDatas($this->invoice); - } - - - /** - * Validate an invoice - * - * If you get a bad value for param notrigger check that ou provide this in body - * { - * "idwarehouse": 0, - * "notrigger": 0 - * } - * - * @param int $id Invoice ID - * @param int $idwarehouse Warehouse ID - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return Object|false Object with cleaned properties - * - * @url POST {id}/validate - */ - public function validate($id, $idwarehouse = 0, $notrigger = 0) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); - if ($result == 0) { - throw new RestException(304, 'Error nothing done. May be object is already validated'); - } - if ($result < 0) { - throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - return $this->_cleanObjectDatas($this->invoice); - } - - /** - * Sets an invoice as paid - * - * @param int $id Order ID - * @param string $close_code Code filled if we classify to 'Paid completely' when payment is not complete (for escompte for example) - * @param string $close_note Comment defined if we classify to 'Paid' when payment is not complete (for escompte for example) - * @return Object Object with cleaned properties - * - * @url POST {id}/settopaid - * - * @throws RestException 304 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 500 System error - */ - public function settopaid($id, $close_code = '', $close_note = '') - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->setPaid(DolibarrApiAccess::$user, $close_code, $close_note); - if ($result == 0) { - throw new RestException(304, 'Error nothing done. May be object is already validated'); - } - if ($result < 0) { - throw new RestException(500, 'Error : '.$this->invoice->error); - } - - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - return $this->_cleanObjectDatas($this->invoice); - } - - - /** - * Sets an invoice as unpaid - * - * @param int $id Order ID - * @return Object Object with cleaned properties - * - * @url POST {id}/settounpaid - * - * @throws RestException 304 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 500 System error - */ - public function settounpaid($id) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->setUnpaid(DolibarrApiAccess::$user); - if ($result == 0) { - throw new RestException(304, 'Nothing done'); - } - if ($result < 0) { - throw new RestException(500, 'Error : '.$this->invoice->error); - } - - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - return $this->_cleanObjectDatas($this->invoice); - } - - /** - * Get discount from invoice - * - * @param int $id Id of invoice - * @return Object Object with cleaned properties - * - * @url GET {id}/discount - */ - public function getDiscount($id) - { - require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - - if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) { - throw new RestException(401); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $discountcheck = new DiscountAbsolute($this->db); - $result = $discountcheck->fetch(0, $this->invoice->id); - - if ($result == 0) { - throw new RestException(404, 'Discount not found'); - } - if ($result < 0) { - throw new RestException(500, $discountcheck->error); - } - - return parent::_cleanObjectDatas($discountcheck); - } - - /** - * Create a discount (credit available) for a credit note or a deposit. - * - * @param int $id Invoice ID - * @return Object Object with cleaned properties - * - * @url POST {id}/markAsCreditAvailable - * - * @throws RestException 304 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 500 System error - */ - public function markAsCreditAvailable($id) - { - require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - if ($this->invoice->paye) { - throw new RestException(500, 'Alreay paid'); - } - - $this->invoice->fetch($id); - $this->invoice->fetch_thirdparty(); - - // Check if there is already a discount (protection to avoid duplicate creation when resubmit post) - $discountcheck = new DiscountAbsolute($this->db); - $result = $discountcheck->fetch(0, $this->invoice->id); - - $canconvert = 0; - if ($this->invoice->type == Facture::TYPE_DEPOSIT && empty($discountcheck->id)) { - $canconvert = 1; // we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc) - } - if (($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_STANDARD) && $this->invoice->paye == 0 && empty($discountcheck->id)) { - $canconvert = 1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) - } - if ($canconvert) { - $this->db->begin(); - - $amount_ht = $amount_tva = $amount_ttc = array(); - $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array(); - - // Loop on each vat rate - $i = 0; - foreach ($this->invoice->lines as $line) { - if ($line->product_type < 9 && $line->total_ht != 0) { // Remove lines with product_type greater than or equal to 9 - // no need to create discount if amount is null - $amount_ht[$line->tva_tx] += $line->total_ht; - $amount_tva[$line->tva_tx] += $line->total_tva; - $amount_ttc[$line->tva_tx] += $line->total_ttc; - $multicurrency_amount_ht[$line->tva_tx] += $line->multicurrency_total_ht; - $multicurrency_amount_tva[$line->tva_tx] += $line->multicurrency_total_tva; - $multicurrency_amount_ttc[$line->tva_tx] += $line->multicurrency_total_ttc; - $i++; - } - } - - // Insert one discount by VAT rate category - $discount = new DiscountAbsolute($this->db); - if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { - $discount->description = '(CREDIT_NOTE)'; - } elseif ($this->invoice->type == Facture::TYPE_DEPOSIT) { - $discount->description = '(DEPOSIT)'; - } elseif ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION) { - $discount->description = '(EXCESS RECEIVED)'; - } else { - throw new RestException(500, 'Cant convert to reduc an Invoice of this type'); - } - - $discount->fk_soc = $this->invoice->socid; - $discount->fk_facture_source = $this->invoice->id; - - $error = 0; - - if ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION) { - // If we're on a standard invoice, we have to get excess received to create a discount in TTC without VAT - - // Total payments - $sql = 'SELECT SUM(pf.amount) as total_payments'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; - $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id'; - $sql .= ' WHERE pf.fk_facture = '.((int) $this->invoice->id); - $sql .= ' AND pf.fk_paiement = p.rowid'; - $sql .= ' AND p.entity IN ('.getEntity('invoice').')'; - $resql = $this->db->query($sql); - if (!$resql) { - dol_print_error($this->db); - } - - $res = $this->db->fetch_object($resql); - $total_payments = $res->total_payments; - - // Total credit note and deposit - $total_creditnote_and_deposit = 0; - $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; - $sql .= " re.description, re.fk_facture_source"; - $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re"; - $sql .= " WHERE fk_facture = ".((int) $this->invoice->id); - $resql = $this->db->query($sql); - if (!empty($resql)) { - while ($obj = $this->db->fetch_object($resql)) { - $total_creditnote_and_deposit += $obj->amount_ttc; - } - } else { - dol_print_error($this->db); - } - - $discount->amount_ht = $discount->amount_ttc = $total_payments + $total_creditnote_and_deposit - $this->invoice->total_ttc; - $discount->amount_tva = 0; - $discount->tva_tx = 0; - - $result = $discount->create(DolibarrApiAccess::$user); - if ($result < 0) { - $error++; - } - } - if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_DEPOSIT) { - foreach ($amount_ht as $tva_tx => $xxx) { - $discount->amount_ht = abs($amount_ht[$tva_tx]); - $discount->amount_tva = abs($amount_tva[$tva_tx]); - $discount->amount_ttc = abs($amount_ttc[$tva_tx]); - $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]); - $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]); - $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]); - $discount->tva_tx = abs($tva_tx); - - $result = $discount->create(DolibarrApiAccess::$user); - if ($result < 0) { - $error++; - break; - } - } - } - - if (empty($error)) { - if ($this->invoice->type != Facture::TYPE_DEPOSIT) { - // Classe facture - $result = $this->invoice->setPaid(DolibarrApiAccess::$user); - if ($result >= 0) { - $this->db->commit(); - } else { - $this->db->rollback(); - throw new RestException(500, 'Could not set paid'); - } - } else { - $this->db->commit(); - } - } else { - $this->db->rollback(); - throw new RestException(500, 'Discount creation error'); - } - } - - return $this->_cleanObjectDatas($this->invoice); - } - - /** - * Add a discount line into an invoice (as an invoice line) using an existing absolute discount - * - * Note that this consume the discount. - * - * @param int $id Id of invoice - * @param int $discountid Id of discount - * @return int - * - * @url POST {id}/usediscount/{discountid} - * - * @throws RestException 400 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 405 - */ - public function useDiscount($id, $discountid) - { - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - if (empty($id)) { - throw new RestException(400, 'Invoice ID is mandatory'); - } - if (empty($discountid)) { - throw new RestException(400, 'Discount ID is mandatory'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - $result = $this->invoice->insert_discount($discountid); - if ($result < 0) { - throw new RestException(405, $this->invoice->error); - } - - return $result; - } - - /** - * Add an available credit note discount to payments of an existing invoice. - * - * Note that this consume the credit note. - * - * @param int $id Id of invoice - * @param int $discountid Id of a discount coming from a credit note - * @return int - * - * @url POST {id}/usecreditnote/{discountid} - * - * @throws RestException 400 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 405 - */ - public function useCreditNote($id, $discountid) - { - require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - if (empty($id)) { - throw new RestException(400, 'Invoice ID is mandatory'); - } - if (empty($discountid)) { - throw new RestException(400, 'Credit ID is mandatory'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - $discount = new DiscountAbsolute($this->db); - $result = $discount->fetch($discountid); - if (!$result) { - throw new RestException(404, 'Credit not found'); - } - - $result = $discount->link_to_invoice(0, $id); - if ($result < 0) { - throw new RestException(405, $discount->error); - } - - return $result; - } - - /** - * Get list of payments of a given invoice - * - * @param int $id Id of invoice - * @return array - * - * @url GET {id}/payments - * - * @throws RestException 400 - * @throws RestException 401 - * @throws RestException 404 - * @throws RestException 405 - */ - public function getPayments($id) - { - if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) { - throw new RestException(401); - } - if (empty($id)) { - throw new RestException(400, 'Invoice ID is mandatory'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - $result = $this->invoice->getListOfPayments(); - if ($result < 0) { - throw new RestException(405, $this->invoice->error); - } - - return $result; - } - - - /** - * Add payment line to a specific invoice with the remain to pay as amount. - * - * @param int $id Id of invoice - * @param string $datepaye {@from body} Payment date {@type timestamp} - * @param int $paymentid {@from body} Payment mode Id {@min 1} - * @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no} - * @param int $accountid {@from body} Account Id {@min 1} - * @param string $num_payment {@from body} Payment number (optional) - * @param string $comment {@from body} Note private (optional) - * @param string $chqemetteur {@from body} Payment issuer (mandatory if paymentcode = 'CHQ') - * @param string $chqbank {@from body} Issuer bank name (optional) - * - * @url POST {id}/payments - * - * @return int Payment ID - * - * @throws RestException 400 - * @throws RestException 401 - * @throws RestException 404 - */ - public function addPayment($id, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '') - { - require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; - - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(403); - } - if (empty($id)) { - throw new RestException(400, 'Invoice ID is mandatory'); - } - - if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - if (isModEnabled("banque")) { - if (empty($accountid)) { - throw new RestException(400, 'Account ID is mandatory'); - } - } - - if (empty($paymentid)) { - throw new RestException(400, 'Payment ID or Payment Code is mandatory'); - } - - - $result = $this->invoice->fetch($id); - if (!$result) { - throw new RestException(404, 'Invoice not found'); - } - - // Calculate amount to pay - $totalpaid = $this->invoice->getSommePaiement(); - $totalcreditnotes = $this->invoice->getSumCreditNotesUsed(); - $totaldeposits = $this->invoice->getSumDepositsUsed(); - $resteapayer = price2num($this->invoice->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT'); - - $this->db->begin(); - - $amounts = array(); - $multicurrency_amounts = array(); - - // Clean parameters amount if payment is for a credit note - if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { - $resteapayer = price2num($resteapayer, 'MT'); - $amounts[$id] = price2num(-1 * $resteapayer, 'MT'); - // Multicurrency - $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT'); - $multicurrency_amounts[$id] = price2num(-1 * $newvalue, 'MT'); - } else { - $resteapayer = price2num($resteapayer, 'MT'); - $amounts[$id] = $resteapayer; - // Multicurrency - $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT'); - $multicurrency_amounts[$id] = $newvalue; - } - - // Creation of payment line - $paymentobj = new Paiement($this->db); - $paymentobj->datepaye = $datepaye; - $paymentobj->amounts = $amounts; // Array with all payments dispatching with invoice id - $paymentobj->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching - $paymentobj->paiementid = $paymentid; - $paymentobj->paiementcode = dol_getIdFromCode($this->db, $paymentid, 'c_paiement', 'id', 'code', 1); - $paymentobj->num_payment = $num_payment; - $paymentobj->note_private = $comment; - - $payment_id = $paymentobj->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices - if ($payment_id < 0) { - $this->db->rollback(); - throw new RestException(400, 'Payment error : '.$paymentobj->error); - } - - if (isModEnabled("banque")) { - $label = '(CustomerInvoicePayment)'; - - if ($paymentobj->paiementcode == 'CHQ' && empty($chqemetteur)) { - throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paymentobj->paiementcode); - } - if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { - $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note - } - $result = $paymentobj->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank); - if ($result < 0) { - $this->db->rollback(); - throw new RestException(400, 'Add payment to bank error : '.$paymentobj->error); - } - } - - $this->db->commit(); - - return $payment_id; - } - - /** - * Add a payment to pay partially or completely one or several invoices. - * Warning: Take care that all invoices are owned by the same customer. - * Example of value for parameter arrayofamounts: {"1": {"amount": "99.99", "multicurrency_amount": ""}, "2": {"amount": "", "multicurrency_amount": "10"}} - * - * @param array $arrayofamounts {@from body} Array with id of invoices with amount to pay for each invoice - * @param string $datepaye {@from body} Payment date {@type timestamp} - * @param int $paymentid {@from body} Payment mode Id {@min 1} - * @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no} - * @param int $accountid {@from body} Account Id {@min 1} - * @param string $num_payment {@from body} Payment number (optional) - * @param string $comment {@from body} Note private (optional) - * @param string $chqemetteur {@from body} Payment issuer (mandatory if paiementcode = 'CHQ') - * @param string $chqbank {@from body} Issuer bank name (optional) - * @param string $ref_ext {@from body} External reference (optional) - * @param bool $accepthigherpayment {@from body} Accept higher payments that it remains to be paid (optional) - * - * @url POST /paymentsdistributed - * - * @return int Payment ID - * - * @throws RestException 400 - * @throws RestException 401 - * @throws RestException 403 - * @throws RestException 404 - */ - public function addPaymentDistributed($arrayofamounts, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '', $ref_ext = '', $accepthigherpayment = false) - { - require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; - - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(403); - } - foreach ($arrayofamounts as $id => $amount) { - if (empty($id)) { - throw new RestException(400, 'Invoice ID is mandatory. Fill the invoice id and amount into arrayofamounts parameter. For example: {"1": "99.99", "2": "10"}'); - } - if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(403, 'Access not allowed on invoice ID '.$id.' for login '.DolibarrApiAccess::$user->login); - } - } - - if (isModEnabled("banque")) { - if (empty($accountid)) { - throw new RestException(400, 'Account ID is mandatory'); - } - } - if (empty($paymentid)) { - throw new RestException(400, 'Payment ID or Payment Code is mandatory'); - } - - $this->db->begin(); - - $amounts = array(); - $multicurrency_amounts = array(); - - // Loop on each invoice to pay - foreach ($arrayofamounts as $id => $amountarray) { - $result = $this->invoice->fetch($id); - if (!$result) { - $this->db->rollback(); - throw new RestException(404, 'Invoice ID '.$id.' not found'); - } - - if (($amountarray["amount"] == "remain" || $amountarray["amount"] > 0) && ($amountarray["multicurrency_amount"] == "remain" || $amountarray["multicurrency_amount"] > 0)) { - $this->db->rollback(); - throw new RestException(400, 'Payment in both currency '.$id.' ( amount: '.$amountarray["amount"].', multicurrency_amount: '.$amountarray["multicurrency_amount"].')'); - } - - $is_multicurrency = 0; - $total_ttc = $this->invoice->total_ttc; - - if ($amountarray["multicurrency_amount"] > 0 || $amountarray["multicurrency_amount"] == "remain") { - $is_multicurrency = 1; - $total_ttc = $this->invoice->multicurrency_total_ttc; - } - - // Calculate amount to pay - $totalpaid = $this->invoice->getSommePaiement($is_multicurrency); - $totalcreditnotes = $this->invoice->getSumCreditNotesUsed($is_multicurrency); - $totaldeposits = $this->invoice->getSumDepositsUsed($is_multicurrency); - $remainstopay = $amount = price2num($total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT'); - - if (!$is_multicurrency && $amountarray["amount"] != 'remain') { - $amount = price2num($amountarray["amount"], 'MT'); - } - - if ($is_multicurrency && $amountarray["multicurrency_amount"] != 'remain') { - $amount = price2num($amountarray["multicurrency_amount"], 'MT'); - } - - if ($amount > $remainstopay && !$accepthigherpayment) { - $this->db->rollback(); - throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$remainstopay.')'); - } - - if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { - $amount = price2num(-1 * $amount, 'MT'); - } - - if ($is_multicurrency) { - $amounts[$id] = null; - // Multicurrency - $multicurrency_amounts[$id] = $amount; - } else { - $amounts[$id] = $amount; - // Multicurrency - $multicurrency_amounts[$id] = null; - } - } - - // Creation of payment line - $paymentobj = new Paiement($this->db); - $paymentobj->datepaye = $datepaye; - $paymentobj->amounts = $amounts; // Array with all payments dispatching with invoice id - $paymentobj->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching - $paymentobj->paiementid = $paymentid; - $paymentobj->paiementcode = dol_getIdFromCode($this->db, $paymentid, 'c_paiement', 'id', 'code', 1); - $paymentobj->num_payment = $num_payment; - $paymentobj->note_private = $comment; - $paymentobj->ref_ext = $ref_ext; - $payment_id = $paymentobj->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices - if ($payment_id < 0) { - $this->db->rollback(); - throw new RestException(400, 'Payment error : '.$paymentobj->error); - } - if (isModEnabled("banque")) { - $label = '(CustomerInvoicePayment)'; - if ($paymentobj->paiementcode == 'CHQ' && empty($chqemetteur)) { - throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paymentobj->paiementcode); - } - if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { - $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note - } - $result = $paymentobj->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank); - if ($result < 0) { - $this->db->rollback(); - throw new RestException(400, 'Add payment to bank error : '.$paymentobj->error); - } - } - - $this->db->commit(); - - return $payment_id; - } - - /** - * Update a payment - * - * @param int $id Id of payment - * @param string $num_payment Payment number - * - * @url PUT payments/{id} - * - * @return array - * - * @throws RestException 400 Bad parameters - * @throws RestException 401 Not allowed - * @throws RestException 404 Not found - */ - public function putPayment($id, $num_payment = '') - { - require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; - - if (!DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); - } - if (empty($id)) { - throw new RestException(400, 'Payment ID is mandatory'); - } - - $paymentobj = new Paiement($this->db); - $result = $paymentobj->fetch($id); - - if (!$result) { - throw new RestException(404, 'Payment not found'); - } - - if (!empty($num_payment)) { - $result = $paymentobj->update_num($num_payment); - if ($result < 0) { - throw new RestException(500, 'Error when updating the payment num'); - } - } - - return [ - 'success' => [ - 'code' => 200, - 'message' => 'Payment updated' - ] - ]; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore - /** - * Clean sensible object datas - * - * @param Object $object Object to clean - * @return Object Object with cleaned properties - */ - protected function _cleanObjectDatas($object) - { - // phpcs:enable - $object = parent::_cleanObjectDatas($object); - - unset($object->note); - unset($object->address); - unset($object->barcode_type); - unset($object->barcode_type_code); - unset($object->barcode_type_label); - unset($object->barcode_type_coder); - unset($object->canvas); - - return $object; - } - - /** - * Validate fields before create or update object - * - * @param array|null $data Datas to validate - * @return array - * - * @throws RestException - */ - private function _validate($data) - { - $invoice = array(); - foreach (Invoices::$FIELDS as $field) { - if (!isset($data[$field])) { - throw new RestException(400, "$field field missing"); - } - $invoice[$field] = $data[$field]; - } - return $invoice; - } - - - /** - * Get properties of a template invoice object - * - * Return an array with invoice informations - * - * @param int $id ID of template invoice - * @param int $contact_list 0:Return array contains all properties, 1:Return array contains just id, -1: Do not return contacts/adddesses - * @return Object Object with cleaned properties - * - * @url GET templates/{id} - * - * @throws RestException - */ - public function getTemplateInvoice($id, $contact_list = 1) - { - return $this->_fetchTemplateInvoice($id, '', '', $contact_list); - } - - /** - * Get properties of an invoice object - * - * Return an array with invoice informations - * - * @param int $id ID of order - * @param string $ref Ref of object - * @param string $ref_ext External reference of object - * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id, -1: Do not return contacts/adddesses - * @return Object Object with cleaned properties - * - * @throws RestException - */ - private function _fetchTemplateInvoice($id, $ref = '', $ref_ext = '', $contact_list = 1) - { - if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) { - throw new RestException(401); - } - - $result = $this->template_invoice->fetch($id, $ref, $ref_ext); - if (!$result) { - throw new RestException(404, 'Template invoice not found'); - } - - if (!DolibarrApi::_checkAccessToResource('facturerec', $this->template_invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - // Add external contacts ids - if ($contact_list > -1) { - $tmparray = $this->template_invoice->liste_contact(-1, 'external', $contact_list); - if (is_array($tmparray)) { - $this->template_invoice->contacts_ids = $tmparray; - } - } - - $this->template_invoice->fetchObjectLinked(); - return $this->_cleanTemplateObjectDatas($this->template_invoice); - } - - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore - /** - * Clean sensible object datas - * - * @param Object $object Object to clean - * @return Object Object with cleaned properties - */ - protected function _cleanTemplateObjectDatas($object) - { - // phpcs:enable - $object = parent::_cleanObjectDatas($object); - - unset($object->note); - unset($object->address); - unset($object->barcode_type); - unset($object->barcode_type_code); - unset($object->barcode_type_label); - unset($object->barcode_type_coder); - unset($object->canvas); - - return $object; - } + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 403 + * @throws RestException 404 + */ + public function addPaymentDistributed($arrayofamounts, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement = '', $comment = '', $chqemetteur = '', $chqbank = '') + { + global $conf; + + require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; + + if (!DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(403); + } + foreach ($arrayofamounts as $id => $amount) { + if (empty($id)) { + throw new RestException(400, 'Invoice ID is mandatory. Fill the invoice id and amount into arrayofamounts parameter. For example: {"1": "99.99", "2": "10"}'); + } + if (!DolibarrApi::_checkAccessToResource('facture', $id)) { + throw new RestException(403, 'Access not allowed on invoice ID '.$id.' for login '.DolibarrApiAccess::$user->login); + } + } + + if (!empty($conf->banque->enabled)) { + if (empty($accountid)) { + throw new RestException(400, 'Account ID is mandatory'); + } + } + if (empty($paiementid)) { + throw new RestException(400, 'Paiement ID or Paiement Code is mandatory'); + } + + $this->db->begin(); + + $amounts = array(); + $multicurrency_amounts = array(); + + // Loop on each invoice to pay + foreach ($arrayofamounts as $id => $amount) + { + $result = $this->invoice->fetch($id); + if (!$result) { + $this->db->rollback(); + throw new RestException(404, 'Invoice ID '.$id.' not found'); + } + + // Calculate amount to pay + $totalpaye = $this->invoice->getSommePaiement(); + $totalcreditnotes = $this->invoice->getSumCreditNotesUsed(); + $totaldeposits = $this->invoice->getSumDepositsUsed(); + $resteapayer = price2num($this->invoice->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + if ($amount != 'remain') + { + if ($amount > $resteapayer) + { + $this->db->rollback(); + throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$resteapayer.')'); + } + $resteapayer = $amount; + } + // Clean parameters amount if payment is for a credit note + if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { + $resteapayer = price2num($resteapayer, 'MT'); + $amounts[$id] = -$resteapayer; + // Multicurrency + $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT'); + $multicurrency_amounts[$id] = -$newvalue; + } else { + $resteapayer = price2num($resteapayer, 'MT'); + $amounts[$id] = $resteapayer; + // Multicurrency + $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT'); + $multicurrency_amounts[$id] = $newvalue; + } + } + + // Creation of payment line + $paiement = new Paiement($this->db); + $paiement->datepaye = $datepaye; + $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id + $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching + $paiement->paiementid = $paiementid; + $paiement->paiementcode = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->num_paiement = $num_paiement; + $paiement->note = $comment; + $paiement_id = $paiement->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices + if ($paiement_id < 0) + { + $this->db->rollback(); + throw new RestException(400, 'Payment error : '.$paiement->error); + } + if (!empty($conf->banque->enabled)) { + $label = '(CustomerInvoicePayment)'; + if ($paiement->paiementcode == 'CHQ' && empty($chqemetteur)) { + throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paiement->paiementcode); + } + if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note + $result = $paiement->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank); + if ($result < 0) + { + $this->db->rollback(); + throw new RestException(400, 'Add payment to bank error : '.$paiement->error); + } + } + + $this->db->commit(); + + return $paiement_id; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + protected function _cleanObjectDatas($object) + { + // phpcs:enable + $object = parent::_cleanObjectDatas($object); + + unset($object->note); + unset($object->address); + unset($object->barcode_type); + unset($object->barcode_type_code); + unset($object->barcode_type_label); + unset($object->barcode_type_coder); + + return $object; + } + + /** + * Validate fields before create or update object + * + * @param array|null $data Datas to validate + * @return array + * + * @throws RestException + */ + private function _validate($data) + { + $invoice = array(); + foreach (Invoices::$FIELDS as $field) { + if (!isset($data[$field])) { + throw new RestException(400, "$field field missing"); + } + $invoice[$field] = $data[$field]; + } + return $invoice; + } --- /tmp/dsg/dolibarr/htdocs/compta/facture/class/github_19.0.3_facture-rec.class.php +++ /tmp/dsg/dolibarr/htdocs/compta/facture/class/client_facture-rec.class.php @@ -10 +9,0 @@ - * Copyright (C) 2023 Nick Fragoulis @@ -29 +28 @@ - * \brief File of class to manage recurring invoices + * \brief Fichier de la classe des factures recurentes @@ -43 +41,0 @@ - const TRIGGER_PREFIX = 'BILLREC'; @@ -55 +53 @@ - * @var string Name of subtable line + * @var int Name of subtable line @@ -60 +58 @@ - * @var string Field with ID of parent key if this field has a parent + * @var int Field with ID of parent key if this field has a parent @@ -79,16 +76,0 @@ - /** - * @var string The label of recurring invoice - */ - public $title; - - /** - * @var string The label of recurring invoice - * @deprecated Use $title instead - */ - public $titre; - - /** - * @var double - */ - public $multicurrency_subprice; - public $socid; @@ -97,8 +79,2 @@ - //public $remise; - //public $remise_absolue; - //public $remise_percent; - - /** - * @deprecated - * @see $total_ht - */ + public $remise; + public $tva; @@ -106,6 +82,2 @@ - - /** - * @deprecated - * @see $total_tva - */ - public $tva; + public $db_table; + public $propalid; @@ -118,2 +89,0 @@ - public $user_author; - @@ -125 +95 @@ - /** + /** @@ -135,4 +104,0 @@ - public $date_lim_reglement; - public $cond_reglement_code; // Code in llx_c_paiement - public $mode_reglement_code; // Code in llx_c_paiement - @@ -140,4 +105,0 @@ - - public $auto_validate; // 0 to create in draft, 1 to create and validate the new invoice - public $generate_pdf; // 1 to generate PDF on invoice generation (default) - @@ -163 +125 @@ - * 'arrayofkeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") @@ -177,4 +139,7 @@ - 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'isModEnabled("societe")', 'visible'=>-1, 'notnull'=>1, 'position'=>25), - 'subtype' =>array('type'=>'smallint(6)', 'label'=>'InvoiceSubtype', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>30), - 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>35), - 'total_tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>55, 'isameasure'=>1), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25), + 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>30), + //'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), + 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>40), + //'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>45), + //'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>50), + 'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>55, 'isameasure'=>1), @@ -183 +148 @@ - 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'Total', 'enabled'=>1, 'visible'=>-1, 'position'=>70, 'isameasure'=>1), + 'total' =>array('type'=>'double(24,8)', 'label'=>'Total', 'enabled'=>1, 'visible'=>-1, 'position'=>70, 'isameasure'=>1), @@ -186 +151 @@ - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Fk projet', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>85), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>85), @@ -190,2 +155,2 @@ - 'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>105), - 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>110), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>105), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110), @@ -192,0 +158,2 @@ + 'last_gen' =>array('type'=>'varchar(7)', 'label'=>'Last gen', 'enabled'=>1, 'visible'=>-1, 'position'=>120), + 'unit_frequency' =>array('type'=>'varchar(2)', 'label'=>'Unit frequency', 'enabled'=>1, 'visible'=>-1, 'position'=>125), @@ -198 +164,0 @@ - 'unit_frequency' =>array('type'=>'varchar(2)', 'label'=>'UnitFrequency', 'enabled'=>1, 'visible'=>-1, 'position'=>152), @@ -203 +169 @@ - 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>'isModEnabled("banque")', 'visible'=>-1, 'position'=>175), + 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>175), @@ -226 +192 @@ - public function __construct(DoliDB $db) + public function __construct($db) @@ -236,5 +202,3 @@ - * @param int $notrigger No trigger - * @param array $onlylines Only the lines of the array - * @return int Return integer <0 if KO, id of invoice created if OK - */ - public function create($user, $facid, $notrigger = 0, $onlylines = array()) + * @return int <0 if KO, id of invoice created if OK + */ + public function create($user, $facid) @@ -248 +212 @@ - $this->titre = trim(isset($this->titre) ? $this->titre : $this->title); // deprecated + $this->titre = trim($this->titre); // deprecated @@ -251,3 +215 @@ - if (empty($this->suspended)) { - $this->suspended = 0; - } + if (empty($this->suspended)) $this->suspended = 0; @@ -256 +218,2 @@ - if (empty($this->frequency)) { + if (empty($this->frequency)) + { @@ -259,0 +223 @@ + @@ -269 +233 @@ - // Load invoice template + // Charge facture modele @@ -272,2 +236,4 @@ - if ($result > 0) { - $this->socid = $facsrc->socid; + if ($result > 0) + { + // On positionne en mode brouillon la facture + $this->brouillon = 1; @@ -278 +243,0 @@ - $sql .= ", subtype"; @@ -282 +247 @@ - //$sql .= ", remise"; + $sql .= ", remise"; @@ -306,3 +271,2 @@ - $sql .= ", ".((int) $this->socid); - $sql .= ", ".($this->subtype ? "'".$this->db->escape($this->subtype)."'" : "null"); - $sql .= ", ".((int) $conf->entity); + $sql .= ", ".$facsrc->socid; + $sql .= ", ".$conf->entity; @@ -310,2 +274,2 @@ - $sql .= ", ".(!empty($facsrc->total_ttc) ? ((float) $facsrc->total_ttc) : '0'); - //$sql .= ", ".(!empty($facsrc->remise_absolue) ? ((float) $this->remise_absolue) : '0'); + $sql .= ", ".(!empty($facsrc->amount) ? $facsrc->amount : '0'); + $sql .= ", ".(!empty($facsrc->remise) ? $this->remise : '0'); @@ -314,8 +278,8 @@ - $sql .= ", ".(!empty($this->model_pdf) ? ("'".$this->db->escape($this->model_pdf)."'") : "NULL"); - $sql .= ", ".((int) $user->id); - $sql .= ", ".(!empty($this->fk_project) ? ((int) $this->fk_project) : "null"); - $sql .= ", ".(!empty($facsrc->fk_account) ? ((int) $facsrc->fk_account) : "null"); - $sql .= ", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) : "null"); - $sql .= ", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) : "null"); - $sql .= ", ".((int) $this->usenewprice); - $sql .= ", ".((int) $this->frequency); + $sql .= ", ".(!empty($this->modelpdf) ? ("'".$this->db->escape($this->modelpdf)."'") : "NULL"); + $sql .= ", '".$this->db->escape($user->id)."'"; + $sql .= ", ".(!empty($facsrc->fk_project) ? "'".$facsrc->fk_project."'" : "null"); + $sql .= ", ".(!empty($facsrc->fk_account) ? "'".$facsrc->fk_account."'" : "null"); + $sql .= ", ".($facsrc->cond_reglement_id > 0 ? $this->db->escape($facsrc->cond_reglement_id) : "null"); + $sql .= ", ".($facsrc->mode_reglement_id > 0 ? $this->db->escape($facsrc->mode_reglement_id) : "null"); + $sql .= ", ".$this->usenewprice; + $sql .= ", ".$this->frequency; @@ -325,5 +289,5 @@ - $sql .= ", ".((int) $this->nb_gen_done); - $sql .= ", ".((int) $this->nb_gen_max); - $sql .= ", ".((int) $this->auto_validate); - $sql .= ", ".((int) $this->generate_pdf); - $sql .= ", ".((int) $facsrc->fk_multicurrency); + $sql .= ", ".$this->db->escape($this->nb_gen_done); + $sql .= ", ".$this->db->escape($this->nb_gen_max); + $sql .= ", ".$this->db->escape($this->auto_validate); + $sql .= ", ".$this->db->escape($this->generate_pdf); + $sql .= ", ".$this->db->escape($facsrc->fk_multicurrency); @@ -331,2 +295,2 @@ - $sql .= ", ".((float) $facsrc->multicurrency_tx); - $sql .= ", ".((int) $this->suspended); + $sql .= ", ".$this->db->escape($facsrc->multicurrency_tx); + $sql .= ", ".$this->db->escape($this->suspended); @@ -335 +299,2 @@ - if ($this->db->query($sql)) { + if ($this->db->query($sql)) + { @@ -344,2 +308,0 @@ - $fk_parent_line = 0; - @@ -347,10 +310,2 @@ - for ($i = 0; $i < $num; $i++) { - if (!empty($onlylines) && !in_array($facsrc->lines[$i]->id, $onlylines)) { - continue; // Skip unselected lines - } - - // Reset fk_parent_line for no child products and special product - if (($facsrc->lines[$i]->product_type != 9 && empty($facsrc->lines[$i]->fk_parent_line)) || $facsrc->lines[$i]->product_type == 9) { - $fk_parent_line = 0; - } - + for ($i = 0; $i < $num; $i++) + { @@ -358,11 +313,6 @@ - if (!empty($facsrc->lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) { - $tva_tx .= ' ('.$facsrc->lines[$i]->vat_src_code.')'; - } - - $default_start_fill = getDolGlobalInt('INVOICEREC_SET_AUTOFILL_DATE_START'); - $default_end_fill = getDolGlobalInt('INVOICEREC_SET_AUTOFILL_DATE_END'); - - $result_insert = $this->addline( - $facsrc->lines[$i]->desc, - $facsrc->lines[$i]->subprice, - $facsrc->lines[$i]->qty, + if (!empty($facsrc->lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) $tva_tx .= ' ('.$facsrc->lines[$i]->vat_src_code.')'; + + $result_insert = $this->addline( + $facsrc->lines[$i]->desc, + $facsrc->lines[$i]->subprice, + $facsrc->lines[$i]->qty, @@ -370,5 +320,5 @@ - $facsrc->lines[$i]->localtax1_tx, - $facsrc->lines[$i]->localtax2_tx, - $facsrc->lines[$i]->fk_product, - $facsrc->lines[$i]->remise_percent, - 'HT', + $facsrc->lines[$i]->localtax1_tx, + $facsrc->lines[$i]->localtax2_tx, + $facsrc->lines[$i]->fk_product, + $facsrc->lines[$i]->remise_percent, + 'HT', @@ -376,6 +326,6 @@ - '', - 0, - $facsrc->lines[$i]->product_type, - $facsrc->lines[$i]->rang, - $facsrc->lines[$i]->special_code, - $facsrc->lines[$i]->label, + '', + 0, + $facsrc->lines[$i]->product_type, + $facsrc->lines[$i]->rang, + $facsrc->lines[$i]->special_code, + $facsrc->lines[$i]->label, @@ -383,66 +333,5 @@ - $facsrc->lines[$i]->multicurrency_subprice, - $default_start_fill, - $default_end_fill, - null, - $facsrc->lines[$i]->pa_ht, - $fk_parent_line - ); - - // Defined the new fk_parent_line - if ($result_insert > 0 && $facsrc->lines[$i]->product_type == 9) { - $fk_parent_line = $result_insert; - } - - if ($result_insert < 0) { - $error++; - } else { - $objectline = new FactureLigneRec($this->db); - - $result2 = $objectline->fetch($result_insert); - if ($result2 > 0) { - // Extrafields - if (method_exists($facsrc->lines[$i], 'fetch_optionals')) { - $facsrc->lines[$i]->fetch_optionals($facsrc->lines[$i]->id); - $objectline->array_options = $facsrc->lines[$i]->array_options; - } - - $result = $objectline->insertExtraFields(); - if ($result < 0) { - $error++; - } - } elseif ($result2 < 0) { - $this->errors[] = $objectline->error; - $error++; - } - } - } - - if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) { // To use new linkedObjectsIds instead of old linked_objects - $this->linked_objects = $this->linkedObjectsIds; // TODO Replace linked_objects with linkedObjectsIds - } - - // Add object linked - if (!$error && $this->id && !empty($this->linked_objects) && is_array($this->linked_objects)) { - foreach ($this->linked_objects as $origin => $tmp_origin_id) { - if (is_array($tmp_origin_id)) { // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...)) - foreach ($tmp_origin_id as $origin_id) { - $ret = $this->add_object_linked($origin, $origin_id); - if (!$ret) { - $this->error = $this->db->lasterror(); - $error++; - } - } - } else { // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1)) - $origin_id = $tmp_origin_id; - $ret = $this->add_object_linked($origin, $origin_id); - if (!$ret) { - $this->error = $this->db->lasterror(); - $error++; - } - } - } - } - - if (!$error) { - $result = $this->insertExtraFields(); - if ($result < 0) { + $facsrc->lines[$i]->multicurrency_subprice + ); + + if ($result_insert < 0) + { @@ -451,8 +340,16 @@ - } - - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('BILLREC_CREATE', $user); - if ($result < 0) { - $this->db->rollback(); - return -2; + else { + $objectline = new FactureLigneRec($this->db); + if ($objectline->fetch($result_insert)) + { + // Extrafields + if (method_exists($facsrc->lines[$i], 'fetch_optionals')) { + $facsrc->lines[$i]->fetch_optionals($facsrc->lines[$i]->rowid); + $objectline->array_options = $facsrc->lines[$i]->array_options; + } + + $result = $objectline->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } @@ -460,4 +357,39 @@ - // End call triggers - } - - if ($error) { + } + + if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) // To use new linkedObjectsIds instead of old linked_objects + { + $this->linked_objects = $this->linkedObjectsIds; // TODO Replace linked_objects with linkedObjectsIds + } + + // Add object linked + if (!$error && $this->id && is_array($this->linked_objects) && !empty($this->linked_objects)) + { + foreach ($this->linked_objects as $origin => $tmp_origin_id) + { + if (is_array($tmp_origin_id)) // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...)) + { + foreach ($tmp_origin_id as $origin_id) + { + $ret = $this->add_object_linked($origin, $origin_id); + if (!$ret) + { + $this->error = $this->db->lasterror(); + $error++; + } + } + } + else // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1)) + { + $origin_id = $tmp_origin_id; + $ret = $this->add_object_linked($origin, $origin_id); + if (!$ret) + { + $this->error = $this->db->lasterror(); + $error++; + } + } + } + } + + if ($error) + { @@ -465,2 +397,3 @@ - return -3; - } else { + } + else + { @@ -470,2 +403,4 @@ - } else { - $this->error = $this->db->lasterror(); + } + else + { + $this->error = $this->db->lasterror(); @@ -475 +410,3 @@ - } else { + } + else + { @@ -483 +420 @@ - * Update a line invoice_rec. + * Update a line to invoice_rec. @@ -487 +424 @@ - * @return int Return integer <0 if KO, Id of line if OK + * @return int <0 if KO, Id of line if OK @@ -491,44 +428,42 @@ - $error = 0; - - $sql = "UPDATE ".MAIN_DB_PREFIX."facture_rec SET"; - $sql .= " entity = ".((int) $this->entity).","; - $sql .= " titre = '".$this->db->escape($this->title)."',"; - $sql .= " suspended = ".((int) $this->suspended).","; - $sql .= " fk_soc = ".((int) $this->socid).","; - $sql .= " total_tva = ".((float) $this->total_tva).","; - $sql .= " localtax1 = ".((float) $this->total_localtax1).","; - $sql .= " localtax2 = ".((float) $this->total_localtax2).","; - $sql .= " total_ht = ".((float) $this->total_ht).","; - $sql .= " total_ttc = ".((float) $this->total_ttc); - // TODO Add missing fields - $sql .= " WHERE rowid = ".((int) $this->id); - - $this->db->begin(); - - dol_syslog(get_class($this)."::update", LOG_DEBUG); - - $resql = $this->db->query($sql); - if ($resql) { - if (!$error) { - $result = $this->insertExtraFields(); - if ($result < 0) { - $error++; - } - } - - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('BILLREC_MODIFY', $user); - if ($result < 0) { - $this->db->rollback(); - return -2; - } - // End call triggers - } - $this->db->commit(); - return 1; - } else { - $this->error = $this->db->lasterror(); - $this->db->rollback(); - return -1; - } + global $conf; + + $error = 0; + + $sql = "UPDATE ".MAIN_DB_PREFIX."facture_rec SET"; + $sql .= " fk_soc = ".$this->fk_soc; + // TODO Add missing fields + $sql .= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + if (!$error) + { + $result = $this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('BILLREC_UPDATE', $user); + if ($result < 0) + { + $this->db->rollback(); + return -2; + } + // End call triggers + } + $this->db->commit(); + return 1; + } + else + { + $this->error = $this->db->lasterror(); + $this->db->rollback(); + return -2; + } @@ -543,2 +477,0 @@ - * @param int $noextrafields 0=Default to load extrafields, 1=No extrafields - * @param int $nolines 0=Default to load lines, 1=No lines @@ -547 +480 @@ - public function fetch($rowid, $ref = '', $ref_ext = '', $noextrafields = 0, $nolines = 0) + public function fetch($rowid, $ref = '', $ref_ext = '') @@ -549,3 +482,2 @@ - dol_syslog('FactureRec::fetch', LOG_DEBUG); - - $sql = 'SELECT f.rowid, f.entity, f.titre as title, f.suspended, f.fk_soc, f.subtype, f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc'; + $sql = 'SELECT f.rowid, f.entity, f.titre as title, f.suspended, f.fk_soc, f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc'; + $sql .= ', f.remise_percent, f.remise_absolue, f.remise'; @@ -554 +486 @@ - $sql .= ', f.modelpdf as model_pdf'; + $sql .= ', f.modelpdf'; @@ -558,3 +490,3 @@ - $sql .= ', f.generate_pdf'; - $sql .= ", f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc"; - $sql .= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; + $sql .= ', f.generate_pdf'; + $sql .= ", f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc"; + $sql .= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; @@ -568,7 +500,2 @@ - if ($rowid) { - $sql .= ' AND f.rowid = '.((int) $rowid); - } elseif ($ref) { - $sql .= " AND f.titre = '".$this->db->escape($ref)."'"; - } else { - $sql .= ' AND f.rowid = 0'; - } + if ($rowid) $sql .= ' AND f.rowid='.$rowid; + elseif ($ref) $sql .= " AND f.titre='".$this->db->escape($ref)."'"; @@ -576,2 +503,3 @@ - if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'"; - */ + 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)."'"; + */ @@ -580,2 +508,4 @@ - if ($result) { - if ($this->db->num_rows($result)) { + if ($result) + { + if ($this->db->num_rows($result)) + { @@ -589 +519 @@ - $this->subtype = $obj->subtype; + $this->ref_client = $obj->ref_client; @@ -591,2 +521,8 @@ - $this->total_ht = $obj->total_ht; - $this->total_tva = $obj->total_tva; + $this->type = $obj->type; + $this->datep = $obj->dp; + $this->date = $obj->df; + $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; @@ -595,0 +532,3 @@ + $this->paye = $obj->paye; + $this->close_code = $obj->close_code; + $this->close_note = $obj->close_note; @@ -606,0 +546 @@ + $this->fk_facture_source = $obj->fk_facture_source; @@ -610,2 +550,3 @@ - $this->model_pdf = $obj->model_pdf; - //$this->special_code = $obj->special_code; + $this->modelpdf = $obj->modelpdf; + $this->rang = $obj->rang; + $this->special_code = $obj->special_code; @@ -630 +571,3 @@ - // Retrieve all extrafield + if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1; + + // Retreive all extrafield @@ -632,17 +575,11 @@ - if (empty($noextrafields)) { - $result = $this->fetch_optionals(); - if ($result < 0) { - $this->error = $this->db->lasterror(); - return -4; - } - } - - // Retreive lines - if (empty($nolines)) { - $result = $this->fetch_lines(); - if ($result < 0) { - $this->error = $this->db->lasterror(); - return -3; - } - } - + $this->fetch_optionals(); + + /* + * Lines + */ + $result = $this->fetch_lines(); + if ($result < 0) + { + $this->error = $this->db->lasterror(); + return -3; + } @@ -650,2 +587,4 @@ - } else { - $this->error = 'Bill with id '.$rowid.' or ref '.$ref.' not found'; + } + else + { + $this->error = 'Bill with id '.$rowid.' or ref '.$ref.' not found sql='.$sql; @@ -655 +594,3 @@ - } else { + } + else + { @@ -669 +610 @@ - return $this->fetch_lines(); + return $this->fetch_lines(); @@ -673 +614 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -678 +619 @@ - */ + */ @@ -681,2 +622,3 @@ - // phpcs:enable - + global $extrafields; + + // phpcs:enable @@ -685,3 +627,10 @@ - dol_syslog('FactureRec::fetch_lines', LOG_DEBUG); - - $sql = 'SELECT l.rowid, l.fk_facture, l.fk_product, l.fk_parent_line, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx, '; + // Retreive all extrafield for line + // fetch optionals attributes and labels + if (!is_object($extrafields)) + { + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields = new ExtraFields($this->db); + } + $extrafields->fetch_name_optionals_label($this->table_element_line, true); + + $sql = 'SELECT l.rowid, l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx, '; @@ -689 +638,3 @@ - $sql .= ' l.info_bits, l.date_start_fill, l.date_end_fill, l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price, l.buy_price_ht as pa_ht,'; + $sql .= ' l.info_bits, l.date_start_fill, l.date_end_fill, l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; + //$sql.= ' l.situation_percent, l.fk_prev_id,'; + //$sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice,'; @@ -690,0 +642 @@ + //$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,'; @@ -696 +648 @@ - $sql .= ' WHERE l.fk_facture = '.((int) $this->id); + $sql .= ' WHERE l.fk_facture = '.$this->id; @@ -698,0 +651 @@ + dol_syslog('FactureRec::fetch_lines', LOG_DEBUG); @@ -700 +653,2 @@ - if ($result) { + if ($result) + { @@ -703 +657,2 @@ - while ($i < $num) { + while ($i < $num) + { @@ -707,41 +662,35 @@ - $line->id = $objp->rowid; - $line->rowid = $objp->rowid; - $line->fk_facture = $objp->fk_facture; - $line->fk_parent_line = $objp->fk_parent_line; - $line->desc = $objp->description; // Description line - $line->description = $objp->description; // Description line - $line->ref = $objp->product_ref; // Ref product - $line->product_ref = $objp->product_ref; // Ref product - $line->libelle = $objp->product_label; // deprecated - $line->product_label = $objp->product_label; // Label product - $line->product_desc = $objp->product_desc; // Description product - $line->product_type = $objp->product_type; // Type of line - $line->fk_product_type = $objp->fk_product_type; // Type of product - $line->qty = $objp->qty; - $line->subprice = $objp->subprice; - - $line->label = $objp->custom_label; // @deprecated - - $line->vat_src_code = $objp->vat_src_code; - $line->tva_tx = $objp->tva_tx; - $line->localtax1_tx = $objp->localtax1_tx; - $line->localtax2_tx = $objp->localtax2_tx; - $line->localtax1_type = $objp->localtax1_type; - $line->localtax2_type = $objp->localtax2_type; - $line->remise_percent = $objp->remise_percent; - //$line->fk_remise_except = $objp->fk_remise_except; - $line->fk_product = $objp->fk_product; - $line->date_start_fill = $objp->date_start_fill; - $line->date_end_fill = $objp->date_end_fill; - $line->info_bits = $objp->info_bits; - $line->total_ht = $objp->total_ht; - $line->total_tva = $objp->total_tva; - $line->total_ttc = $objp->total_ttc; - - $line->fk_product_fournisseur_price = $objp->fk_product_fournisseur_price; - $line->fk_fournprice = $objp->fk_product_fournisseur_price; // For backward compatibility - - $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $objp->fk_product_fournisseur_price, $objp->pa_ht); - - $line->buyprice = $marginInfos[0]; - $line->pa_ht = $marginInfos[0]; // For backward compatibility + $line->id = $objp->rowid; + $line->rowid = $objp->rowid; + $line->desc = $objp->description; // Description line + $line->description = $objp->description; // Description line + $line->product_type = $objp->product_type; // Type of line + $line->ref = $objp->product_ref; // Ref product + $line->product_ref = $objp->product_ref; // Ref product + $line->libelle = $objp->product_label; // 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->label = $objp->custom_label; // @deprecated + + $line->vat_src_code = $objp->vat_src_code; + $line->tva_tx = $objp->tva_tx; + $line->localtax1_tx = $objp->localtax1_tx; + $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; + $line->remise_percent = $objp->remise_percent; + $line->fk_remise_except = $objp->fk_remise_except; + $line->fk_product = $objp->fk_product; + $line->date_start_fill = $objp->date_start_fill; + $line->date_end_fill = $objp->date_end_fill; + $line->info_bits = $objp->info_bits; + $line->total_ht = $objp->total_ht; + $line->total_tva = $objp->total_tva; + $line->total_ttc = $objp->total_ttc; + $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]; @@ -750,4 +699,4 @@ - $line->rang = $objp->rang; - $line->special_code = $objp->special_code; - $line->fk_unit = $objp->fk_unit; - $line->fk_contract_line = $objp->fk_contract_line; + $line->rang = $objp->rang; + $line->special_code = $objp->special_code; + $line->fk_unit = $objp->fk_unit; + $line->fk_contract_line = $objp->fk_contract_line; @@ -756,2 +705,2 @@ - $line->price = $objp->price; - $line->remise = $objp->remise; + $line->price = $objp->price; + $line->remise = $objp->remise; @@ -776 +725,3 @@ - } else { + } + else + { @@ -789 +740 @@ - * @return int Return integer <0 if KO, >0 if OK + * @return int <0 if KO, >0 if OK @@ -793,5 +744,5 @@ - $rowid = $this->id; - - dol_syslog(get_class($this)."::delete rowid=".((int) $rowid), LOG_DEBUG); - - $error = 0; + $rowid = $this->id; + + dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG); + + $error = 0; @@ -801,7 +752,8 @@ - $ef = $main."_extrafields"; - - $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM ".$main." WHERE fk_facture = ".((int) $rowid).")"; - $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet_rec WHERE fk_facture = ".((int) $rowid); - - if ($this->db->query($sqlef) && $this->db->query($sql)) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_rec WHERE rowid = ".((int) $rowid); + $ef = $main."_extrafields"; + $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_facture = $rowid)"; + dol_syslog($sqlef); + $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet_rec WHERE fk_facture = ".$rowid; + dol_syslog($sql); + if ($this->db->query($sqlef) && $this->db->query($sql)) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_rec WHERE rowid = ".$rowid; @@ -809 +761,2 @@ - if ($this->db->query($sql)) { + if ($this->db->query($sql)) + { @@ -812,3 +765 @@ - if ($res < 0) { - $error = -3; - } + if ($res < 0) $error = -3; @@ -816,5 +767,5 @@ - $res = $this->deleteExtraFields(); - if ($res < 0) { - $error = -4; - } - } else { + $res = $this->deleteExtraFields(); + if ($res < 0) $error = -4; + } + else + { @@ -824 +775,3 @@ - } else { + } + else + { @@ -828,14 +781,10 @@ - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('BILLREC_DELETE', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } - if (!$error) { - $this->db->commit(); - return 1; - } else { - $this->db->rollback(); - return $error; + + if (!$error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return $error; @@ -849,4 +798,4 @@ - * @param string $desc Description de la ligne - * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) - * @param double $qty Quantite - * @param double $txtva Taux de tva force, sinon -1 + * @param string $desc Description de la ligne + * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) + * @param double $qty Quantite + * @param double $txtva Taux de tva force, sinon -1 @@ -855,11 +804,11 @@ - * @param int $fk_product Product/Service ID predefined - * @param double $remise_percent Percentage discount of the line - * @param string $price_base_type HT or TTC - * @param int $info_bits VAT npr or not ? - * @param int $fk_remise_except Id remise - * @param double $pu_ttc Prix unitaire TTC (> 0 even for credit note) - * @param int $type Type of line (0=product, 1=service) - * @param int $rang Position of line - * @param int $special_code Special code - * @param string $label Label of the line - * @param string $fk_unit Unit + * @param int $fk_product Product/Service ID predefined + * @param double $remise_percent Percentage discount of the line + * @param string $price_base_type HT or TTC + * @param int $info_bits VAT npr or not ? + * @param int $fk_remise_except Id remise + * @param double $pu_ttc Prix unitaire TTC (> 0 even for credit note) + * @param int $type Type of line (0=product, 1=service) + * @param int $rang Position of line + * @param int $special_code Special code + * @param string $label Label of the line + * @param string $fk_unit Unit @@ -871,4 +820,3 @@ - * @param int $fk_parent_line Id of parent line - * @return int Return integer <0 if KO, Id of line if OK - */ - public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $price_base_type = 'HT', $info_bits = 0, $fk_remise_except = 0, $pu_ttc = 0, $type = 0, $rang = -1, $special_code = 0, $label = '', $fk_unit = null, $pu_ht_devise = 0, $date_start_fill = 0, $date_end_fill = 0, $fk_fournprice = null, $pa_ht = 0, $fk_parent_line = 0) + * @return int <0 if KO, Id of line if OK + */ + public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $price_base_type = 'HT', $info_bits = 0, $fk_remise_except = '', $pu_ttc = 0, $type = 0, $rang = -1, $special_code = 0, $label = '', $fk_unit = null, $pu_ht_devise = 0, $date_start_fill = 0, $date_end_fill = 0, $fk_fournprice = null, $pa_ht = 0) @@ -876 +824 @@ - global $mysoc; + global $mysoc; @@ -884,3 +832 @@ - if ($type < 0) { - return -1; - } + if ($type < 0) return -1; @@ -891 +836,0 @@ - $reg = array(); @@ -893 +838,2 @@ - if (preg_match('/\((.*)\)/', $txtva, $reg)) { + if (preg_match('/\((.*)\)/', $txtva, $reg)) + { @@ -898,150 +844,134 @@ - - // Clean parameters - $remise_percent = price2num($remise_percent); - if (empty($remise_percent)) { - $remise_percent = 0; - } - $qty = price2num($qty); - $pu_ht = price2num($pu_ht); - $pu_ttc = price2num($pu_ttc); - if (!preg_match('/\((.*)\)/', $txtva)) { - $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' - } - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); - if (empty($txtva)) { - $txtva = 0; - } - if (empty($txlocaltax1)) { - $txlocaltax1 = 0; - } - if (empty($txlocaltax2)) { - $txlocaltax2 = 0; - } - if (empty($info_bits)) { - $info_bits = 0; - } - - if ($price_base_type == 'HT') { - $pu = $pu_ht; - } else { - $pu = $pu_ttc; - } - - // Calcul du total TTC et de la TVA pour la ligne a partir de - // qty, pu, remise_percent et txtva - // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker - // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. - - $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1 = $tabprice[9]; - $total_localtax2 = $tabprice[10]; - $pu_ht = $tabprice[3]; - - // MultiCurrency - $multicurrency_total_ht = $tabprice[16]; - $multicurrency_total_tva = $tabprice[17]; - $multicurrency_total_ttc = $tabprice[18]; - $pu_ht_devise = $tabprice[19]; - - $product_type = $type; - if ($fk_product) { - $product = new Product($this->db); - $result = $product->fetch($fk_product); - $product_type = $product->type; - } - - if (empty($fk_parent_line) || $fk_parent_line < 0) { - $fk_parent_line = 0; - } - - // Rank to use - $ranktouse = $rang; - if ($ranktouse == -1) { - $rangmax = $this->line_max(0); - $ranktouse = $rangmax + 1; - } - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."facturedet_rec ("; - $sql .= "fk_facture"; - $sql .= ", fk_parent_line"; - $sql .= ", label"; - $sql .= ", description"; - $sql .= ", price"; - $sql .= ", qty"; - $sql .= ", tva_tx"; - $sql .= ", vat_src_code"; - $sql .= ", localtax1_tx"; - $sql .= ", localtax1_type"; - $sql .= ", localtax2_tx"; - $sql .= ", localtax2_type"; - $sql .= ", fk_product"; - $sql .= ", product_type"; - $sql .= ", remise_percent"; - $sql .= ", subprice"; - $sql .= ", remise"; - $sql .= ", total_ht"; - $sql .= ", total_tva"; - $sql .= ", total_localtax1"; - $sql .= ", total_localtax2"; - $sql .= ", total_ttc"; - $sql .= ", date_start_fill"; - $sql .= ", date_end_fill"; - $sql .= ", fk_product_fournisseur_price"; - $sql .= ", buy_price_ht"; - $sql .= ", info_bits"; - $sql .= ", rang"; - $sql .= ", special_code"; - $sql .= ", fk_unit"; - $sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc'; - $sql .= ") VALUES ("; - $sql .= " ".((int) $facid); - $sql .= ", ".($fk_parent_line > 0 ? ((int) $fk_parent_line) : "null"); - $sql .= ", ".(!empty($label) ? "'".$this->db->escape($label)."'" : "null"); - $sql .= ", '".$this->db->escape($desc)."'"; - $sql .= ", ".price2num($pu_ht); - $sql .= ", ".price2num($qty); - $sql .= ", ".price2num($txtva); - $sql .= ", '".$this->db->escape($vat_src_code)."'"; - $sql .= ", ".price2num($txlocaltax1); - $sql .= ", '".$this->db->escape(isset($localtaxes_type[0]) ? $localtaxes_type[0] : '')."'"; - $sql .= ", ".price2num($txlocaltax2); - $sql .= ", '".$this->db->escape(isset($localtaxes_type[2]) ? $localtaxes_type[2] : '')."'"; - $sql .= ", ".(!empty($fk_product) ? "'".$this->db->escape($fk_product)."'" : "null"); - $sql .= ", ".((int) $product_type); - $sql .= ", ".price2num($remise_percent); - $sql .= ", ".price2num($pu_ht); - $sql .= ", null"; - $sql .= ", ".price2num($total_ht); - $sql .= ", ".price2num($total_tva); - $sql .= ", ".price2num($total_localtax1); - $sql .= ", ".price2num($total_localtax2); - $sql .= ", ".price2num($total_ttc); - $sql .= ", ".(int) $date_start_fill; - $sql .= ", ".(int) $date_end_fill; - $sql .= ", ".($fk_fournprice > 0 ? $fk_fournprice : 'null'); - $sql .= ", ".($pa_ht ? price2num($pa_ht) : 0); - $sql .= ", ".((int) $info_bits); - $sql .= ", ".((int) $ranktouse); - $sql .= ", ".((int) $special_code); - $sql .= ", ".($fk_unit ? ((int) $fk_unit) : "null"); - $sql .= ", ".(int) $this->fk_multicurrency; - $sql .= ", '".$this->db->escape($this->multicurrency_code)."'"; - $sql .= ", ".price2num($pu_ht_devise, 'CU'); - $sql .= ", ".price2num($multicurrency_total_ht, 'CT'); - $sql .= ", ".price2num($multicurrency_total_tva, 'CT'); - $sql .= ", ".price2num($multicurrency_total_ttc, 'CT'); - $sql .= ")"; - - dol_syslog(get_class($this)."::addline", LOG_DEBUG); - if ($this->db->query($sql)) { - $lineId = $this->db->last_insert_id(MAIN_DB_PREFIX."facturedet_rec"); - $this->id = $facid; - $this->update_price(1); - return $lineId; - } else { - $this->error = $this->db->lasterror(); - return -1; + if ($this->brouillon) + { + // Clean parameters + $remise_percent = price2num($remise_percent); + if (empty($remise_percent)) $remise_percent = 0; + $qty = price2num($qty); + $pu_ht = price2num($pu_ht); + $pu_ttc = price2num($pu_ttc); + $txtva = price2num($txtva); + $txlocaltax1 = price2num($txlocaltax1); + $txlocaltax2 = price2num($txlocaltax2); + if (empty($txtva)) $txtva = 0; + if (empty($txlocaltax1)) $txlocaltax1 = 0; + if (empty($txlocaltax2)) $txlocaltax2 = 0; + if (empty($info_bits)) $info_bits = 0; + + if ($price_base_type == 'HT') + { + $pu = $pu_ht; + } + else + { + $pu = $pu_ttc; + } + + // Calcul du total TTC et de la TVA pour la ligne a partir de + // qty, pu, remise_percent et txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + + $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; + $pu_ht = $tabprice[3]; + + // MultiCurrency + $multicurrency_total_ht = $tabprice[16]; + $multicurrency_total_tva = $tabprice[17]; + $multicurrency_total_ttc = $tabprice[18]; + $pu_ht_devise = $tabprice[19]; + + $product_type = $type; + if ($fk_product) + { + $product = new Product($this->db); + $result = $product->fetch($fk_product); + $product_type = $product->type; + } + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."facturedet_rec ("; + $sql .= "fk_facture"; + $sql .= ", label"; + $sql .= ", description"; + $sql .= ", price"; + $sql .= ", qty"; + $sql .= ", tva_tx"; + $sql .= ", vat_src_code"; + $sql .= ", localtax1_tx"; + $sql .= ", localtax1_type"; + $sql .= ", localtax2_tx"; + $sql .= ", localtax2_type"; + $sql .= ", fk_product"; + $sql .= ", product_type"; + $sql .= ", remise_percent"; + $sql .= ", subprice"; + $sql .= ", remise"; + $sql .= ", total_ht"; + $sql .= ", total_tva"; + $sql .= ", total_localtax1"; + $sql .= ", total_localtax2"; + $sql .= ", total_ttc"; + $sql .= ", date_start_fill"; + $sql .= ", date_end_fill"; + $sql .= ", fk_product_fournisseur_price"; + $sql .= ", buy_price_ht"; + $sql .= ", info_bits"; + $sql .= ", rang"; + $sql .= ", special_code"; + $sql .= ", fk_unit"; + $sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc'; + $sql .= ") VALUES ("; + $sql .= "'".$facid."'"; + $sql .= ", ".(!empty($label) ? "'".$this->db->escape($label)."'" : "null"); + $sql .= ", '".$this->db->escape($desc)."'"; + $sql .= ", ".price2num($pu_ht); + $sql .= ", ".price2num($qty); + $sql .= ", ".price2num($txtva); + $sql .= ", '".$this->db->escape($vat_src_code)."'"; + $sql .= ", ".price2num($txlocaltax1); + $sql .= ", '".$this->db->escape($localtaxes_type[0])."'"; + $sql .= ", ".price2num($txlocaltax2); + $sql .= ", '".$this->db->escape($localtaxes_type[2])."'"; + $sql .= ", ".(!empty($fk_product) ? "'".$fk_product."'" : "null"); + $sql .= ", ".$product_type; + $sql .= ", ".price2num($remise_percent); + $sql .= ", ".price2num($pu_ht); + $sql .= ", null"; + $sql .= ", ".price2num($total_ht); + $sql .= ", ".price2num($total_tva); + $sql .= ", ".price2num($total_localtax1); + $sql .= ", ".price2num($total_localtax2); + $sql .= ", ".price2num($total_ttc); + $sql .= ", ".(int) $date_start_fill; + $sql .= ", ".(int) $date_end_fill; + $sql .= ", ".($fk_fournprice > 0 ? $fk_fournprice : 'null'); + $sql .= ", ".($pa_ht ? price2num($pa_ht) : 0); + $sql .= ", ".$info_bits; + $sql .= ", ".$rang; + $sql .= ", ".$special_code; + $sql .= ", ".($fk_unit ? "'".$this->db->escape($fk_unit)."'" : "null"); + $sql .= ", ".(int) $this->fk_multicurrency; + $sql .= ", '".$this->db->escape($this->multicurrency_code)."'"; + $sql .= ", ".price2num($pu_ht_devise); + $sql .= ", ".price2num($multicurrency_total_ht); + $sql .= ", ".price2num($multicurrency_total_tva); + $sql .= ", ".price2num($multicurrency_total_ttc); + $sql .= ")"; + + dol_syslog(get_class($this)."::addline", LOG_DEBUG); + if ($this->db->query($sql)) + { + $lineId = $this->db->last_insert_id(MAIN_DB_PREFIX."facturedet_rec"); + $this->id = $facid; + $this->update_price(); + return $lineId; + } + else + { + $this->error = $this->db->lasterror(); + return -1; + } @@ -1078,4 +1008,3 @@ - * @param int $fk_parent_line Id of parent line - * @return int Return integer <0 if KO, Id of line if OK - */ - public function updateline($rowid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $price_base_type = 'HT', $info_bits = 0, $fk_remise_except = 0, $pu_ttc = 0, $type = 0, $rang = -1, $special_code = 0, $label = '', $fk_unit = null, $pu_ht_devise = 0, $notrigger = 0, $date_start_fill = 0, $date_end_fill = 0, $fk_fournprice = null, $pa_ht = 0, $fk_parent_line = 0) + * @return int <0 if KO, Id of line if OK + */ + public function updateline($rowid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $price_base_type = 'HT', $info_bits = 0, $fk_remise_except = '', $pu_ttc = 0, $type = 0, $rang = -1, $special_code = 0, $label = '', $fk_unit = null, $pu_ht_devise = 0, $notrigger = 0, $date_start_fill = 0, $date_end_fill = 0, $fk_fournprice = null, $pa_ht = 0) @@ -1083,144 +1012,129 @@ - global $mysoc; - - $facid = $this->id; - - dol_syslog(get_class($this)."::updateline facid=".$facid." rowid=$rowid, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product, remise_percent=$remise_percent, 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, pu_ht_devise=$pu_ht_devise", LOG_DEBUG); - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - - // Clean parameters - if (empty($remise_percent)) { - $remise_percent = 0; - } - - // Check parameters - if ($type < 0) { - return -1; - } - - // Clean parameters - $remise_percent = price2num($remise_percent); - $qty = price2num($qty); - if (empty($info_bits)) { - $info_bits = 0; - } - $pu_ht = price2num($pu_ht); - $pu_ttc = price2num($pu_ttc); - $pu_ht_devise = price2num($pu_ht_devise); - if (!preg_match('/\((.*)\)/', $txtva)) { - $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' - } - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); - if (empty($txlocaltax1)) { - $txlocaltax1 = 0; - } - if (empty($txlocaltax2)) { - $txlocaltax2 = 0; - } - - if (empty($this->multicurrency_subprice)) { - $this->multicurrency_subprice = 0; - } - if (empty($this->multicurrency_total_ht)) { - $this->multicurrency_total_ht = 0; - } - if (empty($this->multicurrency_total_tva)) { - $this->multicurrency_total_tva = 0; - } - if (empty($this->multicurrency_total_ttc)) { - $this->multicurrency_total_ttc = 0; - } - - if ($price_base_type == 'HT') { - $pu = $pu_ht; - } else { - $pu = $pu_ttc; - } - - // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva - // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker - // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. - - $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); - - // Clean vat code - $vat_src_code = ''; - $reg = array(); - if (preg_match('/\((.*)\)/', $txtva, $reg)) { - $vat_src_code = $reg[1]; - $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. - } - - $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); - - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1 = $tabprice[9]; - $total_localtax2 = $tabprice[10]; - $pu_ht = $tabprice[3]; - $pu_tva = $tabprice[4]; - $pu_ttc = $tabprice[5]; - - // MultiCurrency - $multicurrency_total_ht = $tabprice[16]; - $multicurrency_total_tva = $tabprice[17]; - $multicurrency_total_ttc = $tabprice[18]; - $pu_ht_devise = $tabprice[19]; - - $product_type = $type; - if ($fk_product) { - $product = new Product($this->db); - $result = $product->fetch($fk_product); - $product_type = $product->type; - } - - if (empty($fk_parent_line) || $fk_parent_line < 0) { - $fk_parent_line = 0; - } - - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet_rec SET "; - $sql .= "fk_facture = ".((int) $facid); - $sql .= ", fk_parent_line = ".($fk_parent_line > 0 ? ((int) $fk_parent_line) : "null"); - $sql .= ", label=".(!empty($label) ? "'".$this->db->escape($label)."'" : "null"); - $sql .= ", description='".$this->db->escape($desc)."'"; - $sql .= ", price=".price2num($pu_ht); - $sql .= ", qty=".price2num($qty); - $sql .= ", tva_tx=".price2num($txtva); - $sql .= ", vat_src_code='".$this->db->escape($vat_src_code)."'"; - $sql .= ", localtax1_tx=".((float) $txlocaltax1); - $sql .= ", localtax1_type='".$this->db->escape($localtaxes_type[0])."'"; - $sql .= ", localtax2_tx=".((float) $txlocaltax2); - $sql .= ", localtax2_type='".$this->db->escape($localtaxes_type[2])."'"; - $sql .= ", fk_product=".(!empty($fk_product) ? "'".$this->db->escape($fk_product)."'" : "null"); - $sql .= ", product_type=".((int) $product_type); - $sql .= ", remise_percent='".price2num($remise_percent)."'"; - $sql .= ", subprice='".price2num($pu_ht)."'"; - $sql .= ", total_ht='".price2num($total_ht)."'"; - $sql .= ", total_tva='".price2num($total_tva)."'"; - $sql .= ", total_localtax1='".price2num($total_localtax1)."'"; - $sql .= ", total_localtax2='".price2num($total_localtax2)."'"; - $sql .= ", total_ttc='".price2num($total_ttc)."'"; - $sql .= ", date_start_fill=".((int) $date_start_fill); - $sql .= ", date_end_fill=".((int) $date_end_fill); - $sql .= ", fk_product_fournisseur_price=".($fk_fournprice > 0 ? $fk_fournprice : 'null'); - $sql .= ", buy_price_ht=".($pa_ht ? price2num($pa_ht) : 0); - $sql .= ", info_bits=".((int) $info_bits); - $sql .= ", rang=".((int) $rang); - $sql .= ", special_code=".((int) $special_code); - $sql .= ", fk_unit=".($fk_unit ? "'".$this->db->escape($fk_unit)."'" : "null"); - $sql .= ', multicurrency_subprice = '.price2num($pu_ht_devise); - $sql .= ', multicurrency_total_ht = '.price2num($multicurrency_total_ht); - $sql .= ', multicurrency_total_tva = '.price2num($multicurrency_total_tva); - $sql .= ', multicurrency_total_ttc = '.price2num($multicurrency_total_ttc); - $sql .= " WHERE rowid = ".((int) $rowid); - - dol_syslog(get_class($this)."::updateline", LOG_DEBUG); - if ($this->db->query($sql)) { - $this->id = $facid; - $this->update_price(1); - return 1; - } else { - $this->error = $this->db->lasterror(); - return -1; - } + global $mysoc; + + $facid = $this->id; + + dol_syslog(get_class($this)."::updateline facid=".$facid." rowid=$rowid, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product, remise_percent=$remise_percent, 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, pu_ht_devise=$pu_ht_devise", LOG_DEBUG); + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + // Clean parameters + if (empty($remise_percent)) $remise_percent = 0; + + // Check parameters + if ($type < 0) return -1; + + if ($this->brouillon) + { + // Clean parameters + $remise_percent = price2num($remise_percent); + $qty = price2num($qty); + if (empty($info_bits)) $info_bits = 0; + $pu_ht = price2num($pu_ht); + $pu_ttc = price2num($pu_ttc); + $pu_ht_devise = price2num($pu_ht_devise); + $txtva = price2num($txtva); + $txlocaltax1 = price2num($txlocaltax1); + $txlocaltax2 = price2num($txlocaltax2); + if (empty($txlocaltax1)) $txlocaltax1 = 0; + if (empty($txlocaltax2)) $txlocaltax2 = 0; + + if (empty($this->multicurrency_subprice)) $this->multicurrency_subprice = 0; + if (empty($this->multicurrency_total_ht)) $this->multicurrency_total_ht = 0; + if (empty($this->multicurrency_total_tva)) $this->multicurrency_total_tva = 0; + if (empty($this->multicurrency_total_ttc)) $this->multicurrency_total_ttc = 0; + + if ($price_base_type == 'HT') + { + $pu = $pu_ht; + } + else + { + $pu = $pu_ttc; + } + + // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + + $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); + + // Clean vat code + $vat_src_code = ''; + if (preg_match('/\((.*)\)/', $txtva, $reg)) + { + $vat_src_code = $reg[1]; + $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. + } + + $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); + + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; + $pu_ht = $tabprice[3]; + $pu_tva = $tabprice[4]; + $pu_ttc = $tabprice[5]; + + // MultiCurrency + $multicurrency_total_ht = $tabprice[16]; + $multicurrency_total_tva = $tabprice[17]; + $multicurrency_total_ttc = $tabprice[18]; + $pu_ht_devise = $tabprice[19]; + + $product_type = $type; + if ($fk_product) + { + $product = new Product($this->db); + $result = $product->fetch($fk_product); + $product_type = $product->type; + } + + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet_rec SET "; + $sql .= "fk_facture = '".$facid."'"; + $sql .= ", label=".(!empty($label) ? "'".$this->db->escape($label)."'" : "null"); + $sql .= ", description='".$this->db->escape($desc)."'"; + $sql .= ", price=".price2num($pu_ht); + $sql .= ", qty=".price2num($qty); + $sql .= ", tva_tx=".price2num($txtva); + $sql .= ", vat_src_code='".$this->db->escape($vat_src_code)."'"; + $sql .= ", localtax1_tx=".$txlocaltax1; + $sql .= ", localtax1_type='".$this->db->escape($localtaxes_type[0])."'"; + $sql .= ", localtax2_tx=".$txlocaltax2; + $sql .= ", localtax2_type='".$this->db->escape($localtaxes_type[2])."'"; + $sql .= ", fk_product=".(!empty($fk_product) ? "'".$fk_product."'" : "null"); + $sql .= ", product_type=".$product_type; + $sql .= ", remise_percent='".price2num($remise_percent)."'"; + $sql .= ", subprice='".price2num($pu_ht)."'"; + $sql .= ", total_ht='".price2num($total_ht)."'"; + $sql .= ", total_tva='".price2num($total_tva)."'"; + $sql .= ", total_localtax1='".price2num($total_localtax1)."'"; + $sql .= ", total_localtax2='".price2num($total_localtax2)."'"; + $sql .= ", total_ttc='".price2num($total_ttc)."'"; + $sql .= ", date_start_fill=".((int) $date_start_fill); + $sql .= ", date_end_fill=".((int) $date_end_fill); + $sql .= ", fk_product_fournisseur_price=".($fk_fournprice > 0 ? $fk_fournprice : 'null'); + $sql .= ", buy_price_ht=".($pa_ht ? price2num($pa_ht) : 0); + $sql .= ", info_bits=".$info_bits; + $sql .= ", rang=".$rang; + $sql .= ", special_code=".$special_code; + $sql .= ", fk_unit=".($fk_unit ? "'".$this->db->escape($fk_unit)."'" : "null"); + $sql .= ', multicurrency_subprice = '.$pu_ht_devise; + $sql .= ', multicurrency_total_ht = '.$multicurrency_total_ht; + $sql .= ', multicurrency_total_tva = '.$multicurrency_total_tva; + $sql .= ', multicurrency_total_ttc = '.$multicurrency_total_ttc; + $sql .= " WHERE rowid = ".$rowid; + + dol_syslog(get_class($this)."::updateline", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->id = $facid; + $this->update_price(); + return 1; + } + else + { + $this->error = $this->db->lasterror(); + return -1; + } + } @@ -1237,3 +1151 @@ - if (empty($this->date_when)) { - return false; - } + if (empty($this->date_when)) return false; @@ -1251,3 +1163 @@ - if ($this->nb_gen_max > 0 && ($this->nb_gen_done >= $this->nb_gen_max)) { - $ret = true; - } + if ($this->nb_gen_max > 0 && ($this->nb_gen_done >= $this->nb_gen_max)) $ret = true; @@ -1277 +1186,0 @@ - * @param int $notrigger Disable the trigger @@ -1280 +1189 @@ - public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidation = 0, $notrigger = 0) + public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidation = 0) @@ -1294,2 +1202,0 @@ - $this->output = null; - @@ -1300 +1207 @@ - $sql .= " AND (date_when IS NULL OR date_when <= '".$this->db->idate($today)."')"; + $sql .= " AND (date_when IS NULL OR date_when <= '".$db->idate($today)."')"; @@ -1304,4 +1211,3 @@ - if ($restrictioninvoiceid > 0) { - $sql .= ' AND rowid = '.((int) $restrictioninvoiceid); - } - $sql .= $this->db->order('entity', 'ASC'); + if ($restrictioninvoiceid > 0) + $sql .= ' AND rowid = '.$restrictioninvoiceid; + $sql .= $db->order('entity', 'ASC'); @@ -1315,2 +1221,3 @@ - $resql = $this->db->query($sql); - if ($resql) { + $resql = $db->query($sql); + if ($resql) + { @@ -1318,3 +1225,3 @@ - $num = $this->db->num_rows($resql); - - if ($num) { + $num = $db->num_rows($resql); + + if ($num) @@ -1322 +1229 @@ - } else { + else @@ -1324 +1230,0 @@ - } @@ -1328,4 +1234,5 @@ - while ($i < $num) { // Loop on each template invoice. If $num = 0, test is false at first pass. - $line = $this->db->fetch_object($resql); - - $this->db->begin(); + while ($i < $num) // Loop on each template invoice. If $num = 0, test is false at first pass. + { + $line = $db->fetch_object($resql); + + $db->begin(); @@ -1336 +1243 @@ - $facturerec = new FactureRec($this->db); + $facturerec = new FactureRec($db); @@ -1339 +1246,2 @@ - if ($facturerec->id > 0) { + if ($facturerec->id > 0) + { @@ -1345 +1253 @@ - $facture = new Facture($this->db); + $facture = new Facture($db); @@ -1350,3 +1258 @@ - $facture->subtype = $facturerec->subtype; - $facture->statut = self::STATUS_DRAFT; // deprecated - $facture->status = self::STATUS_DRAFT; + $facture->brouillon = 1; @@ -1355,5 +1260,0 @@ - if (!empty($facturerec->fk_multicurrency)) { - $facture->fk_multicurrency = $facturerec->fk_multicurrency; - $facture->multicurrency_code = $facturerec->multicurrency_code; - $facture->multicurrency_tx = $facturerec->multicurrency_tx; - } @@ -1362 +1263,2 @@ - if ($invoiceidgenerated <= 0) { + if ($invoiceidgenerated <= 0) + { @@ -1367,3 +1269,2 @@ - - - if (!$error && ($facturerec->auto_validate || $forcevalidation)) { + if (!$error && ($facturerec->auto_validate || $forcevalidation)) + { @@ -1371 +1272,2 @@ - if ($result <= 0) { + if ($result <= 0) + { @@ -1377 +1279,2 @@ - if (!$error && $facturerec->generate_pdf) { + if (!$error && $facturerec->generate_pdf) + { @@ -1380,2 +1283,3 @@ - $result = $facture->generateDocument($facturerec->model_pdf, $langs); - if ($result <= 0) { + $result = $facture->generateDocument($facturerec->modelpdf, $langs); + if ($result <= 0) + { @@ -1387,11 +1291,3 @@ - if (!$error && !$notrigger) { - // Call trigger - $result = $facturerec->call_trigger('BILLREC_CREATEBILL', $user); - if ($result < 0) { - $this->errors = $facturerec->errors; - $this->error = $facturerec->error; - $error++; - } - // End call triggers - } - } else { + } + else + { @@ -1404,2 +1300,3 @@ - if (!$error && $invoiceidgenerated >= 0) { - $this->db->commit("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref); + if (!$error && $invoiceidgenerated >= 0) + { + $db->commit("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref); @@ -1409,2 +1306,4 @@ - } else { - $this->db->rollback("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref); + } + else + { + $db->rollback("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref); @@ -1427,3 +1326,2 @@ - } else { - dol_print_error($this->db); - } + } + else dol_print_error($db); @@ -1444,2 +1342,2 @@ - * @param int $notooltip 1=Disable tooltip - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @param int $notooltip 1=Disable tooltip + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking @@ -1448 +1346 @@ - public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1) + public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = '', $save_lastsearch_value = -1) @@ -1450 +1348 @@ - global $langs, $hookmanager; + global $langs; @@ -1468,22 +1366,15 @@ - if (!empty($this->suspended)) { - $label .= ' ('.$langs->trans("Disabled").')'; - } - } - } - - $url = DOL_URL_ROOT.'/compta/facture/card-rec.php?facid='.$this->id; - - if ($short) { - return $url; - } - - if ($option != 'nolink') { - // Add param to save lastsearch_values or not - $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { - $add_save_lastsearch_values = 1; - } - if ($add_save_lastsearch_values) { - $url .= '&save_lastsearch_values=1'; - } - } + if (!empty($this->suspended)) $label .= ' ('.$langs->trans("Disabled").')'; + } + } + + $url = DOL_URL_ROOT.'/compta/facture/card-rec.php?facid='.$this->id; + + if ($short) return $url; + + if ($option != 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; + if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; + } @@ -1495,6 +1386,2 @@ - if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); - } - if ($withpicto != 2) { - $result .= $this->ref; - } + if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + if ($withpicto != 2) $result .= $this->ref; @@ -1502,9 +1389 @@ - global $action; - $hookmanager->initHooks(array($this->element . 'dao')); - $parameters = array('id'=>$this->id, 'getnomurl' => &$result); - $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) { - $result = $hookmanager->resPrint; - } else { - $result .= $hookmanager->resPrint; - } + @@ -1526 +1405 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -1539 +1418 @@ - // phpcs:enable + // phpcs:enable @@ -1543 +1422 @@ - $labelStatus = $langs->transnoentitiesnoconv('Active'); + $labelStatus = $langs->trans('Active'); @@ -1547,2 +1426,5 @@ - if ($mode == 0) { - if ($recur) { + if ($mode == 0) + { + $prefix = ''; + if ($recur) + { @@ -1550,5 +1432,8 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { - $labelStatus = $langs->transnoentitiesnoconv('Active'); - } - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { + $labelStatus = $langs->trans('Active'); + } + } + else + { @@ -1556,6 +1441,9 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { - $labelStatus = $langs->transnoentitiesnoconv("Draft"); - } - } - } elseif ($mode == 1) { + $labelStatus = $langs->trans('Disabled'); + } + else { + $labelStatus = $langs->trans("Draft"); + } + } + } + elseif ($mode == 1) + { @@ -1563 +1451,2 @@ - if ($recur) { + if ($recur) + { @@ -1565,5 +1454,8 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { - $labelStatus = $langs->transnoentitiesnoconv('Active'); - } - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { + $labelStatus = $langs->trans('Active'); + } + } + else + { @@ -1571,7 +1463,11 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { - $labelStatus = $langs->transnoentitiesnoconv("Draft"); - } - } - } elseif ($mode == 2) { - if ($recur) { + $labelStatus = $langs->trans('Disabled'); + } + else { + $labelStatus = $langs->trans("Draft"); + } + } + } + elseif ($mode == 2) + { + if ($recur) + { @@ -1580,2 +1476,3 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { @@ -1583,3 +1480,5 @@ - $labelStatus = $langs->transnoentitiesnoconv('Active'); - } - } else { + $labelStatus = $langs->trans('Active'); + } + } + else + { @@ -1588,2 +1487,3 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { @@ -1591,5 +1491,8 @@ - $labelStatus = $langs->transnoentitiesnoconv('Draft'); - } - } - } elseif ($mode == 3) { - if ($recur) { + $labelStatus = $langs->trans('Draft'); + } + } + } + elseif ($mode == 3) + { + if ($recur) + { @@ -1599,2 +1502,3 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { @@ -1602,3 +1506,5 @@ - $labelStatus = $langs->transnoentitiesnoconv('Active'); - } - } else { + $labelStatus = $langs->trans('Active'); + } + } + else + { @@ -1607,2 +1513,3 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { @@ -1610,4 +1517,6 @@ - $labelStatus = $langs->transnoentitiesnoconv('Draft'); - } - } - } elseif ($mode == 4) { + $labelStatus = $langs->trans('Draft'); + } + } + } + elseif ($mode == 4) + { @@ -1615 +1524,2 @@ - if ($recur) { + if ($recur) + { @@ -1618,2 +1528,3 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { @@ -1621,3 +1532,5 @@ - $labelStatus = $langs->transnoentitiesnoconv('Active'); - } - } else { + $labelStatus = $langs->trans('Active'); + } + } + else + { @@ -1626,2 +1539,3 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { @@ -1629,4 +1543,6 @@ - $labelStatus = $langs->transnoentitiesnoconv('Draft'); - } - } - } elseif ($mode == 5 || $mode == 6) { + $labelStatus = $langs->trans('Draft'); + } + } + } + elseif ($mode == 5 || $mode == 6) + { @@ -1634,4 +1550,3 @@ - if ($mode == 5) { - $prefix = 'Short'; - } - if ($recur) { + if ($mode == 5) $prefix = 'Short'; + if ($recur) + { @@ -1640,2 +1555,3 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { @@ -1643,3 +1559,5 @@ - $labelStatus = $langs->transnoentitiesnoconv('Active'); - } - } else { + $labelStatus = $langs->trans('Active'); + } + } + else + { @@ -1648,2 +1566,3 @@ - $labelStatus = $langs->transnoentitiesnoconv('Disabled'); - } else { + $labelStatus = $langs->trans('Disabled'); + } + else { @@ -1651,6 +1570,6 @@ - $labelStatus = $langs->transnoentitiesnoconv('Draft'); - } - } - } - - $labelStatusShort = $labelStatus; + $labelStatus = $langs->trans('Draft'); + } + } + } + + if (empty($labelStatusShort)) $labelStatusShort = $labelStatus; @@ -1659,44 +1577,0 @@ - } - - /** - * Return next reference of invoice not already used (or last reference) - * - * @param Societe $soc Thirdparty object - * @param string $mode 'next' for next value or 'last' for last value - * @return string free ref or last ref - */ - public function getNextNumRef($soc, $mode = 'next') - { - // Not used for recurring invoices - return ''; - } - - /** - * Load miscellaneous information for tab "Info" - * - * @param int $id Id of object to load - * @return void - */ - public function info($id) - { - $sql = 'SELECT c.rowid, datec, tms as datem,'; - $sql .= ' fk_user_author, fk_user_modif'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_rec as c'; - $sql .= ' WHERE c.rowid = '.((int) $id); - - $result = $this->db->query($sql); - if ($result) { - if ($this->db->num_rows($result)) { - $obj = $this->db->fetch_object($result); - - $this->id = $obj->rowid; - - $this->user_creation_id = $obj->fk_user_author; - $this->user_modification_id = $obj->fk_user_modif; - $this->date_creation = $this->db->jdate($obj->datec); - $this->date_modification = $this->db->jdate($obj->datem); - } - $this->db->free($result); - } else { - dol_print_error($this->db); - } @@ -1715 +1590 @@ - global $langs; + global $user, $langs, $conf; @@ -1721 +1596 @@ - // Load array of products prodids + // Load array of products prodids @@ -1728,2 +1602,0 @@ - $sql .= $this->db->plimit(100); - @@ -1731 +1604,2 @@ - if ($resql) { + if ($resql) + { @@ -1734 +1608,2 @@ - while ($i < $num_prods) { + while ($i < $num_prods) + { @@ -1744 +1618,0 @@ - $this->title = 'SPECIMEN'; @@ -1760 +1634,2 @@ - if (empty($option) || $option != 'nolines') { + if (empty($option) || $option != 'nolines') + { @@ -1764 +1639,2 @@ - while ($xnbp < $nbp) { + while ($xnbp < $nbp) + { @@ -1773 +1649,2 @@ - if ($xnbp == 1) { // Qty is negative (product line) + if ($xnbp == 1) // Qty is negative (product line) + { @@ -1780 +1657,3 @@ - } elseif ($xnbp == 2) { // UP is negative (free line) + } + elseif ($xnbp == 2) // UP is negative (free line) + { @@ -1786 +1665,3 @@ - } elseif ($xnbp == 3) { // Discount is 50% (product line) + } + elseif ($xnbp == 3) // Discount is 50% (product line) + { @@ -1793 +1674,3 @@ - } else { // (product line) + } + else // (product line) + { @@ -1836,6 +1719,6 @@ - * @param DoliDB $dbs Database handler, because function is static we name it $dbs not $db to avoid breaking coding test - * @param int $origin_id Old thirdparty id - * @param int $dest_id New thirdparty id - * @return bool - */ - public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id) + * @param DoliDB $db Database handler + * @param int $origin_id Old thirdparty id + * @param int $dest_id New thirdparty id + * @return bool + */ + public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id) @@ -1847 +1730 @@ - return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables); + return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); @@ -1851,275 +1734,196 @@ - * Function used to replace a product id with another one. - * - * @param DoliDB $dbs Database handler, because function is static we name it $dbs not $db to avoid breaking coding test - * @param int $origin_id Old product id - * @param int $dest_id New product id - * @return bool - */ - public static function replaceProduct(DoliDB $dbs, $origin_id, $dest_id) - { - $tables = array( - 'facturedet_rec' - ); - - return CommonObject::commonReplaceProduct($dbs, $origin_id, $dest_id, $tables); - } - - /** - * Update frequency and unit - * - * @param int $frequency value of frequency - * @param string $unit unit of frequency (d, m, y) - * @param int $notrigger Disable the trigger - * @return int Return integer <0 if KO, >0 if OK - */ - public function setFrequencyAndUnit($frequency, $unit, $notrigger = 0) - { - global $user; - - if (!$this->table_element) { - dol_syslog(get_class($this)."::setFrequencyAndUnit was called on objet with property table_element not defined", LOG_ERR); - return -1; - } - - if (!empty($frequency) && empty($unit)) { - dol_syslog(get_class($this)."::setFrequencyAndUnit was called on objet with params frequency defined but unit not defined", LOG_ERR); - return -2; - } - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET frequency = '.($frequency ? $this->db->escape($frequency) : 'null'); - if (!empty($unit)) { - $sql .= ', unit_frequency = \''.$this->db->escape($unit).'\''; - } - $sql .= " WHERE rowid = ".((int) $this->id); - - dol_syslog(get_class($this)."::setFrequencyAndUnit", LOG_DEBUG); - if ($this->db->query($sql)) { - $this->frequency = $frequency; - if (!empty($unit)) { - $this->unit_frequency = $unit; - } - - if (!$notrigger) { - // Call trigger - $result = $this->call_trigger('BILLREC_MODIFY', $user); - if ($result < 0) { - return $result; - } - // End call triggers - } - - return 1; - } else { - dol_print_error($this->db); - return -1; - } - } - - /** - * Update the next date of execution - * - * @param datetime $date date of execution - * @param int $increment_nb_gen_done 0 do nothing more, >0 increment nb_gen_done - * @param int $notrigger Disable the trigger - * @return int Return integer <0 if KO, >0 if OK - */ - public function setNextDate($date, $increment_nb_gen_done = 0, $notrigger = 0) - { - global $user; - - if (!$this->table_element) { - dol_syslog(get_class($this)."::setNextDate was called on objet with property table_element not defined", LOG_ERR); - return -1; - } - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= " SET date_when = ".($date ? "'".$this->db->idate($date)."'" : "null"); - if ($increment_nb_gen_done > 0) { - $sql .= ', nb_gen_done = nb_gen_done + 1'; - } - $sql .= " WHERE rowid = ".((int) $this->id); - - dol_syslog(get_class($this)."::setNextDate", LOG_DEBUG); - if ($this->db->query($sql)) { - $this->date_when = $date; - if ($increment_nb_gen_done > 0) { - $this->nb_gen_done++; - } - - if (!$notrigger) { - // Call trigger - $result = $this->call_trigger('BILLREC_MODIFY', $user); - if ($result < 0) { - return $result; - } - // End call triggers - } - return 1; - } else { - dol_print_error($this->db); - return -1; - } - } - - /** - * Update the maximum period - * - * @param int $nb number of maximum period - * @param int $notrigger Disable the trigger - * @return int Return integer <0 if KO, >0 if OK - */ - public function setMaxPeriod($nb, $notrigger = 0) - { - global $user; - - if (!$this->table_element) { - dol_syslog(get_class($this)."::setMaxPeriod was called on objet with property table_element not defined", LOG_ERR); - return -1; - } - - if (empty($nb)) { - $nb = 0; - } - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET nb_gen_max = '.((int) $nb); - $sql .= " WHERE rowid = ".((int) $this->id); - - dol_syslog(get_class($this)."::setMaxPeriod", LOG_DEBUG); - if ($this->db->query($sql)) { - $this->nb_gen_max = $nb; - - if (!$notrigger) { - // Call trigger - $result = $this->call_trigger('BILLREC_MODIFY', $user); - if ($result < 0) { - return $result; - } - // End call triggers - } - - return 1; - } else { - dol_print_error($this->db); - return -1; - } - } - - /** - * Update the auto validate flag of invoice - * - * @param int $validate 0 to create in draft, 1 to create and validate invoice - * @param int $notrigger Disable the trigger - * @return int Return integer <0 if KO, >0 if OK - */ - public function setAutoValidate($validate, $notrigger = 0) - { - global $user; - - if (!$this->table_element) { - dol_syslog(get_class($this)."::setAutoValidate was called on objet with property table_element not defined", LOG_ERR); - return -1; - } - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET auto_validate = '.((int) $validate); - $sql .= " WHERE rowid = ".((int) $this->id); - - dol_syslog(get_class($this)."::setAutoValidate", LOG_DEBUG); - if ($this->db->query($sql)) { - $this->auto_validate = $validate; - - if (!$notrigger) { - // Call trigger - $result = $this->call_trigger('BILLREC_MODIFY', $user); - if ($result < 0) { - return $result; - } - // End call triggers - } - - return 1; - } else { - dol_print_error($this->db); - return -1; - } - } - - /** - * Update the auto generate documents - * - * @param int $validate 0 no document, 1 to generate document - * @param int $notrigger Disable the trigger - * @return int Return integer <0 if KO, >0 if OK - */ - public function setGeneratePdf($validate, $notrigger = 0) - { - global $user; - - if (!$this->table_element) { - dol_syslog(get_class($this)."::setGeneratePdf was called on objet with property table_element not defined", LOG_ERR); - return -1; - } - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET generate_pdf = '.((int) $validate); - $sql .= " WHERE rowid = ".((int) $this->id); - - dol_syslog(get_class($this)."::setGeneratePdf", LOG_DEBUG); - if ($this->db->query($sql)) { - $this->generate_pdf = $validate; - - if (!$notrigger) { - // Call trigger - $result = $this->call_trigger('BILLREC_MODIFY', $user); - if ($result < 0) { - return $result; - } - // End call triggers - } - - return 1; - } else { - dol_print_error($this->db); - return -1; - } - } - - /** - * Update the model for documents - * - * @param string $model model of document generator - * @param int $notrigger Disable the trigger - * @return int Return integer <0 if KO, >0 if OK - */ - public function setModelPdf($model, $notrigger = 0) - { - global $user; - if (!$this->table_element) { - dol_syslog(get_class($this)."::setModelPdf was called on objet with property table_element not defined", LOG_ERR); - return -1; - } - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= " SET modelpdf = '".$this->db->escape($model)."'"; - $sql .= " WHERE rowid = ".((int) $this->id); - - dol_syslog(get_class($this)."::setModelPdf", LOG_DEBUG); - if ($this->db->query($sql)) { - $this->model_pdf = $model; - - if (!$notrigger) { - // Call trigger - $result = $this->call_trigger('BILLREC_MODIFY', $user); - if ($result < 0) { - return $result; - } - // End call triggers - } - - return 1; - } else { - dol_print_error($this->db); - return -1; - } - } + * Update frequency and unit + * + * @param int $frequency value of frequency + * @param string $unit unit of frequency (d, m, y) + * @return int <0 if KO, >0 if OK + */ + public function setFrequencyAndUnit($frequency, $unit) + { + if (!$this->table_element) { + dol_syslog(get_class($this)."::setFrequencyAndUnit was called on objet with property table_element not defined", LOG_ERR); + return -1; + } + + if (!empty($frequency) && empty($unit)) { + dol_syslog(get_class($this)."::setFrequencyAndUnit was called on objet with params frequency defined but unit not defined", LOG_ERR); + return -2; + } + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET frequency = '.($frequency ? $this->db->escape($frequency) : 'null'); + if (!empty($unit)) { + $sql .= ', unit_frequency = \''.$this->db->escape($unit).'\''; + } + $sql .= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::setFrequencyAndUnit", LOG_DEBUG); + if ($this->db->query($sql)) { + $this->frequency = $frequency; + if (!empty($unit)) $this->unit_frequency = $unit; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Update the next date of execution + * + * @param datetime $date date of execution + * @param int $increment_nb_gen_done 0 do nothing more, >0 increment nb_gen_done + * @return int <0 if KO, >0 if OK + */ + public function setNextDate($date, $increment_nb_gen_done = 0) + { + if (!$this->table_element) + { + dol_syslog(get_class($this)."::setNextDate was called on objet with property table_element not defined", LOG_ERR); + return -1; + } + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET date_when = ".($date ? "'".$this->db->idate($date)."'" : "null"); + if ($increment_nb_gen_done > 0) $sql .= ', nb_gen_done = nb_gen_done + 1'; + $sql .= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::setNextDate", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->date_when = $date; + if ($increment_nb_gen_done > 0) $this->nb_gen_done++; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Update the maximum period + * + * @param int $nb number of maximum period + * @return int <0 if KO, >0 if OK + */ + public function setMaxPeriod($nb) + { + if (!$this->table_element) + { + dol_syslog(get_class($this)."::setMaxPeriod was called on objet with property table_element not defined", LOG_ERR); + return -1; + } + + if (empty($nb)) $nb = 0; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET nb_gen_max = '.$nb; + $sql .= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::setMaxPeriod", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->nb_gen_max = $nb; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Update the auto validate flag of invoice + * + * @param int $validate 0 to create in draft, 1 to create and validate invoice + * @return int <0 if KO, >0 if OK + */ + public function setAutoValidate($validate) + { + if (!$this->table_element) + { + dol_syslog(get_class($this)."::setAutoValidate was called on objet with property table_element not defined", LOG_ERR); + return -1; + } + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET auto_validate = '.$validate; + $sql .= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::setAutoValidate", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->auto_validate = $validate; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Update the auto generate documents + * + * @param int $validate 0 no document, 1 to generate document + * @return int <0 if KO, >0 if OK + */ + public function setGeneratePdf($validate) + { + if (!$this->table_element) + { + dol_syslog(get_class($this)."::setGeneratePdf was called on objet with property table_element not defined", LOG_ERR); + return -1; + } + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET generate_pdf = '.$validate; + $sql .= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::setGeneratePdf", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->generate_pdf = $validate; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Update the model for documents + * + * @param string $model model of document generator + * @return int <0 if KO, >0 if OK + */ + public function setModelPdf($model) + { + if (!$this->table_element) + { + dol_syslog(get_class($this)."::setModelPdf was called on objet with property table_element not defined", LOG_ERR); + return -1; + } + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET modelpdf = "'.$model.'"'; + $sql .= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::setModelPdf", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->modelpdf = $model; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } @@ -2146,62 +1950,46 @@ - //! From llx_facturedet_rec - //! Id facture - public $fk_facture; - //! Id parent line - public $fk_parent_line; - - public $fk_product_fournisseur_price; - public $fk_fournprice; // For backward compatibility - - public $rang; - //public $situation_percent; // Not supported on recurring invoice line - - public $desc; - public $description; - - public $fk_product_type; // Use instead product_type - - public $fk_contract_line; - - - /** - * Delete line in database - * - * @param User $user Object user - * @param int $notrigger Disable triggers - * @return int Return integer <0 if KO, >0 if OK - */ - public function delete(User $user, $notrigger = 0) - { - $error = 0; - - $this->db->begin(); - - if (!$error) { - if (!$notrigger) { - // Call triggers - $result = $this->call_trigger('LINEBILLREC_DELETE', $user); - if ($result < 0) { - $error++; - } // Do also here what you must do to rollback action if trigger fail - // End call triggers - } - } - - if (!$error) { - $result = $this->deleteExtraFields(); - if ($result < 0) { - $error++; - } - } - - if (!$error) { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE rowid='.((int) $this->id); - - $res = $this->db->query($sql); - if (!$res) { - $error++; - $this->errors[] = $this->db->lasterror(); - } - } - - // Commit or rollback + public $date_start_fill; + public $date_end_fill; + + + /** + * Delete line in database + * + * @param User $user Object user + * @param int $notrigger Disable triggers + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + $error = 0; + + $this->db->begin(); + + if (!$error) { + if (!$notrigger) { + // Call triggers + $result = $this->call_trigger('LINEBILLREC_DELETE', $user); + if ($result < 0) { $error++; } // Do also here what you must do to rollback action if trigger fail + // End call triggers + } + } + + if (!$error) + { + $result = $this->deleteExtraFields(); + if ($result < 0) { + $error++; + } + } + + if (!$error) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE rowid='.$this->id; + + $res = $this->db->query($sql); + if ($res === false) { + $error++; + $this->errors[] = $this->db->lasterror(); + } + } + + // Commit or rollback @@ -2209,2 +1997,2 @@ - $this->db->rollback(); - return -1; + $this->db->rollback(); + return -1; @@ -2212,181 +2000,160 @@ - $this->db->commit(); - return 1; - } - } - - - /** - * Get line of template invoice - * - * @param int $rowid Id of invoice - * @return int 1 if OK, < 0 if KO - */ - public function fetch($rowid) - { - $sql = 'SELECT l.rowid, l.fk_facture, l.fk_parent_line, l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx,'; - $sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise, l.remise_percent, l.subprice,'; - $sql .= ' l.date_start_fill, l.date_end_fill, l.info_bits, l.total_ht, l.total_tva, l.total_ttc,'; - $sql .= ' l.rang, l.special_code,'; - $sql .= ' l.fk_unit, l.fk_contract_line,'; - $sql .= ' l.import_key, l.fk_multicurrency,'; - $sql .= ' l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,'; - $sql .= ' l.buy_price_ht, l.fk_product_fournisseur_price,'; - $sql .= ' l.fk_user_author, l.fk_user_modif,'; - $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_rec as l'; - $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; - $sql .= ' WHERE l.rowid = '.((int) $rowid); - $sql .= ' ORDER BY l.rang'; - - dol_syslog('FactureRec::fetch', LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) { - $objp = $this->db->fetch_object($result); - - $this->id = $objp->rowid; - $this->fk_facture = $objp->fk_facture; - $this->fk_parent_line = $objp->fk_parent_line; - $this->label = $objp->custom_label; // Label line - $this->desc = $objp->description; // Description line - $this->description = $objp->description; // Description line - $this->product_type = $objp->product_type; // Type of line - $this->ref = $objp->product_ref; // Ref product - $this->product_ref = $objp->product_ref; // Ref product - $this->libelle = $objp->product_label; // deprecated - $this->product_label = $objp->product_label; // Label product - $this->product_desc = $objp->product_desc; // Description product - $this->fk_product_type = $objp->fk_product_type; // Type of product - $this->qty = $objp->qty; - $this->price = $objp->price; - $this->subprice = $objp->subprice; - $this->vat_src_code = $objp->vat_src_code; - $this->tva_tx = $objp->tva_tx; - $this->localtax1_tx = $objp->localtax1_tx; - $this->localtax2_tx = $objp->localtax2_tx; - $this->localtax1_type = $objp->localtax1_type; - $this->localtax2_type = $objp->localtax2_type; - $this->remise_percent = $objp->remise_percent; - //$this->fk_remise_except = $objp->fk_remise_except; - $this->fk_product = $objp->fk_product; - $this->date_start_fill = $objp->date_start_fill; - $this->date_end_fill = $objp->date_end_fill; - $this->info_bits = $objp->info_bits; - $this->total_ht = $objp->total_ht; - $this->total_tva = $objp->total_tva; - $this->total_ttc = $objp->total_ttc; - - $this->rang = $objp->rang; - $this->special_code = $objp->special_code; - $this->fk_unit = $objp->fk_unit; - $this->fk_contract_line = $objp->fk_contract_line; - $this->import_key = $objp->import_key; - $this->fk_multicurrency = $objp->fk_multicurrency; - $this->multicurrency_code = $objp->multicurrency_code; - $this->multicurrency_subprice = $objp->multicurrency_subprice; - $this->multicurrency_total_ht = $objp->multicurrency_total_ht; - $this->multicurrency_total_tva = $objp->multicurrency_total_tva; - $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc; - - $this->buy_price_ht = $objp->buy_price_ht; - - $this->fk_product_fournisseur_price = $objp->fk_product_fournisseur_price; - $this->fk_user_author = $objp->fk_user_author; - $this->fk_user_modif = $objp->fk_user_modif; - - $this->db->free($result); - return 1; - } else { - $this->error = $this->db->lasterror(); - return -3; - } - } - - - /** - * Update a line to invoice_rec. - * - * @param User $user User - * @param int $notrigger No trigger - * @return int Return integer <0 if KO, Id of line if OK - */ - public function update(User $user, $notrigger = 0) - { - global $conf; - - $error = 0; - - // Clean parameters - if (empty($this->fk_parent_line)) { - $this->fk_parent_line = 0; - } - - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet_rec SET"; - $sql .= " fk_facture = ".((int) $this->fk_facture); - $sql .= ", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line : "null"); - $sql .= ", label=".(!empty($this->label) ? "'".$this->db->escape($this->label)."'" : "null"); - $sql .= ", description='".$this->db->escape($this->desc)."'"; - $sql .= ", price=".price2num($this->price); - $sql .= ", qty=".price2num($this->qty); - $sql .= ", tva_tx=".price2num($this->tva_tx); - $sql .= ", vat_src_code='".$this->db->escape($this->vat_src_code)."'"; - $sql .= ", localtax1_tx=".price2num($this->localtax1_tx); - $sql .= ", localtax1_type='".$this->db->escape($this->localtax1_type)."'"; - $sql .= ", localtax2_tx=".price2num($this->localtax2_tx); - $sql .= ", localtax2_type='".$this->db->escape($this->localtax2_type)."'"; - $sql .= ", fk_product=".($this->fk_product > 0 ? $this->fk_product : "null"); - $sql .= ", product_type=".((int) $this->product_type); - $sql .= ", remise_percent=".price2num($this->remise_percent); - $sql .= ", subprice=".price2num($this->subprice); - $sql .= ", info_bits=".price2num($this->info_bits); - $sql .= ", date_start_fill=".(int) $this->date_start_fill; - $sql .= ", date_end_fill=".(int) $this->date_end_fill; - if (empty($this->skip_update_total)) { - $sql .= ", total_ht=".price2num($this->total_ht); - $sql .= ", total_tva=".price2num($this->total_tva); - $sql .= ", total_localtax1=".price2num($this->total_localtax1); - $sql .= ", total_localtax2=".price2num($this->total_localtax2); - $sql .= ", total_ttc=".price2num($this->total_ttc); - } - $sql .= ", rang=".((int) $this->rang); - $sql .= ", special_code=".((int) $this->special_code); - $sql .= ", fk_unit=".($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'" : "null"); - $sql .= ", fk_contract_line=".($this->fk_contract_line ? $this->fk_contract_line : "null"); - $sql .= " WHERE rowid = ".((int) $this->id); - - $this->db->begin(); - - dol_syslog(get_class($this)."::updateline", LOG_DEBUG); - - $resql = $this->db->query($sql); - if ($resql) { - if (!$error) { - $result = $this->insertExtraFields(); - if ($result < 0) { - $error++; - } - } - - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('LINEBILLREC_MODIFY', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } - - if ($error) { - $this->db->rollback(); - return -2; - } else { - $this->db->commit(); - return 1; - } - } else { - $this->error = $this->db->lasterror(); - $this->db->rollback(); - return -2; - } - } + $this->db->commit(); + return 1; + } + } + + + /** + * Get line of template invoice + * + * @param int $rowid Id of invoice + * @return int 1 if OK, < 0 if KO + */ + public function fetch($rowid) + { + $sql = 'SELECT l.rowid, l.fk_facture ,l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx,'; + $sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise, l.remise_percent, l.subprice,'; + $sql .= ' l.date_start_fill, l.date_end_fill, l.info_bits, l.total_ht, l.total_tva, l.total_ttc,'; + $sql .= ' l.rang, l.special_code,'; + $sql .= ' l.fk_unit, l.fk_contract_line,'; + $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_rec as l'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; + $sql .= ' WHERE l.rowid = '.$rowid; + $sql .= ' ORDER BY l.rang'; + + dol_syslog('FactureRec::fetch', LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $objp = $this->db->fetch_object($result); + + $this->id = $objp->rowid; + $this->label = $objp->custom_label; // Label line + $this->desc = $objp->description; // Description line + $this->description = $objp->description; // Description line + $this->product_type = $objp->product_type; // Type of line + $this->ref = $objp->product_ref; // Ref product + $this->product_ref = $objp->product_ref; // Ref product + $this->libelle = $objp->product_label; // deprecated + $this->product_label = $objp->product_label; // Label product + $this->product_desc = $objp->product_desc; // Description product + $this->fk_product_type = $objp->fk_product_type; // Type of product + $this->qty = $objp->qty; + $this->price = $objp->price; + $this->subprice = $objp->subprice; + $this->fk_facture = $objp->fk_facture; + $this->vat_src_code = $objp->vat_src_code; + $this->tva_tx = $objp->tva_tx; + $this->localtax1_tx = $objp->localtax1_tx; + $this->localtax2_tx = $objp->localtax2_tx; + $this->localtax1_type = $objp->localtax1_type; + $this->localtax2_type = $objp->localtax2_type; + $this->remise_percent = $objp->remise_percent; + $this->fk_remise_except = $objp->fk_remise_except; + $this->fk_product = $objp->fk_product; + $this->date_start_fill = $objp->date_start_fill; + $this->date_end_fill = $objp->date_end_fill; + $this->info_bits = $objp->info_bits; + $this->total_ht = $objp->total_ht; + $this->total_tva = $objp->total_tva; + $this->total_ttc = $objp->total_ttc; + $this->code_ventilation = $objp->fk_code_ventilation; + $this->rang = $objp->rang; + $this->special_code = $objp->special_code; + $this->fk_unit = $objp->fk_unit; + $this->fk_contract_line = $objp->fk_contract_line; + + + $this->db->free($result); + return 1; + } + else + { + $this->error = $this->db->lasterror(); + return -3; + } + } + + + /** + * Update a line to invoice_rec. + * + * @param User $user User + * @param int $notrigger No trigger + * @return int <0 if KO, Id of line if OK + */ + public function update(User $user, $notrigger = 0) + { + global $conf; + + $error = 0; + + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet_rec SET"; + $sql .= " fk_facture = ".$this->fk_facture; + $sql .= ", label=".(!empty($this->label) ? "'".$this->db->escape($this->label)."'" : "null"); + $sql .= ", description='".$this->db->escape($this->desc)."'"; + $sql .= ", price=".price2num($this->price); + $sql .= ", qty=".price2num($this->qty); + $sql .= ", tva_tx=".price2num($this->tva_tx); + $sql .= ", vat_src_code='".$this->db->escape($this->vat_src_code)."'"; + $sql .= ", localtax1_tx=".price2num($this->localtax1_tx); + $sql .= ", localtax1_type='".$this->db->escape($this->localtax1_type)."'"; + $sql .= ", localtax2_tx=".price2num($this->localtax2_tx); + $sql .= ", localtax2_type='".$this->db->escape($this->localtax2_type)."'"; + $sql .= ", fk_product=".($this->fk_product > 0 ? $this->fk_product : "null"); + $sql .= ", product_type=".$this->product_type; + $sql .= ", remise_percent='".price2num($this->remise_percent)."'"; + $sql .= ", subprice='".price2num($this->subprice)."'"; + $sql .= ", info_bits='".price2num($this->info_bits)."'"; + $sql .= ", date_start_fill=".(int) $this->date_start_fill; + $sql .= ", date_end_fill=".(int) $this->date_end_fill; + if (empty($this->skip_update_total)) { + $sql .= ", total_ht=".price2num($this->total_ht); + $sql .= ", total_tva=".price2num($this->total_tva); + $sql .= ", total_localtax1=".price2num($this->total_localtax1); + $sql .= ", total_localtax2=".price2num($this->total_localtax2); + $sql .= ", total_ttc=".price2num($this->total_ttc); + } + $sql .= ", rang=".$this->rang; + $sql .= ", special_code=".$this->special_code; + $sql .= ", fk_unit=".($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'" : "null"); + $sql .= ", fk_contract_line=".($this->fk_contract_line ? $this->fk_contract_line : "null"); + $sql .= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::updateline", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + if (!$error) + { + $result = $this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('LINEBILLREC_UPDATE', $user); + if ($result < 0) + { + $this->db->rollback(); + return -2; + } + // End call triggers + } + $this->db->commit(); + return 1; + } + else + { + $this->error = $this->db->lasterror(); + $this->db->rollback(); + return -2; + } + } --- /tmp/dsg/dolibarr/htdocs/compta/facture/class/github_19.0.3_facture.class.php +++ /tmp/dsg/dolibarr/htdocs/compta/facture/class/client_facture.class.php @@ -2,21 +2,18 @@ -/* Copyright (C) 2002-2007 Rodolphe Quiedeville - * Copyright (C) 2004-2013 Laurent Destailleur - * Copyright (C) 2004 Sebastien Di Cintio - * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2014 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2007 Franky Van Liedekerke - * Copyright (C) 2010-2020 Juanjo Menent - * Copyright (C) 2012-2014 Christophe Battarel - * Copyright (C) 2012-2015 Marcos García - * Copyright (C) 2012 Cédric Salvador - * Copyright (C) 2012-2014 Raphaël Doursenaud - * Copyright (C) 2013 Cedric Gross - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2016-2022 Ferran Marcet - * Copyright (C) 2018-2022 Alexandre Spangaro - * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2022 Sylvain Legrand - * Copyright (C) 2023 Gauthier VERDOL - * Copyright (C) 2023 Nick Fragoulis +/* Copyright (C) 2002-2007 Rodolphe Quiedeville + * Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2005 Marc Barilley / Ocebo + * Copyright (C) 2005-2014 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2007 Franky Van Liedekerke + * Copyright (C) 2010-2016 Juanjo Menent + * Copyright (C) 2012-2014 Christophe Battarel + * Copyright (C) 2012-2015 Marcos García + * Copyright (C) 2012 Cédric Salvador + * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2013 Cedric Gross + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2016 Ferran Marcet + * Copyright (C) 2018 Alexandre Spangaro + * Copyright (C) 2018 Nicolas ZABOURI @@ -44 +41 @@ -require_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php'; +include_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php'; @@ -51,6 +48,2 @@ -if (isModEnabled('accounting')) { - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -} -if (isModEnabled('accounting')) { - require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; -} +if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; +if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; @@ -74 +67 @@ - * @var string Name of subtable line + * @var int Name of subtable line @@ -79 +72 @@ - * @var string Fieldname with ID of parent key if this field has a parent + * @var int Field with ID of parent key if this field has a parent @@ -84 +77 @@ - * @var string String with name of icon for myobject. + * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png @@ -95,5 +87,0 @@ - * @var int Does object support extrafields ? 0=No, 1=Yes - */ - public $isextrafieldmanaged = 1; - - /** @@ -109,0 +98,2 @@ + public $socid; + @@ -113 +103,15 @@ - * @var int ID + * @var int ID + */ + public $fk_user_author; + + /** + * @var int ID + */ + public $fk_user_valid; + + public $date; // Date invoice + public $datem; + public $ref_client; + + /** + * @var int Ref Int @@ -115,50 +119,14 @@ - * @see $fk_user_author - */ - public $user_author; - - /** - * @var int ID - */ - public $fk_user_author; - - /** - * @var int ID - * @deprecated - * @see $fk_user_valid - */ - public $user_valid; - - /** - * @var int ID - */ - public $fk_user_valid; - - /** - * @var int ID - */ - public $fk_user_modif; - - public $datem; - - /** - * @var int Date expected for delivery - */ - public $delivery_date; // Date expected of shipment (date of start of shipment, not the reception that occurs some days after) - - /** - * @var string customer ref - * @deprecated - * @see $ref_customer - */ - public $ref_client; - - /** - * @var string customer ref - */ - public $ref_customer; - - public $total_ht; - public $total_tva; - public $total_localtax1; - public $total_localtax2; - public $total_ttc; + */ + public $ref_int; // deprecated + + //Check constants for types + public $type = self::TYPE_STANDARD; + + //var $amount; + public $remise_absolue; + public $remise_percent; + public $total_ht = 0; + public $total_tva = 0; + public $total_localtax1 = 0; + public $total_localtax2 = 0; + public $total_ttc = 0; @@ -167,5 +135,6 @@ - public $resteapayer; - - /** - * 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code) - */ + //! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon + //! Fermeture alors que aucun paiement: replaced (si remplace), abandon + public $close_code; + //! Commentaire si mis a paye sans paiement complet + public $close_note; + //! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code) @@ -173 +141,0 @@ - @@ -183,4 +151,7 @@ - - /** - * @var int ID Field to store bank id to use when payment mode is withdraw - */ + public $date_lim_reglement; + public $cond_reglement_code; // Code in llx_c_paiement + public $mode_reglement_code; // Code in llx_c_paiement + + /** + * @var int ID Field to store bank id to use when payment mode is withdraw + */ @@ -189,0 +161,5 @@ + * @deprecated + */ + public $products = array(); + + /** @@ -194,3 +169,0 @@ - /** - * @var FactureLigne - */ @@ -199,4 +172,2 @@ - - /** - * @var int ID facture rec - */ + public $specimen; + @@ -205,2 +176,11 @@ - public $date_pointoftax; - + // Multicurrency + /** + * @var int ID + */ + public $fk_multicurrency; + + public $multicurrency_code; + public $multicurrency_tx; + public $multicurrency_total_ht; + public $multicurrency_total_tva; + public $multicurrency_total_ttc; @@ -233,3 +212,0 @@ - /** - * @var Facture object oldcopy - */ @@ -252,17 +228,0 @@ - - /** - * @var int availabilty ID - */ - public $availability_id; - - public $date_closing; - - /** - * @var int - */ - public $source; - - /** - * @var int - */ - public $remise_percent; @@ -289 +249 @@ - * 'arrayofkeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") @@ -300,2 +260,2 @@ - 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>1), - 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>5), + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>15), @@ -303,4 +263,4 @@ - 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>10), - 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>12), - 'type' =>array('type'=>'smallint(6)', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15), - 'subtype' =>array('type'=>'smallint(6)', 'label'=>'InvoiceSubtype', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15), + 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>25), + 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'Ref int', 'enabled'=>1, 'visible'=>0, 'position'=>30), // deprecated + 'type' =>array('type'=>'smallint(6)', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), + 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'Ref client', 'enabled'=>1, 'visible'=>-1, 'position'=>40), @@ -309,4 +269,5 @@ - 'datef' =>array('type'=>'date', 'label'=>'DateInvoice', 'enabled'=>1, 'visible'=>1, 'position'=>20), - 'date_valid' =>array('type'=>'date', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>22), - 'date_lim_reglement' =>array('type'=>'date', 'label'=>'DateDue', 'enabled'=>1, 'visible'=>1, 'position'=>25), - 'date_closing' =>array('type'=>'datetime', 'label'=>'Date closing', 'enabled'=>1, 'visible'=>-1, 'position'=>30), + 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), + 'datef' =>array('type'=>'date', 'label'=>'DateInvoice', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'date_valid' =>array('type'=>'date', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>65), + 'date_closing' =>array('type'=>'datetime', 'label'=>'Date closing', 'enabled'=>1, 'visible'=>-1, 'position'=>70), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>75), @@ -315,2 +276,2 @@ - //'remise_percent' =>array('type'=>'double', 'label'=>'RelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>90), - //'remise_absolue' =>array('type'=>'double', 'label'=>'CustomerRelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>91), + 'remise_percent' =>array('type'=>'double', 'label'=>'RelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'remise_absolue' =>array('type'=>'double', 'label'=>'CustomerRelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>95), @@ -318,8 +279,12 @@ - 'close_code' =>array('type'=>'varchar(16)', 'label'=>'EarlyClosingReason', 'enabled'=>1, 'visible'=>-1, 'position'=>92), - 'close_note' =>array('type'=>'varchar(128)', 'label'=>'EarlyClosingComment', 'enabled'=>1, 'visible'=>-1, 'position'=>93), - 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'AmountHT', 'enabled'=>1, 'visible'=>1, 'position'=>95, 'isameasure'=>1), - 'total_tva' =>array('type'=>'double(24,8)', 'label'=>'AmountVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>100, 'isameasure'=>1), - 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'LT1', 'enabled'=>1, 'visible'=>-1, 'position'=>110, 'isameasure'=>1), - 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LT2', 'enabled'=>1, 'visible'=>-1, 'position'=>120, 'isameasure'=>1), - 'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>115, 'isameasure'=>1), - 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'AmountTTC', 'enabled'=>1, 'visible'=>1, 'position'=>130, 'isameasure'=>1), + 'close_code' =>array('type'=>'varchar(16)', 'label'=>'EarlyClosingReason', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'close_note' =>array('type'=>'varchar(128)', 'label'=>'EarlyClosingComment', 'enabled'=>1, 'visible'=>-1, 'position'=>110), + 'tva' =>array('type'=>'double(24,8)', 'label'=>'TotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>115, 'isameasure'=>1), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'LT1', 'enabled'=>1, 'visible'=>-1, 'position'=>120, 'isameasure'=>1), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LT2', 'enabled'=>1, 'visible'=>-1, 'position'=>125, 'isameasure'=>1), + 'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>130, 'isameasure'=>1), + 'total' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1), + 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>150), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>155), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>160), + 'fk_user_closing' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>165), @@ -327 +292 @@ - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>175), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>175), @@ -332,2 +297,3 @@ - 'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>205), - 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>210), + 'date_lim_reglement' =>array('type'=>'date', 'label'=>'DateDue', 'enabled'=>1, 'visible'=>-1, 'position'=>200), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>205), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>210), @@ -345,6 +311,6 @@ - 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyID', 'enabled'=>'isModEnabled("multicurrency")', 'visible'=>-1, 'position'=>275), - 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Currency', 'enabled'=>'isModEnabled("multicurrency")', 'visible'=>-1, 'position'=>280), - 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'CurrencyRate', 'enabled'=>'isModEnabled("multicurrency")', 'visible'=>-1, 'position'=>285, 'isameasure'=>1), - 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountHT', 'enabled'=>'isModEnabled("multicurrency")', 'visible'=>-1, 'position'=>290, 'isameasure'=>1), - 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountVAT', 'enabled'=>'isModEnabled("multicurrency")', 'visible'=>-1, 'position'=>291, 'isameasure'=>1), - 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountTTC', 'enabled'=>'isModEnabled("multicurrency")', 'visible'=>-1, 'position'=>292, 'isameasure'=>1), + 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyID', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>275), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCurrency', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>280), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>285, 'isameasure'=>1), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountHT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>290, 'isameasure'=>1), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountVAT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>295, 'isameasure'=>1), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountTTC', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>300, 'isameasure'=>1), @@ -353,8 +319,3 @@ - 'module_source' =>array('type'=>'varchar(32)', 'label'=>'POSModule', 'enabled'=>"(isModEnabled('cashdesk') || isModEnabled('takepos') || getDolGlobalInt('INVOICE_SHOW_POS'))", 'visible'=>-1, 'position'=>315), - 'pos_source' =>array('type'=>'varchar(32)', 'label'=>'POSTerminal', 'enabled'=>"(isModEnabled('cashdesk') || isModEnabled('takepos') || getDolGlobalInt('INVOICE_SHOW_POS'))", 'visible'=>-1, 'position'=>320), - 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>500), - 'tms' =>array('type'=>'timestamp', 'label'=>'DateModificationShort', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>502), - 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>506), - 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'notnull'=>-1, 'position'=>508), - 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>510), - 'fk_user_closing' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>512), + 'module_source' =>array('type'=>'varchar(32)', 'label'=>'POSModule', 'enabled'=>1, 'visible'=>-1, 'position'=>315), + 'pos_source' =>array('type'=>'varchar(32)', 'label'=>'POSTerminal', 'enabled'=>1, 'visible'=>-1, 'position'=>320), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Paid', 3=>'Abandonned')), @@ -362 +322,0 @@ - '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')), @@ -366,24 +326,24 @@ - /** - * Standard invoice - */ - const TYPE_STANDARD = 0; - - /** - * Replacement invoice - */ - const TYPE_REPLACEMENT = 1; - - /** - * Credit note invoice - */ - const TYPE_CREDIT_NOTE = 2; - - /** - * Deposit invoice - */ - const TYPE_DEPOSIT = 3; - - /** - * Proforma invoice (should not be used. a proforma is an order) - */ - const TYPE_PROFORMA = 4; + /** + * Standard invoice + */ + const TYPE_STANDARD = 0; + + /** + * Replacement invoice + */ + const TYPE_REPLACEMENT = 1; + + /** + * Credit note invoice + */ + const TYPE_CREDIT_NOTE = 2; + + /** + * Deposit invoice + */ + const TYPE_DEPOSIT = 3; + + /** + * Proforma invoice (should not be used. a proforma is an order) + */ + const TYPE_PROFORMA = 4; @@ -425,4 +385 @@ - const CLOSECODE_BADDEBT = 'badcustomer'; // Abandonned remain - bad customer - const CLOSECODE_BANKCHARGE = 'bankcharge'; // Abandonned remain - bank charge - const CLOSECODE_OTHER = 'other'; // Abandonned remain - other - + const CLOSECODE_BADDEBT = 'badcustomer'; // Abandonned - bad @@ -438 +395 @@ - public function __construct(DoliDB $db) + public function __construct($db) @@ -451,3 +408,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function create(User $user, $notrigger = 0, $forceduedate = 0) + * @return int <0 if KO, >0 if OK + */ + public function create(User $user, $notrigger = 0, $forceduedate = 0) @@ -459,4 +416 @@ - if (empty($this->type)) { - $this->type = self::TYPE_STANDARD; - } - + if (empty($this->type)) $this->type = self::TYPE_STANDARD; @@ -464 +417,0 @@ - @@ -468,22 +421,9 @@ - if (!$this->cond_reglement_id) { - $this->cond_reglement_id = 0; - } - if (!$this->mode_reglement_id) { - $this->mode_reglement_id = 0; - } - $this->status = self::STATUS_DRAFT; - $this->statut = self::STATUS_DRAFT; // deprecated - - if (!empty($this->multicurrency_code)) { - // Multicurrency (test on $this->multicurrency_tx because we should take the default rate of multicurrency_code only if not using original rate) - if (empty($this->multicurrency_tx)) { - // If original rate is not set, we take a default value from date - list($this->fk_multicurrency, $this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $this->date); - } else { - // original rate multicurrency_tx and multicurrency_code are set, we use them - $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code); - } - } else { - $this->fk_multicurrency = 0; - } - if (empty($this->fk_multicurrency)) { + if (!$this->cond_reglement_id) $this->cond_reglement_id = 0; + if (!$this->mode_reglement_id) $this->mode_reglement_id = 0; + $this->brouillon = 1; + + // Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate) + if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency, $this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code); + else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code); + if (empty($this->fk_multicurrency)) + { @@ -498 +438,2 @@ - if (empty($this->date)) { + if (empty($this->date)) + { @@ -505 +446,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -512 +453,0 @@ - $this->date_creation = $now; @@ -520,3 +461,4 @@ - // Erase some properties of the invoice to create with the one of the recurring invoice - if ($this->fac_rec > 0) { - $this->fk_fac_rec_source = $this->fac_rec; + // Create invoice from a template invoice + if ($this->fac_rec > 0) + { + $this->fk_fac_rec_source = $this->fac_rec; @@ -531,8 +473,5 @@ - $nextdatewhen = null; - $previousdaynextdatewhen = null; - if ($originaldatewhen) { - $nextdatewhen = dol_time_plus_duree($originaldatewhen, $_facrec->frequency, $_facrec->unit_frequency); - $previousdaynextdatewhen = dol_time_plus_duree($nextdatewhen, -1, 'd'); - } - - if (!empty($_facrec->frequency)) { // Invoice are created on same thirdparty than template when there is a recurrence, but not necessarly when there is no recurrence. + $nextdatewhen = dol_time_plus_duree($originaldatewhen, $_facrec->frequency, $_facrec->unit_frequency); + $previousdaynextdatewhen = dol_time_plus_duree($nextdatewhen, -1, 'd'); + + if (!empty($_facrec->frequency)) // Invoice are created on same thirdparty than template when there is a recurrence, but not necessarly when there is no recurrence. + { @@ -545,3 +484,3 @@ - $this->note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $_facrec->note_public; - $this->note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $_facrec->note_private; - $this->model_pdf = GETPOSTISSET('model') ? GETPOST('model', 'alpha') : $_facrec->model_pdf; + $this->note_public = GETPOST('note_public', 'none') ? GETPOST('note_public', 'none') : $_facrec->note_public; + $this->note_private = GETPOST('note_private', 'none') ? GETPOST('note_private', 'none') : $_facrec->note_private; + $this->modelpdf = GETPOST('model', 'alpha') ? GETPOST('model', 'alpha') : $_facrec->modelpdf; @@ -557,2 +496,2 @@ - //$this->remise_absolue = $_facrec->remise_absolue; - //$this->remise_percent = $_facrec->remise_percent; // TODO deprecated + $this->remise_absolue = $_facrec->remise_absolue; + $this->remise_percent = $_facrec->remise_percent; @@ -563,3 +502 @@ - if (!$this->type) { - $this->type = self::TYPE_STANDARD; - } + if (!$this->type) $this->type = self::TYPE_STANDARD; @@ -567 +503,0 @@ - $this->ref_customer = trim($this->ref_customer); @@ -570,9 +506,7 @@ - $this->note_private = dol_concatdesc($this->note_private, $langs->trans("GeneratedFromRecurringInvoice", $_facrec->ref)); - - $this->array_options = $_facrec->array_options; - - if (!$this->mode_reglement_id) { - $this->mode_reglement_id = 0; - } - $this->status = self::STATUS_DRAFT; - $this->statut = self::STATUS_DRAFT; // deprecated + $this->note_private = dol_concatdesc($this->note_private, $langs->trans("GeneratedFromRecurringInvoice", $_facrec->ref)); + + $this->array_options = $_facrec->array_options; + + //if (! $this->remise) $this->remise = 0; + if (!$this->mode_reglement_id) $this->mode_reglement_id = 0; + $this->brouillon = 1; @@ -583,0 +518,2 @@ + $forceduedate = $this->calculate_date_lim_reglement(); + @@ -585,9 +521,8 @@ - if ($_facrec->frequency > 0) { - dol_syslog("This is a recurring invoice so we set date_last_gen and next date_when"); - if (empty($_facrec->date_when)) { - $_facrec->date_when = $now; - } - $next_date = $_facrec->getNextDate(); // Calculate next date - $result = $_facrec->setValueFrom('date_last_gen', $now, '', null, 'date', '', $user, ''); - //$_facrec->setValueFrom('nb_gen_done', $_facrec->nb_gen_done + 1); // Not required, +1 already included into setNextDate when second param is 1. - $result = $_facrec->setNextDate($next_date, 1); + if ($_facrec->frequency > 0) + { + dol_syslog("This is a recurring invoice so we set date_last_gen and next date_when"); + if (empty($_facrec->date_when)) $_facrec->date_when = $now; + $next_date = $_facrec->getNextDate(); // Calculate next date + $result = $_facrec->setValueFrom('date_last_gen', $now, '', null, 'date', '', $user, ''); + //$_facrec->setValueFrom('nb_gen_done', $_facrec->nb_gen_done + 1); // Not required, +1 already included into setNextDate when second param is 1. + $result = $_facrec->setNextDate($next_date, 1); @@ -600,9 +535,6 @@ - if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && isset($this->thirdparty->default_lang)) { - $newlang = $this->thirdparty->default_lang; // for proposal, order, invoice, ... - } - if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && isset($this->default_lang)) { - $newlang = $this->default_lang; // for thirdparty - } - if (!empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && isset($this->thirdparty->default_lang)) $newlang = $this->thirdparty->default_lang; // for proposal, order, invoice, ... + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && isset($this->default_lang)) $newlang = $this->default_lang; // for thirdparty + if (!empty($newlang)) + { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); @@ -623,3 +555,3 @@ - $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = (isset($originaldatewhen) ? dol_print_date($originaldatewhen, 'dayhour') : ''); - $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = (isset($nextdatewhen) ? dol_print_date($nextdatewhen, 'dayhour') : ''); - $substitutionarray['__INVOICE_PREVIOUS_DATE_NEXT_INVOICE_AFTER_GEN__'] = (isset($previousdaynextdatewhen) ? dol_print_date($previousdaynextdatewhen, 'dayhour') : ''); + $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = dol_print_date($originaldatewhen, 'dayhour'); + $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = dol_print_date($nextdatewhen, 'dayhour'); + $substitutionarray['__INVOICE_PREVIOUS_DATE_NEXT_INVOICE_AFTER_GEN__'] = dol_print_date($previousdaynextdatewhen, 'dayhour'); @@ -638,10 +570,10 @@ - if (empty($forceduedate)) { - $duedate = $this->calculate_date_lim_reglement(); - /*if ($duedate < 0) { Regression, a date can be negative if before 1970. - dol_syslog(__METHOD__ . ' Error in calculate_date_lim_reglement. We got ' . $duedate, LOG_ERR); - return -1; - }*/ - $this->date_lim_reglement = $duedate; - } else { - $this->date_lim_reglement = $forceduedate; - } + if (empty($forceduedate)) { + $duedate = $this->calculate_date_lim_reglement(); + /*if ($duedate < 0) { Regression, a date can be negative if before 1970. + dol_syslog(__METHOD__ . ' Error in calculate_date_lim_reglement. We got ' . $duedate, LOG_ERR); + return -1; + }*/ + $this->date_lim_reglement = $duedate; + } else { + $this->date_lim_reglement = $forceduedate; + } @@ -657 +588,0 @@ - $sql .= ", subtype"; @@ -659,0 +591,2 @@ + $sql .= ", remise_absolue"; + $sql .= ", remise_percent"; @@ -664,2 +597,2 @@ - $sql .= ", ref_client"; - $sql .= ", fk_account"; + $sql .= ", ref_client, ref_int"; + $sql .= ", fk_account"; @@ -670,6 +603,6 @@ - $sql .= ", fk_multicurrency"; - $sql .= ", multicurrency_code"; - $sql .= ", multicurrency_tx"; - $sql .= ", retained_warranty"; - $sql .= ", retained_warranty_date_limit"; - $sql .= ", retained_warranty_fk_cond_reglement"; + $sql .= ", fk_multicurrency"; + $sql .= ", multicurrency_code"; + $sql .= ", multicurrency_tx"; + $sql .= ", retained_warranty"; + $sql .= ", retained_warranty_date_limit"; + $sql .= ", retained_warranty_fk_cond_reglement"; @@ -682,3 +615,4 @@ - $sql .= ", ".($this->subtype ? "'".$this->db->escape($this->subtype)."'" : "null"); - $sql .= ", ".((int) $socid); - $sql .= ", '".$this->db->idate($this->date_creation)."'"; + $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'); @@ -686 +620 @@ - $sql .= ", ".(empty($this->date_pointoftax) ? "null" : "'".$this->db->idate($this->date_pointoftax)."'"); + $sql .= ", ".(strval($this->date_pointoftax) != '' ? "'".$this->db->idate($this->date_pointoftax)."'" : 'null'); @@ -689 +623,2 @@ - $sql .= ", ".($this->ref_customer ? "'".$this->db->escape($this->ref_customer)."'" : ($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null")); + $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null"); + $sql .= ", ".($this->ref_int ? "'".$this->db->escape($this->ref_int)."'" : "null"); @@ -695 +630 @@ - $sql .= ", ".($user->id > 0 ? (int) $user->id : "null"); + $sql .= ", ".($user->id > 0 ? "'".$user->id."'" : "null"); @@ -697,4 +632,3 @@ - $sql .= ", ".((int) $this->cond_reglement_id); - $sql .= ", ".((int) $this->mode_reglement_id); - $sql .= ", '".$this->db->idate($this->date_lim_reglement)."'"; - $sql .= ", ".(isset($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : "null"); + $sql .= ", ".$this->cond_reglement_id; + $sql .= ", ".$this->mode_reglement_id; + $sql .= ", '".$this->db->idate($this->date_lim_reglement)."', '".$this->db->escape($this->modelpdf)."'"; @@ -705 +639 @@ - $sql .= ", '".$this->db->escape($this->location_incoterms)."'"; + $sql .= ", '".$this->db->escape($this->location_incoterms)."'"; @@ -708 +642 @@ - $sql .= ", ".(float) $this->multicurrency_tx; + $sql .= ", ".(double) $this->multicurrency_tx; @@ -715 +649,2 @@ - if ($resql) { + if ($resql) + { @@ -720 +655 @@ - $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".((int) $this->id); + $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".$this->id; @@ -723,5 +658,4 @@ - if (!$resql) { - $error++; - } - - if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) { // To use new linkedObjectsIds instead of old linked_objects + if (!$resql) $error++; + + if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) // To use new linkedObjectsIds instead of old linked_objects + { @@ -732,18 +666,26 @@ - if (!$error && $this->id && !empty($this->linked_objects) && is_array($this->linked_objects)) { - foreach ($this->linked_objects as $origin => $tmp_origin_id) { - if (is_array($tmp_origin_id)) { // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...)) - foreach ($tmp_origin_id as $origin_id) { - $ret = $this->add_object_linked($origin, $origin_id); - if (!$ret) { - $this->error = $this->db->lasterror(); - $error++; - } - } - } else { // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1)) - $origin_id = $tmp_origin_id; - $ret = $this->add_object_linked($origin, $origin_id); - if (!$ret) { - $this->error = $this->db->lasterror(); - $error++; - } - } + if (!$error && $this->id && is_array($this->linked_objects) && !empty($this->linked_objects)) + { + foreach ($this->linked_objects as $origin => $tmp_origin_id) + { + if (is_array($tmp_origin_id)) // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...)) + { + foreach ($tmp_origin_id as $origin_id) + { + $ret = $this->add_object_linked($origin, $origin_id); + if (!$ret) + { + $this->error = $this->db->lasterror(); + $error++; + } + } + } + else // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1)) + { + $origin_id = $tmp_origin_id; + $ret = $this->add_object_linked($origin, $origin_id); + if (!$ret) + { + $this->error = $this->db->lasterror(); + $error++; + } + } @@ -754 +696,2 @@ - if (!$error && $this->id && getDolGlobalString('MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN') && !empty($this->origin) && !empty($this->origin_id)) { // Get contact from origin object + if (!$error && $this->id && !empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN) && !empty($this->origin) && !empty($this->origin_id)) // Get contact from origin object + { @@ -757,16 +700,16 @@ - if ($originforcontact == 'shipping') { // shipment and order share the same contacts. If creating from shipment we take data of order - require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; - $exp = new Expedition($this->db); - $exp->fetch($this->origin_id); - $exp->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0); - if (count($exp->linkedObjectsIds['commande']) > 0) { - foreach ($exp->linkedObjectsIds['commande'] as $key => $value) { - $originforcontact = 'commande'; - if (is_object($value)) { - $originidforcontact = $value->id; - } else { - $originidforcontact = $value; - } - break; // We take first one - } - } + if ($originforcontact == 'shipping') // shipment and order share the same contacts. If creating from shipment we take data of order + { + require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; + $exp = new Expedition($this->db); + $exp->fetch($this->origin_id); + $exp->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0); + if (count($exp->linkedObjectsIds['commande']) > 0) + { + foreach ($exp->linkedObjectsIds['commande'] as $key => $value) + { + $originforcontact = 'commande'; + if (is_object($value)) $originidforcontact = $value->id; + else $originidforcontact = $value; + break; // We take first one + } + } @@ -776 +719 @@ - $sqlcontact .= " WHERE element_id = ".((int) $originidforcontact)." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$this->db->escape($originforcontact)."'"; + $sqlcontact .= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'"; @@ -779,7 +722,7 @@ - if ($resqlcontact) { - while ($objcontact = $this->db->fetch_object($resqlcontact)) { - //print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n"; - $this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source); // May failed because of duplicate key or because code of contact type does not exists for new object - } - } else { - dol_print_error($resqlcontact); + if ($resqlcontact) + { + while ($objcontact = $this->db->fetch_object($resqlcontact)) + { + //print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n"; + $this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source); // May failed because of duplicate key or because code of contact type does not exists for new object + } @@ -786,0 +730 @@ + else dol_print_error($resqlcontact); @@ -792 +736,2 @@ - if (!$error && empty($this->fac_rec) && count($this->lines) && is_object($this->lines[0])) { // If this->lines is array of InvoiceLines (preferred mode) + if (!$error && empty($this->fac_rec) && count($this->lines) && is_object($this->lines[0])) // If this->lines is array of InvoiceLines (preferred mode) + { @@ -795,2 +740,3 @@ - dol_syslog("There is ".count($this->lines)." lines into ->lines that are InvoiceLines"); - foreach ($this->lines as $i => $val) { + dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects"); + foreach ($this->lines as $i => $val) + { @@ -798,3 +743,0 @@ - - $newinvoiceline->context = $this->context; - @@ -807 +750,2 @@ - if ($this->lines[$i]->date_start_fill == 1 && $originaldatewhen) { // $originaldatewhen is defined when generating from recurring invoice only + if ($this->lines[$i]->date_start_fill == 1 && $originaldatewhen) // $originaldatewhen is defined when generating from recurring invoice only + { @@ -810 +754,2 @@ - if ($this->lines[$i]->date_end_fill == 1 && $previousdaynextdatewhen) { // $previousdaynextdatewhen is defined when generating from recurring invoice only + if ($this->lines[$i]->date_end_fill == 1 && $previousdaynextdatewhen) // $previousdaynextdatewhen is defined when generating from recurring invoice only + { @@ -814 +759,2 @@ - if ($result >= 0) { + if ($result >= 0) + { @@ -820,6 +765,0 @@ - // Complete vat rate with code - $vatrate = $newinvoiceline->tva_tx; - if ($newinvoiceline->vat_src_code && ! preg_match('/\(.*\)/', $vatrate)) { - $vatrate.=' ('.$newinvoiceline->vat_src_code.')'; - } - @@ -829,40 +769,8 @@ - $discount = new DiscountAbsolute($this->db); - $discount->fetch($newinvoiceline->fk_remise_except); - - $discountId = $soc->set_remise_except($discount->amount_ht, $user, $discount->description, $discount->tva_tx); - $newinvoiceline->fk_remise_except = $discountId; - } - - $result = $this->addline( - $newinvoiceline->desc, - $newinvoiceline->subprice, - $newinvoiceline->qty, - $vatrate, - $newinvoiceline->localtax1_tx, - $newinvoiceline->localtax2_tx, - $newinvoiceline->fk_product, - $newinvoiceline->remise_percent, - $newinvoiceline->date_start, - $newinvoiceline->date_end, - $newinvoiceline->fk_code_ventilation, - $newinvoiceline->info_bits, - $newinvoiceline->fk_remise_except, - 'HT', - 0, - $newinvoiceline->product_type, - $newinvoiceline->rang, - $newinvoiceline->special_code, - $newinvoiceline->element, - $newinvoiceline->id, - $fk_parent_line, - $newinvoiceline->fk_fournprice, - $newinvoiceline->pa_ht, - $newinvoiceline->label, - $newinvoiceline->array_options, - $newinvoiceline->situation_percent, - $newinvoiceline->fk_prev_id, - $newinvoiceline->fk_unit, - $newinvoiceline->multicurrency_subprice, - $newinvoiceline->ref_ext, - 1 - ); + $discount = new DiscountAbsolute($this->db); + $discount->fetch($newinvoiceline->fk_remise_except); + + $discountId = $soc->set_remise_except($discount->amount_ht, $user, $discount->description, $discount->tva_tx); + $newinvoiceline->fk_remise_except = $discountId; + } + + $result = $newinvoiceline->insert(); @@ -875 +783,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -877 +785,0 @@ - $this->errors = $newinvoiceline->errors; @@ -882 +790,3 @@ - } elseif (!$error && empty($this->fac_rec)) { // If this->lines is an array of invoice line arrays + } + elseif (!$error && empty($this->fac_rec)) // If this->lines is an array of invoice line arrays + { @@ -885,12 +795,12 @@ - dol_syslog("There is ".count($this->lines)." lines into ->lines as a simple array"); - - foreach ($this->lines as $i => $val) { - $line = $this->lines[$i]; - - // Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array - //if (! is_object($line)) $line=json_decode(json_encode($line), false); // convert recursively array into object. - if (!is_object($line)) { - $line = (object) $line; - } - - if ($result >= 0) { + dol_syslog("There is ".count($this->lines)." lines that are array lines"); + + foreach ($this->lines as $i => $val) + { + $line = $this->lines[$i]; + + // Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array + //if (! is_object($line)) $line=json_decode(json_encode($line), false); // convert recursively array into object. + if (!is_object($line)) $line = (object) $line; + + if ($result >= 0) + { @@ -904,5 +814,3 @@ - if ($line->vat_src_code && !preg_match('/\(.*\)/', $vatrate)) { - $vatrate .= ' ('.$line->vat_src_code.')'; - } - - if (getDolGlobalString('MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION')) { + if ($line->vat_src_code && !preg_match('/\(.*\)/', $vatrate)) $vatrate .= ' ('.$line->vat_src_code.')'; + + if (!empty($conf->global->MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION)) { @@ -916,6 +824 @@ - // init ref_ext - if (empty($line->ref_ext)) { - $line->ref_ext = ''; - } - - $result = $this->addline( + $result = $this->addline( @@ -940,2 +843,2 @@ - $origintype, - $originid, + $origintype, + $originid, @@ -950,3 +853 @@ - $line->multicurrency_subprice, - $line->ref_ext, - 1 + $line->pu_ht_devise @@ -954 +855,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -970 +872 @@ - * Insert lines coming from the template invoice + * Insert lines of template invoices @@ -972,6 +874,6 @@ - if (!$error && $this->fac_rec > 0) { - dol_syslog("There is ".count($_facrec->lines)." lines from recurring invoice"); - $fk_parent_line = 0; - - foreach ($_facrec->lines as $i => $val) { - if ($_facrec->lines[$i]->fk_product) { + if (!$error && $this->fac_rec > 0) + { + foreach ($_facrec->lines as $i => $val) + { + if ($_facrec->lines[$i]->fk_product) + { @@ -980,5 +881,0 @@ - } - - // Reset fk_parent_line for no child products and special product - if (($_facrec->lines[$i]->product_type != 9 && empty($_facrec->lines[$i]->fk_parent_line)) || $_facrec->lines[$i]->product_type == 9) { - $fk_parent_line = 0; @@ -997,3 +894 @@ - if (empty($tva_tx)) { - $tva_npr = 0; - } + if (empty($tva_tx)) $tva_npr = 0; @@ -1003 +898 @@ - $fk_product_fournisseur_price = empty($_facrec->lines[$i]->fk_product_fournisseur_price) ? null : $_facrec->lines[$i]->fk_product_fournisseur_price; + $fk_product_fournisseur_price = empty($_facrec->lines[$i]->fk_product_fournisseur_price) ?null:$_facrec->lines[$i]->fk_product_fournisseur_price; @@ -1005 +899,0 @@ - @@ -1007,20 +901,21 @@ - if (!$buyprice && $_facrec->lines[$i]->fk_product > 0) { - require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $producttmp = new ProductFournisseur($this->db); - $producttmp->fetch($_facrec->lines[$i]->fk_product); - - // If margin module defined on costprice, we try the costprice - // If not defined or if module margin defined and pmp and stock module enabled, we try pmp price - // else we get the best supplier price - if (getDolGlobalString('MARGIN_TYPE') == 'costprice' && !empty($producttmp->cost_price)) { - $buyprice = $producttmp->cost_price; - } elseif (isModEnabled('stock') && (getDolGlobalString('MARGIN_TYPE') == 'costprice' || getDolGlobalString('MARGIN_TYPE') == 'pmp') && !empty($producttmp->pmp)) { - $buyprice = $producttmp->pmp; - } else { - if ($producttmp->find_min_price_product_fournisseur($_facrec->lines[$i]->fk_product) > 0) { - if ($producttmp->product_fourn_price_id > 0) { - $buyprice = price2num($producttmp->fourn_unitprice * (1 - $producttmp->fourn_remise_percent / 100) + $producttmp->fourn_remise, 'MU'); - } - } - } - } + if (!$buyprice && $_facrec->lines[$i]->fk_product > 0) + { + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; + $producttmp = new ProductFournisseur($this->db); + $producttmp->fetch($_facrec->lines[$i]->fk_product); + + // If margin module defined on costprice, we try the costprice + // If not defined or if module margin defined and pmp and stock module enabled, we try pmp price + // else we get the best supplier price + if ($conf->global->MARGIN_TYPE == 'costprice' && !empty($producttmp->cost_price)) $buyprice = $producttmp->cost_price; + elseif (!empty($conf->stock->enabled) && ($conf->global->MARGIN_TYPE == 'costprice' || $conf->global->MARGIN_TYPE == 'pmp') && !empty($producttmp->pmp)) $buyprice = $producttmp->pmp; + else { + if ($producttmp->find_min_price_product_fournisseur($_facrec->lines[$i]->fk_product) > 0) + { + if ($producttmp->product_fourn_price_id > 0) + { + $buyprice = price2num($producttmp->fourn_unitprice * (1 - $producttmp->fourn_remise_percent / 100) + $producttmp->fourn_remise, 'MU'); + } + } + } + } @@ -1049,2 +944,2 @@ - $fk_parent_line, - $fk_product_fournisseur_price, + 0, + $fk_product_fournisseur_price, @@ -1053,2 +948,2 @@ - empty($_facrec->lines[$i]->array_options) ? null : $_facrec->lines[$i]->array_options, - 100, // situation percent is undefined on recurring invoice lines + empty($_facrec->lines[$i]->array_options) ?null:$_facrec->lines[$i]->array_options, + $_facrec->lines[$i]->situation_percent, @@ -1057,3 +952 @@ - $_facrec->lines[$i]->multicurrency_subprice, - $_facrec->lines[$i]->ref_ext, - 1 + $_facrec->lines[$i]->pu_ht_devise @@ -1062,6 +955,2 @@ - // Defined the new fk_parent_line - if ($result_insert > 0 && $_facrec->lines[$i]->product_type == 9) { - $fk_parent_line = $result_insert; - } - - if ($result_insert < 0) { + if ($result_insert < 0) + { @@ -1075,3 +964,5 @@ - if (!$error) { - $result = $this->update_price(1, 'auto', 0, $mysoc); - if ($result > 0) { + if (!$error) + { + $result = $this->update_price(1); + if ($result > 0) + { @@ -1081,5 +972,4 @@ - if (!$error) { - $result = $this->insertExtraFields(); - if ($result < 0) { - $error++; - } + if (!$error) + { + $result = $this->insertExtraFields(); + if ($result < 0) $error++; @@ -1088,10 +978,10 @@ - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('BILL_CREATE', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } - - if (!$error) { + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('BILL_CREATE', $user); + if ($result < 0) $error++; + // End call triggers + } + + if (!$error) + { @@ -1100 +990,3 @@ - } else { + } + else + { @@ -1104 +996,3 @@ - } else { + } + else + { @@ -1109 +1003,3 @@ - } else { + } + else + { @@ -1114 +1010,3 @@ - } else { + } + else + { @@ -1127,3 +1025,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function createFromCurrent(User $user, $invertdetail = 0) + * @return int <0 if KO, >0 if OK + */ + public function createFromCurrent(User $user, $invertdetail = 0) @@ -1133 +1031 @@ - // Source invoice load + // Charge facture source @@ -1136 +1034 @@ - // Retrieve all extrafield + // Retreive all extrafield @@ -1140,7 +1038,7 @@ - if (!empty($this->array_options)) { - $facture->array_options = $this->array_options; - } - - foreach ($this->lines as &$line) { - $line->fetch_optionals(); //fetch extrafields - } + if (!empty($this->array_options)) { + $facture->array_options = $this->array_options; + } + + foreach ($this->lines as &$line) { + $line->fetch_optionals(); //fetch extrafields + } @@ -1150 +1047,0 @@ - $facture->subtype = $this->subtype; @@ -1157 +1054 @@ - $facture->model_pdf = $this->model_pdf; + $facture->modelpdf = $this->modelpdf; @@ -1161,2 +1058,2 @@ - //$facture->remise_absolue = $this->remise_absolue; - //$facture->remise_percent = $this->remise_percent; // TODO deprecated + $facture->remise_absolue = $this->remise_absolue; + $facture->remise_percent = $this->remise_percent; @@ -1166 +1062,0 @@ - $facture->fk_account = $this->fk_account; @@ -1168,0 +1065 @@ + $facture->products = $this->lines; // Tant que products encore utilise @@ -1173,5 +1070,3 @@ - $facture->retained_warranty = $this->retained_warranty; - $facture->retained_warranty_fk_cond_reglement = $this->retained_warranty_fk_cond_reglement; - $facture->retained_warranty_date_limit = $this->retained_warranty_date_limit; - - $facture->fk_user_author = $user->id; + $facture->retained_warranty = $this->retained_warranty; + $facture->retained_warranty_fk_cond_reglement = $this->retained_warranty_fk_cond_reglement; + $facture->retained_warranty_date_limit = $this->retained_warranty_date_limit; @@ -1181 +1076,2 @@ - foreach ($facture->lines as $i => $tmpline) { + foreach ($facture->lines as $i => $tmpline) + { @@ -1183 +1079,2 @@ - if ($invertdetail) { + if ($invertdetail) + { @@ -1190 +1086,0 @@ - $facture->lines[$i]->ref_ext = ''; @@ -1197 +1093,2 @@ - if ($facid <= 0) { + if ($facid <= 0) + { @@ -1200 +1097,3 @@ - } elseif ($this->type == self::TYPE_SITUATION && getDolGlobalString('INVOICE_USE_SITUATION')) { + } + elseif ($this->type == self::TYPE_SITUATION && !empty($conf->global->INVOICE_USE_SITUATION)) + { @@ -1203,2 +1102,4 @@ - foreach ($this->linkedObjectsIds as $typeObject => $Tfk_object) { - foreach ($Tfk_object as $fk_object) { + foreach ($this->linkedObjectsIds as $typeObject => $Tfk_object) + { + foreach ($Tfk_object as $fk_object) + { @@ -1219 +1120 @@ - * @param User $user User that clone + * @param User $user User that clone @@ -1235,3 +1135,0 @@ - // Load source object - $objFrom = clone $object; - @@ -1239 +1137,2 @@ - if (!empty($this->socid) && $this->socid != $object->socid) { + if (!empty($this->socid) && $this->socid != $object->socid) + { @@ -1242,6 +1141,7 @@ - if ($objsoc->fetch($this->socid) > 0) { - $object->socid = $objsoc->id; - $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); - $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); - $object->fk_project = ''; - $object->fk_delivery_address = ''; + if ($objsoc->fetch($this->socid) > 0) + { + $object->socid = $objsoc->id; + $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); + $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); + $object->fk_project = ''; + $object->fk_delivery_address = ''; @@ -1255 +1154,0 @@ - $object->status = self::STATUS_DRAFT; @@ -1259,4 +1158,2 @@ - $object->user_creation_id = $user->id; - $object->user_validation_id = null; - $object->fk_user_author = $user->id; - $object->fk_user_valid = null; + $object->user_author = $user->id; + $object->user_valid = ''; @@ -1270 +1167,2 @@ - if (getDolGlobalInt('MAIN_DONT_KEEP_NOTE_ON_CLONING') == 1) { + $object->products = $object->lines; // For backward compatibility + if ($conf->global->MAIN_DONT_KEEP_NOTE_ON_CLONING == 1) { @@ -1276,7 +1174,8 @@ - foreach ($object->lines as $i => $line) { - if (($object->lines[$i]->info_bits & 0x02) == 0x02) { // We do not clone line of discounts - unset($object->lines[$i]); - continue; - } - - // Bloc to update dates of service (month by month only if previously filled and similare to start and end of month) + foreach ($object->lines as $i => $line) + { + if (($object->lines[$i]->info_bits & 0x02) == 0x02) // We do not clone line of discounts + { + unset($object->lines[$i]); + unset($object->products[$i]); // Tant que products encore utilise + } + // Bloc to update dates of service (month by month only if previously filled at 1d near start or end of month) @@ -1284 +1183 @@ - if (getDolGlobalString('INVOICE_AUTO_NEXT_MONTH_ON_LINES') && !empty($line->date_start) && !empty($line->date_end)) { + if (!empty($line->date_start) && !empty($line->date_end) ) { @@ -1291,7 +1190,8 @@ - $last = dol_get_last_day($end['year'], $end['mon']); - - //print dol_print_date(dol_mktime(0, 0, 0, $start['mon'], $start['mday'], $start['year'], 'gmt'), 'dayhour').' '.dol_print_date($first, 'dayhour').'
'; - //print dol_mktime(23, 59, 59, $end['mon'], $end['mday'], $end['year'], 'gmt').' '.$last.'
';exit; - // If start date is first date of month and end date is last date of month - if (dol_mktime(0, 0, 0, $start['mon'], $start['mday'], $start['year'], 'gmt') == $first - && dol_mktime(23, 59, 59, $end['mon'], $end['mday'], $end['year'], 'gmt') == $last) { + $last = dol_get_first_day($end['year'], $end['mon']); + + // Get diff betweend start/end of month and previously filled + $diffFirst = num_between_day($first, dol_mktime($start['hours'], $start['minutes'], $start['seconds'], $start['mon'], $start['mday'], $start['year'], 'user')); + $diffLast = num_between_day(dol_mktime($end['hours'], $end['minutes'], $end['seconds'], $end['mon'], $end['mday'], $end['year'], 'user'), $last); + + // If there is <= 1d (or 2?) of start/or/end of month + if ($diffFirst <= 2 && $diffLast <= 2) { @@ -1305,2 +1204,0 @@ - - $object->lines[$i]->ref_ext = ''; // Do not clone ref_ext @@ -1312,5 +1210,2 @@ - if ($result < 0) { - $error++; - $this->error = $object->error; - $this->errors = $object->errors; - } else { + if ($result < 0) $error++; + else { @@ -1318 +1213 @@ - if ($object->copy_linked_contact($objFrom, 'internal') < 0) { + if ($object->copy_linked_contact($this, 'internal') < 0) @@ -1320,5 +1215,5 @@ - $this->error = $object->error; - $this->errors = $object->errors; - } elseif ($object->socid == $objFrom->socid) { - // copy external contacts if same company - if ($object->copy_linked_contact($objFrom, 'external') < 0) { + + // copy external contacts if same company + elseif ($this->socid == $object->socid) + { + if ($object->copy_linked_contact($this, 'external') < 0) @@ -1326,7 +1221,5 @@ - $this->error = $object->error; - $this->errors = $object->errors; - } - } - } - - if (!$error) { + } + } + + if (!$error) + { @@ -1334,2 +1227,3 @@ - if (is_object($hookmanager)) { - $parameters = array('objFrom'=>$objFrom); + if (is_object($hookmanager)) + { + $parameters = array('objFrom'=>$this); @@ -1338,4 +1232 @@ - if ($reshook < 0) { - $this->setErrorsFromObject($hookmanager); - $error++; - } + if ($reshook < 0) $error++; @@ -1348 +1239,2 @@ - if (!$error) { + if (!$error) + { @@ -1351 +1243,3 @@ - } else { + } + else + { @@ -1362,3 +1256,3 @@ - * @return int Return integer <0 if KO, 0 if nothing done, 1 if OK - */ - public function createFromOrder($object, User $user) + * @return int <0 if KO, 0 if nothing done, 1 if OK + */ + public function createFromOrder($object, User $user) @@ -1375,136 +1269,2 @@ - for ($i = 0; $i < $num; $i++) { - $line = new FactureLigne($this->db); - - $line->libelle = $object->lines[$i]->libelle; // deprecated - $line->label = $object->lines[$i]->label; - $line->desc = $object->lines[$i]->desc; - $line->subprice = $object->lines[$i]->subprice; - $line->total_ht = $object->lines[$i]->total_ht; - $line->total_tva = $object->lines[$i]->total_tva; - $line->total_localtax1 = $object->lines[$i]->total_localtax1; - $line->total_localtax2 = $object->lines[$i]->total_localtax2; - $line->total_ttc = $object->lines[$i]->total_ttc; - $line->vat_src_code = $object->lines[$i]->vat_src_code; - $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; - $line->fk_unit = $object->lines[$i]->fk_unit; - $line->date_start = $object->lines[$i]->date_start; - $line->date_end = $object->lines[$i]->date_end; - - // Multicurrency - $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency; - $line->multicurrency_code = $object->lines[$i]->multicurrency_code; - $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice; - $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht; - $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva; - $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc; - - $line->fk_fournprice = $object->lines[$i]->fk_fournprice; - $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); - $line->pa_ht = $marginInfos[0]; - - // get extrafields from original line - $object->lines[$i]->fetch_optionals(); - foreach ($object->lines[$i]->array_options as $options_key => $value) { - $line->array_options[$options_key] = $value; - } - - $this->lines[$i] = $line; - } - - $this->socid = $object->socid; - $this->fk_project = $object->fk_project; - $this->fk_account = $object->fk_account; - $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->delivery_date = $object->delivery_date; - $this->fk_delivery_address = $object->fk_delivery_address; // deprecated - $this->contact_id = $object->contact_id; - $this->ref_client = $object->ref_client; - - if (!getDolGlobalString('MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN')) { - $this->note_private = $object->note_private; - $this->note_public = $object->note_public; - } - - $this->module_source = $object->module_source; - $this->pos_source = $object->pos_source; - - $this->origin = $object->element; - $this->origin_id = $object->id; - - $this->fk_user_author = $user->id; - - // get extrafields from original line - $object->fetch_optionals(); - foreach ($object->array_options as $options_key => $value) { - $this->array_options[$options_key] = $value; - } - - // Possibility to add external linked objects with hooks - $this->linked_objects[$this->origin] = $this->origin_id; - if (!empty($object->other_linked_objects) && is_array($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) - $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) { - $this->setErrorsFromObject($hookmanager); - $error++; - } - - if (!$error) { - return 1; - } else { - return -1; - } - } else { - return -1; - } - } - - /** - * Load an object from an order and create a new invoice into database - * - * @param Object $object Object source - * @param User $user Object user - * @param array $lines Ids of lines to use for invoice. If empty, all lines will be used. - * @return int Return integer <0 if KO, 0 if nothing done, 1 if OK - */ - public function createFromContract($object, User $user, $lines = array()) - { - global $conf, $hookmanager; - - $error = 0; - - // Closed order - $this->date = dol_now(); - $this->source = 0; - - $use_all_lines = empty($lines); - $num = count($object->lines); - for ($i = 0; $i < $num; $i++) { - if (!$use_all_lines && !in_array($object->lines[$i]->id, $lines)) { - continue; - } - + for ($i = 0; $i < $num; $i++) + { @@ -1551 +1311 @@ - // get extrafields from original line + // get extrafields from original line @@ -1553 +1313 @@ - foreach ($object->lines[$i]->array_options as $options_key => $value) { + foreach ($object->lines[$i]->array_options as $options_key => $value) @@ -1555 +1314,0 @@ - } @@ -1567 +1326 @@ - $this->delivery_date = $object->delivery_date; + $this->date_livraison = $object->date_livraison; @@ -1569 +1328 @@ - $this->contact_id = $object->contact_id; + $this->contact_id = $object->contactid; @@ -1572,6 +1331,7 @@ - if (!getDolGlobalString('MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN')) { - $this->note_private = $object->note_private; - $this->note_public = $object->note_public; - } - - $this->module_source = $object->module_source; + if (empty($conf->global->MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN)) + { + $this->note_private = $object->note_private; + $this->note_public = $object->note_public; + } + + $this->module_source = $object->module_source; @@ -1583,3 +1343 @@ - $this->fk_user_author = $user->id; - - // get extrafields from original line + // get extrafields from original line @@ -1587 +1345 @@ - foreach ($object->array_options as $options_key => $value) { + foreach ($object->array_options as $options_key => $value) @@ -1589 +1346,0 @@ - } @@ -1593 +1350,2 @@ - if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) { + if (!empty($object->other_linked_objects) && is_array($object->other_linked_objects)) + { @@ -1599 +1357,2 @@ - if ($ret > 0) { + if ($ret > 0) + { @@ -1606,6 +1365,4 @@ - if ($reshook < 0) { - $this->setErrorsFromObject($hookmanager); - $error++; - } - - if (!$error) { + if ($reshook < 0) $error++; + + if (!$error) + { @@ -1613,361 +1370,4 @@ - } else { - return -1; - } - } else { - return -1; - } - } - - /** - * Creates a deposit from a proposal or an order by grouping lines by VAT rates - * - * @param Propal|Commande $origin The original proposal or order - * @param int $date Invoice date - * @param int $payment_terms_id Invoice payment terms - * @param User $user Object user - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @param bool $autoValidateDeposit Whether to aumatically validate the deposit created - * @param array $overrideFields Array of fields to force values - * @return Facture|null The deposit created, or null if error (populates $origin->error in this case) - */ - public static function createDepositFromOrigin(CommonObject $origin, $date, $payment_terms_id, User $user, $notrigger = 0, $autoValidateDeposit = false, $overrideFields = array()) - { - global $conf, $langs, $hookmanager, $action; - - if (! in_array($origin->element, array('propal', 'commande'))) { - $origin->error = 'ErrorCanOnlyAutomaticallyGenerateADepositFromProposalOrOrder'; - return null; - } - - if (empty($date)) { - $origin->error = $langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')); - return null; - } - - require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; - - if ($date > (dol_get_last_hour(dol_now('tzuserrel')) + (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY') ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { - $origin->error = 'ErrorDateIsInFuture'; - return null; - } - - if ($payment_terms_id <= 0) { - $origin->error = $langs->trans('ErrorFieldRequired', $langs->transnoentities('PaymentConditionsShort')); - return null; - } - - $payment_conditions_deposit_percent = getDictionaryValue('c_payment_term', 'deposit_percent', $origin->cond_reglement_id); - - if (empty($payment_conditions_deposit_percent)) { - $origin->error = 'ErrorPaymentConditionsNotEligibleToDepositCreation'; - return null; - } - - if (empty($origin->deposit_percent)) { - $origin->error = $langs->trans('ErrorFieldRequired', $langs->transnoentities('DepositPercent')); - return null; - } - - $deposit = new self($origin->db); - $deposit->socid = $origin->socid; - $deposit->type = self::TYPE_DEPOSIT; - $deposit->fk_project = $origin->fk_project; - $deposit->ref_client = $origin->ref_client; - $deposit->date = $date; - $deposit->mode_reglement_id = $origin->mode_reglement_id; - $deposit->cond_reglement_id = $payment_terms_id; - $deposit->availability_id = $origin->availability_id; - $deposit->demand_reason_id = $origin->demand_reason_id; - $deposit->fk_account = $origin->fk_account; - $deposit->fk_incoterms = $origin->fk_incoterms; - $deposit->location_incoterms = $origin->location_incoterms; - $deposit->fk_multicurrency = $origin->fk_multicurrency; - $deposit->multicurrency_code = $origin->multicurrency_code; - $deposit->multicurrency_tx = $origin->multicurrency_tx; - $deposit->module_source = $origin->module_source; - $deposit->pos_source = $origin->pos_source; - $deposit->model_pdf = 'crabe'; - - $modelByTypeConfName = 'FACTURE_ADDON_PDF_' . $deposit->type; - - if (getDolGlobalString($modelByTypeConfName)) { - $deposit->model_pdf = getDolGlobalString($modelByTypeConfName); - } elseif (getDolGlobalString('FACTURE_ADDON_PDF')) { - $deposit->model_pdf = getDolGlobalString('FACTURE_ADDON_PDF'); - } - - if (!getDolGlobalString('MAIN_DISABLE_PROPAGATE_NOTES_FROM_ORIGIN')) { - $deposit->note_private = $origin->note_private; - $deposit->note_public = $origin->note_public; - } - - $deposit->origin = $origin->element; - $deposit->origin_id = $origin->id; - - $origin->fetch_optionals(); - - foreach ($origin->array_options as $extrakey => $value) { - $deposit->array_options[$extrakey] = $value; - } - - $deposit->linked_objects[$deposit->origin] = $deposit->origin_id; - - foreach ($overrideFields as $key => $value) { - $deposit->$key = $value; - } - - $deposit->context['createdepositfromorigin'] = 'createdepositfromorigin'; - - $origin->db->begin(); - - // Facture::create() also imports contact from origin - $createReturn = $deposit->create($user, $notrigger); - - if ($createReturn <= 0) { - $origin->db->rollback(); - $origin->error = $deposit->error; - $origin->errors = $deposit->errors; - return null; - } - - $amount_ttc_diff = 0; - $amountdeposit = array(); - $descriptions = array(); - - if (getDolGlobalString('MAIN_DEPOSIT_MULTI_TVA')) { - $amount = $origin->total_ttc * ($origin->deposit_percent / 100); - - $TTotalByTva = array(); - foreach ($origin->lines as &$line) { - if (!empty($line->special_code)) { - continue; - } - $TTotalByTva[$line->tva_tx] += $line->total_ttc; - $descriptions[$line->tva_tx] .= '
  • ' . (!empty($line->product_ref) ? $line->product_ref . ' - ' : ''); - $descriptions[$line->tva_tx] .= (!empty($line->product_label) ? $line->product_label . ' - ' : ''); - $descriptions[$line->tva_tx] .= $langs->trans('Qty') . ' : ' . $line->qty; - $descriptions[$line->tva_tx] .= ' - ' . $langs->trans('TotalHT') . ' : ' . price($line->total_ht) . '
  • '; - } - - foreach ($TTotalByTva as $tva => &$total) { - $coef = $total / $origin->total_ttc; // Calc coef - $am = $amount * $coef; - $amount_ttc_diff += $am; - $amountdeposit[$tva] += $am / (1 + $tva / 100); // Convert into HT for the addline - } - } else { - $totalamount = 0; - $lines = $origin->lines; - $numlines = count($lines); - for ($i = 0; $i < $numlines; $i++) { - if (empty($lines[$i]->qty)) { - continue; // We discard qty=0, it is an option - } - if (!empty($lines[$i]->special_code)) { - continue; // We discard special_code (frais port, ecotaxe, option, ...) - } - - $totalamount += $lines[$i]->total_ht; // Fixme : is it not for the customer ? Shouldn't we take total_ttc ? - $tva_tx = $lines[$i]->tva_tx; - $amountdeposit[$tva_tx] += ($lines[$i]->total_ht * $origin->deposit_percent) / 100; - $descriptions[$tva_tx] .= '
  • ' . (!empty($lines[$i]->product_ref) ? $lines[$i]->product_ref . ' - ' : ''); - $descriptions[$tva_tx] .= (!empty($lines[$i]->product_label) ? $lines[$i]->product_label . ' - ' : ''); - $descriptions[$tva_tx] .= $langs->trans('Qty') . ' : ' . $lines[$i]->qty; - $descriptions[$tva_tx] .= ' - ' . $langs->trans('TotalHT') . ' : ' . price($lines[$i]->total_ht) . '
  • '; - } - - if ($totalamount == 0) { - $amountdeposit[0] = 0; - } - - $amount_ttc_diff = $amountdeposit[0]; - } - - foreach ($amountdeposit as $tva => $amount) { - if (empty($amount)) { - continue; - } - - $descline = '(DEPOSIT) ('. $origin->deposit_percent .'%) - '.$origin->ref; - - // Hidden conf - if (getDolGlobalString('INVOICE_DEPOSIT_VARIABLE_MODE_DETAIL_LINES_IN_DESCRIPTION') && !empty($descriptions[$tva])) { - $descline .= '
      ' . $descriptions[$tva] . '
    '; - } - - $addlineResult = $deposit->addline( - $descline, - $amount, // subprice - 1, // quantity - $tva, // vat rate - 0, // localtax1_tx - 0, // localtax2_tx - (!getDolGlobalString('INVOICE_PRODUCTID_DEPOSIT') ? 0 : $conf->global->INVOICE_PRODUCTID_DEPOSIT), // fk_product - 0, // remise_percent - 0, // date_start - 0, // date_end - 0, - 0, // info_bits - 0, - 'HT', - 0, - 0, // product_type - 1, - 0, // special_code - $deposit->origin, - 0, - 0, - 0, - 0 - //,$langs->trans('Deposit') //Deprecated - ); - - if ($addlineResult < 0) { - $origin->db->rollback(); - $origin->error = $deposit->error; - $origin->errors = $deposit->errors; - return null; - } - } - - $diff = $deposit->total_ttc - $amount_ttc_diff; - - if (getDolGlobalString('MAIN_DEPOSIT_MULTI_TVA') && $diff != 0) { - $deposit->fetch_lines(); - $subprice_diff = $deposit->lines[0]->subprice - $diff / (1 + $deposit->lines[0]->tva_tx / 100); - - $updatelineResult = $deposit->updateline( - $deposit->lines[0]->id, - $deposit->lines[0]->desc, - $subprice_diff, - $deposit->lines[0]->qty, - $deposit->lines[0]->remise_percent, - $deposit->lines[0]->date_start, - $deposit->lines[0]->date_end, - $deposit->lines[0]->tva_tx, - 0, - 0, - 'HT', - $deposit->lines[0]->info_bits, - $deposit->lines[0]->product_type, - 0, - 0, - 0, - $deposit->lines[0]->pa_ht, - $deposit->lines[0]->label, - 0, - array(), - 100 - ); - - if ($updatelineResult < 0) { - $origin->db->rollback(); - $origin->error = $deposit->error; - $origin->errors = $deposit->errors; - return null; - } - } - - $hookmanager->initHooks(array('invoicedao')); - - $parameters = array('objFrom' => $origin); - $reshook = $hookmanager->executeHooks('createFrom', $parameters, $deposit, $action); // Note that $action and $object may have been - // modified by hook - if ($reshook < 0) { - $origin->db->rollback(); - $origin->error = $hookmanager->error; - $origin->errors = $hookmanager->errors; - return null; - } - - if (!empty($autoValidateDeposit)) { - $validateReturn = $deposit->validate($user, '', 0, $notrigger); - - if ($validateReturn < 0) { - $origin->db->rollback(); - $origin->error = $deposit->error; - $origin->errors = $deposit->errors; - return null; - } - } - - unset($deposit->context['createdepositfromorigin']); - - $origin->db->commit(); - - return $deposit; - } - - /** - * getTooltipContentArray - * - * @param array $params ex option, infologin - * @since v18 - * @return array - */ - public function getTooltipContentArray($params) - { - global $conf, $langs, $mysoc, $user; - - $langs->load('bills'); - - $datas = []; - $moretitle = $params['moretitle'] ?? ''; - $picto = $this->picto; - if ($this->type == self::TYPE_REPLACEMENT) { - $picto .= 'r'; // Replacement invoice - } - if ($this->type == self::TYPE_CREDIT_NOTE) { - $picto .= 'a'; // Credit note - } - if ($this->type == self::TYPE_DEPOSIT) { - $picto .= 'd'; // Deposit invoice - } - - if ($user->hasRight("facture", "read")) { - $datas['picto'] = img_picto('', $picto).' '.$langs->trans("Invoice").''; - - $datas['picto'] .= ' '.$this->getLibType(1); - - // Complete datas - if (!empty($params['fromajaxtooltip']) && !isset($this->alreadypaid)) { - // Load the alreadypaid field - $this->alreadypaid = $this->getSommePaiement(0); - } - if (isset($this->status) && isset($this->alreadypaid)) { - $datas['picto'] .= ' '.$this->getLibStatut(5, $this->alreadypaid); - } - if ($moretitle) { - $datas['picto'] .= ' - '.$moretitle; - } - if (!empty($this->ref)) { - $datas['ref'] = '
    '.$langs->trans('Ref').': '.$this->ref; - } - if (!empty($this->ref_customer)) { - $datas['refcustomer'] = '
    '.$langs->trans('RefCustomer').': '.$this->ref_customer; - } - if (!empty($this->date)) { - $datas['date'] = '
    '.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); - } - if (!empty($this->total_ht)) { - $datas['amountht'] = '
    '.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_tva)) { - $datas['amountvat'] = '
    '.$langs->trans('AmountVAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->revenuestamp) && $this->revenuestamp != 0) { - $datas['amountrevenustamp'] = '
    '.$langs->trans('RevenueStamp').': '.price($this->revenuestamp, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_localtax1) && $this->total_localtax1 != 0) { - // We keep test != 0 because $this->total_localtax1 can be '0.00000000' - $datas['amountlt1'] = '
    '.$langs->transcountry('AmountLT1', $mysoc->country_code).': '.price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_localtax2) && $this->total_localtax2 != 0) { - $datas['amountlt2'] = '
    '.$langs->transcountry('AmountLT2', $mysoc->country_code).': '.price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency); - } - if (!empty($this->total_ttc)) { - $datas['amountttc'] = '
    '.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); - } - } - - return $datas; + } + else return -1; + } + else return -1; @@ -1984,4 +1384,4 @@ - * @param int $notooltip 1=Disable tooltip - * @param int $addlinktonotes 1=Add link to notes - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @param string $target Target of link ('', '_self', '_blank', '_parent', '_backoffice', ...) + * @param int $notooltip 1=Disable tooltip + * @param int $addlinktonotes 1=Add link to notes + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @param string $target Target of link ('', '_self', '_blank', '_parent', '_backoffice', ...) @@ -1990 +1390 @@ - public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = 0, $addlinktonotes = 0, $save_lastsearch_value = -1, $target = '') + public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = 0, $addlinktonotes = 0, $save_lastsearch_value = -1, $target = '') @@ -1994,3 +1394 @@ - if (!empty($conf->dol_no_mouse_hover)) { - $notooltip = 1; // Force disable tooltips - } + if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips @@ -2000,11 +1398,8 @@ - if ($option == 'withdraw') { - $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id; - } else { - $url = DOL_URL_ROOT.'/compta/facture/card.php?facid='.$this->id; - } - - if (!$user->hasRight("facture", "read")) { - $option = 'nolink'; - } - - if ($option !== 'nolink') { + if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id; + else $url = DOL_URL_ROOT.'/compta/facture/card.php?facid='.$this->id; + + if (!$user->rights->facture->lire) + $option = 'nolink'; + + if ($option !== 'nolink') + { @@ -2013,11 +1408,5 @@ - if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { - $add_save_lastsearch_values = 1; - } - if ($add_save_lastsearch_values) { - $url .= '&save_lastsearch_values=1'; - } - } - - if ($short) { - return $url; - } + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; + if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; + } + + if ($short) return $url; @@ -2026,24 +1415,32 @@ - if ($this->type == self::TYPE_REPLACEMENT) { - $picto .= 'r'; // Replacement invoice - } - if ($this->type == self::TYPE_CREDIT_NOTE) { - $picto .= 'a'; // Credit note - } - if ($this->type == self::TYPE_DEPOSIT) { - $picto .= 'd'; // Deposit invoice - } - $params = [ - 'id' => $this->id, - 'objecttype' => $this->element, - 'moretitle' => $moretitle, - 'option' => $option, - ]; - $classfortooltip = 'classfortooltip'; - $dataparams = ''; - if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { - $classfortooltip = 'classforajaxtooltip'; - $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"'; - $label = ''; - } else { - $label = implode($this->getTooltipContentArray($params)); - } + if ($this->type == self::TYPE_REPLACEMENT) $picto .= 'r'; // Replacement invoice + if ($this->type == self::TYPE_CREDIT_NOTE) $picto .= 'a'; // Credit note + if ($this->type == self::TYPE_DEPOSIT) $picto .= 'd'; // Deposit invoice + $label = ''; + + if ($user->rights->facture->lire) { + $label = ''.$langs->trans("Invoice").''; + if ($this->type == self::TYPE_REPLACEMENT) $label = ''.$langs->transnoentitiesnoconv("ReplacementInvoice").''; + if ($this->type == self::TYPE_CREDIT_NOTE) $label = ''.$langs->transnoentitiesnoconv("CreditNote").''; + if ($this->type == self::TYPE_DEPOSIT) $label = ''.$langs->transnoentitiesnoconv("Deposit").''; + if ($this->type == self::TYPE_SITUATION) $label = ''.$langs->transnoentitiesnoconv("InvoiceSituation").''; + if (!empty($this->ref)) + $label .= '
    '.$langs->trans('Ref').': '.$this->ref; + if (!empty($this->ref_client)) + $label .= '
    '.$langs->trans('RefCustomer').': '.$this->ref_client; + if (!empty($this->date)) + $label .= '
    '.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); + if (!empty($this->total_ht)) + $label .= '
    '.$langs->trans('AmountHT').': '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); + if (!empty($this->total_tva)) + $label .= '
    '.$langs->trans('AmountVAT').': '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); + if (!empty($this->total_localtax1) && $this->total_localtax1 != 0) // We keep test != 0 because $this->total_localtax1 can be '0.00000000' + $label .= '
    '.$langs->transcountry('AmountLT1', $mysoc->country_code).': '.price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency); + if (!empty($this->total_localtax2) && $this->total_localtax2 != 0) + $label .= '
    '.$langs->transcountry('AmountLT2', $mysoc->country_code).': '.price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency); + if (!empty($this->total_ttc)) + $label .= '
    '.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); + if ($moretitle) $label .= ' - '.$moretitle; + if (isset($this->statut) && isset($this->alreadypaid)) { + $label .= '
    '.$langs->trans("Status").": ".$this->getLibStatut(5, $this->alreadypaid); + } + } @@ -2052,11 +1449,13 @@ - if (empty($notooltip) && $user->hasRight("facture", "read")) { - if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) { - $label = $langs->trans("Invoice"); - $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; - } - $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"'); - $linkclose .= $dataparams.' class="'.$classfortooltip.'"'; - } - - $linkstart = ''; + if (empty($notooltip) && $user->rights->facture->lire) + { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label = $langs->trans("Invoice"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip"'; + } + + $linkstart = ''; @@ -2065,4 +1464,4 @@ - if ($option == 'nolink') { - $linkstart = ''; - $linkend = ''; - } + if ($option == 'nolink') { + $linkstart = ''; + $linkend = ''; + } @@ -2071,6 +1470,2 @@ - if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1); - } - if ($withpicto != 2) { - $result .= ($max ? dol_trunc($this->ref, $max) : $this->ref); - } + if ($withpicto) $result .= img_object(($notooltip ? '' : $label), $picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + if ($withpicto != 2) $result .= ($max ?dol_trunc($this->ref, $max) : $this->ref); @@ -2079,23 +1474,15 @@ - if ($addlinktonotes) { - $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private); - if ($txttoshow) { - //$notetoshow = $langs->trans("ViewPrivateNote").':
    '.dol_string_nohtmltag($txttoshow, 1); - $notetoshow = $langs->trans("ViewPrivateNote").':
    '.$txttoshow; - $result .= ' '; - $result .= '
    '; - $result .= img_picto('', 'note'); - $result .= ''; - //$result.=img_picto($langs->trans("ViewNote"),'object_generic'); - //$result.=''; - $result .= ''; - } - } - - global $action, $hookmanager; - $hookmanager->initHooks(array('invoicedao')); - $parameters = array('id'=>$this->id, 'getnomurl' => &$result, 'notooltip' => $notooltip, 'addlinktonotes' => $addlinktonotes, 'save_lastsearch_value'=> $save_lastsearch_value, 'target' => $target); - $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) { - $result = $hookmanager->resPrint; - } else { - $result .= $hookmanager->resPrint; + if ($addlinktonotes) + { + $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private); + if ($txttoshow) + { + //$notetoshow = $langs->trans("ViewPrivateNote").':
    '.dol_string_nohtmltag($txttoshow, 1); + $notetoshow = $langs->trans("ViewPrivateNote").':
    '.$txttoshow; + $result .= ' '; + $result .= ''; + $result .= img_picto('', 'note'); + $result .= ''; + //$result.=img_picto($langs->trans("ViewNote"),'object_generic'); + //$result.=''; + $result .= ''; + } @@ -2114 +1501 @@ - * @param bool $fetch_situation Load also the previous and next situation invoice into $tab_previous_situation_invoice and $tab_next_situation_invoice + * @param bool $fetch_situation Fetch the previous and next situation in $tab_previous_situation_invoice and $tab_next_situation_invoice @@ -2117 +1504 @@ - public function fetch($rowid, $ref = '', $ref_ext = '', $notused = 0, $fetch_situation = false) + public function fetch($rowid, $ref = '', $ref_ext = '', $notused = '', $fetch_situation = false) @@ -2119,6 +1506,7 @@ - if (empty($rowid) && empty($ref) && empty($ref_ext)) { - return -1; - } - - $sql = 'SELECT f.rowid, f.entity, f.ref, f.ref_client, f.ref_ext, f.type, f.subtype, f.fk_soc'; - $sql .= ', f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc, f.revenuestamp'; + global $conf; + + if (empty($rowid) && empty($ref) && empty($ref_ext)) return -1; + + $sql = 'SELECT f.rowid,f.entity,f.ref,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc'; + $sql .= ', f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc, f.revenuestamp'; + $sql .= ', f.remise_percent, f.remise_absolue, f.remise'; @@ -2130 +1518 @@ - $sql .= ', f.note_private, f.note_public, f.fk_statut as status, 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'; + $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.model_pdf, f.last_main_doc'; @@ -2138,4 +1526,4 @@ - $sql .= ', f.fk_incoterms, f.location_incoterms'; - $sql .= ', f.module_source, f.pos_source'; - $sql .= ", i.libelle as label_incoterms"; - $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"; + $sql .= ', f.fk_incoterms, f.location_incoterms'; + $sql .= ', f.module_source, f.pos_source'; + $sql .= ", i.libelle as label_incoterms"; + $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"; @@ -2147,10 +1535,6 @@ - if ($rowid) { - $sql .= " WHERE f.rowid = ".((int) $rowid); - } else { - $sql .= ' WHERE f.entity IN ('.getEntity('invoice').')'; // Don't use entity if you use rowid - if ($ref) { - $sql .= " AND f.ref = '".$this->db->escape($ref)."'"; - } - if ($ref_ext) { - $sql .= " AND f.ref_ext = '".$this->db->escape($ref_ext)."'"; - } + if ($rowid) $sql .= " WHERE f.rowid=".$rowid; + else { + $sql .= ' WHERE f.entity IN ('.getEntity('invoice').')'; // Dont't use entity if you use rowid + if ($ref) $sql .= " AND f.ref='".$this->db->escape($ref)."'"; + if ($ref_ext) $sql .= " AND f.ref_ext='".$this->db->escape($ref_ext)."'"; + if ($notused) $sql .= " AND f.ref_int='".$this->db->escape($notused)."'"; // deprecated @@ -2160,4 +1544,6 @@ - $resql = $this->db->query($sql); - if ($resql) { - if ($this->db->num_rows($resql)) { - $obj = $this->db->fetch_object($resql); + $result = $this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); @@ -2168,3 +1554,2 @@ - $this->ref = $obj->ref; - $this->ref_client = $obj->ref_client; - $this->ref_customer = $obj->ref_client; + $this->ref = $obj->ref; + $this->ref_client = $obj->ref_client; @@ -2171,0 +1557 @@ + $this->ref_int = $obj->ref_int; @@ -2173 +1558,0 @@ - $this->subtype = $obj->subtype; @@ -2176 +1561 @@ - $this->date_creation = $this->db->jdate($obj->datec); + $this->date_creation = $this->db->jdate($obj->datec); @@ -2178,4 +1563,6 @@ - $this->date_modification = $this->db->jdate($obj->datem); - $this->datem = $this->db->jdate($obj->datem); - $this->total_ht = $obj->total_ht; - $this->total_tva = $obj->total_tva; + $this->date_modification = $this->db->jdate($obj->datem); + $this->datem = $this->db->jdate($obj->datem); + $this->remise_percent = $obj->remise_percent; + $this->remise_absolue = $obj->remise_absolue; + $this->total_ht = $obj->total; + $this->total_tva = $obj->tva; @@ -2185,2 +1572,2 @@ - $this->revenuestamp = $obj->revenuestamp; - $this->paye = $obj->paye; + $this->revenuestamp = $obj->revenuestamp; + $this->paye = $obj->paye; @@ -2196,3 +1583 @@ - $this->statut = $obj->status; // deprecated - $this->status = $obj->status; - + $this->statut = $obj->fk_statut; @@ -2213,7 +1598,3 @@ - $this->user_creation_id = $obj->fk_user_author; - $this->user_validation_id = $obj->fk_user_valid; - $this->user_modification_id = $obj->fk_user_modif; - $this->fk_user_author = $obj->fk_user_author; - $this->fk_user_valid = $obj->fk_user_valid; - $this->fk_user_modif = $obj->fk_user_modif; - $this->model_pdf = $obj->model_pdf; + $this->user_author = $obj->fk_user_author; + $this->user_valid = $obj->fk_user_valid; + $this->modelpdf = $obj->model_pdf; @@ -2228 +1609 @@ - $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams, true) : array(); + $this->extraparams = (array) json_decode($obj->extraparams, true); @@ -2235 +1616 @@ - $this->module_source = $obj->module_source; + $this->module_source = $obj->module_source; @@ -2246 +1627,2 @@ - if (($this->type == self::TYPE_SITUATION || ($this->type == self::TYPE_CREDIT_NOTE && $this->situation_cycle_ref > 0)) && $fetch_situation) { + if (($this->type == self::TYPE_SITUATION || ($this->type == self::TYPE_CREDIT_NOTE && $this->situation_cycle_ref > 0)) && $fetch_situation) + { @@ -2250 +1632,3 @@ - // Retrieve all extrafield + if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1; + + // Retreive all extrafield @@ -2258 +1642,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -2262,3 +1646,0 @@ - - $this->db->free($resql); - @@ -2266 +1648,3 @@ - } else { + } + else + { @@ -2268,2 +1652 @@ - - dol_syslog(__METHOD__.$this->error, LOG_WARNING); + dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); @@ -2272,2 +1655,4 @@ - } else { - $this->error = $this->db->lasterror(); + } + else + { + $this->error = $this->db->error(); @@ -2279 +1664 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -2290 +1675,2 @@ - // phpcs:enable + global $langs, $conf; + // phpcs:enable @@ -2294 +1680 @@ - $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,'; + $sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice,'; @@ -2296 +1682 @@ - $sql .= ' l.rang, l.special_code, l.batch, l.fk_warehouse,'; + $sql .= ' l.rang, l.special_code,'; @@ -2301 +1687 @@ - $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc, p.barcode as product_barcode'; + $sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc'; @@ -2304 +1690 @@ - $sql .= ' WHERE l.fk_facture = '.((int) $this->id); + $sql .= ' WHERE l.fk_facture = '.$this->id; @@ -2309 +1695,2 @@ - if ($result) { + if ($result) + { @@ -2312 +1699,2 @@ - while ($i < $num) { + while ($i < $num) + { @@ -2326,2 +1714 @@ - $line->product_label = $objp->product_label; // Label product - $line->product_barcode = $objp->product_barcode; // Barcode number product + $line->product_label = $objp->product_label; // Label product @@ -2332,3 +1719,2 @@ - $line->ref_ext = $objp->ref_ext; // line external ref - - $line->vat_src_code = $objp->vat_src_code; + + $line->vat_src_code = $objp->vat_src_code; @@ -2344,0 +1731,2 @@ + $line->date_start = $this->db->jdate($objp->date_start); + $line->date_end = $this->db->jdate($objp->date_end); @@ -2351 +1738,0 @@ - @@ -2365,3 +1751,0 @@ - $line->batch = $objp->batch; - $line->fk_warehouse = $objp->fk_warehouse; - @@ -2379 +1763 @@ - $line->fetch_optionals(); + $line->fetch_optionals(); @@ -2382,7 +1766,5 @@ - if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) { - $tmpproduct = new Product($this->db); - $tmpproduct->fetch($objp->fk_product); - $tmpproduct->getMultiLangs(); - - $line->multilangs = $tmpproduct->multilangs; - } + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($objp->fk_product) && !empty($loadalsotranslation)) { + $line = new Product($this->db); + $line->fetch($objp->fk_product); + $line->getMultiLangs(); + } @@ -2396 +1778,3 @@ - } else { + } + else + { @@ -2408 +1792 @@ - public function fetchPreviousNextSituationInvoice() + public function fetchPreviousNextSituationInvoice() @@ -2416,2 +1800,2 @@ - $sql .= " WHERE rowid <> ".((int) $this->id); - $sql .= ' AND entity = '.((int) $this->entity); + $sql .= ' WHERE rowid <> '.$this->id; + $sql .= ' AND entity = '.$this->entity; @@ -2423,2 +1807,4 @@ - if ($result && $this->db->num_rows($result) > 0) { - while ($objp = $this->db->fetch_object($result)) { + if ($result && $this->db->num_rows($result) > 0) + { + while ($objp = $this->db->fetch_object($result)) + { @@ -2426,7 +1812,11 @@ - if ($invoice->fetch($objp->rowid) > 0) { - if ($objp->situation_counter < $this->situation_counter - || ($objp->situation_counter == $this->situation_counter && $objp->rowid < $this->id) // This case appear when there are credit notes - ) { - $this->tab_previous_situation_invoice[] = $invoice; - } else { - $this->tab_next_situation_invoice[] = $invoice; + if ($invoice->fetch($objp->rowid) > 0) + { + if ($objp->situation_counter < $this->situation_counter + || ($objp->situation_counter == $this->situation_counter && $objp->rowid < $this->id) // This case appear when there are credit notes + ) + { + $this->tab_previous_situation_invoice[] = $invoice; + } + else + { + $this->tab_next_situation_invoice[] = $invoice; @@ -2444,3 +1834,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function update(User $user, $notrigger = 0) + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = 0) @@ -2447,0 +1838,2 @@ + global $conf; + @@ -2451,42 +1843,12 @@ - if (empty($this->type)) { - $this->type = self::TYPE_STANDARD; - } - if (isset($this->subtype)) { - $this->subtype = trim($this->subtype); - } - if (isset($this->ref)) { - $this->ref = trim($this->ref); - } - if (isset($this->ref_ext)) { - $this->ref_ext = trim($this->ref_ext); - } - 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->model_pdf)) { - $this->model_pdf = trim($this->model_pdf); - } - if (isset($this->import_key)) { - $this->import_key = trim($this->import_key); - } - if (isset($this->retained_warranty)) { - $this->retained_warranty = (float) $this->retained_warranty; - } + if (empty($this->type)) $this->type = self::TYPE_STANDARD; + if (isset($this->ref)) $this->ref = 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); + if (isset($this->retained_warranty)) $this->retained_warranty = floatval($this->retained_warranty); @@ -2501 +1862,0 @@ - $sql .= " ref_ext=".(isset($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null").","; @@ -2503 +1863,0 @@ - $sql .= " subtype=".(isset($this->subtype) ? $this->db->escape($this->subtype) : "null").","; @@ -2511,0 +1872,2 @@ + $sql .= " remise_percent=".(isset($this->remise_percent) ? $this->db->escape($this->remise_percent) : "null").","; + $sql .= " remise_absolue=".(isset($this->remise_absolue) ? $this->db->escape($this->remise_absolue) : "null").","; @@ -2514 +1876 @@ - $sql .= " total_tva=".(isset($this->total_tva) ? $this->total_tva : "null").","; + $sql .= " tva=".(isset($this->total_tva) ? $this->total_tva : "null").","; @@ -2517 +1879 @@ - $sql .= " total_ht=".(isset($this->total_ht) ? $this->total_ht : "null").","; + $sql .= " total=".(isset($this->total_ht) ? $this->total_ht : "null").","; @@ -2520 +1882 @@ - $sql .= " fk_statut=".(isset($this->status) ? $this->db->escape($this->status) : "null").","; + $sql .= " fk_statut=".(isset($this->statut) ? $this->db->escape($this->statut) : "null").","; @@ -2530 +1892 @@ - $sql .= " model_pdf=".(isset($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : "null").","; + $sql .= " model_pdf=".(isset($this->modelpdf) ? "'".$this->db->escape($this->modelpdf)."'" : "null").","; @@ -2537,2 +1899,2 @@ - $sql .= " retained_warranty_fk_cond_reglement=".(isset($this->retained_warranty_fk_cond_reglement) ? intval($this->retained_warranty_fk_cond_reglement) : "null"); - $sql .= " WHERE rowid=".((int) $this->id); + $sql .= " retained_warranty_fk_cond_reglement=".(isset($this->retained_warranty_fk_cond_reglement) ?intval($this->retained_warranty_fk_cond_reglement) : "null"); + $sql .= " WHERE rowid=".$this->id; @@ -2545,5 +1907,5 @@ - $error++; - $this->errors[] = "Error ".$this->db->lasterror(); - } - - if (!$error) { + $error++; $this->errors[] = "Error ".$this->db->lasterror(); + } + + if (!$error) + { @@ -2551 +1913,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -2556 +1919,2 @@ - if (!$error && !$notrigger) { + if (!$error && !$notrigger) + { @@ -2559,3 +1923 @@ - if ($result < 0) { - $error++; - } + if ($result < 0) $error++; @@ -2566,2 +1928,4 @@ - if ($error) { - foreach ($this->errors as $errmsg) { + if ($error) + { + foreach ($this->errors as $errmsg) + { @@ -2573 +1937,3 @@ - } else { + } + else + { @@ -2580 +1946 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -2587 +1953 @@ - public function insert_discount($idremise) + public function insert_discount($idremise) @@ -2589,2 +1955,2 @@ - // phpcs:enable - global $conf, $langs; + // phpcs:enable + global $langs; @@ -2600,2 +1966,4 @@ - if ($result > 0) { - if ($remise->fk_facture) { // Protection against multiple submission + if ($result > 0) + { + if ($remise->fk_facture) // Protection against multiple submission + { @@ -2620,8 +1987,0 @@ - if (getDolGlobalString('MAIN_ADD_LINE_AT_POSITION')) { - $facligne->rang = 1; - $linecount = count($this->lines); - for ($ii = 1; $ii <= $linecount; $ii++) { - $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii+1); - } - } - @@ -2629,7 +1989,8 @@ - if ($remise->fk_facture_source > 0) { - $srcinvoice = new Facture($this->db); - $srcinvoice->fetch($remise->fk_facture_source); - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; // TODO Move this into commonobject - $formmargin = new FormMargin($this->db); - $arraytmp = $formmargin->getMarginInfosArray($srcinvoice, false); - $facligne->pa_ht = $arraytmp['pa_total']; + if ($remise->fk_facture_source > 0) + { + $srcinvoice = new Facture($this->db); + $srcinvoice->fetch($remise->fk_facture_source); + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; // TODO Move this into commonobject + $formmargin = new FormMargin($this->db); + $arraytmp = $formmargin->getMarginInfosArray($srcinvoice, false); + $facligne->pa_ht = $arraytmp['pa_total']; @@ -2648 +2009,2 @@ - if ($lineid > 0) { + if ($lineid > 0) + { @@ -2650 +2012,2 @@ - if ($result > 0) { + if ($result > 0) + { @@ -2653 +2016,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -2661 +2025,3 @@ - } else { + } + else + { @@ -2666 +2032,3 @@ - } else { + } + else + { @@ -2671 +2039,3 @@ - } else { + } + else + { @@ -2677 +2047 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -2683,3 +2053,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function set_ref_client($ref_client, $notrigger = 0) + * @return int <0 if KO, >0 if OK + */ + public function set_ref_client($ref_client, $notrigger = 0) @@ -2687,2 +2057,2 @@ - // phpcs:enable - global $user; + // phpcs:enable + global $user; @@ -2695 +2065 @@ - if (empty($ref_client)) { + if (empty($ref_client)) @@ -2697 +2067 @@ - } else { + else @@ -2699,2 +2069 @@ - } - $sql .= " WHERE rowid = ".((int) $this->id); + $sql .= ' WHERE rowid = '.$this->id; @@ -2704 +2073,2 @@ - if (!$resql) { + if (!$resql) + { @@ -2709 +2079,2 @@ - if (!$error) { + if (!$error) + { @@ -2713 +2084,2 @@ - if (!$notrigger && empty($error)) { + if (!$notrigger && empty($error)) + { @@ -2716,3 +2088 @@ - if ($result < 0) { - $error++; - } + if ($result < 0) $error++; @@ -2722 +2092,2 @@ - if (!$error) { + if (!$error) + { @@ -2727,2 +2098,5 @@ - } else { - foreach ($this->errors as $errmsg) { + } + else + { + foreach ($this->errors as $errmsg) + { @@ -2743,3 +2117,3 @@ - * @return int Return integer <0 if KO, 0=Refused, >0 if OK - */ - public function delete($user, $notrigger = 0, $idwarehouse = -1) + * @return int <0 if KO, 0=Refused, >0 if OK + */ + public function delete($user, $notrigger = 0, $idwarehouse = -1) @@ -2752 +2126 @@ - dol_syslog(get_class($this)."::delete rowid=".$rowid.", ref=".$this->ref.", thirdparty=".(empty($this->thirdparty) ? '' : $this->thirdparty->name), LOG_DEBUG); + dol_syslog(get_class($this)."::delete rowid=".$rowid.", ref=".$this->ref.", thirdparty=".$this->thirdparty->name, LOG_DEBUG); @@ -2757,3 +2131 @@ - if ($result <= 0) { - return 0; - } + if ($result <= 0) return 0; @@ -2765,7 +2137,6 @@ - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('BILL_DELETE', $user); - if ($result < 0) { - $error++; - } - // End call triggers + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('BILL_DELETE', $user); + if ($result < 0) $error++; + // End call triggers @@ -2777 +2148,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -2783 +2155,2 @@ - if (!$error) { + if (!$error) + { @@ -2786,6 +2159,5 @@ - if ($res < 0) { - $error++; - } - } - - if (!$error) { + if ($res < 0) $error++; + } + + if (!$error) + { @@ -2794 +2166 @@ - $sql .= ' WHERE fk_facture_source = '.((int) $rowid); + $sql .= ' WHERE fk_facture_source = '.$rowid; @@ -2798 +2170 @@ - // If invoice has consumed discounts + // If invoice has consumned discounts @@ -2801 +2173,2 @@ - foreach ($this->lines as $key => $invoiceline) { + foreach ($this->lines as $key => $invoiceline) + { @@ -2805,2 +2178,3 @@ - // Consumed discounts are freed - if (count($list_rowid_det)) { + // Consumned discounts are freed + if (count($list_rowid_det)) + { @@ -2809,3 +2183,5 @@ - $sql .= ' WHERE fk_facture_line IN ('.$this->db->sanitize(join(',', $list_rowid_det)).')'; - - if (!$this->db->query($sql)) { + $sql .= ' WHERE fk_facture_line IN ('.join(',', $list_rowid_det).')'; + + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + if (!$this->db->query($sql)) + { @@ -2813 +2188,0 @@ - $this->errors[] = $this->error; @@ -2819,24 +2193,0 @@ - // Remove other links to the deleted invoice - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'eventorganization_conferenceorboothattendee'; - $sql .= ' SET fk_invoice = NULL'; - $sql .= ' WHERE fk_invoice = '.((int) $rowid); - - if (!$this->db->query($sql)) { - $this->error = $this->db->error()." sql=".$sql; - $this->errors[] = $this->error; - $this->db->rollback(); - return -5; - } - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'element_time'; - $sql .= ' SET invoice_id = NULL, invoice_line_id = NULL'; - $sql .= ' WHERE invoice_id = '.((int) $rowid); - - if (!$this->db->query($sql)) { - $this->error = $this->db->error()." sql=".$sql; - $this->errors[] = $this->error; - $this->db->rollback(); - return -5; - } - @@ -2844 +2195,2 @@ - if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_BILL') && $idwarehouse != -1) { + if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && !empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse != -1) + { @@ -2849,2 +2201,4 @@ - for ($i = 0; $i < $num; $i++) { - if ($this->lines[$i]->fk_product > 0) { + for ($i = 0; $i < $num; $i++) + { + if ($this->lines[$i]->fk_product > 0) + { @@ -2853 +2206,0 @@ - $mouvP->setOrigin($this->element, $this->id); @@ -2855,5 +2208,2 @@ - if ($this->type == self::TYPE_CREDIT_NOTE) { - $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceDeleteDolibarr", $this->ref)); - } else { - $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceDeleteDolibarr", $this->ref)); // we use 0 for price, to not change the weighted average value - } + if ($this->type == self::TYPE_CREDIT_NOTE) $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceDeleteDolibarr", $this->ref)); + else $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceDeleteDolibarr", $this->ref)); // we use 0 for price, to not change the weighted average value @@ -2864 +2214 @@ - // Invoice line extrafileds + // Invoice line extrafileds @@ -2867 +2217 @@ - $sqlef = "DELETE FROM ".$ef." WHERE fk_object IN (SELECT rowid FROM ".$main." WHERE fk_facture = ".((int) $rowid).")"; + $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_facture = $rowid)"; @@ -2869,4 +2219,9 @@ - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.((int) $rowid); - - if ($this->db->query($sqlef) && $this->db->query($sql) && $this->delete_linked_contact()) { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.((int) $rowid); + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid; + + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + + if ($this->db->query($sqlef) && $this->db->query($sql) && $this->delete_linked_contact()) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid; + + dol_syslog(get_class($this)."::delete", LOG_DEBUG); @@ -2875,5 +2230,2 @@ - if ($resql) { - // Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive - $this->deleteEcmFiles(0); // Deleting files physically is done later with the dol_delete_dir_recursive - $this->deleteEcmFiles(1); // Deleting files physically is done later with the dol_delete_dir_recursive - + if ($resql) + { @@ -2882 +2234,2 @@ - if ($conf->facture->dir_output && !empty($this->ref)) { + if ($conf->facture->dir_output && !empty($this->ref)) + { @@ -2885 +2238,2 @@ - if (file_exists($file)) { // We must delete all files before deleting directory + if (file_exists($file)) // We must delete all files before deleting directory + { @@ -2888 +2242,2 @@ - if (!dol_delete_file($file, 0, 0, 0, $this)) { // For triggers + if (!dol_delete_file($file, 0, 0, 0, $this)) // For triggers + { @@ -2891 +2245,0 @@ - $this->errors[] = $this->error; @@ -2896,2 +2250,4 @@ - if (file_exists($dir)) { - if (!dol_delete_dir_recursive($dir)) { // For remove dir and meta + if (file_exists($dir)) + { + if (!dol_delete_dir_recursive($dir)) // For remove dir and meta + { @@ -2900 +2255,0 @@ - $this->errors[] = $this->error; @@ -2909 +2264,3 @@ - } else { + } + else + { @@ -2911 +2267,0 @@ - $this->errors[] = $this->error; @@ -2915 +2271,3 @@ - } else { + } + else + { @@ -2917 +2274,0 @@ - $this->errors[] = $this->error; @@ -2921 +2278,3 @@ - } else { + } + else + { @@ -2927 +2286 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -2931,19 +2289,0 @@ - * - * @deprecated - * @see setPaid() - * @param User $user Object user that modify - * @param string $close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple) - * @param string $close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple) - * @return int Return integer <0 if KO, >0 if OK - */ - public function set_paid($user, $close_code = '', $close_note = '') - { - // phpcs:enable - dol_syslog(get_class($this)."::set_paid is deprecated, use setPaid instead", LOG_NOTICE); - return $this->setPaid($user, $close_code, $close_note); - } - - /** - * Tag the invoice as : - * - paid completely (if close_code is not filled) => this->fk_statut=2, this->paye=1 - * - or partially (if close_code filled) + appel trigger BILL_PAYED => this->fk_statut=2, this->paye stay 0 @@ -2954,3 +2294,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function setPaid($user, $close_code = '', $close_note = '') + * @return int <0 if KO, >0 if OK + */ + public function set_paid($user, $close_code = '', $close_note = '') @@ -2957,0 +2298 @@ + // phpcs:enable @@ -2960 +2301,2 @@ - if ($this->paye != 1) { + if ($this->paye != 1) + { @@ -2965 +2307 @@ - dol_syslog(get_class($this)."::setPaid rowid=".((int) $this->id), LOG_DEBUG); + dol_syslog(get_class($this)."::set_paid rowid=".$this->id, LOG_DEBUG); @@ -2969,10 +2311,4 @@ - if (!$close_code) { - $sql .= ', paye=1'; - } - if ($close_code) { - $sql .= ", close_code='".$this->db->escape($close_code)."'"; - } - if ($close_note) { - $sql .= ", close_note='".$this->db->escape($close_note)."'"; - } - $sql .= ', fk_user_closing = '.((int) $user->id); + if (!$close_code) $sql .= ', paye=1'; + if ($close_code) $sql .= ", close_code='".$this->db->escape($close_code)."'"; + if ($close_note) $sql .= ", close_note='".$this->db->escape($close_note)."'"; + $sql .= ', fk_user_closing = '.$user->id; @@ -2980 +2316 @@ - $sql .= " WHERE rowid = ".((int) $this->id); + $sql .= ' WHERE rowid = '.$this->id; @@ -2983,8 +2319,9 @@ - if ($resql) { - // Call trigger - $result = $this->call_trigger('BILL_PAYED', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } else { + if ($resql) + { + // Call trigger + $result = $this->call_trigger('BILL_PAYED', $user); + if ($result < 0) $error++; + // End call triggers + } + else + { @@ -2995 +2332,2 @@ - if (!$error) { + if (!$error) + { @@ -2998 +2336,3 @@ - } else { + } + else + { @@ -3002 +2342,3 @@ - } else { + } + else + { @@ -3008,18 +2350 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Tag la facture comme non payee completement + appel trigger BILL_UNPAYED - * Fonction utilisee quand un paiement prelevement est refuse, - * ou quand une facture annulee et reouverte. - * - * @deprecated - * @see setUnpaid() - * @param User $user Object user that change status - * @return int Return integer <0 if KO, >0 if OK - */ - public function set_unpaid($user) - { - // phpcs:enable - dol_syslog(get_class($this)."::set_unpaid is deprecated, use setUnpaid instead", LOG_NOTICE); - return $this->setUnpaid($user); - } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -3032,3 +2357,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function setUnpaid($user) + * @return int <0 if KO, >0 if OK + */ + public function set_unpaid($user) @@ -3035,0 +2361 @@ + // phpcs:enable @@ -3044,3 +2370,3 @@ - $sql .= " WHERE rowid = ".((int) $this->id); - - dol_syslog(get_class($this)."::setUnpaid", LOG_DEBUG); + $sql .= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_unpaid", LOG_DEBUG); @@ -3048,8 +2374,9 @@ - if ($resql) { - // Call trigger - $result = $this->call_trigger('BILL_UNPAYED', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } else { + if ($resql) + { + // Call trigger + $result = $this->call_trigger('BILL_UNPAYED', $user); + if ($result < 0) $error++; + // End call triggers + } + else + { @@ -3061 +2388,2 @@ - if (!$error) { + if (!$error) + { @@ -3064 +2392,3 @@ - } else { + } + else + { @@ -3071,20 +2401 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never received) + call trigger BILL_CANCEL - * Warning, if option to decrease stock on invoice was set, this function does not change stock (it might be a cancel because - * of no payment even if merchandises were sent). - * - * @deprecated - * @see setCanceled() - * @param User $user Object user making change - * @param string $close_code Code of closing invoice (CLOSECODE_REPLACED, CLOSECODE_...) - * @param string $close_note Comment - * @return int Return integer <0 if KO, >0 if OK - */ - public function set_canceled($user, $close_code = '', $close_note = '') - { - // phpcs:enable - dol_syslog(get_class($this)."::set_canceled is deprecated, use setCanceled instead", LOG_NOTICE); - return $this->setCanceled($user, $close_code, $close_note); - } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -3099,3 +2410,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function setCanceled($user, $close_code = '', $close_note = '') + * @return int <0 if KO, >0 if OK + */ + public function set_canceled($user, $close_code = '', $close_note = '') @@ -3103 +2414,3 @@ - dol_syslog(get_class($this)."::setCanceled rowid=".((int) $this->id), LOG_DEBUG); + // phpcs:enable + + dol_syslog(get_class($this)."::set_canceled rowid=".$this->id, LOG_DEBUG); @@ -3106 +2418,0 @@ - $now = dol_now(); @@ -3110,9 +2422,3 @@ - if ($close_code) { - $sql .= ", close_code='".$this->db->escape($close_code)."'"; - } - if ($close_note) { - $sql .= ", close_note='".$this->db->escape($close_note)."'"; - } - $sql .= ', fk_user_closing = '.((int) $user->id); - $sql .= ", date_closing = '".$this->db->idate($now)."'"; - $sql .= " WHERE rowid = ".((int) $this->id); + if ($close_code) $sql .= ", close_code='".$this->db->escape($close_code)."'"; + if ($close_note) $sql .= ", close_note='".$this->db->escape($close_note)."'"; + $sql .= ' WHERE rowid = '.$this->id; @@ -3121,3 +2427,4 @@ - if ($resql) { - // Bound discounts are deducted from the invoice - // as they have not been used since the invoice is abandoned. + if ($resql) + { + // On desaffecte de la facture les remises liees + // car elles n'ont pas ete utilisees vu que la facture est abandonnee. @@ -3126 +2433 @@ - $sql .= ' WHERE fk_facture = '.((int) $this->id); + $sql .= ' WHERE fk_facture = '.$this->id; @@ -3129,4 +2436,6 @@ - if ($resql) { - // Call trigger - $result = $this->call_trigger('BILL_CANCEL', $user); - if ($result < 0) { + if ($resql) + { + // Call trigger + $result = $this->call_trigger('BILL_CANCEL', $user); + if ($result < 0) + { @@ -3136 +2445 @@ - // End call triggers + // End call triggers @@ -3140 +2449,3 @@ - } else { + } + else + { @@ -3145 +2456,3 @@ - } else { + } + else + { @@ -3158 +2471 @@ - * @param int $idwarehouse Id of warehouse to use for stock decrease if option to decrease on stock is on (0=no decrease) + * @param int $idwarehouse Id of warehouse to use for stock decrease if option to decreasenon stock is on (0=no decrease) @@ -3160,4 +2473,5 @@ - * @param int $batch_rule 0=do not decrement batch, else batch rule to use, 1=take in batches ordered by sellby and eatby dates - * @return int Return integer <0 if KO, 0=Nothing done because invoice is not a draft, >0 if OK - */ - public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0) + * @param int $batch_rule [=0] 0 not decrement batch, else batch rule to use + * 1=take in batches ordered by sellby and eatby dates + * @return int <0 if KO, 0=Nothing done because invoice is not a draft, >0 if OK + */ + public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0) @@ -3165 +2479 @@ - global $conf, $langs, $mysoc; + global $conf, $langs; @@ -3167 +2480,0 @@ - @@ -3176 +2488,0 @@ - $productbatch = new Productbatch($this->db); @@ -3189,2 +2501,3 @@ - if ($this->status != self::STATUS_DRAFT) { - dol_syslog(get_class($this)."::validate Current status is not draft. operation canceled.", LOG_WARNING); + if (!$this->brouillon) + { + dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING); @@ -3193,2 +2506,3 @@ - if (count($this->lines) <= 0) { - $langs->load("errors"); + if (count($this->lines) <= 0) + { + $langs->load("errors"); @@ -3198,2 +2512,3 @@ - if ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('facture', 'creer')) - || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('facture', 'invoice_advance', 'validate'))) { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->creer)) + || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->invoice_advance->validate))) + { @@ -3201 +2516 @@ - dol_syslog(get_class($this)."::validate ".$this->error.' MAIN_USE_ADVANCED_PERMS=' . getDolGlobalString('MAIN_USE_ADVANCED_PERMS'), LOG_ERR); + dol_syslog(get_class($this)."::validate ".$this->error.' MAIN_USE_ADVANCED_PERMS='.$conf->global->MAIN_USE_ADVANCED_PERMS, LOG_ERR); @@ -3204,75 +2518,0 @@ - if ((preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) && // empty should not happened, but when it occurs, the test save life - getDolGlobalString('FAC_FORCE_DATE_VALIDATION') // If option enabled, we force invoice date - ) { - $this->date = dol_now(); - $this->date_lim_reglement = $this->calculate_date_lim_reglement(); - } - if (getDolGlobalString('INVOICE_CHECK_POSTERIOR_DATE')) { - $last_of_type = $this->willBeLastOfSameType(true); - if (!$last_of_type[0]) { - $this->error = $langs->transnoentities("ErrorInvoiceIsNotLastOfSameType", $this->ref, dol_print_date($this->date, 'day'), dol_print_date($last_of_type[1], 'day')); - return -1; - } - } - - // Check for mandatory fields in thirdparty (defined into setup) - if (!empty($this->thirdparty) && is_object($this->thirdparty)) { - $array_to_check = array('IDPROF1', 'IDPROF2', 'IDPROF3', 'IDPROF4', 'IDPROF5', 'IDPROF6', 'EMAIL', 'ACCOUNTANCY_CODE_CUSTOMER'); - foreach ($array_to_check as $key) { - $keymin = strtolower($key); - if (!property_exists($this->thirdparty, $keymin)) { - continue; - } - $vallabel = $this->thirdparty->$keymin; - - $i = (int) preg_replace('/[^0-9]/', '', $key); - if ($i > 0) { - if ($this->thirdparty->isACompany()) { - // Check for mandatory prof id (but only if country is other than ours) - if ($mysoc->country_id > 0 && $this->thirdparty->country_id == $mysoc->country_id) { - $idprof_mandatory = 'SOCIETE_'.$key.'_INVOICE_MANDATORY'; - if (!$vallabel && !empty($conf->global->$idprof_mandatory)) { - $langs->load("errors"); - $this->error = $langs->trans('ErrorProdIdIsMandatory', $langs->transcountry('ProfId'.$i, $this->thirdparty->country_code)).' ('.$langs->trans("ForbiddenBySetupRules").') ['.$langs->trans('Company').' : '.$this->thirdparty->name.']'; - dol_syslog(__METHOD__.' '.$this->error, LOG_ERR); - return -1; - } - } - } - } else { - if ($key == 'EMAIL') { - // Check for mandatory - if (getDolGlobalString('SOCIETE_EMAIL_INVOICE_MANDATORY') && !isValidEMail($this->thirdparty->email)) { - $langs->load("errors"); - $this->error = $langs->trans("ErrorBadEMail", $this->thirdparty->email).' ('.$langs->trans("ForbiddenBySetupRules").') ['.$langs->trans('Company').' : '.$this->thirdparty->name.']'; - dol_syslog(__METHOD__.' '.$this->error, LOG_ERR); - return -1; - } - } - if ($key == 'ACCOUNTANCY_CODE_CUSTOMER') { - // Check for mandatory - if (getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_INVOICE_MANDATORY') && empty($this->thirdparty->code_compta)) { - $langs->load("errors"); - $this->error = $langs->trans("ErrorAccountancyCodeCustomerIsMandatory", $this->thirdparty->name).' ('.$langs->trans("ForbiddenBySetupRules").')'; - dol_syslog(__METHOD__.' '.$this->error, LOG_ERR); - return -1; - } - } - } - } - } - - // Check for mandatory fields in $this - $array_to_check = array('REF_CLIENT'=>'RefCustomer'); - foreach ($array_to_check as $key => $val) { - $keymin = strtolower($key); - $vallabel = $this->$keymin; - - // Check for mandatory - $keymandatory = 'INVOICE_'.$key.'_MANDATORY_FOR_VALIDATION'; - if (!$vallabel && getDolGlobalString($keymandatory)) { - $langs->load("errors"); - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv($val)), null, 'errors'); - } - } @@ -3283,3 +2523,5 @@ - if ($this->type == self::TYPE_REPLACEMENT) { // if this is a replacement invoice - // Check that source invoice is known - if ($this->fk_facture_source <= 0) { + if ($this->type == self::TYPE_REPLACEMENT) // si facture de remplacement + { + // Controle que facture source connue + if ($this->fk_facture_source <= 0) + { @@ -3291 +2533 @@ - // Load source invoice that has been replaced + // Charge la facture source a remplacer @@ -3294 +2536,2 @@ - if ($result <= 0) { + if ($result <= 0) + { @@ -3300 +2543 @@ - // Check that source invoice not already replaced by another one. + // Controle que facture source non deja remplacee par une autre @@ -3302 +2545,2 @@ - if ($idreplacement && $idreplacement != $this->id) { + if ($idreplacement && $idreplacement != $this->id) + { @@ -3310,2 +2554,3 @@ - $result = $facreplaced->setCanceled($user, self::CLOSECODE_REPLACED, ''); - if ($result < 0) { + $result = $facreplaced->set_canceled($user, self::CLOSECODE_REPLACED, ''); + if ($result < 0) + { @@ -3319 +2564,2 @@ - if ($force_number) { + if ($force_number) + { @@ -3321,2 +2567,5 @@ - } elseif (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) { // empty should not happened, but when it occurs, the test save life - if (getDolGlobalString('FAC_FORCE_DATE_VALIDATION')) { // If option enabled, we force invoice date + } + elseif (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life + { + if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date + { @@ -3327 +2576,3 @@ - } else { + } + else + { @@ -3330 +2580,0 @@ - @@ -3333 +2583,2 @@ - if ($num) { + if ($num) + { @@ -3338,2 +2589,3 @@ - $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)."'"; - if (getDolGlobalString('FAC_FORCE_DATE_VALIDATION')) { // If option enabled, we force invoice date + $sql .= " SET ref='".$num."', fk_statut = ".self::STATUS_VALIDATED.", fk_user_valid = ".($user->id > 0 ? $user->id : "null").", date_valid = '".$this->db->idate($now)."'"; + if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date + { @@ -3343 +2595 @@ - $sql .= " WHERE rowid = ".((int) $this->id); + $sql .= ' WHERE rowid = '.$this->id; @@ -3347 +2599,2 @@ - if (!$resql) { + if (!$resql) + { @@ -3352,2 +2605,3 @@ - // We check if the invoice was provisional - if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref))) { + // On verifie si la facture etait une provisoire + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref))) + { @@ -3357 +2611,2 @@ - if (!$error) { + if (!$error) + { @@ -3359,4 +2614,5 @@ - $result = $this->thirdparty->setAsCustomer(); - - // If active we decrement the main product and its components at invoice validation - if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_BILL') && $idwarehouse > 0) { + $result = $this->thirdparty->set_as_client(); + + // Si active on decremente le produit principal et ses composants a la validation de facture + if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && !empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse > 0) + { @@ -3368,2 +2624,4 @@ - for ($i = 0; $i < $cpt; $i++) { - if ($this->lines[$i]->fk_product > 0) { + for ($i = 0; $i < $cpt; $i++) + { + if ($this->lines[$i]->fk_product > 0) + { @@ -3372,5 +2629,0 @@ - $mouvP->setOrigin($this->element, $this->id); - - // TODO If warehouseid has been set into invoice line, we should use this value in priority - // $idwarehouse = $this->lines[$i]->fk_warehouse; - @@ -3400 +2653 @@ - $resBatchList = $productbatch->findAllForProduct($productStatic->id, $idwarehouse, (getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER') ? null : 0), $sortfield, $sortorder); + $resBatchList = Productbatch::findAllForProduct($this->db, $productStatic->id, $idwarehouse, (!empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) ? null : 0), $sortfield, $sortorder); @@ -3417,3 +2670 @@ - if ($batch->qty <= 0) { - continue; // try to decrement only batches have positive quantity first - } + if ($batch->qty <= 0) continue; // try to decrement only batches have positive quantity first @@ -3424,2 +2675,2 @@ - } else { - // not enough (take all in batch) + } // not enough (take all in batch) + else { @@ -3432 +2682,0 @@ - $this->errors = $mouvP->errors; @@ -3438,3 +2688 @@ - if ($product_qty_remain <= 0) { - break; - } + if ($product_qty_remain <= 0) break; @@ -3444 +2692 @@ - if (getDolGlobalInt('STOCK_ALLOW_NEGATIVE_TRANSFER')) { + if ($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) { @@ -3451 +2698,0 @@ - $this->errors = $mouvP->errors; @@ -3470 +2716,0 @@ - $this->errors = $mouvP->errors; @@ -3479,19 +2724,0 @@ - /* - * Set situation_final to 0 if is a credit note and the invoice source is a invoice situation (case when invoice situation is at 100%) - * So we can continue to create new invoice situation - */ - if (!$error && $this->type == self::TYPE_CREDIT_NOTE && $this->fk_facture_source > 0) { - $invoice_situation = new Facture($this->db); - $result = $invoice_situation->fetch($this->fk_facture_source); - if ($result > 0 && $invoice_situation->type == self::TYPE_SITUATION && $invoice_situation->situation_final == 1) { - $invoice_situation->situation_final = 0; - // Disable triggers because module can force situation_final to 1 by triggers (ex: SubTotal) - $result = $invoice_situation->setFinal($user, 1); - } - if ($result < 0) { - $this->error = $invoice_situation->error; - $this->errors = $invoice_situation->errors; - $error++; - } - } - @@ -3499,10 +2726,10 @@ - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('BILL_VALIDATE', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } - - if (!$error) { + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('BILL_VALIDATE', $user); + if ($result < 0) $error++; + // End call triggers + } + + if (!$error) + { @@ -3512 +2739,2 @@ - if (preg_match('/^[\(]?PROV/i', $this->ref)) { + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { @@ -3517,11 +2745 @@ - if (!$resql) { - $error++; - $this->error = $this->db->lasterror(); - } - $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'facture/".$this->db->escape($this->newref)."'"; - $sql .= " WHERE filepath = 'facture/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->error = $this->db->lasterror(); - } + if (!$resql) { $error++; $this->error = $this->db->lasterror(); } @@ -3534 +2752,2 @@ - if (!$error && file_exists($dirsource)) { + if (!$error && file_exists($dirsource)) + { @@ -3537 +2756,2 @@ - if (@rename($dirsource, $dirdest)) { + if (@rename($dirsource, $dirdest)) + { @@ -3539,9 +2759,10 @@ - // Rename docs starting with $oldref with $newref - $listoffiles = dol_dir_list($conf->facture->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); - foreach ($listoffiles as $fileentry) { - $dirsource = $fileentry['name']; - $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); - $dirsource = $fileentry['path'].'/'.$dirsource; - $dirdest = $fileentry['path'].'/'.$dirdest; - @rename($dirsource, $dirdest); - } + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->facture->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) + { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } @@ -3553,2 +2774,4 @@ - if (!$error && !$this->is_last_in_cycle()) { - if (!$this->updatePriceNextInvoice($langs)) { + if (!$error && !$this->is_last_in_cycle()) + { + if (!$this->updatePriceNextInvoice($langs)) + { @@ -3560 +2783,2 @@ - if (!$error) { + if (!$error) + { @@ -3562,2 +2786,3 @@ - $this->statut = self::STATUS_VALIDATED; // deprecated - $this->status = self::STATUS_VALIDATED; + $this->ref = $num; + $this->statut = self::STATUS_VALIDATED; + $this->brouillon = 0; @@ -3567,18 +2792,18 @@ - if (getDolGlobalString('INVOICE_USE_SITUATION')) { - $final = true; - $nboflines = count($this->lines); - while (($i < $nboflines) && $final) { - $final = ($this->lines[$i]->situation_percent == 100); - $i++; - } - - if (empty($final)) { - $this->situation_final = 0; - } else { - $this->situation_final = 1; - } - - $this->setFinal($user); - } - } - } else { + if (!empty($conf->global->INVOICE_USE_SITUATION)) + { + $final = true; + $nboflines = count($this->lines); + while (($i < $nboflines) && $final) { + $final = ($this->lines[$i]->situation_percent == 100); + $i++; + } + + if (empty($final)) $this->situation_final = 0; + else $this->situation_final = 1; + + $this->setFinal($user); + } + } + } + else + { @@ -3588 +2813,2 @@ - if (!$error) { + if (!$error) + { @@ -3591 +2817,3 @@ - } else { + } + else + { @@ -3601,3 +2829,3 @@ - * @return bool false if KO, true if OK - */ - public function updatePriceNextInvoice(&$langs) + * @return bool false if KO, true if OK + */ + public function updatePriceNextInvoice(&$langs) @@ -3605 +2833,2 @@ - foreach ($this->tab_next_situation_invoice as $next_invoice) { + foreach ($this->tab_next_situation_invoice as $next_invoice) + { @@ -3608 +2837,2 @@ - if ($next_invoice->status == self::STATUS_DRAFT && $is_last != 1) { + if ($next_invoice->statut == self::STATUS_DRAFT && $is_last != 1) + { @@ -3613 +2843,3 @@ - foreach ($next_invoice->lines as $line) { + $next_invoice->brouillon = 1; + foreach ($next_invoice->lines as $line) + { @@ -3615,21 +2847,3 @@ - $line->id, - $line->desc, - $line->subprice, - $line->qty, - $line->remise_percent, - $line->date_start, - $line->date_end, - $line->tva_tx, - $line->localtax1_tx, - $line->localtax2_tx, - 'HT', - $line->info_bits, - $line->product_type, - $line->fk_parent_line, - 0, - $line->fk_fournprice, - $line->pa_ht, - $line->label, - $line->special_code, - $line->array_options, - $line->situation_percent, + $line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, + $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, + $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, @@ -3639 +2853,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -3656 +2871 @@ - * @return int Return integer <0 if KO, >0 if OK + * @return int <0 if KO, >0 if OK @@ -3660 +2875 @@ - // phpcs:enable + // phpcs:enable @@ -3665 +2880,2 @@ - if ($this->status == self::STATUS_DRAFT) { + if ($this->statut == self::STATUS_DRAFT) + { @@ -3676 +2892 @@ - $sql .= " WHERE rowid = ".((int) $this->id); + $sql .= " WHERE rowid = ".$this->id; @@ -3679,2 +2895,4 @@ - if ($result) { - if (!$error) { + if ($result) + { + if (!$error) + { @@ -3685 +2903,2 @@ - if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_BILL')) { + if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && !empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL)) + { @@ -3690,2 +2909,4 @@ - for ($i = 0; $i < $num; $i++) { - if ($this->lines[$i]->fk_product > 0) { + for ($i = 0; $i < $num; $i++) + { + if ($this->lines[$i]->fk_product > 0) + { @@ -3694 +2914,0 @@ - $mouvP->setOrigin($this->element, $this->id); @@ -3696,5 +2916,2 @@ - if ($this->type == self::TYPE_CREDIT_NOTE) { - $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref)); - } else { - $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref)); // we use 0 for price, to not change the weighted average value - } + if ($this->type == self::TYPE_CREDIT_NOTE) $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref)); + else $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref)); // we use 0 for price, to not change the weighted average value @@ -3705,4 +2922,5 @@ - if ($error == 0) { - $old_statut = $this->status; - $this->statut = self::STATUS_DRAFT; // deprecated - $this->status = self::STATUS_DRAFT; + if ($error == 0) + { + $old_statut = $this->statut; + $this->brouillon = 1; + $this->statut = self::STATUS_DRAFT; @@ -3712 +2930,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -3714,2 +2933,2 @@ - $this->statut = $old_statut; // deprecated - $this->status = $old_statut; + $this->statut = $old_statut; + $this->brouillon = 0; @@ -3723 +2942,2 @@ - if ($error == 0) { + if ($error == 0) + { @@ -3726 +2946,3 @@ - } else { + } + else + { @@ -3730 +2952,3 @@ - } else { + } + else + { @@ -3740 +2963,0 @@ - * Note: ->thirdparty must be defined. @@ -3754,2 +2977,2 @@ - * @param int|string $date_start Date start of service - * @param int|string $date_end Date end of service + * @param int $date_start Date start of service + * @param int $date_end Date end of service @@ -3762 +2985 @@ - * @param int $rang Position of line (-1 means last value + 1) + * @param int $rang Position of line @@ -3774,38 +2997,34 @@ - * @param double $pu_ht_devise Unit price in foreign currency - * @param string $ref_ext External reference of the line - * @param int $noupdateafterinsertline No update after insert of line - * @return int Return integer <0 if KO, Id of line if OK - */ - public function 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 = 0, - $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 = array(), - $situation_percent = 100, - $fk_prev_id = 0, - $fk_unit = null, - $pu_ht_devise = 0, - $ref_ext = '', - $noupdateafterinsertline = 0 - ) { + * @param double $pu_ht_devise Unit price in currency + * @return int <0 if KO, Id of line if OK + */ + public function 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 = self::TYPE_STANDARD, + $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 + ) { @@ -3820,3 +3039,4 @@ - 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); - - if ($this->status == self::STATUS_DRAFT) { + dol_syslog(get_class($this)."::addline id=$this->id,desc=$desc,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", LOG_DEBUG); + + if ($this->statut == self::STATUS_DRAFT) + { @@ -3826,36 +3046,11 @@ - if (empty($remise_percent)) { - $remise_percent = 0; - } - if (empty($qty)) { - $qty = 0; - } - if (empty($info_bits)) { - $info_bits = 0; - } - if (empty($rang)) { - $rang = 0; - } - if (empty($ventil)) { - $ventil = 0; - } - if (empty($txtva)) { - $txtva = 0; - } - if (empty($txlocaltax1)) { - $txlocaltax1 = 0; - } - if (empty($txlocaltax2)) { - $txlocaltax2 = 0; - } - if (empty($fk_parent_line) || $fk_parent_line < 0) { - $fk_parent_line = 0; - } - if (empty($fk_prev_id)) { - $fk_prev_id = 'null'; - } - if (!isset($situation_percent) || $situation_percent > 100 || (string) $situation_percent == '') { - $situation_percent = 100; - } - if (empty($ref_ext)) { - $ref_ext = ''; - } + if (empty($remise_percent)) $remise_percent = 0; + if (empty($qty)) $qty = 0; + if (empty($info_bits)) $info_bits = 0; + if (empty($rang)) $rang = 0; + if (empty($ventil)) $ventil = 0; + if (empty($txtva)) $txtva = 0; + if (empty($txlocaltax1)) $txlocaltax1 = 0; + if (empty($txlocaltax2)) $txlocaltax2 = 0; + if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line = 0; + if (empty($fk_prev_id)) $fk_prev_id = 'null'; + if (!isset($situation_percent) || $situation_percent > 100 || (string) $situation_percent == '') $situation_percent = 100; @@ -3875 +3070,2 @@ - if ($price_base_type == 'HT') { + if ($price_base_type == 'HT') + { @@ -3877 +3073,3 @@ - } else { + } + else + { @@ -3882,3 +3080 @@ - if ($type < 0) { - return -1; - } + if ($type < 0) return -1; @@ -3895 +3091,2 @@ - if (!empty($fk_product) && $fk_product > 0) { + if (!empty($fk_product)) + { @@ -3900,3 +3097,3 @@ - if (getDolGlobalString('STOCK_MUST_BE_ENOUGH_FOR_INVOICE') && $product_type == 0 && $product->stock_reel < $qty) { - $langs->load("errors"); - $this->error = $langs->trans('ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref); + if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) { + $langs->load("errors"); + $this->error = $langs->trans('ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref); @@ -3913 +3110,2 @@ - if (preg_match('/\((.*)\)/', $txtva, $reg)) { + if (preg_match('/\((.*)\)/', $txtva, $reg)) + { @@ -3934,2 +3132,2 @@ - $multicurrency_total_tva = $tabprice[17]; - $multicurrency_total_ttc = $tabprice[18]; + $multicurrency_total_tva = $tabprice[17]; + $multicurrency_total_ttc = $tabprice[18]; @@ -3940 +3138,2 @@ - if ($ranktouse == -1) { + if ($ranktouse == -1) + { @@ -3953,4 +3152,3 @@ - $this->line->ref_ext = $ref_ext; - - $this->line->qty = ($this->type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty); // For credit note, quantity is always positive and unit price negative - $this->line->subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise + + $this->line->qty = ($this->type == self::TYPE_CREDIT_NOTE ?abs($qty) : $qty); // For credit note, quantity is always positive and unit price negative + $this->line->subprice = ($this->type == self::TYPE_CREDIT_NOTE ?-abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise @@ -3962,8 +3160,8 @@ - $this->line->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; - $this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; - - $this->line->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative - $this->line->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc); // For credit note and if qty is negative, total is negative - $this->line->total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_tva) : $total_tva); // For credit note and if qty is negative, total is negative - $this->line->total_localtax1 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax1) : $total_localtax1); // For credit note and if qty is negative, total is negative - $this->line->total_localtax2 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax2) : $total_localtax2); // For credit note and if qty is negative, total is negative + $this->line->localtax1_type = $localtaxes_type[0]; + $this->line->localtax2_type = $localtaxes_type[2]; + + $this->line->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative + $this->line->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ttc) : $total_ttc); // For credit note and if qty is negative, total is negative + $this->line->total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_tva) : $total_tva); // For credit note and if qty is negative, total is negative + $this->line->total_localtax1 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_localtax1) : $total_localtax1); // For credit note and if qty is negative, total is negative + $this->line->total_localtax2 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_localtax2) : $total_localtax2); // For credit note and if qty is negative, total is negative @@ -3996,5 +3194,4 @@ - $this->line->multicurrency_subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht_devise) : $pu_ht_devise); // For credit note, unit price always negative, always positive otherwise - - $this->line->multicurrency_total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ht) : $multicurrency_total_ht); // For credit note and if qty is negative, total is negative - $this->line->multicurrency_total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_tva) : $multicurrency_total_tva); // For credit note and if qty is negative, total is negative - $this->line->multicurrency_total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ttc) : $multicurrency_total_ttc); // For credit note and if qty is negative, total is negative + $this->line->multicurrency_subprice = $pu_ht_devise; + $this->line->multicurrency_total_ht = $multicurrency_total_ht; + $this->line->multicurrency_total_tva = $multicurrency_total_tva; + $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; @@ -4007 +3204,2 @@ - if ($result > 0) { + if ($result > 0) + { @@ -4009,8 +3207 @@ - if (!empty($fk_parent_line)) { - $this->line_order(true, 'DESC'); - } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) { // Update all rank of all other lines - $linecount = count($this->lines); - for ($ii = $ranktouse; $ii <= $linecount; $ii++) { - $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii + 1); - } - } + if (!empty($fk_parent_line)) $this->line_order(true, 'DESC'); @@ -4019,5 +3210,4 @@ - if (empty($noupdateafterinsertline)) { - $result = $this->update_price(1, 'auto', 0, $mysoc); // The addline method is designed to add line from user input so total calculation with update_price must be done using 'auto' mode. - } - - if ($result > 0) { + $result = $this->update_price(1, 'auto', 0, $mysoc); // The addline method is designed to add line from user input so total calculation with update_price must be done using 'auto' mode. + + if ($result > 0) + { @@ -4026 +3216,3 @@ - } else { + } + else + { @@ -4031 +3223,3 @@ - } else { + } + else + { @@ -4033 +3226,0 @@ - $this->errors = $this->line->errors; @@ -4037,3 +3230,4 @@ - } else { - $this->errors[] = 'status of invoice must be Draft to allow use of ->addline()'; - dol_syslog(get_class($this)."::addline status of invoice must be Draft to allow use of ->addline()", LOG_ERR); + } + else + { + dol_syslog(get_class($this)."::addline status of order must be Draft to allow use of ->addline()", LOG_ERR); @@ -4066 +3260 @@ - * @param array $array_options extrafields array + * @param array $array_options extrafields array @@ -4071,5 +3265,3 @@ - * @param string $ref_ext External reference of the line - * @param integer $rang rank of line - * @return int Return integer < 0 if KO, > 0 if OK - */ - 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 = array(), $situation_percent = 100, $fk_unit = null, $pu_ht_devise = 0, $notrigger = 0, $ref_ext = '', $rang = 0) + * @return int < 0 if KO, > 0 if OK + */ + 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) @@ -4089,6 +3281,7 @@ - if ($this->status == self::STATUS_DRAFT) { - if (!$this->is_last_in_cycle() && empty($this->error)) { - if (!$this->checkProgressLine($rowid, $situation_percent)) { - if (!$this->error) { - $this->error = $langs->trans('invoiceLineProgressError'); - } + if ($this->brouillon) + { + if (!$this->is_last_in_cycle() && empty($this->error)) + { + if (!$this->checkProgressLine($rowid, $situation_percent)) + { + if (!$this->error) $this->error = $langs->trans('invoiceLineProgressError'); @@ -4108,15 +3301,4 @@ - if (empty($qty)) { - $qty = 0; - } - if (empty($fk_parent_line) || $fk_parent_line < 0) { - $fk_parent_line = 0; - } - if (empty($special_code) || $special_code == 3) { - $special_code = 0; - } - if (!isset($situation_percent) || $situation_percent > 100 || (string) $situation_percent == '') { - $situation_percent = 100; - } - if (empty($ref_ext)) { - $ref_ext = ''; - } + if (empty($qty)) $qty = 0; + if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line = 0; + if (empty($special_code) || $special_code == 3) $special_code = 0; + if (!isset($situation_percent) || $situation_percent > 100 || (string) $situation_percent == '') $situation_percent = 100; @@ -4127,5 +3309,3 @@ - $pu_ht_devise = price2num($pu_ht_devise); - $pa_ht = price2num($pa_ht); - if (!preg_match('/\((.*)\)/', $txtva)) { - $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' - } + $pu_ht_devise = price2num($pu_ht_devise); + $pa_ht = price2num($pa_ht); + $txtva = price2num($txtva); @@ -4136,3 +3316 @@ - if ($type < 0) { - return -1; - } + if ($type < 0) return -1; @@ -4147,6 +3325,6 @@ - $reg = array(); - $vat_src_code = ''; - if (preg_match('/\((.*)\)/', $txtva, $reg)) { - $vat_src_code = $reg[1]; - $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. - } + $vat_src_code = ''; + if (preg_match('/\((.*)\)/', $txtva, $reg)) + { + $vat_src_code = $reg[1]; + $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. + } @@ -4167,2 +3345,2 @@ - $multicurrency_total_tva = $tabprice[17]; - $multicurrency_total_ttc = $tabprice[18]; + $multicurrency_total_tva = $tabprice[17]; + $multicurrency_total_ttc = $tabprice[18]; @@ -4174,3 +3352,4 @@ - if ($remise_percent > 0) { - $remise = round(((float) $pu * (float) $remise_percent / 100), 2); - $price = ((float) $pu - $remise); + if ($remise_percent > 0) + { + $remise = round(($pu * $remise_percent / 100), 2); + $price = ($pu - $remise); @@ -4185 +3364,2 @@ - if (!empty($line->fk_product)) { + if (!empty($line->fk_product)) + { @@ -4190,3 +3370,3 @@ - if (getDolGlobalString('STOCK_MUST_BE_ENOUGH_FOR_INVOICE') && $product_type == 0 && $product->stock_reel < $qty) { - $langs->load("errors"); - $this->error = $langs->trans('ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref); + if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) { + $langs->load("errors"); + $this->error = $langs->trans('ErrorStockIsNotEnoughToAddProductOnInvoice', $product->ref); @@ -4202,2 +3382 @@ - $this->line->context = $this->context; - $this->line->rang = $rang; + $this->line->context = $this->context; @@ -4206 +3385,2 @@ - if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) { + if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) + { @@ -4212,2 +3392,2 @@ - $this->line->rowid = $rowid; - $this->line->label = $label; + $this->line->rowid = $rowid; + $this->line->label = $label; @@ -4215,2 +3395 @@ - $this->line->ref_ext = $ref_ext; - $this->line->qty = ($this->type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty); // For credit note, quantity is always positive and unit price negative + $this->line->qty = ($this->type == self::TYPE_CREDIT_NOTE ?abs($qty) : $qty); // For credit note, quantity is always positive and unit price negative @@ -4222,2 +3401,2 @@ - $this->line->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; - $this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; + $this->line->localtax1_type = $localtaxes_type[0]; + $this->line->localtax2_type = $localtaxes_type[2]; @@ -4226 +3405 @@ - $this->line->subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise + $this->line->subprice = ($this->type == 2 ?-abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise @@ -4229,2 +3408,2 @@ - $this->line->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative - $this->line->total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_tva) : $total_tva); + $this->line->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative + $this->line->total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_tva) : $total_tva); @@ -4233 +3412 @@ - $this->line->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc); + $this->line->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ttc) : $total_ttc); @@ -4246,4 +3425,4 @@ - $this->line->multicurrency_subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht_devise) : $pu_ht_devise); // For credit note, unit price always negative, always positive otherwise - $this->line->multicurrency_total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ht) : $multicurrency_total_ht); // For credit note and if qty is negative, total is negative - $this->line->multicurrency_total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_tva) : $multicurrency_total_tva); - $this->line->multicurrency_total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ttc) : $multicurrency_total_ttc); + $this->line->multicurrency_subprice = $pu_ht_devise; + $this->line->multicurrency_total_ht = $multicurrency_total_ht; + $this->line->multicurrency_total_tva = $multicurrency_total_tva; + $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; @@ -4259 +3438,2 @@ - if ($result > 0) { + if ($result > 0) + { @@ -4261,3 +3441 @@ - if (!empty($fk_parent_line)) { - $this->line_order(true, 'DESC'); - } + if (!empty($fk_parent_line)) $this->line_order(true, 'DESC'); @@ -4266 +3444 @@ - $this->update_price(1, 'auto'); + $this->update_price(1); @@ -4269,2 +3447,4 @@ - } else { - $this->error = $this->line->error; + } + else + { + $this->error = $this->line->error; @@ -4274 +3454,3 @@ - } else { + } + else + { @@ -4285,3 +3467,3 @@ - * @return bool false if KO, true if OK - */ - public function checkProgressLine($idline, $situation_percent) + * @return false if KO, true if OK + */ + public function checkProgressLine($idline, $situation_percent) @@ -4291 +3473,2 @@ - WHERE fd.fk_prev_id = '.((int) $idline).' AND f.fk_statut <> 0'; + WHERE fd.fk_prev_id = '.$idline.' + AND f.fk_statut <> 0'; @@ -4294 +3477,2 @@ - if (!$result) { + if (!$result) + { @@ -4301,5 +3485,2 @@ - if ($obj === null) { - return true; - } else { - return ($situation_percent < $obj->situation_percent); - } + if ($obj === null) return true; + else return $situation_percent < $obj->situation_percent; @@ -4308 +3489 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -4312,3 +3493,2 @@ - * @param FactureLigne $line Invoice line - * @param int $percent Percentage - * @param boolean $update_price Update object price + * @param FactureLigne $line Invoice line + * @param int $percent Percentage @@ -4317 +3497 @@ - public function update_percent($line, $percent, $update_price = true) + public function update_percent($line, $percent) @@ -4319,7 +3499,8 @@ - // phpcs:enable - global $mysoc, $user; - - // Progress should never be changed for discount lines - if (($line->info_bits & 2) == 2) { - return; - } + // phpcs:enable + global $mysoc, $user; + + // Progress should never be changed for discount lines + if (($line->info_bits & 2) == 2) + { + return; + } @@ -4330,3 +3511 @@ - if ($percent > 100) { - $percent = 100; - } + if ($percent > 100) $percent = 100; @@ -4344,5 +3523 @@ - - // sometimes it is better to not update price for each line, ie when updating situation on all lines - if ($update_price) { - $this->update_price(1); - } + $this->update_price(1); @@ -4355,4 +3530,3 @@ - * @param int $id Id of object (for a check) - * @return int Return integer <0 if KO, >0 if OK - */ - public function deleteline($rowid, $id = 0) + * @return int <0 if KO, >0 if OK + */ + public function deleteline($rowid) @@ -4360,5 +3534,6 @@ - global $user; - - dol_syslog(get_class($this)."::deleteline rowid=".((int) $rowid), LOG_DEBUG); - - if ($this->status != self::STATUS_DRAFT) { + global $user; + + dol_syslog(get_class($this)."::deleteline rowid=".$rowid, LOG_DEBUG); + + if (!$this->brouillon) + { @@ -4368,0 +3544,16 @@ + $this->db->begin(); + + // Libere remise liee a ligne de facture + $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql .= ' SET fk_facture_line = NULL'; + $sql .= ' WHERE fk_facture_line = '.$rowid; + + dol_syslog(get_class($this)."::deleteline", LOG_DEBUG); + $result = $this->db->query($sql); + if (!$result) + { + $this->error = $this->db->error(); + $this->db->rollback(); + return -1; + } + @@ -4371,3 +3562,3 @@ - $line->context = $this->context; - - // Load line + $line->context = $this->context; + + // For triggers @@ -4375,17 +3566,4 @@ - if (!($result > 0)) { - dol_print_error($this->db, $line->error, $line->errors); - return -1; - } - - if ($id > 0 && $line->fk_facture != $id) { - $this->error = 'ErrorLineIDDoesNotMatchWithObjectID'; - return -1; - } - - $this->db->begin(); - - // Memorize previous line for triggers - $staticline = clone $line; - $line->oldline = $staticline; - - if ($line->delete($user) > 0) { + if (!($result > 0)) dol_print_error($this->db, $line->error, $line->errors); + + if ($line->delete($user) > 0) + { @@ -4394 +3572,2 @@ - if ($result > 0) { + if ($result > 0) + { @@ -4397 +3576,3 @@ - } else { + } + else + { @@ -4402 +3583,3 @@ - } else { + } + else + { @@ -4409,18 +3592 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Set percent discount - * - * @deprecated - * @see setDiscount() - * @param User $user User that set discount - * @param double $remise Discount - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int Return integer <0 if KO, >0 if OK - */ - public function set_remise($user, $remise, $notrigger = 0) - { - // phpcs:enable - dol_syslog(get_class($this)."::set_remise is deprecated, use setDiscount instead", LOG_NOTICE); - return $this->setDiscount($user, $remise, $notrigger); - } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -4433,4 +3599,3 @@ - * @return int Return integer <0 if KO, >0 if OK - * @deprecated remise_percent is a deprecated field for object parent - */ - public function setDiscount($user, $remise, $notrigger = 0) + * @return int <0 if ko, >0 if ok + */ + public function set_remise($user, $remise, $notrigger = 0) @@ -4437,0 +3603 @@ + // phpcs:enable @@ -4439,6 +3605,5 @@ - if (empty($remise)) { - $remise = 0; - } - - if ($user->hasRight('facture', 'creer')) { - $remise = price2num($remise, 2); + if (empty($remise)) $remise = 0; + + if ($user->rights->facture->creer) + { + $remise = price2num($remise); @@ -4451,2 +3616,2 @@ - $sql .= ' SET remise_percent = '.((float) $remise); - $sql .= " WHERE rowid = ".((int) $this->id); + $sql .= ' SET remise_percent = '.$remise; + $sql .= ' WHERE rowid = '.$this->id; @@ -4457 +3622,2 @@ - if (!$resql) { + if (!$resql) + { @@ -4462 +3628,2 @@ - if (!$notrigger && empty($error)) { + if (!$notrigger && empty($error)) + { @@ -4465,3 +3632 @@ - if ($result < 0) { - $error++; - } + if ($result < 0) $error++; @@ -4471 +3636,2 @@ - if (!$error) { + if (!$error) + { @@ -4477,2 +3643,5 @@ - } else { - foreach ($this->errors as $errmsg) { + } + else + { + foreach ($this->errors as $errmsg) + { @@ -4486,2 +3654,0 @@ - - return 0; @@ -4491 +3658 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -4498,4 +3665,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - /* - public function set_remise_absolue($user, $remise, $notrigger = 0) + * @return int <0 if KO, >0 if OK + */ + public function set_remise_absolue($user, $remise, $notrigger = 0) @@ -4503,6 +3669,5 @@ - // phpcs:enable - if (empty($remise)) { - $remise = 0; - } - - if ($user->hasRight('facture', 'creer')) { + // phpcs:enable + if (empty($remise)) $remise = 0; + + if ($user->rights->facture->creer) + { @@ -4516,2 +3681,2 @@ - $sql .= ' SET remise_absolue = '.((float) $remise); - $sql .= " WHERE rowid = ".((int) $this->id); + $sql .= ' SET remise_absolue = '.$remise; + $sql .= ' WHERE rowid = '.$this->id; @@ -4522 +3687,2 @@ - if (!$resql) { + if (!$resql) + { @@ -4527 +3693,2 @@ - if (!$error) { + if (!$error) + { @@ -4533 +3700,2 @@ - if (!$notrigger && empty($error)) { + if (!$notrigger && empty($error)) + { @@ -4536,3 +3704 @@ - if ($result < 0) { - $error++; - } + if ($result < 0) $error++; @@ -4542 +3708,2 @@ - if (!$error) { + if (!$error) + { @@ -4545,2 +3712,5 @@ - } else { - foreach ($this->errors as $errmsg) { + } + else + { + foreach ($this->errors as $errmsg) + { @@ -4554,2 +3723,0 @@ - - return 0; @@ -4557 +3724,0 @@ - */ @@ -4567 +3734 @@ - public function getNextNumRef($soc, $mode = 'next') + public function getNextNumRef($soc, $mode = 'next') @@ -4572 +3739 @@ - $langs->load('cashdesk'); + $langs->load('cashdesk@cashdesk'); @@ -4579,3 +3746 @@ - if (!getDolGlobalString('TAKEPOS_REF_ADDON')) { - $conf->global->TAKEPOS_REF_ADDON = 'mod_takepos_ref_simple'; - } + if (empty($conf->global->TAKEPOS_REF_ADDON)) $conf->global->TAKEPOS_REF_ADDON = 'mod_takepos_ref_simple'; @@ -4592,7 +3757,3 @@ - if (!getDolGlobalString('FACTURE_ADDON')) { - $conf->global->FACTURE_ADDON = 'mod_facture_terre'; - } elseif (getDolGlobalString('FACTURE_ADDON') == 'terre') { - $conf->global->FACTURE_ADDON = 'mod_facture_terre'; - } elseif (getDolGlobalString('FACTURE_ADDON') == 'mercure') { - $conf->global->FACTURE_ADDON = 'mod_facture_mercure'; - } + if (empty($conf->global->FACTURE_ADDON)) $conf->global->FACTURE_ADDON = 'mod_facture_terre'; + elseif ($conf->global->FACTURE_ADDON == 'terre') $conf->global->FACTURE_ADDON = 'mod_facture_terre'; + elseif ($conf->global->FACTURE_ADDON == 'mercure') $conf->global->FACTURE_ADDON = 'mod_facture_mercure'; @@ -4604 +3765 @@ - dol_syslog("Call getNextNumRef with ".$addonConstName." = " . getDolGlobalString('FACTURE_ADDON').", thirdparty=".$soc->name.", type=".$soc->typent_code.", mode=".$mode, LOG_DEBUG); + dol_syslog("Call getNextNumRef with ".$addonConstName." = ".$conf->global->FACTURE_ADDON.", thirdparty=".$soc->nom.", type=".$soc->typent_code, LOG_DEBUG); @@ -4606,0 +3768 @@ + @@ -4645 +3806,0 @@ - @@ -4647 +3807,0 @@ - @@ -4672 +3832 @@ - public function info($id) + public function info($id) @@ -4678 +3838 @@ - $sql .= ' WHERE c.rowid = '.((int) $id); + $sql .= ' WHERE c.rowid = '.$id; @@ -4681,2 +3841,4 @@ - if ($result) { - if ($this->db->num_rows($result)) { + if ($result) + { + if ($this->db->num_rows($result)) + { @@ -4684 +3845,0 @@ - @@ -4686,3 +3847,18 @@ - $this->user_creation_id = $obj->fk_user_author; - $this->user_validation_id = $obj->fk_user_valid; - $this->user_closing_id = $obj->fk_user_closing; + if ($obj->fk_user_author) + { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + if ($obj->fk_user_valid) + { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + if ($obj->fk_user_closing) + { + $cluser = new User($this->db); + $cluser->fetch($obj->fk_user_closing); + $this->user_closing = $cluser; + } @@ -4696 +3872,3 @@ - } else { + } + else + { @@ -4702 +3880 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -4716 +3894 @@ - public function liste_array($shortlist = 0, $draft = 0, $excluser = null, $socid = 0, $limit = 0, $offset = 0, $sortfield = 'f.datef,f.rowid', $sortorder = 'DESC') + public function liste_array($shortlist = 0, $draft = 0, $excluser = '', $socid = 0, $limit = 0, $offset = 0, $sortfield = 'f.datef,f.rowid', $sortorder = 'DESC') @@ -4718 +3896 @@ - // phpcs:enable + // phpcs:enable @@ -4725,3 +3903 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$socid) { - $sql .= ", sc.fk_soc, sc.fk_user"; - } + if (!$user->rights->societe->client->voir && !$socid) $sql .= ", sc.fk_soc, sc.fk_user"; @@ -4729,3 +3905 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } + if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -4734,12 +3908,7 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$socid) { //restriction - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); - } - if ($socid) { - $sql .= " AND s.rowid = ".((int) $socid); - } - if ($draft) { - $sql .= " AND f.fk_statut = ".self::STATUS_DRAFT; - } - if (is_object($excluser)) { - $sql .= " AND f.fk_user_author <> ".((int) $excluser->id); - } + if (!$user->rights->societe->client->voir && !$socid) //restriction + { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; + } + if ($socid) $sql .= " AND s.rowid = ".$socid; + if ($draft) $sql .= " AND f.fk_statut = ".self::STATUS_DRAFT; + if (is_object($excluser)) $sql .= " AND f.fk_user_author <> ".$excluser->id; @@ -4750 +3919,2 @@ - if ($result) { + if ($result) + { @@ -4752 +3922,2 @@ - if ($numc) { + if ($numc) + { @@ -4754 +3925,2 @@ - while ($i < $numc) { + while ($i < $numc) + { @@ -4757 +3929,2 @@ - if ($shortlist == 1) { + if ($shortlist == 1) + { @@ -4759 +3932,3 @@ - } elseif ($shortlist == 2) { + } + elseif ($shortlist == 2) + { @@ -4761 +3936,3 @@ - } else { + } + else + { @@ -4770 +3947,3 @@ - } else { + } + else + { @@ -4777 +3956 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -4783,4 +3962,4 @@ - * @param int $socid Id thirdparty - * @return array|int Array of invoices ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) - */ - public function list_replacable_invoices($socid = 0) + * @param int $socid Id thirdparty + * @return array|int Array of invoices ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) + */ + public function list_replacable_invoices($socid = 0) @@ -4788 +3967 @@ - // phpcs:enable + // phpcs:enable @@ -4793 +3972 @@ - $sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut as status, f.paye as paid,"; + $sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut,"; @@ -4795 +3973,0 @@ - //$sql .= ", SUM(pf.amount) as alreadypaid"; @@ -4801,7 +3979,4 @@ - $sql .= " AND f.paye = 0"; // Not paid completely - $sql .= " AND pf.fk_paiement IS NULL"; // No payment already done - $sql .= " AND ff.fk_statut IS NULL"; // Return true if it is not a replacement invoice - if ($socid > 0) { - $sql .= " AND f.fk_soc = ".((int) $socid); - } - //$sql .= " GROUP BY f.rowid, f.ref, f.fk_statut, f.paye, ff.rowid"; + $sql .= " AND f.paye = 0"; // Pas classee payee completement + $sql .= " AND pf.fk_paiement IS NULL"; // Aucun paiement deja fait + $sql .= " AND ff.fk_statut IS NULL"; // Renvoi vrai si pas facture de remplacement + if ($socid > 0) $sql .= " AND f.fk_soc = ".$socid; @@ -4812,9 +3987,7 @@ - if ($resql) { - while ($obj = $this->db->fetch_object($resql)) { - $return[$obj->rowid] = array( - 'id' => $obj->rowid, - 'ref' => $obj->ref, - 'status' => $obj->status, - 'paid' => $obj->paid, - 'alreadypaid' => 0 - ); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + $return[$obj->rowid] = array('id' => $obj->rowid, + 'ref' => $obj->ref, + 'status' => $obj->fk_statut); @@ -4824 +3997,3 @@ - } else { + } + else + { @@ -4831 +4006 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -4837,4 +4012,4 @@ - * @param int $socid Id thirdparty - * @return array|int Array of invoices ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>) - */ - public function list_qualified_avoir_invoices($socid = 0) + * @param int $socid Id thirdparty + * @return array Array of invoices ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>) + */ + public function list_qualified_avoir_invoices($socid = 0) @@ -4842 +4017 @@ - // phpcs:enable + // phpcs:enable @@ -4848 +4023 @@ - $sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut, f.type, f.subtype, f.paye, pf.fk_paiement"; + $sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut, f.type, f.paye, pf.fk_paiement"; @@ -4858,22 +4033,19 @@ - $sql .= " AND f.type <> ".self::TYPE_CREDIT_NOTE; // Exclude credit note invoices from selection - - if (getDolGlobalString('INVOICE_USE_SITUATION_CREDIT_NOTE')) { - // Keep invoices that are not situation invoices or that are the last in serie if it is a situation invoice - $sql .= " AND (f.type <> ".self::TYPE_SITUATION." OR f.rowid IN "; - $sql .= '(SELECT MAX(fs.rowid)'; // This select returns several ID becasue of the group by later - $sql .= " FROM ".MAIN_DB_PREFIX."facture as fs"; - $sql .= " WHERE fs.entity IN (".getEntity('invoice').")"; - $sql .= " AND fs.type = ".self::TYPE_SITUATION; - $sql .= " AND fs.fk_statut IN (".self::STATUS_VALIDATED.",".self::STATUS_CLOSED.")"; - if ($socid > 0) { - $sql .= " AND fs.fk_soc = ".((int) $socid); - } - $sql .= " GROUP BY fs.situation_cycle_ref)"; // For each situation_cycle_ref, we take the higher rowid - $sql .= ")"; - } else { - $sql .= " AND f.type <> ".self::TYPE_SITUATION; // Keep invoices that are not situation invoices - } - - if ($socid > 0) { - $sql .= " AND f.fk_soc = ".((int) $socid); - } + $sql .= " AND f.type != ".self::TYPE_CREDIT_NOTE; // Type non 2 si facture non avoir + + if (!empty($conf->global->INVOICE_USE_SITUATION_CREDIT_NOTE)) { + // Select the last situation invoice + $sqlSit = 'SELECT MAX(fs.rowid)'; + $sqlSit .= " FROM ".MAIN_DB_PREFIX."facture as fs"; + $sqlSit .= " WHERE fs.entity IN (".getEntity('invoice').")"; + $sqlSit .= " AND fs.type = ".self::TYPE_SITUATION; + $sqlSit .= " AND fs.fk_statut in (".self::STATUS_VALIDATED.",".self::STATUS_CLOSED.")"; + $sqlSit .= " GROUP BY fs.situation_cycle_ref"; + $sqlSit .= " ORDER BY fs.situation_counter"; + $sql .= " AND ( f.type != ".self::TYPE_SITUATION." OR f.rowid IN (".$sqlSit.") )"; // Type non 5 si facture non avoir + } + else + { + $sql .= " AND f.type != ".self::TYPE_SITUATION; // Type non 5 si facture non avoir + } + + if ($socid > 0) $sql .= " AND f.fk_soc = ".$socid; @@ -4884,2 +4056,4 @@ - if ($resql) { - while ($obj = $this->db->fetch_object($resql)) { + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { @@ -4887,7 +4061,4 @@ - if ($obj->fk_statut == self::STATUS_VALIDATED) { - $qualified = 1; - } - if ($obj->fk_statut == self::STATUS_CLOSED) { - $qualified = 1; - } - if ($qualified) { + if ($obj->fk_statut == self::STATUS_VALIDATED) $qualified = 1; + if ($obj->fk_statut == self::STATUS_CLOSED) $qualified = 1; + if ($qualified) + { @@ -4901 +4072,3 @@ - } else { + } + else + { @@ -4908 +4081 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -4912,4 +4085,4 @@ - * @param User $user Object user - * @return WorkboardResponse|int Return integer <0 if KO, WorkboardResponse if OK - */ - public function load_board($user) + * @param User $user Object user + * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK + */ + public function load_board($user) @@ -4917 +4090 @@ - // phpcs:enable + // phpcs:enable @@ -4922 +4095 @@ - $sql = "SELECT f.rowid, f.date_lim_reglement as datefin, f.fk_statut as status, f.total_ht"; + $sql = "SELECT f.rowid, f.date_lim_reglement as datefin,f.fk_statut, f.total"; @@ -4924,3 +4097,4 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$user->socid) { - $sql .= " JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON f.fk_soc = sc.fk_soc"; - $sql .= " WHERE sc.fk_user = ".((int) $user->id); + if (!$user->rights->societe->client->voir && !$user->socid) + { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON f.fk_soc = sc.fk_soc"; + $sql .= " WHERE sc.fk_user = ".$user->id; @@ -4932,3 +4106 @@ - if ($user->socid) { - $sql .= " AND f.fk_soc = ".((int) $user->socid); - } + if ($user->socid) $sql .= " AND f.fk_soc = ".$user->socid; @@ -4937 +4109,2 @@ - if ($resql) { + if ($resql) + { @@ -4950 +4123,2 @@ - while ($obj = $this->db->fetch_object($resql)) { + while ($obj = $this->db->fetch_object($resql)) + { @@ -4952,2 +4126 @@ - $generic_facture->statut = $obj->status; - $generic_facture->status = $obj->status; + $generic_facture->statut = $obj->fk_statut; @@ -4956 +4129 @@ - $response->total += $obj->total_ht; + $response->total += $obj->total; @@ -4964 +4136,0 @@ - $this->db->free($resql); @@ -4966 +4138,3 @@ - } else { + } + else + { @@ -4981 +4155 @@ - public function getIdBillingContact() + public function getIdBillingContact() @@ -4991 +4165 @@ - public function getIdShippingContact() + public function getIdShippingContact() @@ -5005 +4179 @@ - public function initAsSpecimen($option = '') + public function initAsSpecimen($option = '') @@ -5007 +4181 @@ - global $conf, $langs, $user; + global $conf, $langs; @@ -5013 +4187 @@ - // Load array of products prodids + // Load array of products prodids @@ -5019,2 +4192,0 @@ - $sql .= $this->db->plimit(100); - @@ -5022 +4194,2 @@ - if ($resql) { + if ($resql) + { @@ -5025 +4198,2 @@ - while ($i < $num_prods) { + while ($i < $num_prods) + { @@ -5054,2 +4227,0 @@ - $this->fk_user_author = $user->id; - @@ -5062 +4234,2 @@ - if (empty($option) || $option != 'nolines') { + if (empty($option) || $option != 'nolines') + { @@ -5066 +4239,2 @@ - while ($xnbp < $nbp) { + while ($xnbp < $nbp) + { @@ -5075 +4249,2 @@ - if ($xnbp == 1) { // Qty is negative (product line) + if ($xnbp == 1) // Qty is negative (product line) + { @@ -5085 +4260,3 @@ - } elseif ($xnbp == 2) { // UP is negative (free line) + } + elseif ($xnbp == 2) // UP is negative (free line) + { @@ -5094 +4271,3 @@ - } elseif ($xnbp == 3) { // Discount is 50% (product line) + } + elseif ($xnbp == 3) // Discount is 50% (product line) + { @@ -5104 +4283,3 @@ - } else { // (product line) + } + else // (product line) + { @@ -5154 +4335 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -5158,3 +4339,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function load_state_board() + * @return int <0 if KO, >0 if OK + */ + public function load_state_board() @@ -5162 +4343 @@ - // phpcs:enable + // phpcs:enable @@ -5172 +4353,2 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$user->socid) { + if (!$user->rights->societe->client->voir && !$user->socid) + { @@ -5174 +4356 @@ - $sql .= " WHERE sc.fk_user = ".((int) $user->id); + $sql .= " WHERE sc.fk_user = ".$user->id; @@ -5180,2 +4362,4 @@ - if ($resql) { - while ($obj = $this->db->fetch_object($resql)) { + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { @@ -5184 +4368 @@ - $this->db->free($resql); + $this->db->free($resql); @@ -5186 +4370,3 @@ - } else { + } + else + { @@ -5198 +4384 @@ - public function getLinesArray() + public function getLinesArray() @@ -5200 +4386 @@ - return $this->fetch_lines(); + return $this->fetch_lines(); @@ -5206,2 +4392,2 @@ - * @param string $modele Generator to use. Caller must set it to obj->model_pdf or GETPOST('model','alpha') for example. - * @param Translate $outputlangs Object lang to use for translation + * @param string $modele Generator to use. Caller must set it to obj->modelpdf or GETPOST('modelpdf','alpha') for example. + * @param Translate $outputlangs objet lang a utiliser pour traduction @@ -5211,2 +4397,2 @@ - * @param null|array $moreparams Array to provide more information - * @return int Return integer <0 if KO, >0 if OK + * @param null|array $moreparams Array to provide more information + * @return int <0 if KO, >0 if OK @@ -5218,3 +4404,4 @@ - $outputlangs->loadLangs(array("bills", "products")); - - if (!dol_strlen($modele)) { + $langs->load("bills"); + + if (!dol_strlen($modele)) + { @@ -5224,5 +4411,5 @@ - if (!empty($this->model_pdf)) { - $modele = $this->model_pdf; - } elseif (getDolGlobalString($thisTypeConfName)) { - $modele = getDolGlobalString($thisTypeConfName); - } elseif (getDolGlobalString('FACTURE_ADDON_PDF')) { + if ($this->modelpdf) { + $modele = $this->modelpdf; + } elseif (!empty($conf->global->$thisTypeConfName)) { + $modele = $conf->global->$thisTypeConfName; + } elseif (!empty($conf->global->FACTURE_ADDON_PDF)) { @@ -5243 +4430 @@ - public function newCycle() + public function newCycle() @@ -5249 +4436,2 @@ - if ($this->db->num_rows($resql) > 0) { + if ($resql->num_rows > 0) + { @@ -5265 +4453 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -5271 +4459 @@ - public function is_first() + public function is_first() @@ -5273 +4461 @@ - // phpcs:enable + // phpcs:enable @@ -5277 +4465 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -5283 +4471 @@ - public function get_prev_sits() + public function get_prev_sits() @@ -5285 +4473 @@ - // phpcs:enable + // phpcs:enable @@ -5289,2 +4477,2 @@ - $sql .= ' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref); - $sql .= ' AND situation_counter < '.((int) $this->situation_counter); + $sql .= ' WHERE situation_cycle_ref = '.$this->situation_cycle_ref; + $sql .= ' AND situation_counter < '.$this->situation_counter; @@ -5294 +4482 @@ - if ($resql && $this->db->num_rows($resql) > 0) { + if ($resql && $resql->num_rows > 0) { @@ -5315,3 +4503,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function setFinal(User $user, $notrigger = 0) + * @return int <0 if KO, >0 if OK + */ + public function setFinal(User $user, $notrigger = 0) @@ -5323 +4511 @@ - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET situation_final = '.((int) $this->situation_final).' WHERE rowid = '.((int) $this->id); + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET situation_final = '.$this->situation_final.' where rowid = '.$this->id; @@ -5327 +4515,2 @@ - if (!$resql) { + if (!$resql) + { @@ -5332 +4521,2 @@ - if (!$notrigger && empty($error)) { + if (!$notrigger && empty($error)) + { @@ -5335,3 +4525 @@ - if ($result < 0) { - $error++; - } + if ($result < 0) $error++; @@ -5341 +4529,2 @@ - if (!$error) { + if (!$error) + { @@ -5344,2 +4533,5 @@ - } else { - foreach ($this->errors as $errmsg) { + } + else + { + foreach ($this->errors as $errmsg) + { @@ -5354 +4546 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -5360 +4552 @@ - public function is_last_in_cycle() + public function is_last_in_cycle() @@ -5362 +4554 @@ - // phpcs:enable + // phpcs:enable @@ -5368 +4560 @@ - $sql .= ' WHERE situation_cycle_ref = '.((int) $this->situation_cycle_ref); + $sql .= ' WHERE situation_cycle_ref = '.$this->situation_cycle_ref; @@ -5372 +4564 @@ - if ($resql && $this->db->num_rows($resql) > 0) { + if ($resql && $resql->num_rows > 0) { @@ -5389,6 +4581,6 @@ - * @param DoliDB $dbs Database handler, because function is static we name it $dbs not $db to avoid breaking coding test - * @param int $origin_id Old thirdparty id - * @param int $dest_id New thirdparty id - * @return bool - */ - public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id) + * @param DoliDB $db Database handler + * @param int $origin_id Old third-party id + * @param int $dest_id New third-party id + * @return bool + */ + public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id) @@ -5400,18 +4592 @@ - return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables); - } - - /** - * Function used to replace a product id with another one. - * - * @param DoliDB $db Database handler - * @param int $origin_id Old product id - * @param int $dest_id New product id - * @return bool - */ - public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) - { - $tables = array( - 'facturedet' - ); - - return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); @@ -5432,3 +4607 @@ - if ($this->status != Facture::STATUS_VALIDATED) { - return false; - } + if ($this->statut != Facture::STATUS_VALIDATED) return false; @@ -5437,13 +4610,20 @@ - if ($hasDelay && !empty($this->retained_warranty) && !empty($this->retained_warranty_date_limit)) { - $totalpaid = $this->getSommePaiement(); - $totalpaid = (float) $totalpaid; - $RetainedWarrantyAmount = $this->getRetainedWarrantyAmount(); - if ($totalpaid >= 0 && $RetainedWarrantyAmount >= 0) { - if (($totalpaid < $this->total_ttc - $RetainedWarrantyAmount) && $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay)) { - $hasDelay = 1; - } elseif ($totalpaid < $this->total_ttc && $this->retained_warranty_date_limit < ($now - $conf->facture->client->warning_delay)) { - $hasDelay = 1; - } else { - $hasDelay = 0; - } - } + if ($hasDelay && !empty($this->retained_warranty) && !empty($this->retained_warranty_date_limit)) + { + $totalpaye = $this->getSommePaiement(); + $totalpaye = floatval($totalpaye); + $RetainedWarrantyAmount = $this->getRetainedWarrantyAmount(); + if ($totalpaye >= 0 && $RetainedWarrantyAmount >= 0) + { + if (($totalpaye < $this->total_ttc - $RetainedWarrantyAmount) && $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay)) + { + $hasDelay = 1; + } + elseif ($totalpaye < $this->total_ttc && $this->retained_warranty_date_limit < ($now - $conf->facture->client->warning_delay)) + { + $hasDelay = 1; + } + else + { + $hasDelay = 0; + } + } @@ -5465 +4645 @@ - // note : we don't need to test INVOICE_USE_RETAINED_WARRANTY because if $this->retained_warranty is not empty it's because it was set when this conf was active + // note : we dont need to test INVOICE_USE_RETAINED_WARRANTY because if $this->retained_warranty is not empty it's because it was set when this conf was active @@ -5471 +4651 @@ - if ($this->type == Facture::TYPE_SITUATION && getDolGlobalString('INVOICE_RETAINED_WARRANTY_LIMITED_TO_FINAL_SITUATION')) { + if ($this->type == Facture::TYPE_SITUATION && !empty($conf->global->INVOICE_RETAINED_WARRANTY_LIMITED_TO_FINAL_SITUATION)) { @@ -5495 +4675 @@ - * @return float or -1 if not available + * @return number or -1 if not available @@ -5500,37 +4680,42 @@ - if (empty($this->retained_warranty)) { - return -1; - } - - $retainedWarrantyAmount = 0; - - // Billed - retained warranty - if ($this->type == Facture::TYPE_SITUATION && getDolGlobalString('INVOICE_RETAINED_WARRANTY_LIMITED_TO_FINAL_SITUATION')) { - $displayWarranty = true; - // Check if this situation invoice is 100% for real - if (!empty($this->lines)) { - foreach ($this->lines as $i => $line) { - if ($line->product_type < 2 && $line->situation_percent < 100) { - $displayWarranty = false; - break; - } - } - } - - if ($displayWarranty && !empty($this->situation_final)) { - $this->fetchPreviousNextSituationInvoice(); - $TPreviousIncoice = $this->tab_previous_situation_invoice; - - $total2BillWT = 0; - foreach ($TPreviousIncoice as &$fac) { - $total2BillWT += $fac->total_ttc; - } - $total2BillWT += $this->total_ttc; - - $retainedWarrantyAmount = $total2BillWT * $this->retained_warranty / 100; - } else { - return -1; - } - } else { - // Because one day retained warranty could be used on standard invoices - $retainedWarrantyAmount = $this->total_ttc * $this->retained_warranty / 100; - } + if (empty($this->retained_warranty)) { + return -1; + } + + $retainedWarrantyAmount = 0; + + // Billed - retained warranty + if ($this->type == Facture::TYPE_SITUATION && !empty($conf->global->INVOICE_RETAINED_WARRANTY_LIMITED_TO_FINAL_SITUATION)) + { + $displayWarranty = true; + // Check if this situation invoice is 100% for real + if (!empty($this->lines)) { + foreach ($this->lines as $i => $line) { + if ($line->product_type < 2 && $line->situation_percent < 100) { + $displayWarranty = false; + break; + } + } + } + + if ($displayWarranty && !empty($this->situation_final)) + { + $this->fetchPreviousNextSituationInvoice(); + $TPreviousIncoice = $this->tab_previous_situation_invoice; + + $total2BillWT = 0; + foreach ($TPreviousIncoice as &$fac) { + $total2BillWT += $fac->total_ttc; + } + $total2BillWT += $this->total_ttc; + + $retainedWarrantyAmount = $total2BillWT * $this->retained_warranty / 100; + } + else { + return -1; + } + } + else + { + // Because one day retained warranty could be used on standard invoices + $retainedWarrantyAmount = $this->total_ttc * $this->retained_warranty / 100; + } @@ -5539 +4724 @@ - $rounding = min(getDolGlobalString('MAIN_MAX_DECIMALS_UNIT'), getDolGlobalString('MAIN_MAX_DECIMALS_TOT')); + $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT); @@ -5546 +4731 @@ - return $retainedWarrantyAmount; + return $retainedWarrantyAmount; @@ -5557,21 +4742,26 @@ - dol_syslog(get_class($this).'::setRetainedWarranty('.$value.')'); - - if ($this->status >= 0) { - $fieldname = 'retained_warranty'; - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= " SET ".$fieldname." = ".((float) $value); - $sql .= ' WHERE rowid='.((int) $this->id); - - if ($this->db->query($sql)) { - $this->retained_warranty = (float) $value; - return 1; - } else { - dol_syslog(get_class($this).'::setRetainedWarranty Erreur '.$sql.' - '.$this->db->error()); - $this->error = $this->db->error(); - return -1; - } - } else { - dol_syslog(get_class($this).'::setRetainedWarranty, status of the object is incompatible'); - $this->error = 'Status of the object is incompatible '.$this->status; - return -2; - } + dol_syslog(get_class($this).'::setRetainedWarranty('.$value.')'); + if ($this->statut >= 0) + { + $fieldname = 'retained_warranty'; + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET '.$fieldname.' = '.floatval($value); + $sql .= ' WHERE rowid='.$this->id; + + if ($this->db->query($sql)) + { + $this->retained_warranty = floatval($value); + return 1; + } + else + { + dol_syslog(get_class($this).'::setRetainedWarranty Erreur '.$sql.' - '.$this->db->error()); + $this->error = $this->db->error(); + return -1; + } + } + else + { + dol_syslog(get_class($this).'::setRetainedWarranty, status of the object is incompatible'); + $this->error = 'Status of the object is incompatible '.$this->statut; + return -2; + } @@ -5588 +4778 @@ - public function setRetainedWarrantyDateLimit($timestamp, $dateYmd = '') + public function setRetainedWarrantyDateLimit($timestamp, $dateYmd = false) @@ -5590,422 +4780,31 @@ - if (!$timestamp && $dateYmd) { - $timestamp = $this->db->jdate($dateYmd); - } - - - dol_syslog(get_class($this).'::setRetainedWarrantyDateLimit('.$timestamp.')'); - if ($this->status >= 0) { - $fieldname = 'retained_warranty_date_limit'; - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= " SET ".$fieldname." = ".(strval($timestamp) != '' ? "'".$this->db->idate($timestamp)."'" : 'null'); - $sql .= ' WHERE rowid = '.((int) $this->id); - - if ($this->db->query($sql)) { - $this->retained_warranty_date_limit = $timestamp; - return 1; - } else { - dol_syslog(get_class($this).'::setRetainedWarrantyDateLimit Erreur '.$sql.' - '.$this->db->error()); - $this->error = $this->db->error(); - return -1; - } - } else { - dol_syslog(get_class($this).'::setRetainedWarrantyDateLimit, status of the object is incompatible'); - $this->error = 'Status of the object is incompatible '.$this->status; - return -2; - } - } - - - /** - * Send reminders by emails for invoices validated that are due. - * CAN BE A CRON TASK - * - * @param int $nbdays Delay before due date (or after if delay is negative) - * @param string $paymentmode '' or 'all' by default (no filter), or 'LIQ', 'CHQ', CB', ... - * @param int|string $template Name (or id) of email template (Must be a template of type 'facture_send') - * @param string $datetouse 'duedate' (default) or 'invoicedate' - * @param string $forcerecipient Force email of recipient (for example to send the email to an accountant supervisor instead of the customer) - * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) - */ - public function sendEmailsRemindersOnInvoiceDueDate($nbdays = 0, $paymentmode = 'all', $template = '', $datetouse = 'duedate', $forcerecipient = '') - { - global $conf, $langs, $user; - - $error = 0; - $this->output = ''; - $this->error = ''; - $nbMailSend = 0; - $errorsMsg = array(); - - $langs->load("bills"); - - if (!isModEnabled('facture')) { // Should not happen. If module disabled, cron job should not be visible. - $this->output .= $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Facture")); - return 0; - } - if (!in_array($datetouse, array('duedate', 'invoicedate'))) { - $this->output .= 'Bad value for parameter datetouse. Must be "duedate" or "invoicedate"'; - return 0; - } - /*if (empty($conf->global->FACTURE_REMINDER_EMAIL)) { - $langs->load("bills"); - $this->output .= $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Facture")); - return 0; - } - */ - - require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $formmail = new FormMail($this->db); - - $now = dol_now(); - $tmpidate = dol_get_first_hour(dol_time_plus_duree($now, $nbdays, 'd'), 'gmt'); - - $tmpinvoice = new Facture($this->db); - - dol_syslog(__METHOD__." start", LOG_INFO); - - // Select all action comm reminder - $sql = "SELECT rowid as id FROM ".MAIN_DB_PREFIX."facture as f"; - if (!empty($paymentmode) && $paymentmode != 'all') { - $sql .= ", ".MAIN_DB_PREFIX."c_paiement as cp"; - } - $sql .= " WHERE f.paye = 0"; // Only unpaid - $sql .= " AND f.fk_statut = ".self::STATUS_VALIDATED; // Only validated status - if ($datetouse == 'invoicedate') { - $sql .= " AND f.datef = '".$this->db->idate($tmpidate, 'gmt')."'"; - } else { - $sql .= " AND f.date_lim_reglement = '".$this->db->idate($tmpidate, 'gmt')."'"; - } - $sql .= " AND f.entity IN (".getEntity('facture', 0).")"; // One batch process only one company (no sharing) - if (!empty($paymentmode) && $paymentmode != 'all') { - $sql .= " AND f.fk_mode_reglement = cp.id AND cp.code = '".$this->db->escape($paymentmode)."'"; - } - // TODO Add a filter to check there is no payment started yet - if ($datetouse == 'invoicedate') { - $sql .= $this->db->order("datef", "ASC"); - } else { - $sql .= $this->db->order("date_lim_reglement", "ASC"); - } - - $resql = $this->db->query($sql); - - $stmpidate = dol_print_date($tmpidate, 'day', 'gmt'); - if ($datetouse == 'invoicedate') { - $this->output .= $langs->transnoentitiesnoconv("SearchValidatedInvoicesWithDate", $stmpidate); - } else { - $this->output .= $langs->transnoentitiesnoconv("SearchUnpaidInvoicesWithDueDate", $stmpidate); - } - if (!empty($paymentmode) && $paymentmode != 'all') { - $this->output .= ' ('.$langs->transnoentitiesnoconv("PaymentMode").' '.$paymentmode.')'; - } - $this->output .= '
    '; - - if ($resql) { - while ($obj = $this->db->fetch_object($resql)) { - if (!$error) { - // Load event - $res = $tmpinvoice->fetch($obj->id); - if ($res > 0) { - $tmpinvoice->fetch_thirdparty(); - - $outputlangs = new Translate('', $conf); - if ($tmpinvoice->thirdparty->default_lang) { - $outputlangs->setDefaultLang($tmpinvoice->thirdparty->default_lang); - $outputlangs->loadLangs(array("main", "bills")); - } else { - $outputlangs = $langs; - } - - // Select email template according to language of recipient - $arraymessage = $formmail->getEMailTemplate($this->db, 'facture_send', $user, $outputlangs, (is_numeric($template) ? $template : 0), 1, (is_numeric($template) ? '' : $template)); - if (is_numeric($arraymessage) && $arraymessage <= 0) { - $langs->load("errors"); - $this->output .= $langs->trans('ErrorFailedToFindEmailTemplate', $template); - return 0; - } - - // PREPARE EMAIL - $errormesg = ''; - - // Make substitution in email content - $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, '', $tmpinvoice); - - complete_substitutions_array($substitutionarray, $outputlangs, $tmpinvoice); - - // Topic - $sendTopic = make_substitutions(empty($arraymessage->topic) ? $outputlangs->transnoentitiesnoconv('InformationMessage') : $arraymessage->topic, $substitutionarray, $outputlangs, 1); - - // Content - $content = $outputlangs->transnoentitiesnoconv($arraymessage->content); - - $sendContent = make_substitutions($content, $substitutionarray, $outputlangs, 1); - - // Recipient - $to = array(); - if ($forcerecipient) { // If a recipient was forced - $to = array($forcerecipient); - } else { - $res = $tmpinvoice->fetch_thirdparty(); - $recipient = $tmpinvoice->thirdparty; - if ($res > 0) { - $tmparraycontact = $tmpinvoice->liste_contact(-1, 'external', 0, 'BILLING'); - if (is_array($tmparraycontact) && count($tmparraycontact) > 0) { - foreach ($tmparraycontact as $data_email) { - if (!empty($data_email['email'])) { - $to[] = $tmpinvoice->thirdparty->contact_get_property($data_email['id'], 'email'); - } - } - } - if (empty($to) && !empty($recipient->email)) { - $to[] = $recipient->email; - } - if (empty($to)) { - $errormesg = "Failed to send remind to thirdparty id=".$tmpinvoice->socid.". No email defined for invoice or customer."; - $error++; - } - } else { - $errormesg = "Failed to load recipient with thirdparty id=".$tmpinvoice->socid; - $error++; - } - } - - // Sender - $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM'); - if (!empty($arraymessage->email_from)) { // If a sender is defined into template, we use it in priority - $from = $arraymessage->email_from; - } - if (empty($from)) { - $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM"; - $error++; - } - - if (!$error && !empty($to)) { - $this->db->begin(); - - $to = implode(',', $to); - if (!empty($arraymessage->email_to)) { // If a recipient is defined into template, we add it - $to = $to.','.$arraymessage->email_to; - } - - // Errors Recipient - $errors_to = $conf->global->MAIN_MAIL_ERRORS_TO; - - $trackid = 'inv'.$tmpinvoice->id; - $sendcontext = 'standard'; - - $email_tocc = ''; - if (!empty($arraymessage->email_tocc)) { // If a CC is defined into template, we use it - $email_tocc = $arraymessage->email_tocc; - } - - $email_tobcc = ''; - if (!empty($arraymessage->email_tobcc)) { // If a BCC is defined into template, we use it - $email_tobcc = $arraymessage->email_tobcc; - } - - //join file is asked - $joinFile = []; - $joinFileName = []; - $joinFileMime = []; - if ($arraymessage->joinfiles == 1 && !empty($tmpinvoice->last_main_doc)) { - $joinFile[] = DOL_DATA_ROOT.'/'.$tmpinvoice->last_main_doc; - $joinFileName[] = basename($tmpinvoice->last_main_doc); - $joinFileMime[] = dol_mimetype(DOL_DATA_ROOT.'/'.$tmpinvoice->last_main_doc); - } - - // Mail Creation - $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, $joinFile, $joinFileMime, $joinFileName, $email_tocc, $email_tobcc, 0, 1, $errors_to, '', $trackid, '', $sendcontext, ''); - - // Sending Mail - if ($cMailFile->sendfile()) { - $nbMailSend++; - - // Add a line into event table - require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; - - // Insert record of emails sent - $actioncomm = new ActionComm($this->db); - - $actioncomm->type_code = 'AC_OTH_AUTO'; // Event insert into agenda automatically - $actioncomm->socid = $tmpinvoice->thirdparty->id; // To link to a company - $actioncomm->contact_id = 0; - - $actioncomm->code = 'AC_EMAIL'; - $actioncomm->label = 'sendEmailsRemindersOnInvoiceDueDateOK (nbdays='.$nbdays.' paymentmode='.$paymentmode.' template='.$template.' datetouse='.$datetouse.' forcerecipient='.$forcerecipient.')'; - $actioncomm->note_private = $sendContent; - $actioncomm->fk_project = $tmpinvoice->fk_project; - $actioncomm->datep = dol_now(); - $actioncomm->datef = $actioncomm->datep; - $actioncomm->percentage = -1; // Not applicable - $actioncomm->authorid = $user->id; // User saving action - $actioncomm->userownerid = $user->id; // Owner of action - // Fields when action is an email (content should be added into note) - $actioncomm->email_msgid = $cMailFile->msgid; - $actioncomm->email_subject = $sendTopic; - $actioncomm->email_from = $from; - $actioncomm->email_sender = ''; - $actioncomm->email_to = $to; - //$actioncomm->email_tocc = $sendtocc; - //$actioncomm->email_tobcc = $sendtobcc; - //$actioncomm->email_subject = $subject; - $actioncomm->errors_to = $errors_to; - - $actioncomm->elementtype = 'invoice'; - $actioncomm->fk_element = $tmpinvoice->id; - - //$actioncomm->extraparams = $extraparams; - - $actioncomm->create($user); - } else { - $errormesg = $cMailFile->error.' : '.$to; - $error++; - - // Add a line into event table - require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; - - // Insert record of emails sent - $actioncomm = new ActionComm($this->db); - - $actioncomm->type_code = 'AC_OTH_AUTO'; // Event insert into agenda automatically - $actioncomm->socid = $tmpinvoice->thirdparty->id; // To link to a company - $actioncomm->contact_id = 0; - - $actioncomm->code = 'AC_EMAIL'; - $actioncomm->label = 'sendEmailsRemindersOnInvoiceDueDateKO'; - $actioncomm->note_private = $errormesg; - $actioncomm->fk_project = $tmpinvoice->fk_project; - $actioncomm->datep = dol_now(); - $actioncomm->datef = $actioncomm->datep; - $actioncomm->percentage = -1; // Not applicable - $actioncomm->authorid = $user->id; // User saving action - $actioncomm->userownerid = $user->id; // Owner of action - // Fields when action is an email (content should be added into note) - $actioncomm->email_msgid = $cMailFile->msgid; - $actioncomm->email_from = $from; - $actioncomm->email_sender = ''; - $actioncomm->email_to = $to; - //$actioncomm->email_tocc = $sendtocc; - //$actioncomm->email_tobcc = $sendtobcc; - //$actioncomm->email_subject = $subject; - $actioncomm->errors_to = $errors_to; - - //$actioncomm->extraparams = $extraparams; - - $actioncomm->create($user); - } - - $this->db->commit(); // We always commit - } - - if ($errormesg) { - $errorsMsg[] = $errormesg; - } - } else { - $errorsMsg[] = 'Failed to fetch record invoice with ID = '.$obj->id; - $error++; - } - } - } - } else { - $error++; - } - - if (!$error) { - $this->output .= 'Nb of emails sent : '.$nbMailSend; - - dol_syslog(__METHOD__." end - ".$this->output, LOG_INFO); - - return 0; - } else { - $this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? join(', ', $errorsMsg) : $error; - - dol_syslog(__METHOD__." end - ".$this->error, LOG_INFO); - - return $error; - } - } - - /** - * See if current invoice date is posterior to the last invoice date among validated invoices of same type. - * - * @param boolean $allow_validated_drafts return true if the invoice has been validated before returning to DRAFT state. - * @return array return array - */ - public function willBeLastOfSameType($allow_validated_drafts = false) - { - // get date of last validated invoices of same type - $sql = "SELECT datef"; - $sql .= " FROM ".MAIN_DB_PREFIX."facture"; - $sql .= " WHERE type = " . (int) $this->type ; - $sql .= " AND date_valid IS NOT NULL"; - $sql .= " AND entity IN (".getEntity('invoice').")"; - $sql .= " ORDER BY datef DESC LIMIT 1"; - - $result = $this->db->query($sql); - if ($result) { - // compare with current validation date - if ($this->db->num_rows($result)) { - $obj = $this->db->fetch_object($result); - $last_date = $this->db->jdate($obj->datef); - $invoice_date = $this->date; - - $is_last_of_same_type = $invoice_date >= $last_date; - if ($allow_validated_drafts) { - $is_last_of_same_type = $is_last_of_same_type || (!strpos($this->ref, 'PROV') && $this->status == self::STATUS_DRAFT); - } - - return array($is_last_of_same_type, $last_date); - } else { - // element is first of type to be validated - return array(true); - } - } else { - dol_print_error($this->db); - } - - return array(); - } - - /** - * Return clicable link of object (with eventually picto) - * - * @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link) - * @param array $arraydata Array of data - * @return string HTML Code for Kanban thumb. - */ - public function getKanbanView($option = '', $arraydata = null) - { - global $langs; - - $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); - - $return = '
    '; - $return .= '
    '; - $return .= ''; - $return .= img_picto('', $this->picto); - $return .= ''; - $return .= '
    '; - $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; - if ($selected >= 0) { - $return .= ''; - } - if (!empty($arraydata['thirdparty'])) { - $return .= '
    '.$arraydata['thirdparty'].''; - } - if (property_exists($this, 'date')) { - $return .= '
    '.dol_print_date($this->date, 'day').''; - } - if (property_exists($this, 'total_ht')) { - $return .= '   '.price($this->total_ht); - $return .= ' '.$langs->trans("HT"); - $return .= ''; - } - if (method_exists($this, 'getLibStatut')) { - $alreadypaid = (empty($arraydata['alreadypaid']) ? 0 : $arraydata['alreadypaid']); - $return .= '
    '.$this->getLibStatut(3, $alreadypaid).'
    '; - } - $return .= '
    '; - $return .= '
    '; - $return .= '
    '; - return $return; + if (!$timestamp && $dateYmd) { + $timestamp = $this->db->jdate($dateYmd); + } + + + dol_syslog(get_class($this).'::setRetainedWarrantyDateLimit('.$timestamp.')'); + if ($this->statut >= 0) + { + $fieldname = 'retained_warranty_date_limit'; + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET '.$fieldname.' = '.(strval($timestamp) != '' ? '\''.$this->db->idate($timestamp).'\'' : 'null'); + $sql .= ' WHERE rowid='.$this->id; + + if ($this->db->query($sql)) + { + $this->retained_warranty_date_limit = $timestamp; + return 1; + } + else + { + dol_syslog(get_class($this).'::setRetainedWarrantyDateLimit Erreur '.$sql.' - '.$this->db->error()); + $this->error = $this->db->error(); + return -1; + } + } + else + { + dol_syslog(get_class($this).'::setRetainedWarrantyDateLimit, status of the object is incompatible'); + $this->error = 'Status of the object is incompatible '.$this->statut; + return -2; + } @@ -6021 +4820 @@ - /** + /** @@ -6026 +4825 @@ - /** + /** @@ -6031,3 +4829,0 @@ - /** - * @var FactureLigne - */ @@ -6041 +4837,4 @@ - + /** + * @deprecated + */ + public $label; @@ -6044 +4842,0 @@ - public $ref_ext; // External reference of the line @@ -6056,5 +4853,0 @@ - /** - * @var int - */ - public $tva_npr; - @@ -6063,18 +4856,4 @@ - /** - * List of special options to define line: - * 1: shipment cost lines - * 2: ecotaxe - * 3: ?? - * idofmodule: a meaning for the module - */ - public $special_code; - - /** - * @var string To store the batch to consume in stock when using a POS module - */ - public $batch; - /** - * @var string To store the warehouse where to consume stock when using a POS module - */ - public $fk_warehouse; - + public $special_code; // Liste d'options non cumulabels: + // 1: frais de port + // 2: ecotaxe + // 3: ?? @@ -6085,3 +4863,0 @@ - /** - * @var integer Id in table llx_accounting_bookeeping to know accounting account for product line - */ @@ -6089 +4864,0 @@ - @@ -6093,0 +4869,15 @@ + // From llx_product + /** + * @deprecated + * @see $product_ref + */ + public $ref; // Product ref (deprecated) + public $product_ref; // Product ref + /** + * @deprecated + * @see $product_label + */ + public $libelle; // Product label (deprecated) + public $product_label; // Product label + public $product_desc; // Description produit + @@ -6106,9 +4896,7 @@ - /** - * Constructor - * - * @param DoliDB $db handler d'acces base de donnee - */ - public function __construct($db) - { - $this->db = $db; - } + // Multicurrency + public $fk_multicurrency; + public $multicurrency_code; + public $multicurrency_subprice; + public $multicurrency_total_ht; + public $multicurrency_total_tva; + public $multicurrency_total_ttc; @@ -6120,3 +4908,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function fetch($rowid) + * @return int <0 if KO, >0 if OK + */ + public function fetch($rowid) @@ -6125 +4913 @@ - $sql .= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice, fd.ref_ext,'; + $sql .= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice,'; @@ -6135 +4923 @@ - $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc'; + $sql .= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc'; @@ -6138 +4926 @@ - $sql .= ' WHERE fd.rowid = '.((int) $rowid); + $sql .= ' WHERE fd.rowid = '.$rowid; @@ -6141 +4929,2 @@ - if ($result) { + if ($result) + { @@ -6143,5 +4931,0 @@ - - if (!$objp) { - $this->error = 'InvoiceLine with id '. $rowid .' not found sql='.$sql; - return 0; - } @@ -6157 +4940,0 @@ - $this->ref_ext = $objp->ref_ext; @@ -6185 +4967,0 @@ - @@ -6187 +4969,2 @@ - $this->product_label = $objp->product_label; + $this->libelle = $objp->product_libelle; // deprecated + $this->product_label = $objp->product_libelle; @@ -6189,2 +4972 @@ - - $this->fk_unit = $objp->fk_unit; + $this->fk_unit = $objp->fk_unit; @@ -6202,2 +4983,0 @@ - $this->fetch_optionals(); - @@ -6207,2 +4987,4 @@ - } else { - $this->error = $this->db->lasterror(); + } + else + { + $this->error = $this->db->lasterror(); @@ -6218,3 +5000,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function insert($notrigger = 0, $noerrorifdiscountalreadylinked = 0) + * @return int <0 if KO, >0 if OK + */ + public function insert($notrigger = 0, $noerrorifdiscountalreadylinked = 0) @@ -6226,3 +5008,3 @@ - $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == ''); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'. - - dol_syslog(get_class($this)."::insert rang=".$this->rang, LOG_DEBUG); + $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == ''); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'. + + dol_syslog(get_class($this)."::insert rang=".$this->rang, LOG_DEBUG); @@ -6232,64 +5014,21 @@ - if (empty($this->tva_tx)) { - $this->tva_tx = 0; - } - if (empty($this->localtax1_tx)) { - $this->localtax1_tx = 0; - } - if (empty($this->localtax2_tx)) { - $this->localtax2_tx = 0; - } - if (empty($this->localtax1_type)) { - $this->localtax1_type = 0; - } - if (empty($this->localtax2_type)) { - $this->localtax2_type = 0; - } - if (empty($this->total_localtax1)) { - $this->total_localtax1 = 0; - } - if (empty($this->total_localtax2)) { - $this->total_localtax2 = 0; - } - if (empty($this->rang)) { - $this->rang = 0; - } - if (empty($this->remise_percent)) { - $this->remise_percent = 0; - } - if (empty($this->info_bits)) { - $this->info_bits = 0; - } - if (empty($this->subprice)) { - $this->subprice = 0; - } - if (empty($this->ref_ext)) { - $this->ref_ext = ''; - } - if (empty($this->special_code)) { - $this->special_code = 0; - } - if (empty($this->fk_parent_line)) { - $this->fk_parent_line = 0; - } - if (empty($this->fk_prev_id)) { - $this->fk_prev_id = 0; - } - if (!isset($this->situation_percent) || $this->situation_percent > 100 || (string) $this->situation_percent == '') { - $this->situation_percent = 100; - } - - if (empty($this->pa_ht)) { - $this->pa_ht = 0; - } - if (empty($this->multicurrency_subprice)) { - $this->multicurrency_subprice = 0; - } - if (empty($this->multicurrency_total_ht)) { - $this->multicurrency_total_ht = 0; - } - if (empty($this->multicurrency_total_tva)) { - $this->multicurrency_total_tva = 0; - } - if (empty($this->multicurrency_total_ttc)) { - $this->multicurrency_total_ttc = 0; - } + if (empty($this->tva_tx)) $this->tva_tx = 0; + if (empty($this->localtax1_tx)) $this->localtax1_tx = 0; + if (empty($this->localtax2_tx)) $this->localtax2_tx = 0; + if (empty($this->localtax1_type)) $this->localtax1_type = 0; + if (empty($this->localtax2_type)) $this->localtax2_type = 0; + if (empty($this->total_localtax1)) $this->total_localtax1 = 0; + if (empty($this->total_localtax2)) $this->total_localtax2 = 0; + if (empty($this->rang)) $this->rang = 0; + if (empty($this->remise_percent)) $this->remise_percent = 0; + if (empty($this->info_bits)) $this->info_bits = 0; + if (empty($this->subprice)) $this->subprice = 0; + if (empty($this->special_code)) $this->special_code = 0; + if (empty($this->fk_parent_line)) $this->fk_parent_line = 0; + if (empty($this->fk_prev_id)) $this->fk_prev_id = 0; + if (!isset($this->situation_percent) || $this->situation_percent > 100 || (string) $this->situation_percent == '') $this->situation_percent = 100; + + if (empty($this->pa_ht)) $this->pa_ht = 0; + if (empty($this->multicurrency_subprice)) $this->multicurrency_subprice = 0; + if (empty($this->multicurrency_total_ht)) $this->multicurrency_total_ht = 0; + if (empty($this->multicurrency_total_tva)) $this->multicurrency_total_tva = 0; + if (empty($this->multicurrency_total_ttc)) $this->multicurrency_total_ttc = 0; @@ -6298,2 +5037,4 @@ - if ($this->pa_ht == 0 && $pa_ht_isemptystring) { - if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) { + if ($this->pa_ht == 0 && $pa_ht_isemptystring) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { @@ -6301 +5042,3 @@ - } else { + } + else + { @@ -6307 +5050,2 @@ - if ($this->product_type < 0) { + if ($this->product_type < 0) + { @@ -6311 +5055,2 @@ - if (!empty($this->fk_product) && $this->fk_product > 0) { + if (!empty($this->fk_product)) + { @@ -6314 +5059,2 @@ - if ($result <= 0) { + if ($result <= 0) + { @@ -6323 +5069 @@ - // Update line in database + // Insertion dans base de la ligne @@ -6327 +5073 @@ - $sql .= ' fk_product, product_type, remise_percent, subprice, ref_ext, fk_remise_except,'; + $sql .= ' fk_product, product_type, remise_percent, subprice, fk_remise_except,'; @@ -6340 +5086 @@ - $sql .= " ".(empty($this->vat_src_code) ? "''" : "'".$this->db->escape($this->vat_src_code)."'").","; + $sql .= " ".(empty($this->vat_src_code) ? "''" : "'".$this->db->escape($this->vat_src_code)."'").","; @@ -6346 +5092 @@ - $sql .= ' '.((!empty($this->fk_product) && $this->fk_product > 0) ? $this->fk_product : "null").','; + $sql .= ' '.(!empty($this->fk_product) ? $this->fk_product : "null").','; @@ -6350 +5095,0 @@ - $sql .= " '".$this->db->escape($this->ref_ext)."',"; @@ -6354,3 +5099,3 @@ - $sql .= ' '.((int) $this->fk_code_ventilation).','; - $sql .= ' '.((int) $this->rang).','; - $sql .= ' '.((int) $this->special_code).','; + $sql .= ' '.$this->fk_code_ventilation.','; + $sql .= ' '.$this->rang.','; + $sql .= ' '.$this->special_code.','; @@ -6365 +5110 @@ - $sql .= ", ".((float) $this->situation_percent); + $sql .= ", ".$this->situation_percent; @@ -6368,2 +5113,2 @@ - $sql .= ", ".((int) $user->id); - $sql .= ", ".((int) $user->id); + $sql .= ", ".$user->id; + $sql .= ", ".$user->id; @@ -6380 +5125,2 @@ - if ($resql) { + if ($resql) + { @@ -6384,10 +5130,13 @@ - if (!$error) { - $result = $this->insertExtraFields(); - if ($result < 0) { - $error++; - } - } - - // If fk_remise_except is defined, the discount is linked to the invoice - // which flags it as "consumed". - if ($this->fk_remise_except) { + if (!$error) + { + $result = $this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + // Si fk_remise_except defini, on lie la remise a la facture + // ce qui la flague comme "consommee". + if ($this->fk_remise_except) + { @@ -6396 +5145,2 @@ - if ($result >= 0) { + if ($result >= 0) + { @@ -6398,10 +5148,15 @@ - if ($result > 0) { - // Check if discount not already affected to another invoice - if ($discount->fk_facture_line > 0) { - if (empty($noerrorifdiscountalreadylinked)) { - $this->error = $langs->trans("ErrorDiscountAlreadyUsed", $discount->id); - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; - } - } else { + if ($result > 0) + { + // Check if discount not already affected to another invoice + if ($discount->fk_facture_line > 0) + { + if (empty($noerrorifdiscountalreadylinked)) + { + $this->error = $langs->trans("ErrorDiscountAlreadyUsed", $discount->id); + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } + } + else + { @@ -6409 +5164,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -6416 +5172,3 @@ - } else { + } + else + { @@ -6422 +5180,3 @@ - } else { + } + else + { @@ -6430,4 +5190,6 @@ - if (!$notrigger) { - // Call trigger - $result = $this->call_trigger('LINEBILL_INSERT', $user); - if ($result < 0) { + if (!$notrigger) + { + // Call trigger + $result = $this->call_trigger('LINEBILL_INSERT', $user); + if ($result < 0) + { @@ -6437 +5199 @@ - // End call triggers + // End call triggers @@ -6442 +5204,3 @@ - } else { + } + else + { @@ -6454,3 +5218,3 @@ - * @return int Return integer <0 if KO, >0 if OK - */ - public function update($user = null, $notrigger = 0) + * @return int <0 if KO, >0 if OK + */ + public function update($user = '', $notrigger = 0) @@ -6466,58 +5230,19 @@ - if (empty($this->ref_ext)) { - $this->ref_ext = ''; - } - if (empty($this->tva_tx)) { - $this->tva_tx = 0; - } - if (empty($this->localtax1_tx)) { - $this->localtax1_tx = 0; - } - if (empty($this->localtax2_tx)) { - $this->localtax2_tx = 0; - } - if (empty($this->localtax1_type)) { - $this->localtax1_type = 0; - } - if (empty($this->localtax2_type)) { - $this->localtax2_type = 0; - } - if (empty($this->total_localtax1)) { - $this->total_localtax1 = 0; - } - if (empty($this->total_localtax2)) { - $this->total_localtax2 = 0; - } - if (empty($this->remise_percent)) { - $this->remise_percent = 0; - } - if (empty($this->info_bits)) { - $this->info_bits = 0; - } - if (empty($this->special_code)) { - $this->special_code = 0; - } - if (empty($this->product_type)) { - $this->product_type = 0; - } - if (empty($this->fk_parent_line)) { - $this->fk_parent_line = 0; - } - if (!isset($this->situation_percent) || $this->situation_percent > 100 || (string) $this->situation_percent == '') { - $this->situation_percent = 100; - } - if (empty($this->pa_ht)) { - $this->pa_ht = 0; - } - - if (empty($this->multicurrency_subprice)) { - $this->multicurrency_subprice = 0; - } - if (empty($this->multicurrency_total_ht)) { - $this->multicurrency_total_ht = 0; - } - if (empty($this->multicurrency_total_tva)) { - $this->multicurrency_total_tva = 0; - } - if (empty($this->multicurrency_total_ttc)) { - $this->multicurrency_total_ttc = 0; - } + if (empty($this->tva_tx)) $this->tva_tx = 0; + if (empty($this->localtax1_tx)) $this->localtax1_tx = 0; + if (empty($this->localtax2_tx)) $this->localtax2_tx = 0; + if (empty($this->localtax1_type)) $this->localtax1_type = 0; + if (empty($this->localtax2_type)) $this->localtax2_type = 0; + if (empty($this->total_localtax1)) $this->total_localtax1 = 0; + if (empty($this->total_localtax2)) $this->total_localtax2 = 0; + if (empty($this->remise_percent)) $this->remise_percent = 0; + if (empty($this->info_bits)) $this->info_bits = 0; + if (empty($this->special_code)) $this->special_code = 0; + if (empty($this->product_type)) $this->product_type = 0; + if (empty($this->fk_parent_line)) $this->fk_parent_line = 0; + if (!isset($this->situation_percent) || $this->situation_percent > 100 || (string) $this->situation_percent == '') $this->situation_percent = 100; + if (empty($this->pa_ht)) $this->pa_ht = 0; + + if (empty($this->multicurrency_subprice)) $this->multicurrency_subprice = 0; + if (empty($this->multicurrency_total_ht)) $this->multicurrency_total_ht = 0; + if (empty($this->multicurrency_total_tva)) $this->multicurrency_total_tva = 0; + if (empty($this->multicurrency_total_ttc)) $this->multicurrency_total_ttc = 0; @@ -6526,9 +5251,7 @@ - if ($this->product_type < 0) { - return -1; - } - - // if buy price not provided, define buyprice as configured in margin admin - if ($this->pa_ht == 0 && $pa_ht_isemptystring) { - // We call defineBuyPrice only if data was not provided (if input was '0', we will not go here and value will remaine '0') - $result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product); - if ($result < 0) { + if ($this->product_type < 0) return -1; + + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0 && $pa_ht_isemptystring) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { @@ -6536 +5259,3 @@ - } else { + } + else + { @@ -6543,12 +5268,8 @@ - // Update line in database - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; - $sql .= " description='".$this->db->escape($this->desc)."'"; - $sql .= ", ref_ext='".$this->db->escape($this->ref_ext)."'"; - $sql .= ", label=".(!empty($this->label) ? "'".$this->db->escape($this->label)."'" : "null"); - $sql .= ", subprice=".price2num($this->subprice); - $sql .= ", remise_percent=".price2num($this->remise_percent); - if ($this->fk_remise_except) { - $sql .= ", fk_remise_except=".$this->fk_remise_except; - } else { - $sql .= ", fk_remise_except=null"; - } + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; + $sql .= " description='".$this->db->escape($this->desc)."'"; + $sql .= ", label=".(!empty($this->label) ? "'".$this->db->escape($this->label)."'" : "null"); + $sql .= ", subprice=".price2num($this->subprice).""; + $sql .= ", remise_percent=".price2num($this->remise_percent).""; + if ($this->fk_remise_except) $sql .= ", fk_remise_except=".$this->fk_remise_except; + else $sql .= ", fk_remise_except=null"; @@ -6556,3 +5277,3 @@ - $sql .= ", tva_tx=".price2num($this->tva_tx); - $sql .= ", localtax1_tx=".price2num($this->localtax1_tx); - $sql .= ", localtax2_tx=".price2num($this->localtax2_tx); + $sql .= ", tva_tx=".price2num($this->tva_tx).""; + $sql .= ", localtax1_tx=".price2num($this->localtax1_tx).""; + $sql .= ", localtax2_tx=".price2num($this->localtax2_tx).""; @@ -6561,13 +5282,14 @@ - $sql .= ", qty=".price2num($this->qty); - $sql .= ", date_start=".(!empty($this->date_start) ? "'".$this->db->idate($this->date_start)."'" : "null"); - $sql .= ", date_end=".(!empty($this->date_end) ? "'".$this->db->idate($this->date_end)."'" : "null"); - $sql .= ", product_type=".$this->product_type; - $sql .= ", info_bits='".$this->db->escape($this->info_bits)."'"; - $sql .= ", special_code='".$this->db->escape($this->special_code)."'"; - if (empty($this->skip_update_total)) { - $sql .= ", total_ht=".price2num($this->total_ht); - $sql .= ", total_tva=".price2num($this->total_tva); - $sql .= ", total_ttc=".price2num($this->total_ttc); - $sql .= ", total_localtax1=".price2num($this->total_localtax1); - $sql .= ", total_localtax2=".price2num($this->total_localtax2); - } + $sql .= ", qty=".price2num($this->qty); + $sql .= ", date_start=".(!empty($this->date_start) ? "'".$this->db->idate($this->date_start)."'" : "null"); + $sql .= ", date_end=".(!empty($this->date_end) ? "'".$this->db->idate($this->date_end)."'" : "null"); + $sql .= ", product_type=".$this->product_type; + $sql .= ", info_bits='".$this->db->escape($this->info_bits)."'"; + $sql .= ", special_code='".$this->db->escape($this->special_code)."'"; + if (empty($this->skip_update_total)) + { + $sql .= ", total_ht=".price2num($this->total_ht); + $sql .= ", total_tva=".price2num($this->total_tva); + $sql .= ", total_ttc=".price2num($this->total_ttc); + $sql .= ", total_localtax1=".price2num($this->total_localtax1); + $sql .= ", total_localtax2=".price2num($this->total_localtax2); + } @@ -6575 +5297 @@ - $sql .= ", buy_price_ht=".(($this->pa_ht || (string) $this->pa_ht === '0') ? price2num($this->pa_ht) : "null"); // $this->pa_ht should always be defined (set to 0 or to sell price depending on option) + $sql .= ", buy_price_ht='".price2num($this->pa_ht)."'"; @@ -6577,6 +5299,4 @@ - if (!empty($this->rang)) { - $sql .= ", rang=".((int) $this->rang); - } - $sql .= ", situation_percent = ".((float) $this->situation_percent); - $sql .= ", fk_unit = ".(!$this->fk_unit ? 'NULL' : $this->fk_unit); - $sql .= ", fk_user_modif = ".((int) $user->id); + if (!empty($this->rang)) $sql .= ", rang=".$this->rang; + $sql .= ", situation_percent=".$this->situation_percent; + $sql .= ", fk_unit=".(!$this->fk_unit ? 'NULL' : $this->fk_unit); + $sql .= ", fk_user_modif =".$user->id; @@ -6585,6 +5305,6 @@ - $sql .= ", multicurrency_subprice=".price2num($this->multicurrency_subprice); - $sql .= ", multicurrency_total_ht=".price2num($this->multicurrency_total_ht); - $sql .= ", multicurrency_total_tva=".price2num($this->multicurrency_total_tva); - $sql .= ", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc); - - $sql .= " WHERE rowid = ".((int) $this->rowid); + $sql .= ", multicurrency_subprice=".price2num($this->multicurrency_subprice).""; + $sql .= ", multicurrency_total_ht=".price2num($this->multicurrency_total_ht).""; + $sql .= ", multicurrency_total_tva=".price2num($this->multicurrency_total_tva).""; + $sql .= ", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc).""; + + $sql .= " WHERE rowid = ".$this->rowid; @@ -6594,13 +5314,18 @@ - if ($resql) { - if (!$error) { - $this->id = $this->rowid; - $result = $this->insertExtraFields(); - if ($result < 0) { - $error++; - } - } - - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('LINEBILL_MODIFY', $user); - if ($result < 0) { + if ($resql) + { + if (!$error) + { + $this->id = $this->rowid; + $result = $this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('LINEBILL_UPDATE', $user); + if ($result < 0) + { @@ -6610 +5335 @@ - // End call triggers + // End call triggers @@ -6614 +5339,3 @@ - } else { + } + else + { @@ -6622,7 +5349,6 @@ - * Delete line in database - * - * @param User $tmpuser User that deletes - * @param bool $notrigger false=launch triggers after, true=disable triggers - * @return int Return integer <0 if KO, >0 if OK - */ - public function delete($tmpuser = null, $notrigger = false) + * Delete line in database + * TODO Add param User $user and notrigger (see skeleton) + * + * @return int <0 if KO, >0 if OK + */ + public function delete() @@ -6635,12 +5361,3 @@ - if (empty($notrigger)) { - $result = $this->call_trigger('LINEBILL_DELETE', $user); - if ($result < 0) { - $this->db->rollback(); - return -1; - } - } - // End call triggers - - // extrafields - $result = $this->deleteExtraFields(); - if ($result < 0) { + $result = $this->call_trigger('LINEBILL_DELETE', $user); + if ($result < 0) + { @@ -6650,11 +5367,20 @@ - - // Free discount linked to invoice line - $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql .= ' SET fk_facture_line = NULL'; - $sql .= ' WHERE fk_facture_line = '.((int) $this->id); - - dol_syslog(get_class($this)."::deleteline", LOG_DEBUG); - $result = $this->db->query($sql); - if (!$result) { - $this->error = $this->db->error(); - $this->errors[] = $this->error; + // End call triggers + + // extrafields + $result = $this->deleteExtraFields(); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet WHERE rowid = ".$this->rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->db->commit(); + return 1; + } + else + { + $this->error = $this->db->error()." sql=".$sql; @@ -6664,14 +5390,33 @@ - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'element_time'; - $sql .= ' SET invoice_id = NULL, invoice_line_id = NULL'; - $sql .= ' WHERE invoice_line_id = '.((int) $this->id); - if (!$this->db->query($sql)) { - $this->error = $this->db->error()." sql=".$sql; - $this->errors[] = $this->error; - $this->db->rollback(); - return -1; - } - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet WHERE rowid = ".((int) $this->id); - - if ($this->db->query($sql)) { + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Update DB line fields total_xxx + * Used by migration + * + * @return int <0 if KO, >0 if OK + */ + public function update_total() + { + // phpcs:enable + $this->db->begin(); + dol_syslog(get_class($this)."::update_total", LOG_DEBUG); + + // Clean parameters + if (empty($this->total_localtax1)) $this->total_localtax1 = 0; + if (empty($this->total_localtax2)) $this->total_localtax2 = 0; + + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; + $sql .= " total_ht=".price2num($this->total_ht).""; + $sql .= ",total_tva=".price2num($this->total_tva).""; + $sql .= ",total_localtax1=".price2num($this->total_localtax1).""; + $sql .= ",total_localtax2=".price2num($this->total_localtax2).""; + $sql .= ",total_ttc=".price2num($this->total_ttc).""; + $sql .= " WHERE rowid = ".$this->rowid; + + dol_syslog(get_class($this)."::update_total", LOG_DEBUG); + + $resql = $this->db->query($sql); + if ($resql) + { @@ -6680,45 +5425,3 @@ - } else { - $this->error = $this->db->error()." sql=".$sql; - $this->errors[] = $this->error; - $this->db->rollback(); - return -1; - } - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Update DB line fields total_xxx - * Used by migration - * - * @return int Return integer <0 if KO, >0 if OK - */ - public function update_total() - { - // phpcs:enable - $this->db->begin(); - dol_syslog(get_class($this)."::update_total", LOG_DEBUG); - - // Clean parameters - if (empty($this->total_localtax1)) { - $this->total_localtax1 = 0; - } - if (empty($this->total_localtax2)) { - $this->total_localtax2 = 0; - } - - // Update line in database - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; - $sql .= " total_ht=".price2num($this->total_ht); - $sql .= ",total_tva=".price2num($this->total_tva); - $sql .= ",total_localtax1=".price2num($this->total_localtax1); - $sql .= ",total_localtax2=".price2num($this->total_localtax2); - $sql .= ",total_ttc=".price2num($this->total_ttc); - $sql .= " WHERE rowid = ".((int) $this->rowid); - - dol_syslog(get_class($this)."::update_total", LOG_DEBUG); - - $resql = $this->db->query($sql); - if ($resql) { - $this->db->commit(); - return 1; - } else { + } + else + { @@ -6731 +5434 @@ - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -6736 +5439 @@ - * @param int $invoiceid Invoice id + * @param int $invoiceid Invoice id @@ -6738,3 +5441,3 @@ - * @return int >= 0 - */ - public function get_prev_progress($invoiceid, $include_credit_note = true) + * @return int >= 0 + */ + public function get_prev_progress($invoiceid, $include_credit_note = true) @@ -6742 +5445 @@ - // phpcs:enable + // phpcs:enable @@ -6744 +5446,0 @@ - @@ -6748 +5450 @@ - // If invoice is not a situation invoice, this->fk_prev_id is used for something else + // If invoice is not a situation invoice, this->fk_prev_id is used for something else @@ -6753,5 +5455,3 @@ - if ($invoicecache[$invoiceid]->type != Facture::TYPE_SITUATION) { - return 0; - } - - $sql = "SELECT situation_percent FROM ".MAIN_DB_PREFIX."facturedet WHERE rowid = ".((int) $this->fk_prev_id); + if ($invoicecache[$invoiceid]->type != Facture::TYPE_SITUATION) return 0; + + $sql = 'SELECT situation_percent FROM '.MAIN_DB_PREFIX.'facturedet WHERE rowid='.$this->fk_prev_id; @@ -6759 +5459 @@ - if ($resql && $this->db->num_rows($resql) > 0) { + if ($resql && $resql->num_rows > 0) { @@ -6762 +5462 @@ - $returnPercent = (float) $res['situation_percent']; + $returnPercent = floatval($res['situation_percent']); @@ -6765,14 +5465,14 @@ - $sql = 'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.'facturedet fd'; - $sql .= ' JOIN '.MAIN_DB_PREFIX.'facture f ON (f.rowid = fd.fk_facture) '; - $sql .= " WHERE fd.fk_prev_id = ".((int) $this->fk_prev_id); - $sql .= " AND f.situation_cycle_ref = ".((int) $invoicecache[$invoiceid]->situation_cycle_ref); // Prevent cycle outed - $sql .= " AND f.type = ".Facture::TYPE_CREDIT_NOTE; - - $res = $this->db->query($sql); - if ($res) { - while ($obj = $this->db->fetch_object($res)) { - $returnPercent = $returnPercent + (float) $obj->situation_percent; - } - } else { - dol_print_error($this->db); - } + $sql = 'SELECT fd.situation_percent FROM '.MAIN_DB_PREFIX.'facturedet fd'; + $sql .= ' JOIN '.MAIN_DB_PREFIX.'facture f ON (f.rowid = fd.fk_facture) '; + $sql .= ' WHERE fd.fk_prev_id ='.$this->fk_prev_id; + $sql .= ' AND f.situation_cycle_ref = '.$invoicecache[$invoiceid]->situation_cycle_ref; // Prevent cycle outed + $sql .= ' AND f.type = '.Facture::TYPE_CREDIT_NOTE; + + $res = $this->db->query($sql); + if ($res) { + while ($obj = $this->db->fetch_object($res)) { + $returnPercent = $returnPercent + floatval($obj->situation_percent); + } + } else { + dol_print_error($this->db); + } --- /tmp/dsg/dolibarr/htdocs/compta/facture/class/github_19.0.3_facturestats.class.php +++ /tmp/dsg/dolibarr/htdocs/compta/facture/class/client_facturestats.class.php @@ -36,4 +36,4 @@ - public $socid; - public $userid; - - /** + public $socid; + public $userid; + + /** @@ -44,9 +44,9 @@ - public $from; - public $field; - public $where; - public $join; - - - /** - * Constructor - * + public $from; + public $field; + public $where; + public $join; + + + /** + * Constructor + * @@ -56,5 +56,5 @@ - * @param int $userid Id user for filter (creation user) - * @param int $typentid Id typent of thirdpary for filter - * @param int $categid Id category of thirdpary for filter - */ - public function __construct(DoliDB $db, $socid, $mode, $userid = 0, $typentid = 0, $categid = 0) + * @param int $userid Id user for filter (creation user) + * @param int $typentid Id typent of thirdpary for filter + * @param int $categid Id category of thirdpary for filter + */ + public function __construct($db, $socid, $mode, $userid = 0, $typentid = 0, $categid = 0) @@ -65,2 +65,2 @@ - $this->socid = ($socid > 0 ? $socid : 0); - $this->userid = $userid; + $this->socid = ($socid > 0 ? $socid : 0); + $this->userid = $userid; @@ -68,3 +68,4 @@ - $this->join = ''; - - if ($mode == 'customer') { + $this->join = ''; + + if ($mode == 'customer') + { @@ -74 +75 @@ - $this->field = 'total_ht'; + $this->field = 'total'; @@ -77 +78,2 @@ - if ($mode == 'supplier') { + if ($mode == 'supplier') + { @@ -88,2 +90,5 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$this->socid) { - $this->where .= " AND f.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); + if (!$user->rights->societe->client->voir && !$this->socid) $this->where .= " AND f.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id; + if ($mode == 'customer') $this->where .= " AND (f.fk_statut <> 3 OR f.close_code <> 'replaced')"; // Exclude replaced invoices as they are duplicated (we count closed invoices for other reasons) + if ($this->socid) + { + $this->where .= " AND f.fk_soc = ".$this->socid; @@ -91,32 +96,16 @@ - if ($mode == 'customer') { - $this->where .= " AND (f.fk_statut <> 3 OR f.close_code <> 'replaced')"; // Exclude replaced invoices as they are duplicated (we count closed invoices for other reasons) - } - if ($this->socid) { - $this->where .= " AND f.fk_soc = ".((int) $this->socid); - } - if ($this->userid > 0) { - $this->where .= ' AND f.fk_user_author = '.((int) $this->userid); - } - if ($mode == 'customer') { - if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) { - $this->where .= " AND f.type IN (0,1,2,5)"; - } else { - $this->where .= " AND f.type IN (0,1,2,3,5)"; - } - } - if ($mode == 'supplier') { - if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { - $this->where .= " AND f.type IN (0,1,2,5)"; - } else { - $this->where .= " AND f.type IN (0,1,2,3,5)"; - } - } - - if ($typentid) { - $this->join .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON s.rowid = f.fk_soc'; - $this->where .= ' AND s.fk_typent = '.((int) $typentid); - } - - if ($categid) { - $this->where .= ' AND EXISTS (SELECT rowid FROM '.MAIN_DB_PREFIX.'categorie_societe as cats WHERE cats.fk_soc = f.fk_soc AND cats.fk_categorie = '.((int) $categid).')'; - } + if ($this->userid > 0) $this->where .= ' AND f.fk_user_author = '.$this->userid; + if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $this->where .= " AND f.type IN (0,1,2,5)"; + else $this->where .= " AND f.type IN (0,1,2,3,5)"; + + if ($typentid) + { + $this->join .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON s.rowid = f.fk_soc'; + $this->where .= ' AND s.fk_typent = '.$typentid; + } + + if ($categid) + { + $this->join .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_societe as cs ON cs.fk_soc = f.fk_soc'; + $this->join .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie as c ON c.rowid = cs.fk_categorie'; + $this->where .= ' AND c.rowid = '.$categid; + } @@ -130 +119 @@ - * @param int $format 0=Label of abscissa is a translated text, 1=Label of abscissa is month number, 2=Label of abscissa is first letter of month + * @param int $format 0=Label of abscissa is a translated text, 1=Label of abscissa is month number, 2=Label of abscissa is first letter of month @@ -139,4 +128,2 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql .= $this->join; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= $this->join; @@ -146 +133 @@ - $sql .= $this->db->order('dm', 'DESC'); + $sql .= $this->db->order('dm', 'DESC'); @@ -165,4 +152,2 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql .= $this->join; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= $this->join; @@ -171 +156 @@ - $sql .= $this->db->order('dm', 'DESC'); + $sql .= $this->db->order('dm', 'DESC'); @@ -181 +166 @@ - * @param int $format 0=Label of abscissa is a translated text, 1=Label of abscissa is month number, 2=Label of abscissa is first letter of month + * @param int $format 0=Label of abscissa is a translated text, 1=Label of abscissa is month number, 2=Label of abscissa is first letter of month @@ -190,4 +175,2 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql .= $this->join; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= $this->join; @@ -196,2 +179,2 @@ - $sql .= " GROUP BY dm"; - $sql .= $this->db->order('dm', 'DESC'); + $sql .= " GROUP BY dm"; + $sql .= $this->db->order('dm', 'DESC'); @@ -216,5 +199,3 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql .= $this->join; - $sql .= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= $this->join; + $sql .= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -222,2 +203,2 @@ - $sql .= " GROUP BY dm"; - $sql .= $this->db->order('dm', 'DESC'); + $sql .= " GROUP BY dm"; + $sql .= $this->db->order('dm', 'DESC'); @@ -239,4 +220,2 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql .= $this->join; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= $this->join; @@ -245 +224 @@ - $sql .= $this->db->order('year', 'DESC'); + $sql .= $this->db->order('year', 'DESC'); @@ -254 +233 @@ - * @param int $limit Limit + * @param int $limit Limit @@ -263,4 +242,2 @@ - if (!$user->hasRight('societe', 'client', 'voir') && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql .= $this->join; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= $this->join; @@ -269 +246 @@ - $sql .= " AND f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'"; + $sql .= " AND f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'"; @@ -271,31 +248,4 @@ - $sql .= $this->db->order('nb', 'DESC'); - //$sql.= $this->db->plimit(20); - - return $this->_getAllByProduct($sql, $limit); - } - /** - * Return the invoices amount by year for a number of past years - * - * @param int $numberYears Years to scan - * @param int $format 0=Label of abscissa is a translated text, 1=Label of abscissa is year, 2=Label of abscissa is last number of year - * @return array Array with amount by year - */ - public function getAmountByYear($numberYears, $format = 0) - { - global $user; - - $endYear = date('Y'); - $startYear = $endYear - $numberYears; - $sql = "SELECT date_format(datef,'%Y') as dm, SUM(f.".$this->field.")"; - $sql .= " FROM ".$this->from; - if (!$user->hasRight('societe', 'client', 'voir') && !$this->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql .= $this->join; - $sql .= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($startYear))."' AND '".$this->db->idate(dol_get_last_day($endYear))."'"; - $sql .= " AND ".$this->where; - $sql .= " GROUP BY dm"; - $sql .= $this->db->order('dm', 'ASC'); - - $res = $this->_getAmountByYear($sql); - return $res; + $sql .= $this->db->order('nb', 'DESC'); + //$sql.= $this->db->plimit(20); + + return $this->_getAllByProduct($sql, $limit); --- /tmp/dsg/dolibarr/htdocs/compta/facture/class/github_19.0.3_paymentterm.class.php +++ /tmp/dsg/dolibarr/htdocs/compta/facture/class/client_paymentterm.class.php @@ -31,3 +31,3 @@ - * @var DoliDB Database handler. - */ - public $db; + * @var DoliDB Database handler. + */ + public $db; @@ -49 +49 @@ - /** + /** @@ -53,6 +52,0 @@ - - - /** - * @var int Entity ID - */ - public $entity; @@ -72,3 +66,3 @@ - /** - * Constructor - * + /** + * Constructor + * @@ -76,17 +70,17 @@ - */ - public function __construct(DoliDB $db) - { - $this->db = $db; - } - - - /** - * Create in database - * - * @param User $user User that create - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int Return integer <0 if KO, Id of created object if OK - */ - public function create($user, $notrigger = 0) - { - global $conf, $langs; + */ + public function __construct($db) + { + $this->db = $db; + } + + + /** + * Create in database + * + * @param User $user User that create + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + public function create($user, $notrigger = 0) + { + global $conf, $langs; @@ -97,24 +91,8 @@ - if (isset($this->code)) { - $this->code = trim($this->code); - } - if (isset($this->sortorder)) { - $this->sortorder = trim($this->sortorder); - } - if (isset($this->active)) { - $this->active = trim($this->active); - } - if (isset($this->libelle)) { - $this->libelle = trim($this->libelle); - } - if (isset($this->libelle_facture)) { - $this->libelle_facture = trim($this->libelle_facture); - } - if (isset($this->type_cdr)) { - $this->type_cdr = trim($this->type_cdr); - } - if (isset($this->nbjour)) { - $this->nbjour = trim($this->nbjour); - } - if (isset($this->decalage)) { - $this->decalage = trim($this->decalage); - } + if (isset($this->code)) $this->code = trim($this->code); + if (isset($this->sortorder)) $this->sortorder = trim($this->sortorder); + if (isset($this->active)) $this->active = trim($this->active); + if (isset($this->libelle)) $this->libelle = trim($this->libelle); + if (isset($this->libelle_facture)) $this->libelle_facture = trim($this->libelle_facture); + if (isset($this->type_cdr)) $this->type_cdr = trim($this->type_cdr); + if (isset($this->nbjour)) $this->nbjour = trim($this->nbjour); + if (isset($this->decalage)) $this->decalage = trim($this->decalage); @@ -126 +104 @@ - // Insert request + // Insert request @@ -137,2 +115,2 @@ - $sql .= ") VALUES ("; - $sql .= " ".(!isset($this->entity) ? getEntity('c_payment_term') : "'".$this->db->escape($this->entity)."'").","; + $sql .= ") VALUES ("; + $sql .= " ".(!isset($this->entity) ?getEntity('c_payment_term') : "'".$this->db->escape($this->entity)."'").","; @@ -146 +124 @@ - $sql .= " ".(!isset($this->decalage) ? 'NULL' : "'".$this->db->escape($this->decalage)."'"); + $sql .= " ".(!isset($this->decalage) ? 'NULL' : "'".$this->db->escape($this->decalage)."'").""; @@ -151,16 +129,16 @@ - dol_syslog(get_class($this)."::create", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = "Error ".$this->db->lasterror(); - } - - if (!$error) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."c_payment_term"); - } - - // Commit or rollback - if ($error) { - foreach ($this->errors as $errmsg) { - dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); - $this->error .= ($this->error ? ', '.$errmsg : $errmsg); + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } + + if (!$error) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."c_payment_term"); + } + + // Commit or rollback + if ($error) + { + foreach ($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); + $this->error .= ($this->error ? ', '.$errmsg : $errmsg); @@ -170 +148,3 @@ - } else { + } + else + { @@ -172,15 +152,15 @@ - return $this->id; - } - } - - - /** - * Load object in memory from database - * - * @param int $id Id object - * @param string $code Code object - * @return int Return integer <0 if KO, >0 if OK - */ - public function fetch($id, $code = '') - { - $sql = "SELECT"; + return $this->id; + } + } + + + /** + * Load object in memory from database + * + * @param int $id Id object + * @return int <0 if KO, >0 if OK + */ + public function fetch($id) + { + global $langs; + $sql = "SELECT"; @@ -188,0 +169 @@ + @@ -197,15 +178,14 @@ - $sql .= " FROM ".MAIN_DB_PREFIX."c_payment_term as t"; - if ($id) { - $sql .= " WHERE t.rowid = ".((int) $id); - } - if ($code) { - $sql .= " WHERE t.code='".$this->db->escape($code)."' AND t.entity IN (".getEntity('payment_term').")"; - } - - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) { - if ($this->db->num_rows($resql)) { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->rowid; + + + $sql .= " FROM ".MAIN_DB_PREFIX."c_payment_term as t"; + $sql .= " WHERE t.rowid = ".$id; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; @@ -221,16 +201,18 @@ - } - $this->db->free($resql); - - return 1; - } else { - $this->error = "Error ".$this->db->lasterror(); - return -1; - } - } - - - /** - * Return id of default payment term - * - * @return int Return integer <0 if KO, >0 if OK - */ + } + $this->db->free($resql); + + return 1; + } + else + { + $this->error = "Error ".$this->db->lasterror(); + return -1; + } + } + + + /** + * Return id of default payment term + * + * @return int <0 if KO, >0 if OK + */ @@ -251,2 +233,4 @@ - if ($resql) { - if ($this->db->num_rows($resql)) { + if ($resql) + { + if ($this->db->num_rows($resql)) + { @@ -254,3 +238 @@ - if ($obj) { - $ret = $obj->rowid; - } + if ($obj) $ret = $obj->rowid; @@ -260 +242,3 @@ - } else { + } + else + { @@ -268,6 +252,6 @@ - * Update database - * - * @param User $user User that modify - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int Return integer <0 if KO, >0 if OK - */ + * 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 + */ @@ -282,24 +266,8 @@ - if (isset($this->code)) { - $this->code = trim($this->code); - } - if (isset($this->sortorder)) { - $this->sortorder = trim($this->sortorder); - } - if (isset($this->active)) { - $this->active = trim($this->active); - } - if (isset($this->libelle)) { - $this->libelle = trim($this->libelle); - } - if (isset($this->libelle_facture)) { - $this->libelle_facture = trim($this->libelle_facture); - } - if (isset($this->type_cdr)) { - $this->type_cdr = trim($this->type_cdr); - } - if (isset($this->nbjour)) { - $this->nbjour = trim($this->nbjour); - } - if (isset($this->decalage)) { - $this->decalage = trim($this->decalage); - } + if (isset($this->code)) $this->code = trim($this->code); + if (isset($this->sortorder)) $this->sortorder = trim($this->sortorder); + if (isset($this->active)) $this->active = trim($this->active); + if (isset($this->libelle)) $this->libelle = trim($this->libelle); + if (isset($this->libelle_facture)) $this->libelle_facture = trim($this->libelle_facture); + if (isset($this->type_cdr)) $this->type_cdr = trim($this->type_cdr); + if (isset($this->nbjour)) $this->nbjour = trim($this->nbjour); + if (isset($this->decalage)) $this->decalage = trim($this->decalage); @@ -321,2 +289,2 @@ - $sql .= " decalage=".(isset($this->decalage) ? $this->decalage : "null"); - $sql .= " WHERE rowid = ".((int) $this->id); + $sql .= " decalage=".(isset($this->decalage) ? $this->decalage : "null").""; + $sql .= " WHERE rowid = ".$this->id; @@ -328,4 +296 @@ - if (!$resql) { - $error++; - $this->errors[] = "Error ".$this->db->lasterror(); - } + if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } @@ -334,2 +299,4 @@ - if ($error) { - foreach ($this->errors as $errmsg) { + if ($error) + { + foreach ($this->errors as $errmsg) + { @@ -341 +308,3 @@ - } else { + } + else + { @@ -353 +322 @@ - * @return int Return integer <0 if KO, >0 if OK + * @return int <0 if KO, >0 if OK @@ -361 +330 @@ - $sql .= " WHERE rowid = ".((int) $this->id); + $sql .= " WHERE rowid = ".$this->id; @@ -367,10 +336,9 @@ - if (!$resql) { - $error++; - $this->errors[] = "Error ".$this->db->lasterror(); - } - - // Commit or rollback - if ($error) { - foreach ($this->errors as $errmsg) { - dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); - $this->error .= ($this->error ? ', '.$errmsg : $errmsg); + if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } + + // Commit or rollback + if ($error) + { + foreach ($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error .= ($this->error ? ', '.$errmsg : $errmsg); @@ -380 +348,3 @@ - } else { + } + else + { @@ -405,0 +376,4 @@ + $object->statut = 0; + + // Clear fields + // ... @@ -412 +386,2 @@ - if ($result < 0) { + if ($result < 0) + { @@ -420 +395,2 @@ - if (!$error) { + if (!$error) + { @@ -423 +399,3 @@ - } else { + } + else + { @@ -430,9 +408,9 @@ - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return void - */ - public function initAsSpecimen() - { + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + public function initAsSpecimen() + {