Merge branch 'develop' of ssh://github.com/Dolibarr/dolibarr into fix_5053
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 251 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 96 KiB |
@ -126,8 +126,8 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e
|
||||
if (empty($reshook))
|
||||
{
|
||||
if ($cancel) $action='';
|
||||
|
||||
include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once
|
||||
|
||||
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
|
||||
|
||||
@ -672,7 +672,7 @@ if (empty($reshook))
|
||||
|
||||
/*
|
||||
* Insert new invoice in database
|
||||
*/
|
||||
*/
|
||||
else if ($action == 'add' && $user->rights->facture->creer)
|
||||
{
|
||||
if ($socid > 0) $object->socid = GETPOST('socid', 'int');
|
||||
@ -722,7 +722,7 @@ if (empty($reshook))
|
||||
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
||||
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
|
||||
$object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int');
|
||||
|
||||
|
||||
// Proprietes particulieres a facture de remplacement
|
||||
$object->fk_facture_source = $_POST['fac_replacement'];
|
||||
$object->type = Facture::TYPE_REPLACEMENT;
|
||||
@ -868,6 +868,15 @@ if (empty($reshook))
|
||||
$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['type'] == 3?1:$_POST['cond_reglement_id']);
|
||||
$object->mode_reglement_id = $_POST['mode_reglement_id'];
|
||||
$object->fk_account = GETPOST('fk_account', 'int');
|
||||
$object->amount = $_POST['amount'];
|
||||
$object->remise_absolue = $_POST['remise_absolue'];
|
||||
$object->remise_percent = $_POST['remise_percent'];
|
||||
$object->fk_incoterms = GETPOST('incoterm_id', 'int');
|
||||
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
||||
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
|
||||
$object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int');
|
||||
|
||||
@ -2329,6 +2338,15 @@ if ($action == 'create')
|
||||
}
|
||||
}
|
||||
|
||||
// Template invoice
|
||||
print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
|
||||
$tmp='<input type="radio" name="type" id="radio_template" value="0" disabled> ';
|
||||
$text = $tmp.$langs->trans("RepeatableInvoice") . ' ';
|
||||
//$text.= '('.$langs->trans("YouMustCreateStandardInvoiceFirst").') ';
|
||||
$desc = $form->textwithpicto($text, $langs->transnoentities("YouMustCreateStandardInvoiceFirstDesc"), 1, 'help', '', 0, 3);
|
||||
print $desc;
|
||||
print '</div></div>';
|
||||
|
||||
print '</div>';
|
||||
|
||||
print '</td></tr>';
|
||||
|
||||
@ -348,7 +348,7 @@ class FactureRec extends CommonInvoice
|
||||
*/
|
||||
function fetch_lines()
|
||||
{
|
||||
$sql = 'SELECT l.rowid, l.fk_product, l.product_type, l.label as custom_label, l.description, l.price, l.qty, l.tva_tx, ';
|
||||
$sql = 'SELECT l.rowid, l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, ';
|
||||
$sql.= ' l.remise, l.remise_percent, l.subprice,';
|
||||
$sql.= ' l.total_ht, l.total_tva, l.total_ttc,';
|
||||
$sql.= ' l.rang, l.special_code,';
|
||||
@ -358,7 +358,7 @@ class FactureRec extends CommonInvoice
|
||||
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
|
||||
$sql.= ' WHERE l.fk_facture = '.$this->id;
|
||||
|
||||
dol_syslog('Facture::fetch_lines', LOG_DEBUG);
|
||||
dol_syslog('FactureRec::fetch_lines', LOG_DEBUG);
|
||||
$result = $this->db->query($sql);
|
||||
if ($result)
|
||||
{
|
||||
@ -369,10 +369,13 @@ class FactureRec extends CommonInvoice
|
||||
$objp = $this->db->fetch_object($result);
|
||||
$line = new FactureLigne($this->db);
|
||||
|
||||
$line->id = $objp->rowid;
|
||||
$line->rowid = $objp->rowid;
|
||||
$line->label = $objp->custom_label; // Label line
|
||||
$line->desc = $objp->description; // Description line
|
||||
$line->description = $objp->description; // Description line
|
||||
$line->product_type = $objp->product_type; // Type of line
|
||||
$line->ref = $objp->product_ref; // Ref product
|
||||
$line->product_ref = $objp->product_ref; // Ref product
|
||||
$line->libelle = $objp->product_label; // deprecated
|
||||
$line->product_label = $objp->product_label; // Label product
|
||||
@ -904,3 +907,52 @@ class FactureRec extends CommonInvoice
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage invoice lines of templates.
|
||||
* Saved into database table llx_facturedet_rec
|
||||
*/
|
||||
class FactureLigneRec extends CommonInvoiceLine
|
||||
{
|
||||
|
||||
/**
|
||||
* Delete line in database
|
||||
*
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
global $conf,$langs,$user;
|
||||
|
||||
$error=0;
|
||||
|
||||
$this->db->begin();
|
||||
|
||||
// Call trigger
|
||||
/*$result=$this->call_trigger('LINEBILLREC_DELETE',$user);
|
||||
if ($result < 0)
|
||||
{
|
||||
$this->db->rollback();
|
||||
return -1;
|
||||
}*/
|
||||
// End call triggers
|
||||
|
||||
|
||||
$sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet_rec WHERE rowid = ".($this->rowid > 0 ? $this->rowid : $this->id);
|
||||
dol_syslog(get_class($this)."::delete", LOG_DEBUG);
|
||||
if ($this->db->query($sql) )
|
||||
{
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error=$this->db->error()." sql=".$sql;
|
||||
$this->db->rollback();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -280,7 +280,7 @@ class Facture extends CommonInvoice
|
||||
|
||||
$this->socid = $_facrec->socid;
|
||||
|
||||
$this->fk_project = $_facrec->fk_project;
|
||||
$this->fk_project = GETPOST('projectid','int') > 0 ? GETPOST('projectid','int') : $_facrec->fk_project;
|
||||
$this->fk_account = $_facrec->fk_account;
|
||||
$this->cond_reglement_id = $_facrec->cond_reglement_id;
|
||||
$this->mode_reglement_id = $_facrec->mode_reglement_id;
|
||||
|
||||
@ -32,18 +32,23 @@ require '../../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
|
||||
|
||||
$langs->load('bills');
|
||||
$langs->load('compta');
|
||||
|
||||
// Security check
|
||||
$id=(GETPOST('facid','int')?GETPOST('facid','int'):GETPOST('id','int'));
|
||||
$confirm = GETPOST('confirm', 'alpha');
|
||||
$cancel = GETPOST('cancel', 'alpha');
|
||||
$lineid=GETPOST('lineid','int');
|
||||
$ref=GETPOST('ref','alpha');
|
||||
$action=GETPOST('action', 'alpha');
|
||||
if ($user->societe_id) $socid=$user->societe_id;
|
||||
$objecttype = 'facture_rec';
|
||||
if ($action == "create" || $action == "add") $objecttype = '';
|
||||
$result = restrictedArea($user, 'facture', $id, $objecttype);
|
||||
$projectid = GETPOST('projectid','int');
|
||||
|
||||
if ($page == -1)
|
||||
{
|
||||
@ -68,10 +73,16 @@ if (($id > 0 || $ref) && $action != 'create' && $action != 'add')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actions
|
||||
*/
|
||||
|
||||
// Set note
|
||||
$permissionnote=$user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php
|
||||
include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.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')
|
||||
@ -119,6 +130,8 @@ if ($action == 'add')
|
||||
$object->nb_gen_max = $nb_gen_max;
|
||||
$object->auto_validate = GETPOST('auto_validate', 'int');
|
||||
|
||||
$object->fk_project = $projectid;
|
||||
|
||||
$date_next_execution = dol_mktime($rehour, $remin, 0, $remonth, $reday, $reyear);
|
||||
$object->date_when = $date_next_execution;
|
||||
|
||||
@ -233,9 +246,329 @@ elseif ($action == 'setauto_validate' && $user->rights->facture->creer)
|
||||
{
|
||||
$object->setAutoValidate(GETPOST('auto_validate', 'int'));
|
||||
}
|
||||
// Set note
|
||||
$permissionnote=$user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php
|
||||
include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once
|
||||
|
||||
// Delete line
|
||||
if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->facture->creer)
|
||||
{
|
||||
$object->fetch($id);
|
||||
$object->fetch_thirdparty();
|
||||
|
||||
$db->begin();
|
||||
|
||||
$line=new FactureLigneRec($db);
|
||||
|
||||
// For triggers
|
||||
$line->id = $lineid;
|
||||
|
||||
if ($line->delete() > 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');
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new line
|
||||
if ($action == 'addline' && $user->rights->facture->creer)
|
||||
{
|
||||
$langs->load('errors');
|
||||
$error = 0;
|
||||
|
||||
// Set if we used free entry or predefined product
|
||||
$predef='';
|
||||
$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
|
||||
$price_ht = GETPOST('price_ht');
|
||||
if (GETPOST('prod_entry_mode') == 'free')
|
||||
{
|
||||
$idprod=0;
|
||||
$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$idprod=GETPOST('idprod', 'int');
|
||||
$tva_tx = '';
|
||||
}
|
||||
|
||||
$qty = GETPOST('qty' . $predef);
|
||||
$remise_percent = GETPOST('remise_percent' . $predef);
|
||||
|
||||
// Extrafields
|
||||
$extrafieldsline = new ExtraFields($db);
|
||||
$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
|
||||
$array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
|
||||
// Unset extrafield
|
||||
if (is_array($extralabelsline)) {
|
||||
// Get extra fields
|
||||
foreach ($extralabelsline as $key => $value) {
|
||||
unset($_POST["options_" . $key . $predef]);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) {
|
||||
setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
|
||||
$error ++;
|
||||
}
|
||||
if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) {
|
||||
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
|
||||
$error ++;
|
||||
}
|
||||
if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($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 (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && 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 (! $error && ($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
|
||||
$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
|
||||
// Replaces $fk_unit with the product's
|
||||
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
|
||||
$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;
|
||||
|
||||
$pu_ht = $prod->price;
|
||||
$pu_ttc = $prod->price_ttc;
|
||||
$price_min = $prod->price_min;
|
||||
$price_base_type = $prod->price_base_type;
|
||||
|
||||
// We define price for product
|
||||
if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
|
||||
{
|
||||
$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
|
||||
$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
|
||||
$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
|
||||
$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
|
||||
if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility
|
||||
{
|
||||
if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
|
||||
if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level];
|
||||
if (empty($tva_tx)) $tva_npr=0;
|
||||
}
|
||||
}
|
||||
elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
|
||||
{
|
||||
require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
|
||||
|
||||
$prodcustprice = new Productcustomerprice($db);
|
||||
|
||||
$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
|
||||
|
||||
$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
|
||||
if ($result) {
|
||||
if (count($prodcustprice->lines) > 0) {
|
||||
$pu_ht = price($prodcustprice->lines[0]->price);
|
||||
$pu_ttc = price($prodcustprice->lines[0]->price_ttc);
|
||||
$price_base_type = $prodcustprice->lines[0]->price_base_type;
|
||||
$prod->tva_tx = $prodcustprice->lines[0]->tva_tx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if price ht was forced (ie: from gui when calculated by margin rate and cost price)
|
||||
if (! empty($price_ht))
|
||||
{
|
||||
$pu_ht = price2num($price_ht, 'MU');
|
||||
$pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU');
|
||||
}
|
||||
// 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).
|
||||
elseif ($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->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 = '(';
|
||||
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;
|
||||
$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
|
||||
$desc = $product_desc;
|
||||
$type = GETPOST('type');
|
||||
$fk_unit= GETPOST('units', 'alpha');
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($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($desc, $pu_ht, $qty, $tva_tx, $idprod, $remise_percent, $price_base_type, $info_bits, '', $pu_ttc, $type, - 1, $special_code, $label, $fk_unit);
|
||||
|
||||
if ($result > 0)
|
||||
{
|
||||
// Define output language
|
||||
/*if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
|
||||
{
|
||||
$outputlangs = $langs;
|
||||
$newlang = '';
|
||||
if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha');
|
||||
if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
|
||||
if (! empty($newlang)) {
|
||||
$outputlangs = new Translate("", $conf);
|
||||
$outputlangs->setDefaultLang($newlang);
|
||||
}
|
||||
$model=$object->modelpdf;
|
||||
$ret = $object->fetch($id); // Reload to get new records
|
||||
|
||||
$result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
||||
if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
|
||||
}*/
|
||||
$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['situations']);
|
||||
unset($_POST['progress']);
|
||||
} else {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
}
|
||||
|
||||
$action = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -262,7 +595,8 @@ if ($action == 'create')
|
||||
|
||||
$object = new Facture($db); // Source invoice
|
||||
$product_static = new Product($db);
|
||||
|
||||
$formproject = new FormProjets($db);
|
||||
|
||||
if ($object->fetch($id, $ref) > 0)
|
||||
{
|
||||
print '<form action="fiche-rec.php" method="post">';
|
||||
@ -281,14 +615,14 @@ if ($action == 'create')
|
||||
$object->fetch_thirdparty();
|
||||
|
||||
// Third party
|
||||
print '<tr><td>'.$langs->trans("Customer").'</td><td>'.$object->thirdparty->getNomUrl(1,'customer').'</td>';
|
||||
print '<tr><td class="titlefieldcreate">'.$langs->trans("Customer").'</td><td>'.$object->thirdparty->getNomUrl(1,'customer').'</td>';
|
||||
print '<td>';
|
||||
print $langs->trans("Comment");
|
||||
print '</td></tr>';
|
||||
|
||||
// Title
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans("Title").'</td><td>';
|
||||
print '<input class="flat" type="text" name="titre" size="24" value="'.$_POST["titre"].'">';
|
||||
print '<input class="flat quatrevingtpercent" type="text" name="titre" value="'.$_POST["titre"].'">';
|
||||
print '</td>';
|
||||
|
||||
// Note
|
||||
@ -310,18 +644,16 @@ if ($action == 'create')
|
||||
print "</td></tr>";
|
||||
|
||||
// Project
|
||||
if (! empty($conf->projet->enabled))
|
||||
{
|
||||
print "<tr><td>".$langs->trans("Project")."</td><td>";
|
||||
if ($object->fk_project > 0)
|
||||
{
|
||||
$project = new Project($db);
|
||||
$project->fetch($object->fk_project);
|
||||
print $project->getNomUrl(1);
|
||||
}
|
||||
print "</td></tr>";
|
||||
}
|
||||
|
||||
if (! empty($conf->projet->enabled) && is_object($object->thirdparty) && $object->thirdparty->id > 0)
|
||||
{
|
||||
$projectid = $object->fk_project;
|
||||
$langs->load('projects');
|
||||
print '<tr><td>' . $langs->trans('Project') . '</td><td colspan="2">';
|
||||
$numprojet = $formproject->select_projects($socid, $projectid, 'projectid', 0);
|
||||
print ' <a href="'.DOL_URL_ROOT.'/projet/card.php?socid=' . $soc->id . '&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'">' . $langs->trans("AddProject") . '</a>';
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
// Bank account
|
||||
if ($object->fk_account > 0)
|
||||
{
|
||||
@ -342,7 +674,7 @@ if ($action == 'create')
|
||||
print '<table class="border" width="100%">';
|
||||
|
||||
// Frequency
|
||||
print "<tr><td>".$form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency'))."</td><td>";
|
||||
print '<tr><td class="titlefieldcreate">'.$form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency'))."</td><td>";
|
||||
print "<input type='text' name='frequency' value='".GETPOST('frequency', 'int')."' size='5' /> ".$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 "</td></tr>";
|
||||
|
||||
@ -375,6 +707,7 @@ if ($action == 'create')
|
||||
|
||||
print load_fiche_titre($title, '', '');
|
||||
|
||||
|
||||
/*
|
||||
* Invoice lines
|
||||
*/
|
||||
@ -580,9 +913,16 @@ else
|
||||
{
|
||||
$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);
|
||||
}
|
||||
|
||||
print $formconfirm;
|
||||
|
||||
$author = new User($db);
|
||||
$author->fetch($object->user_author);
|
||||
|
||||
|
||||
$head=array();
|
||||
$h=0;
|
||||
$head[$h][0] = $_SERVER["PHP_SELF"].'?id='.$object->id;
|
||||
@ -851,96 +1191,45 @@ else
|
||||
print '<br>';
|
||||
}
|
||||
|
||||
/*
|
||||
* Lines
|
||||
*/
|
||||
|
||||
print '<table class="noborder noshadow" width="100%">';
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>'.$langs->trans("Description").'</td>';
|
||||
print '<td align="right">'.$langs->trans("VAT").'</td>';
|
||||
print '<td align="right">'.$langs->trans("PriceUHT").'</td>';
|
||||
print '<td align="center">'.$langs->trans("Qty").'</td>';
|
||||
print '<td align="center">'.$langs->trans("ReductionShort").'</td>';
|
||||
if ($conf->global->PRODUCT_USE_UNITS) {
|
||||
print '<td align="left">'.$langs->trans("Unit").'</td>';
|
||||
// Lines
|
||||
print ' <form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#add' : '#line_' . GETPOST('lineid')) . '" method="POST">
|
||||
<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
|
||||
<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateligne') . '">
|
||||
<input type="hidden" name="mode" value="">
|
||||
<input type="hidden" name="id" value="' . $object->id . '">
|
||||
';
|
||||
|
||||
if (! empty($conf->use_javascript_ajax) && $object->statut == 0) {
|
||||
include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
|
||||
}
|
||||
print '</tr>';
|
||||
|
||||
$num = count($object->lines);
|
||||
$i = 0;
|
||||
$var=true;
|
||||
while ($i < $num)
|
||||
|
||||
print '<table id="tablelines" class="noborder noshadow" width="100%">';
|
||||
// Show object lines
|
||||
if (! empty($object->lines))
|
||||
{
|
||||
$var=!$var;
|
||||
|
||||
$product_static=new Product($db);
|
||||
|
||||
// Show product and description
|
||||
$type=(isset($object->lines[$i]->product_type)?$object->lines[$i]->product_type:$object->lines[$i]->fk_product_type);
|
||||
// Try to enhance type detection using date_start and date_end for free lines when type
|
||||
// was not saved.
|
||||
if (! empty($objp->date_start)) $type=1;
|
||||
if (! empty($objp->date_end)) $type=1;
|
||||
|
||||
// Show line
|
||||
print "<tr ".$bc[$var].">";
|
||||
if ($object->lines[$i]->fk_product > 0)
|
||||
{
|
||||
print '<td>';
|
||||
print '<a name="'.$object->lines[$i]->id.'"></a>'; // ancre pour retourner sur la ligne
|
||||
|
||||
// Show product and description
|
||||
$product_static->type=$object->lines[$i]->fk_product_type;
|
||||
$product_static->id=$object->lines[$i]->fk_product;
|
||||
$product_static->ref=$object->lines[$i]->product_ref;
|
||||
$text=$product_static->getNomUrl(1);
|
||||
$text.= ' - '.(! empty($object->lines[$i]->label)?$object->lines[$i]->label:$object->lines[$i]->product_label);
|
||||
$description=(! empty($conf->global->PRODUIT_DESC_IN_FORM)?'':dol_htmlentitiesbr($object->lines[$i]->desc));
|
||||
print $form->textwithtooltip($text,$description,3,'','',$i);
|
||||
|
||||
// Show range
|
||||
print_date_range($object->lines[$i]->date_start, $object->lines[$i]->date_end);
|
||||
|
||||
// Add description in form
|
||||
if (! empty($conf->global->PRODUIT_DESC_IN_FORM))
|
||||
print (! empty($object->lines[$i]->desc) && $object->lines[$i]->desc!=$fac->lines[$i]->product_label)?'<br>'.dol_htmlentitiesbr($object->lines[$i]->desc):'';
|
||||
|
||||
print '</td>';
|
||||
}
|
||||
else
|
||||
{
|
||||
print '<td>';
|
||||
|
||||
if ($type==1) $text = img_object($langs->trans('Service'),'service');
|
||||
else $text = img_object($langs->trans('Product'),'product');
|
||||
|
||||
if (! empty($object->lines[$i]->label)) {
|
||||
|
||||
$text.= ' <strong>'.$object->lines[$i]->label.'</strong>';
|
||||
print $form->textwithtooltip($text,dol_htmlentitiesbr($object->lines[$i]->desc),3,'','',$i);
|
||||
|
||||
} else {
|
||||
|
||||
print $text.' '.nl2br($object->lines[$i]->desc);
|
||||
}
|
||||
|
||||
// Show range
|
||||
print_date_range($object->lines[$i]->date_start, $object->lines[$i]->date_end);
|
||||
|
||||
print '</td>';
|
||||
}
|
||||
print '<td align="right">'.vatrate($object->lines[$i]->tva_tx, 1).'</td>';
|
||||
print '<td align="right">'.price($object->lines[$i]->price).'</td>';
|
||||
print '<td align="center">'.$object->lines[$i]->qty.'</td>';
|
||||
print '<td align="center">'.$object->lines[$i]->remise_percent.' %</td>';
|
||||
if ($conf->global->PRODUCT_USE_UNITS) {
|
||||
print "<td align=\"left\">".$object->lines[$i]->getLabelOfUnit()."</td>";
|
||||
}
|
||||
print "</tr>\n";
|
||||
$i++;
|
||||
$disableedit=1;
|
||||
$disablemove=1;
|
||||
$ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 0); // No date selector for template invoice
|
||||
}
|
||||
print '</table>';
|
||||
|
||||
// Form to add new line
|
||||
if ($object->statut == 0 && $user->rights->facture->creer && $action != 'valid' && $action != 'editline')
|
||||
{
|
||||
if ($action != 'editline')
|
||||
{
|
||||
$var = true;
|
||||
|
||||
// Add free products/services
|
||||
$object->formAddObjectLine(0, $mysoc, $soc); // No date selector for template invoice
|
||||
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
||||
}
|
||||
}
|
||||
|
||||
print "</table>\n";
|
||||
|
||||
print "</form>\n";
|
||||
|
||||
dol_fiche_end();
|
||||
|
||||
@ -1089,7 +1378,7 @@ else
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
else print '<tr '.$bc[false].'><td colspan="6">'.$langs->trans("NoneF").'</td></tr>';
|
||||
else print '<tr '.$bc[false].'><td colspan="9">'.$langs->trans("NoneF").'</td></tr>';
|
||||
|
||||
print "</table>";
|
||||
$db->free($resql);
|
||||
|
||||
@ -3236,7 +3236,7 @@ abstract class CommonObject
|
||||
*/
|
||||
function printObjectLines($action, $seller, $buyer, $selected=0, $dateSelector=0)
|
||||
{
|
||||
global $conf, $hookmanager, $inputalsopricewithtax, $usemargins, $langs, $user;
|
||||
global $conf, $hookmanager, $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $langs, $user;
|
||||
|
||||
// Define usemargins
|
||||
$usemargins=0;
|
||||
@ -3365,7 +3365,8 @@ abstract class CommonObject
|
||||
function printObjectLine($action,$line,$var,$num,$i,$dateSelector,$seller,$buyer,$selected=0,$extrafieldsline=0)
|
||||
{
|
||||
global $conf,$langs,$user,$object,$hookmanager;
|
||||
global $form,$bc,$bcdd, $object_rights;
|
||||
global $form,$bc,$bcdd;
|
||||
global $object_rights, $disableedit, $disablemove; // TODO We should not use global var for this !
|
||||
|
||||
$object_rights = $this->getRights();
|
||||
|
||||
@ -4458,7 +4459,10 @@ abstract class CommonObject
|
||||
{
|
||||
global $user;
|
||||
|
||||
return $user->rights->{$this->element};
|
||||
$element = $this->element;
|
||||
if ($element == 'facturerec') $element='facture';
|
||||
|
||||
return $user->rights->{$element};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -46,7 +46,7 @@ if (empty($inputalsopricewithtax)) $inputalsopricewithtax=0;
|
||||
|
||||
// Define colspan for button Add
|
||||
$colspan = 3; // Col total ht + col edit + col delete
|
||||
if (in_array($object->element,array('propal', 'supplier_proposal','facture','invoice','commande','order','order_supplier','invoice_supplier'))) $colspan++; // With this, there is a column move button
|
||||
if (in_array($object->element,array('propal', 'supplier_proposal','facture','facturerec','invoice','commande','order','order_supplier','invoice_supplier'))) $colspan++; // With this, there is a column move button
|
||||
//print $object->element;
|
||||
?>
|
||||
|
||||
@ -360,6 +360,7 @@ if ((! empty($conf->service->enabled) || ($object->element == 'contrat')) && $da
|
||||
'propal',
|
||||
'supplier_proposal',
|
||||
'facture',
|
||||
'facturerec',
|
||||
'invoice',
|
||||
'commande',
|
||||
'order',
|
||||
|
||||
@ -30,7 +30,9 @@
|
||||
* $senderissupplier (0 by default, 1 for supplier invoices/orders)
|
||||
* $inputalsopricewithtax (0 by default, 1 to also show column with unit price including tax)
|
||||
* $usemargins (0 to disable all margins columns, 1 to show according to margin setup)
|
||||
*
|
||||
* $object_rights->creer initialized from = $object->getRights()
|
||||
* $disableedit, $disablemove
|
||||
*
|
||||
* $type, $text, $description, $line
|
||||
*/
|
||||
|
||||
@ -201,9 +203,10 @@ if (empty($usemargins)) $usemargins=0;
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($this->statut == 0 && ($object_rights->creer)) { ?>
|
||||
<?php
|
||||
if ($this->statut == 0 && ($object_rights->creer)) { ?>
|
||||
<td class="linecoledit" align="center"><?php $coldisplay++; ?>
|
||||
<?php if (($line->info_bits & 2) == 2) { ?>
|
||||
<?php if (($line->info_bits & 2) == 2 || ! empty($disableedit)) { ?>
|
||||
<?php } else { ?>
|
||||
<a href="<?php echo $_SERVER["PHP_SELF"].'?id='.$this->id.'&action=editline&lineid='.$line->id.'#line_'.$line->id; ?>">
|
||||
<?php echo img_edit(); ?>
|
||||
@ -221,7 +224,8 @@ if (empty($usemargins)) $usemargins=0;
|
||||
?>
|
||||
</td>
|
||||
|
||||
<?php if ($num > 1 && empty($conf->browser->phone) && ($this->situation_counter == 1 || !$this->situation_cycle_ref)) { ?>
|
||||
<?php
|
||||
if ($num > 1 && empty($conf->browser->phone) && ($this->situation_counter == 1 || !$this->situation_cycle_ref) && empty($disablemove)) { ?>
|
||||
<td align="center" class="linecolmove tdlineupdown"><?php $coldisplay++; ?>
|
||||
<?php if ($i > 0) { ?>
|
||||
<a class="lineupdown" href="<?php echo $_SERVER["PHP_SELF"].'?id='.$this->id.'&action=up&rowid='.$line->id; ?>">
|
||||
@ -235,7 +239,7 @@ if (empty($usemargins)) $usemargins=0;
|
||||
<?php } ?>
|
||||
</td>
|
||||
<?php } else { ?>
|
||||
<td align="center"<?php echo (empty($conf->browser->phone)?' class="linecolmove tdlineupdown"':' class="linecolmove"'); ?>><?php $coldisplay++; ?></td>
|
||||
<td align="center"<?php echo ((empty($conf->browser->phone) && empty($disablemove)) ?' class="linecolmove tdlineupdown"':' class="linecolmove"'); ?>><?php $coldisplay++; ?></td>
|
||||
<?php } ?>
|
||||
<?php } else { ?>
|
||||
<td colspan="3"><?php $coldisplay=$coldisplay+3; ?></td>
|
||||
|
||||
@ -433,6 +433,7 @@ ListOfYourUnpaidInvoices=List of unpaid invoices
|
||||
NoteListOfYourUnpaidInvoices=Note: This list contains only invoices for third parties you are linked to as a sale representative.
|
||||
RevenueStamp=Revenue stamp
|
||||
YouMustCreateInvoiceFromThird=This option is only available when creating invoice from tab "customer" of thirdparty
|
||||
YouMustCreateStandardInvoiceFirstDesc=You have to create a standard invoice first and convert it to "template" to create a new template invoice
|
||||
PDFCrabeDescription=Invoice PDF template Crabe. A complete invoice template (recommended Template)
|
||||
PDFCrevetteDescription=Invoice PDF template Crevette. A complete invoice template for invoice situation
|
||||
TerreNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0
|
||||
|
||||