* Copyright (C) 2004-2016 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2015 Alexandre Spangaro * Copyright (C) 2016 Meziane Sof * Copyright (C) 2017-2018 Frédéric France * * 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 . */ /** * \file htdocs/fourn/facture/card-rec.php * \ingroup facture fournisseurs * \brief Page to show predefined invoice */ // Load Dolibarr environment require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture-rec.class.php'; require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; if (isModEnabled('project')) { include_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php'; } require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; // Load translation files required by the page $langs->loadLangs(array('bills', 'companies', 'compta', 'admin', 'other', 'products', 'banks', 'suppliers')); $action = GETPOST('action', 'alpha'); $massaction = GETPOST('massaction', 'alpha'); $show_files = GETPOST('show_files', 'int'); $confirm = GETPOST('confirm', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); $toselect = GETPOST('toselect', 'array'); $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'supplierinvoicetemplatelist'; // To manage different context of search $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); $sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); // Security check $id = (GETPOST('facid', 'int') ? GETPOST('facid', 'int') : GETPOST('id', 'int')); $lineid = GETPOST('lineid', 'int'); $title = GETPOST('title', 'alpha'); $ref_supplier = GETPOST('ref_supplier', 'alpha'); $projectid = GETPOST('projectid', 'int'); $year_date_when = GETPOST('year_date_when'); $month_date_when = GETPOST('month_date_when'); if ($user->socid) { $socid = $user->socid; } $objecttype = 'facturefournisseur_rec'; if ($action == "create" || $action == "add") { $objecttype = ''; } if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; if (! $sortorder) { $sortorder = 'DESC'; } if (! $sortfield) { $sortfield = 'f.titre'; } $pageprev = $page - 1; $pagenext = $page + 1; $object = new FactureFournisseurRec($db); if (($id > 0 || $title) && $action != 'create' && $action != 'add') { $ret = $object->fetch($id, $title); if (! $ret) { setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors'); } } // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('supplierinvoicereccard', 'globalcard')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); $permissionnote = $user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer; // Used by the include of actions_setnotes.inc.php $permissiondellink = $user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer;; // Used by the include of actions_dellink.inc.php $permissiontoedit = $user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer;; // Used by the include of actions_lineupdonw.inc.php $usercanread = $user->rights->fournisseur->facture->lire || $user->rights->supplier_invoice->lire; $usercancreate = $user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer; $usercandelete = $user->rights->fournisseur->facture->supprimer || $user->rights->supplier_invoice->supprimer; $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($usercancreate)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->supplier_invoice_advance->validate))); $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->fournisseur->supplier_invoice_advance->send); $usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)); $usercancreatemargin = $user->rights->margins->creer; $usercanreadallmargin = $user->rights->margins->liretous; $usercancreatewithdrarequest = $user->rights->prelevement->bons->creer; $now = dol_now(); $error = 0; $result = restrictedArea($user, 'facture', $object->id, $objecttype); /* * Actions */ if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } if (! GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; } $parameters = array('socid' => $socid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } if (empty($reshook)) { if (GETPOST('cancel', 'alpha')) { $action = ''; } // Selection of new fields include DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php'; // Set note include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not include_once include DOL_DOCUMENT_ROOT . '/core/actions_dellink.inc.php'; // Must be include, not include_once include DOL_DOCUMENT_ROOT . '/core/actions_lineupdown.inc.php'; // Must be include, not include_once // Create predefined invoice if ($action == 'add') { if (! GETPOST('title', 'alphanohtml')) { setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Title")), null, 'errors'); $action = "create"; $error++; } $frequency = GETPOST('frequency', 'int'); $reyear = GETPOST('reyear', 'int'); $remonth = GETPOST('remonth', 'int'); $reday = GETPOST('reday', 'int'); $rehour = GETPOST('rehour', 'int'); $remin = GETPOST('remin', 'int'); $nb_gen_max = GETPOST('nb_gen_max', 'int'); //if (empty($nb_gen_max)) $nb_gen_max =0; if (GETPOST('frequency', 'int')) { if (empty($reyear) || empty($remonth) || empty($reday)) { setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Date")), null, 'errors'); $action = "create"; $error++; } } if (! $error) { $object->titre = GETPOST('title', 'alphanohtml'); // deprecated $object->title = GETPOST('title', 'alphanohtml'); $object->fk_project = GETPOST('projectid', 'int'); $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml'); $object->note_private = GETPOST('note_private', 'restricthtml'); $object->note_public = GETPOST('note_public', 'restricthtml'); $object->model_pdf = GETPOST('modelpdf', 'alpha'); $object->usenewprice = GETPOST('usenewprice', 'alpha'); $object->frequency = $frequency; $object->unit_frequency = GETPOST('unit_frequency', 'alpha'); $object->nb_gen_max = $nb_gen_max; $object->auto_validate = GETPOST('auto_validate', 'int'); $object->generate_pdf = GETPOST('generate_pdf', 'int'); $date_next_execution = dol_mktime($rehour, $remin, 0, $remonth, $reday, $reyear); $object->date_when = $date_next_execution; $db->begin(); $oldinvoice = new FactureFournisseur($db); $oldinvoice->fetch(GETPOST('facid', 'int')); $object->cond_reglement_id = $oldinvoice->cond_reglement_id; $object->cond_reglement_code = $oldinvoice->cond_reglement_code; $object->cond_reglement_label = $oldinvoice->cond_reglement_label; $object->cond_reglement_doc = $oldinvoice->cond_reglement_doc; $object->mode_reglement_id = $oldinvoice->mode_reglement_id; $object->mode_reglement_code = $oldinvoice->mode_reglement_code; $result = $object->create($user, $oldinvoice->id); if ($result > 0) { $result = $oldinvoice->delete($user, 1); if ($result < 0) { $error++; setEventMessages($oldinvoice->error, $oldinvoice->errors, 'errors'); $action = "create"; } } else { $error++; setEventMessages($object->error, $object->errors, 'errors'); $action = "create"; } if (! $error) { $db->commit(); header("Location: " . $_SERVER['PHP_SELF'] . '?facid=' . $object->id); exit; } else { $db->rollback(); $error++; setEventMessages($object->error, $object->errors, 'errors'); $action = "create"; } } } // Delete //TODO : Droits if ($action == 'confirm_deleteinvoice' && $confirm == 'yes' && ($user->rights->fournisseur->facture->supprimer || $user->rights->supplier_invoice->supprimer)) { $object->delete($user); header('Location: ' . DOL_URL_ROOT . '/fourn/facture/list-rec.php'); exit; } // Update field // Set condition if ($action == 'setconditions' && $usercancreate) { $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); } elseif ($action == 'setmode' && $usercancreate) { // Set mode $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); } elseif ($action == 'classin' && $usercancreate) { // Set project $object->setProject(GETPOST('projectid', 'int')); } elseif ($action == 'setref_supplier' && $usercancreate) { $result = $object->setValueFrom('ref_supplier', $ref_supplier, '', null, 'text', '', $user); if ($result <= 0) { $error++; if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { $langs->load("errors"); setEventMessages($langs->trans('ErrorRefAlreadyExists', $ref_supplier), null, 'errors'); } else { setEventMessages($object->error, $object->errors, 'errors'); } } } elseif ($action == 'settitle' && $usercancreate) { $result = $object->setValueFrom('titre', $title, '', null, 'text', '', $user); if ($result > 0) { $object->titre = $title; $object->title = $title; $object->ref = $object->title; } else { $error++; if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { $langs->load("errors"); setEventMessages($langs->trans('ErrorTitreAlreadyExists', $title), null, 'errors'); } else { setEventMessages($object->error, $object->errors, 'errors'); } } } elseif ($action == 'setbankaccount' && $usercancreate) { // Set bank account $result = $object->setBankAccount(GETPOST('fk_account', 'int')); } elseif ($action == 'setfrequency' && $usercancreate) { // Set frequency and unit frequency $object->setFrequencyAndUnit(GETPOST('frequency', 'int'), GETPOST('unit_frequency', 'alpha')); } elseif ($action == 'setdate_when' && $usercancreate) { // Set next date of execution $date = dol_mktime(GETPOST('date_whenhour'), GETPOST('date_whenmin'), 0, GETPOST('date_whenmonth'), GETPOST('date_whenday'), GETPOST('date_whenyear')); if (!empty($date)) { $object->setNextDate($date); } } elseif ($action == 'setnb_gen_max' && $usercancreate) { // Set max period $object->setMaxPeriod(GETPOST('nb_gen_max', 'int')); } elseif ($action == 'setauto_validate' && $usercancreate) { // Set auto validate $object->setAutoValidate(GETPOST('auto_validate', 'int')); } elseif ($action == 'setgenerate_pdf' && $usercancreate) { // Set generate pdf $object->setGeneratepdf(GETPOST('generate_pdf', 'int')); } elseif ($action == 'setmodelpdf' && $usercancreate) { // Set model pdf $object->setModelpdf(GETPOST('modelpdf', 'alpha')); } elseif ($action == 'disable' && $usercancreate) { // Set status disabled $db->begin(); $object->fetch($id); $res = $object->setValueFrom('suspended', 1); if ($res <= 0) { $error++; } if (! $error) { $db->commit(); } else { $db->rollback(); setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'enable' && $usercancreate) { // Set status enabled $db->begin(); $object->fetch($id); $res = $object->setValueFrom('suspended', 0); if ($res <= 0) { $error++; } if (! $error) { $db->commit(); } else { $db->rollback(); setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'setmulticurrencycode' && $usercancreate) { // Multicurrency Code $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha')); } elseif ($action == 'setmulticurrencyrate' && $usercancreate) { // Multicurrency rate $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx')), GETPOST('calculation_mode', 'int')); } elseif ($action == 'setlibelle' && $usercancreate) { // Set label $object->fetch($id); $object->libelle = GETPOST('libelle'); $result = $object->update($user); if ($result < 0) { dol_print_error($db); } } // Delete line if ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate) { $object->fetch($id); $object->fetch_thirdparty(); $db->begin(); $line = new FactureFournisseurLigneRec($db); // For triggers $line->id = $lineid; if ($line->delete($user) > 0) { $result = $object->update_price(1); if ($result > 0) { $db->commit(); $object->fetch($object->id); // Reload lines } else { $db->rollback(); setEventMessages($db->lasterror(), null, 'errors'); } } else { $db->rollback(); setEventMessages($line->error, $line->errors, 'errors'); } } elseif ($action == 'update_extras') { $object->oldcopy = dol_clone($object); // Fill array 'array_options' with data from update form $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml')); if ($ret < 0) { $error++; } if (! $error) { $result = $object->insertExtraFields('BILLREC_MODIFY'); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; } } } // Add a new line if ($action == 'addline' && $usercancreate) { $langs->load('errors'); $error = 0; // Set if we used free entry or predefined product $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); $prod_entry_mode = GETPOST('prod_entry_mode', 'alpha'); if ($prod_entry_mode == 'free') { $idprod = 0; $tva_tx = (GETPOST('tva_tx', 'alpha') ? GETPOST('tva_tx', 'alpha') : 0); $ref_fournisseur = (GETPOSTISSET('fourn_ref') ? GETPOST('fourn_ref', 'restricthtml') : ''); } else { $idprod = GETPOST('idprod', 'int'); $tva_tx = ''; } $qty = price2num(GETPOST('qty' . $predef, 'alpha'), 'MS', 2); $remise_percent = price2num(GETPOST('remise_percent' . $predef), '', 2); // Extrafields $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line); $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef); // Unset extrafield if (is_array($extralabelsline)) { // Get extra fields foreach ($extralabelsline as $key => $value) { unset($_POST["options_" . $key . $predef]); } } if ((empty($idprod) || $idprod < 0) && ($price_ht < 0) && ($qty < 0)) { setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error++; } if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && (! ($price_ht >= 0) || $price_ht == '')) { // Unit price can be 0 but not '' setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); $error++; } if ($qty == '') { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors'); $error++; } if ($qty < 0) { $langs->load("errors"); setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors'); $error++; } if ($prod_entry_mode != 'free' && empty($error)) { // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or '' $productsupplier = new ProductFournisseur($db); $idprod = 0; if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') { $idprod = -99; // Same behaviour than with combolist. When not select idprodfournprice is now -99 (to avoid conflict with next action that may return -1, -2, ...) } $reg = array(); if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) { $idprod = (int) $reg[1]; $res = $productsupplier->fetch($idprod); // Load product from its id // Call to init some price properties of $productsupplier // So if a supplier price already exists for another thirdparty (first one found), we use it as reference price if (!empty($conf->global->SUPPLIER_TAKE_FIRST_PRICE_IF_NO_PRICE_FOR_CURRENT_SUPPLIER)) { $fksoctosearch = 0; $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist if ($productsupplier->fourn_socid != $socid) { // The price we found is for another supplier, so we clear supplier price $productsupplier->ref_supplier = ''; } } else { $fksoctosearch = $object->thirdparty->id; $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist } } elseif (GETPOST('idprodfournprice', 'alpha') > 0) { $qtytosearch = $qty; // Just to see if a price exists for the quantity. Not used to found vat. $idprod = $productsupplier->get_buyprice(GETPOST('idprodfournprice', 'alpha'), $qtytosearch); $res = $productsupplier->fetch($idprod); $ref_fournisseur = $productsupplier->ref_supplier; } } if (! $error && ($qty >= 0) && (!empty($product_desc) || (!empty($idprod) && $idprod > 0))) { $ret = $object->fetch($id); if ($ret < 0) { dol_print_error($db, $object->error); exit(); } $ret = $object->fetch_thirdparty(); // Clean parameters $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 $tva_tx par celui du produit // Ecrase $base_price_type par celui du produit // Replaces $fk_unit with the product's if (!empty($idprod) && $idprod > 0) { $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 $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id); $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id); if (empty($tva_tx)) { $tva_npr = 0; } // Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp']. $pqp = (GETPOST('pbq', 'int') ? GETPOST('pbq', 'int') : 0); $datapriceofproduct = $prod->getSellPrice($mysoc, $object->thirdparty, $pqp); $pu_ht = $datapriceofproduct['pu_ht']; $pu_ttc = $datapriceofproduct['pu_ttc']; $price_min = $datapriceofproduct['price_min']; $price_base_type = $datapriceofproduct['price_base_type']; $tva_tx = $datapriceofproduct['tva_tx']; $tva_npr = $datapriceofproduct['tva_npr']; $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx)); $tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx)); // if price ht was forced (ie: from gui when calculated by margin rate and cost price). TODO Why this ? if (!empty($price_ht)) { $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU'); } elseif ($tmpvat != $tmpprodvat) { // 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 ($price_base_type != 'HT') { $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU'); } else { $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU'); } } $desc = ''; // Define output language if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { $outputlangs = $langs; $newlang = ''; if (empty($newlang) && GETPOST('lang_id', 'aZ09')) { $newlang = GETPOST('lang_id', 'aZ09'); } if (empty($newlang)) { $newlang = $object->thirdparty->default_lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); $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); // Add custom code and origin country into description if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (!empty($prod->customcode) || !empty($prod->country_code))) { $tmptxt = '('; // Define output language if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { $outputlangs = $langs; $newlang = ''; if (empty($newlang) && GETPOST('lang_id', 'alpha')) { $newlang = GETPOST('lang_id', 'alpha'); } if (empty($newlang)) { $newlang = $object->thirdparty->default_lang; } if (!empty($newlang)) { $outputlangs = new Translate("", $conf); $outputlangs->setDefaultLang($newlang); $outputlangs->load('products'); } if (!empty($prod->customcode)) { $tmptxt .= $outputlangs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode; } if (!empty($prod->customcode) && !empty($prod->country_code)) { $tmptxt .= ' - '; } if (!empty($prod->country_code)) { $tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $outputlangs, 0); } } else { 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_concatdesc($desc, $tmptxt); } $type = $prod->type; $fk_unit = $prod->fk_unit; } 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); if (empty($tva_tx)) { $tva_npr = 0; } $desc = $product_desc; $type = GETPOST('type'); $fk_unit = GETPOST('units', 'alpha'); } $date_start_fill = !empty(GETPOST('date_start_fill', 'int')) ? GETPOST('date_start_fill', 'int') : null; $date_end_fill = !empty(GETPOST('date_end_fill', 'int')) ? GETPOST('date_end_fill', 'int') : null; // Margin $fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); $buyingprice = price2num(GETPOST('buying_price' . $predef) != '' ? GETPOST('buying_price' . $predef) : ''); // If buying_price is '0', we must keep this value // Local Taxes $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr); $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr); $info_bits = 0; if ($tva_npr) { $info_bits |= 0x01; } //To set vars in float type to avoid non-numeric warnings $pu_ht = (float) price2num($pu_ht); $remise_percent = (float) price2num($remise_percent); $price_min = (float) price2num($price_min); if ($usercanproductignorepricemin && (!empty($price_min) && ($pu_ht * (1 - $remise_percent / 100) < $price_min))) { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); setEventMessages($mesg, null, 'errors'); } else { // Insert line $result = $object->addline($idprod, $ref_fournisseur, $label, $desc, $pu_ht, $pu_ttc, $qty, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $price_base_type, $type, $date_start_fill, $date_end_fill, $info_bits, $special_code, -1, $fk_unit); if ($result > 0) { $object->fetch($object->id); // Reload lines unset($_POST['prod_entry_mode']); unset($_POST['qty']); unset($_POST['type']); unset($_POST['remise_percent']); unset($_POST['price_ht']); unset($_POST['multicurrency_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']); unset($_POST['np_marginRate']); unset($_POST['np_markRate']); unset($_POST['dp_desc']); unset($_POST['idprod']); unset($_POST['units']); unset($_POST['date_starthour']); unset($_POST['date_startmin']); unset($_POST['date_startsec']); unset($_POST['date_startday']); unset($_POST['date_startmonth']); unset($_POST['date_startyear']); unset($_POST['date_endhour']); unset($_POST['date_endmin']); unset($_POST['date_endsec']); unset($_POST['date_endday']); unset($_POST['date_endmonth']); unset($_POST['date_endyear']); unset($_POST['date_start_fill']); unset($_POST['date_end_fill']); unset($_POST['situations']); unset($_POST['progress']); } else { setEventMessages($object->error, $object->errors, 'errors'); } $action = ''; } } } elseif ($action == 'updateline' && $usercancreate && ! GETPOST('cancel', 'alpha')) { if (! $object->fetch($id) > 0) { dol_print_error($db); } $object->fetch_thirdparty(); // Clean parameters $date_start = ''; $date_end = ''; $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml') ? GETPOST('product_desc', 'restricthtml') : GETPOST('desc', 'restricthtml')); $ref_fourn = GETPOST('fourn_ref', 'alpha'); $pu_ht = price2num(GETPOST('price_ht'), '', 2); $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); $qty = GETPOST('qty'); $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2); // Define info_bits $info_bits = 0; if (preg_match('/\*/', $vat_rate)) { $info_bits |= 0x01; } // Define vat_rate $vat_rate = str_replace('*', '', $vat_rate); $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty); $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty); // Extrafields $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line); $array_options = $extrafields->getOptionalsFromPost($object->table_element_line); $objectline = new FactureFournisseurLigneRec($db); if ($objectline->fetch(GETPOST('lineid', 'int'))) { $objectline->array_options = $array_options; $result = $objectline->insertExtraFields(); if ($result < 0) { setEventMessages($langs->trans('Error') . $result, null, 'errors'); } } $position = ($objectline->rang >= 0 ? $objectline->rang : 0); // Unset extrafield if (is_array($extralabelsline)) { // Get extra fields foreach ($extralabelsline as $key => $value) { unset($_POST["options_" . $key]); } } // Define special_code for special lines $special_code = GETPOST('special_code', 'int'); if (! GETPOST('qty', 'alpha')) { $special_code = 3; } $remise_percent = price2num(GETPOST('remise_percent'), '', 2); // 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->thirdparty->price_level)) { $price_min = $product->multiprices_min[$object->thirdparty->price_level]; } $label = $product->label; // Check price is not lower than minimum (check is done only for standard or replacement invoices) if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && $price_min && (price2num($pu_ht) * (1 - $remise_percent / 100) < price2num($price_min))) { setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)), null, 'errors'); $error++; } } else { $type = GETPOST('type', 'int'); $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); // Check parameters if (GETPOST('type', 'int') < 0) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors'); $error++; } } if ($qty < 0) { $langs->load("errors"); setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors'); $error++; } $date_start_fill = !empty(GETPOST('date_start_fill', 'int')) ? GETPOST('date_start_fill', 'int') : 'NULL'; $date_end_fill = !empty(GETPOST('date_end_fill', 'int')) ? GETPOST('date_end_fill', 'int') : 'NULL'; // Update line if (! $error) { $result = $object->updateline(GETPOST('lineid', 'int'), GETPOST('productid', 'int'), $ref_fourn, $label, $description, $pu_ht, $qty, $remise_percent, $vat_rate, $localtax1_rate, $localtax1_rate, 'HT', $type, $date_start_fill, $date_end_fill, $info_bits, $special_code, -1); if ($result >= 0) { $object->fetch($object->id); // Reload lines unset($_POST['qty']); unset($_POST['type']); unset($_POST['productid']); unset($_POST['remise_percent']); unset($_POST['price_ht']); unset($_POST['multicurrency_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']); unset($_POST['np_marginRate']); unset($_POST['np_markRate']); unset($_POST['dp_desc']); unset($_POST['idprod']); unset($_POST['units']); unset($_POST['date_starthour']); unset($_POST['date_startmin']); unset($_POST['date_startsec']); unset($_POST['date_startday']); unset($_POST['date_startmonth']); unset($_POST['date_startyear']); unset($_POST['date_endhour']); unset($_POST['date_endmin']); unset($_POST['date_endsec']); unset($_POST['date_endday']); unset($_POST['date_endmonth']); unset($_POST['date_endyear']); unset($_POST['situations']); unset($_POST['progress']); } else { setEventMessages($object->error, $object->errors, 'errors'); } } } } /* * View */ $help_url = ''; llxHeader('', $langs->trans("RepeatableSupplierInvoice"), $help_url); $form = new Form($db); $formother = new FormOther($db); if (isModEnabled('project')) { $formproject = new FormProjets($db); } $companystatic = new Societe($db); $invoicerectmp = new FactureFournisseurRec($db); $now = dol_now(); $nowlasthour = dol_get_last_hour($now); /* * Create mode */ if ($action == 'create') { print load_fiche_titre($langs->trans("CreateRepeatableInvoice"), '', 'bill'); $object = new FactureFournisseur($db); // Source invoice $product_static = new Product($db); if ($object->fetch($id) > 0) { $result = $object->fetch_lines(); print '
'; print ''; print ''; print ''; print dol_get_fiche_head(null, '', '', 0); $rowspan = 4; if (isModEnabled('project')) $rowspan++; if ($object->fk_account > 0) $rowspan++; print ''; $object->fetch_thirdparty(); // Title print ''; // Ref supplier print ''; // Third party print ''; print ''; $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $object->note_public; $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $object->note_private; // Help of substitution key $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object); $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'm'), '%m') . ')'; $substitutionarray['__INVOICE_MONTH__'] = $langs->trans("MonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date, '%m') . ')'; $substitutionarray['__INVOICE_NEXT_MONTH__'] = $langs->trans("NextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, 1, 'm'), '%m') . ')'; $substitutionarray['__INVOICE_PREVIOUS_MONTH_TEXT__'] = $langs->trans("TextPreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'm'), '%B') . ')'; $substitutionarray['__INVOICE_MONTH_TEXT__'] = $langs->trans("TextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date, '%B') . ')'; $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = $langs->trans("TextNextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, 1, 'm'), '%B') . ')'; $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = $langs->trans("PreviousYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, -1, 'y'), '%Y') . ')'; $substitutionarray['__INVOICE_YEAR__'] = $langs->trans("YearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date, '%Y') . ')'; $substitutionarray['__INVOICE_NEXT_YEAR__'] = $langs->trans("NextYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date, 1, 'y'), '%Y') . ')'; // Only on template invoices $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $langs->trans("DateNextInvoiceBeforeGen") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($object->date_when, 'dayhour') . ')'; $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = $langs->trans("DateNextInvoiceAfterGen") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($object->date_when, $object->frequency, $object->unit_frequency), 'dayhour') . ')'; $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $langs->trans("Count"); $substitutionarray['__INVOICE_COUNTER_MAX__'] = $langs->trans("MaxPeriodNumber"); $htmltext = '' . $langs->trans("FollowingConstantsWillBeSubstituted") . ':
'; foreach ($substitutionarray as $key => $val) { $htmltext .= $key . ' = ' . $langs->trans($val) . '
'; } $htmltext .= '
'; // Libelle print ''; // Public note print ''; print ''; print ''; print ''; print ''; } // Author print ""; // Payment term print ""; // Payment mode print ""; // Project if (isModEnabled('project') && is_object($object->thirdparty) && $object->thirdparty->id > 0) { $projectid = GETPOST('projectid') ? GETPOST('projectid') : $object->fk_project; $langs->load('projects'); print ''; } // Bank account if ($object->fk_account > 0) { print ""; } // Model pdf print ""; print "
' . $langs->trans("Title") . ''; print ''; print '
' . $langs->trans("SupplierRef") . ''; print ''; print '
' . $langs->trans("Customer") . '' . $object->thirdparty->getNomUrl(1, 'customer') . '
' . $langs->trans("Label") . ''; print ''; print '
'; print $form->textwithpicto($langs->trans('NotePublic'), $htmltext, 1, 'help', '', 0, 2, 'notepublic'); print ''; $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->global->FCKEDITOR_ENABLE_NOTE_PUBLIC) ? 0 : 1, ROWS_3, '90%'); print $doleditor->Create(1); // Private note if (empty($user->socid)) { print '
'; print $form->textwithpicto($langs->trans('NotePrivate'), $htmltext, 1, 'help', '', 0, 2, 'noteprivate'); print ''; $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->global->FCKEDITOR_ENABLE_NOTE_PRIVATE) ? 0 : 1, ROWS_3, '90%'); print $doleditor->Create(1); print '
" . $langs->trans("Author") . "" . $user->getFullName($langs) . "
" . $langs->trans("PaymentConditions") . ""; $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->cond_reglement_id, 'none'); print "
" . $langs->trans("PaymentMode") . ""; $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'none', '', 1); print "
' . $langs->trans('Project') . ''; $numprojet = $formproject->select_projects($object->thirdparty->id, $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, ''); print '   thirdparty->id . (!empty($id) ? '&id=' . $id : '')) . '">' . $langs->trans("AddProject") . ''; print '
" . $langs->trans('BankAccount') . ""; $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'none'); print "
" . $langs->trans('Model') . ""; include_once DOL_DOCUMENT_ROOT . '/core/modules/supplier_invoice/modules_facturefournisseur.php'; $list = ModelePDFSuppliersInvoices::liste_modeles($db); print $form->selectarray('modelpdf', $list, $conf->global->INVOICE_SUPPLIER_ADDON_PDF); print "
"; print dol_get_fiche_end(); // Autogeneration $title = $langs->trans("Recurrence"); print load_fiche_titre(img_picto('', 'recurring', 'class="pictofixedwidth"') . $title, '', ''); print dol_get_fiche_head(null, '', '', 0); print ''; // Frequency + unit print '"; // Date next run print ""; // Number max of generation print ""; // Auto validate the invoice print ""; // Auto generate document if (!empty($conf->global->INVOICE_REC_CAN_DISABLE_DOCUMENT_FILE_GENERATION)) { print ""; } else { print ''; } print "
' . $form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency')) . ""; print " " . $form->selectarray('unit_frequency', array('d' => $langs->trans('Day'), 'm' => $langs->trans('Month'), 'y' => $langs->trans('Year')), (GETPOST('unit_frequency') ? GETPOST('unit_frequency') : 'm')); print "
" . $langs->trans('NextDateToExecution') . ""; $date_next_execution = isset($date_next_execution) ? $date_next_execution : (GETPOST('remonth') ? dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')) : -1); print $form->selectDate($date_next_execution, '', 1, 1, '', "add", 1, 1); print "
" . $langs->trans("MaxPeriodNumber") . ""; print ''; print "
" . $langs->trans("StatusOfGeneratedInvoices") . ""; $select = array('0' => $langs->trans('BillStatusDraft'), '1' => $langs->trans('BillStatusValidated')); print $form->selectarray('auto_validate', $select, GETPOST('auto_validate')); print "
" . $langs->trans("StatusOfGeneratedDocuments") . ""; $select = array('0' => $langs->trans('DoNotGenerateDoc'), '1' => $langs->trans('AutoGenerateDoc')); print $form->selectarray('generate_pdf', $select, GETPOST('generate_pdf')); print "
"; print dol_get_fiche_end(); $title = $langs->trans("ProductsAndServices"); if (empty($conf->service->enabled)) { $title = $langs->trans("Products"); } elseif (empty($conf->product->enabled)) { $title = $langs->trans("Services"); } print load_fiche_titre($title, '', ''); /* * Invoice lines */ print '
'; print ''; // Show object lines if (!empty($object->lines)) { $disableedit = 1; $disablemove = 1; $disableremove = 1; $object->printObjectLines('', $mysoc, $object->thirdparty, $lineid, 0); // No date selector for template invoice } print "
\n"; print '
'; print ''; print "\n"; print $form->buttonsSaveCancel("Create"); print "\n"; } else { dol_print_error('', "Error, no invoice " . $object->id); } } else { /* * View mode */ if ($object->id > 0) { $object->fetch($object->id); $object->fetch_thirdparty(); // Confirmation de la suppression d'une ligne produit if ($action == 'ask_deleteline') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1); } // Confirm delete of repeatable invoice if ($action == 'ask_deleteinvoice') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteRepeatableInvoice'), $langs->trans('ConfirmDeleteRepeatableInvoice'), 'confirm_deleteinvoice', '', 'no', 1); } print $formconfirm; $author = new User($db); $author->fetch($object->user_author); $head = supplier_invoice_rec_prepare_head($object); print dol_get_fiche_head($head, 'card', $langs->trans('RepeatableInvoice'), -1, 'bill'); // Add a div // Recurring invoice content $linkback = '' . $langs->trans('BackToList') . ''; $morehtmlref = ''; if ($action != 'edittitle') { $morehtmlref .= $form->editfieldkey($object->titre, 'title', $object->titre, $object, $usercancreate, '', '', 0, 2); } else { $morehtmlref .= $form->editfieldval('', 'title', $object->titre, $object, $usercancreate, 'string'); } $morehtmlref .= '
'; //Ref supplier $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', 0, 1); $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', null, null, '', 1); // Thirdparty $morehtmlref .= '
' . $langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1); // Project if (isModEnabled('project')) { $langs->load('projects'); $morehtmlref .= '
' . $langs->trans('Project') . ' '; if ($usercancreate) { if ($action != 'classify') { $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; } if ($action == 'classify') { $morehtmlref .= '
'; $morehtmlref .= ''; $morehtmlref .= ''; $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); $morehtmlref .= ''; $morehtmlref .= '
'; } else { $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); } } else { if (!empty($object->fk_project)) { $project = new Project($db); $project->fetch($object->fk_project); $morehtmlref .= ' : ' . $project->getNomUrl(1); if ($project->title) { $morehtmlref .= ' - ' . $project->title; } } else { $morehtmlref .= ''; } } } $morehtmlref .= '
'; $morehtmlright = ''; dol_banner_tab($object, 'ref', $linkback, 1, 'title', 'none', $morehtmlref, '', 0, '', $morehtmlright); print '
'; print '
'; print '
'; print ''; print '"; // Label print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; // Amount Local Taxes if (($mysoc->localtax1_assuj == "1" && $mysoc->useLocalTax(1)) || $object->total_localtax1 != 0) { // Localtax1 print ''; print ''; } if (($mysoc->localtax2_assuj == "1" && $mysoc->useLocalTax(2)) || $object->total_localtax2 != 0) { // Localtax2 print ''; print ''; } print ''; print ''; // Payment term print ''; // Payment mode print ''; // Multicurrency if (isModEnabled("multicurrency")) { // Multicurrency code print ''; print ''; // Multicurrency rate if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) { print ''; print ''; } } // Help of substitution key $dateexample = dol_now(); if (!empty($object->frequency) && !empty($object->date_when)) { $dateexample = $object->date_when; } $substitutionarray = getCommonSubstitutionArray($langs, 2, null, $object); $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = $langs->trans("PreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m') . ')'; $substitutionarray['__INVOICE_MONTH__'] = $langs->trans("MonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($dateexample, '%m') . ')'; $substitutionarray['__INVOICE_NEXT_MONTH__'] = $langs->trans("NextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%m') . ')'; $substitutionarray['__INVOICE_PREVIOUS_MONTH_TEXT__'] = $langs->trans("TextPreviousMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%B') . ')'; $substitutionarray['__INVOICE_MONTH_TEXT__'] = $langs->trans("TextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($dateexample, '%B') . ')'; $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = $langs->trans("TextNextMonthOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B') . ')'; $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = $langs->trans("PreviousYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'), '%Y') . ')'; $substitutionarray['__INVOICE_YEAR__'] = $langs->trans("YearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date($dateexample, '%Y') . ')'; $substitutionarray['__INVOICE_NEXT_YEAR__'] = $langs->trans("NextYearOfInvoice") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'), '%Y') . ')'; // Only on template invoices $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $langs->trans("DateNextInvoiceBeforeGen") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(($object->date_when ? $object->date_when : dol_now()), 'dayhour') . ')'; $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = $langs->trans("DateNextInvoiceAfterGen") . ' (' . $langs->trans("Example") . ': ' . dol_print_date(dol_time_plus_duree(($object->date_when ? $object->date_when : dol_now()), $object->frequency, $object->unit_frequency), 'dayhour') . ')'; $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $object->nb_gen_done; $substitutionarray['__INVOICE_COUNTER_MAX__'] = $object->nb_gen_max; $htmltext = '' . $langs->trans("FollowingConstantsWillBeSubstituted") . ':
'; foreach ($substitutionarray as $key => $val) { $htmltext .= $key . ' = ' . $langs->trans($val) . '
'; } $htmltext .= '
'; // Note public print ''; print ''; // Note private print ''; print ''; // Bank Account print '"; print ''; // Model pdf print '"; print ''; // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; print '
' . $langs->trans('Author') . ''; print $author->getNomUrl(-1); print "
' . $form->editfieldkey("Label", 'libelle', $object->libelle, $object, $usercancreate) . '' . $form->editfieldval("Label", 'libelle', $object->libelle, $object, $usercancreate) . '
' . $langs->trans('AmountHT') . '' . price($object->total_ht, '', $langs, 1, -1, -1, $conf->currency) . '
' . $langs->trans("AmountVAT") . '' . price($object->total_tva, '', $langs, 1, -1, -1, $conf->currency) . '
' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '' . price($object->total_localtax1, 1, '', 1, -1, -1, $conf->currency) . '
' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '' . price($object->total_localtax2, 1, '', 1, -1, -1, $conf->currency) . '
' . $langs->trans("AmountTTC") . '' . price($object->total_ttc, '', $langs, 1, -1, -1, $conf->currency) . '
'; print ''; if ($action != 'editconditions' && $usercancreate) { print ''; } print '
'; print $langs->trans('PaymentConditionsShort'); print '' . img_edit($langs->trans('SetConditions'), 1) . '
'; print '
'; 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'); } print '
'; print ''; if ($action != 'editmode' && $usercancreate) { print ''; } print '
'; print $langs->trans('PaymentMode'); print '' . img_edit($langs->trans('SetMode'), 1) . '
'; print '
'; if ($action == 'editmode') { $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1); } else { $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->mode_reglement_id, 'none'); } print '
'; print ''; if ($usercancreate && $action != 'editmulticurrencycode' && !empty($object->brouillon)) { print ''; } print '
'; print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0); print '' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
'; print '
'; $htmlname = (($usercancreate && $action == 'editmulticurrencycode') ? 'multicurrency_code' : 'none'); $form->form_multicurrency_code($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_code, $htmlname); print '
'; print ''; if ($usercancreate && $action != 'editmulticurrencyrate' && !empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { print ''; } print '
'; print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0); print '' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
'; print '
'; if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') { if ($action == 'actualizemulticurrencyrate') { list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code); } $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, ($usercancreate ? 'multicurrency_tx' : 'none'), $object->multicurrency_code); } else { $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code); if ($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { print '
        '; print '' . $langs->trans("ActualizeCurrency") . ''; print '
'; } } print '
'; print $form->editfieldkey($form->textwithpicto($langs->trans('NotePublic'), $htmltext, 1, 'help', '', 0, 2, 'notepublic'), 'note_public', $object->note_public, $object, $usercancreate); print ''; print $form->editfieldval($langs->trans("NotePublic"), 'note_public', $object->note_public, $object, $usercancreate, 'textarea:' . ROWS_4 . ':90%', '', null, null, '', 1); print '
'; print $form->editfieldkey($form->textwithpicto($langs->trans("NotePrivate"), $htmltext, 1, 'help', '', 0, 2, 'noteprivate'), 'note_private', $object->note_private, $object, $usercancreate); print ''; print $form->editfieldval($langs->trans("NotePrivate"), 'note_private', $object->note_private, $object, $usercancreate, 'textarea:' . ROWS_4 . ':90%', '', null, null, '', 1); print '
'; print ''; } print '
'; print $langs->trans('BankAccount'); print ''; if ($action != 'editbankaccount' && $usercancreate && $object->statut == FactureFournisseurRec::STATUS_NOTSUSPENDED) { print '' . img_edit($langs->trans('SetBankAccount'), 1) . '
'; print '
'; if ($action == 'editbankaccount') { $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'fk_account', 1); } else { $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'none'); } print "
'; print ''; } print '
'; print $langs->trans('Model'); print ''; if ($action != 'editmodelpdf' && $usercancreate && $object->statut == FactureFournisseurRec::STATUS_NOTSUSPENDED) { print '' . img_edit($langs->trans('SetModel'), 1) . '
'; print '
'; if ($action == 'editmodelpdf') { include_once DOL_DOCUMENT_ROOT . '/core/modules/supplier_invoice/modules_facturefournisseur.php'; $list = array(); $models = ModelePDFSuppliersInvoices::liste_modeles($db); foreach ($models as $k => $model) { $list[] = str_replace(':', '|', $k) . ':' . $model; } $select = 'select;' . implode(',', $list); //TODO : Droits print $form->editfieldval($langs->trans('Model'), 'modelpdf', $object->model_pdf, $object, $usercancreate, $select); } else { print $object->model_pdf; } print "
'; print '
'; print '
'; print '
'; /* * Recurrence */ $title = $langs->trans("Recurrence"); //print load_fiche_titre($title, '', 'calendar'); print ''; print ''; // if "frequency" is empty or = 0, the reccurence is disabled print ''; // Date when (next invoice generation) print ''; print ''; // Max period / Rest period print ''; print ''; // Status of generated invoices print ''; // Auto generate documents if (!empty($conf->global->INVOICE_REC_CAN_DISABLE_DOCUMENT_FILE_GENERATION)) { print ''; print ''; print ''; print ''; } else { print ''; } print '
' . img_picto('', 'recurring', 'class="pictofixedwidth"') . $title . '
'; print ''; if ($action != 'editfrequency' && $usercancreate) { print ''; } print '
'; print $langs->trans('Frequency'); print '' . img_edit($langs->trans('Edit'), 1) . '
'; print '
'; if ($action == 'editfrequency') { print '
'; print ''; print ''; print ''; print ''; print ''; print '
'; print " " . $form->selectarray('unit_frequency', array('d' => $langs->trans('Day'), 'm' => $langs->trans('Month'), 'y' => $langs->trans('Year')), ($object->unit_frequency ? $object->unit_frequency : 'm')); print '
'; } else { if ($object->frequency > 0) { print $langs->trans('FrequencyPer_' . $object->unit_frequency, $object->frequency); } else { print $langs->trans("NotARecurringInvoiceTemplate"); } } print '
'; if ($action == 'date_when' || $object->frequency > 0) { print $form->editfieldkey($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $usercancreate, 'day'); } else { print $langs->trans("NextDateToExecution"); } print ''; if ($action == 'date_when' || $object->frequency > 0) { print $form->editfieldval($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $usercancreate, 'day', $object->date_when, null, '', '', 0, 'strikeIfMaxNbGenReached'); } //var_dump(dol_print_date($object->date_when+60, 'dayhour').' - '.dol_print_date($now, 'dayhour')); if (! $object->isMaxNbGenReached()) { if (! $object->suspended && $action != 'editdate_when' && $object->frequency > 0 && $object->date_when && $object->date_when < $now) { print img_warning($langs->trans("Late")); } } else { print img_info($langs->trans("MaxNumberOfGenerationReached")); } print '
'; if ($action == 'nb_gen_max' || $object->frequency > 0) { print $form->editfieldkey($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max, $object, $usercancreate); } else { print $langs->trans("MaxPeriodNumber"); } print ''; if ($action == 'nb_gen_max' || $object->frequency > 0) { print $form->editfieldval($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max ? $object->nb_gen_max : '', $object, $usercancreate); } else { print ''; } print '
'; if ($action == 'auto_validate' || $object->frequency > 0) { print $form->editfieldkey($langs->trans("StatusOfGeneratedInvoices"), 'auto_validate', $object->auto_validate, $object, $usercancreate); } else { print $langs->trans("StatusOfGeneratedInvoices"); } print ''; $select = 'select;0:' . $langs->trans('BillStatusDraft') . ',1:' . $langs->trans('BillStatusValidated'); if ($action == 'auto_validate' || $object->frequency > 0) { print $form->editfieldval($langs->trans("StatusOfGeneratedInvoices"), 'auto_validate', $object->auto_validate, $object, $usercancreate, $select); } print '
'; if ($action == 'generate_pdf' || $object->frequency > 0) { print $form->editfieldkey($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', $object->generate_pdf, $object, $usercancreate); } else { print $langs->trans("StatusOfGeneratedDocuments"); } print ''; $select = 'select;0:' . $langs->trans('DoNotGenerateDoc') . ',1:' . $langs->trans('AutogenerateDoc'); if ($action == 'generate_pdf' || $object->frequency > 0) { print $form->editfieldval($langs->trans("StatusOfGeneratedDocuments"), 'generate_pdf', $object->generate_pdf, $object, $usercancreate, $select); } print '
'; // Frequencry/Recurring section if ($object->frequency > 0) { print '
'; if (empty($conf->cron->enabled)) { print info_admin($langs->trans("EnableAndSetupModuleCron", $langs->transnoentitiesnoconv("Module2300Name"))); } print '
'; print ''; // Nb of generation already done print ''; print ''; print ''; // Date last print ''; print ''; print '
' . $langs->trans("NbOfGenerationDone") . ''; print $object->nb_gen_done ? $object->nb_gen_done : '0'; print '
'; print $langs->trans("DateLastGeneration"); print ''; print dol_print_date($object->date_last_gen, 'dayhour'); print '
'; print '
'; } print '
'; print '
'; print '

