/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
- <?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 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))
- facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
- header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET['rowid']);
- exit;
- }
- // Modify line position (down)
- else if ($action == 'down' && $user->rights->facture->creer) {
- $object->fetch($id);
- $object->fetch_thirdparty();
- $object->line_down($_GET['rowid']);
- // 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))
- facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
- header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET['rowid']);
- exit;
- }
- /*
- * Add file in email form
- */
- if (GETPOST('addfile')) {
- require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
- // Set tmp user directory
- $vardir = $conf->user->dir_output . "/" . $user->id;
- $upload_dir_tmp = $vardir . '/temp';
- dol_add_file_process($upload_dir_tmp, 0, 0);
- $action = 'presend';
- }
- /*
- * Remove file in email form
- */
- if (!empty($_POST['removedfile'])) {
- require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
- // Set tmp user directory
- $vardir = $conf->user->dir_output . "/" . $user->id;
- $upload_dir_tmp = $vardir . '/temp';
- // TODO Delete only files that was uploaded from email form
- dol_remove_file_process($_POST['removedfile'], 0);
- $action = 'presend';
- }
- /*
- * Send mail
- */
- if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST['removedfile'] && !$_POST['cancel']) {
- $langs->load('mails');
- $actiontypecode = '';
- $subject = '';
- $actionmsg = '';
- $actionmsg2 = '';
- $result = $object->fetch($id);
- $result = $object->fetch_thirdparty();
- if ($result > 0) {
- // $ref = dol_sanitizeFileName($object->ref);
- // $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf';
- // if (is_readable($file))
- // {
- if ($_POST['sendto']) {
- // Le destinataire a ete fourni via le champ libre
- $sendto = $_POST['sendto'];
- $sendtoid = 0;
- } elseif ($_POST['receiver'] != '-1') {
- // Recipient was provided from combo list
- if ($_POST['receiver'] == 'thirdparty') { // Id of third party
- $sendto = $object->client->email;
- $sendtoid = 0;
- } else { // Id du contact
- $sendto = $object->client->contact_get_property($_POST['receiver'], 'email');
- $sendtoid = $_POST['receiver'];
- }
- }
- if (dol_strlen($sendto)) {
- $langs->load("commercial");
- $from = $_POST['fromname'] . ' <' . $_POST['frommail'] . '>';
- $replyto = $_POST['replytoname'] . ' <' . $_POST['replytomail'] . '>';
- $message = $_POST['message'];
- $sendtocc = $_POST['sendtocc'];
- $deliveryreceipt = $_POST['deliveryreceipt'];
- if ($action == 'send') {
- if (dol_strlen($_POST['subject']))
- $subject = $_POST['subject'];
- else
- $subject = $langs->transnoentities('Bill') . ' ' . $object->ref;
- $actiontypecode = 'AC_FAC';
- $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n";
- if ($message) {
- $actionmsg.=$langs->transnoentities('MailTopic') . ": " . $subject . "\n";
- $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody') . ":\n";
- $actionmsg.=$message;
- }
- //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
- }
- if ($action == 'relance') {
- if (dol_strlen($_POST['subject']))
- $subject = $_POST['subject'];
- else
- $subject = $langs->transnoentities('Relance facture ' . $object->ref);
- $actiontypecode = 'AC_FAC';
- $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto . ".\n";
- if ($message) {
- $actionmsg.=$langs->transnoentities('MailTopic') . ": " . $subject . "\n";
- $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody') . ":\n";
- $actionmsg.=$message;
- }
- //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode);
- }
- // Create form object
- include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
- $formmail = new FormMail($db);
- $attachedfiles = $formmail->get_attached_files();
- $filepath = $attachedfiles['paths'];
- $filename = $attachedfiles['names'];
- $mimetype = $attachedfiles['mimes'];
- // Send mail
- require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
- $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1);
- if ($mailfile->error) {
- $mesgs[] = '<div class="error">' . $mailfile->error . '</div>';
- } else {
- $result = $mailfile->sendfile();
- if ($result) {
- $error = 0;
- // Initialisation donnees
- $object->sendtoid = $sendtoid;
- $object->actiontypecode = $actiontypecode;
- $object->actionmsg = $actionmsg; // Long text
- $object->actionmsg2 = $actionmsg2; // Short text
- $object->fk_element = $object->id;
- $object->elementtype = $object->element;
- // Appel des triggers
- include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
- $interface = new Interfaces($db);
- $result = $interface->run_triggers('BILL_SENTBYMAIL', $object, $user, $langs, $conf);
- if ($result < 0) {
- $error++;
- $this->errors = $interface->errors;
- }
- // Fin appel triggers
- if ($error) {
- dol_print_error($db);
- } else {
- // Redirect here
- // This avoid sending mail twice if going out and then back to page
- $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2));
- setEventMessage($mesg);
- header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id);
- exit;
- }
- } else {
- $langs->load("other");
- $mesg = '<div class="error">';
- if ($mailfile->error) {
- $mesg.=$langs->trans('ErrorFailedToSendMail', $from, $sendto);
- $mesg.='<br>' . $mailfile->error;
- } else {
- $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
- }
- $mesg.='</div>';
- $mesgs[] = $mesg;
- }
- }
- /* }
- else
- {
- $langs->load("other");
- $mesgs[]='<div class="error">'.$langs->trans('ErrorMailRecipientIsEmpty').'</div>';
- dol_syslog('Recipient email is empty');
- } */
- } else {
- $langs->load("errors");
- $mesgs[] = '<div class="error">' . $langs->trans('ErrorCantReadFile', $file) . '</div>';
- dol_syslog('Failed to read file: ' . $file);
- }
- } else {
- $langs->load("other");
- $mesgs[] = '<div class="error">' . $langs->trans('ErrorFailedToReadEntity', $langs->trans("Invoice")) . '</div>';
- dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.');
- }
- $action = 'presend';
- }
- /*
- * Generate document
- */ else if ($action == 'builddoc') { // En get ou en post
- $object->fetch($id);
- $object->fetch_thirdparty();
- if (GETPOST('model')) {
- $object->setDocModel($user, GETPOST('model'));
- }
- // 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);
- }
- $result = facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
- if ($result <= 0) {
- dol_print_error($db, $result);
- exit;
- } else {
- header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#builddoc'));
- exit;
- }
- }
- // Remove file in doc form
- else if ($action == 'remove_file') {
- if ($object->fetch($id)) {
- require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
- $object->fetch_thirdparty();
- $langs->load("other");
- $upload_dir = $conf->facture->dir_output;
- $file = $upload_dir . '/' . GETPOST('file');
- $ret = dol_delete_file($file, 0, 0, 0, $object);
- if ($ret)
- setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile')));
- else
- setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors');
- $action = '';
- }
- }
- if (!empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) {
- if ($action == 'addcontact') {
- $result = $object->fetch($id);
- if ($result > 0 && $id > 0) {
- $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
- $result = $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]);
- }
- if ($result >= 0) {
- header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
- exit;
- } else {
- if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
- $langs->load("errors");
- $mesgs[] = '<div class="error">' . $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType") . '</div>';
- } else {
- $mesgs[] = '<div class="error">' . $object->error . '</div>';
- }
- }
- }
- // bascule du statut d'un contact
- else if ($action == 'swapstatut') {
- if ($object->fetch($id)) {
- $result = $object->swapContactStatus(GETPOST('ligne'));
- } else {
- dol_print_error($db);
- }
- }
- // Efface un contact
- else if ($action == 'deletecontact') {
- $object->fetch($id);
- $result = $object->delete_contact($lineid);
- if ($result >= 0) {
- header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
- exit;
- } else {
- dol_print_error($db);
- }
- }
- }
- /*
- * View
- */
- llxHeader('', $langs->trans('Bill'), 'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes');
- $form = new Form($db);
- $htmlother = new FormOther($db);
- $formfile = new FormFile($db);
- $bankaccountstatic = new Account($db);
- $now = dol_now();
- /* * *******************************************************************
- *
- * Mode creation
- *
- * ******************************************************************** */
- if ($action == 'create') {
- $facturestatic = new Facture($db);
- print_fiche_titre($langs->trans('NewBill'));
- $soc = new Societe($db);
- if ($socid)
- $res = $soc->fetch($socid);
- if (!empty($origin) && !empty($originid)) {
- // Parse element/subelement (ex: project_task)
- $element = $subelement = $origin;
- if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
- $element = $regs[1];
- $subelement = $regs[2];
- }
- if ($element == 'project') {
- $projectid = $originid;
- } else {
- // For compatibility
- if ($element == 'order' || $element == 'commande') {
- $element = $subelement = 'commande';
- }
- if ($element == 'propal') {
- $element = 'comm/propal';
- $subelement = 'propal';
- }
- if ($element == 'contract') {
- $element = $subelement = 'contrat';
- }
- if ($element == 'shipping') {
- $element = $subelement = 'expedition';
- }
- dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
- $classname = ucfirst($subelement);
- $objectsrc = new $classname($db);
- $objectsrc->fetch($originid);
- if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines'))
- $objectsrc->fetch_lines();
- $objectsrc->fetch_thirdparty();
- $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
- $ref_client = (!empty($objectsrc->ref_client) ? $objectsrc->ref_client : '');
- $ref_int = (!empty($objectsrc->ref_int) ? $objectsrc->ref_int : '');
- $soc = $objectsrc->client;
- $cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 1));
- $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0));
- $remise_percent = (!empty($objectsrc->remise_percent) ? $objectsrc->remise_percent : (!empty($soc->remise_percent) ? $soc->remise_percent : 0));
- $remise_absolue = (!empty($objectsrc->remise_absolue) ? $objectsrc->remise_absolue : (!empty($soc->remise_absolue) ? $soc->remise_absolue : 0));
- $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE) ? -1 : 0;
- }
- }
- else {
- $cond_reglement_id = $soc->cond_reglement_id;
- $mode_reglement_id = $soc->mode_reglement_id;
- $remise_percent = $soc->remise_percent;
- $remise_absolue = 0;
- $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE) ? -1 : 0;
- }
- $absolute_discount = $soc->getAvailableDiscounts();
- print '<form name="add" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
- print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
- print '<input type="hidden" name="action" value="add">';
- // print '<input type="hidden" name="socid" value="'.$soc->id.'">' ."\n";
- print '<input name="facnumber" type="hidden" value="provisoire">';
- print '<input name="ref_client" type="hidden" value="' . $ref_client . '">';
- print '<input name="ref_int" type="hidden" value="' . $ref_int . '">';
- print '<input type="hidden" name="origin" value="' . $origin . '">';
- print '<input type="hidden" name="originid" value="' . $originid . '">';
- print '<table class="border" width="100%">';
- // Ref
- print '<tr><td class="fieldrequired">' . $langs->trans('Ref') . '</td><td colspan="2">' . $langs->trans('Draft') . '</td></tr>';
- // Factures predefinies
- // if (empty($origin) && empty($originid))
- // {
- // $sql = 'SELECT r.rowid, r.titre, r.total_ttc';
- // $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r';
- // $sql.= ' WHERE r.fk_soc = '.$soc->id;
- //
- // $resql=$db->query($sql);
- // if ($resql)
- // {
- // $num = $db->num_rows($resql);
- // $i = 0;
- //
- // if ($num > 0)
- // {
- // print '<tr><td>'.$langs->trans('CreateFromRepeatableInvoice').'</td><td>';
- // print '<select class="flat" name="fac_rec">';
- // print '<option value="0" selected="selected"></option>';
- // while ($i < $num)
- // {
- // $objp = $db->fetch_object($resql);
- // print '<option value="'.$objp->rowid.'"';
- // if (GETPOST('fac_rec') == $objp->rowid) print ' selected="selected"';
- // print '>'.$objp->titre.' ('.price($objp->total_ttc).' '.$langs->trans("TTC").')</option>';
- // $i++;
- // }
- // print '</select></td></tr>';
- // }
- // $db->free($resql);
- // }
- // else
- // {
- // dol_print_error($db);
- // }
- // }
- // Tiers
- print '<tr><td class="fieldrequired">' . $langs->trans('Customer') . '</td><td colspan="2">';
- print $form->select_company($object->socid, "socid");
- print '</td>';
- print '</tr>' . "\n";
- // Type de facture
- $facids=$facturestatic->list_replacable_invoices($soc->id);
- if ($facids < 0)
- {
- dol_print_error($db,$facturestatic);
- exit;
- }
- $options="";
- foreach ($facids as $facparam)
- {
- $options.='<option value="'.$facparam['id'].'"';
- if ($facparam['id'] == $_POST['fac_replacement']) $options.=' selected="selected"';
- $options.='>'.$facparam['ref'];
- //$options.=' ('.$facturestatic->LibStatut(0,$facparam['status']).')';
- $options.='</option>';
- }
- $facids=$facturestatic->list_qualified_avoir_invoices($soc->id);
- if ($facids < 0)
- {
- dol_print_error($db,$facturestatic);
- exit;
- }
- $optionsav="";
- $newinvoice_static=new Facture($db);
- foreach ($facids as $key => $valarray)
- {
- $newinvoice_static->id=$key;
- $newinvoice_static->ref=$valarray['ref'];
- $newinvoice_static->statut=$valarray['status'];
- $newinvoice_static->type=$valarray['type'];
- $newinvoice_static->paye=$valarray['paye'];
- $optionsav.='<option value="'.$key.'"';
- if ($key == $_POST['fac_avoir']) $optionsav.=' selected="selected"';
- $optionsav.='>';
- $optionsav.=$newinvoice_static->ref;
- //$optionsav.=' ('.$newinvoice_static->getLibStatut(1,$valarray['paymentornot']).')';
- $optionsav.='</option>';
- }
- print '<tr><td valign="top" class="fieldrequired">' . $langs->trans('Type') . '</td><td colspan="2">';
- print '<table class="nobordernopadding">' . "\n";
- // Standard invoice
- print '<tr height="18"><td width="16px" valign="middle">';
- print '<input type="radio" name="type" value="INVOICE_STANDARD"' . (GETPOST('type') == "INVOICE_STANDARD" ? ' checked="checked"' : '') . '>';
- print '</td><td valign="middle">';
- $desc = $form->textwithpicto($langs->trans("InvoiceStandardAsk"), $langs->transnoentities("InvoiceStandardDesc"), 1);
- print $desc;
- print '</td></tr>' . "\n";
- // Deposit
- print '<tr height="18"><td width="16px" valign="middle">';
- print '<input type="radio" name="type" value="INVOICE_DEPOSIT"' . (GETPOST('type') == "INVOICE_DEPOSIT" ? ' checked="checked"' : '') . '>';
- print '</td><td valign="middle">';
- $desc = $form->textwithpicto($langs->trans("InvoiceDeposit"), $langs->transnoentities("InvoiceDepositDesc"), 1);
- print $desc;
- print '</td></tr>' . "\n";
- // Proforma
- if (!empty($conf->global->FACTURE_USE_PROFORMAT)) {
- print '<tr height="18"><td width="16px" valign="middle">';
- print '<input type="radio" name="type" value="4"' . (GETPOST('type') == 4 ? ' checked="checked"' : '') . '>';
- print '</td><td valign="middle">';
- $desc = $form->textwithpicto($langs->trans("InvoiceProForma"), $langs->transnoentities("InvoiceProFormaDesc"), 1);
- print $desc;
- print '</td></tr>' . "\n";
- }
- // Replacement
- print '<tr height="18"><td valign="middle">';
- print '<input type="radio" name="type" value="1"' . (GETPOST('type') == 1 ? ' checked="checked"' : '');
- if (!$options)
- print ' disabled="disabled"';
- print '>';
- print '</td><td valign="middle">';
- $text = $langs->trans("InvoiceReplacementAsk") . ' ';
- $text.='<select class="flat" name="fac_replacement" id="fac_replacement"';
- if (!$options)
- $text.=' disabled="disabled"';
- $text.='>';
- if ($options) {
- $text.='<option value="-1"></option>';
- $text.=$options;
- } else {
- $text.='<option value="-1">' . $langs->trans("NoReplacableInvoice") . '</option>';
- }
- $text.='</select>';
- $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1);
- print $desc;
- print '</td></tr>' . "\n";
- // Credit note
- print '<tr height="18"><td valign="middle">';
- print '<input type="radio" name="type" value="2"' . (GETPOST('type') == 2 ? ' checked=true' : '');
- if (!$optionsav)
- print ' disabled="disabled"';
- print '>';
- print '</td><td valign="middle">';
- $text = $langs->transnoentities("InvoiceAvoirAsk") . ' ';
- // $text.='<input type="text" value="">';
- $text.='<select class="flat" name="fac_avoir" id="fac_avoir"';
- if (!$optionsav)
- $text.=' disabled="disabled"';
- $text.='>';
- if ($optionsav) {
- $text.='<option value="-1"></option>';
- $text.=$optionsav;
- } else {
- $text.='<option value="-1">' . $langs->trans("NoInvoiceToCorrect") . '</option>';
- }
- $text.='</select>';
- $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1);
- print $desc;
- print '</td></tr>' . "\n";
- print '</table>';
- print '</td></tr>';
- // Discounts for third party
- print '<tr><td>' . $langs->trans('Discounts') . '</td><td colspan="2">';
- if ($soc->remise_client)
- print $langs->trans("CompanyHasRelativeDiscount", '<a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">' . $soc->remise_client . '</a>');
- else
- print $langs->trans("CompanyHasNoRelativeDiscount");
- print ' <a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">(' . $langs->trans("EditRelativeDiscount") . ')</a>';
- print '. ';
- print '<br>';
- if ($absolute_discount)
- print $langs->trans("CompanyHasAbsoluteDiscount", '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">' . price($absolute_discount) . '</a>', $langs->trans("Currency" . $conf->currency));
- else
- print $langs->trans("CompanyHasNoAbsoluteDiscount");
- print ' <a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">(' . $langs->trans("EditGlobalDiscounts") . ')</a>';
- print '.';
- print '</td></tr>';
- // Date invoice
- print '<tr><td class="fieldrequired">' . $langs->trans('Date') . '</td><td colspan="2">';
- $form->select_date($dateinvoice, '', '', '', '', "add", 1, 1);
- print '</td></tr>';
- // Payment term
- print '<tr><td nowrap>' . $langs->trans('PaymentConditionsShort') . '</td><td colspan="2">';
- // $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id');
- print $object->select_fk_extrafields('mode_reglement_code', 'mode_reglement_code', $object->mode_reglement_code);
- print '</td></tr>';
- // Payment mode
- print '<tr><td>' . $langs->trans('PaymentMode') . '</td><td colspan="2">';
- // $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id');
- print $object->select_fk_extrafields('cond_reglement_code', 'cond_reglement_code', $object->cond_reglement_code);
- print '</td></tr>';
- // Project
- if (!empty($conf->projet->enabled)) {
- $langs->load('projects');
- print '<tr><td>' . $langs->trans('Project') . '</td><td colspan="2">';
- select_projects($soc->id, $projectid, 'projectid');
- print '</td></tr>';
- }
- // Other attributes
- $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"');
- $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- if (empty($reshook) && !empty($extrafields->attribute_label)) {
- foreach ($extrafields->attribute_label as $key => $label) {
- $value = (isset($_POST["options_" . $key]) ? $_POST["options_" . $key] : $object->array_options["options_" . $key]);
- print '<tr><td>' . $label . '</td><td colspan="3">';
- print $extrafields->showInputField($key, $value);
- print '</td></tr>' . "\n";
- }
- }
- // Modele PDF
- print '<tr><td>' . $langs->trans('Model') . '</td>';
- print '<td>';
- include_once DOL_DOCUMENT_ROOT . '/facture/core/modules/facture/modules_facture.php';
- $liste = ModelePDFFactures::liste_modeles($db);
- print $form->selectarray('model', $liste, $conf->global->FACTURE_ADDON_PDF);
- print "</td></tr>";
- // Public note
- print '<tr>';
- print '<td class="border" valign="top">' . $langs->trans('NotePublic') . '</td>';
- print '<td valign="top" colspan="2">';
- print '<textarea name="note_public" wrap="soft" cols="70" rows="' . ROWS_3 . '">';
- if (is_object($objectsrc)) { // Take value from source object
- print $objectsrc->note_public;
- }
- print '</textarea></td></tr>';
- // Private note
- if (empty($user->societe_id)) {
- print '<tr>';
- print '<td class="border" valign="top">' . $langs->trans('NotePrivate') . '</td>';
- print '<td valign="top" colspan="2">';
- print '<textarea name="note" wrap="soft" cols="70" rows="' . ROWS_3 . '">';
- if (!empty($origin) && !empty($originid) && is_object($objectsrc)) { // Take value from source object
- print $objectsrc->note;
- }
- print '</textarea></td></tr>';
- }
- if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
- // TODO for compatibility
- if ($origin == 'contrat') {
- // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
- $objectsrc->remise_absolue = $remise_absolue;
- $objectsrc->remise_percent = $remise_percent;
- $objectsrc->update_price(1, -1, 1);
- }
- print "\n<!-- " . $classname . " info -->";
- print "\n";
- print '<input type="hidden" name="amount" value="' . $objectsrc->total_ht . '">' . "\n";
- print '<input type="hidden" name="total" value="' . $objectsrc->total_ttc . '">' . "\n";
- print '<input type="hidden" name="tva" value="' . $objectsrc->total_tva . '">' . "\n";
- print '<input type="hidden" name="origin" value="' . $objectsrc->element . '">';
- print '<input type="hidden" name="originid" value="' . $objectsrc->id . '">';
- $newclassname = $classname;
- if ($newclassname == 'Propal')
- $newclassname = 'CommercialProposal';
- print '<tr><td>' . $langs->trans($newclassname) . '</td><td colspan="2">' . $objectsrc->getNomUrl(1) . '</td></tr>';
- print '<tr><td>' . $langs->trans('TotalHT') . '</td><td colspan="2">' . price($objectsrc->total_ht) . '</td></tr>';
- print '<tr><td>' . $langs->trans('TotalVAT') . '</td><td colspan="2">' . price($objectsrc->total_tva) . "</td></tr>";
- if ($mysoc->pays_code == 'ES') {
- if ($mysoc->localtax1_assuj == "1") { //Localtax1 RE
- print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->pays_code) . '</td><td colspan="2">' . price($objectsrc->total_localtax1) . "</td></tr>";
- }
- if ($mysoc->localtax2_assuj == "1") { //Localtax2 IRPF
- print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->pays_code) . '</td><td colspan="2">' . price($objectsrc->total_localtax2) . "</td></tr>";
- }
- }
- print '<tr><td>' . $langs->trans('TotalTTC') . '</td><td colspan="2">' . price($objectsrc->total_ttc) . "</td></tr>";
- } else {
- // Show deprecated optional form to add product line here
- if (!empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) {
- print '<tr><td colspan="3">';
- // Zone de choix des produits predefinis a la creation
- print '<table class="noborder" width="100%">';
- print '<tr>';
- print '<td>' . $langs->trans('ProductsAndServices') . '</td>';
- print '<td>' . $langs->trans('Qty') . '</td>';
- print '<td>' . $langs->trans('ReductionShort') . '</td>';
- print '<td> </td>';
- if (!empty($conf->service->enabled)) {
- print '<td>' . $langs->trans('ServiceLimitedDuration') . '</td>';
- }
- print '</tr>';
- for ($i = 1; $i <= $NBLINES; $i++) {
- print '<tr>';
- print '<td>';
- // multiprix
- if (!empty($conf->global->PRODUIT_MULTIPRICES))
- $form->select_produits('', 'idprod' . $i, '', $conf->product->limit_size, $soc->price_level);
- else
- $form->select_produits('', 'idprod' . $i, '', $conf->product->limit_size);
- print '</td>';
- print '<td><input type="text" size="2" name="qty' . $i . '" value="1"></td>';
- print '<td nowrap="nowrap"><input type="text" size="1" name="remise_percent' . $i . '" value="' . $soc->remise_client . '">%</td>';
- print '<td> </td>';
- // Si le module service est actif, on propose des dates de debut et fin a la ligne
- if (!empty($conf->service->enabled)) {
- print '<td nowrap="nowrap">';
- print '<table class="nobordernopadding"><tr class="nocellnopadd">';
- print '<td class="nobordernopadding" nowrap="nowrap">';
- print $langs->trans('From') . ' ';
- print '</td><td class="nobordernopadding" nowrap="nowrap">';
- print $form->select_date('', 'date_start' . $i, $usehm, $usehm, 1, "add");
- print '</td></tr>';
- print '<td class="nobordernopadding" nowrap="nowrap">';
- print $langs->trans('to') . ' ';
- print '</td><td class="nobordernopadding" nowrap="nowrap">';
- print $form->select_date('', 'date_end' . $i, $usehm, $usehm, 1, "add");
- print '</td></tr></table>';
- print '</td>';
- }
- print "</tr>\n";
- }
- print '</table>';
- print '</td></tr>';
- }
- }
- print "</table>\n";
- // Button "Create Draft"
- print '<br><center><input type="submit" class="button" name="bouton" value="' . $langs->trans('CreateDraft') . '"></center>';
- print "</form>\n";
- // Show origin lines
- if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
- print '<br>';
- $title = $langs->trans('ProductsAndServices');
- print_titre($title);
- print '<table class="noborder" width="100%">';
- $objectsrc->printOriginLinesList();
- print '</table>';
- }
- } else if (!empty($id) || !empty($ref)) {
- /*
- * Show object in view mode
- */
- $result = $object->fetch($id, $ref);
- if ($result > 0) {
- if ($user->societe_id > 0 && $user->societe_id != $object->socid)
- accessforbidden('', 0);
- $result = $object->fetch_thirdparty();
- $soc = new Societe($db);
- $soc->fetch($object->socid);
- $totalpaye = 0;//$object->getSommePaiement();
- $totalcreditnotes = 0;//$object->getSumCreditNotesUsed();
- $totaldeposits = 0;//$object->getSumDepositsUsed();
- //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits;
- // We can also use bcadd to avoid pb with floating points
- // For example print 239.2 - 229.3 - 9.9; does not return 0.
- //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT);
- //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
- $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');
- if ($object->paye)
- $resteapayer = 0;
- $resteapayeraffiche = $resteapayer;
- if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
- $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
- $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
- } else {
- $filterabsolutediscount = "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')";
- $filtercreditnote = "fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'";
- }
- $absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount);
- $absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote);
- $absolute_discount = price2num($absolute_discount, 'MT');
- $absolute_creditnote = price2num($absolute_creditnote, 'MT');
- $author = new User($db);
- if ($object->user_author) {
- $author->fetch($object->user_author);
- }
- $objectidnext = $object->getIdReplacingInvoice();
- $head = facture_prepare_head($object);
- dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill');
- $formconfirm = '';
- // Confirmation de la conversion de l'avoir en reduc
- if ($action == 'converttoreduc') {
- $text = $langs->trans('ConfirmConvertToReduc');
- $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2);
- }
- // Confirmation to delete invoice
- if ($action == 'delete') {
- $text = $langs->trans('ConfirmDeleteBill');
- $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('DeleteBill'), $text, 'confirm_delete', '', 0, 1);
- }
- // Confirmation de la validation
- if ($action == 'valid') {
- // on verifie si l'objet est en numerotation provisoire
- $objectref = substr($object->ref, 1, 4);
- if ($objectref == 'PROV') {
- $savdate = $object->date;
- if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
- $object->date = dol_now();
- $object->date_lim_reglement = $object->calculate_date_lim_reglement();
- }
- $numref = $object->getNextNumRef($soc);
- //$object->date=$savdate;
- } else {
- $numref = $object->ref;
- }
- $text = $langs->trans('ConfirmValidateBill', $numref);
- if (!empty($conf->notification->enabled)) {
- require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
- $notify = new Notify($db);
- $text.='<br>';
- $text.=$notify->confirmMessage('NOTIFY_VAL_FAC', $object->socid);
- }
- $formquestion = array();
- if ($object->type != 3 && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) {
- $langs->load("stocks");
- require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
- $formproduct = new FormProduct($db);
- $label = $object->type == 2 ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
- $formquestion = array(
- //'text' => $langs->trans("ConfirmClone"),
- //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
- //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
- array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'), 'idwarehouse', '', 1)));
- }
- if ($object->type != 2 && $object->total_ttc < 0) { // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on
- $text.='<br>' . img_warning() . ' ' . $langs->trans("ErrorInvoiceOfThisTypeMustBePositive");
- }
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('ValidateBill'), $text, 'confirm_valid', $formquestion, (($object->type != 2 && $object->total_ttc < 0) ? "no" : "yes"), ($conf->notification->enabled ? 0 : 2));
- }
- // Confirm back to draft status
- if ($action == 'modif') {
- $text = $langs->trans('ConfirmUnvalidateBill', $object->ref);
- $formquestion = array();
- if ($object->type != 3 && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) {
- $langs->load("stocks");
- require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
- $formproduct = new FormProduct($db);
- $label = $object->type == 2 ? $langs->trans("SelectWarehouseForStockDecrease") : $langs->trans("SelectWarehouseForStockIncrease");
- $formquestion = array(
- //'text' => $langs->trans("ConfirmClone"),
- //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
- //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
- array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'), 'idwarehouse', '', 1)));
- }
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('UnvalidateBill'), $text, 'confirm_modif', $formquestion, "yes", 1);
- }
- // Confirmation du classement paye
- if ($action == 'paid' && $resteapayer <= 0) {
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', "yes", 1);
- }
- if ($action == 'paid' && $resteapayer > 0) {
- // Code
- $i = 0;
- $close[$i]['code'] = 'discount_vat';
- $i++;
- $close[$i]['code'] = 'badcustomer';
- $i++;
- // Help
- $i = 0;
- $close[$i]['label'] = $langs->trans("HelpEscompte") . '<br><br>' . $langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");
- $i++;
- $close[$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");
- $i++;
- // Texte
- $i = 0;
- $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat", $resteapayer, $langs->trans("Currency" . $conf->currency)), $close[$i]['label'], 1);
- $i++;
- $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $resteapayer, $langs->trans("Currency" . $conf->currency)), $close[$i]['label'], 1);
- $i++;
- // arrayreasons[code]=reason
- foreach ($close as $key => $val) {
- $arrayreasons[$close[$key]['code']] = $close[$key]['reason'];
- }
- // Cree un tableau formulaire
- $formquestion = array(
- 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"),
- array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons),
- array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
- );
- // Paiement incomplet. On demande si motif = escompte ou autre
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidPartially', $object->ref), 'confirm_paid_partially', $formquestion, "yes");
- }
- // Confirmation du classement abandonne
- if ($action == 'canceled') {
- // S'il y a une facture de remplacement pas encore validee (etat brouillon),
- // on ne permet pas de classer abandonner la facture.
- if ($objectidnext) {
- $facturereplacement = new Facture($db);
- $facturereplacement->fetch($objectidnext);
- $statusreplacement = $facturereplacement->statut;
- }
- if ($objectidnext && $statusreplacement == 0) {
- print '<div class="error">' . $langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated") . '</div>';
- } else {
- // Code
- $close[1]['code'] = 'badcustomer';
- $close[2]['code'] = 'abandon';
- // Help
- $close[1]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");
- $close[2]['label'] = $langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
- // Texte
- $close[1]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $object->ref), $close[1]['label'], 1);
- $close[2]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"), $close[2]['label'], 1);
- // arrayreasons
- $arrayreasons[$close[1]['code']] = $close[1]['reason'];
- $arrayreasons[$close[2]['code']] = $close[2]['reason'];
- // Cree un tableau formulaire
- $formquestion = array(
- 'text' => $langs->trans("ConfirmCancelBillQuestion"),
- array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons),
- array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100')
- );
- $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('CancelBill'), $langs->trans('ConfirmCancelBill', $object->ref), 'confirm_canceled', $formquestion, "yes");
- }
- }
- // Confirmation de la suppression d'une ligne produit
- if ($action == 'ask_deleteline') {
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
- }
- // Clone confirmation
- if ($action == 'clone') {
- // Create an array for form
- $formquestion = array(
- //'text' => $langs->trans("ConfirmClone"),
- //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1)
- );
- // Paiement incomplet. On demande si motif = escompte ou autre
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('CloneInvoice'), $langs->trans('ConfirmCloneInvoice', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
- }
- if (!$formconfirm) {
- $parameters = array('lineid' => $lineid);
- $formconfirm = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- }
- // Print form confirm
- print $formconfirm;
- // Invoice content
- print '<table class="border" width="100%">';
- $linkback = '<a href="' . DOL_URL_ROOT . '/compta/facture/list.php' . (!empty($socid) ? '?socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
- // Ref
- print '<tr><td width="20%">' . $langs->trans('Ref') . '</td>';
- print '<td colspan="5">';
- $morehtmlref = '';
- $discount = new DiscountAbsolute($db);
- $result = $discount->fetch(0, $object->id);
- if ($result > 0) {
- $morehtmlref = ' (' . $langs->trans("CreditNoteConvertedIntoDiscount", $discount->getNomUrl(1, 'discount')) . ')';
- }
- if ($result < 0) {
- dol_print_error('', $discount->error);
- }
- print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref);
- print '</td></tr>';
- // Ref customer
- print '<tr><td width="20%">';
- print '<table class="nobordernopadding" width="100%"><tr><td>';
- print $langs->trans('RefCustomer');
- print '</td>';
- if ($action != 'refclient' && !empty($object->brouillon))
- print '<td align="right"><a href="' . $_SERVER['PHP_SELF'] . '?action=refclient&id=' . $object->id . '">' . img_edit($langs->trans('Modify')) . '</a></td>';
- print '</tr></table>';
- print '</td>';
- print '<td colspan="5">';
- if ($user->rights->facture->creer && $action == 'refclient') {
- print '<form action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
- print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
- print '<input type="hidden" name="action" value="set_ref_client">';
- print '<input type="text" class="flat" size="20" name="ref_client" value="' . $object->ref_client . '">';
- print ' <input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
- print '</form>';
- } else {
- print $object->ref_client;
- }
- print '</td></tr>';
- // Third party
- print '<tr><td>';
- print '<table class="nobordernopadding" width="100%">';
- print '<tr><td>' . $langs->trans('Company') . '</td>';
- print '</td><td colspan="5">';
- if (!empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer)
- print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editthirdparty&facid=' . $object->id . '">' . img_edit($langs->trans('SetLinkToThirdParty'), 1) . '</a></td>';
- print '</tr></table>';
- print '</td><td colspan="5">';
- if ($action == 'editthirdparty') {
- $form->form_thirdparty($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->socid, 'socid');
- } else {
- print ' ' . $soc->getNomUrl(1, 'compta');
- print ' (<a href="' . DOL_URL_ROOT . '/compta/facture/list.php?socid=' . $object->socid . '">' . $langs->trans('OtherBills') . '</a>)';
- }
- print '</tr>';
- // Type
- print '<tr><td>' . $langs->trans('Type') . '</td><td colspan="5">';
- print $object->getLibType();
- if ($object->type == 1) {
- $facreplaced = new Facture($db);
- $facreplaced->fetch($object->fk_facture_source);
- print ' (' . $langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)) . ')';
- }
- if ($object->type == 2) {
- $facusing = new Facture($db);
- $facusing->fetch($object->fk_facture_source);
- print ' (' . $langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)) . ')';
- }
- $facidavoir = $object->getListIdAvoirFromInvoice();
- if (count($facidavoir) > 0) {
- print ' (' . $langs->transnoentities("InvoiceHasAvoir");
- $i = 0;
- foreach ($facidavoir as $id) {
- if ($i == 0)
- print ' ';
- else
- print ',';
- $facavoir = new Facture($db);
- $facavoir->fetch($id);
- print $facavoir->getNomUrl(1);
- }
- print ')';
- }
- if ($objectidnext > 0) {
- $facthatreplace = new Facture($db);
- $facthatreplace->fetch($objectidnext);
- print ' (' . $langs->transnoentities("ReplacedByInvoice", $facthatreplace->getNomUrl(1)) . ')';
- }
- print '</td></tr>';
- // Relative and absolute discounts
- $addrelativediscount = '<a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("EditRelativeDiscounts") . '</a>';
- $addabsolutediscount = '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("EditGlobalDiscounts") . '</a>';
- $addcreditnote = '<a href="' . DOL_URL_ROOT . '/compta/facture.php?action=create&socid=' . $soc->id . '&type=2&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("AddCreditNote") . '</a>';
- print '<tr><td>' . $langs->trans('Discounts');
- print '</td><td colspan="5">';
- if ($soc->remise_client)
- print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_client);
- else
- print $langs->trans("CompanyHasNoRelativeDiscount");
- //print ' ('.$addrelativediscount.')';
- if ($absolute_discount > 0) {
- print '. ';
- if ($object->statut > 0 || $object->type == 2 || $object->type == 3) {
- if ($object->statut == 0) {
- print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
- print '. ';
- } else {
- if ($object->statut < 1 || $object->type == 2 || $object->type == 3) {
- $text = $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
- print '<br>' . $text . '.<br>';
- } else {
- $text = $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
- $text2 = $langs->trans("AbsoluteDiscountUse");
- print $form->textwithpicto($text, $text2);
- }
- }
- } else {
- // Remise dispo de type remise fixe (not credit note)
- print '<br>';
- $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' (' . $addabsolutediscount . ')');
- }
- } else {
- if ($absolute_creditnote > 0) { // If not, link will be added later
- if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
- print ' (' . $addabsolutediscount . ')<br>';
- else
- print '. ';
- }
- else
- print '. ';
- }
- if ($absolute_creditnote > 0) {
- // If validated, we show link "add credit note to payment"
- if ($object->statut != 1 || $object->type == 2 || $object->type == 3) {
- if ($object->statut == 0 && $object->type != 3) {
- $text = $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency));
- print $form->textwithpicto($text, $langs->trans("CreditNoteDepositUse"));
- } else {
- print $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency)) . '.';
- }
- } else {
- // Remise dispo de type avoir
- if (!$absolute_discount)
- print '<br>';
- //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer);
- $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher
- }
- }
- if (!$absolute_discount && !$absolute_creditnote) {
- print $langs->trans("CompanyHasNoAbsoluteDiscount");
- if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
- print ' (' . $addabsolutediscount . ')<br>';
- else
- print '. ';
- }
- /* if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
- {
- if (! $absolute_discount && ! $absolute_creditnote) print '<br>';
- //print ' - ';
- print $addabsolutediscount;
- //print ' - '.$addcreditnote; // We disbale link to credit note
- } */
- print '</td></tr>';
- // Date invoice
- print '<tr><td>';
- print '<table class="nobordernopadding" width="100%"><tr><td>';
- print $langs->trans('Date');
- print '</td>';
- if ($object->type != 2 && $action != 'editinvoicedate' && !empty($object->brouillon) && $user->rights->facture->creer)
- print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editinvoicedate&facid=' . $object->id . '">' . img_edit($langs->trans('SetDate'), 1) . '</a></td>';
- print '</tr></table>';
- print '</td><td colspan="3">';
- if ($object->type != 2) {
- if ($action == 'editinvoicedate') {
- $form->form_date($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->date, 'invoicedate');
- } else {
- print dol_print_date($object->date, 'daytext');
- }
- } else {
- print dol_print_date($object->date, 'daytext');
- }
- print '</td>';
- /*
- * List of payments
- */
- $nbrows = 8;
- $nbcols = 2;
- if (!empty($conf->projet->enabled))
- $nbrows++;
- if (!empty($conf->banque->enabled))
- $nbcols++;
- //Local taxes
- if ($mysoc->pays_code == 'ES') {
- if ($mysoc->localtax1_assuj == "1")
- $nbrows++;
- if ($mysoc->localtax2_assuj == "1")
- $nbrows++;
- }
- print '<td rowspan="' . $nbrows . '" colspan="2" valign="top">';
- print '<table class="nobordernopadding" width="100%">';
- // List of payments already done
- print '<tr class="liste_titre">';
- print '<td>' . ($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')) . '</td>';
- print '<td>' . $langs->trans('Type') . '</td>';
- if (!empty($conf->banque->enabled))
- print '<td align="right">' . $langs->trans('BankAccount') . '</td>';
- print '<td align="right">' . $langs->trans('Amount') . '</td>';
- print '<td width="18"> </td>';
- print '</tr>';
- $var = true;
- // Payments already done (from payment on this invoice)
- $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,';
- $sql.= ' c.code as payment_code, c.libelle as payment_label,';
- $sql.= ' pf.amount,';
- $sql.= ' ba.rowid as baid, ba.ref, ba.label';
- $sql.= ' FROM ' . MAIN_DB_PREFIX . 'c_paiement as c, ' . MAIN_DB_PREFIX . 'paiement_facture as pf, ' . MAIN_DB_PREFIX . 'paiement as p';
- $sql.= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank as b ON p.fk_bank = b.rowid';
- $sql.= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank_account as ba ON b.fk_account = ba.rowid';
- $sql.= ' WHERE pf.fk_facture = ' . $object->id . ' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid';
- $sql.= ' ORDER BY p.datep, p.tms';
- $result = $db->query($sql);
- if ($result) {
- $num = $db->num_rows($result);
- $i = 0;
- if ($object->type != 2) {
- if ($num > 0) {
- while ($i < $num) {
- $objp = $db->fetch_object($result);
- $var = !$var;
- print '<tr ' . $bc[$var] . '><td>';
- print '<a href="' . DOL_URL_ROOT . '/compta/paiement/fiche.php?id=' . $objp->rowid . '">' . img_object($langs->trans('ShowPayment'), 'payment') . ' ';
- print dol_print_date($db->jdate($objp->dp), 'day') . '</a></td>';
- $label = ($langs->trans("PaymentType" . $objp->payment_code) != ("PaymentType" . $objp->payment_code)) ? $langs->trans("PaymentType" . $objp->payment_code) : $objp->payment_label;
- print '<td>' . $label . ' ' . $objp->num_paiement . '</td>';
- if (!empty($conf->banque->enabled)) {
- $bankaccountstatic->id = $objp->baid;
- $bankaccountstatic->ref = $objp->ref;
- $bankaccountstatic->label = $objp->ref;
- print '<td align="right">';
- if ($bankaccountstatic->id)
- print $bankaccountstatic->getNomUrl(1, 'transactions');
- print '</td>';
- }
- print '<td align="right">' . price($objp->amount) . '</td>';
- print '<td> </td>';
- print '</tr>';
- $i++;
- }
- }
- else {
- print '<tr ' . $bc[$var] . '><td colspan="' . $nbcols . '">' . $langs->trans("None") . '</td><td></td><td></td></tr>';
- }
- }
- $db->free($result);
- } else {
- dol_print_error($db);
- }
- if ($object->type != 2) {
- // Total already paid
- print '<tr><td colspan="' . $nbcols . '" align="right">';
- if ($object->type != 3)
- print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits');
- else
- print $langs->trans('AlreadyPaid');
- print ' :</td><td align="right">' . price($totalpaye) . '</td><td> </td></tr>';
- $resteapayeraffiche = $resteapayer;
- // Loop on each credit note or deposit amount applied
- $creditnoteamount = 0;
- $depositamount = 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 = " . $object->id;
- $resql = $db->query($sql);
- if ($resql) {
- $num = $db->num_rows($resql);
- $i = 0;
- $invoice = new Facture($db);
- while ($i < $num) {
- $obj = $db->fetch_object($resql);
- $invoice->fetch($obj->fk_facture_source);
- print '<tr><td colspan="' . $nbcols . '" align="right">';
- if ($invoice->type == 2)
- print $langs->trans("CreditNote") . ' ';
- if ($invoice->type == 3)
- print $langs->trans("Deposit") . ' ';
- print $invoice->getNomUrl(0);
- print ' :</td>';
- print '<td align="right">' . price($obj->amount_ttc) . '</td>';
- print '<td align="right">';
- print '<a href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&action=unlinkdiscount&discountid=' . $obj->rowid . '">' . img_delete() . '</a>';
- print '</td></tr>';
- $i++;
- if ($invoice->type == 2)
- $creditnoteamount += $obj->amount_ttc;
- if ($invoice->type == 3)
- $depositamount += $obj->amount_ttc;
- }
- }
- else {
- dol_print_error($db);
- }
- // Paye partiellement 'escompte'
- if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat') {
- print '<tr><td colspan="' . $nbcols . '" align="right" nowrap="1">';
- print $form->textwithpicto($langs->trans("Escompte") . ':', $langs->trans("HelpEscompte"), -1);
- print '</td><td align="right">' . price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye) . '</td><td> </td></tr>';
- $resteapayeraffiche = 0;
- }
- // Paye partiellement ou Abandon 'badcustomer'
- if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer') {
- print '<tr><td colspan="' . $nbcols . '" align="right" nowrap="1">';
- print $form->textwithpicto($langs->trans("Abandoned") . ':', $langs->trans("HelpAbandonBadCustomer"), -1);
- print '</td><td align="right">' . price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye) . '</td><td> </td></tr>';
- //$resteapayeraffiche=0;
- }
- // Paye partiellement ou Abandon 'product_returned'
- if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned') {
- print '<tr><td colspan="' . $nbcols . '" align="right" nowrap="1">';
- print $form->textwithpicto($langs->trans("ProductReturned") . ':', $langs->trans("HelpAbandonProductReturned"), -1);
- print '</td><td align="right">' . price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye) . '</td><td> </td></tr>';
- $resteapayeraffiche = 0;
- }
- // Paye partiellement ou Abandon 'abandon'
- if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon') {
- print '<tr><td colspan="' . $nbcols . '" align="right" nowrap="1">';
- $text = $langs->trans("HelpAbandonOther");
- if ($object->close_note)
- $text.='<br><br><b>' . $langs->trans("Reason") . '</b>:' . $object->close_note;
- print $form->textwithpicto($langs->trans("Abandoned") . ':', $text, -1);
- print '</td><td align="right">' . price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye) . '</td><td> </td></tr>';
- $resteapayeraffiche = 0;
- }
- // Billed
- print '<tr><td colspan="' . $nbcols . '" align="right">' . $langs->trans("Billed") . ' :</td><td align="right" style="border: 1px solid;">' . price($object->total_ttc) . '</td><td> </td></tr>';
- // Remainder to pay
- print '<tr><td colspan="' . $nbcols . '" align="right">';
- if ($resteapayeraffiche >= 0)
- print $langs->trans('RemainderToPay');
- else
- print $langs->trans('ExcessReceived');
- print ' :</td>';
- print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>' . price($resteapayeraffiche) . '</b></td>';
- print '<td nowrap="nowrap"> </td></tr>';
- }
- else {
- // Sold credit note
- print '<tr><td colspan="' . $nbcols . '" align="right">' . $langs->trans('TotalTTC') . ' :</td>';
- print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>' . price(abs($object->total_ttc)) . '</b></td><td> </td></tr>';
- }
- print '</table>';
- // Margin Infos
- if (!empty($conf->margin->enabled)) {
- print '<br>';
- $object->displayMarginInfos($object->statut > 0);
- }
- print '</td></tr>';
- // Date payment term
- print '<tr><td>';
- print '<table class="nobordernopadding" width="100%"><tr><td>';
- print $langs->trans('DateMaxPayment');
- print '</td>';
- if ($object->type != 2 && $action != 'editpaymentterm' && !empty($object->brouillon) && $user->rights->facture->creer)
- print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editpaymentterm&facid=' . $object->id . '">' . img_edit($langs->trans('SetDate'), 1) . '</a></td>';
- print '</tr></table>';
- print '</td><td colspan="3">';
- if ($object->type != 2) {
- if ($action == 'editpaymentterm') {
- $form->form_date($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->date_lim_reglement, 'paymentterm');
- } else {
- print dol_print_date($object->date_lim_reglement, 'daytext');
- if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && !$object->paye && $object->statut == 1 && !isset($object->am))
- print img_warning($langs->trans('Late'));
- }
- }
- else {
- print ' ';
- }
- print '</td></tr>';
- // Conditions de reglement
- print '<tr><td>';
- print '<table class="nobordernopadding" width="100%"><tr><td>';
- print $langs->trans('PaymentConditionsShort');
- print '</td>';
- if ($object->type != 2 && $action != 'editconditions' && !empty($object->brouillon) && $user->rights->facture->creer)
- print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editconditions&facid=' . $object->id . '">' . img_edit($langs->trans('SetConditions'), 1) . '</a></td>';
- print '</tr></table>';
- print '</td><td colspan="3">';
- if ($object->type != 2) {
- if ($action == 'editconditions') {
- $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->cond_reglement_id, 'cond_reglement_id');
- } else {
- $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->cond_reglement_id, 'none');
- }
- } else {
- print ' ';
- }
- print '</td></tr>';
- // Mode de reglement
- print '<tr><td>';
- print '<table class="nobordernopadding" width="100%"><tr><td>';
- print $langs->trans('PaymentMode');
- print '</td>';
- if ($action != 'editmode' && !empty($object->brouillon) && $user->rights->facture->creer)
- print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmode&facid=' . $object->id . '">' . img_edit($langs->trans('SetMode'), 1) . '</a></td>';
- print '</tr></table>';
- print '</td><td colspan="3">';
- if ($action == 'editmode') {
- $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->mode_reglement_id, 'mode_reglement_id');
- } else {
- $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->mode_reglement_id, 'none');
- }
- print '</td></tr>';
- // Amount
- print '<tr><td>' . $langs->trans('AmountHT') . '</td>';
- print '<td align="right" colspan="2" nowrap>' . price($object->total_ht) . '</td>';
- print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td></tr>';
- print '<tr><td>' . $langs->trans('AmountVAT') . '</td><td align="right" colspan="2" nowrap>' . price($object->total_tva) . '</td>';
- print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td>';
- print '</tr>';
- // Amount Local Taxes
- if ($mysoc->pays_code == 'ES') {
- if ($mysoc->localtax1_assuj == "1") { //Localtax1 RE
- print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->pays_code) . '</td>';
- print '<td align="right" colspan="2" nowrap>' . price($object->total_localtax1) . '</td>';
- print '<td>' . $langs->trans("Currency" . $conf->currency) . '</td></tr>';
- }
- if ($mysoc->localtax2_assuj == "1") { //Localtax2 IRPF
- print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->pays_code) . '</td>';
- print '<td align="right" colspan="2" nowrap>' . price($object->total_localtax2) . '</td>';
- print '<td>' . $langs->trans("Currency" . $conf->currency) . '</td></tr>';
- }
- }
- print '<tr><td>' . $langs->trans('AmountTTC') . '</td><td align="right" colspan="2" nowrap>' . price($object->total_ttc) . '</td>';
- print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td></tr>';
- // Statut
- print '<tr><td>' . $langs->trans('Status') . '</td>';
- print '<td align="left" colspan="3">' . ($object->getLibStatut(4, $totalpaye)) . '</td></tr>';
- // Project
- if (!empty($conf->projet->enabled)) {
- $langs->load('projects');
- print '<tr>';
- print '<td>';
- print '<table class="nobordernopadding" width="100%"><tr><td>';
- print $langs->trans('Project');
- print '</td>';
- if ($action != 'classify') {
- print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=classify&facid=' . $object->id . '">';
- print img_edit($langs->trans('SetProject'), 1);
- print '</a></td>';
- }
- print '</tr></table>';
- print '</td><td colspan="3">';
- if ($action == 'classify') {
- $form->form_project($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->socid, $object->fk_project, 'projectid');
- } else {
- $form->form_project($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->socid, $object->fk_project, 'none');
- }
- print '</td>';
- print '</tr>';
- }
- // Other attributes
- $parameters = array('colspan' => ' colspan="3"');
- $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- if (empty($reshook) && !empty($extrafields->attribute_label)) {
- foreach ($extrafields->attribute_label as $key => $label) {
- $value = (isset($_POST["options_" . $key]) ? $_POST["options_" . $key] : $object->array_options["options_" . $key]);
- print '<tr><td>' . $label . '</td><td colspan="3">';
- print $extrafields->showInputField($key, $value);
- print '</td></tr>' . "\n";
- }
- }
- print '</table><br>';
- if (!empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) {
- $blocname = 'contacts';
- $title = $langs->trans('ContactsAddresses');
- include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php';
- }
- if (!empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
- $blocname = 'notes';
- $title = $langs->trans('Notes');
- include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php';
- }
- /*
- * Lines
- */
- $result = $object->getLinesArray();
- if (!empty($conf->use_javascript_ajax) && $object->statut == 0) {
- include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
- }
- print '<table id="tablelines" class="noborder noshadow" width="100%">';
- // Show object lines
- if (!empty($object->lines))
- $ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 1);
- /*
- * Form to add new line
- */
- if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline') {
- $var = true;
- if ($conf->global->MAIN_FEATURES_LEVEL > 1) {
- // Add free or predefined products/services
- $object->formAddObjectLine(1, $mysoc, $soc);
- } else {
- // Add free products/services
- $object->formAddFreeProduct(1, $mysoc, $soc);
- // Add predefined products/services
- if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
- $var = !$var;
- $object->formAddPredefinedProduct(1, $mysoc, $soc);
- }
- }
- $parameters = array();
- $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- }
- print "</table>\n";
- print "</div>\n";
- /*
- * Boutons actions
- */
- if ($action != 'prerelance' && $action != 'presend') {
- if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline') {
- print '<div class="tabsAction">';
- // Editer une facture deja validee, sans paiement effectue et pas exporte en compta
- if ($object->statut == 1) {
- // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
- $ventilExportCompta = $object->getVentilExportCompta();
- if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) {
- if (!$objectidnext) {
- if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) {
- print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&action=modif">' . $langs->trans('Modify') . '</a>';
- } else {
- print '<span class="butActionRefused" title="' . $langs->trans("NotEnoughPermissions") . '">' . $langs->trans('Modify') . '</span>';
- }
- } else {
- print '<span class="butActionRefused" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('Modify') . '</span>';
- }
- }
- }
- // Reopen a standard paid invoice
- if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) { // A paid invoice (partially or completely)
- if (!$objectidnext && $object->close_code != 'replaced') { // Not replaced by another invoice
- print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&action=reopen">' . $langs->trans('ReOpen') . '</a>';
- } else {
- print '<span class="butActionRefused" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('ReOpen') . '</span>';
- }
- }
- // Validate
- if ($object->statut == 0 && count($object->lines) > 0 &&
- (
- (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (!empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0))
- || ($object->type == 2 && $object->total_ttc <= 0))
- ) {
- if ($user->rights->facture->valider) {
- print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&action=valid">' . $langs->trans('Validate') . '</a>';
- }
- }
- // Send by mail
- if (($object->statut == 1 || $object->statut == 2)) {
- if ($objectidnext) {
- print '<span class="butActionRefused" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('SendByMail') . '</span>';
- } else {
- if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) {
- print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&action=presend&mode=init">' . $langs->trans('SendByMail') . '</a>';
- }
- else
- print '<a class="butActionRefused" href="#">' . $langs->trans('SendByMail') . '</a>';
- }
- }
- if (!empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) { // For backward compatibility
- if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) {
- if ($objectidnext) {
- print '<span class="butActionRefused" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('SendRemindByMail') . '</span>';
- } else {
- if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) {
- print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&action=prerelance&mode=init">' . $langs->trans('SendRemindByMail') . '</a>';
- }
- else
- print '<a class="butActionRefused" href="#">' . $langs->trans('SendRemindByMail') . '</a>';
- }
- }
- }
- // Create payment
- if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) {
- if ($objectidnext) {
- print '<span class="butActionRefused" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('DoPayment') . '</span>';
- } else {
- if ($resteapayer == 0) {
- print '<span class="butActionRefused" title="' . $langs->trans("DisabledBecauseRemainderToPayIsZero") . '">' . $langs->trans('DoPayment') . '</span>';
- } else {
- print '<a class="butAction" href="paiement.php?facid=' . $object->id . '&action=create">' . $langs->trans('DoPayment') . '</a>';
- }
- }
- }
- // Reverse back money or convert to reduction
- if ($object->type == 2 || $object->type == 3) {
- // For credit note only
- if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) {
- print '<a class="butAction" href="paiement.php?facid=' . $object->id . '&action=create">' . $langs->trans('DoPaymentBack') . '</a>';
- }
- // For credit note
- if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) {
- print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&action=converttoreduc">' . $langs->trans('ConvertToReduc') . '</a>';
- }
- // For deposit invoice
- if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer) {
- print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&action=converttoreduc">' . $langs->trans('ConvertToReduc') . '</a>';
- }
- }
- // Classify paid (if not deposit and not credit note. Such invoice are "converted")
- if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement &&
- (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0))) {
- print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&action=paid">' . $langs->trans('ClassifyPaid') . '</a>';
- }
- // Classify 'closed not completely paid' (possible si validee et pas encore classee payee)
- if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0
- && $user->rights->facture->paiement) {
- if ($totalpaye > 0 || $totalcreditnotes > 0) {
- // If one payment or one credit note was linked to this invoice
- print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&action=paid">' . $langs->trans('ClassifyPaidPartially') . '</a>';
- } else {
- if ($objectidnext) {
- print '<span class="butActionRefused" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('ClassifyCanceled') . '</span>';
- } else {
- print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&action=canceled">' . $langs->trans('ClassifyCanceled') . '</a>';
- }
- }
- }
- // Clone
- if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer) {
- print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&action=clone&object=invoice">' . $langs->trans("ToClone") . '</a>';
- }
- // Clone as predefined
- if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer) {
- if (!$objectidnext) {
- print '<a class="butAction" href="facture/fiche-rec.php?facid=' . $object->id . '&action=create">' . $langs->trans("ChangeIntoRepeatableInvoice") . '</a>';
- }
- }
- // Delete
- if ($user->rights->facture->supprimer) {
- if (!$object->is_erasable()) {
- print '<a class="butActionRefused" href="#" title="' . $langs->trans("DisabledBecauseNotErasable") . '">' . $langs->trans('Delete') . '</a>';
- } else if ($objectidnext) {
- print '<a class="butActionRefused" href="#" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('Delete') . '</a>';
- } elseif ($object->getSommePaiement()) {
- print '<a class="butActionRefused" href="#" title="' . $langs->trans("DisabledBecausePayments") . '">' . $langs->trans('Delete') . '</a>';
- } else {
- print '<a class="butActionDelete" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&action=delete">' . $langs->trans('Delete') . '</a>';
- }
- } else {
- print '<a class="butActionRefused" href="#" title="' . $langs->trans("NotAllowed") . '">' . $langs->trans('Delete') . '</a>';
- }
- print '</div>';
- }
- }
- if ($action != 'prerelance' && $action != 'presend') {
- print '<table width="100%"><tr><td width="50%" valign="top">';
- print '<a name="builddoc"></a>'; // ancre
- /*
- * Documents generes
- */
- $filename = dol_sanitizeFileName($object->ref);
- $filedir = $conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref);
- $urlsource = $_SERVER['PHP_SELF'] . '?facid=' . $object->id;
- $genallowed = $user->rights->facture->creer;
- $delallowed = $user->rights->facture->supprimer;
- print '<br>';
- print $formfile->showdocuments('facture', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang);
- $somethingshown = $formfile->numoffiles;
- /*
- * Linked object block
- */
- $somethingshown = $object->showLinkedObjectBlock();
- // Link for paypal payment
- if (!empty($conf->paypal->enabled) && $object->statut != 0) {
- include_once DOL_DOCUMENT_ROOT . '/paypal/lib/paypal.lib.php';
- print showPaypalPaymentUrl('invoice', $object->ref);
- }
- print '</td><td valign="top" width="50%">';
- print '<br>';
- // List of actions on element
- include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
- $formactions = new FormActions($db);
- $somethingshown = $formactions->showactions($object, 'invoice', $socid);
- print '</td></tr></table>';
- } else {
- /*
- * Affiche formulaire mail
- */
- // By default if $action=='presend'
- $titreform = 'SendBillByMail';
- $topicmail = 'SendBillRef';
- $action = 'send';
- $modelmail = 'facture_send';
- if ($action == 'prerelance') { // For backward compatibility
- $titrefrom = 'SendReminderBillByMail';
- $topicmail = 'SendReminderBillRef';
- $action = 'relance';
- $modelmail = 'facture_relance';
- }
- $ref = dol_sanitizeFileName($object->ref);
- include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
- $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref);
- $file = $fileparams['fullname'];
- // Build document if it not exists
- if (!$file || !is_readable($file)) {
- // 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);
- }
- $result = facture_pdf_create($db, $object, GETPOST('model') ? GETPOST('model') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
- if ($result <= 0) {
- dol_print_error($db, $result);
- exit;
- }
- $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref);
- $file = $fileparams['fullname'];
- }
- print '<br>';
- print_titre($langs->trans($titreform));
- // Cree l'objet formulaire mail
- include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
- $formmail = new FormMail($db);
- $formmail->fromtype = 'user';
- $formmail->fromid = $user->id;
- $formmail->fromname = $user->getFullName($langs);
- $formmail->frommail = $user->email;
- $formmail->withfrom = 1;
- $formmail->withto = empty($_POST["sendto"]) ? 1 : $_POST["sendto"];
- $formmail->withtosocid = $soc->id;
- $formmail->withtocc = 1;
- $formmail->withtoccsocid = 0;
- $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC;
- $formmail->withtocccsocid = 0;
- $formmail->withtopic = $langs->transnoentities($topicmail, '__FACREF__');
- $formmail->withfile = 2;
- $formmail->withbody = 1;
- $formmail->withdeliveryreceipt = 1;
- $formmail->withcancel = 1;
- // Tableau des substitutions
- $formmail->substit['__FACREF__'] = $object->ref;
- $formmail->substit['__SIGNATURE__'] = $user->signature;
- $formmail->substit['__PERSONALIZED__'] = '';
- // Tableau des parametres complementaires du post
- $formmail->param['action'] = $action;
- $formmail->param['models'] = $modelmail;
- $formmail->param['facid'] = $object->id;
- $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id;
- // Init list of files
- if (GETPOST("mode") == 'init') {
- $formmail->clear_attached_files();
- $formmail->add_attached_files($file, basename($file), dol_mimetype($file));
- }
- $formmail->show_form();
- print '<br>';
- }
- } else {
- dol_print_error($db, $object->error);
- }
- }
- print end_box();
- print '</div>';
- dol_htmloutput_mesg('', $mesgs);
- llxFooter();
- $db->close();
- ?>