diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 31a8520505d..e71299b65e3 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -48,6 +48,8 @@ $cancel = GETPOST('cancel', 'aZ09'); $contextpage= GETPOST('contextpage', 'aZ')?GETPOST('contextpage', 'aZ'):'myobjectcard'; // To manage different context of search $backtopage = GETPOST('backtopage', 'alpha'); +$operationid = GETPOST('operationid', 'int'); + // Initialize technical objects $object = new EmailCollector($db); $extrafields = new ExtraFields($db); @@ -64,6 +66,7 @@ foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha')) $search[$key]=GETPOST('search_'.$key, 'alpha'); } +if (GETPOST('saveoperation2')) $action = 'updateoperation'; if (empty($action) && empty($id) && empty($ref)) $action='view'; // Load object @@ -165,6 +168,24 @@ if (GETPOST('addoperation', 'alpha')) } } +if ($action == 'updateoperation') +{ + $emailcollectoroperation = new EmailCollectorAction($db); + $emailcollectoroperation->fetch(GETPOST('rowidoperation2', 'int')); + + $emailcollectoroperation->actionparam = GETPOST('operationparam2', 'none'); + + $result = $emailcollectoroperation->update($user); + + if ($result > 0) + { + $object->fetchActions(); + } + else + { + setEventMessages($emailcollectoroperation->errors, $emailcollectoroperation->error, 'errors'); + } +} if ($action == 'deleteoperation') { $emailcollectoroperation = new EmailCollectorAction($db); @@ -564,7 +585,18 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print $form->textwithpicto('', $langs->transnoentitiesnoconv('IfTrackingIDFoundEventWillBeLinked')); } print ''; - print ''.$ruleaction['actionparam'].''; + print ''; + if ($action == 'editoperation' && $ruleaction['id'] == $operationid) + { + print '
'; + print '
'; + print ' '; + } + else + { + print $ruleaction['actionparam']; + } + print ''; // Move up/down print ''; if ($i > 0) @@ -577,6 +609,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; // Delete print ''; + print ' '.img_edit().''; + print '   '; print ' '.img_delete().''; print ''; print ''; diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 61608b29f09..bd3a3aeb360 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -903,7 +903,7 @@ if ($action == 'create') $numproject=$formproject->select_projects((! empty($societe->id)?$societe->id:-1), $projectid, 'projectid', 0, 0, 1, 1); - print '   '.$langs->trans("AddProject").''; + print '   '.$langs->trans("AddProject").''; $urloption='?action=create'; $url = dol_buildpath('comm/action/card.php', 2).$urloption; @@ -1301,7 +1301,7 @@ if ($id > 0) $numprojet=$formproject->select_projects(($object->socid > 0 ? $object->socid : -1), $object->fk_project, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0); if ($numprojet==0) { - print '   '.$langs->trans("AddProject").''; + print '   '.$langs->trans("AddProject").''; } print ''; } diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 5e3873a83bc..cf27f54a82b 100755 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -4457,7 +4457,9 @@ elseif ($id > 0 || ! empty($ref)) // Show global modifiers if (! empty($conf->global->INVOICE_USE_SITUATION)) { - if ($object->situation_cycle_ref && $object->statut == 0) { + if ($object->situation_cycle_ref && $object->statut == 0) + { + print ''."\n"; print '
'; print '
'; @@ -4473,38 +4475,19 @@ elseif ($id > 0 || ! empty($ref)) if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { print ' '; } - print '' . $langs->trans('ModifyAllLines') . ''; - print ' '; - print ' '; - if ($inputalsopricewithtax) print ' '; - print ' '; - print ' '; - print '' . $langs->trans('Progress') . ''; - if (! empty($conf->margin->enabled) && empty($user->societe_id)) - { - print ' '; - if ((! empty($conf->global->DISPLAY_MARGIN_RATES) || ! empty($conf->global->DISPLAY_MARK_RATES)) && $usercanreadallmargin) { - print ' '; - } - } - print ' '; + print '' . $langs->trans('ModifyAllLines') . ''; + print '' . $langs->trans('Progress') . ''; print ' '; - print ' '; - print ' '; print "\n"; + print ''; // Adds a line numbering column if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { - print ' '; + print ' '; } - print ''; print ' '; - print ' '; - print ' '; - print ' '; - print ' '; print '%'; - print ''; + print ''; print ''; print ''; diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 55dda5a5934..973dae1bbee 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -345,6 +345,7 @@ if (! $error && $massaction == 'confirm_presend') if ($objectclass == 'Supplier_Proposal') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO)); if ($objectclass == 'CommandeFournisseur') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO)); if ($objectclass == 'FactureFournisseur') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO)); + if ($objectclass == 'Project') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO)); // $listofqualifiedobj is array with key = object id and value is instance of qualified objects, for the current thirdparty (but thirdparty property is not loaded yet) // $looparray will be an array with number of email to send for the current thirdparty (so 1 or n if n object for same thirdparty) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 60bfd1e5305..454936d2998 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3963,8 +3963,10 @@ abstract class CommonObject // Reduction short print ''.$langs->trans('ReductionShort').''; + // Fields for situation invoice if ($this->situation_cycle_ref) { print '' . $langs->trans('Progress') . ''; + print '' . $langs->trans('TotalHT100Short') . ''; } if ($usemargins && ! empty($conf->margin->enabled) && empty($user->societe_id)) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 31eeb08e0a6..22683ab0993 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -1037,9 +1037,12 @@ class FormMail extends Form $showinfobcc=''; if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'propal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO; - if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO; if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO) && ! empty($this->param['models']) && $this->param['models'] == 'order_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO; if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO) && ! empty($this->param['models']) && $this->param['models'] == 'facture_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO; + if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO; + if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO) && ! empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO; + if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO) && ! empty($this->param['models']) && $this->param['models'] == 'invoice_supplier_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO; + if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO) && ! empty($this->param['models']) && $this->param['models'] == 'project') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO; if ($showinfobcc) $out.=' + '.$showinfobcc; $out.= "\n"; return $out; diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index f8cb32896f2..40c5ef8c048 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -466,7 +466,9 @@ class Translate if (! $found && ! empty($conf->global->MAIN_ENABLE_OVERWRITE_TRANSLATION)) { // Overwrite translation with database read - $sql="SELECT transkey, transvalue FROM ".MAIN_DB_PREFIX."overwrite_trans where lang='".$db->escape($this->defaultlang)."'"; + $sql ="SELECT transkey, transvalue FROM ".MAIN_DB_PREFIX."overwrite_trans where lang='".$db->escape($this->defaultlang)."' OR lang IS NULL"; + $sql.=" AND entity IN (0, ".getEntity('overwrite_trans').")"; + $sql.=$db->order("lang", "DESC"); $resql=$db->query($sql); if ($resql) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 134cf7c8e5e..cc40fcb9272 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1954,6 +1954,7 @@ function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0) $total_ht = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht); if ($object->lines[$i]->situation_percent > 0) { + // TODO Remove this. The total should be saved correctly in database instead of being modified here. $prev_progress = 0; $progress = 1; if (method_exists($object->lines[$i], 'get_prev_progress')) @@ -1964,7 +1965,9 @@ function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0) $result.=price($sign * ($total_ht/($object->lines[$i]->situation_percent/100)) * $progress, 0, $outputlangs); } else - $result.=price($sign * $total_ht, 0, $outputlangs); + { + $result.=price($sign * $total_ht, 0, $outputlangs); + } } } return $result; diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index 9d3aa99f306..a649d9d225e 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -39,7 +39,7 @@ * @param int $qty Quantity * @param float $pu Unit price (HT or TTC selon price_base_type) * @param float $remise_percent_ligne Discount for line - * @param float $txtva 0=do not apply standard tax, Vat rate=apply + * @param float $txtva 0=do not apply VAT tax, VAT rate=apply (this is VAT rate only without text code, we don't need text code because we alreaydy have all tax info into $localtaxes_array) * @param float $uselocaltax1_rate 0=do not use this localtax, >0=apply and get value from localtaxes_array (or database if empty), -1=autodetect according to seller if we must apply, get value from localtaxes_array (or database if empty). Try to always use -1. * @param float $uselocaltax2_rate 0=do not use this localtax, >0=apply and get value from localtaxes_array (or database if empty), -1=autodetect according to seller if we must apply, get value from localtaxes_array (or database if empty). Try to always use -1. * @param float $remise_percent_global 0 @@ -82,7 +82,7 @@ * 25=multicurrency_total_tax1 for total_ht * 26=multicurrency_total_tax2 for total_ht */ -function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '', $localtaxes_array = '', $progress = 100, $multicurrency_tx = 1, $pu_devise = 0) +function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '', $localtaxes_array='', $progress=100, $multicurrency_tx=1, $pu_devise=0) { global $conf,$mysoc,$db; @@ -131,13 +131,14 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt $localtax2_type = $localtaxes_array[2]; $localtax2_rate = $localtaxes_array[3]; } - else // deprecated method. values and type for localtaxes must be provided by caller and loaded with getLocalTaxesFromRate + else // deprecated method. values and type for localtaxes must be provided by caller and loaded with getLocalTaxesFromRate using the full vat rate (including text code) { - $sql = "SELECT taux, localtax1, localtax2, localtax1_type, localtax2_type"; + dol_syslog("Price.lib::calcul_price_total search vat information using old deprecated method", LOG_WARNING); + + $sql = "SELECT taux, localtax1, localtax2, localtax1_type, localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as cv"; $sql.= " WHERE cv.taux = ".$txtva; $sql.= " AND cv.fk_pays = ".$countryid; - dol_syslog("Price.lib::calcul_price_total search vat information using old deprecated method", LOG_WARNING); $resql = $db->query($sql); if ($resql) { @@ -187,9 +188,9 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt //If input unit price is 'HT', we need to have the totals with main VAT for a correct calculation if ($price_base_type != 'TTC') { - $tot_sans_remise_wt = price2num($tot_sans_remise * (1 + ($txtva / 100)), 'MU'); - $tot_avec_remise_wt = price2num($tot_avec_remise * (1 + ($txtva / 100)), 'MU'); - $pu_wt = price2num($pu * (1 + ($txtva / 100)), 'MU'); + $tot_sans_remise_wt = price2num($tot_sans_remise * (1 + ($txtva / 100)),'MU'); + $tot_avec_remise_wt = price2num($tot_avec_remise * (1 + ($txtva / 100)),'MU'); + $pu_wt = price2num($pu * (1 + ($txtva / 100)),'MU'); } else { @@ -291,9 +292,9 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt //If input unit price is 'TTC', we need to have the totals without main VAT for a correct calculation if ($price_base_type == 'TTC') { - $tot_sans_remise= price2num($tot_sans_remise / (1 + ($txtva / 100)), 'MU'); - $tot_avec_remise= price2num($tot_avec_remise / (1 + ($txtva / 100)), 'MU'); - $pu = price2num($pu / (1 + ($txtva / 100)), 'MU'); + $tot_sans_remise= price2num($tot_sans_remise / (1 + ($txtva / 100)),'MU'); + $tot_avec_remise= price2num($tot_avec_remise / (1 + ($txtva / 100)),'MU'); + $pu = price2num($pu / (1 + ($txtva / 100)),'MU'); } $apply_tax = false; @@ -410,3 +411,4 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt return $result; } + diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index f9cb16fc9c0..3358728d095 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -201,6 +201,11 @@ class modProduct extends DolibarrModules if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'categorie as cat ON cp.fk_categorie = cat.rowid'; @@ -218,7 +223,7 @@ class modProduct extends DolibarrModules $this->export_label[$r]="ProductsMultiPrice"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("produit","export")); $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref", - 'pr.price_base_type'=>"PriceLevelPriceBase",'pr.price_level'=>"PriceLevel", + 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel", 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC", 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", 'pr.tva_tx'=>'PriceLevelVATRate', @@ -240,7 +245,39 @@ class modProduct extends DolibarrModules $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity - $this->export_sql_end[$r] .=' WHERE p.fk_product_type = 0 AND p.entity IN ('.getEntity('product').')'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile + } + + if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + // Exports product multiprice + $r++; + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]="ProductsPricePerCustomer"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_permission[$r]=array(array("produit","export")); + $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref", + 's.nom'=>'ThirdParty', + 'pr.price_base_type'=>"PriceBase", + 'pr.price'=>"PriceUnitPriceHT",'pr.price_ttc'=>"PriceUnitPriceTTC", + 'pr.price_min'=>"MinPriceUnitPriceHT",'pr.price_min_ttc'=>"MinPriceUnitPriceTTC", + 'pr.tva_tx'=>'PriceVATRate', + 'pr.default_vat_code'=>'PriceVATCode', + 'pr.datec'=>'DateCreation'); + if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly']='NPR'; + $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product", + 's.nom'=>'company', + 'pr.price_base_type'=>"product",'pr.price'=>"product", + 'pr.price_ttc'=>"product", + 'pr.price_min'=>"product",'pr.price_min_ttc'=>"product", + 'pr.tva_tx'=>'product', + 'pr.default_vat_code'=>'product', + 'pr.recuperableonly'=>'product', + 'pr.datec'=>"product"); + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_customer_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON pr.fk_soc = s.rowid'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile } if (! empty($conf->global->PRODUIT_SOUSPRODUITS)) @@ -287,7 +324,7 @@ class modProduct extends DolibarrModules $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object,'; $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'product_association as pa, '.MAIN_DB_PREFIX.'product as p2'; - $this->export_sql_end[$r] .=' WHERE p.fk_product_type = 0 AND p.entity IN ('.getEntity('product').')'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile $this->export_sql_end[$r] .=' AND p.rowid = pa.fk_product_pere AND p2.rowid = pa.fk_product_fils'; } @@ -546,12 +583,15 @@ class modProduct extends DolibarrModules ); $this->import_examplevalues_array[$r]=array( - 'sp.fk_product' => "My Ref. eg: PREF123456", + 'sp.fk_product' => "PRODUCT_REF or id:123456", 'sp.fk_soc' => "My Supplier", 'sp.ref_fourn' => "eg: XYZ-F123456", - 'sp.quantity' => "eg: 5", + 'sp.quantity' => "5", 'sp.tva_tx' => 'one of the defined rates eg. 21', - 'sp.default_vat_code' => '', + 'sp.price'=>"50", + 'sp.unitprice'=>'50', + 'sp.remise_percent'=>'0', + 'sp.default_vat_code' => '', 'sp.delivery_time_days' => 'eg. 5', 'sp.supplier_reputation' => 'FAVORITE / NOTTHGOOD / DONOTORDER' ); @@ -589,16 +629,19 @@ class modProduct extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('pr'=>MAIN_DB_PREFIX.'product_price'); $this->import_tables_creator_array[$r]=array('pr'=>'fk_user_author'); // Fields to store import user id - $this->import_fields_array[$r]=array('pr.fk_product'=>"ProductRowid*", - 'pr.price_base_type'=>"PriceLevelPriceBase",'pr.price_level'=>"PriceLevel", + $this->import_fields_array[$r]=array('pr.fk_product'=>"ProductOrService*", + 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel", 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC", 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", - 'pr.tva_tx'=>'PriceLevelVATRate', 'pr.date_price'=>'DateCreation*'); + if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) $this->import_fields_array[$r]['pr.tva_tx']='VATRate'; if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('pr.recuperableonly'=>'NPR')); $this->import_regex_array[$r]=array('pr.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','pr.recuperableonly'=>'^[0|1]$'); - $this->import_examplevalues_array[$r]=array('pr.fk_product'=>"1", - 'pr.price_base_type'=>"HT",'pr.price_level'=>"1", + $this->import_convertvalue_array[$r]=array( + 'pr.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') + ); + $this->import_examplevalues_array[$r]=array('pr.fk_product'=>"PRODUCT_REF or id:123456", + 'pr.price_base_type'=>"HT (for excl tax) or TTC (for inc tax)",'pr.price_level'=>"1", 'pr.price'=>"100",'pr.price_ttc'=>"110", 'pr.price_min'=>"100",'pr.price_min_ttc'=>"110", 'pr.tva_tx'=>'20', @@ -616,13 +659,13 @@ class modProduct extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('l'=>MAIN_DB_PREFIX.'product_lang'); // multiline translation, one line per translation - $this->import_fields_array[$r]=array('l.fk_product'=>'Ref', 'l.lang'=>'Language', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription'); + $this->import_fields_array[$r]=array('l.fk_product'=>'ProductOrService*', 'l.lang'=>'Language*', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription'); //$this->import_fields_array[$r]['l.note']='TranslatedNote'; $this->import_convertvalue_array[$r]=array( 'l.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') ); - $this->import_examplevalues_array[$r]=array('l.fk_product'=>'MyProductRef','l.lang'=>'en_US','l.label'=>'Label in en_US','l.description'=>'Desc in en_US'); - $this->import_updatekeys_array[$r]=array('l.fk_product'=>'Ref','l.lang'=>'Language'); + $this->import_examplevalues_array[$r]=array('l.fk_product'=>'PRODUCT_REF or id:123456','l.lang'=>'en_US','l.label'=>'Label in en_US','l.description'=>'Desc in en_US'); + $this->import_updatekeys_array[$r]=array('l.fk_product'=>'ProductOrService','l.lang'=>'Language'); } } diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 9fa79683a7f..119339d6022 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -141,30 +141,34 @@ class modService extends DolibarrModules $this->export_code[$r]=$this->rights_class.'_'.$r; $this->export_label[$r]="Services"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("service","export")); - $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell",'p.tobuy'=>"OnBuy",'p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification'); - if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock')); - if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->export_fields_array[$r]['p.fk_unit'] = 'Unit'; + $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell",'p.tobuy'=>"OnBuy",'p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification'); + if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['p.recuperableonly']='NPR'; + if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); + if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.barcode'=>'BarCode')); + if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.cost_price'=>'CostPrice')); $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; - if (! empty($conf->fournisseur->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('s.nom'=>'Supplier','pf.ref_fourn'=>'SupplierRef','pf.quantity'=>'QtyMin','pf.remise_percent'=>'DiscountQtyMin','pf.unitprice'=>'BuyingPrice','pf.delivery_time_days'=>'NbDaysToDelivery')); - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('group_concat(cat.label)'=>'Categories')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel','l.description'=>'TranslatedDescription','l.note'=>'TranslatedNote')); + if (! empty($conf->fournisseur->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('s.nom'=>'Supplier','pf.ref_fourn'=>'SupplierRef','pf.quantity'=>'QtyMin','pf.remise_percent'=>'DiscountQtyMin','pf.unitprice'=>'BuyingPrice','pf.delivery_time_days'=>'NbDaysToDelivery')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('group_concat(cat.label)'=>'Categories')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel','l.description'=>'TranslatedDescription','l.note'=>'TranslatedNote')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->export_fields_array[$r]['p.fk_unit'] = 'Unit'; - $this->export_TypeFields_array[$r]=array( - 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text",'p.note'=>"Text",'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date' - ); - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array("group_concat(cat.label)"=>'category')); - if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric','p.seuil_stock_alerte'=>'Numeric','p.desiredstock'=>'Numeric','p.pmp'=>'Numeric','p.cost_price'=>'Numeric')); - if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text')); - if (! empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('s.nom'=>'Text','pf.ref_fourn'=>'Text','pf.unitprice'=>'Numeric','pf.quantity'=>'Numeric','pf.remise_percent'=>'Numeric','pf.delivery_time_days'=>'Numeric')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('l.lang'=>'Text', 'l.label'=>'Text','l.description'=>'Text','l.note'=>'Text')); - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array("group_concat(cat.label)"=>'Text')); - $this->export_entities_array[$r]=array('p.rowid'=>"service",'p.ref'=>"service",'p.label'=>"service",'p.description'=>"service",'p.accountancy_code_sell'=>'service','p.note'=>"service",'p.price_base_type'=>"service",'p.price'=>"service",'p.price_ttc'=>"service",'p.tva_tx'=>"service",'p.tosell'=>"service",'p.tobuy'=>"service",'p.duration'=>"service",'p.datec'=>"service",'p.tms'=>"service"); - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array("group_concat(cat.label)"=>'category')); - if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'service')); - if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'service')); - if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + $this->export_TypeFields_array[$r]=array('p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text",'p.note'=>"Text",'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date'); + if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.stock'=>'Numeric')); + if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.barcode'=>'Text')); + if (! empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('s.nom'=>'Text','pf.ref_fourn'=>'Text','pf.unitprice'=>'Numeric','pf.quantity'=>'Numeric','pf.remise_percent'=>'Numeric','pf.delivery_time_days'=>'Numeric')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('l.lang'=>'Text', 'l.label'=>'Text','l.description'=>'Text','l.note'=>'Text')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array("group_concat(cat.label)"=>'Text')); + $this->export_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array("group_concat(cat.label)"=>'category')); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; @@ -185,7 +189,7 @@ class modService extends DolibarrModules $this->export_label[$r]="ProductsMultiPrice"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("produit","export")); $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref", - 'pr.price_base_type'=>"PriceLevelPriceBase",'pr.price_level'=>"PriceLevel", + 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel", 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC", 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", 'pr.tva_tx'=>'PriceLevelVATRate', @@ -207,9 +211,89 @@ class modService extends DolibarrModules $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity - $this->export_sql_end[$r] .=' WHERE p.fk_product_type = 0 AND p.entity IN ('.getEntity('product').')'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; } - + + if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + // Exports product multiprice + $r++; + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]="ProductsPricePerCustomer"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_permission[$r]=array(array("produit","export")); + $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref", + 's.nom'=>'ThirdParty', + 'pr.price_base_type'=>"PriceBase", + 'pr.price'=>"PriceUnitPriceHT",'pr.price_ttc'=>"PriceUnitPriceTTC", + 'pr.price_min'=>"MinPriceUnitPriceHT",'pr.price_min_ttc'=>"MinPriceUnitPriceTTC", + 'pr.tva_tx'=>'PriceVATRate', + 'pr.default_vat_code'=>'PriceVATCode', + 'pr.datec'=>'DateCreation'); + if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly']='NPR'; + $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product", + 's.nom'=>'company', + 'pr.price_base_type'=>"product",'pr.price'=>"product", + 'pr.price_ttc'=>"product", + 'pr.price_min'=>"product",'pr.price_min_ttc'=>"product", + 'pr.tva_tx'=>'product', + 'pr.default_vat_code'=>'product', + 'pr.recuperableonly'=>'product', + 'pr.datec'=>"product"); + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_customer_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON pr.fk_soc = s.rowid'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; + } + + if (! empty($conf->global->PRODUIT_SOUSPRODUITS)) + { + // Exports virtual products + $r++; + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]="AssociatedProducts"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_permission[$r]=array(array("produit","export")); + $this->export_fields_array[$r]=array( + 'p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl", + 'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note", + 'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.weight'=>"Weight",'p.customcode'=>'CustomCode', + 'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell", + 'p.tobuy'=>"OnBuy",'p.datec'=>'DateCreation','p.tms'=>'DateModification' + ); + if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); + if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.barcode'=>'BarCode')); + $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('pa.qty'=>'Qty','pa.incdec'=>'ComposedProductIncDecStock')); + $this->export_TypeFields_array[$r]=array( + 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text", + 'p.note'=>"Text",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.weight'=>"Numeric",'p.customcode'=>'Text', + 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean", + 'p.datec'=>'Date','p.tms'=>'Date' + ); + if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.stock'=>'Numeric','p.seuil_stock_alerte'=>'Numeric','p.desiredstock'=>'Numeric','p.pmp'=>'Numeric','p.cost_price'=>'Numeric')); + if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.barcode'=>'Text')); + $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('pa.qty'=>'Numeric')); + $this->export_entities_array[$r]=array( + 'p.rowid'=>"virtualproduct",'p.ref'=>"virtualproduct",'p.label'=>"virtualproduct",'p.description'=>"virtualproduct",'p.url'=>"virtualproduct", + 'p.accountancy_code_sell'=>'virtualproduct','p.accountancy_code_buy'=>'virtualproduct','p.note'=>"virtualproduct",'p.length'=>"virtualproduct", + 'p.surface'=>"virtualproduct",'p.volume'=>"virtualproduct",'p.weight'=>"virtualproduct",'p.customcode'=>'virtualproduct', + 'p.price_base_type'=>"virtualproduct",'p.price'=>"virtualproduct",'p.price_ttc'=>"virtualproduct",'p.tva_tx'=>"virtualproduct", + 'p.tosell'=>"virtualproduct",'p.tobuy'=>"virtualproduct",'p.datec'=>"virtualproduct",'p.tms'=>"virtualproduct" + ); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'virtualproduct','p.seuil_stock_alerte'=>'virtualproduct','p.desiredstock'=>'virtualproduct','p.pmp'=>'virtualproduct')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'virtualproduct')); + $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('pa.qty'=>"subproduct",'pa.incdec'=>'subproduct')); + $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p2.rowid'=>"Id",'p2.ref'=>"Ref",'p2.label'=>"Label",'p2.description'=>"Description")); + $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p2.rowid'=>"subproduct",'p2.ref'=>"subproduct",'p2.label'=>"subproduct",'p2.description'=>"subproduct")); + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object,'; + $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'product_association as pa, '.MAIN_DB_PREFIX.'product as p2'; + $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; + $this->export_sql_end[$r] .=' AND p.rowid = pa.fk_product_pere AND p2.rowid = pa.fk_product_fils'; + } + if (! empty($conf->global->PRODUIT_SOUSPRODUITS)) { // Exports virtual products @@ -259,13 +343,12 @@ class modService extends DolibarrModules } } - // Imports //-------- $r=0; // Import list of services - + $r++; $this->import_code[$r]=$this->rights_class.'_'.$r; $this->import_label[$r]="Products"; // Translation key @@ -277,13 +360,14 @@ class modService extends DolibarrModules 'p.ref'=>"Ref*",'p.label'=>"Label*",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode", 'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume", 'p.weight'=>"Weight",'p.duration'=>"Duration",'p.customcode'=>'CustomCode','p.price'=>"SellingPriceHT",'p.price_ttc'=>"SellingPriceTTC", - 'p.tva_tx'=>'VAT','p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation' + 'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation' ); - if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.cost_price'=>'CostPrice')); - if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.recuperableonly'=>'NPR')); - if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.localtax1_tx'=>'LT1', 'p.localtax1_type'=>'LT1Type')); - if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); - if (! empty($conf->barcode->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.barcode'=>'BarCode')); + //if (! empty($conf->stock->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); + if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.cost_price'=>'CostPrice')); + if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax1_tx'=>'LT1', 'p.localtax1_type'=>'LT1Type')); + if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); + if (! empty($conf->barcode->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.barcode'=>'BarCode')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->import_fields_array[$r]['p.fk_unit'] = 'Unit'; // Add extra fields $import_extrafield_sample=array(); @@ -296,24 +380,24 @@ class modService extends DolibarrModules $fieldname='extra.'.$obj->name; $fieldlabel=ucfirst($obj->label); $this->import_fields_array[$r][$fieldname]=$fieldlabel.($obj->fieldrequired?'*':''); + $import_extrafield_sample[$fieldname]=$fieldlabel; } } // End add extra fields $this->import_fieldshidden_array[$r]=array('extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'product'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent) $this->import_regex_array[$r]=array( - 'p.ref' => '[^ ]', - 'p.price_base_type' => '\AHT\z|\ATTC\z', - 'p.tosell' => '^[0|1]$', - 'p.tobuy' => '^[0|1]$', - 'p.fk_product_type' => '^[0|1]$', - 'p.datec' => '^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', - 'p.recuperableonly' => '^[0|1]$', - 'p.finished' => '^[0|1]$' - ); - $this->import_examplevalues_array[$r]=array('p.ref'=>"PREF123456",'p.label'=>"My product",'p.description'=>"This is a description example for record",'p.note'=>"Some note",'p.price'=>"100",'p.price_ttc'=>"110",'p.tva_tx'=>'10','p.tosell'=>"0 or 1",'p.tobuy'=>"0 or 1",'p.fk_product_type'=>"0 for product/1 for service",'p.finished'=>'','p.duration'=>"1y",'p.datec'=>'2008-12-31'); + 'p.ref'=>'[^ ]', + 'p.tosell'=>'^[0|1]$', + 'p.tobuy'=>'^[0|1]$', + 'p.fk_product_type'=>'^[0|1]$', + 'p.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', + 'p.recuperableonly'=>'^[0|1]$' + ); + $import_sample=array('p.ref'=>"SERVICE_REF or id:123456",'p.label'=>"My product",'p.description'=>"This is a description example for record",'p.note'=>"Some note",'p.price'=>"100",'p.price_ttc'=>"110",'p.tva_tx'=>'10','p.tosell'=>"0 or 1",'p.tobuy'=>"0 or 1",'p.fk_product_type'=>"0 for product/1 for service",'p.finished'=>'','p.duration'=>"1y",'p.datec'=>'2008-12-31','p.recuperableonly'=>'0 or 1'); + $this->import_examplevalues_array[$r]=array_merge($import_sample,$import_extrafield_sample); $this->import_updatekeys_array[$r] = array('p.ref'=>'Ref'); if (! empty($conf->barcode->enabled)) $this->import_updatekeys_array[$r]=array_merge($this->import_updatekeys_array[$r], array('p.barcode'=>'BarCode'));//only show/allow barcode as update key if Barcode module enabled - + if (empty($conf->product->enabled)) // We enable next import templates only if module product not already enabled (to avoid duplicate entries) { if (! empty($conf->fournisseur->enabled)) @@ -355,18 +439,19 @@ class modService extends DolibarrModules 'sp.multicurrency_price'=>'CurrencyPrice', )); } - + $this->import_convertvalue_array[$r]=array( 'sp.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty'), 'sp.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') ); $this->import_examplevalues_array[$r]=array( - 'sp.fk_product'=>"PREF123456", + 'sp.fk_product'=>"SERVICE_REF or id:123456", 'sp.fk_soc'=>"My Supplier",'sp.ref_fourn'=>"SupplierRef", 'sp.quantity'=>"1", 'sp.tva_tx'=>'21', 'sp.price'=>"50", 'sp.unitprice'=>'50', 'sp.remise_percent'=>'0' ); + $this->import_updatekeys_array[$r]=array('sp.fk_product'=>'ProductOrService','sp.ref_fourn'=>'SupplierRef','sp.fk_soc'=>'Supplier'); } if (! empty($conf->global->PRODUIT_MULTIPRICES)) @@ -379,21 +464,24 @@ class modService extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('pr'=>MAIN_DB_PREFIX.'product_price'); $this->import_tables_creator_array[$r]=array('pr'=>'fk_user_author'); // Fields to store import user id - $this->import_fields_array[$r]=array('pr.fk_product'=>"ProductRowid*", - 'pr.price_base_type'=>"PriceLevelPriceBase",'pr.price_level'=>"PriceLevel", + $this->import_fields_array[$r]=array('pr.fk_product'=>"ProductOrService*", + 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel", 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC", 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", - 'pr.tva_tx'=>'PriceLevelVATRate', 'pr.date_price'=>'DateCreation*'); - if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('pr.recuperableonly'=>'NPR')); - $this->import_regex_array[$r]=array('pr.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$'); - $this->import_examplevalues_array[$r]=array('pr.fk_product'=>"1", - 'pr.price_base_type'=>"HT",'pr.price_level'=>"1", + if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) $this->import_fields_array[$r]['pr.tva_tx']='VATRate'; + if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('pr.recuperableonly'=>'NPR')); + $this->import_regex_array[$r]=array('pr.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','pr.recuperableonly'=>'^[0|1]$'); + $this->import_convertvalue_array[$r]=array( + 'pr.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') + ); + $this->import_examplevalues_array[$r]=array('pr.fk_product'=>"SERVICE_REF or id:123456", + 'pr.price_base_type'=>"HT (for excl tax) or TTC (for inc tax)",'pr.price_level'=>"1", 'pr.price'=>"100",'pr.price_ttc'=>"110", 'pr.price_min'=>"100",'pr.price_min_ttc'=>"110", - 'pr.tva_tx'=>'20', + 'pr.tva_tx'=>'20', 'pr.recuperableonly'=>'0', - 'pr.date_price'=>'2013-04-10'); + 'pr.date_price'=>'2013-04-10'); } if (! empty($conf->global->MAIN_MULTILANGS)) @@ -406,13 +494,13 @@ class modService extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('l'=>MAIN_DB_PREFIX.'product_lang'); // multiline translation, one line per translation - $this->import_fields_array[$r]=array('l.fk_product'=>'Ref', 'l.lang'=>'Language', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription'); + $this->import_fields_array[$r]=array('l.fk_product'=>'ProductOrService*', 'l.lang'=>'Language*', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription'); //$this->import_fields_array[$r]['l.note']='TranslatedNote'; $this->import_convertvalue_array[$r]=array( 'l.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') ); - $this->import_examplevalues_array[$r]=array('l.fk_product'=>'MyProductRef','l.lang'=>'en_US','l.label'=>'Label in en_US','l.description'=>'Desc in en_US'); - $this->import_updatekeys_array[$r]=array('l.fk_product'=>'Ref','l.lang'=>'Language'); + $this->import_examplevalues_array[$r]=array('l.fk_product'=>'SERVICE_REF or id:123456','l.lang'=>'en_US','l.label'=>'Label in en_US','l.description'=>'Desc in en_US'); + $this->import_updatekeys_array[$r]=array('l.fk_product'=>'ProductOrService','l.lang'=>'Language'); } } } diff --git a/htdocs/core/modules/modWebsite.class.php b/htdocs/core/modules/modWebsite.class.php index 6f882f082ad..24a929c82a0 100644 --- a/htdocs/core/modules/modWebsite.class.php +++ b/htdocs/core/modules/modWebsite.class.php @@ -92,12 +92,18 @@ class modWebsite extends DolibarrModules $r++; $this->rights[$r][0] = 10002; - $this->rights[$r][1] = 'Create/modify website content'; + $this->rights[$r][1] = 'Create/modify website content (html and javascript content)'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'write'; $r++; $this->rights[$r][0] = 10003; + $this->rights[$r][1] = 'Create/modify website content (dynamic php code). Dangerous, must be reserved to restricted developers.'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'writephp'; + $r++; + + $this->rights[$r][0] = 10005; $this->rights[$r][1] = 'Delete website content'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'delete'; diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 388a9228024..04911584809 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -131,8 +131,10 @@ if ($nolinesbefore) { ?> trans('ReductionShort'); ?> situation_cycle_ref) { print '' . $langs->trans('Progress') . ''; + print ''; } if (! empty($usemargins)) { @@ -161,18 +163,18 @@ if ($nolinesbefore) { ?> global->MAIN_VIEW_LINE_NUMBER)) { - $coldisplay=2; + $coldisplay++; ?> + } + $coldisplay++; + ?> global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT; $toolbarname='dolibarr_details'; if (! empty($conf->global->FCKEDITOR_ENABLE_DETAILS_FULL)) $toolbarname='dolibarr_notes'; - $doleditor=new DolEditor('dp_desc', GETPOST('dp_desc'), '', 100, $toolbarname, '', false, true, $enabled, $nbrows, '98%'); + $doleditor=new DolEditor('dp_desc', GETPOST('dp_desc', 'none'), '', (empty($conf->global->MAIN_DOLEDITOR_HEIGHT)?100:$conf->global->MAIN_DOLEDITOR_HEIGHT), $toolbarname, '', false, true, $enabled, $nbrows, '98%'); $doleditor->Create(); // Show autofill date for recurring invoices @@ -353,52 +355,71 @@ else { if ($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier') // We must have same test in printObjectLines { ?> + $coldisplay++; "> tva_assuj == "0") echo ''.vatrate(0, true); else echo $form->load_tva('tva_tx', (isset($_POST["tva_tx"])?GETPOST("tva_tx", 'alpha', 2):-1), $seller, $buyer, 0, 0, '', false, 1); ?> - + + "> - multicurrency->enabled) && $this->multicurrency_code != $conf->currency) { ?> + multicurrency->enabled) && $this->multicurrency_code != $conf->currency) { + $coldisplay++; + ?> "> - + "> - + "> global->PRODUCT_USE_UNITS) { + $coldisplay++; print ''; print $form->selectUnits($line->fk_unit, "units"); print ''; } $remise_percent = $buyer->remise_percent; - if($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier') { + if($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier') + { $remise_percent = $seller->remise_supplier_percent; } + + $coldisplay++; ?> ">% situation_cycle_ref) { $coldisplay++; print '%'; + $coldisplay++; + print ''; } + if (! empty($usemargins)) { if (!empty($user->rights->margins->creer)) { + $coldisplay++; ?> @@ -409,7 +430,6 @@ else { "> rights->margins->creer) @@ -425,12 +445,9 @@ else { $coldisplay++; } } - else - { - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) $coldisplay++; - if (! empty($conf->global->DISPLAY_MARK_RATES)) $coldisplay++; - } } + + $coldisplay+=$colspan; ?> @@ -439,62 +456,18 @@ else { showOptionals($extrafieldsline, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay+8), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD)?0:1); + print $objectline->showOptionals($extrafieldsline, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD)?0:1); } ?> service->enabled) || ($object->element == 'contrat')) && $dateSelector && GETPOST('type') != '0') // We show date field if required { - $colspan = 6; - - if ($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier') // We must have same test in printObjectLines - { - $colspan++; - } - if ($this->situation_cycle_ref) { - $colspan++; - } - // We add 1 if col total ttc - if (!empty($inputalsopricewithtax)) { - $colspan++; - } - if ($conf->global->PRODUCT_USE_UNITS) { - $colspan++; - } - if (count($object->lines)) { - //There will be an edit and a delete button - $colspan += 2; - - // With this, there is a column move button ONLY if lines > 1 - if (in_array($object->element, array( - 'propal', - 'supplier_proposal', - 'facture', - 'facturerec', - 'invoice', - 'commande', - 'order', - 'order_supplier', - 'invoice_supplier' - ))) { - $colspan++; - } - } - - if (!empty($conf->multicurrency->enabled) && $this->multicurrency_code != $conf->currency) $colspan+=2; - - if (! empty($usemargins)) - { - if (!empty($user->rights->margins->creer)) $colspan++; // For the buying price - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) $colspan++; - if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; - } ?> > global->MAIN_VIEW_LINE_NUMBER)) { print ''; } ?> - + multicurrency->enabled) && $this->multicurrency_code != $conf- global->MAIN_VIEW_LINE_NUMBER)) { ?> - +
@@ -113,7 +116,8 @@ $coldisplay=-1; // We remove first td $enable=(isset($conf->global->FCKEDITOR_ENABLE_DETAILS)?$conf->global->FCKEDITOR_ENABLE_DETAILS:0); $toolbarname='dolibarr_details'; if (! empty($conf->global->FCKEDITOR_ENABLE_DETAILS_FULL)) $toolbarname='dolibarr_notes'; - $doleditor=new DolEditor('product_desc', $line->description, '', 164, $toolbarname, '', false, true, $enable, $nbrows, '98%'); + $doleditor=new DolEditor('product_desc', $line->description, '', (empty($conf->global->MAIN_DOLEDITOR_HEIGHT)?164:$conf->global->MAIN_DOLEDITOR_HEIGHT), $toolbarname, '', false, true, $enable, $nbrows, '98%'); + $doleditor=new DolEditor('product_desc', $line->description, '', (empty($conf->global->MAIN_DOLEDITOR_HEIGHT)?164:$conf->global->MAIN_DOLEDITOR_HEIGHT), $toolbarname, '', false, true, $enable, $nbrows, '98%'); $doleditor->Create(); } else { print ''; @@ -136,6 +140,7 @@ $coldisplay=-1; // We remove first td element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier') // We must have same test in printObjectLines { + $coldisplay++; ?> '; if (!empty($conf->multicurrency->enabled) && $this->multicurrency_code != $conf->currency) { + $coldisplay++; print ''; } @@ -182,6 +188,7 @@ $coldisplay=-1; // We remove first td global->PRODUCT_USE_UNITS) { + $coldisplay++; print ''; print $form->selectUnits($line->fk_unit, "units"); print ''; @@ -200,16 +207,17 @@ $coldisplay=-1; // We remove first td situation_cycle_ref) { $coldisplay++; - print '%'; + print '%'; + $coldisplay++; + print ''; } if (! empty($usemargins)) { - if (!empty($user->rights->margins->creer)) { -?> - -rights->margins->creer)) + { $coldisplay++; -?> + ?> + product->enabled) || ! empty($conf->service->enabled)) { ?> @@ -217,8 +225,8 @@ $coldisplay=-1; // We remove first td - -rights->margins->creer) { if (! empty($conf->global->DISPLAY_MARGIN_RATES)) { @@ -245,7 +253,7 @@ $coldisplay=-1; // We remove first td ?> - + ">
"> @@ -262,9 +270,9 @@ if (!empty($extrafieldsline)) service->enabled) && $line->product_type == 1 && $dateSelector) { ?> global->MAIN_VIEW_LINE_NUMBER)) { ?> - + - trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; ?> + trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; ?> global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE:''); print $form->selectDate($line->date_start, 'date_start', $hourmin, $hourmin, $line->date_start?0:1, "updateline", 1, 0); diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index a3bf7d587af..09bedf2ec53 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -237,14 +237,22 @@ $domData .= ' data-product_type="'.$line->product_type.'"';   situation_cycle_ref) { + $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT); + + // Fields for situation invoices + if ($this->situation_cycle_ref) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; $coldisplay++; print '' . $line->situation_percent . '%'; + $coldisplay++; + $locataxes_array = getLocalTaxesFromRate($line->tva.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''), 0, ($senderissupplier?$mysoc:$object->thirdparty), ($senderissupplier?$object->thirdparty:$mysoc)); + $tmp = calcul_price_total($line->qty, $line->pu, $line->remise_percent, $line->txtva, -1, -1, 0, 'HT', $line->info_bits, $line->type, ($senderissupplier?$object->thirdparty:$mysoc), $locataxes_array, 100, $object->multicurrency_tx, $line->multicurrency_subprice); + print '' . price($tmp[0]) . ''; } if ($usemargins && ! empty($conf->margin->enabled) && empty($user->societe_id)) { - $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT); ?> rights->margins->creer)) { ?> diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php index 93ae53dc461..e09cf08480b 100644 --- a/htdocs/core/website.inc.php +++ b/htdocs/core/website.inc.php @@ -25,6 +25,8 @@ // Load website class include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; +include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php'; + // Define $website if (! is_object($website)) { @@ -40,11 +42,15 @@ if (! is_object($weblangs)) if (! $pageid && ! empty($websitepagefile)) { $pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile)); + if ($pageid == 'index.php') $pageid = $website->fk_default_home; } +if (! is_object($websitepage)) +{ + $websitepage=new WebsitePage($db); +} + if ($pageid > 0) { - include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php'; - $websitepage=new WebsitePage($db); $websitepage->fetch($pageid); } diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 04f64a78280..710afc05cec 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -804,29 +804,36 @@ class EmailCollector extends CommonObject $this->errors[] = $this->error; } } - elseif (preg_match('/^SET:(.*)$/', $valueforproperty, $reg)) + elseif (preg_match('/^(SET|SETIFEMPTY):(.*)$/', $valueforproperty, $regforregex)) { - $valuetouse = $reg[1]; - $substitutionarray=array(); - $matcharray=array(); - preg_match_all('/__([a-z0-9]+(?:_[a-z0-9]+)?)__/i', $valuetouse, $matcharray); - //var_dump($tmpproperty.' - '.$object->$tmpproperty.' - '.$valuetouse); var_dump($matcharray); - if (is_array($matcharray[1])) // $matcharray[1] is array with list of substitution key found without the __ + $valuecurrent=''; + if (preg_match('/^options_/', $tmpproperty)) $valuecurrent = $object->array_options[preg_replace('/^options_/', '', $tmpproperty)]; + else $valuecurrent = $object->$tmpproperty; + + if ($regforregex[1] == 'SET' || empty($valuecurrent)) { - foreach($matcharray[1] as $keytoreplace) + $valuetouse = $regforregex[2]; + $substitutionarray=array(); + $matcharray=array(); + preg_match_all('/__([a-z0-9]+(?:_[a-z0-9]+)?)__/i', $valuetouse, $matcharray); + //var_dump($tmpproperty.' - '.$object->$tmpproperty.' - '.$valuetouse); var_dump($matcharray); + if (is_array($matcharray[1])) // $matcharray[1] is array with list of substitution key found without the __ { - if ($keytoreplace && isset($object->$keytoreplace)) + foreach($matcharray[1] as $keytoreplace) { - $substitutionarray['__'.$keytoreplace.'__']=$object->$keytoreplace; + if ($keytoreplace && isset($object->$keytoreplace)) + { + $substitutionarray['__'.$keytoreplace.'__']=$object->$keytoreplace; + } } } + //var_dump($substitutionarray); + dol_syslog(var_export($substitutionarray, true)); + //var_dump($substitutionarray); + $valuetouse = make_substitutions($valuetouse, $substitutionarray); + if (preg_match('/^options_/', $tmpproperty)) $object->array_options[preg_replace('/^options_/', '', $tmpproperty)] = $valuetouse; + else $object->$tmpproperty = $valuetouse; } - //var_dump($substitutionarray); - dol_syslog(var_export($substitutionarray, true)); - //var_dump($substitutionarray); - $valuetouse = make_substitutions($valuetouse, $substitutionarray); - if (preg_match('/^options_/', $tmpproperty)) $object->array_options[preg_replace('/^options_/', '', $tmpproperty)] = $valuetouse; - else $object->$tmpproperty = $valuetouse; } else { @@ -1391,11 +1398,11 @@ class EmailCollector extends CommonObject $this->errors[] = $this->error; } } - elseif (preg_match('/^SET:(.*)$/', $valueforproperty, $reg)) + elseif (preg_match('/^(SET|SETIFEMPTY):(.*)$/', $valueforproperty, $reg)) { //if (preg_match('/^options_/', $tmpproperty)) $object->array_options[preg_replace('/^options_/', '', $tmpproperty)] = $reg[1]; //else $object->$tmpproperty = $reg[1]; - $nametouseforthirdparty = $reg[1]; + $nametouseforthirdparty = $reg[2]; } else { @@ -1570,37 +1577,57 @@ class EmailCollector extends CommonObject $projecttocreate->note_private = $descriptionfull; $projecttocreate->entity = $conf->entity; - // Get next project Ref - $defaultref=''; - $modele = empty($conf->global->PROJECT_ADDON)?'mod_project_simple':$conf->global->PROJECT_ADDON; - - // Search template files - $file=''; $classname=''; $filefound=0; $reldir=''; - $dirmodels=array_merge(array('/'), (array) $conf->modules_parts['models']); - foreach($dirmodels as $reldir) - { - $file=dol_buildpath($reldir."core/modules/project/".$modele.'.php', 0); - if (file_exists($file)) - { - $filefound=1; - $classname = $modele; - break; - } - } - - if ($filefound) - { - $result=dol_include_once($reldir."core/modules/project/".$modele.'.php'); - $modProject = new $classname; - - $defaultref = $modProject->getNextValue(($thirdpartystatic->id > 0 ? $thirdpartystatic : null), $projecttocreate); - } - - $projecttocreate->ref = $defaultref; - - // Overwrite values with values extracted from source email + // Overwrite values with values extracted from source email. + // This may overwrite any $projecttocreate->xxx properties. + $savesocid = $projecttocreate->socid; $errorforthisaction = $this->overwritePropertiesOfObject($projecttocreate, $operation['actionparam'], $messagetext, $subject, $header); + // Set project ref if not yet defined + if (empty($projecttocreate->ref)) + { + // Get next project Ref + $defaultref=''; + $modele = empty($conf->global->PROJECT_ADDON)?'mod_project_simple':$conf->global->PROJECT_ADDON; + + // Search template files + $file=''; $classname=''; $filefound=0; $reldir=''; + $dirmodels=array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + $file=dol_buildpath($reldir."core/modules/project/".$modele.'.php', 0); + if (file_exists($file)) + { + $filefound=1; + $classname = $modele; + break; + } + } + + if ($filefound) + { + $result=dol_include_once($reldir."core/modules/project/".$modele.'.php'); + $modProject = new $classname; + + if ($savesocid > 0) + { + if ($savesocid != $projecttocreate->socid) + { + $errorforactions++; + setEventMessages('You loaded a thirdparty (id='.$savesocid.') and you force another thirdparty id (id='.$projecttocreate->socid.') by setting socid in operation with a different value'); + } + } + else { + if ($projecttocreate->socid > 0) + { + $thirdpartystatic->fetch($projecttocreate->socid); + } + } + + $defaultref = $modProject->getNextValue(($thirdpartystatic->id > 0 ? $thirdpartystatic : null), $projecttocreate); + } + $projecttocreate->ref = $defaultref; + } + if ($errorforthisaction) { $errorforactions++; @@ -1610,7 +1637,7 @@ class EmailCollector extends CommonObject if (empty($projecttocreate->ref) || (is_numeric($projecttocreate->ref) && $projecttocreate->ref <= 0)) { $errorforactions++; - $this->error = 'Failed to create project: Can\'t get a valid value for project Ref with numbering template '.$modele; + $this->error = 'Failed to create project: Can\'t get a valid value for the field ref with numbering template = '.$modele.', thirdparty id = '.$thirdpartystatic->id; } else { @@ -1665,37 +1692,57 @@ class EmailCollector extends CommonObject $tickettocreate->entity = $conf->entity; //$tickettocreate->fk_contact = $contactstatic->id; - // Get next project Ref - $defaultref=''; - $modele = empty($conf->global->TICKET_ADDON)?'mod_ticket_simple':$conf->global->TICKET_ADDON; - - // Search template files - $file=''; $classname=''; $filefound=0; $reldir=''; - $dirmodels=array_merge(array('/'), (array) $conf->modules_parts['models']); - foreach($dirmodels as $reldir) - { - $file=dol_buildpath($reldir."core/modules/ticket/".$modele.'.php', 0); - if (file_exists($file)) - { - $filefound=1; - $classname = $modele; - break; - } - } - - if ($filefound) - { - $result=dol_include_once($reldir."core/modules/ticket/".$modele.'.php'); - $modTicket = new $classname; - - $defaultref = $modTicket->getNextValue(($thirdpartystatic->id > 0 ? $thirdpartystatic : null), $tickettocreate); - } - - $tickettocreate->ref = $defaultref; - - // Overwrite values with values extracted from source email + // Overwrite values with values extracted from source email. + // This may overwrite any $projecttocreate->xxx properties. + $savesocid = $tickettocreate->socid; $errorforthisaction = $this->overwritePropertiesOfObject($tickettocreate, $operation['actionparam'], $messagetext, $subject, $header); + // Set ticket ref if not yet defined + if (empty($tickettocreate->ref)) + { + // Get next project Ref + $defaultref=''; + $modele = empty($conf->global->TICKET_ADDON)?'mod_ticket_simple':$conf->global->TICKET_ADDON; + + // Search template files + $file=''; $classname=''; $filefound=0; $reldir=''; + $dirmodels=array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + $file=dol_buildpath($reldir."core/modules/ticket/".$modele.'.php', 0); + if (file_exists($file)) + { + $filefound=1; + $classname = $modele; + break; + } + } + + if ($filefound) + { + $result=dol_include_once($reldir."core/modules/ticket/".$modele.'.php'); + $modProject = new $classname; + + if ($savesocid > 0) + { + if ($savesocid != $tickettocreate->socid) + { + $errorforactions++; + setEventMessages('You loaded a thirdparty (id='.$savesocid.') and you force another thirdparty id (id='.$tickettocreate->socid.') by setting socid in operation with a different value'); + } + } + else { + if ($tickettocreate->socid > 0) + { + $thirdpartystatic->fetch($tickettocreate->socid); + } + } + + $defaultref = $modTicket->getNextValue(($thirdpartystatic->id > 0 ? $thirdpartystatic : null), $projecttocreate); + } + $tickettocreate->ref = $defaultref; + } + if ($errorforthisaction) { $errorforactions++; @@ -1705,7 +1752,7 @@ class EmailCollector extends CommonObject if (is_numeric($tickettocreate->ref) && $tickettocreate->ref <= 0) { $errorforactions++; - $this->error = "Failed to create ticket: Can't get a valid value for ticket Ref. Check the numbering module used to generate the reference in setup of module Ticket."; + $this->error = 'Failed to create ticket: Can\'t get a valid value for the field ref with numbering template = '.$modele.', thirdparty id = '.$thirdpartystatic->id; } else { diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 876265d8dcb..d1c8d444283 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -2843,6 +2843,7 @@ elseif (! empty($object->id)) $modelmail='order_supplier_send'; $defaulttopic='SendOrderRef'; $diroutput = $conf->fournisseur->commande->dir_output; + $autocopy='MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO'; $trackid = 'sor'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 6dc48d88753..5c47aa41f40 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -3228,6 +3228,7 @@ else $modelmail='invoice_supplier_send'; $defaulttopic='SendBillRef'; $diroutput = $conf->fournisseur->facture->dir_output; + $autocopy='MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO'; $trackid = 'sin'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 2c2d90e96d9..6b3a6400bc3 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -584,7 +584,7 @@ IMG; // using windows libreoffice that must be in path // using linux/mac libreoffice that must be in path // Note PHP Config "fastcgi.impersonate=0" must set to 0 - Default is 1 - $command ='soffice -headless -convert-to pdf -outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name); + $command ='soffice --headless --convert-to pdf --outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name); } elseif (preg_match('/unoconv/', $conf->global->MAIN_ODT_AS_PDF)) { @@ -635,6 +635,7 @@ IMG; //$command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name.' '.$dirname; dol_syslog(get_class($this).'::exportAsAttachedPDF $execmethod='.$execmethod.' Run command='.$command,LOG_DEBUG); + $retval=0; $output_arr=array(); if ($execmethod == 1) { exec($command, $output_arr, $retval); @@ -665,6 +666,7 @@ IMG; if ($retval == 0) { dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); + $filename=''; $linenum=0; if (headers_sent($filename, $linenum)) { throw new OdfException("headers already sent ($filename at $linenum)"); } @@ -681,16 +683,17 @@ IMG; } } else { dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); - dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG); + dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr, true), LOG_DEBUG); if ($retval==126) { throw new OdfException('Permission execute convert script : ' . $command); } else { + $errorstring=''; foreach($output_arr as $line) { - $errors.= $line."
"; + $errorstring.= $line."
"; } - throw new OdfException('ODT to PDF convert fail : ' . $errors); + throw new OdfException('ODT to PDF convert fail (option MAIN_ODT_AS_PDF is '.$conf->global->MAIN_ODT_AS_PDF.', command was '.$command.', retval='.$retval.') : ' . $errorstring); } } } diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 3979ee83638..90abbe90fc6 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1853,7 +1853,7 @@ WithoutDolTrackingID=Dolibarr Tracking ID not found FormatZip=Zip MainMenuCode=Menu entry code (mainmenu) ECMAutoTree=Show automatic ECM tree -OperationParamDesc=Define values to use for action, or how to extract values. For example:
objproperty1=SET:abc
objproperty2=EXTRACT:HEADER:X-Myheaderkey.*[^\s]+(.*)
options_myextrafield=EXTRACT:SUBJECT:([^\s]*)
object.objproperty4=EXTRACT:BODY:My company name is\s([^\s]*)

Use a ; char as separator to extract or set several properties. +OperationParamDesc=Define values to use for action, or how to extract values. For example:
objproperty1=SET:abc
objproperty1=SET:a value with replacement of __objproperty1__
objproperty3=SETIFEMPTY:abc
objproperty4=EXTRACT:HEADER:X-Myheaderkey.*[^\s]+(.*)
options_myextrafield=EXTRACT:SUBJECT:([^\s]*)
object.objproperty5=EXTRACT:BODY:My company name is\s([^\s]*)

Use a ; char as separator to extract or set several properties. OpeningHours=Opening hours OpeningHoursDesc=Enter here the regular opening hours of your company. ResourceSetup=Configuration of Resource module diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 7931f6ec3b6..ae189111c15 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -28,7 +28,7 @@ AliasNames=Alias name (commercial, trademark, ...) AliasNameShort=Alias Name Companies=Companies CountryIsInEEC=Country is inside the European Economic Community -PriceFormatInCurrentLanguage=Price format in current language +PriceFormatInCurrentLanguage=Price display format in the current language and currency ThirdPartyName=Third-party name ThirdPartyEmail=Third-party email ThirdParty=Third-party diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index c739f8d5624..3aec931714b 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -371,6 +371,7 @@ Percentage=Percentage Total=Total SubTotal=Subtotal TotalHTShort=Total (excl.) +TotalHT100Short=Total 100%% (excl.) TotalHTShortCurrency=Total (excl. in currency) TotalTTCShort=Total (inc. tax) TotalHT=Total (excl. tax) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index e69d771fa79..be20d1a7504 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -338,4 +338,5 @@ CloneDestinationReference=Destination product reference ErrorCopyProductCombinations=There was an error while copying the product variants ErrorDestinationProductNotFound=Destination product not found ErrorProductCombinationNotFound=Product variant not found -ActionAvailableOnVariantProductOnly=Action only available on the variant of product \ No newline at end of file +ActionAvailableOnVariantProductOnly=Action only available on the variant of product +ProductsPricePerCustomer=Product prices per customers \ No newline at end of file diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index f20aab8c0a7..4655bf3493a 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -97,3 +97,4 @@ ThisPageHasTranslationPages=This page/container has translation NoWebSiteCreateOneFirst=No website has been created yet. Create one first. GoTo=Go to DynamicPHPCodeContainsAForbiddenInstruction=You add dynamic PHP code that contains the PHP instruction '%s' that is forbidden by default as dynamic content (see hidden options WEBSITE_PHP_ALLOW_xxx to increase list of allowed commands). +NotAllowedToAddDynamicContent=You don't have permission to add or edit PHP dynamic content in websites. Ask permission or just keep code into php tags unmodified. \ No newline at end of file diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 6ffd5a088e8..fa3a8c1cd43 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1813,7 +1813,7 @@ function top_menu_user(User $user, Translate $langs)