Merge remote-tracking branch 'origin/3.9' into develop
Conflicts: htdocs/product/class/product.class.php
This commit is contained in:
commit
b4e5acbaa9
@ -61,31 +61,22 @@ $pagenext = $page + 1;
|
|||||||
if (! $sortorder) { $sortorder=($filter=='outofdate'?"DESC":"ASC"); }
|
if (! $sortorder) { $sortorder=($filter=='outofdate'?"DESC":"ASC"); }
|
||||||
if (! $sortfield) { $sortfield=($filter=='outofdate'?"d.datefin":"d.lastname"); }
|
if (! $sortfield) { $sortfield=($filter=='outofdate'?"d.datefin":"d.lastname"); }
|
||||||
|
|
||||||
if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
|
|
||||||
{
|
|
||||||
$search="";
|
|
||||||
$search_ref="";
|
|
||||||
$search_lastname="";
|
|
||||||
$search_firstname="";
|
|
||||||
$search_login="";
|
|
||||||
$type="";
|
|
||||||
$search_email="";
|
|
||||||
$search_categ="";
|
|
||||||
$catid="";
|
|
||||||
$sall="";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
|
// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
|
||||||
$hookmanager->initHooks(array('memberlist'));
|
$hookmanager->initHooks(array('memberlist'));
|
||||||
$extrafields = new ExtraFields($db);
|
$extrafields = new ExtraFields($db);
|
||||||
|
|
||||||
|
// fetch optionals attributes and labels
|
||||||
|
$extralabels = $extrafields->fetch_name_optionals_label('member');
|
||||||
|
$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_');
|
||||||
|
|
||||||
// List of fields to search into when doing a "search in all"
|
// List of fields to search into when doing a "search in all"
|
||||||
$fieldstosearchall = array(
|
$fieldstosearchall = array(
|
||||||
'd.rowid'=>'Ref',
|
'd.rowid'=>'Ref',
|
||||||
//'d.ref'=>'Ref',
|
//'d.ref'=>'Ref',
|
||||||
'd.lastname'=>'Lastname',
|
'd.lastname'=>'Lastname',
|
||||||
'd.firstname'=>'Firstname',
|
'd.firstname'=>'Firstname',
|
||||||
'd.societe'=>"Company",
|
'd.login'=>'Login',
|
||||||
|
'd.societe'=>"Company",
|
||||||
'd.email'=>'EMail',
|
'd.email'=>'EMail',
|
||||||
'd.address'=>'Address',
|
'd.address'=>'Address',
|
||||||
'd.zip'=>'Zip',
|
'd.zip'=>'Zip',
|
||||||
@ -93,6 +84,66 @@ $fieldstosearchall = array(
|
|||||||
'd.note_public'=>'NotePublic',
|
'd.note_public'=>'NotePublic',
|
||||||
'd.note_private'=>'NotePrivate',
|
'd.note_private'=>'NotePrivate',
|
||||||
);
|
);
|
||||||
|
$arrayfields=array(
|
||||||
|
'd.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1),
|
||||||
|
'd.lastname'=>array('label'=>$langs->trans("Lastname"), 'checked'=>1),
|
||||||
|
'd.firstname'=>array('label'=>$langs->trans("Firstname"), 'checked'=>1),
|
||||||
|
'd.societe'=>array('label'=>$langs->trans("Company"), 'checked'=>1),
|
||||||
|
'd.login'=>array('label'=>$langs->trans("Login"), 'checked'=>1),
|
||||||
|
'd.morphy'=>array('label'=>$langs->trans("MorPhy"), 'checked'=>1),
|
||||||
|
't.libelle'=>array('label'=>$langs->trans("Type"), 'checked'=>1),
|
||||||
|
'd.email'=>array('label'=>$langs->trans("Email"), 'checked'=>1),
|
||||||
|
'd.address'=>array('label'=>$langs->trans("Address"), 'checked'=>0),
|
||||||
|
'd.zip'=>array('label'=>$langs->trans("Zip"), 'checked'=>0),
|
||||||
|
'd.town'=>array('label'=>$langs->trans("Town"), 'checked'=>0),
|
||||||
|
'd.note_public'=>array('label'=>$langs->trans("NotePublic"), 'checked'=>0),
|
||||||
|
'd.note_private'=>array('label'=>$langs->trans("NotePrivate"), 'checked'=>0),
|
||||||
|
'd.datefin'=>array('label'=>$langs->trans("EndSubscription"), 'checked'=>1, 'position'=>500),
|
||||||
|
'd.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
|
||||||
|
'd.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
|
||||||
|
'd.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000)
|
||||||
|
);
|
||||||
|
// Extra fields
|
||||||
|
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
|
||||||
|
{
|
||||||
|
foreach($extrafields->attribute_label as $key => $val)
|
||||||
|
{
|
||||||
|
$arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Actions
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (GETPOST('cancel')) { $action='list'; $massaction=''; }
|
||||||
|
if (! GETPOST('confirmmassaction')) { $massaction=''; }
|
||||||
|
|
||||||
|
$parameters=array('socid'=>$socid);
|
||||||
|
$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
|
||||||
|
if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
||||||
|
|
||||||
|
include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
|
||||||
|
|
||||||
|
// Purge search criteria
|
||||||
|
if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers
|
||||||
|
{
|
||||||
|
$search="";
|
||||||
|
$search_ref="";
|
||||||
|
$search_lastname="";
|
||||||
|
$search_firstname="";
|
||||||
|
$search_login="";
|
||||||
|
$search_company="";
|
||||||
|
$type="";
|
||||||
|
$search_email="";
|
||||||
|
$search_address="";
|
||||||
|
$search_zip="";
|
||||||
|
$search_town="";
|
||||||
|
$search_morphy="";
|
||||||
|
$search_categ="";
|
||||||
|
$catid="";
|
||||||
|
$sall="";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -140,10 +191,25 @@ if ($search_login) $sql.= natural_search("d.login", $search_login);
|
|||||||
if ($search_email) $sql.= natural_search("d.email", $search_email);
|
if ($search_email) $sql.= natural_search("d.email", $search_email);
|
||||||
if ($filter == 'uptodate') $sql.=" AND datefin >= '".$db->idate($now)."'";
|
if ($filter == 'uptodate') $sql.=" AND datefin >= '".$db->idate($now)."'";
|
||||||
if ($filter == 'outofdate') $sql.=" AND (datefin IS NULL OR datefin < '".$db->idate($now)."')";
|
if ($filter == 'outofdate') $sql.=" AND (datefin IS NULL OR datefin < '".$db->idate($now)."')";
|
||||||
|
|
||||||
|
// Add where from extra fields
|
||||||
|
foreach ($search_array_options as $key => $val)
|
||||||
|
{
|
||||||
|
$crit=$val;
|
||||||
|
$tmpkey=preg_replace('/search_options_/','',$key);
|
||||||
|
$typ=$extrafields->attribute_type[$tmpkey];
|
||||||
|
$mode=0;
|
||||||
|
if (in_array($typ, array('int','double'))) $mode=1; // Search on a numeric
|
||||||
|
if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit)))
|
||||||
|
{
|
||||||
|
$sql .= natural_search('ef.'.$tmpkey, $crit, $mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Add where from hooks
|
// Add where from hooks
|
||||||
$parameters=array();
|
$parameters=array();
|
||||||
$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook
|
$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook
|
||||||
$sql.=$hookmanager->resPrint;
|
$sql.=$hookmanager->resPrint;
|
||||||
|
|
||||||
$sql.= $db->order($sortfield,$sortorder);
|
$sql.= $db->order($sortfield,$sortorder);
|
||||||
|
|
||||||
// Count total nb of records with no order and no limits
|
// Count total nb of records with no order and no limits
|
||||||
@ -190,11 +256,25 @@ if ($resql)
|
|||||||
if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
|
if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
|
||||||
if ($statut != "") $param.="&statut=".$statut;
|
if ($statut != "") $param.="&statut=".$statut;
|
||||||
if ($search_nom) $param.="&search_nom=".$search_nom;
|
if ($search_nom) $param.="&search_nom=".$search_nom;
|
||||||
if ($search_login) $param.="&search_login=".$search_login;
|
if ($search_firstname) $param.="&search_firstname=".$search_firstname;
|
||||||
if ($search_email) $param.="&search_email=".$search_email;
|
if ($search_lastname) $param.="&search_lastname=".$search_lastname;
|
||||||
if ($filter) $param.="&filter=".$filter;
|
if ($search_login) $param.="&search_login=".$search_login;
|
||||||
if ($type > 0) $param.="&type=".$type;
|
if ($search_email) $param.="&search_email=".$search_email;
|
||||||
if ($optioncss != '') $param.='&optioncss='.$optioncss;
|
if ($search_company) $param.="&search_company=".$search_company;
|
||||||
|
if ($search_zip) $param.="&search_zip=".$search_zip;
|
||||||
|
if ($search_town) $param.="&search_town=".$search_town;
|
||||||
|
if ($filter) $param.="&filter=".$filter;
|
||||||
|
if ($type > 0) $param.="&type=".$type;
|
||||||
|
if ($optioncss != '') $param.='&optioncss='.$optioncss;
|
||||||
|
// Add $param from extra fields
|
||||||
|
foreach ($search_array_options as $key => $val)
|
||||||
|
{
|
||||||
|
$crit=$val;
|
||||||
|
$tmpkey=preg_replace('/search_options_/','',$key);
|
||||||
|
if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val);
|
||||||
|
}
|
||||||
|
|
||||||
|
//$massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge")));
|
||||||
|
|
||||||
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
|
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
|
||||||
if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
|
||||||
@ -222,42 +302,70 @@ if ($resql)
|
|||||||
$moreforfilter.=$formother->select_categories(Categorie::TYPE_MEMBER,$search_categ,'search_categ',1);
|
$moreforfilter.=$formother->select_categories(Categorie::TYPE_MEMBER,$search_categ,'search_categ',1);
|
||||||
$moreforfilter.='</div>';
|
$moreforfilter.='</div>';
|
||||||
}
|
}
|
||||||
|
$parameters=array();
|
||||||
|
$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook
|
||||||
|
if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint;
|
||||||
|
else $moreforfilter = $hookmanager->resPrint;
|
||||||
if (! empty($moreforfilter))
|
if (! empty($moreforfilter))
|
||||||
{
|
{
|
||||||
print '<div class="liste_titre liste_titre_bydiv centpercent">';
|
print '<div class="liste_titre liste_titre_bydiv centpercent">';
|
||||||
print $moreforfilter;
|
print $moreforfilter;
|
||||||
$parameters=array();
|
print '</div>';
|
||||||
$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook
|
|
||||||
print $hookmanager->resPrint;
|
|
||||||
print '</div>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">';
|
$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
|
||||||
|
$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
|
||||||
|
|
||||||
|
print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
|
||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER))
|
if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER))
|
||||||
{
|
{
|
||||||
print '<td width="5" align="center"> </td>';
|
print '<td width="5" align="center"> </td>';
|
||||||
}
|
}
|
||||||
print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"d.rowid",$param,"","",$sortfield,$sortorder);
|
if (! empty($arrayfields['d.ref']['checked'])) print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],'d.rowid','',$param,'',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans("Name")." / ".$langs->trans("Company"),$_SERVER["PHP_SELF"],"d.lastname",$param,"","",$sortfield,$sortorder);
|
if (! empty($arrayfields['d.firstname']['checked'])) print_liste_field_titre($arrayfields['d.firstname']['label'],$_SERVER["PHP_SELF"],'d.firstname','',$param,'',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans("Login"),$_SERVER["PHP_SELF"],"d.login",$param,"","",$sortfield,$sortorder);
|
if (! empty($arrayfields['d.lastname']['checked'])) print_liste_field_titre($arrayfields['d.lastname']['label'],$_SERVER["PHP_SELF"],'d.lastname','',$param,'',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"t.libelle",$param,"","",$sortfield,$sortorder);
|
if (! empty($arrayfields['d.company']['checked'])) print_liste_field_titre($arrayfields['d.company']['label'],$_SERVER["PHP_SELF"],'d.company','',$param,'',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans("Person"),$_SERVER["PHP_SELF"],"d.morphy",$param,"","",$sortfield,$sortorder);
|
if (! empty($arrayfields['d.login']['checked'])) print_liste_field_titre($arrayfields['d.login']['label'],$_SERVER["PHP_SELF"],'d.login','',$param,'',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans("EMail"),$_SERVER["PHP_SELF"],"d.email",$param,"","",$sortfield,$sortorder);
|
if (! empty($arrayfields['d.morphy']['checked'])) print_liste_field_titre($arrayfields['d.morphy']['label'],$_SERVER["PHP_SELF"],'d.morphy','',$param,'',$sortfield,$sortorder);
|
||||||
|
if (! empty($arrayfields['t.libelle']['checked'])) print_liste_field_titre($arrayfields['t.libelle']['label'],$_SERVER["PHP_SELF"],'t.libelle','',$param,'',$sortfield,$sortorder);
|
||||||
$parameters=array();
|
if (! empty($arrayfields['d.address']['checked'])) print_liste_field_titre($arrayfields['d.address']['label'],$_SERVER["PHP_SELF"],'d.address','',$param,'',$sortfield,$sortorder);
|
||||||
|
if (! empty($arrayfields['d.zip']['checked'])) print_liste_field_titre($arrayfields['d.zip']['label'],$_SERVER["PHP_SELF"],'d.zip','',$param,'',$sortfield,$sortorder);
|
||||||
|
if (! empty($arrayfields['d.town']['checked'])) print_liste_field_titre($arrayfields['d.town']['label'],$_SERVER["PHP_SELF"],'d.town','',$param,'',$sortfield,$sortorder);
|
||||||
|
if (! empty($arrayfields['d.email']['checked'])) print_liste_field_titre($arrayfields['d.email']['label'],$_SERVER["PHP_SELF"],'d.email','',$param,'',$sortfield,$sortorder);
|
||||||
|
if (! empty($arrayfields['d.datefin']['checked'])) print_liste_field_titre($arrayfields['d.datefin']['label'],$_SERVER["PHP_SELF"],'d.datefin','',$param,'',$sortfield,$sortorder);
|
||||||
|
// Extra fields
|
||||||
|
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
|
||||||
|
{
|
||||||
|
foreach($extrafields->attribute_label as $key => $val)
|
||||||
|
{
|
||||||
|
if (! empty($arrayfields["ef.".$key]['checked']))
|
||||||
|
{
|
||||||
|
$align=$extrafields->getAlignFlag($key);
|
||||||
|
print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Hook fields
|
||||||
|
$parameters=array('arrayfields'=>$arrayfields);
|
||||||
$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook
|
$reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook
|
||||||
print $hookmanager->resPrint;
|
print $hookmanager->resPrint;
|
||||||
|
if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"d.statut,d.datefin",$param,"","",$sortfield,$sortorder);
|
if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans("EndSubscription"),$_SERVER["PHP_SELF"],"d.datefin",$param,"",'align="center"',$sortfield,$sortorder);
|
if (! empty($arrayfields['d.statut']['checked'])) print_liste_field_titre($arrayfields['d.statut']['label'],$_SERVER["PHP_SELF"],"d.statut","",$param,'align="right"',$sortfield,$sortorder);
|
||||||
print_liste_field_titre($langs->trans(""),$_SERVER["PHP_SELF"],"",$param,"",'width="60" align="center"',$sortfield,$sortorder);
|
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch ');
|
||||||
print "</tr>\n";
|
print "</tr>\n";
|
||||||
|
|
||||||
// Line for filters fields
|
// Line for filters fields
|
||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
|
|
||||||
print '<td class="liste_titre"> </td>';
|
// Ref
|
||||||
|
if (! empty($arrayfields['c.ref']['checked']))
|
||||||
|
{
|
||||||
|
print '<td class="liste_titre">';
|
||||||
|
print '<input class="flat" size="6" type="text" name="search_ref" value="'.$search_ref.'">';
|
||||||
|
print '</td>';
|
||||||
|
}
|
||||||
|
|
||||||
print '<td class="liste_titre" align="left">';
|
print '<td class="liste_titre" align="left">';
|
||||||
print '<input class="flat" type="text" name="search_ref" value="'.$search_ref.'" size="4"></td>';
|
print '<input class="flat" type="text" name="search_ref" value="'.$search_ref.'" size="4"></td>';
|
||||||
|
|||||||
@ -127,7 +127,7 @@ $arrayfields=array(
|
|||||||
'c.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
|
'c.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
|
||||||
'c.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
|
'c.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
|
||||||
'c.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
|
'c.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
|
||||||
'e.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000, 'enabled'=>(empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)))
|
'c.facture'=>array('label'=>$langs->trans("Billed"), 'checked'=>1, 'position'=>1000, 'enabled'=>(empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)))
|
||||||
);
|
);
|
||||||
// Extra fields
|
// Extra fields
|
||||||
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
|
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
|
||||||
|
|||||||
@ -126,6 +126,7 @@ AssociatedProductsAbility=Activate the package feature
|
|||||||
AssociatedProducts=Package product
|
AssociatedProducts=Package product
|
||||||
AssociatedProductsNumber=Number of products composing this package product
|
AssociatedProductsNumber=Number of products composing this package product
|
||||||
ParentProductsNumber=Number of parent packaging product
|
ParentProductsNumber=Number of parent packaging product
|
||||||
|
ParentProducts=Parent products
|
||||||
IfZeroItIsNotAVirtualProduct=If 0, this product is not a package product
|
IfZeroItIsNotAVirtualProduct=If 0, this product is not a package product
|
||||||
IfZeroItIsNotUsedByVirtualProduct=If 0, this product is not used by any package product
|
IfZeroItIsNotUsedByVirtualProduct=If 0, this product is not used by any package product
|
||||||
EditAssociate=Associate
|
EditAssociate=Associate
|
||||||
@ -291,6 +292,7 @@ DefaultPrice=Default price
|
|||||||
ComposedProductIncDecStock=Increase/Decrease stock on parent change
|
ComposedProductIncDecStock=Increase/Decrease stock on parent change
|
||||||
ComposedProduct=Sub-product
|
ComposedProduct=Sub-product
|
||||||
MinSupplierPrice=Minimum supplier price
|
MinSupplierPrice=Minimum supplier price
|
||||||
|
MinCustomerPrice=Minimum customer price
|
||||||
DynamicPriceConfiguration=Dynamic price configuration
|
DynamicPriceConfiguration=Dynamic price configuration
|
||||||
DynamicPriceDesc=On product card, with this module enabled, you should be able to set mathematic functions to calculate Customer or Supplier prices. Such function can use all mathematic operators, some constants and variables. You can set here the variables you want to be able and if the variable need an automatic update, the external URL to use to ask Dolibarr to update automaticaly the value.
|
DynamicPriceDesc=On product card, with this module enabled, you should be able to set mathematic functions to calculate Customer or Supplier prices. Such function can use all mathematic operators, some constants and variables. You can set here the variables you want to be able and if the variable need an automatic update, the external URL to use to ask Dolibarr to update automaticaly the value.
|
||||||
AddVariable=Add Variable
|
AddVariable=Add Variable
|
||||||
|
|||||||
@ -10,9 +10,12 @@ ListOfSuppliers=List of suppliers
|
|||||||
ShowSupplier=Show supplier
|
ShowSupplier=Show supplier
|
||||||
OrderDate=Order date
|
OrderDate=Order date
|
||||||
BuyingPrice=Buying price
|
BuyingPrice=Buying price
|
||||||
BuyingPriceMin=Minimum buying price
|
BuyingPriceMin=Minimum purchase price
|
||||||
BuyingPriceMinShort=Min buying price
|
BuyingPriceMinShort=Min purchase price
|
||||||
|
SellingPriceMinShort=Min sell price
|
||||||
TotalBuyingPriceMin=Total of subproducts buying prices
|
TotalBuyingPriceMin=Total of subproducts buying prices
|
||||||
|
TotalBuyingPriceMinShort=Total of subproducts purchase prices
|
||||||
|
TotalSellingPriceMinShort=Total of subproducts sell prices
|
||||||
SomeSubProductHaveNoPrices=Some sub-products have no price defined
|
SomeSubProductHaveNoPrices=Some sub-products have no price defined
|
||||||
AddSupplierPrice=Add supplier price
|
AddSupplierPrice=Add supplier price
|
||||||
ChangeSupplierPrice=Change supplier price
|
ChangeSupplierPrice=Change supplier price
|
||||||
|
|||||||
@ -2980,9 +2980,10 @@ class Product extends CommonObject
|
|||||||
*
|
*
|
||||||
* @param int $id Id of product to search childs of
|
* @param int $id Id of product to search childs of
|
||||||
* @param int $firstlevelonly Return only direct child
|
* @param int $firstlevelonly Return only direct child
|
||||||
|
* @param int $level Level of recursing call (start to 1)
|
||||||
* @return array Prod
|
* @return array Prod
|
||||||
*/
|
*/
|
||||||
function getChildsArbo($id, $firstlevelonly=0)
|
function getChildsArbo($id, $firstlevelonly=0, $level=1)
|
||||||
{
|
{
|
||||||
$sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type, pa.incdec";
|
$sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type, pa.incdec";
|
||||||
$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
|
$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
|
||||||
@ -2991,13 +2992,18 @@ class Product extends CommonObject
|
|||||||
$sql.= " AND pa.fk_product_pere = ".$id;
|
$sql.= " AND pa.fk_product_pere = ".$id;
|
||||||
$sql.= " AND pa.fk_product_fils != ".$id; // This should not happens, it is to avoid infinite loop if it happens
|
$sql.= " AND pa.fk_product_fils != ".$id; // This should not happens, it is to avoid infinite loop if it happens
|
||||||
|
|
||||||
dol_syslog(get_class($this).'::getChildsArbo', LOG_DEBUG);
|
dol_syslog(get_class($this).'::getChildsArbo id='.$id.' level='.$level, LOG_DEBUG);
|
||||||
|
|
||||||
|
// Protection against infinite loop
|
||||||
|
if ($level > 30) return array();
|
||||||
|
|
||||||
$res = $this->db->query($sql);
|
$res = $this->db->query($sql);
|
||||||
if ($res)
|
if ($res)
|
||||||
{
|
{
|
||||||
$prods = array();
|
$prods = array();
|
||||||
while ($rec = $this->db->fetch_array($res))
|
while ($rec = $this->db->fetch_array($res))
|
||||||
{
|
{
|
||||||
|
// TODO Add check to not add ne record if already added
|
||||||
$prods[$rec['rowid']]= array(
|
$prods[$rec['rowid']]= array(
|
||||||
0=>$rec['id'],
|
0=>$rec['id'],
|
||||||
1=>$rec['qty'],
|
1=>$rec['qty'],
|
||||||
@ -3009,7 +3015,7 @@ class Product extends CommonObject
|
|||||||
//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty']);
|
//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty']);
|
||||||
if (empty($firstlevelonly))
|
if (empty($firstlevelonly))
|
||||||
{
|
{
|
||||||
$listofchilds=$this->getChildsArbo($rec['id']);
|
$listofchilds=$this->getChildsArbo($rec['id'], 0, $level + 1);
|
||||||
foreach($listofchilds as $keyChild => $valueChild)
|
foreach($listofchilds as $keyChild => $valueChild)
|
||||||
{
|
{
|
||||||
$prods[$rec['rowid']]['childs'][$keyChild] = $valueChild;
|
$prods[$rec['rowid']]['childs'][$keyChild] = $valueChild;
|
||||||
@ -3034,10 +3040,12 @@ class Product extends CommonObject
|
|||||||
*/
|
*/
|
||||||
function get_sousproduits_arbo()
|
function get_sousproduits_arbo()
|
||||||
{
|
{
|
||||||
$parent = $this->getParent();
|
//$parent = $this->getParent();
|
||||||
|
$parent[$this->label]=array(0 => $this->id);
|
||||||
|
|
||||||
foreach($parent as $key => $value) // key=label, value[0]=id
|
foreach($parent as $key => $value) // key=label, value[0]=id
|
||||||
{
|
{
|
||||||
foreach($this->getChildsArbo($value[0]) as $keyChild => $valueChild)
|
foreach($this->getChildsArbo($value[0]) as $keyChild => $valueChild) // Warning. getChildsArbo can gell getChildsArbo recursively.
|
||||||
{
|
{
|
||||||
$parent[$key][$keyChild] = $valueChild;
|
$parent[$key][$keyChild] = $valueChild;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -190,25 +190,10 @@ if ($id > 0 || ! empty($ref))
|
|||||||
*/
|
*/
|
||||||
if ($user->rights->produit->lire || $user->rights->service->lire)
|
if ($user->rights->produit->lire || $user->rights->service->lire)
|
||||||
{
|
{
|
||||||
|
dol_banner_tab($object, 'ref', '', ($user->societe_id?0:1), 'ref');
|
||||||
|
|
||||||
print '<table class="border" width="100%">';
|
print '<table class="border" width="100%">';
|
||||||
|
|
||||||
print "<tr>";
|
|
||||||
|
|
||||||
$nblignes=6;
|
|
||||||
if ($object->isProduct() && ! empty($conf->stock->enabled)) $nblignes++;
|
|
||||||
if ($object->isService()) $nblignes++;
|
|
||||||
|
|
||||||
// Reference
|
|
||||||
print '<td width="25%">'.$langs->trans("Ref").'</td><td>';
|
|
||||||
print $form->showrefnav($object,'ref','',1,'ref');
|
|
||||||
print '</td>';
|
|
||||||
|
|
||||||
print '</tr>';
|
|
||||||
|
|
||||||
// Label
|
|
||||||
print '<tr><td>'.$langs->trans("Label").'</td><td>'.$object->label.'</td>';
|
|
||||||
print '</tr>';
|
|
||||||
|
|
||||||
// Nature
|
// Nature
|
||||||
if($object->type!=Product::TYPE_SERVICE)
|
if($object->type!=Product::TYPE_SERVICE)
|
||||||
{
|
{
|
||||||
@ -265,7 +250,7 @@ if ($id > 0 || ! empty($ref))
|
|||||||
print load_fiche_titre($langs->trans("ProductParentList"),'','').'<br>';
|
print load_fiche_titre($langs->trans("ProductParentList"),'','').'<br>';
|
||||||
print '<table class="centpercent noborder">';
|
print '<table class="centpercent noborder">';
|
||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
print '<td>'.$langs->trans('ParentProduct').'</td>';
|
print '<td>'.$langs->trans('ParentProducts').'</td>';
|
||||||
print '<td>'.$langs->trans('Label').'</td>';
|
print '<td>'.$langs->trans('Label').'</td>';
|
||||||
print '<td>'.$langs->trans('Qty').'</td>';
|
print '<td>'.$langs->trans('Qty').'</td>';
|
||||||
print '</td>';
|
print '</td>';
|
||||||
@ -323,6 +308,7 @@ if ($id > 0 || ! empty($ref))
|
|||||||
print '<td>'.$langs->trans('ComposedProduct').'</td>';
|
print '<td>'.$langs->trans('ComposedProduct').'</td>';
|
||||||
print '<td>'.$langs->trans('Label').'</td>';
|
print '<td>'.$langs->trans('Label').'</td>';
|
||||||
print '<td align="right" colspan="2">'.$langs->trans('MinSupplierPrice').'</td>';
|
print '<td align="right" colspan="2">'.$langs->trans('MinSupplierPrice').'</td>';
|
||||||
|
print '<td align="right" colspan="2">'.$langs->trans('MinCustomerPrice').'</td>';
|
||||||
if (! empty($conf->stock->enabled)) print '<td align="right">'.$langs->trans('Stock').'</td>';
|
if (! empty($conf->stock->enabled)) print '<td align="right">'.$langs->trans('Stock').'</td>';
|
||||||
print '<td align="center">'.$langs->trans('Qty').'</td>';
|
print '<td align="center">'.$langs->trans('Qty').'</td>';
|
||||||
print '<td align="center">'.$langs->trans('ComposedProductIncDecStock').'</td>';
|
print '<td align="center">'.$langs->trans('ComposedProductIncDecStock').'</td>';
|
||||||
@ -334,10 +320,7 @@ if ($id > 0 || ! empty($ref))
|
|||||||
{
|
{
|
||||||
foreach($prods_arbo as $value)
|
foreach($prods_arbo as $value)
|
||||||
{
|
{
|
||||||
$productstatic->id=$value['id'];
|
$productstatic->fetch($value['id']);
|
||||||
$productstatic->type=$value['type'];
|
|
||||||
$productstatic->label=$value['label'];
|
|
||||||
$productstatic->entity=$value['entity'];
|
|
||||||
|
|
||||||
if ($value['level'] <= 1)
|
if ($value['level'] <= 1)
|
||||||
{
|
{
|
||||||
@ -345,7 +328,6 @@ if ($id > 0 || ! empty($ref))
|
|||||||
print '<tr class="'.$class.'">';
|
print '<tr class="'.$class.'">';
|
||||||
|
|
||||||
$notdefined=0;
|
$notdefined=0;
|
||||||
$productstatic->ref=$value['ref'];
|
|
||||||
$nb_of_subproduct = $value['nb'];
|
$nb_of_subproduct = $value['nb'];
|
||||||
|
|
||||||
print '<td>'.$productstatic->getNomUrl(1,'composition').'</td>';
|
print '<td>'.$productstatic->getNomUrl(1,'composition').'</td>';
|
||||||
@ -355,7 +337,7 @@ if ($id > 0 || ! empty($ref))
|
|||||||
print '<td align="right">';
|
print '<td align="right">';
|
||||||
if ($product_fourn->find_min_price_product_fournisseur($productstatic->id) > 0)
|
if ($product_fourn->find_min_price_product_fournisseur($productstatic->id) > 0)
|
||||||
{
|
{
|
||||||
print ' '.$langs->trans("BuyingPriceMinShort").': ';
|
print $langs->trans("BuyingPriceMinShort").': ';
|
||||||
if ($product_fourn->product_fourn_price_id > 0) print $product_fourn->display_price_product_fournisseur(0,0);
|
if ($product_fourn->product_fourn_price_id > 0) print $product_fourn->display_price_product_fournisseur(0,0);
|
||||||
else { print $langs->trans("NotDefined"); $notdefined++; $atleastonenotdefined++; }
|
else { print $langs->trans("NotDefined"); $notdefined++; $atleastonenotdefined++; }
|
||||||
}
|
}
|
||||||
@ -363,10 +345,23 @@ if ($id > 0 || ! empty($ref))
|
|||||||
|
|
||||||
$totalline=price2num($value['nb'] * ($product_fourn->fourn_unitprice * (1 - $product_fourn->fourn_remise_percent/100) + $product_fourn->fourn_unitcharges - $product_fourn->fourn_remise), 'MT');
|
$totalline=price2num($value['nb'] * ($product_fourn->fourn_unitprice * (1 - $product_fourn->fourn_remise_percent/100) + $product_fourn->fourn_unitcharges - $product_fourn->fourn_remise), 'MT');
|
||||||
$total+=$totalline;
|
$total+=$totalline;
|
||||||
|
|
||||||
print '<td align="right">';
|
print '<td align="right">';
|
||||||
print ($notdefined?'':($value['nb']> 1 ? $value['nb'].'x' : '').price($product_fourn->fourn_unitprice,'','',0,0,-1,$conf->currency));
|
print ($notdefined?'':($value['nb']> 1 ? $value['nb'].'x' : '').price($product_fourn->fourn_unitprice,'','',0,0,-1,$conf->currency));
|
||||||
print '</td>';
|
print '</td>';
|
||||||
|
|
||||||
|
// Best selling price
|
||||||
|
$pricesell=$productstatic->price;
|
||||||
|
if (! empty($conf->global->PRODUIT_MULTIPRICES))
|
||||||
|
{
|
||||||
|
$pricesell='Variable';
|
||||||
|
}
|
||||||
|
$totallinesell=price2num($value['nb'] * ($pricesell), 'MT');
|
||||||
|
$totalsell+=$totallinesell;
|
||||||
|
print '<td align="right" colspan="2">';
|
||||||
|
print ($notdefined?'':($value['nb']> 1 ? $value['nb'].'x' : '').price($pricesell,'','',0,0,-1,$conf->currency));
|
||||||
|
print '</td>';
|
||||||
|
|
||||||
// Stock
|
// Stock
|
||||||
if (! empty($conf->stock->enabled)) print '<td align="right">'.$value['stock'].'</td>'; // Real stock
|
if (! empty($conf->stock->enabled)) print '<td align="right">'.$value['stock'].'</td>'; // Real stock
|
||||||
|
|
||||||
@ -416,7 +411,7 @@ if ($id > 0 || ! empty($ref))
|
|||||||
|
|
||||||
// Minimum buying price
|
// Minimum buying price
|
||||||
print '<td class="liste_total" align="right">';
|
print '<td class="liste_total" align="right">';
|
||||||
print $langs->trans("TotalBuyingPriceMin");
|
print $langs->trans("TotalBuyingPriceMinShort");
|
||||||
print '</td>';
|
print '</td>';
|
||||||
|
|
||||||
print '<td class="liste_total" align="right">';
|
print '<td class="liste_total" align="right">';
|
||||||
@ -424,6 +419,16 @@ if ($id > 0 || ! empty($ref))
|
|||||||
print ($atleastonenotdefined?'':price($total,'','',0,0,-1,$conf->currency));
|
print ($atleastonenotdefined?'':price($total,'','',0,0,-1,$conf->currency));
|
||||||
print '</td>';
|
print '</td>';
|
||||||
|
|
||||||
|
// Minimum selling price
|
||||||
|
print '<td class="liste_total" align="right">';
|
||||||
|
print $langs->trans("TotalSellingPriceMinShort");
|
||||||
|
print '</td>';
|
||||||
|
|
||||||
|
print '<td class="liste_total" align="right">';
|
||||||
|
if ($atleastonenotdefined) print $langs->trans("Unknown").' ('.$langs->trans("SomeSubProductHaveNoPrices").')';
|
||||||
|
print ($atleastonenotdefined?'':price($totalsell,'','',0,0,-1,$conf->currency));
|
||||||
|
print '</td>';
|
||||||
|
|
||||||
// Stock
|
// Stock
|
||||||
if (! empty($conf->stock->enabled)) print '<td class="liste_total" align="right"> </td>';
|
if (! empty($conf->stock->enabled)) print '<td class="liste_total" align="right"> </td>';
|
||||||
|
|
||||||
@ -464,24 +469,22 @@ if ($id > 0 || ! empty($ref))
|
|||||||
|
|
||||||
print load_fiche_titre($langs->trans("ProductToAddSearch"),'','');
|
print load_fiche_titre($langs->trans("ProductToAddSearch"),'','');
|
||||||
print '<form action="'.DOL_URL_ROOT.'/product/composition/card.php?id='.$id.'" method="POST">';
|
print '<form action="'.DOL_URL_ROOT.'/product/composition/card.php?id='.$id.'" method="POST">';
|
||||||
print '<table class="border" width="100%"><tr><td>';
|
|
||||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
|
||||||
print $langs->trans("KeywordFilter").' ';
|
|
||||||
print '</td>';
|
|
||||||
print '<td><input type="text" name="key" value="'.$key.'">';
|
|
||||||
print '<input type="hidden" name="action" value="search">';
|
print '<input type="hidden" name="action" value="search">';
|
||||||
print '<input type="hidden" name="id" value="'.$id.'">';
|
print '<input type="hidden" name="id" value="'.$id.'">';
|
||||||
print '</td>';
|
print '<div class="inline-block">';
|
||||||
print '<td rowspan="'.$rowspan.'" valign="middle">';
|
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||||
print '<input type="submit" class="button" value="'.$langs->trans("Search").'">';
|
print $langs->trans("KeywordFilter").': ';
|
||||||
print '</td></tr>';
|
print '<input type="text" name="key" value="'.$key.'"> ';
|
||||||
|
print '</div>';
|
||||||
if (! empty($conf->categorie->enabled))
|
if (! empty($conf->categorie->enabled))
|
||||||
{
|
{
|
||||||
require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
|
require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
|
||||||
print '<tr><td>'.$langs->trans("CategoryFilter").' </td>';
|
print '<div class="inline-block">'.$langs->trans("CategoryFilter").': ';
|
||||||
print '<td class="maxwidthonsmartphone">'.$form->select_all_categories(Categorie::TYPE_PRODUCT, $parent).'</td></tr>';
|
print $form->select_all_categories(Categorie::TYPE_PRODUCT, $parent).' </div>';
|
||||||
}
|
}
|
||||||
print '</table>';
|
print '<div class="inline-block">';
|
||||||
|
print '<input type="submit" class="button" value="'.$langs->trans("Search").'">';
|
||||||
|
print '</div>';
|
||||||
print '</form>';
|
print '</form>';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,7 +497,7 @@ if ($id > 0 || ! empty($ref))
|
|||||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||||
print '<input type="hidden" name="action" value="add_prod">';
|
print '<input type="hidden" name="action" value="add_prod">';
|
||||||
print '<input type="hidden" name="id" value="'.$id.'">';
|
print '<input type="hidden" name="id" value="'.$id.'">';
|
||||||
print '<table class="nobordernopadding" width="100%">';
|
print '<table class="noborder centpercent">';
|
||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
print '<th class="liste_titre">'.$langs->trans("ComposedProduct").'</td>';
|
print '<th class="liste_titre">'.$langs->trans("ComposedProduct").'</td>';
|
||||||
print '<th class="liste_titre">'.$langs->trans("Label").'</td>';
|
print '<th class="liste_titre">'.$langs->trans("Label").'</td>';
|
||||||
|
|||||||
@ -519,14 +519,15 @@ if ($resql)
|
|||||||
$moreforfilter.=$formother->select_categories('customer',$search_categ,'search_categ',1);
|
$moreforfilter.=$formother->select_categories('customer',$search_categ,'search_categ',1);
|
||||||
$moreforfilter.='</div>';
|
$moreforfilter.='</div>';
|
||||||
}
|
}
|
||||||
// If the user can view prospects other than his'
|
}
|
||||||
if ($user->rights->societe->client->voir || $socid)
|
|
||||||
{
|
// If the user can view prospects other than his'
|
||||||
$moreforfilter.='<div class="divsearchfield">';
|
if ($user->rights->societe->client->voir || $socid)
|
||||||
$moreforfilter.=$langs->trans('SalesRepresentatives'). ': ';
|
{
|
||||||
$moreforfilter.=$formother->select_salesrepresentatives($search_sale,'search_sale',$user, 0, 1, 'maxwidth300');
|
$moreforfilter.='<div class="divsearchfield">';
|
||||||
$moreforfilter.='</div>';
|
$moreforfilter.=$langs->trans('SalesRepresentatives'). ': ';
|
||||||
}
|
$moreforfilter.=$formother->select_salesrepresentatives($search_sale,'search_sale',$user, 0, 1, 'maxwidth300');
|
||||||
|
$moreforfilter.='</div>';
|
||||||
}
|
}
|
||||||
if ($type == 'f')
|
if ($type == 'f')
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user