'; // Lines print '
'; if (!empty($conf->use_javascript_ajax) && $object->statut == 0) { include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; } print '
'; print ''; $object->fetch_lines(); // Show object lines if (!empty($object->lines)) { $canchangeproduct = 1; // To set ref for getNomURL function foreach ($object->lines as $line) { $line->ref = $line->label; $line->product_label = $line->label; $line->subprice = $line->pu_ht; } global $canchangeproduct; $canchangeproduct = 0; $object->statut = $object->suspended; $object->printObjectLines($action, $mysoc, $object->thirdparty, $lineid, 0); // No date selector for template invoice } // Form to add new line //TODO : Droits if ($object->statut == $object::STATUS_DRAFT && $usercancreate && $action != 'valid' && $action != 'editline') { if ($action != 'editline') { // Add free products/services $parameters = array(); $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); if (empty($reshook)) global $senderissupplier; $senderissupplier = 2; $object->formAddObjectLine(0, $object->thirdparty, $mysoc); // No date selector for template invoice } } print "
\n"; print '
'; print "
\n"; print dol_get_fiche_end(); /* * Action bar */ print '
'; if (empty($object->suspended)) { if ($usercancreate) { if (!empty($object->frequency) && $object->nb_gen_max > 0 && ($object->nb_gen_done >= $object->nb_gen_max)) { print ''; } else { if (empty($object->frequency) || $object->date_when <= $nowlasthour) { print ''; } else { print ''; } } } else { print ''; } } if ($usercancreate) { if (empty($object->suspended)) { print ''; } else { print ''; } } // Delete print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=ask_deleteinvoice&token='.newToken(), 'delete', ($user->rights->fournisseur->facture->supprimer || $user->rights->supplier_invoice->supprimer)); print '
'; print '
'; print ''; // ancre // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('invoice')); $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); print '
'; } } // End of page llxFooter(); $db->close();