/htdocs/facture/facture.php
PHP | 2985 lines | 2268 code | 347 blank | 370 comment | 1010 complexity | cdbf5f8b60e3127b4a250dee586ce023 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-3.0, MIT
Large files files are truncated, but you can click here to view the full file
- <?php
- /* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
- * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
- * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
- * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
- * Copyright (C) 2010-2012 Juanjo Menent <jmenent@2byte.es>
- * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
- * Copyright (C) 2011-2012 Herve Prot <herve.prot@symeos.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /**
- * \file htdocs/compta/facture.php
- * \ingroup facture
- * \brief Page to create/see an invoice
- */
- require '../main.inc.php';
- require DOL_DOCUMENT_ROOT . '/facture/class/facture.class.php';
- require DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
- require DOL_DOCUMENT_ROOT . '/facture/core/modules/facture/modules_facture.php';
- require DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
- require DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
- require DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
- require DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php';
- require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
- require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
- if (!empty($conf->commande->enabled)) {
- require DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
- }
- if (!empty($conf->projet->enabled)) {
- require DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
- require DOL_DOCUMENT_ROOT . '/core/lib/project.lib.php';
- }
- $langs->load('bills');
- $langs->load('companies');
- $langs->load('products');
- $langs->load('main');
- if (!empty($conf->margin->enabled))
- $langs->load('margins');
- $sall = trim(GETPOST('sall'));
- $projectid = (GETPOST('projectid') ? GETPOST('projectid', 'int') : 0);
- $id = (GETPOST('id', 'alpha') ? GETPOST('id', 'akpha') : GETPOST('facid', 'alpha')); // For backward compatibility
- $ref = GETPOST('ref', 'alpha');
- $socid = GETPOST('socid', 'alpha');
- $action = GETPOST('action', 'alpha');
- $confirm = GETPOST('confirm', 'alpha');
- $lineid = GETPOST('lineid', 'alpha');
- $userid = GETPOST('userid', 'alpha');
- $search_ref = GETPOST('sf_ref') ? GETPOST('sf_ref', 'alpha') : GETPOST('search_ref', 'alpha');
- $search_societe = GETPOST('search_societe', 'alpha');
- $search_montant_ht = GETPOST('search_montant_ht', 'alpha');
- $search_montant_ttc = GETPOST('search_montant_ttc', 'alpha');
- $origin = GETPOST('origin', 'alpha');
- $originid = (GETPOST('originid', 'alpha') ? GETPOST('originid', 'alpha') : GETPOST('origin_id', 'alpha')); // For backward compatibility
- //PDF
- $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
- $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
- $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
- // Security check
- $fieldid = (!empty($ref) ? 'facnumber' : 'rowid');
- if ($user->societe_id)
- $socid = $user->societe_id;
- $result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid);
- // Nombre de ligne pour choix de produit/service predefinis
- $NBLINES = 4;
- $usehm = (!empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE) ? $conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE : 0);
- $object = new Facture($db);
- // Load object
- if (!empty($id) || !empty($ref)) {
- $ret = $object->fetch($id, $ref);
- }
- // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
- $hookmanager->initHooks(array('invoicecard'));
- /*
- * Actions
- */
- $parameters = array('socid' => $socid);
- $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
- // Action clone object
- if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer) {
- if (1 == 0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) {
- $mesgs[] = '<div class="error">' . $langs->trans("NoCloneOptionsSpecified") . '</div>';
- } else {
- if ($object->fetch($id) > 0) {
- $result = $object->createFromClone($socid);
- if ($result > 0) {
- header("Location: " . $_SERVER['PHP_SELF'] . '?facid=' . $result);
- exit;
- } else {
- $mesgs[] = $object->error;
- $action = '';
- }
- }
- }
- }
- // Change status of invoice
- else if ($action == 'reopen' && $user->rights->facture->creer) {
- $result = $object->fetch($id);
- if ($object->statut == 2
- || ($object->statut == 3 && $object->close_code != 'replaced')) {
- $result = $object->set_unpaid($user);
- if ($result > 0) {
- header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
- exit;
- } else {
- $mesgs[] = '<div class="error">' . $object->error . '</div>';
- }
- }
- }
- // Delete invoice
- else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer) {
- $result = $object->fetch($id);
- $object->fetch_thirdparty();
- $result = $object->delete();
- if ($result > 0) {
- header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php');
- exit;
- } else {
- $mesgs[] = '<div class="error">' . $object->error . '</div>';
- }
- }
- // Delete line
- else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer) {
- $object->fetch($id);
- $object->fetch_thirdparty();
- $result = $object->deleteline($_GET['lineid'], $user);
- if ($result > 0) {
- // Define output language
- $outputlangs = $langs;
- $newlang = '';
- if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id']))
- $newlang = $_REQUEST['lang_id'];
- if ($conf->global->MAIN_MULTILANGS && empty($newlang))
- $newlang = $object->client->default_lang;
- if (!empty($newlang)) {
- $outputlangs = new Translate();
- $outputlangs->setDefaultLang($newlang);
- }
- if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
- $ret = $object->fetch($id); // Reload to get new records
- $result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
- }
- if ($result >= 0) {
- header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
- exit;
- }
- } else {
- $mesgs[] = '<div clas="error">' . $object->error . '</div>';
- $action = '';
- }
- }
- // Delete link of credit note to invoice
- else if ($action == 'unlinkdiscount' && $user->rights->facture->creer) {
- $discount = new DiscountAbsolute($db);
- $result = $discount->fetch($_GET["discountid"]);
- $discount->unlink_invoice();
- }
- // Validation
- else if ($action == 'valid' && $user->rights->facture->creer) {
- $object->fetch($id);
- // On verifie signe facture
- if ($object->type == 2) {
- // Si avoir, le signe doit etre negatif
- if ($object->total_ht >= 0) {
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorInvoiceAvoirMustBeNegative") . '</div>';
- $action = '';
- }
- } else {
- // Si non avoir, le signe doit etre positif
- if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) {
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorInvoiceOfThisTypeMustBePositive") . '</div>';
- $action = '';
- }
- }
- } else if ($action == 'set_thirdparty' && $user->rights->facture->creer) {
- $object->fetch($id);
- $object->setValueFrom('fk_soc', $socid);
- header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
- exit;
- } else if ($action == 'classin' && $user->rights->facture->creer) {
- $object->fetch($id);
- $object->setProject($_POST['projectid']);
- } else if ($action == 'setmode' && $user->rights->facture->creer) {
- $object->fetch($id);
- $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
- if ($result < 0)
- dol_print_error($db, $object->error);
- }
- else if ($action == 'setinvoicedate' && $user->rights->facture->creer) {
- $object->fetch($id);
- $object->date = dol_mktime(12, 0, 0, $_POST['invoicedatemonth'], $_POST['invoicedateday'], $_POST['invoicedateyear']);
- if ($object->date_lim_reglement < $object->date)
- $object->date_lim_reglement = $object->date;
- $result = $object->update($user);
- if ($result < 0)
- dol_print_error($db, $object->error);
- }
- else if ($action == 'setpaymentterm' && $user->rights->facture->creer) {
- $object->fetch($id);
- $object->date_lim_reglement = dol_mktime(12, 0, 0, $_POST['paymenttermmonth'], $_POST['paymenttermday'], $_POST['paymenttermyear']);
- if ($object->date_lim_reglement < $object->date) {
- $object->date_lim_reglement = $object->date;
- setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), 'warnings');
- }
- $result = $object->update($user);
- if ($result < 0)
- dol_print_error($db, $object->error);
- }
- else if ($action == 'setconditions' && $user->rights->facture->creer) {
- $object->fetch($id);
- $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
- if ($result < 0)
- dol_print_error($db, $object->error);
- }
- else if ($action == 'setremisepercent' && $user->rights->facture->creer) {
- $object->fetch($id);
- $result = $object->set_remise($user, $_POST['remise_percent']);
- } else if ($action == "setabsolutediscount" && $user->rights->facture->creer) {
- // POST[remise_id] ou POST[remise_id_for_payment]
- if (!empty($_POST["remise_id"])) {
- $ret = $object->fetch($id);
- if ($ret > 0) {
- $result = $object->insert_discount($_POST["remise_id"]);
- if ($result < 0) {
- $mesgs[] = '<div class="error">' . $object->error . '</div>';
- }
- } else {
- dol_print_error($db, $object->error);
- }
- }
- if (!empty($_POST["remise_id_for_payment"])) {
- require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
- $discount = new DiscountAbsolute($db);
- $discount->fetch($_POST["remise_id_for_payment"]);
- $result = $discount->link_to_invoice(0, $id);
- if ($result < 0) {
- $mesgs[] = '<div class="error">' . $discount->error . '</div>';
- }
- }
- } else if ($action == 'set_ref_client' && $user->rights->facture->creer) {
- $object->fetch($id);
- $object->set_ref_client($_POST['ref_client']);
- } else if ($action == 'setnote_public' && $user->rights->facture->creer) {
- $object->fetch($id);
- $result = $object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES));
- if ($result < 0)
- dol_print_error($db, $object->error);
- }
- else if ($action == 'setnote' && $user->rights->facture->creer) {
- $object->fetch($id);
- $result = $object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES));
- if ($result < 0)
- dol_print_error($db, $object->error);
- }
- // Classify to validated
- else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider) {
- $idwarehouse = GETPOST('idwarehouse');
- $object->fetch($id);
- $object->fetch_thirdparty();
- // Check parameters
- if ($object->type != 3 && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) {
- if (!$idwarehouse || $idwarehouse == -1) {
- $error++;
- $mesgs[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse"));
- $action = '';
- }
- }
- if (!$error) {
- $result = $object->validate($user, '', $idwarehouse);
- if ($result >= 0) {
- // Define output language
- $outputlangs = $langs;
- $newlang = '';
- if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id']))
- $newlang = $_REQUEST['lang_id'];
- if ($conf->global->MAIN_MULTILANGS && empty($newlang))
- $newlang = $object->client->default_lang;
- if (!empty($newlang)) {
- $outputlangs = new Translate();
- $outputlangs->setDefaultLang($newlang);
- }
- if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
- $ret = $object->fetch($id); // Reload to get new records
- facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
- }
- } else {
- $mesgs[] = '<div class="error">' . $object->error . '</div>';
- }
- }
- }
- // Go back to draft status (unvalidate)
- else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)) {
- $idwarehouse = GETPOST('idwarehouse');
- $object->fetch($id);
- $object->fetch_thirdparty();
- // Check parameters
- if ($object->type != 3 && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) {
- if (!$idwarehouse || $idwarehouse == -1) {
- $error++;
- $mesgs[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse"));
- $action = '';
- }
- }
- if (!$error) {
- // On verifie si la facture a des paiements
- $sql = 'SELECT pf.amount';
- $sql.= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture as pf';
- $sql.= ' WHERE pf.fk_facture = ' . $object->id;
- $result = $db->query($sql);
- if ($result) {
- $i = 0;
- $num = $db->num_rows($result);
- while ($i < $num) {
- $objp = $db->fetch_object($result);
- $totalpaye += $objp->amount;
- $i++;
- }
- } else {
- dol_print_error($db, '');
- }
- $resteapayer = $object->total_ttc - $totalpaye;
- // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
- $ventilExportCompta = $object->getVentilExportCompta();
- // On verifie si aucun paiement n'a ete effectue
- if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) {
- $object->set_draft($user, $idwarehouse);
- // Define output language
- $outputlangs = $langs;
- $newlang = '';
- if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id']))
- $newlang = $_REQUEST['lang_id'];
- if ($conf->global->MAIN_MULTILANGS && empty($newlang))
- $newlang = $object->client->default_lang;
- if (!empty($newlang)) {
- $outputlangs = new Translate();
- $outputlangs->setDefaultLang($newlang);
- }
- if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
- $ret = $object->fetch($id); // Reload to get new records
- facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
- }
- }
- }
- }
- // Classify "paid"
- else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement) {
- $object->fetch($id);
- $result = $object->set_paid($user);
- }
- // Classif "paid partialy"
- else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement) {
- $object->fetch($id);
- $close_code = $_POST["close_code"];
- $close_note = $_POST["close_note"];
- if ($close_code) {
- $result = $object->set_paid($user, $close_code, $close_note);
- } else {
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Reason")) . '</div>';
- }
- }
- // Classify "abandoned"
- else if ($action == 'confirm_canceled' && $confirm == 'yes') {
- $object->fetch($id);
- $close_code = $_POST["close_code"];
- $close_note = $_POST["close_note"];
- if ($close_code) {
- $result = $object->set_canceled($user, $close_code, $close_note);
- } else {
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Reason")) . '</div>';
- }
- }
- // Convertir en reduc
- else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer) {
- $db->begin();
- $object->fetch($id);
- $object->fetch_thirdparty();
- $object->fetch_lines();
- if (!$object->paye) { // protection against multiple submit
- // Boucle sur chaque taux de tva
- $i = 0;
- foreach ($object->lines as $line) {
- $amount_ht[$line->tva_tx]+=$line->total_ht;
- $amount_tva[$line->tva_tx]+=$line->total_tva;
- $amount_ttc[$line->tva_tx]+=$line->total_ttc;
- $i++;
- }
- // Insert one discount by VAT rate category
- $discount = new DiscountAbsolute($db);
- if ($object->type == 2)
- $discount->description = '(CREDIT_NOTE)';
- elseif ($object->type == 3)
- $discount->description = '(DEPOSIT)';
- else {
- $this->error = "CantConvertToReducAnInvoiceOfThisType";
- return -1;
- }
- $discount->tva_tx = abs($object->total_ttc);
- $discount->fk_soc = $object->socid;
- $discount->fk_facture_source = $object->id;
- $error = 0;
- 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->tva_tx = abs($tva_tx);
- $result = $discount->create($user);
- if ($result < 0) {
- $error++;
- break;
- }
- }
- if (!$error) {
- // Classe facture
- $result = $object->set_paid($user);
- if ($result > 0) {
- //$mesgs[]='OK'.$discount->id;
- $db->commit();
- } else {
- $mesgs[] = '<div class="error">' . $object->error . '</div>';
- $db->rollback();
- }
- } else {
- $mesgs[] = '<div class="error">' . $discount->error . '</div>';
- $db->rollback();
- }
- }
- }
- /*
- * Insert new invoice in database
- */ else if ($action == 'add' && $user->rights->facture->creer) {
- $object->socid = GETPOST('socid', 'int');
- $error = 0;
- // Replacement invoice
- if ($_POST['type'] == 1) {
- $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
- if (empty($datefacture)) {
- $error++;
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
- }
- if (!($_POST['fac_replacement'] > 0)) {
- $error++;
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("ReplaceInvoice")) . '</div>';
- }
- if (!$error) {
- // This is a replacement invoice
- $result = $object->fetch($_POST['fac_replacement']);
- $object->fetch_thirdparty();
- $object->date = $datefacture;
- $object->note_public = trim($_POST['note_public']);
- $object->note = trim($_POST['note']);
- $object->ref_client = $_POST['ref_client'];
- $object->ref_int = $_POST['ref_int'];
- $object->modelpdf = $_POST['model'];
- $object->fk_project = $_POST['projectid'];
- $object->cond_reglement_id = $_POST['cond_reglement_id'];
- $object->mode_reglement_id = $_POST['mode_reglement_id'];
- $object->remise_absolue = $_POST['remise_absolue'];
- $object->remise_percent = $_POST['remise_percent'];
- // Proprietes particulieres a facture de remplacement
- $object->fk_facture_source = $_POST['fac_replacement'];
- $object->type = 1;
- $id = $object->createFromCurrent($user);
- if ($id <= 0)
- $mesgs[] = $object->error;
- }
- }
- // Credit note invoice
- if ($_POST['type'] == 2) {
- if (!$_POST['fac_avoir'] > 0) {
- $error++;
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("CorrectInvoice")) . '</div>';
- }
- $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
- if (empty($datefacture)) {
- $error++;
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
- }
- if (!$error) {
- // Si facture avoir
- $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
- //$result=$object->fetch($_POST['fac_avoir']);
- $object->socid = $_POST['socid'];
- $object->number = $_POST['facnumber'];
- $object->date = $datefacture;
- $object->note_public = trim($_POST['note_public']);
- $object->note = trim($_POST['note']);
- $object->ref_client = $_POST['ref_client'];
- $object->ref_int = $_POST['ref_int'];
- $object->modelpdf = $_POST['model'];
- $object->fk_project = $_POST['projectid'];
- $object->cond_reglement_id = 0;
- $object->mode_reglement_id = $_POST['mode_reglement_id'];
- $object->remise_absolue = $_POST['remise_absolue'];
- $object->remise_percent = $_POST['remise_percent'];
- // Proprietes particulieres a facture avoir
- $object->fk_facture_source = $_POST['fac_avoir'];
- $object->type = 2;
- $id = $object->create($user);
- // Add predefined lines
- for ($i = 1; $i <= $NBLINES; $i++) {
- if ($_POST['idprod' . $i]) {
- $product = new Product($db);
- $product->fetch($_POST['idprod' . $i]);
- $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']);
- $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']);
- $result = $object->addline($id, $product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
- }
- }
- }
- }
- // Standard invoice or Deposit invoice created from a Predefined invoice
- if (($_POST['type'] == "INVOICE_STANDARD" || $_POST['type'] == "INVOICE_DEPOSIT") && $_POST['fac_rec'] > 0) {
- $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
- if (empty($datefacture)) {
- $error++;
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
- }
- if (!$error) {
- $object->socid = $_POST['socid'];
- $object->type = $_POST['type'];
- $object->number = $_POST['facnumber'];
- $object->date = $datefacture;
- $object->note_public = trim($_POST['note_public']);
- $object->note = trim($_POST['note']);
- $object->ref_client = $_POST['ref_client'];
- $object->ref_int = $_POST['ref_int'];
- $object->modelpdf = $_POST['model'];
- // Source facture
- $object->fac_rec = $_POST['fac_rec'];
- $id = $object->create($user);
- }
- }
- // Standard or deposit or proforma invoice
- if (($_POST['type'] == "INVOICE_STANDARD" || $_POST['type'] == "INVOICE_DEPOSIT" || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) {
- $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
- if (empty($datefacture)) {
- $error++;
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
- }
- if (!$error) {
- // Si facture standard
- $object->socid = $_POST['socid'];
- $object->type = $_POST['type'];
- $object->number = $_POST['facnumber'];
- $object->date = $datefacture;
- $object->note_public = trim($_POST['note_public']);
- $object->note = trim($_POST['note']);
- $object->ref_client = $_POST['ref_client'];
- $object->ref_int = $_POST['ref_int'];
- $object->modelpdf = $_POST['model'];
- $object->fk_project = $_POST['projectid'];
- $object->cond_reglement_code = $_POST["cond_reglement_code"]; //($_POST['type'] == 3?1:$_POST['cond_reglement_id']);
- $object->mode_reglement_code = $_POST['mode_reglement_code'];
- $object->amount = $_POST['amount'];
- $object->remise_absolue = $_POST['remise_absolue'];
- $object->remise_percent = $_POST['remise_percent'];
- // If creation from another object of another module (Example: origin=propal, originid=1)
- if ($_POST['origin'] && $_POST['originid']) {
- // Parse element/subelement (ex: project_task)
- $element = $subelement = $_POST['origin'];
- if (preg_match('/^([^_]+)_([^_]+)/i', $_POST['origin'], $regs)) {
- $element = $regs[1];
- $subelement = $regs[2];
- }
- // For compatibility
- if ($element == 'order') {
- $element = $subelement = 'commande';
- }
- if ($element == 'propal') {
- $element = 'comm/propal';
- $subelement = 'propal';
- }
- if ($element == 'contract') {
- $element = $subelement = 'contrat';
- }
- if ($element == 'inter') {
- $element = $subelement = 'ficheinter';
- }
- if ($element == 'shipping') {
- $element = $subelement = 'expedition';
- }
- $object->origin = $_POST['origin'];
- $object->origin_id = $_POST['originid'];
- // Possibility to add external linked objects with hooks
- $object->linked_objects[$object->origin] = $object->origin_id;
- if (is_array($_POST['other_linked_objects']) && !empty($_POST['other_linked_objects'])) {
- $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
- }
- $id = $object->create($user);
- if ($id > 0) {
- dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
- $classname = ucfirst($subelement);
- $srcobject = new $classname($db);
- dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines");
- $result = $srcobject->fetch($object->origin_id);
- if ($result > 0) {
- $lines = $srcobject->lines;
- if (empty($lines) && method_exists($srcobject, 'fetch_lines'))
- $lines = $srcobject->fetch_lines();
- $fk_parent_line = 0;
- $num = count($lines);
- for ($i = 0; $i < $num; $i++) {
- $label = (!empty($lines[$i]->label) ? $lines[$i]->label : '');
- $desc = (!empty($lines[$i]->desc) ? $lines[$i]->desc : $lines[$i]->libelle);
- if ($lines[$i]->subprice < 0) {
- // Negative line, we create a discount line
- $discount = new DiscountAbsolute($db);
- $discount->fk_soc = $object->socid;
- $discount->amount_ht = abs($lines[$i]->total_ht);
- $discount->amount_tva = abs($lines[$i]->total_tva);
- $discount->amount_ttc = abs($lines[$i]->total_ttc);
- $discount->tva_tx = $lines[$i]->tva_tx;
- $discount->fk_user = $user->id;
- $discount->description = $desc;
- $discountid = $discount->create($user);
- if ($discountid > 0) {
- $result = $object->insert_discount($discountid); // This include link_to_invoice
- } else {
- $mesgs[] = $discount->error;
- $error++;
- break;
- }
- } else {
- // Positive line
- $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
- // Date start
- $date_start = false;
- if ($lines[$i]->date_debut_prevue)
- $date_start = $lines[$i]->date_debut_prevue;
- if ($lines[$i]->date_debut_reel)
- $date_start = $lines[$i]->date_debut_reel;
- if ($lines[$i]->date_start)
- $date_start = $lines[$i]->date_start;
- //Date end
- $date_end = false;
- if ($lines[$i]->date_fin_prevue)
- $date_end = $lines[$i]->date_fin_prevue;
- if ($lines[$i]->date_fin_reel)
- $date_end = $lines[$i]->date_fin_reel;
- if ($lines[$i]->date_end)
- $date_end = $lines[$i]->date_end;
- // Reset fk_parent_line for no child products and special product
- if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
- $fk_parent_line = 0;
- }
- $result = $object->addline(
- $id, $desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $object->origin, $lines[$i]->rowid, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label
- );
- if ($result > 0) {
- $lineid = $result;
- } else {
- $lineid = 0;
- $error++;
- break;
- }
- // Defined the new fk_parent_line
- if ($result > 0 && $lines[$i]->product_type == 9) {
- $fk_parent_line = $result;
- }
- }
- }
- // Hooks
- $parameters = array('objFrom' => $srcobject);
- $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- if ($reshook < 0)
- $error++;
- }
- else {
- $mesgs[] = $srcobject->error;
- $error++;
- }
- } else {
- $mesgs[] = $object->error;
- $error++;
- }
- }
- // If some invoice's lines already known
- else {
- $id = $object->create($user);
- for ($i = 1; $i <= $NBLINES; $i++) {
- if ($_POST['idprod' . $i]) {
- $product = new Product($db);
- $product->fetch($_POST['idprod' . $i]);
- $startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']);
- $endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']);
- $result = $object->addline($id, $product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type);
- }
- }
- if (!empty($id)) {
- header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
- exit;
- }
- }
- }
- }
- // End of object creation, we show it
- if ($id > 0 && !$error) {
- $db->commit();
- header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
- exit;
- } else {
- $db->rollback();
- $action = 'create';
- $_GET["origin"] = $_POST["origin"];
- $_GET["originid"] = $_POST["originid"];
- $mesgs[] = '<div class="error">' . $object->error . '</div>';
- }
- }
- // Add a new line
- else if (($action == 'addline' || $action == 'addline_predef') && $user->rights->facture->creer) {
- $langs->load('errors');
- $error = false;
- $idprod = GETPOST('idprod', 'int');
- $product_desc = (GETPOST('product_desc') ? GETPOST('product_desc') : (GETPOST('np_desc') ? GETPOST('np_desc') : (GETPOST('dp_desc') ? GETPOST('dp_desc') : '')));
- $price_ht = GETPOST('price_ht');
- $tva_tx = GETPOST('tva_tx');
- if ((empty($idprod) || GETPOST('usenewaddlineform')) && ($price_ht < 0) && (GETPOST('qty') < 0)) {
- setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors');
- $error = true;
- }
- if (empty($idprod) && GETPOST('type') < 0) {
- setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors');
- $error = true;
- }
- if ((empty($idprod) || GETPOST('usenewaddlineform')) && (!($price_ht >= 0) || $price_ht == '')) { // Unit price can be 0 but not ''
- setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors');
- $error++;
- }
- if (!GETPOST('qty') && GETPOST('qty') == '') {
- setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors');
- $error = true;
- }
- if (empty($idprod) && empty($product_desc)) {
- setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors');
- $error = true;
- }
- if (!$error && (GETPOST('qty') >= 0) && (!empty($product_desc) || !empty($idprod))) {
- $ret = $object->fetch($id);
- if ($ret < 0) {
- dol_print_error($db, $object->error);
- exit;
- }
- $ret = $object->fetch_thirdparty();
- // Clean parameters
- $predef = ((!empty($idprod) && $conf->global->MAIN_FEATURES_LEVEL < 2) ? '_predef' : '');
- $date_start = dol_mktime(GETPOST('date_start' . $predef . 'hour'), GETPOST('date_start' . $predef . 'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year'));
- $date_end = dol_mktime(GETPOST('date_end' . $predef . 'hour'), GETPOST('date_end' . $predef . 'min'), GETPOST('date_end' . $predef . 'sec'), GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year'));
- $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
- // Define special_code for special lines
- $special_code = 0;
- //if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices
- // Ecrase $pu par celui du produit
- // Ecrase $desc par celui du produit
- // Ecrase $txtva par celui du produit
- // Ecrase $base_price_type par celui du produit
- if (!empty($idprod)) {
- $prod = new Product($db);
- $prod->fetch($idprod);
- $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
- // Update if prices fields are defined
- if (GETPOST('usenewaddlineform')) {
- $pu_ht = price2num($price_ht, 'MU');
- $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
- $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
- $tva_tx = str_replace('*', '', $tva_tx);
- $desc = $product_desc;
- } else {
- $tva_tx = get_default_tva($mysoc, $object->client, $prod->id);
- $tva_npr = get_default_npr($mysoc, $object->client, $prod->id);
- // We define price for product
- if (!empty($conf->global->PRODUIT_MULTIPRICES) && !empty($object->client->price_level)) {
- $pu_ht = $prod->multiprices[$object->client->price_level];
- $pu_ttc = $prod->multiprices_ttc[$object->client->price_level];
- $price_min = $prod->multiprices_min[$object->client->price_level];
- $price_base_type = $prod->multiprices_base_type[$object->client->price_level];
- } else {
- $pu_ht = $prod->price;
- $pu_ttc = $prod->price_ttc;
- $price_min = $prod->price_min;
- $price_base_type = $prod->price_base_type;
- }
- // On reevalue prix selon taux tva car taux tva transaction peut etre different
- // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
- if ($tva_tx != $prod->tva_tx) {
- if ($price_base_type != 'HT') {
- $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU');
- } else {
- $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
- }
- }
- $desc = '';
- // Define output language
- if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
- $outputlangs = $langs;
- $newlang = '';
- if (empty($newlang) && GETPOST('lang_id'))
- $newlang = GETPOST('lang_id');
- if (empty($newlang))
- $newlang = $object->client->default_lang;
- if (!empty($newlang)) {
- $outputlangs = new Translate();
- $outputlangs->setDefaultLang($newlang);
- }
- $desc = (!empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description;
- } else {
- $desc = $prod->description;
- }
- $desc = dol_concatdesc($desc, $product_desc);
- }
- if (!empty($prod->customcode) || !empty($prod->country_code)) {
- $tmptxt = '(';
- if (!empty($prod->customcode))
- $tmptxt.=$langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode;
- if (!empty($prod->customcode) && !empty($prod->country_code))
- $tmptxt.=' - ';
- if (!empty($prod->country_code))
- $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0);
- $tmptxt.=')';
- $desc.= (dol_textishtml($desc) ? "<br>\n" : "\n") . $tmptxt;
- }
- $type = $prod->type;
- }
- else {
- $pu_ht = price2num($price_ht, 'MU');
- $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
- $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
- $tva_tx = str_replace('*', '', $tva_tx);
- $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
- $desc = $product_desc;
- $type = GETPOST('type');
- }
- // Margin
- $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : '');
- $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : '');
- // Local Taxes
- $localtax1_tx = get_localtax($tva_tx, 1, $object->client);
- $localtax2_tx = get_localtax($tva_tx, 2, $object->client);
- $info_bits = 0;
- if ($tva_npr)
- $info_bits |= 0x01;
- if (!empty($price_min) && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
- $mesg = $langs->trans("CantBeLessThanMinPrice", price2num($price_min, 'MU') . $langs->getCurrencySymbol($conf->currency));
- setEventMessage($mesg, 'errors');
- } else {
- // Insert line
- $result = $object->addline(
- $id, $desc, $pu_ht, GETPOST('qty'), $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, GETPOST('remise_percent'), $date_start, $date_end, 0, $info_bits, '', $price_base_type, $pu_ttc, $type, -1, $special_code, '', 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label
- );
- if ($result > 0) {
- if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
- // Define output language
- $outputlangs = $langs;
- $newlang = GETPOST('lang_id', 'alpha');
- if (!empty($conf->global->MAIN_MULTILANGS) && empty($newlang))
- $newlang = $object->client->default_lang;
- if (!empty($newlang)) {
- $outputlangs = new Translate();
- $outputlangs->setDefaultLang($newlang);
- }
- $ret = $object->fetch($id); // Reload to get new records
- facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
- }
- unset($_POST['qty']);
- unset($_POST['type']);
- unset($_POST['idprod']);
- unset($_POST['remise_percent']);
- unset($_POST['price_ht']);
- unset($_POST['price_ttc']);
- unset($_POST['tva_tx']);
- unset($_POST['product_ref']);
- unset($_POST['product_label']);
- unset($_POST['product_desc']);
- unset($_POST['fournprice']);
- unset($_POST['buying_price']);
- // old method
- unset($_POST['np_desc']);
- unset($_POST['dp_desc']);
- } else {
- setEventMessage($object->error, 'errors');
- }
- $action = '';
- }
- }
- }
- else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['save'] == $langs->trans('Save')) {
- if (!$object->fetch($id) > 0)
- dol_print_error($db);
- $object->fetch_thirdparty();
- // Clean parameters
- $date_start = '';
- $date_end = '';
- $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
- $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
- $description = dol_htmlcleanlastbr(GETPOST('product_desc'));
- $pu_ht = GETPOST('price_ht');
- // Define info_bits
- $info_bits = 0;
- if (preg_match('/\*/', GETPOST('tva_tx')))
- $info_bits |= 0x01;
- // Define vat_rate
- $vat_rate = $_POST['tva_tx'];
- $vat_rate = str_replace('*', '', $vat_rate);
- $localtax1_rate = get_localtax($vat_rate, 1, $object->client);
- $localtax2_rate = get_localtax($vat_rate, 2, $object->client);
- // Add buying price
- $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : '');
- $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : '');
- // Check minimum price
- $productid = GETPOST('productid', 'int');
- if (!empty($productid)) {
- $product = new Product($db);
- $product->fetch($productid);
- $type = $product->type;
- $price_min = $product->price_min;
- if (!empty($conf->global->PRODUIT_MULTIPRICES) && !empty($object->client->price_level))
- $price_min = $product->multiprices_min[$object->client->price_level];
- $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
- if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
- setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min, 'MU')) . $langs->getCurrencySymbol($conf->currency), 'errors');
- $error++;
- }
- } else {
- $type = GETPOST('type');
- $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
- // Check parameters
- if (GETPOST('type') < 0) {
- setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors');
- $error++;
- }
- }
- // Update line
- if (!$error) {
- $result = $object->updateline(
- GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label
- );
- if ($result >= 0) {
- if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
- // Define output language
- $outputlangs = $langs;
- $newlang = '';
- if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id'))
- $newlang = GETPOST('lang_id');
- if ($conf->global->MAIN_MULTILANGS && empty($newlang))
- $newlang = $object->client->default_lang;
- if (!empty($newlang)) {
- $outputlangs = new Translate();
- $outputlangs->setDefaultLang($newlang);
- }
- $ret = $object->fetch($id); // Reload to get new records
- facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
- }
- unset($_POST['qty']);
- unset($_POST['type']);
- unset($_POST['productid']);
- unset($_POST['remise_percent']);
- unset($_POST['price_ht']);
- unset($_POST['price_ttc']);
- unset($_POST['tva_tx']);
- unset($_POST['product_ref']);
- unset($_POST['product_label']);
- unset($_POST['product_desc']);
- unset($_POST['fournprice']);
- unset($_POST['buying_price']);
- } else {
- setEventMessage($object->error, 'errors');
- }
- }
- } else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) {
- header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); // Pour reaffichage de la fiche en cours d'edition
- exit;
- }
- // Modify line position (up)
- else if ($action == 'up' && $user->rights->facture->creer) {
- $object->fetch($id);
- $object->fetch_thirdparty();
- $object->line_up($_GET['rowid']);
- // Define output l…
Large files files are truncated, but you can click here to view the full file