diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index e039342dd38..aed5ee01a5d 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -2116,7 +2116,7 @@ if ($action == 'create') $form_close .= $object->note; $form_close .= ''; $form_close .= ''; - $form_close .= ''; + $form_close .= ''; $form_close .= '   '; $form_close .= ' '; $form_close .= ''; @@ -2204,10 +2204,10 @@ if ($action == 'create') } } - // Close + // Set accepted/refused if ($object->statut == Propal::STATUS_VALIDATED && $user->rights->propal->cloturer) { print '
global->MAIN_JUMP_TAG) ? '' : '#close') . '"'; - print '>' . $langs->trans('Close') . '
'; + print '>' . $langs->trans('SetAcceptedRefused') . ''; } // Clone diff --git a/htdocs/comm/propal/class/propalestats.class.php b/htdocs/comm/propal/class/propalestats.class.php index 07a5ff606bc..e38297a3377 100644 --- a/htdocs/comm/propal/class/propalestats.class.php +++ b/htdocs/comm/propal/class/propalestats.class.php @@ -26,6 +26,7 @@ include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php'; include_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php'; +include_once DOL_DOCUMENT_ROOT . '/supplier_proposal/class/supplier_proposal.class.php'; include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; @@ -50,8 +51,9 @@ class PropaleStats extends Stats * @param DoliDB $db Database handler * @param int $socid Id third party for filter. This value must be forced during the new to external user company if user is an external user. * @param int $userid Id user for filter (creation user) + * @param string $mode Option ('customer', 'supplier') */ - function __construct($db, $socid=0, $userid=0) + function __construct($db, $socid=0, $userid=0, $mode='customer') { global $user, $conf; @@ -59,15 +61,30 @@ class PropaleStats extends Stats $this->socid = ($socid > 0 ? $socid : 0); $this->userid = $userid; - $object=new Propal($this->db); - - $this->from = MAIN_DB_PREFIX.$object->table_element." as p"; - $this->from_line = MAIN_DB_PREFIX.$object->table_element_line." as tl"; - - $this->field='total_ht'; - $this->field_line='total_ht'; - - $this->where.= " p.fk_statut > 0"; + if ($mode == 'customer') + { + $object=new Propal($this->db); + + $this->from = MAIN_DB_PREFIX.$object->table_element." as p"; + $this->from_line = MAIN_DB_PREFIX.$object->table_element_line." as tl"; + $this->field_date='p.datep'; + $this->field='total_ht'; + $this->field_line='total_ht'; + + $this->where.= " p.fk_statut > 0"; + } + if ($mode == 'supplier') + { + $object=new SupplierProposal($this->db); + + $this->from = MAIN_DB_PREFIX.$object->table_element." as p"; + $this->from_line = MAIN_DB_PREFIX.$object->table_element_line." as tl"; + $this->field_date='p.date_valid'; + $this->field='total_ht'; + $this->field_line='total_ht'; + + $this->where.= " p.fk_statut > 0"; // Validated, accepted, refused and closed + } //$this->where.= " AND p.fk_soc = s.rowid AND p.entity = ".$conf->entity; $this->where.= " AND p.entity IN (".getEntity('propal', 1).")"; if (!$user->rights->societe->client->voir && !$this->socid) $this->where .= " AND p.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; @@ -89,10 +106,10 @@ class PropaleStats extends Stats { global $user; - $sql = "SELECT date_format(p.datep,'%m') as dm, COUNT(*) as nb"; + $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, COUNT(*) as nb"; $sql.= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; + $sql.= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; $sql.= " AND ".$this->where; $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); @@ -111,7 +128,7 @@ class PropaleStats extends Stats { global $user; - $sql = "SELECT date_format(p.datep,'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")"; + $sql = "SELECT date_format(".$this->field_date.",'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")"; $sql.= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE ".$this->where; @@ -131,10 +148,10 @@ class PropaleStats extends Stats { global $user; - $sql = "SELECT date_format(p.datep,'%m') as dm, SUM(p.".$this->field.")"; + $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, SUM(p.".$this->field.")"; $sql.= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; + $sql.= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; $sql.= " AND ".$this->where; $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); @@ -153,10 +170,10 @@ class PropaleStats extends Stats { global $user; - $sql = "SELECT date_format(p.datep,'%m') as dm, AVG(p.".$this->field.")"; + $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, AVG(p.".$this->field.")"; $sql.= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; + $sql.= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; $sql.= " AND ".$this->where; $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); @@ -173,7 +190,7 @@ class PropaleStats extends Stats { global $user; - $sql = "SELECT date_format(p.datep,'%Y') as year, COUNT(*) as nb, SUM(".$this->field.") as total, AVG(".$this->field.") as avg"; + $sql = "SELECT date_format(".$this->field_date.",'%Y') as year, COUNT(*) as nb, SUM(".$this->field.") as total, AVG(".$this->field.") as avg"; $sql.= " FROM ".$this->from; if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE ".$this->where; @@ -200,7 +217,7 @@ class PropaleStats extends Stats if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE ".$this->where; $sql.= " AND p.rowid = tl.fk_propal AND tl.fk_product = product.rowid"; - $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,1,false))."' AND '".$this->db->idate(dol_get_last_day($year,12,false))."'"; + $sql.= " AND ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year,1,false))."' AND '".$this->db->idate(dol_get_last_day($year,12,false))."'"; $sql.= " GROUP BY product.ref"; $sql.= $this->db->order('nb','DESC'); //$sql.= $this->db->plimit(20); diff --git a/htdocs/comm/propal/stats/index.php b/htdocs/comm/propal/stats/index.php index 5ff5723a6c0..2c93f874baa 100644 --- a/htdocs/comm/propal/stats/index.php +++ b/htdocs/comm/propal/stats/index.php @@ -33,6 +33,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formpropal.class.php'; $WIDTH=DolGraph::getDefaultGraphSizeForStats('width'); $HEIGHT=DolGraph::getDefaultGraphSizeForStats('height'); +$mode=GETPOST("mode")?GETPOST("mode"):'customer'; +if ($mode == 'customer' && ! $user->rights->propale->lire) accessforbidden(); +if ($mode == 'supplier' && ! $user->rights->supplier_proposal->lire) accessforbidden(); + $object_statut=GETPOST('propal_statut'); $userid=GETPOST('userid','int'); @@ -50,7 +54,10 @@ $year = GETPOST('year')>0?GETPOST('year'):$nowyear; $startyear=$year-1; $endyear=$year; -$mode=GETPOST('mode'); +$langs->load('orders'); +$langs->load('companies'); +$langs->load('other'); +$langs->load('suppliers'); /* @@ -64,16 +71,26 @@ $langs->load('propal'); $langs->load('other'); $langs->load("companies"); -llxHeader('', $langs->trans("ProposalsStatistics")); +if ($mode == 'customer') +{ + $title=$langs->trans("ProposalsStatistics"); + $dir=$conf->propale->dir_temp; +} +if ($mode == 'supplier') +{ + $title=$langs->trans("ProposalsStatisticsSuppliers").' ('.$langs->trans("SentToSuppliers").")"; + $dir=$conf->supplier_proposal->dir_temp; +} -print load_fiche_titre($langs->trans("ProposalsStatistics"),'','title_commercial.png'); +llxHeader('', $title); + +print load_fiche_titre($title,'','title_commercial.png'); -$dir=$conf->propal->dir_temp; dol_mkdir($dir); -$stats = new PropaleStats($db, $socid, ($userid>0?$userid:0)); +$stats = new PropaleStats($db, $socid, ($userid>0?$userid:0), $mode); if ($object_statut != '' && $object_statut >= 0) $stats->where .= ' AND p.fk_statut IN ('.$object_statut.')'; // Build graphic number of object @@ -248,7 +265,7 @@ print '
'; print ''; // Status print ''.$langs->trans("Status").''; - $formpropal->selectProposalStatus($object_statut,0,1); + $formpropal->selectProposalStatus($object_statut,0,1,1,$mode); print ''; // Year print ''.$langs->trans("Year").''; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 9e7f5fae4f8..a152b005ee8 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -261,6 +261,13 @@ if (empty($reshook)) $object->fk_incoterms = GETPOST('incoterm_id', 'int'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); + // Fill array 'array_options' with data from add form + if (! $error) + { + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) $error++; + } + // If creation from another object of another module (Example: origin=propal, originid=1) if (! empty($origin) && ! empty($originid)) { @@ -293,10 +300,6 @@ if (empty($reshook)) $object->linked_objects = array_merge($object->linked_objects, $other_linked_objects); } - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) $error++; - if (! $error) { $object_id = $object->create($user); @@ -386,10 +389,6 @@ if (empty($reshook)) $action = 'create'; } } else { - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) $error++; - if (! $error) { $object_id = $object->create($user); diff --git a/htdocs/commande/stats/index.php b/htdocs/commande/stats/index.php index bf0331f251d..1f0f763bfd1 100644 --- a/htdocs/commande/stats/index.php +++ b/htdocs/commande/stats/index.php @@ -64,8 +64,6 @@ $langs->load('suppliers'); $form=new Form($db); -llxHeader(); - if ($mode == 'customer') { $title=$langs->trans("OrdersStatistics"); @@ -77,6 +75,8 @@ if ($mode == 'supplier') $dir=$conf->fournisseur->dir_output.'/commande/temp'; } +llxHeader('', $title); + print load_fiche_titre($title,'','title_commercial.png'); dol_mkdir($dir); @@ -277,12 +277,12 @@ print '
'; print ''; print ''; print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; print ''; $oldyear=0; diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index e0d08dbc1fa..78f12335f36 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1077,7 +1077,7 @@ if ($action == 'create') else { print ''; } print ''."\n"; @@ -1110,12 +1110,13 @@ if ($action == 'create') $form->select_date($datecontrat,'',0,0,'',"contrat"); print ""; + // Project if (! empty($conf->projet->enabled)) { $formproject=new FormProjets($db); print '"; } @@ -1325,11 +1326,11 @@ else print '"; } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index d1fa0b20448..005f4684322 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2384,14 +2384,14 @@ abstract class CommonObject { // Parse element/subelement (ex: project_task) $module = $element = $subelement = $objecttype; - if ($objecttype != 'order_supplier' && $objecttype != 'invoice_supplier' && preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs)) + if ($objecttype != 'supplier_proposal' && $objecttype != 'order_supplier' && $objecttype != 'invoice_supplier' + && preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs)) { $module = $element = $regs[1]; $subelement = $regs[2]; } $classpath = $element.'/class'; - // To work with non standard classpath or module name if ($objecttype == 'facture') { $classpath = 'compta/facture/class'; @@ -2427,7 +2427,10 @@ abstract class CommonObject else if ($objecttype == 'order_supplier') { $classfile = 'fournisseur.commande'; $classname = 'CommandeFournisseur'; } - + else if ($objecttype == 'supplier_proposal') { + $classfile = 'supplier_proposal'; $classname = 'SupplierProposal'; + } + // Here $module, $classfile and $classname are set if ($conf->$module->enabled && (($element != $this->element) || $alsosametype)) { @@ -2595,6 +2598,7 @@ abstract class CommonObject $error = 0; $trigkey=''; + if ($this->element == 'supplier_proposal' && $status == 2) $trigkey='SUPPLIER_PROPOSAL_CLOSE'; if ($this->element == 'fichinter' && $status == 2) $trigkey='FICHINTER_CLASSIFY_BILLED'; if ($this->element == 'fichinter' && $status == 1) $trigkey='FICHINTER_CLASSIFY_UNBILLED'; diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 909afda913a..ee5f1465e3f 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -748,8 +748,9 @@ class ExtraFields $out.=''; print '
'.$langs->trans("Year").''.$langs->trans("NbOfOrders").'%'.$langs->trans("AmountTotal").'%'.$langs->trans("AmountAverage").'%'.$langs->trans("NbOfOrders").'%'.$langs->trans("AmountTotal").'%'.$langs->trans("AmountAverage").'%
'; - print $form->select_company('','socid','',1); + print $form->select_company('','socid','',1,1); print '
'.$langs->trans("Project").''; - $formproject->select_projects($soc->id,$projectid,"projectid"); + $formproject->select_projects(($soc->id>0?$soc->id:-1),$projectid,"projectid",0,0,1,1); print "
'; if ($action == "classify") { - $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id,$object->socid,$object->fk_project,"projectid", 0, 0, 1); + $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, "projectid", 1, 0, 1); } else { - $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id,$object->socid,$object->fk_project,"none", 0, 0); + $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, "none", 0, 0); } print "
'; print ''; print ''; print '
'; - $formproject->select_projects($socid,$selected,$htmlname,$maxlength,0,1,$discard_closed, $forcefocus); + $formproject->select_projects($socid, $selected, $htmlname, $maxlength, 0, 1, $discard_closed, $forcefocus); print '
'; @@ -4967,13 +4967,13 @@ class Form { $tplpath = $element = $subelement = $objecttype; - if (preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs)) + if ($objecttype != 'supplier_proposal' && preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs)) { $element = $regs[1]; $subelement = $regs[2]; $tplpath = $element.'/'.$subelement; } - + // To work with non standard path if ($objecttype == 'facture') { $tplpath = 'compta/'.$element; @@ -4984,7 +4984,6 @@ class Form if (empty($conf->propal->enabled)) continue; // Do not show if module disabled } else if ($objecttype == 'supplier_proposal') { - $tplpath = 'comm/'.$element; if (empty($conf->supplier_proposal->enabled)) continue; // Do not show if module disabled } else if ($objecttype == 'shipping' || $objecttype == 'shipment') { @@ -5001,7 +5000,7 @@ class Form else if ($objecttype == 'order_supplier') { $tplpath = 'fourn/commande'; } - + global $linkedObjectBlock; $linkedObjectBlock = $objects; diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 3b26576b0fa..498604d9307 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -55,13 +55,13 @@ class FormProjets * @param int $discard_closed Discard closed projects (0=Keep,1=hide completely,2=Disable) * @param int $forcefocus Force focus on field (works with javascript only) * @param int $disabled Disabled - * @param int $mode 0 for HTML mode and 1 for JSON mode - * @param string $filterkey Key to filter + * @param int $mode 0 for HTML mode and 1 for JSON mode + * @param string $filterkey Key to filter * @return int Nber of project if OK, <0 if KO */ function select_projects($socid=-1, $selected='', $htmlname='projectid', $maxlength=16, $option_only=0, $show_empty=1, $discard_closed=0, $forcefocus=0, $disabled=0, $mode = 0, $filterkey = '') { - global $langs,$conf; + global $langs,$conf,$form; if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PROJECT_USE_SEARCH_TO_SELECT)) { @@ -86,6 +86,14 @@ class FormProjets else { print $this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, $discard_closed, $forcefocus, $disabled, 0, $filterkey); + if ($discard_closed) + { + if (class_exists('Form')) + { + if (empty($form)) $form=new Form($this->db); + print $form->textwithpicto('', $langs->trans("ClosedProjectsAreHidden")); + } + } } } @@ -174,7 +182,7 @@ class FormProjets } else { - if ($discard_closed == 1 && $obj->fk_statut == 2) + if ($discard_closed == 1 && $obj->fk_statut == 2 && $obj->rowid != $selected) // We discard closed except if selected { $i++; continue; diff --git a/htdocs/core/class/html.formpropal.class.php b/htdocs/core/class/html.formpropal.class.php index e3f21212e8b..d64cd23e98d 100644 --- a/htdocs/core/class/html.formpropal.class.php +++ b/htdocs/core/class/html.formpropal.class.php @@ -49,66 +49,85 @@ class FormPropal * @param int $short Use short labels * @param int $excludedraft 0=All status, 1=Exclude draft status * @param int $showempty 1=Add empty line + * @param string $mode 'customer', 'supplier' * @return void */ - function selectProposalStatus($selected='',$short=0, $excludedraft=0, $showempty=1) + function selectProposalStatus($selected='',$short=0, $excludedraft=0, $showempty=1, $mode='customer') { global $langs; - $sql = "SELECT id, code, label, active FROM ".MAIN_DB_PREFIX."c_propalst"; - $sql .= " WHERE active = 1"; - - dol_syslog(get_class($this)."::selectProposalStatus", LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) + $prefix=''; + $listofstatus=array(); + if ($mode == 'supplier') { - print ''; + $prefix='SupplierProposalStatus'; + + $langs->load("supplier_proposal"); + $listofstatus=array(0=>array('code'=>'PR_DRAFT'), 1=>array('code'=>'PR_OPEN'), 2=>array('code'=>'PR_SIGNED'), 3=>array('code'=>'PR_NOTSIGNED'), 4=>array('code'=>'PR_CLOSED')); } else { - dol_print_error($this->db); + $prefix="PropalStatus"; + + $sql = "SELECT id, code, label, active FROM ".MAIN_DB_PREFIX."c_propalst"; + $sql .= " WHERE active = 1"; + dol_syslog(get_class($this)."::selectProposalStatus", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + if ($num) + { + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $listofstatus[$obj->id]=array('id'=>$obj->id,'code'=>$obj->code,'label'=>$obj->label); + } + } + } + else + { + dol_print_error($this->db); + } } - } + print ''; + } } diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 912b432174e..b54e9a560ac 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -162,6 +162,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->ficheinter->enabled', __HANDLER__, 'left', 1500__+MAX_llx_menu__, 'commercial', 'ficheinter', 5__+MAX_llx_menu__, '/fichinter/list.php?leftmenu=ficheinter', 'Interventions', 0, 'interventions', '$user->rights->ficheinter->lire', '', 2, 8, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->ficheinter->enabled', __HANDLER__, 'left', 1501__+MAX_llx_menu__, 'commercial', '', 1500__+MAX_llx_menu__, '/fichinter/card.php?action=create&leftmenu=ficheinter', 'NewIntervention', 1, 'interventions', '$user->rights->ficheinter->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->ficheinter->enabled', __HANDLER__, 'left', 1502__+MAX_llx_menu__, 'commercial', '', 1500__+MAX_llx_menu__, '/fichinter/list.php?leftmenu=ficheinter', 'List', 1, 'interventions', '$user->rights->ficheinter->lire', '', 2, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->ficheinter->enabled', __HANDLER__, 'left', 1503__+MAX_llx_menu__, 'commercial', '', 1500__+MAX_llx_menu__, '/fichinter/stats/index.php?leftmenu=ficheinter', 'Statistics', 1, 'interventions', '$user->rights->ficheinter->lire', '', 2, 2, __ENTITY__); -- Accountancy - Supplier invoice insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1600__+MAX_llx_menu__, 'accountancy', 'supplier_bills', 6__+MAX_llx_menu__, '/fourn/facture/list.php?leftmenu=suppliers_bills', 'BillsSuppliers', 0, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1601__+MAX_llx_menu__, 'accountancy', '', 1600__+MAX_llx_menu__, '/fourn/facture/card.php?action=create&leftmenu=suppliers_bills', 'NewBill', 1, 'bills', '$user->rights->fournisseur->facture->creer', '', 2, 0, __ENTITY__); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index ce8b166197b..6263b1b709d 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -487,7 +487,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $langs->load("users"); // Home - dashboard - $newmenu->add("/index.php?mainmenu=home&leftmenu=home", $langs->trans("Home"), 0, 1, '', $mainmenu, 'home'); + $newmenu->add("/index.php?mainmenu=home&leftmenu=home", $langs->trans("Dashboard"), 0, 1, '', $mainmenu, 'home'); // Setup $newmenu->add("/admin/index.php?mainmenu=home&leftmenu=setup", $langs->trans("Setup"), 0, $user->admin, '', $mainmenu, 'setup'); @@ -771,6 +771,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/fichinter/index.php?leftmenu=ficheinter", $langs->trans("Interventions"), 0, $user->rights->ficheinter->lire, '', $mainmenu, 'ficheinter', 2200); $newmenu->add("/fichinter/card.php?action=create&leftmenu=ficheinter", $langs->trans("NewIntervention"), 1, $user->rights->ficheinter->creer, '', '', '', 201); $newmenu->add("/fichinter/list.php?leftmenu=ficheinter", $langs->trans("List"), 1, $user->rights->ficheinter->lire, '', '', '', 202); + + $newmenu->add("/fichinter/stats/index.php?leftmenu=ficheinter", $langs->trans("Statistics"), 1, $user->rights->fournisseur->commande->lire); } } diff --git a/htdocs/core/modules/modSupplierProposal.class.php b/htdocs/core/modules/modSupplierProposal.class.php index 692cf2aefab..f38ce9b7f7e 100644 --- a/htdocs/core/modules/modSupplierProposal.class.php +++ b/htdocs/core/modules/modSupplierProposal.class.php @@ -23,6 +23,7 @@ /** * \defgroup supplier_proposal Module supplier_proposal * \brief Module to request supplier price proposals + * * \file htdocs/core/modules/modSupplierProposal.class.php * \ingroup supplier_proposal * \brief File to describe and activate module SupplierProposal @@ -52,7 +53,7 @@ class modSupplierProposal extends DolibarrModules $this->name = preg_replace('/^mod/i','',get_class($this)); $this->description = "supplier_proposalDESC"; - $this->version = 'experimental'; + $this->version = 'dolibarr'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); $this->special = 0; @@ -114,15 +115,13 @@ class modSupplierProposal extends DolibarrModules $this->rights[$r][0] = $this->numero + $r; // id de la permission $this->rights[$r][1] = 'Validate supplier proposals'; // libelle de la permission $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut - $this->rights[$r][4] = ''; - $this->rights[$r][5] = 'validate'; + $this->rights[$r][4] = 'validate_advance'; $r++; $this->rights[$r][0] = $this->numero + $r; // id de la permission $this->rights[$r][1] = 'Envoyer les demandes fournisseurs'; // libelle de la permission $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut - $this->rights[$r][4] = ''; - $this->rights[$r][5] = 'send_advance'; + $this->rights[$r][4] = 'send_advance'; $r++; $this->rights[$r][0] = $this->numero + $r; // id de la permission @@ -157,7 +156,7 @@ class modSupplierProposal extends DolibarrModules 'fk_menu'=>'fk_mainmenu=commercial,fk_leftmenu=supplier_proposalsubmenu', 'type'=>'left', 'titre'=>'SupplierProposalNew', - 'url'=>'/supplier_proposal/card.php?action=create', + 'url'=>'/supplier_proposal/card.php?action=create&leftmenu=supplier_proposals', 'langs'=>'supplier_proposal', 'enabled'=>'$conf->supplier_proposal->enabled', 'perms'=>'$user->rights->supplier_proposal->creer', @@ -170,7 +169,7 @@ class modSupplierProposal extends DolibarrModules 'fk_menu'=>'fk_mainmenu=commercial,fk_leftmenu=supplier_proposalsubmenu', 'type'=>'left', 'titre'=>'List', - 'url'=>'/supplier_proposal/list.php', + 'url'=>'/supplier_proposal/list.php?leftmenu=supplier_proposals', 'langs'=>'supplier_proposal', 'enabled'=>'$conf->supplier_proposal->enabled', 'perms'=>'$user->rights->supplier_proposal->lire', @@ -178,6 +177,19 @@ class modSupplierProposal extends DolibarrModules 'position'=>302 ); $r++; + + $this->menu[$r]=array( + 'fk_menu'=>'fk_mainmenu=commercial,fk_leftmenu=supplier_proposalsubmenu', + 'type'=>'left', + 'titre'=>'Statistics', + 'url'=>'/comm/propal/stats/index.php?leftmenu=supplier_proposals&mode=supplier', + 'langs'=>'supplier_proposal', + 'enabled'=>'$conf->supplier_proposal->enabled', + 'perms'=>'$user->rights->supplier_proposal->lire', + 'user'=>2, + 'position'=>303 + ); + $r++; } diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 4d80ac04039..4ba91ba7e96 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -1275,21 +1275,10 @@ else if ($id > 0 || ! empty($ref)) print ''.$langs->trans("TotalDuration").''; print ''.convertSecondToTime($object->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY).''; print ''; - - // Date create - print ''.$langs->trans("Datec").''; - print ''; - print $object->datec ? dol_print_date($object->datec, 'daytext') : ' '; - print ''; - print ''; - - // Date Validation - print ''.$langs->trans("Datev").''; - print ''; - print $object->datev ? dol_print_date($object->datev, 'daytext') : ' '; - print ''; - print ''; - + } + + if (! empty($conf->global->FICHINTER_USE_PLANNED_AND_DONE_DATES)) + { // Date Start print ''.$langs->trans("Dateo").''; print ''; diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index ca698c55d5c..c177eb7965c 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -137,6 +137,7 @@ class Fichinter extends CommonObject $sql.= ", ref"; $sql.= ", entity"; $sql.= ", fk_user_author"; + $sql.= ", fk_user_modif"; $sql.= ", description"; $sql.= ", model_pdf"; $sql.= ", fk_projet"; @@ -151,6 +152,7 @@ class Fichinter extends CommonObject $sql.= ", '".$this->db->escape($this->ref)."'"; $sql.= ", ".$conf->entity; $sql.= ", ".$user->id; + $sql.= ", ".$user->id; $sql.= ", ".($this->description?"'".$this->db->escape($this->description)."'":"null"); $sql.= ", '".$this->db->escape($this->modelpdf)."'"; $sql.= ", ".($this->fk_project ? $this->fk_project : 0); diff --git a/htdocs/fichinter/class/fichinterstats.class.php b/htdocs/fichinter/class/fichinterstats.class.php new file mode 100644 index 00000000000..1219a83d9e0 --- /dev/null +++ b/htdocs/fichinter/class/fichinterstats.class.php @@ -0,0 +1,211 @@ + + * Copyright (c) 2005-2013 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2012 Marcos GarcĂ­a + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/fichinter/class/fichinterstats.class.php + * \ingroup fichinter + * \brief File of class to manage intervention statistics + */ +include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php'; +include_once DOL_DOCUMENT_ROOT . '/fichinter/class/fichinter.class.php'; +include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; + + +/** + * Class to manage intervention statistics + */ +class FichinterStats extends Stats +{ + public $table_element; + + var $socid; + var $userid; + + var $from; + var $field; + var $where; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + * @param int $socid Id third party for filter. This value must be forced during the new to external user company if user is an external user. + * @param string $mode Option ('customer', 'supplier') + * @param int $userid Id user for filter (creation user) + */ + function __construct($db, $socid, $mode, $userid=0) + { + global $user, $conf; + + $this->db = $db; + + $this->socid = ($socid > 0 ? $socid : 0); + $this->userid = $userid; + $this->cachefilesuffix = $mode; + + if ($mode == 'customer') + { + $object=new Fichinter($this->db); + $this->from = MAIN_DB_PREFIX.$object->table_element." as c"; + $this->from_line = MAIN_DB_PREFIX.$object->table_element_line." as tl"; + $this->field='0'; + $this->field_line='0'; + $this->where.= " c.fk_statut > 0"; // Not draft and not cancelled + } + //$this->where.= " AND c.fk_soc = s.rowid AND c.entity = ".$conf->entity; + $this->where.= " AND c.entity = ".$conf->entity; + if (!$user->rights->societe->client->voir && !$this->socid) $this->where .= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; + if ($this->socid) + { + $this->where.=" AND c.fk_soc = ".$this->socid; + } + if ($this->userid > 0) $this->where.=' AND c.fk_user_author = '.$this->userid; + } + + /** + * Return intervention number by month for a year + * + * @param int $year Year to scan + * @return array Array with number by month + */ + function getNbByMonth($year) + { + global $user; + + $sql = "SELECT date_format(c.date_valid,'%m') as dm, COUNT(*) as nb"; + $sql.= " FROM ".$this->from; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; + $sql.= " AND ".$this->where; + $sql.= " GROUP BY dm"; + $sql.= $this->db->order('dm','DESC'); + + $res=$this->_getNbByMonth($year, $sql); + return $res; + } + + /** + * Return interventions number per year + * + * @return array Array with number by year + * + */ + function getNbByYear() + { + global $user; + + $sql = "SELECT date_format(c.date_valid,'%Y') as dm, COUNT(*) as nb, 0"; + $sql.= " FROM ".$this->from; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE ".$this->where; + $sql.= " GROUP BY dm"; + $sql.= $this->db->order('dm','DESC'); + + return $this->_getNbByYear($sql); + } + + /** + * Return the intervention amount by month for a year + * + * @param int $year Year to scan + * @return array Array with amount by month + */ + function getAmountByMonth($year) + { + global $user; + + $sql = "SELECT date_format(c.date_valid,'%m') as dm, 0"; + $sql.= " FROM ".$this->from; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; + $sql.= " AND ".$this->where; + $sql.= " GROUP BY dm"; + $sql.= $this->db->order('dm','DESC'); + + $res=$this->_getAmountByMonth($year, $sql); + return $res; + } + + /** + * Return the intervention amount average by month for a year + * + * @param int $year year for stats + * @return array array with number by month + */ + function getAverageByMonth($year) + { + global $user; + + $sql = "SELECT date_format(c.date_valid,'%m') as dm, 0"; + $sql.= " FROM ".$this->from; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; + $sql.= " AND ".$this->where; + $sql.= " GROUP BY dm"; + $sql.= $this->db->order('dm','DESC'); + + return $this->_getAverageByMonth($year, $sql); + } + + /** + * Return nb, total and average + * + * @return array Array of values + */ + function getAllByYear() + { + global $user; + + $sql = "SELECT date_format(c.date_valid,'%Y') as year, COUNT(*) as nb, 0 as total, 0 as avg"; + $sql.= " FROM ".$this->from; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE ".$this->where; + $sql.= " GROUP BY year"; + $sql.= $this->db->order('year','DESC'); + + return $this->_getAllByYear($sql); + } + + /** + * Return nb, amount of predefined product for year + * + * @param int $year Year to scan + * @return array Array of values + */ + function getAllByProduct($year) + { + global $user; + + $sql = "SELECT product.ref, COUNT(product.ref) as nb, 0 as total, 0 as avg"; + $sql.= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product"; + //if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE ".$this->where; + $sql.= " AND c.rowid = tl.fk_fichinter AND tl.fk_product = product.rowid"; + $sql.= " AND c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year,1,false))."' AND '".$this->db->idate(dol_get_last_day($year,12,false))."'"; + $sql.= " GROUP BY product.ref"; + $sql.= $this->db->order('nb','DESC'); + //$sql.= $this->db->plimit(20); + + return $this->_getAllByProduct($sql); + } + +} + diff --git a/htdocs/fichinter/stats/index.php b/htdocs/fichinter/stats/index.php new file mode 100644 index 00000000000..5cdd7923cbd --- /dev/null +++ b/htdocs/fichinter/stats/index.php @@ -0,0 +1,337 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/fichinter/stats/index.php + * \ingroup fichinter + * \brief Page with interventions statistics + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinterstats.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + +$WIDTH=DolGraph::getDefaultGraphSizeForStats('width'); +$HEIGHT=DolGraph::getDefaultGraphSizeForStats('height'); + +$mode='customer'; +if ($mode == 'customer' && ! $user->rights->ficheinter->lire) accessforbidden(); + +$userid=GETPOST('userid','int'); +$socid=GETPOST('socid','int'); +// Security check +if ($user->societe_id > 0) +{ + $action = ''; + $socid = $user->societe_id; +} + +$nowyear=strftime("%Y", dol_now()); +$year = GETPOST('year')>0?GETPOST('year'):$nowyear; +//$startyear=$year-2; +$startyear=$year-1; +$endyear=$year; + +$langs->load('interventions'); +$langs->load('companies'); +$langs->load('other'); +$langs->load('suppliers'); + + +/* + * View + */ + +$form=new Form($db); + +if ($mode == 'customer') +{ + $title=$langs->trans("InterventionStatistics"); + $dir=$conf->ficheinter->dir_temp; +} + +llxHeader('', $title); + +print load_fiche_titre($title,'','title_commercial.png'); + +dol_mkdir($dir); + +$stats = new FichinterStats($db, $socid, $mode, ($userid>0?$userid:0)); + +// Build graphic number of object +$data = $stats->getNbByMonthWithPrevYear($endyear,$startyear); +//var_dump($data); +// $data = array(array('Lib',val1,val2,val3),...) + + +if (!$user->rights->societe->client->voir || $user->societe_id) +{ + $filenamenb = $dir.'/interventionsnbinyear-'.$user->id.'-'.$year.'.png'; + if ($mode == 'customer') $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsnbinyear-'.$user->id.'-'.$year.'.png'; +} +else +{ + $filenamenb = $dir.'/interventionsnbinyear-'.$year.'.png'; + if ($mode == 'customer') $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsnbinyear-'.$year.'.png'; +} + +$px1 = new DolGraph(); +$mesg = $px1->isGraphKo(); +if (! $mesg) +{ + $px1->SetData($data); + $px1->SetPrecisionY(0); + $i=$startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px1->SetLegend($legend); + $px1->SetMaxValue($px1->GetCeilMaxValue()); + $px1->SetMinValue(min(0,$px1->GetFloorMinValue())); + $px1->SetWidth($WIDTH); + $px1->SetHeight($HEIGHT); + $px1->SetYLabel($langs->trans("NbOfIntervention")); + $px1->SetShading(3); + $px1->SetHorizTickIncrement(1); + $px1->SetPrecisionY(0); + $px1->mode='depth'; + $px1->SetTitle($langs->trans("NumberOfInterventionsByMonth")); + + $px1->draw($filenamenb,$fileurlnb); +} + +// Build graphic amount of object +$data = $stats->getAmountByMonthWithPrevYear($endyear,$startyear); +//var_dump($data); +// $data = array(array('Lib',val1,val2,val3),...) + +if (!$user->rights->societe->client->voir || $user->societe_id) +{ + $filenameamount = $dir.'/interventionsamountinyear-'.$user->id.'-'.$year.'.png'; + if ($mode == 'customer') $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsamountinyear-'.$user->id.'-'.$year.'.png'; + if ($mode == 'supplier') $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstatssupplier&file=interventionsamountinyear-'.$user->id.'-'.$year.'.png'; +} +else +{ + $filenameamount = $dir.'/interventionsamountinyear-'.$year.'.png'; + if ($mode == 'customer') $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsamountinyear-'.$year.'.png'; + if ($mode == 'supplier') $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstatssupplier&file=interventionsamountinyear-'.$year.'.png'; +} + +$px2 = new DolGraph(); +$mesg = $px2->isGraphKo(); +if (! $mesg) +{ + $px2->SetData($data); + $i=$startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px2->SetLegend($legend); + $px2->SetMaxValue($px2->GetCeilMaxValue()); + $px2->SetMinValue(min(0,$px2->GetFloorMinValue())); + $px2->SetWidth($WIDTH); + $px2->SetHeight($HEIGHT); + $px2->SetYLabel($langs->trans("AmountOfinterventions")); + $px2->SetShading(3); + $px2->SetHorizTickIncrement(1); + $px2->SetPrecisionY(0); + $px2->mode='depth'; + $px2->SetTitle($langs->trans("AmountOfinterventionsByMonthHT")); + + $px2->draw($filenameamount,$fileurlamount); +} + + +$data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); + +if (!$user->rights->societe->client->voir || $user->societe_id) +{ + $filename_avg = $dir.'/interventionsaverage-'.$user->id.'-'.$year.'.png'; + if ($mode == 'customer') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsaverage-'.$user->id.'-'.$year.'.png'; + if ($mode == 'supplier') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstatssupplier&file=interventionsaverage-'.$user->id.'-'.$year.'.png'; +} +else +{ + $filename_avg = $dir.'/interventionsaverage-'.$year.'.png'; + if ($mode == 'customer') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsaverage-'.$year.'.png'; + if ($mode == 'supplier') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstatssupplier&file=interventionsaverage-'.$year.'.png'; +} + +$px3 = new DolGraph(); +$mesg = $px3->isGraphKo(); +if (! $mesg) +{ + $px3->SetData($data); + $i=$startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px3->SetLegend($legend); + $px3->SetYLabel($langs->trans("AmountAverage")); + $px3->SetMaxValue($px3->GetCeilMaxValue()); + $px3->SetMinValue($px3->GetFloorMinValue()); + $px3->SetWidth($WIDTH); + $px3->SetHeight($HEIGHT); + $px3->SetShading(3); + $px3->SetHorizTickIncrement(1); + $px3->SetPrecisionY(0); + $px3->mode='depth'; + $px3->SetTitle($langs->trans("AmountAverage")); + + $px3->draw($filename_avg,$fileurl_avg); +} + + + +// Show array +$data = $stats->getAllByYear(); +$arrayyears=array(); +foreach($data as $val) { + if (! empty($val['year'])) { + $arrayyears[$val['year']]=$val['year']; + } +} +if (! count($arrayyears)) $arrayyears[$nowyear]=$nowyear; + +$h=0; +$head = array(); +$head[$h][0] = DOL_URL_ROOT . '/commande/stats/index.php?mode='.$mode; +$head[$h][1] = $langs->trans("ByMonthYear"); +$head[$h][2] = 'byyear'; +$h++; + +if ($mode == 'customer') $type='order_stats'; +if ($mode == 'supplier') $type='supplier_order_stats'; + +complete_head_from_modules($conf,$langs,null,$head,$h,$type); + +dol_fiche_head($head,'byyear',$langs->trans("Statistics")); + + +print '
'; + + +//if (empty($socid)) +//{ + // Show filter box + print '
'; + print ''; + print ''; + print ''; + // Company + print ''; + // User + print ''; + print ''; + print '
'.$langs->trans("Filter").'
'.$langs->trans("ThirdParty").''; + if ($mode == 'customer') $filter='s.client in (1,2,3)'; + if ($mode == 'supplier') $filter='s.fournisseur = 1'; + print $form->select_company($socid,'socid',$filter,1,0,0,array(),0,'','style="width: 95%"'); + print '
'.$langs->trans("CreatedBy").''; + print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); + // Year + print '
'.$langs->trans("Year").''; + if (! in_array($year,$arrayyears)) $arrayyears[$year]=$year; + if (! in_array($nowyear,$arrayyears)) $arrayyears[$nowyear]=$nowyear; + arsort($arrayyears); + print $form->selectarray('year',$arrayyears,$year,0); + print '
'; + print '
'; + print '

'; +//} + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +$oldyear=0; +$var=true; +foreach ($data as $val) +{ + $year = $val['year']; + while (! empty($year) && $oldyear > $year+1) + { // If we have empty year + $oldyear--; + $var=!$var; + print ''; + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + + $var=!$var; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + $oldyear=$year; +} + +print '
'.$langs->trans("Year").''.$langs->trans("NbOfinterventions").'%'.$langs->trans("AmountTotal").'%'.$langs->trans("AmountAverage").'%
0?'&userid='.$userid:'').'">'.$oldyear.'000
0?'&userid='.$userid:'').'">'.$year.''.$val['nb'].''.round($val['nb_diff']).''.price(price2num($val['total'],'MT'),1).''.round($val['total_diff']).''.price(price2num($val['avg'],'MT'),1).''.round($val['avg_diff']).'
'; + + +print '
'; + + +// Show graphs +print '
'; +if ($mesg) { print $mesg; } +else { + print $px1->show(); + /*print "
\n"; + print $px2->show(); + print "
\n"; + print $px3->show();*/ +} +print '
'; + + +print '
'; +print '
'; + +dol_fiche_end(); + + +llxFooter(); + +$db->close(); diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 3b1fa498336..d7bd5d18696 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -954,12 +954,12 @@ if (empty($reshook)) $object->linked_objects = array_merge($object->linked_objects, $other_linked_objects); } - $object_id = $object->create($user); - if ($object_id > 0) + $id = $object->create($user); + if ($id > 0) { dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); - $classname = ucfirst($subelement); + $classname = 'SupplierProposal'; $srcobject = new $classname($db); dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); @@ -980,7 +980,7 @@ if (empty($reshook)) $num = count($lines); $productsupplier = new ProductFournisseur($db); - + for($i = 0; $i < $num; $i ++) { @@ -995,7 +995,7 @@ if (empty($reshook)) if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { $fk_parent_line = 0; } - + // Extrafields if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) // For avoid conflicts if // trigger used @@ -1003,10 +1003,13 @@ if (empty($reshook)) $lines[$i]->fetch_optionals($lines[$i]->rowid); $array_option = $lines[$i]->array_options; } - - $idprod = $productsupplier->find_min_price_product_fournisseur($lines[$i]->fk_product, $lines[$i]->qty); - $res = $productsupplier->fetch($idProductFourn); - + + $res = $productsupplier->find_min_price_product_fournisseur($lines[$i]->fk_product, $lines[$i]->qty); + /*if ($productsupplier->id > 0) + { + $res = $productsupplier->fetch($productsupplier->id); + }*/ + $result = $object->addline( $desc, $lines[$i]->subprice, @@ -1030,7 +1033,7 @@ if (empty($reshook)) ); if ($result < 0) { - $error ++; + $error++; break; } @@ -1040,10 +1043,13 @@ if (empty($reshook)) } } + // Add link between elements + + // Hooks $parameters = array('objFrom' => $srcobject); $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook + if ($reshook < 0) $error ++; } else { @@ -1459,7 +1465,7 @@ if ($action=='create') dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); - $classname = ucfirst($subelement); + $classname = 'SupplierProposal'; $objectsrc = new $classname($db); $objectsrc->fetch($originid); if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) @@ -1604,8 +1610,6 @@ if ($action=='create') print ''; $newclassname = $classname; - if ($newclassname == 'SupplierProposal') - $newclassname = 'CommercialSupplierProposal'; print '' . $langs->trans($newclassname) . '' . $objectsrc->getNomUrl(1) . ''; print '' . $langs->trans('TotalHT') . '' . price($objectsrc->total_ht) . ''; print '' . $langs->trans('TotalVAT') . '' . price($objectsrc->total_tva) . ""; @@ -1981,7 +1985,7 @@ elseif (! empty($object->id)) //print "$object->id, $object->socid, $object->fk_project"; if ($action == 'classify') { - $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)?$object->socid:'-1'), $object->fk_project, 'projectid', 0, 0, 1); + $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)?$object->socid:-1), $object->fk_project, 'projectid', 0, 0, 1); } else { @@ -2830,7 +2834,7 @@ elseif (! empty($object->id)) // Linked object block $somethingshown = $form->showLinkedObjectBlock($object); - + // Show links to link elements //$linktoelem = $form->showLinkToObjectBlock($object); //if ($linktoelem) print '
'.$linktoelem; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 2573b40baf4..ac630989ba0 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1470,7 +1470,7 @@ if ($action == 'create') $langs->load('projects'); print '' . $langs->trans('Project') . ''; - $formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)?$societe->id:'-1'), $projectid, 'projectid', 0); + $formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)?$societe->id:-1), $projectid, 'projectid', 0, 0, 1, 1); print ''; } @@ -2039,7 +2039,7 @@ else print ''; if ($action == 'classify') { - $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)?$object->socid:'-1'), $object->fk_project, 'projectid', 0, 0, 1); + $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)?$object->socid:-1), $object->fk_project, 'projectid', 0, 0, 1); } else { diff --git a/htdocs/includes/ckeditor/ckeditor/contents.css b/htdocs/includes/ckeditor/ckeditor/contents.css index 1d6a4becb8e..2e1895ee2ff 100644 --- a/htdocs/includes/ckeditor/ckeditor/contents.css +++ b/htdocs/includes/ckeditor/ckeditor/contents.css @@ -15,7 +15,7 @@ body /* Remove the background color to make it transparent */ background-color: #fff; - margin: 20px; + margin: 10px; } .cke_editable diff --git a/htdocs/index.php b/htdocs/index.php index 04e91b5110d..54b818954d4 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -294,7 +294,7 @@ if (empty($user->societe_id)) $text=$langs->trans($titres[$key]); print ''; print '
'; - print img_object("",$icons[$key]).' '.$text.'
'; + print ''.img_object("",$icons[$key]).' '.$text.'
'; print ''.$board->nb[$val].''; print '
'; print '
'; diff --git a/htdocs/install/mysql/tables/llx_propal.sql b/htdocs/install/mysql/tables/llx_propal.sql index 8090b1fcb4d..402b141761f 100644 --- a/htdocs/install/mysql/tables/llx_propal.sql +++ b/htdocs/install/mysql/tables/llx_propal.sql @@ -42,7 +42,7 @@ create table llx_propal fk_user_modif integer, -- user making last change fk_user_valid integer, -- user validating fk_user_cloture integer, -- user closing (signed or not) - fk_statut smallint DEFAULT 0 NOT NULL, + fk_statut smallint DEFAULT 0 NOT NULL, -- 0=draft, 1=validated, 2=accepted, 3=refused, 4=billed/closed price real DEFAULT 0, -- (obsolete) remise_percent real DEFAULT 0, -- remise globale relative en pourcent (obsolete) remise_absolue real DEFAULT 0, -- remise globale absolue (obsolete) diff --git a/htdocs/install/mysql/tables/llx_supplier_proposal.sql b/htdocs/install/mysql/tables/llx_supplier_proposal.sql index ef307b85c9f..e271d36ffe5 100644 --- a/htdocs/install/mysql/tables/llx_supplier_proposal.sql +++ b/htdocs/install/mysql/tables/llx_supplier_proposal.sql @@ -31,7 +31,7 @@ CREATE TABLE llx_supplier_proposal ( fk_user_modif integer DEFAULT NULL, fk_user_valid integer DEFAULT NULL, fk_user_cloture integer DEFAULT NULL, - fk_statut smallint NOT NULL DEFAULT '0', + fk_statut smallint NOT NULL DEFAULT '0', -- 0=draft, 1=validated, 2=accepted, 3=refused, 4=closed price double DEFAULT '0', remise_percent double DEFAULT '0', remise_absolue double DEFAULT '0', diff --git a/htdocs/install/mysql/tables/llx_website.key.sql b/htdocs/install/mysql/tables/llx_website.key.sql new file mode 100644 index 00000000000..cdaa38079b3 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_website.key.sql @@ -0,0 +1,23 @@ +-- ============================================================================ +-- Copyright (C) 2016 Laurent Destailleur +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- =========================================================================== + +ALTER TABLE llx_website_page ADD UNIQUE INDEX uk_website_page_url (fk_website,pageurl); + +ALTER TABLE llx_website_page ADD CONSTRAINT fk_website_page_website FOREIGN KEY (fk_website) REFERENCES llx_website (rowid); + + diff --git a/htdocs/install/mysql/tables/llx_website.sql b/htdocs/install/mysql/tables/llx_website.sql new file mode 100644 index 00000000000..e24a68b514b --- /dev/null +++ b/htdocs/install/mysql/tables/llx_website.sql @@ -0,0 +1,30 @@ +-- ======================================================================== +-- Copyright (C) 2016 Laurent Destailleur +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- ======================================================================== + + +CREATE TABLE llx_website +( + rowid integer AUTO_INCREMENT NOT NULL PRIMARY KEY, + entity integer, + shortname varchar(24) NOT NULL, + description varchar(255), + status integer, + date_creation datetime, + date_modification datetime, + tms timestamp +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_website_pages.key.sql b/htdocs/install/mysql/tables/llx_website_pages.key.sql new file mode 100644 index 00000000000..cdaa38079b3 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_website_pages.key.sql @@ -0,0 +1,23 @@ +-- ============================================================================ +-- Copyright (C) 2016 Laurent Destailleur +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- =========================================================================== + +ALTER TABLE llx_website_page ADD UNIQUE INDEX uk_website_page_url (fk_website,pageurl); + +ALTER TABLE llx_website_page ADD CONSTRAINT fk_website_page_website FOREIGN KEY (fk_website) REFERENCES llx_website (rowid); + + diff --git a/htdocs/install/mysql/tables/llx_website_pages.sql b/htdocs/install/mysql/tables/llx_website_pages.sql index 0a28153f5bf..379fa08582e 100644 --- a/htdocs/install/mysql/tables/llx_website_pages.sql +++ b/htdocs/install/mysql/tables/llx_website_pages.sql @@ -20,10 +20,14 @@ CREATE TABLE llx_website_page ( rowid integer AUTO_INCREMENT NOT NULL PRIMARY KEY, + fk_website integer, pageurl varchar(16) NOT NULL, title varchar(255), description varchar(255), keywords varchar(255), content text, + status integer, + date_creation datetime, + date_modification datetime, tms timestamp ) ENGINE=innodb; diff --git a/htdocs/langs/en_US/interventions.lang b/htdocs/langs/en_US/interventions.lang index 7e57d7da6a1..2d3a1d5a4a3 100644 --- a/htdocs/langs/en_US/interventions.lang +++ b/htdocs/langs/en_US/interventions.lang @@ -54,6 +54,9 @@ PacificNumRefModelDesc1=Return numero with format %syymm-nnnn where yy is year, PacificNumRefModelError=An intervention card starting with $syymm already exists and is not compatible with this model of sequence. Remove it or rename it to activate this module. PrintProductsOnFichinter=Print products on intervention card PrintProductsOnFichinterDetails=interventions generated from orders +InterventionStatistics=Statistics of interventions +NbOfinterventions=Nb of intervention cards +NumberOfInterventionsByMonth=Nb of intervention cards by month (date of validation) ##### Exports ##### InterId=Intervention id InterRef=Intervention ref. diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 7a23657123f..5990ee991d9 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -700,6 +700,7 @@ Test=Test Element=Element NoPhotoYet=No pictures available yet HomeDashboard=Home summary +Dashboard=Dashboard Deductible=Deductible from=from toward=toward diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index 5ed20ca738a..95d6b7fe55f 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -14,6 +14,7 @@ ProjectsPublicTaskDesc=This view presents all projects and tasks you are allowed ProjectsDesc=This view presents all projects (your user permissions grant you permission to view everything). MyTasksDesc=This view is limited to projects or tasks you are a contact for (whatever is the type). OnlyOpenedProject=Only open projects are visible (projects in draft or closed status are not visible). +ClosedProjectsAreHidden=Closed projects are not visible. TasksPublicDesc=This view presents all projects and tasks you are allowed to read. TasksDesc=This view presents all projects and tasks (your user permissions grant you permission to view everything). AllTaskVisibleButEditIfYouAreAssigned=All tasks for such project are visible, but you can enter time only for task you are assigned on. Assign task to you if you want to enter time on it. diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index f78ac37601c..15b10e7d92f 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -63,7 +63,8 @@ DatePropal=Date of proposal DateEndPropal=Validity ending date DateEndPropalShort=Date end ValidityDuration=Validity duration -CloseAs=Close with status +CloseAs=Set status to +SetAcceptedRefused=Set accepted/refused ClassifyBilled=Classify billed BuildBill=Build invoice ErrorPropalNotFound=Propal %s not found @@ -101,3 +102,4 @@ DefaultModelPropalCreate=Default model creation DefaultModelPropalToBill=Default template when closing a business proposal (to be invoiced) DefaultModelPropalClosed=Default template when closing a business proposal (unbilled) ProposalCustomerSignature=Written acceptance, company stamp, date and signature +ProposalsStatisticsSuppliers=Supplier proposals statistics \ No newline at end of file diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index ce9e36b83ce..6ecdb43ec51 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -98,7 +98,7 @@ function test_sql_and_script_inject($val, $type) $sql_inj += preg_match('/'; -// Add a new project/task -print '
'; -print '
'; -print ''; -print ''; -print ''; -print ''; -print ''; -print $langs->trans("AssignTaskToMe").'
'; -$formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1); -print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0); -print ''; -print '
'; - - llxFooter(); $db->close(); diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index cc31d1090f8..13bfa001630 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -100,8 +100,10 @@ if (GETPOST('submitdateselect')) $action = ''; } -if ($action == 'assign') +if ($action == 'addtime' && GETPOST('assigntask')) { + $action = 'assigntask'; + if ($taskid > 0) { $result = $object->fetch($taskid, $ref); @@ -298,7 +300,24 @@ print "\n"; */ -print '
'.$nav.'
'; +// Add a new project/task +//print '
'; +//print '
'; +//print ''; +//print ''; +//print ''; +//print ''; +//print ''; +print '
'; +print $langs->trans("AssignTaskToMe").'
'; +$formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1); +print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0); +print ''; +//print ''; +print '
'; + +print '
'.$nav.'
'; +print '
'; print ''; @@ -378,22 +397,6 @@ print "});"; print ''; -// Add a new project/task -print '
'; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print $langs->trans("AssignTaskToMe").'
'; -$formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1); -print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0); -print ''; -print ''; - - - llxFooter(); $db->close(); diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 2a64fa5d4c5..82eeb323a36 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2014 Laurent Destailleur + * Copyright (C) 2004-2016 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005 Marc Barilley / Ocebo * Copyright (C) 2005-2012 Regis Houssin @@ -45,6 +45,7 @@ $langs->load('companies'); $langs->load('supplier_proposal'); $langs->load('compta'); $langs->load('bills'); +$langs->load('propal'); $langs->load('orders'); $langs->load('products'); $langs->load("deliveries"); @@ -173,7 +174,7 @@ if (empty($reshook)) // Validation else if ($action == 'confirm_validate' && $confirm == 'yes' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->supplier_proposal->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->supplier_proposal->validate))) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->supplier_proposal->validate_advance))) ) { $result = $object->valid($user); @@ -434,6 +435,14 @@ if (empty($reshook)) } // Close proposal + else if ($action == 'close' && $user->rights->supplier_proposal->cloturer && ! GETPOST('cancel')) { + // prevent browser refresh from reopening proposal several times + if ($object->statut == 2) { + $object->setStatut(4); + } + } + + // Set accepted/refused else if ($action == 'setstatut' && $user->rights->supplier_proposal->cloturer && ! GETPOST('cancel')) { if (! GETPOST('statut')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), null, 'errors'); @@ -441,7 +450,7 @@ if (empty($reshook)) } else { // prevent browser refresh from closing proposal several times if ($object->statut == 1) { - $object->cloture($user, GETPOST('statut'), GETPOST('note')); + $object->cloture($user, GETPOST('statut'), GETPOST('note')); } } } @@ -1596,11 +1605,9 @@ if ($action == 'create') if ($action == 'statut') { - /* - * Form to close proposal (signed or not) - */ + // Form to set proposal accepted/refused $form_close = '
'; - $form_close .= '

