NEW: Introduce option SUPPLIER_ORDER_DOUBLE_APPROVAL to allow 2

approvals to make a supplier order approved. Activating this option
introduce a new permission to the second level approval.
This commit is contained in:
Laurent Destailleur 2015-04-01 21:00:51 +02:00
parent 8e9c1c4747
commit d8db32a99c
10 changed files with 230 additions and 79 deletions

View File

@ -169,29 +169,57 @@ else if ($action == 'set_SUPPLIER_ORDER_OTHER')
{
$freetext = GETPOST('SUPPLIER_ORDER_FREE_TEXT'); // No alpha here, we want exact string
$doubleapproval = GETPOST('SUPPLIER_ORDER_DOUBLE_APPROVAL');
$doubleapprovalgroup = GETPOST('SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP') > 0 ? GETPOST('SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP') : '';
//$doubleapprovalgroup = GETPOST('SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP') > 0 ? GETPOST('SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP') : '';
$res1 = dolibarr_set_const($db, "SUPPLIER_ORDER_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity);
$res2 = dolibarr_set_const($db, "SUPPLIER_ORDER_DOUBLE_APPROVAL",$doubleapproval,'chaine',0,'',$conf->entity);
if (isset($_POST["SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP"]))
/*if (isset($_POST["SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP"]))
{
$res3 = dolibarr_set_const($db, "SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP",$doubleapprovalgroup,'chaine',0,'',$conf->entity);
}
else
{
$res3=1;
}
if (! $res1 > 0 || ! $res2 > 0 || ! $res3 > 0) $error++;
}*/
if (! $error)
{
setEventMessage($langs->trans("SetupSaved"));
}
else
{
setEventMessage($langs->trans("Error"),'errors');
}
// TODO We add/delete permission until permission can have a condition on a global var
$r_id = 1190;
$entity = $conf->entity;
$r_desc='Permission for second approval';
$r_modul='fournisseur';
$r_type='w';
$r_perms='commande';
$r_subperms='approve2';
$r_def=0;
if ($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL)
{
$sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def";
$sql.= " (id, entity, libelle, module, type, bydefault, perms, subperms)";
$sql.= " VALUES ";
$sql.= "(".$r_id.",".$entity.",'".$db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."','".$r_subperms."')";
$resqlinsert=$db->query($sql,1);
if (! $resqlinsert)
{
if ($db->errno() != "DB_ERROR_RECORD_ALREADY_EXISTS")
{
setEventMessage($db->lasterror(),'errors');
$error++;
}
}
}
else
{
$sql = "DELETE FROM ".MAIN_DB_PREFIX."rights_def";
$sql.= " WHERE id = ".$r_id;
$resqldelete=$db->query($sql,1);
if (! $resqldelete)
{
setEventMessage($db->lasterror(),'errors');
$error++;
}
}
}
@ -467,16 +495,25 @@ print '<td>'.$langs->trans("Parameter").'</td>';
print '<td align="center" width="60">'.$langs->trans("Value").'</td>';
print '<td width="80">&nbsp;</td>';
print "</tr>\n";
$var=false;
if ($conf->global->MAIN_FEATURES_LEVEL > 0)
{
print '<tr '.$bc[$var].'><td>';
print $langs->trans("UseDoubleApproval").'</td><td>';
print $form->selectyesno('SUPPLIER_ORDER_DOUBLE_APPROVAL', $conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL);
print '<br>'.$form->select_dolgroups($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP,'SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP', 1);
print $langs->trans("UseDoubleApproval").'<br>';
print $langs->trans("IfSetToYesDontForgetPermission");
print '</td><td>';
print $form->selectyesno('SUPPLIER_ORDER_DOUBLE_APPROVAL', $conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL, 1);
print '</td><td align="right">';
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
print "</td></tr>\n";
$var=!$var;
/*print '<tr '.$bc[$var].'><td>';
print $langs->trans("GroupOfUserForSecondApproval").'</td><td>';
print $form->select_dolgroups($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP,'SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP', 1);
print '</td><td align="right">';
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
print "</td></tr>\n";
$var=!$var;*/
}
print '<tr '.$bc[$var].'><td colspan="2">';

View File

@ -395,12 +395,12 @@ class Form
$htmltext=str_replace("\n","",$htmltext);
$htmltext=str_replace('"',"&quot;",$htmltext);
if ($tooltipon == 2 || $tooltipon == 3) $paramfortooltipimg=' class="classfortooltip inline-block'.($extracss?' '.$extracss:'').'" title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on td img tag to store tooltip
if ($tooltipon == 2 || $tooltipon == 3) $paramfortooltipimg=' class="classfortooltip inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;" title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on td img tag to store tooltip
else $paramfortooltipimg =($extracss?' class="'.$extracss.'"':''); // Attribut to put on td text tag
if ($tooltipon == 1 || $tooltipon == 3) $paramfortooltiptd=' class="classfortooltip inline-block'.($extracss?' '.$extracss:'').'" title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on td tag to store tooltip
if ($tooltipon == 1 || $tooltipon == 3) $paramfortooltiptd=' class="classfortooltip inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;" title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on td tag to store tooltip
else $paramfortooltiptd =($extracss?' class="'.$extracss.'"':''); // Attribut to put on td text tag
$s="";
if (empty($notabs)) $s.='<table class="nobordernopadding" summary=""><tr>';
if (empty($notabs)) $s.='<table class="nobordernopadding" summary=""><tr style="height: auto;">';
elseif ($notabs == 2) $s.='<div class="inline-block nowrap">';
if ($direction < 0) {
$s.='<'.$tag.$paramfortooltipimg;
@ -412,8 +412,8 @@ class Form
// Use another method to help avoid having a space in value in order to use this value with jquery
// TODO add this in css
//if ($text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.(($direction < 0)?'&nbsp;':'').$text.(($direction > 0)?'&nbsp;':'').'</'.$tag.'>';
$paramfortooltiptd.= (($direction < 0)?' class="inline-block" style="padding-left: 3px !important;"':'');
$paramfortooltiptd.= (($direction > 0)?' class="inline-block" style="padding-right: 3px !important;"':'');
$paramfortooltiptd.= (($direction < 0)?' class="inline-block" style="padding: 0px; padding-left: 3px !important;"':'');
$paramfortooltiptd.= (($direction > 0)?' class="inline-block" style="padding: 0px; padding-right: 3px !important;"':'');
if ((string) $text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.$text.'</'.$tag.'>';
if ($direction > 0) {
$s.='<'.$tag.$paramfortooltipimg;

View File

@ -455,7 +455,7 @@ class FormCompany
{
$out.= '<div id="particulier2" class="visible">';
$out.= '<select class="flat" name="forme_juridique_code" id="legal_form">';
if ($country_codeid) $out.= '<option value="0">&nbsp;</option>';
if ($country_codeid) $out.= '<option value="0">&nbsp;</option>'; // When country_codeid is set, we force to add an empty line because it does not appears from select. When not set, we already get the empty line from select.
$num = $this->db->num_rows($resql);
if ($num)
@ -465,13 +465,21 @@ class FormCompany
while ($i < $num)
{
$obj = $this->db->fetch_object($resql);
$labelcountry=(($langs->trans("Country".$obj->country_code)!="Country".$obj->country_code) ? $langs->trans("Country".$obj->country_code) : $obj->country);
$labeljs=(($langs->trans("JuridicalStatus".$obj->code)!="JuridicalStatus".$obj->code) ? $langs->trans("JuridicalStatus".$obj->code) : ($obj->label!='-'?$obj->label:'')); // $obj->label is already in output charset (converted by database driver)
$arraydata[$obj->code]=array('code'=>$obj->code, 'label'=>$labeljs, 'label_sort'=>$labelcountry.'_'.$labeljs, 'country_code'=>$obj->country_code, 'country'=>$labelcountry);
if ($obj->code) // We exclude empty line, we will add it later
{
$labelcountry=(($langs->trans("Country".$obj->country_code)!="Country".$obj->country_code) ? $langs->trans("Country".$obj->country_code) : $obj->country);
$labeljs=(($langs->trans("JuridicalStatus".$obj->code)!="JuridicalStatus".$obj->code) ? $langs->trans("JuridicalStatus".$obj->code) : ($obj->label!='-'?$obj->label:'')); // $obj->label is already in output charset (converted by database driver)
$arraydata[$obj->code]=array('code'=>$obj->code, 'label'=>$labeljs, 'label_sort'=>$labelcountry.'_'.$labeljs, 'country_code'=>$obj->country_code, 'country'=>$labelcountry);
}
$i++;
}
$arraydata=dol_sort_array($arraydata, 'label_sort', 'ASC');
if (empty($country_codeid)) // Introduce empty value (if $country_codeid not empty, empty value was already added)
{
$arraydata[0]=array('code'=>0, 'label'=>'', 'label_sort'=>'_', 'country_code'=>'', 'country'=>'');
}
foreach($arraydata as $key => $val)
{

View File

@ -65,6 +65,7 @@ class CommandeFournisseur extends CommonOrder
var $date;
var $date_valid;
var $date_approve;
var $date_approve2; // Used when SUPPLIER_ORDER_DOUBLE_APPROVAL is set
var $date_commande;
var $date_livraison; // Date livraison souhaitee
var $total_ht;
@ -85,12 +86,13 @@ class CommandeFournisseur extends CommonOrder
var $user_author_id;
var $user_valid_id;
var $user_approve_id;
var $user_approve_id2; // Used when SUPPLIER_ORDER_DOUBLE_APPROVAL is set
//Incorterms
var $fk_incoterms;
var $location_incoterms;
var $libelle_incoterms; //Used into tooltip
var $extraparams=array();
/**
@ -110,7 +112,7 @@ class CommandeFournisseur extends CommonOrder
function __construct($db)
{
global $conf;
$this->db = $db;
$this->products = array();
@ -144,8 +146,8 @@ class CommandeFournisseur extends CommonOrder
$sql = "SELECT c.rowid, c.ref, ref_supplier, c.fk_soc, c.fk_statut, c.amount_ht, c.total_ht, c.total_ttc, c.tva,";
$sql.= " c.localtax1, c.localtax2, ";
$sql.= " c.date_creation, c.date_valid, c.date_approve,";
$sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_approve,";
$sql.= " c.date_creation, c.date_valid, c.date_approve, c.date_approve2,";
$sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_approve, c.fk_user_approve2,";
$sql.= " c.date_commande as date_commande, c.date_livraison as date_livraison, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_projet as fk_project, c.remise_percent, c.source, c.fk_input_method,";
$sql.= " c.fk_account,";
$sql.= " c.note_private, c.note_public, c.model_pdf, c.extraparams,";
@ -184,6 +186,7 @@ class CommandeFournisseur extends CommonOrder
$this->user_author_id = $obj->fk_user_author;
$this->user_valid_id = $obj->fk_user_valid;
$this->user_approve_id = $obj->fk_user_approve;
$this->user_approve_id2 = $obj->fk_user_approve2;
$this->total_ht = $obj->total_ht;
$this->total_tva = $obj->tva;
$this->total_localtax1 = $obj->localtax1;
@ -192,7 +195,8 @@ class CommandeFournisseur extends CommonOrder
$this->date = $this->db->jdate($obj->date_creation);
$this->date_valid = $this->db->jdate($obj->date_valid);
$this->date_approve = $this->db->jdate($obj->date_approve);
$this->date_commande = $this->db->jdate($obj->date_commande); // date a laquelle la commande a ete transmise
$this->date_approve2 = $this->db->jdate($obj->date_approve2);
$this->date_commande = $this->db->jdate($obj->date_commande); // date we make the order to supplier
$this->date_livraison = $this->db->jdate($obj->date_livraison);
$this->remise_percent = $obj->remise_percent;
$this->methode_commande_id = $obj->fk_input_method;
@ -216,9 +220,9 @@ class CommandeFournisseur extends CommonOrder
//Incoterms
$this->fk_incoterms = $obj->fk_incoterms;
$this->location_incoterms = $obj->location_incoterms;
$this->location_incoterms = $obj->location_incoterms;
$this->libelle_incoterms = $obj->libelle_incoterms;
$this->extraparams = (array) json_decode($obj->extraparams, true);
$this->db->free($resql);
@ -645,9 +649,10 @@ class CommandeFournisseur extends CommonOrder
*
* @param User $user Object user
* @param int $idwarehouse Id of warhouse for stock change
* @param int $secondlevel 0=Standard approval, 1=Second level approval (used when option SUPPLIER_ORDER_DOUBLE_APPROVAL is set)
* @return int <0 if KO, >0 if OK
*/
function approve($user, $idwarehouse=0)
function approve($user, $idwarehouse=0, $secondlevel=0)
{
global $langs,$conf;
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
@ -658,6 +663,8 @@ class CommandeFournisseur extends CommonOrder
if ($user->rights->fournisseur->commande->approuver)
{
$now = dol_now();
$this->db->begin();
// Definition du nom de modele de numerotation de commande
@ -675,11 +682,26 @@ class CommandeFournisseur extends CommonOrder
}
$this->newref = $num;
// Do we have to change status now ? (If double approval is required and first approval, we keep status to 1 = validated)
$movetoapprovestatus=true;
$sql = "UPDATE ".MAIN_DB_PREFIX."commande_fournisseur";
$sql.= " SET ref='".$this->db->escape($num)."',";
$sql.= " fk_statut = 2,";
$sql.= " date_approve='".$this->db->idate(dol_now())."',";
$sql.= " fk_user_approve = ".$user->id;
if (empty($secondlevel)) // standard or first level approval
{
$sql.= " date_approve='".$this->db->idate($now)."',";
$sql.= " fk_user_approve = ".$user->id;
if (! empty($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL)) $movetoapprovestatus=false;
}
else // request a second level approval
{
$sql.= " date_approve2='".$this->db->idate($now)."',";
$sql.= " fk_user_approve2 = ".$user->id;
if (empty($this->user_approve_id)) $movetoapprovestatus=false; // first level approval not done
}
// If double approval is required and first approval, we keep status to 1 = validated
if ($movetoapprovestatus) $sql.= ", fk_statut = 2";
else $sql.= ", fk_statut = 1";
$sql.= " WHERE rowid = ".$this->id;
$sql.= " AND fk_statut = 1";
@ -697,7 +719,7 @@ class CommandeFournisseur extends CommonOrder
}
// If stock is incremented on validate order, we must increment it
if (! $error && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER))
if (! $error && $movetoapprovestatus && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER))
{
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
$langs->load("agenda");
@ -729,6 +751,20 @@ class CommandeFournisseur extends CommonOrder
if (! $error)
{
$this->ref=$newref;
if ($movetoapprovestatus) $this->statut = 2;
else $this->statut = 1;
if (empty($secondlevel)) // standard or first level approval
{
$this->date_approve = $now;
$this->user_approve_id = $user->id;
}
else // request a second level approval
{
$this->date_approve2 = $now;
$this->user_approve_id2 = $user->id;
}
$this->db->commit();
return 1;
}
@ -1088,6 +1124,10 @@ class CommandeFournisseur extends CommonOrder
$this->date_creation = '';
$this->date_validation = '';
$this->ref_supplier = '';
$this->user_approve_id = '';
$this->user_approve_id2 = '';
$this->date_approve = '';
$this->date_approve2 = '';
// Create clone
$result=$this->create($user);
@ -1625,14 +1665,14 @@ class CommandeFournisseur extends CommonOrder
/**
* Return array of dispathed lines waiting to be approved for this order
*
*
* @param int $status Filter on stats (-1 = no filter, 0 = lines draft to be approved, 1 = approved lines)
* @return array Array of lines
*/
function getDispachedLines($status=-1)
{
$ret = array();
// List of already dispatched lines
$sql = "SELECT p.ref, p.label,";
$sql.= " e.rowid as warehouse_id, e.label as entrepot,";
@ -1655,16 +1695,16 @@ class CommandeFournisseur extends CommonOrder
{
$objp = $this->db->fetch_object($resql);
if ($objp) $ret[]=array('id'=>$objp->dispatchedlineid, 'productid'=>$objp->fk_product, 'warehouseid'=>$objp->warehouse_id);
$i++;
}
}
else dol_print_error($this->db, 'Failed to execute request to get dispatched lines');
return $ret;
}
/**
* Set a delivery in database for this supplier order
*
@ -1677,10 +1717,10 @@ class CommandeFournisseur extends CommonOrder
function Livraison($user, $date, $type, $comment)
{
global $conf;
$result = 0;
$error = 0;
dol_syslog(get_class($this)."::Livraison");
if ($user->rights->fournisseur->commande->receptionner)
@ -1709,7 +1749,7 @@ class CommandeFournisseur extends CommonOrder
dol_syslog(get_class($this)."::Livraison Error -2", LOG_ERR);
$result = -2;
}
if (! $error)
{
$this->db->begin();
@ -2094,6 +2134,8 @@ class CommandeFournisseur extends CommonOrder
$this->mode_reglement_code = 'CHQ';
$this->note_public='This is a comment (public)';
$this->note_private='This is a comment (private)';
$this->statut=0;
// Lines
$nbp = 5;
$xnbp = 0;
@ -2350,7 +2392,7 @@ class CommandeFournisseurLigne extends CommonOrderLine
{
public $element='commande_fournisseurdet';
public $table_element='commande_fournisseurdet';
/**
* Unit price without taxes
* @var float

View File

@ -200,14 +200,29 @@ if (empty($reshook))
else if ($object->statut == 7) $newstatus=3; // Canceled->Process running
else if ($object->statut == 9) $newstatus=1; // Refused->Validated
$db->begin();
$result = $object->setStatus($user, $newstatus);
if ($result > 0)
{
if ($newstatus == 0)
{
$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur';
$sql.= ' SET fk_user_approve = null, fk_user_approve2 = null, date_approve = null, date_approve2 = null';
$sql.= ' WHERE rowid = '.$object->id;
$resql=$db->query($sql);
}
$db->commit();
header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
exit;
}
else
{
{
$db->rollback();
setEventMessage($object->error, 'errors');
}
}
@ -570,6 +585,7 @@ if (empty($reshook))
}
}
// Validate
if ($action == 'confirm_valid' && $confirm == 'yes' &&
((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->commande->creer))
|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->supplier_order_advance->validate)))
@ -605,11 +621,11 @@ if (empty($reshook))
// If we have permission, and if we don't need to provide the idwarehouse, we go directly on approved step
if ($user->rights->fournisseur->commande->approuver && ! (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) && $object->hasProductsOrServices(1)))
{
$action='confirm_approve';
$action='confirm_approve'; // can make standard or first level approval also if permission is set
}
}
if ($action == 'confirm_approve' && $confirm == 'yes' && $user->rights->fournisseur->commande->approuver)
if (($action == 'confirm_approve' || $action == 'confirm_approve2') && $confirm == 'yes' && $user->rights->fournisseur->commande->approuver)
{
$idwarehouse=GETPOST('idwarehouse', 'int');
@ -624,7 +640,7 @@ if (empty($reshook))
}
// Check parameters
if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) && $qualified_for_stock_change)
if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) && $qualified_for_stock_change) // warning name of option should be STOCK_CALCULATE_ON_SUPPLIER_APPROVE_ORDER
{
if (! $idwarehouse || $idwarehouse == -1)
{
@ -636,7 +652,7 @@ if (empty($reshook))
if (! $error)
{
$result = $object->approve($user, $idwarehouse);
$result = $object->approve($user, $idwarehouse, ($action=='confirm_approve2'?1:0));
if ($result > 0)
{
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
@ -1663,9 +1679,9 @@ elseif (! empty($object->id))
}
/*
* Confirmation de l'approbation
* Confirm approval
*/
if ($action == 'approve')
if ($action == 'approve' || $action == 'approve2')
{
$qualified_for_stock_change=0;
if (empty($conf->global->STOCK_SUPPORTS_SERVICES))
@ -1699,7 +1715,7 @@ elseif (! empty($object->id))
$text.=$notify->confirmMessage('ORDER_SUPPLIER_APPROVE', $object->socid, $object);
}
$formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ApproveThisOrder"), $text, "confirm_approve", $formquestion, 1, 1, 240);
$formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ApproveThisOrder"), $text, "confirm_".$action, $formquestion, 1, 1, 240);
}
/*
@ -2589,13 +2605,51 @@ elseif (! empty($object->id))
{
if ($user->rights->fournisseur->commande->approuver)
{
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=approve">'.$langs->trans("ApproveOrder").'</a>';
if (! empty($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL) && ! empty($object->user_approve_id))
{
print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("FirstApprovalAlreadyDone")).'">'.$langs->trans("ApproveOrder").'</a>';
}
else
{
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=approve">'.$langs->trans("ApproveOrder").'</a>';
}
}
else
{
print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("ApproveOrder").'</a>';
}
}
// Second approval (if option SUPPLIER_ORDER_DOUBLE_APPROVAL is set)
if ($object->statut == 1)
{
if ($user->rights->fournisseur->commande->approve2)
{
if (! empty($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL) && ! empty($object->user_approve_id2))
{
print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("SecondApprovalAlreadyDone")).'">'.$langs->trans("Approve2Order").'</a>';
}
else
{
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=approve2">'.$langs->trans("Approve2Order").'</a>';
}
}
else
{
print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("Approve2Order").'</a>';
}
}
// Refuse
if ($object->statut == 1)
{
if ($user->rights->fournisseur->commande->approuver || $user->rights->fournisseur->commande->approve2)
{
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=refuse">'.$langs->trans("RefuseOrder").'</a>';
}
else
{
print '<a class="butActionRefused" href="#">'.$langs->trans("ApproveOrder").'</a>';
print '<a class="butActionRefused" href="#">'.$langs->trans("RefuseOrder").'</a>';
print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("RefuseOrder").'</a>';
}
}
@ -2625,7 +2679,7 @@ elseif (! empty($object->id))
}
// Create bill
if (! empty($conf->fournisseur->enabled) && $object->statut >= 2) // 2 means accepted
if (! empty($conf->fournisseur->enabled) && ($object->statut >= 2 && $object->statut != 9)) // 2 means accepted
{
if ($user->rights->fournisseur->facture->creer)
{
@ -2645,6 +2699,12 @@ elseif (! empty($object->id))
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=webservice&amp;mode=init">'.$langs->trans('CreateRemoteOrder').'</a>';
}
// Clone
if ($user->rights->fournisseur->commande->creer)
{
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;socid='.$object->socid.'&amp;action=clone&amp;object=order">'.$langs->trans("ToClone").'</a>';
}
// Cancel
if ($object->statut == 2)
{
@ -2654,12 +2714,6 @@ elseif (! empty($object->id))
}
}
// Clone
if ($user->rights->fournisseur->commande->creer)
{
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;socid='.$object->socid.'&amp;action=clone&amp;object=order">'.$langs->trans("ToClone").'</a>';
}
// Delete
if ($user->rights->fournisseur->commande->supprimer)
{
@ -2696,23 +2750,17 @@ elseif (! empty($object->id))
print '</div><div class="fichehalfright"><div class="ficheaddleft">';
// List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions=new FormActions($db);
$somethingshown=$formactions->showactions($object,'order_supplier',$socid);
if ($user->rights->fournisseur->commande->commander && $object->statut == 2)
{
/*
* Commander (action=commande)
*/
print '<br>';
print '<form name="commande" action="card.php?id='.$object->id.'&amp;action=commande" method="post">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="commande">';
print_fiche_titre($langs->trans("ToOrder"),'','');
print '<table class="border" width="100%">';
print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("ToOrder").'</td></tr>';
//print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("ToOrder").'</td></tr>';
print '<tr><td>'.$langs->trans("OrderDate").'</td><td>';
$date_com = dol_mktime(0, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
print $form->select_date($date_com,'','','','',"commande");
@ -2726,6 +2774,7 @@ elseif (! empty($object->id))
print '<tr><td align="center" colspan="2"><input type="submit" class="button" value="'.$langs->trans("ToOrder").'"></td></tr>';
print '</table>';
print '</form>';
print "<br>";
}
if ($user->rights->fournisseur->commande->receptionner && ($object->statut == 3 || $object->statut == 4))
@ -2733,12 +2782,12 @@ elseif (! empty($object->id))
/*
* Receptionner (action=livraison)
*/
print '<br>';
print '<form action="card.php?id='.$object->id.'" method="post">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="livraison">';
print_fiche_titre($langs->trans("Receive"),'','');
print '<table class="border" width="100%">';
print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Receive").'</td></tr>';
//print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Receive").'</td></tr>';
print '<tr><td>'.$langs->trans("DeliveryDate").'</td><td>';
print $form->select_date('','','','','',"commande");
print "</td></tr>\n";
@ -2758,8 +2807,15 @@ elseif (! empty($object->id))
print '<tr><td align="center" colspan="2"><input type="submit" class="button" value="'.$langs->trans("Receive").'"></td></tr>';
print "</table>\n";
print "</form>\n";
print "<br>";
}
// List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions=new FormActions($db);
$somethingshown=$formactions->showactions($object,'order_supplier',$socid);
// List of actions on element
/* Hidden because" available into "Log" tab
print '<br>';

View File

@ -385,6 +385,8 @@ ALTER TABLE llx_commande ADD COLUMN fk_incoterms integer;
ALTER TABLE llx_commande ADD COLUMN location_incoterms varchar(255);
ALTER TABLE llx_commande_fournisseur ADD COLUMN fk_incoterms integer;
ALTER TABLE llx_commande_fournisseur ADD COLUMN location_incoterms varchar(255);
ALTER TABLE llx_commande_fournisseur ADD COLUMN date_approve2 datetime after date_approve;
ALTER TABLE llx_commande_fournisseur ADD COLUMN fk_user_approve2 integer after fk_user_approve;
ALTER TABLE llx_facture ADD COLUMN fk_incoterms integer;
ALTER TABLE llx_facture ADD COLUMN location_incoterms varchar(255);
ALTER TABLE llx_facture_fourn ADD COLUMN fk_incoterms integer;

View File

@ -36,11 +36,13 @@ create table llx_commande_fournisseur
date_creation datetime, -- date de creation
date_valid datetime, -- date de validation
date_approve datetime, -- date de approve
date_approve2 datetime, -- date de approve 2 (when double approving is accivated)
date_commande date, -- date de la commande
fk_user_author integer, -- user making creation
fk_user_modif integer, -- user making last change
fk_user_valid integer, -- user validating
fk_user_approve integer, -- user approving
fk_user_approve2 integer, -- user approving 2 (when double approving is accivated)
source smallint NOT NULL, -- not used, except by setting this to 42 for orders coming for replenishment and 0 in other case ?
fk_statut smallint default 0,
amount_ht real default 0,

View File

@ -1565,6 +1565,7 @@ SuppliersSetup=Supplier module setup
SuppliersCommandModel=Complete template of supplier order (logo...)
SuppliersInvoiceModel=Complete template of supplier invoice (logo...)
SuppliersInvoiceNumberingModel=Supplier invoices numbering models
IfSetToYesDontForgetPermission=If set to yes, don't forget to provide permissions to groups or users allowed for the second approval
##### GeoIPMaxmind #####
GeoIPMaxmindSetup=GeoIP Maxmind module setup
PathToGeoIPMaxmindCountryDataFile=Path to file containing Maxmind ip to country translation.<br>Examples:<br>/usr/local/share/GeoIP/GeoIP.dat<br>/usr/share/GeoIP/GeoIP.dat

View File

@ -64,7 +64,8 @@ ShipProduct=Ship product
Discount=Discount
CreateOrder=Create Order
RefuseOrder=Refuse order
ApproveOrder=Accept order
ApproveOrder=Approve order
Approve2Order=Approve order (second level)
ValidateOrder=Validate order
UnvalidateOrder=Unvalidate order
DeleteOrder=Delete order
@ -120,6 +121,7 @@ PaymentOrderRef=Payment of order %s
CloneOrder=Clone order
ConfirmCloneOrder=Are you sure you want to clone this order <b>%s</b> ?
DispatchSupplierOrder=Receiving supplier order %s
FirstApprovalAlreadyDone=First approval already done
##### Types de contacts #####
TypeContact_commande_internal_SALESREPFOLL=Representative following-up customer order
TypeContact_commande_internal_SHIPPING=Representative following-up shipping

View File

@ -1587,8 +1587,9 @@ else
if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
print '</td></tr>';
// Juridical type
print '<tr><td><label for="legal_form">'.$langs->trans('JuridicalStatus').'</label></td><td colspan="3">';
print $formcompany->select_juridicalstatus($object->forme_juridique_code,$object->country_code);
print $formcompany->select_juridicalstatus($object->forme_juridique_code,$object->country_code,'',0);
print '</td></tr>';
// Capital