'.$langs->trans('SupplierProposalRefFournNotice').'

'; + if (! empty($conf->global->SUPPLIER_PROPOSAL_UPDATE_PRICE_ON_SUPPlIER_PROPOSAL)) $form_close .= '

'.$langs->trans('SupplierProposalRefFournNotice').'

'; // TODO Suggest a permanent checkbox instead of option $form_close .= ''; $form_close .= '
'; $form_close .= ''; $form_close .= ''; $form_close .= '
' . $langs->trans("CloseAs") . ''; @@ -1615,9 +1622,9 @@ if ($action == 'create') $form_close .= $object->note; $form_close .= '
'; - $form_close .= ''; + $form_close .= ''; $form_close .= '   '; - $form_close .= ' '; + $form_close .= ' '; $form_close .= '
'; @@ -1640,7 +1647,7 @@ if ($action == 'create') // Validate if ($object->statut == 0 && $object->total_ttc >= 0 && count($object->lines) > 0 && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->supplier_proposal->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->supplier_proposal->validate))) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->supplier_proposal->validate_advance))) ) { if (count($object->lines) > 0) print ''; @@ -1660,7 +1667,7 @@ if ($action == 'create') // Send if ($object->statut == 1 || $object->statut == 2) { - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->supplier_proposal->send) { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->supplier_proposal->send_advance) { print ''; } else print ''; @@ -1673,12 +1680,18 @@ if ($action == 'create') } } - // Close + // Set accepted/refused if ($object->statut == 1 && $user->rights->supplier_proposal->cloturer) { - print ''; + print ''; } + // Close + if ($object->statut == 2 && $user->rights->supplier_proposal->cloturer) { + print ''; + } + // Clone if ($user->rights->supplier_proposal->creer) { print ''; diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 54a578a1e61..97f52526e66 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -27,7 +27,7 @@ */ /** - * \file htdocs/supplier_proposal/class/supplier_propal.class.php + * \file htdocs/supplier_proposal/class/supplier_proposal.class.php * \brief File of class to manage supplier proposals */ @@ -151,16 +151,16 @@ class SupplierProposal extends CommonObject $this->remise_absolue = 0; $langs->load("supplier_proposal"); - $this->labelstatut[0]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_DRAFT_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_DRAFT_LABEL : $langs->trans("SupplierProposalStatusDraft")); - $this->labelstatut[1]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_VALIDATED_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_VALIDATED_LABEL : $langs->trans("SupplierProposalStatusValidated")); - $this->labelstatut[2]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_SIGNED_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_SIGNED_LABEL : $langs->trans("SupplierProposalStatusSigned")); - $this->labelstatut[3]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_NOTSIGNED_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_NOTSIGNED_LABEL : $langs->trans("SupplierProposalStatusNotSigned")); - $this->labelstatut[4]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_BILLED_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_BILLED_LABEL : $langs->trans("SupplierProposalStatusBilled")); - $this->labelstatut_short[0]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_DRAFTSHORT_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_DRAFTSHORT_LABEL : $langs->trans("SupplierProposalStatusDraftShort")); - $this->labelstatut_short[1]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_VALIDATEDSHORT_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_VALIDATEDSHORT_LABEL : $langs->trans("Opened")); - $this->labelstatut_short[2]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_SIGNEDSHORT_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_SIGNEDSHORT_LABEL : $langs->trans("SupplierProposalStatusSignedShort")); - $this->labelstatut_short[3]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_NOTSIGNEDSHORT_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_NOTSIGNEDSHORT_LABEL : $langs->trans("SupplierProposalStatusNotSignedShort")); - $this->labelstatut_short[4]=(! empty($conf->global->SUPPLIER_PROPOSAL_STATUS_BILLEDSHORT_LABEL) ? $conf->global->SUPPLIER_PROPOSAL_STATUS_BILLEDSHORT_LABEL : $langs->trans("SupplierProposalStatusBilledShort")); + $this->labelstatut[0]=$langs->trans("SupplierProposalStatusDraft"); + $this->labelstatut[1]=$langs->trans("SupplierProposalStatusValidated"); + $this->labelstatut[2]=$langs->trans("SupplierProposalStatusSigned"); + $this->labelstatut[3]=$langs->trans("SupplierProposalStatusNotSigned"); + $this->labelstatut[4]=$langs->trans("SupplierProposalStatusClosed"); + $this->labelstatut_short[0]=$langs->trans("SupplierProposalStatusDraftShort"); + $this->labelstatut_short[1]=$langs->trans("Opened"); + $this->labelstatut_short[2]=$langs->trans("SupplierProposalStatusSignedShort"); + $this->labelstatut_short[3]=$langs->trans("SupplierProposalStatusNotSignedShort"); + $this->labelstatut_short[4]=$langs->trans("SupplierProposalStatusClosedShort"); } @@ -1257,7 +1257,7 @@ class SupplierProposal extends CommonObject $now=dol_now(); if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->supplier_proposal->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->supplier_proposal->validate))) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->supplier_proposal->validate_advance))) { $this->db->begin(); @@ -1545,7 +1545,7 @@ class SupplierProposal extends CommonObject $soc=new Societe($this->db); $soc->id = $this->socid; $result=$soc->set_as_client(); - + if ($result < 0) { $this->error=$this->db->error(); @@ -1554,14 +1554,17 @@ class SupplierProposal extends CommonObject } else { - $this->updateOrCreatePriceFournisseur($user); + if (! empty($conf->global->SUPPLIER_PROPOSAL_UPDATE_PRICE_ON_SUPPlIER_PROPOSAL)) // TODO This option was not tested correctly. Error if product ref does not exists + { + $result = $this->updateOrCreatePriceFournisseur($user); + } } } if ($statut == 4) { $trigger_name='SUPPLIER_PROPOSAL_CLASSIFY_BILLED'; } - + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { // Define output language @@ -1594,25 +1597,27 @@ class SupplierProposal extends CommonObject } else { - $this->error=$this->db->error(); + $this->error=$this->db->lasterror(); + $this->errors[]=$this->db->lasterror(); $this->db->rollback(); return -1; } } /** - * Choose between update or create ProductFournisseur + * Add or update supplier price according to result of proposal * - * @param User $user Object user + * @param User $user Object user + * @return int > 0 if OK */ function updateOrCreatePriceFournisseur($user) { $productsupplier = new ProductFournisseur($this->db); dol_syslog(get_class($this)."::updateOrCreatePriceFournisseur", LOG_DEBUG); - foreach ($this->lines as $product) { - if ($product->subprice <= 0) - continue; + foreach ($this->lines as $product) + { + if ($product->subprice <= 0) continue; $idProductFourn = $productsupplier->find_min_price_product_fournisseur($product->fk_product, $product->qty); $res = $productsupplier->fetch($idProductFourn); @@ -1627,6 +1632,8 @@ class SupplierProposal extends CommonObject $this->createPriceFournisseur($product, $user); } } + + return 1; } /** diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 82027cd613b..ccb3f01d293 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2547,6 +2547,10 @@ div.tabBar .noborder { background-color: #; } +span.boxstatstext { + opacity: 0.8; + line-height: 18px; +} span.boxstatsindicator { font-size: 110%; font-weight: normal; diff --git a/htdocs/theme/md/img/object_project.png b/htdocs/theme/md/img/object_project.png index 76139922af1..c873ff4f0dc 100644 Binary files a/htdocs/theme/md/img/object_project.png and b/htdocs/theme/md/img/object_project.png differ diff --git a/htdocs/theme/md/img/object_projectpub.png b/htdocs/theme/md/img/object_projectpub.png index 76139922af1..b16c55a1597 100644 Binary files a/htdocs/theme/md/img/object_projectpub.png and b/htdocs/theme/md/img/object_projectpub.png differ diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 29f2294bd54..782eb0d66a2 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2374,6 +2374,10 @@ div.tabBar .noborder { background-color: #; } +span.boxstatstext { + opacity: 0.8; + line-height: 18px; +} span.boxstatsindicator { font-size: 110%; font-weight: normal;