This commit is contained in:
Alexis Algoud 2016-12-14 14:34:12 +01:00
parent efc22a4cd8
commit a636d27ccb
8 changed files with 1433 additions and 124 deletions

View File

@ -1,5 +1,7 @@
<?php
/* Copyright (C) 2016 ATM Consulting <support@atm-consulting.fr>
/* EXPERIMENTAL
*
* Copyright (C) 2016 ATM Consulting <support@atm-consulting.fr>
*
* 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
@ -220,9 +222,8 @@ class CoreObject extends CommonObject {
WHERE rowid='.$id;
$res = $this->db->query( $sql );
if($obj = $this->db->fetch_object($res)) {
$this->rowid=$id;
$this->id=$id;
$this->set_vars_by_db($obj);
@ -248,12 +249,12 @@ class CoreObject extends CommonObject {
$this->{$className}=array();
$sql = " SELECT rowid FROM ".MAIN_DB_PREFIX.$childTable." WHERE ".$this->fk_element."=".$this->rowid;
$sql = " SELECT rowid FROM ".MAIN_DB_PREFIX.$childTable." WHERE ".$this->fk_element."=".$this->id;
$res = $this->db->query($sql);
if($res) {
while($obj = $db->fetch_object($res)) {
$Tab=array();
while($obj = $this->db->fetch_object($res)) {
$o=new $className($this->db);
$o->fetch($obj->rowid);
@ -282,5 +283,14 @@ class CoreObject extends CommonObject {
}
public function get_date($field,$format='') {
if(empty($this->{$field})) return '';
elseif($this->{$field}<=strtotime('1000-01-01 00:00:00')) return '';
else {
return dol_print_date($this->{$field}, $format);
}
}
}

View File

@ -1,7 +1,8 @@
<?php
/*
EXPERIMENTAL
Copyright (C) 2013-2015 ATM Consulting <support@atm-consulting.fr>
Copyright (C) 2016 ATM Consulting <support@atm-consulting.fr>
This program and all files within this directory and sub directory
is free software: you can redistribute it and/or modify it under
@ -505,88 +506,91 @@ class Listview {
}
private function renderList(&$THeader, &$TField, &$TTotal,&$TTotalGroup, &$TParam) {
$javaScript = $this->getJS($TParam);
$TPagination=array(
/*$TPagination=array(
'pagination'=>array('pageSize'=>$TParam['limit']['nbLine'], 'pageNum'=>$TParam['limit']['page'], 'blockName'=>'champs', 'totalNB'=>count($TField))
);
);*/
$TSearch = $this->setSearch($THeader, $TParam);
$TExport=$this->setExport($TParam, $TField, $THeader);
$TField = $this->addTotalGroup($TField,$TTotalGroup);
$out = $javaScript;
$out.=load_fiche_titre($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $TParam['limit']['page'], count($TField), 'title_products.png', 0, '', '', $limit);
$out.='<table id="'.$this->id.'" class="liste" width="100%">
<thead>';
$out.=load_fiche_titre($TParam['list']['title']);
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, count($TField), 'title_products.png', 0, '', '', $limit);
/*
$out.='<table width="100%" border="0" class="notopnoleftnoright" style="margin-bottom: 2px;">
<tr>
[onshow;block=begin; when [liste.noheader]==0]
<td class="nobordernopadding" width="40" align="left" valign="middle">
[liste.image;magnet=img; strconv=no]
</td>
<td class="nobordernopadding"><div class="titre">[liste.titre; strconv=no]</div></td>
[onshow;block=end]
<td class="nobordernopadding" align="right" valign="middle">
<div class="pagination">
[onshow;block=div; when [liste.havePage]+-0 ]
<!-- [onshow;block=div;when [pagination.last]+-1 ] -->
<ul style="display: inline-block; list-style: outside none none;">
<li class="pagination" style="display: inline-block;"><a class="paginationprevious" href="javascript:TListTBS_GoToPage('[liste.id]',[pagination.prev])"><!-- [pagination.prev;endpoint;magnet=li] --> [liste.picto_precedent;strconv=no] </a></li>
<li class="pagination" style="display: inline-block;"><a class="page" href="javascript:TListTBS_GoToPage('[liste.id]',[pagination.page;navsize=15;navpos=centred])"> [pagination.page;block=li] </a></li>
<li class="pagination" style="display: inline-block;"><span class="active"> [pagination.page;block=li;currpage] </span></li>
<li class="pagination" style="display: inline-block;"><a class="paginationnext" href="javascript:TListTBS_GoToPage('[liste.id]',[pagination.next])"><!-- [pagination.last;endpoint;magnet=li] --> [liste.picto_suivant;strconv=no] </a></li>
</ul>
</div>
</td>
</tr>
</table>
if(!empty($TParam['liste']['head_search'])) {
$out.='<tr class="liste_titre barre-recherche-head">
<td colspan="'.$TParam['liste']['nb_columns'].'">'.$TParam['liste']['head_search'].'</td>
</tr>';
}
$out.='<tr class="liste_titre">';
<table id="[liste.id]" class="liste" width="100%">
<thead>
<tr class="liste_titre barre-recherche-head">
<td colspan="[liste.nb_columns]">[liste.head_search;strconv=no;magnet=tr]</td>
</tr>
<tr class="liste_titre">
<th style="width:[entete.width;];text-align:[entete.text-align]" class="liste_titre">[entete.libelle;block=th;strconv=no]
<span class="nowrap">[onshow;block=span; when [entete.order]==1]<a href="javascript:TListTBS_OrderDown('[liste.id]','[entete.$;strconv=js]')">[liste.order_down;strconv=no]</a><a href="javascript:TListTBS_OrderUp('[liste.id]', '[entete.$;strconv=js]')">[liste.order_up;strconv=no]</a></span>
[entete.more;strconv=no;]
</th>
</tr>
foreach($THeader as $head) {
$out.='<th style="width:'.$head['width'].';text-align:'.$head['text-align'].'" class="liste_titre">'.$head['libelle'];
if($head['order']) $out.='<span class="nowrap">[onshow;block=span; when [entete.order]==1]<a href="javascript:Listview_OrderDown(\'[liste.id]\',\'[entete.$;strconv=js]\')">'.img_down().'</a>
<a href="javascript:Listview_OrderUp(\'[liste.id]\', \'[entete.$;strconv=js]\')">'.img_up().'</a></span>';
$out.=$head['more'];
$out.='</th>';
}
$out.='</tr>';
if(!empty($TParam['liste']['nbSearch'])) {
$out.='<tr class="liste_titre barre-recherche">
<td class="liste_titre">'.img_search().'</td>
</tr>';
}
<tr class="liste_titre barre-recherche">[onshow;block=tr;when [liste.nbSearch]+-0]
<td class="liste_titre">[recherche.val;block=td;strconv=no]</td>
</tr>
</thead>
<tbody>
<tr class="impair">
<!-- [champs.$;block=tr;sub1] -->
<td field="[champs_sub1.$]">[champs_sub1.val;block=td; strconv=no]</td>
</tr>
<tr class="pair">
<!-- [champs.$;block=tr;sub1] -->
<td field="[champs_sub1.$]">[champs_sub1.val;block=td; strconv=no]</td>
</tr>
</tbody>
<tfoot>
<tr class="liste_total">
[onshow;block=tr; when [liste.haveTotal]+-0 ]
<td align="right" field="[total.$]">[total.val;block=td;strconv=no;frm=0 000,00]</td>
</tr>
</tfoot>
</table>
$out.='</thead><tbody>';
<div class="tabsAction">
[onshow;block=div; when [liste.haveExport]+-0 ]
<a href="javascript:;" onclick="TListTBS_downloadAs(this, '[export.mode]','[export.url]','[export.token]','[export.session_name]');" class="butAction">[export.label;block=a;]</a>
</div>
<p align="center">
[liste.messageNothing;strconv=no] [onshow; block=p; when [liste.totalNB]==0]
</p>';*/
$class='pair';
if(empty($TField)) {
$out.='<tr class="'.$class.'">
<td colspan="'.$TParam['liste']['nb_columns'].'">'.$TParam['liste']['messageNothing'].'</td></tr>';
}
else{
foreach($TField as $fields) { //TODO pagination limit
$class = ($class=='pair') ? 'impair' : 'pair';
$out.='<tr class="'.$class.'"> <!-- '.$field.' -->';
foreach($fields as $field=>$value) {
$out.='<td field="'.$field.'">'.$value.'</td>';
}
$out.='</tr>';
}
$out.='</tbody>';
if(!empty($TParam['liste']['haveTotal'])) {
$out.='<tfoot>
<tr class="liste_total">';
foreach($TTotal as $field=>$total) {
$out.='<td align="right" field="'.$field.'">'.price($total).'</td>';
}
$out.='</tr></tfoot>';
}
}
$out.='</table>';
return $out;
}
public function renderArray(&$db,$TField, $TParam=array()) {

View File

@ -3157,7 +3157,7 @@ function load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png',
}
/**
* Print a title with navigation controls for pagination
* return a title with navigation controls for pagination
*
* @param string $titre Title to show (required)
* @param int $page Numero of page to show in navigation links (required)
@ -3176,7 +3176,7 @@ function load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png',
* @param int $hideselectlimit Force to hide select limit
* @return void
*/
function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $center='', $num=-1, $totalnboflines=-1, $picto='title_generic.png', $pictoisfullpath=0, $morehtml='', $morecss='', $limit=-1, $hideselectlimit=0)
function load_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $center='', $num=-1, $totalnboflines=-1, $picto='title_generic.png', $pictoisfullpath=0, $morehtml='', $morecss='', $limit=-1, $hideselectlimit=0)
{
global $conf,$langs;
@ -3196,27 +3196,26 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so
$nextpage = 0;
}
//print 'totalnboflines='.$totalnboflines.'-savlimit='.$savlimit.'-limit='.$limit.'-num='.$num.'-nextpage='.$nextpage;
print "\n";
print "<!-- Begin title '".$titre."' -->\n";
print '<table width="100%" border="0" class="notopnoleftnoright'.($morecss?' '.$morecss:'').'" style="margin-bottom: 6px;"><tr>';
$out = "\n";
$out.= "<!-- Begin title '".$titre."' -->\n";
$out.='<table width="100%" border="0" class="notopnoleftnoright'.($morecss?' '.$morecss:'').'" style="margin-bottom: 6px;"><tr>';
// Left
//if ($picto && $titre) print '<td class="nobordernopadding hideonsmartphone" width="40" align="left" valign="middle">'.img_picto('', $picto, 'id="pictotitle"', $pictoisfullpath).'</td>';
print '<td class="nobordernopadding valignmiddle">';
if ($picto && $titre) print img_picto('', $picto, 'class="hideonsmartphone valignmiddle" id="pictotitle"', $pictoisfullpath);
print '<div class="titre inline-block">'.$titre;
if (!empty($titre) && $savtotalnboflines >= 0) print ' ('.$totalnboflines.')';
print '</div></td>';
//if ($picto && $titre) $out.='<td class="nobordernopadding hideonsmartphone" width="40" align="left" valign="middle">'.img_picto('', $picto, 'id="pictotitle"', $pictoisfullpath).'</td>';
$out.='<td class="nobordernopadding valignmiddle">';
if ($picto && $titre) $out.=img_picto('', $picto, 'class="hideonsmartphone valignmiddle" id="pictotitle"', $pictoisfullpath);
$out.='<div class="titre inline-block">'.$titre;
if (!empty($titre) && $savtotalnboflines >= 0) $out.=' ('.$totalnboflines.')';
$out.='</div></td>';
// Center
if ($center)
{
print '<td class="nobordernopadding center valignmiddle">'.$center.'</td>';
$out.='<td class="nobordernopadding center valignmiddle">'.$center.'</td>';
}
// Right
print '<td class="nobordernopadding valignmiddle" align="right">';
$out.='<td class="nobordernopadding valignmiddle" align="right">';
if ($sortfield) $options .= "&amp;sortfield=".$sortfield;
if ($sortorder) $options .= "&amp;sortorder=".$sortorder;
// Show navigation bar
@ -3265,15 +3264,39 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so
$pagelist.= '<li'.(($conf->dol_use_jmobile != 4)?' class="pagination"':'').'><span '.(($conf->dol_use_jmobile != 4)?'class="active"':'data-role="button"').'>'.($page+1)."</li>";
}
}
print_fleche_navigation($page, $file, $options, $nextpage, $pagelist, $morehtml, $savlimit, $totalnboflines, $hideselectlimit); // output the div and ul for previous/last completed with page numbers into $pagelist
print '</td>';
$out.=load_fleche_navigation($page, $file, $options, $nextpage, $pagelist, $morehtml, $savlimit, $totalnboflines, $hideselectlimit); // output the div and ul for previous/last completed with page numbers into $pagelist
$out.='</td>';
print '</tr></table>'."\n";
print "<!-- End title -->\n\n";
$out.='</tr></table>'."\n";
$out.="<!-- End title -->\n\n";
}
/**
* Print a title with navigation controls for pagination
*
* @param string $titre Title to show (required)
* @param int $page Numero of page to show in navigation links (required)
* @param string $file Url of page (required)
* @param string $options More parameters for links ('' by default, does not include sortfield neither sortorder)
* @param string $sortfield Field to sort on ('' by default)
* @param string $sortorder Order to sort ('' by default)
* @param string $center String in the middle ('' by default). We often find here string $massaction comming from $form->selectMassAction()
* @param int $num Number of records found by select with limit+1
* @param int $totalnboflines Total number of records/lines for all pages (if known). Use a negative value to not show number.
* @param string $picto Icon to use before title (should be a 32x32 transparent png file)
* @param int $pictoisfullpath 1=Icon name is a full absolute url of image
* @param string $morehtml More html to show
* @param string $morecss More css to the table
* @param int $limit Max number of lines (-1 = use default, 0 = no limit, > 0 = limit).
* @param int $hideselectlimit Force to hide select limit
* @return void
*/
function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $center='', $num=-1, $totalnboflines=-1, $picto='title_generic.png', $pictoisfullpath=0, $morehtml='', $morecss='', $limit=-1, $hideselectlimit=0)
{
echo load_barre_liste($titre, $page, $file, $options, $sortfield, $sortorder, $center, $num, $totalnboflines, $picto, $pictoisfullpath, $morehtml, $morecss, $limit, $hideselectlimit);
}
/**
* Function to show navigation arrows into lists
* Function to return navigation arrows into lists
*
* @param int $page Number of page
* @param string $file Page URL (in most cases provided with $_SERVER["PHP_SELF"])
@ -3286,11 +3309,11 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so
* @param int $hideselectlimit Force to hide select limit
* @return void
*/
function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betweenarrows='', $afterarrows='', $limit=-1, $totalnboflines=0, $hideselectlimit=0)
function load_fleche_navigation($page, $file, $options='', $nextpage=0, $betweenarrows='', $afterarrows='', $limit=-1, $totalnboflines=0, $hideselectlimit=0)
{
global $conf, $langs;
print '<div class="pagination"><ul>';
$out='<div class="pagination"><ul>';
if ((int) $limit >= 0 && empty($hideselectlimit))
{
$pagesizechoices='10:10,20:20,30:30,40:40,50:50,100:100,250:250,500:500,1000:1000,5000:5000';
@ -3298,8 +3321,8 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee
//$pagesizechoices.=',2:2';
if (! empty($conf->global->MAIN_PAGESIZE_CHOICES)) $pagesizechoices=$conf->global->MAIN_PAGESIZE_CHOICES;
print '<li class="pagination">';
print '<select class="flat selectlimit" name="limit">';
$out.='<li class="pagination">';
$out.='<select class="flat selectlimit" name="limit">';
$tmpchoice=explode(',',$pagesizechoices);
$tmpkey=$limit.':'.$limit;
if (! in_array($tmpkey, $tmpchoice)) $tmpchoice[]=$tmpkey;
@ -3320,13 +3343,13 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee
$selected = ' selected="selected"';
$found = true;
}
print '<option name="'.$key.'"'.$selected.'>'.dol_escape_htmltag($val).'</option>'."\n";
$out.='<option name="'.$key.'"'.$selected.'>'.dol_escape_htmltag($val).'</option>'."\n";
}
}
print '</select>';
$out.='</select>';
if ($conf->use_javascript_ajax)
{
print '<!-- JS CODE TO ENABLE select limit to launch submit of page -->
$out.='<!-- JS CODE TO ENABLE select limit to launch submit of page -->
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery(".selectlimit").change(function() {
@ -3337,31 +3360,48 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee
</script>
';
}
print '</li>';
$out.='</li>';
}
if ($page > 0)
{
if (($conf->dol_use_jmobile != 4)) print '<li class="pagination"><a class="paginationprevious" href="'.$file.'?page='.($page-1).$options.'"><</a></li>';
else print '<li><a data-role="button" data-icon="arrow-l" data-iconpos="left" href="'.$file.'?page='.($page-1).$options.'">'.$langs->trans("Previous").'</a></li>';
if (($conf->dol_use_jmobile != 4)) $out.='<li class="pagination"><a class="paginationprevious" href="'.$file.'?page='.($page-1).$options.'"><</a></li>';
else $out.='<li><a data-role="button" data-icon="arrow-l" data-iconpos="left" href="'.$file.'?page='.($page-1).$options.'">'.$langs->trans("Previous").'</a></li>';
}
if ($betweenarrows)
{
print $betweenarrows;
$out.=$betweenarrows;
}
if ($nextpage > 0)
{
if (($conf->dol_use_jmobile != 4)) print '<li class="pagination"><a class="paginationnext" href="'.$file.'?page='.($page+1).$options.'">></a></li>';
else print '<li><a data-role="button" data-icon="arrow-r" data-iconpos="right" href="'.$file.'?page='.($page+1).$options.'">'.$langs->trans("Next").'</a></li>';
if (($conf->dol_use_jmobile != 4)) $out.='<li class="pagination"><a class="paginationnext" href="'.$file.'?page='.($page+1).$options.'">></a></li>';
else $out.='<li><a data-role="button" data-icon="arrow-r" data-iconpos="right" href="'.$file.'?page='.($page+1).$options.'">'.$langs->trans("Next").'</a></li>';
}
if ($afterarrows)
{
print '<li class="paginationafterarrows">';
print $afterarrows;
print '</li>';
$out.='<li class="paginationafterarrows">';
$out.=$afterarrows;
$out.='</li>';
}
print '</ul></div>'."\n";
$out.='</ul></div>'."\n";
}
/**
* Function to show navigation arrows into lists
*
* @param int $page Number of page
* @param string $file Page URL (in most cases provided with $_SERVER["PHP_SELF"])
* @param string $options Other url paramaters to propagate ("" by default, may include sortfield and sortorder)
* @param integer $nextpage Do we show a next page button
* @param string $betweenarrows HTML content to show between arrows. MUST contains '<li> </li>' tags or '<li><span> </span></li>'.
* @param string $afterarrows HTML content to show after arrows. Must NOT contains '<li> </li>' tags.
* @param int $limit Max nb of record to show (-1 = no combo with limit, 0 = no limit, > 0 = limit)
* @param int $totalnboflines Total number of records/lines for all pages (if known)
* @param int $hideselectlimit Force to hide select limit
* @return void
*/
function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betweenarrows='', $afterarrows='', $limit=-1, $totalnboflines=0, $hideselectlimit=0)
{
echo load_fleche_navigation($page, $file, $options, $nextpage, $betweenarrows, $afterarrows, $limit, $totalnboflines, $hideselectlimit);
}
/**
* Return a string with VAT rate label formated for view output

View File

@ -97,17 +97,20 @@ class Inventory extends CoreObject
if(!$annexe) $this->withChild = false;
$res = parent::fetch($id);
$this->sort_det();
$this->amount = 0;
if(!empty($this->Inventorydet )) {
foreach($this->Inventorydet as &$det){
$this->amount+=$det->qty_view * $det->pmp;
}
if($res>0) {
$this->sort_det();
$this->amount = 0;
if(!empty($this->Inventorydet )) {
foreach($this->Inventorydet as &$det){
$this->amount+=$det->qty_view * $det->pmp;
}
}
}
return $res;
}
@ -312,9 +315,8 @@ class Inventory extends CoreObject
global $langs,$db;
$i = new Inventory($db);
$i->fetch($id, false);
return $i->getNomUrl();
if($i->fetch($id, false)>0) return $i->getNomUrl();
else return $langs->trans('InventoryUnableToFetchObject');
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,797 @@
<?php
/* Copyright (C) 2016 ATM Consulting <support@atm-consulting.fr>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/inventory/inventory.php
* \ingroup product
* \brief File of class to manage inventory
*/
require_once '../main.inc.php';
ini_set('memory_limit', '512M');
require_once DOL_DOCUMENT_ROOT.'/core/class/listview.class.php';
require_once DOL_DOCUMENT_ROOT.'/inventory/class/inventory.class.php';
require_once DOL_DOCUMENT_ROOT.'/inventory/lib/inventory.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
set_time_limit(0);
if(!$user->rights->inventory->read) accessforbidden();
$langs->load("inventory");
_action();
function _action()
{
global $user, $db, $conf, $langs;
/*******************************************************************
* ACTIONS
*
* Put here all code to do according to value of "action" parameter
********************************************************************/
$action=GETPOST('action');
switch($action) {
case 'list':
_list();
break;
case 'create':
if (!$user->rights->inventory->create) accessforbidden();
$inventory = new Inventory($db);
_fiche_warehouse($user, $db, $conf, $langs, $inventory);
break;
case 'confirmCreate':
if (!$user->rights->inventory->create) accessforbidden();
$inventory = new Inventory($db);
$inventory->set_values($_REQUEST);
$fk_inventory = $inventory->save();
$fk_category = (int)GETPOST('fk_category');
$fk_supplier = (int)GETPOST('fk_supplier');
$fk_warehouse = (int)GETPOST('fk_warehouse');
$only_prods_in_stock = (int)GETPOST('OnlyProdsInStock');
$e = new Entrepot($db);
$e->fetch($fk_warehouse);
$TChildWarehouses = array($fk_warehouse);
if(method_exists($e, 'get_children_warehouses')) $e->get_children_warehouses($fk_warehouse, $TChildWarehouses);
$sql = 'SELECT ps.fk_product, ps.fk_entrepot
FROM '.MAIN_DB_PREFIX.'product_stock ps
INNER JOIN '.MAIN_DB_PREFIX.'product p ON (p.rowid = ps.fk_product)
LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product cp ON (cp.fk_product = p.rowid)
LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price pfp ON (pfp.fk_product = p.rowid)
WHERE ps.fk_entrepot IN ('.implode(', ', $TChildWarehouses).')';
if($fk_category>0) $sql.= " AND cp.fk_categorie=".$fk_category;
if($fk_supplier>0) $sql.= " AND pfp.fk_soc=".$fk_supplier;
if($only_prods_in_stock>0) $sql.= ' AND ps.reel > 0';
$sql.=' GROUP BY ps.fk_product, ps.fk_entrepot
ORDER BY p.ref ASC,p.label ASC';
$Tab = $PDOdb->ExecuteAsArray($sql);
foreach($Tab as &$row) {
$inventory->add_product($PDOdb, $row->fk_product, $row->fk_entrepot);
}
$inventory->save($PDOdb);
header('Location: '.dol_buildpath('inventory/inventory.php?id='.$inventory->getId().'&action=edit', 1));
case 'edit':
if (!$user->rights->inventory->write) accessforbidden();
$id = __get('id', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
_fiche($PDOdb, $user, $db, $conf, $langs, $inventory, __get('action', 'edit', 'string'));
break;
case 'save':
if (!$user->rights->inventory->write) accessforbidden();
$id = __get('id', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
$inventory->set_values($_REQUEST);
if ($inventory->errors)
{
setEventMessage($inventory->errors, 'errors');
_fiche($PDOdb, $user, $db, $conf, $langs, $inventory, 'edit');
}
else
{
$inventory->save($PDOdb);
header('Location: '.dol_buildpath('inventory/inventory.php?id='.$inventory->getId().'&action=view', 1));
}
break;
case 'regulate':
$id = __get('id', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
if($inventory->status == 0) {
$inventory->status = 1;
$inventory->save($PDOdb);
_fiche($PDOdb, $user, $db, $conf, $langs, $inventory, 'view');
}
else {
_fiche($PDOdb, $user, $db, $conf, $langs, $inventory, 'view');
}
break;
case 'changePMP':
$id = __get('id', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
$inventory->changePMP($PDOdb);
_fiche($PDOdb, $user, $db, $conf, $langs, $inventory, 'view');
break;
case 'add_line':
if (!$user->rights->inventory->write) accessforbidden();
$id = __get('id', 0, 'int');
$fk_warehouse = __get('fk_warehouse', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
$type = (!empty($conf->use_javascript_ajax) && !empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT) ? 'string' : 'int'); //AA heu ?
$fk_product = __get('fk_product', 0, $type);
if ($fk_product)
{
$product = new Product($db);
$product->fetch($fk_product); // ! ref TODO vérifier quand même
if($product->type != 0) {
setEventMessage($langs->trans('ThisIsNotAProduct'),'errors');
}
else{
//Check product not already exists
$alreadyExists = false;
foreach ($inventory->Inventorydet as $invdet)
{
if ($invdet->fk_product == $product->id
&& $invdet->fk_warehouse == $fk_warehouse)
{
$alreadyExists = true;
break;
}
}
if (!$alreadyExists)
{
$inventory->add_product($PDOdb, $product->id, $fk_warehouse);
}
else
{
setEventMessage($langs->trans('inventoryWarningProductAlreadyExists'), 'warnings');
}
}
$inventory->save($PDOdb);
$inventory->sort_det();
}
_fiche($PDOdb, $user, $db, $conf, $langs, $inventory, 'edit');
break;
case 'delete_line':
if (!$user->rights->inventory->write) accessforbidden();
//Cette action devrais se faire uniquement si le status de l'inventaire est à 0 mais aucune vérif
$rowid = __get('rowid', 0, 'int');
$Inventorydet = new Inventory($db);
$Inventorydet->load($PDOdb, $rowid);
$Inventorydet->delete($PDOdb);
$id = __get('id', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
_fiche($PDOdb, $user, $db, $conf, $langs, $inventory, 'edit');
break;
case 'flush':
if (!$user->rights->inventory->create) accessforbidden();
$id = __get('id', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
$inventory->deleteAllLine($PDOdb);
setEventMessage('Inventaire vidé');
_fiche($PDOdb, $user, $db, $conf, $langs, $inventory, 'edit');
break;
case 'delete':
if (!$user->rights->inventory->create) accessforbidden();
$id = __get('id', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
$inventory->delete($PDOdb);
header('Location: '.dol_buildpath('/inventory/inventory.php', 1));
exit;
//_list();
case 'printDoc':
$id = __get('id', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
generateODT($PDOdb, $db, $conf, $langs, $inventory);
break;
case 'exportCSV':
$id = __get('id', 0, 'int');
$inventory = new Inventory($db);
$inventory->load($PDOdb, $id);
exportCSV($inventory);
exit;
break;
default:
if (!$user->rights->inventory->write) accessforbidden();
$id = GETPOST('id');
$inventory = new Inventory($db);
$inventory->fetch($id);
_card($inventory, $action );
break;
}
}
function _list()
{
global $db, $conf, $langs, $user;
llxHeader('',$langs->trans('inventoryListTitle'),'','');
$inventory = new Inventory($db);
$l = new ListView($db,'listInventory');
$THide = array('label');
echo $l->render(Inventory::getSQL('All'), array(
'limit'=>array(
'nbLine'=>'30'
)
,'subQuery'=>array()
,'link'=>array(
'fk_warehouse'=>'<a href="'.DOL_URL_ROOT.'/product/stock/card.php?id=@val@">'.img_picto('','object_stock.png','',0).' @label@</a>'
)
,'translate'=>array()
,'hide'=>$THide
,'type'=>array(
'date_cre'=>'date'
,'date_maj'=>'datetime'
,'date_inventory'=>'date'
)
,'liste'=>array(
'titre'=>$langs->trans('inventoryListTitle')
,'image'=>img_picto('','title.png', '', 0)
,'picto_precedent'=>img_picto('','back.png', '', 0)
,'picto_suivant'=>img_picto('','next.png', '', 0)
,'noheader'=> (int)isset($_REQUEST['fk_soc']) | (int)isset($_REQUEST['fk_product'])
,'messageNothing'=>$langs->trans('inventoryListEmpty')
,'picto_search'=>img_picto('','search.png', '', 0)
)
,'title'=>array(
'rowid'=>$langs->trans('Title')
,'fk_warehouse'=>$langs->trans('Warehouse')
,'date_inventory'=>$langs->trans('InventoryDate')
,'datec'=>$langs->trans('DateCreation')
,'tms'=>$langs->trans('DateUpdate')
,'status'=>$langs->trans('Status')
)
,'eval'=>array(
'status' => '(@val@ ? img_picto("'.$langs->trans("inventoryValidate").'", "statut4") : img_picto("'.$langs->trans("inventoryDraft").'", "statut3"))'
,'rowid'=>'Inventory::getLink(@val@)'
)
));
if ($user->rights->inventory->create)
{
print '<div class="tabsAction">';
print '<a class="butAction" href="inventory.php?action=create">'.$langs->trans('inventoryCreate').'</a>';
print '</div>';
}
llxFooter('');
}
function _fiche_warehouse(&$PDOdb, &$user, &$db, &$conf, $langs, $inventory)
{
dol_include_once('/categories/class/categorie.class.php');
llxHeader('',$langs->trans('inventorySelectWarehouse'),'','');
print dol_get_fiche_head(inventoryPrepareHead($inventory));
$form=new TFormCore('inventory.php', 'confirmCreate');
print $form->hidden('action', 'confirmCreate');
$form->Set_typeaff('edit');
$formproduct = new FormProduct($db);
$formDoli = new Form($db);
?>
<table class="border" width="100%" >
<tr>
<td><?php echo $langs->trans('Title') ?></td>
<td><?php echo $form->texte('', 'title', '',50,255) ?></td>
</tr>
<tr>
<td><?php echo $langs->trans('Date') ?></td>
<td><?php echo $form->calendrier('', 'date_inventory',time()) ?></td>
</tr>
<tr>
<td><?php echo $langs->trans('inventorySelectWarehouse') ?></td>
<td><?php echo $formproduct->selectWarehouses('', 'fk_warehouse') ?></td>
</tr>
<tr>
<td><?php echo $langs->trans('SelectCategory') ?></td>
<td><?php echo $formDoli->select_all_categories(0,'', 'fk_category') ?></td>
</tr>
<tr>
<td><?php echo $langs->trans('SelectFournisseur') ?></td>
<td><?php echo $formDoli->select_thirdparty('','fk_supplier','s.fournisseur = 1') ?></td>
</tr>
<tr>
<td><?php echo $langs->trans('OnlyProdsInStock') ?></td>
<td><input type="checkbox" name="OnlyProdsInStock" value="1"></td>
</tr>
</table>
<?php
print '<div class="tabsAction">';
print '<input type="submit" class="butAction" value="'.$langs->trans('inventoryConfirmCreate').'" />';
print '</div>';
print $form->end_form();
llxFooter('');
}
function _card(&$inventory, $mode='edit')
{
global $langs, $conf, $db, $user;
llxHeader('',$langs->trans('inventoryEdit'),'','');
$warehouse = new Entrepot($db);
$warehouse->fetch($inventory->fk_warehouse);
print dol_get_fiche_head(inventoryPrepareHead($inventory, $langs->trans('inventoryOfWarehouse', $warehouse->libelle), '&action='.$mode));
$lines = array();
_card_line($inventory, $lines, $form);
print '<b>'.$langs->trans('inventoryOnDate')." ".$inventory->get_date('date_inventory').'</b><br><br>';
$inventoryTPL = array(
'id'=> $inventory->id
,'date_cre' => $inventory->get_date('date_cre', 'd/m/Y')
,'date_maj' => $inventory->get_date('date_maj', 'd/m/Y H:i')
,'fk_warehouse' => $inventory->fk_warehouse
,'status' => $inventory->status
,'entity' => $inventory->entity
,'amount' => price( round($inventory->amount,2) )
,'amount_actual'=>price (round($inventory->amount_actual,2))
);
$can_validate = !empty($user->rights->inventory->validate);
$view_url = dol_buildpath('/inventory/inventory.php', 1);
$view = array(
'mode' => $mode
,'url' => dol_buildpath('/inventory/inventory.php', 1)
,'can_validate' => (int) $user->rights->inventory->validate
,'is_already_validate' => (int) $inventory->status
,'token'=>$_SESSION['newtoken']
);
include './tpl/inventory.tpl.php';
llxFooter('');
}
function _card_line(&$inventory, &$lines, &$form)
{
global $db;
$inventory->amount_actual = 0;
$TCacheEntrepot = array();
foreach ($inventory->Inventorydet as $k => $Inventorydet)
{
$product = & $Inventorydet->product;
$stock = $Inventorydet->qty_stock;
$pmp = $Inventorydet->pmp;
$pmp_actual = $pmp * $stock;
$inventory->amount_actual+=$pmp_actual;
$last_pa = $Inventorydet->pa;
$current_pa = $Inventorydet->current_pa;
$e = new Entrepot($db);
if(!empty($TCacheEntrepot[$Inventorydet->fk_warehouse])) $e = $TCacheEntrepot[$Inventorydet->fk_warehouse];
elseif($e->fetch($Inventorydet->fk_warehouse) > 0) $TCacheEntrepot[$e->id] = $e;
$lines[]=array(
'produit' => $product->getNomUrl(1).'&nbsp;-&nbsp;'.$product->label
,'entrepot'=>$e->getNomUrl(1)
,'barcode' => $product->barcode
/*,'qty' => $form->texte('', 'qty_to_add['.$k.']', (isset($_REQUEST['qty_to_add'][$k]) ? $_REQUEST['qty_to_add'][$k] : 0), 8, 0, "style='text-align:center;'")
.($form->type_aff!='view' ? '<a id="a_save_qty_'.$k.'" href="javascript:save_qty('.$k.')">'.img_picto('Ajouter', 'plus16@inventory').'</a>' : '')
,'qty_view' => $Inventorydet->qty_view ? $Inventorydet->qty_view : 0
,'qty_stock' => $stock
,'qty_regulated' => $Inventorydet->qty_regulated ? $Inventorydet->qty_regulated : 0
,'action' => $user->rights->inventory->write ? '<a onclick="if (!confirm(\'Confirmez-vous la suppression de la ligne ?\')) return false;" href="'.dol_buildpath('inventory/inventory.php?id='.$inventory->getId().'&action=delete_line&rowid='.$Inventorydet->getId(), 1).'">'.img_picto($langs->trans('inventoryDeleteLine'), 'delete').'</a>' : ''
,'pmp_stock'=>round($pmp_actual,2)
,'pmp_actual'=> round($pmp * $Inventorydet->qty_view,2)
,'pmp_new'=>(!empty($user->rights->inventory->changePMP) ? $form->texte('', 'new_pmp['.$k.']',$Inventorydet->new_pmp, 8, 0, "style='text-align:right;'")
.($form->type_aff!='view' ? '<a id="a_save_new_pmp_'.$k.'" href="javascript:save_pmp('.$k.')">'.img_picto($langs->trans('Save'), 'bt-save.png@inventory').'</a>' : '') : '' )
*/,'pa_stock'=>round($last_pa * $stock,2)
,'pa_actual'=>round($last_pa * $Inventorydet->qty_view,2)
,'current_pa_stock'=>round($current_pa * $stock,2)
,'current_pa_actual'=>round($current_pa * $Inventorydet->qty_view,2)
,'k'=>$k
,'id'=>$Inventorydet->id
);
}
}
function exportCSV(&$inventory) {
global $conf;
header('Content-Type: application/octet-stream');
header('Content-disposition: attachment; filename=inventory-'. $inventory->getId().'-'.date('Ymd-His').'.csv');
header('Pragma: no-cache');
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
echo 'Ref;Label;barcode;qty theorique;PMP;dernier PA;';
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)) echo 'PA courant;';
echo 'qty réelle;PMP;dernier PA;';
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)) echo 'PA courant;';
echo 'qty regulée;'."\r\n";
foreach ($inventory->Inventorydet as $k => $Inventorydet)
{
$product = & $Inventorydet->product;
$stock = $Inventorydet->qty_stock;
$pmp = $Inventorydet->pmp;
$pmp_actual = $pmp * $stock;
$inventory->amount_actual+=$pmp_actual;
$last_pa = $Inventorydet->pa;
$current_pa = $Inventorydet->current_pa;
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)) {
$row=array(
'produit' => $product->ref
,'label'=>$product->label
,'barcode' => $product->barcode
,'qty_stock' => $stock
,'pmp_stock'=>round($pmp_actual,2)
,'pa_stock'=>round($last_pa * $stock,2)
,'current_pa_stock'=>round($current_pa * $stock,2)
,'qty_view' => $Inventorydet->qty_view ? $Inventorydet->qty_view : 0
,'pmp_actual'=>round($pmp * $Inventorydet->qty_view,2)
,'pa_actual'=>round($last_pa * $Inventorydet->qty_view,2)
,'current_pa_actual'=>round($current_pa * $Inventorydet->qty_view,2)
,'qty_regulated' => $Inventorydet->qty_regulated ? $Inventorydet->qty_regulated : 0
);
}
else{
$row=array(
'produit' => $product->ref
,'label'=>$product->label
,'barcode' => $product->barcode
,'qty_stock' => $stock
,'pmp_stock'=>round($pmp_actual,2)
,'pa_stock'=>round($last_pa * $stock,2)
,'qty_view' => $Inventorydet->qty_view ? $Inventorydet->qty_view : 0
,'pmp_actual'=>round($pmp * $Inventorydet->qty_view,2)
,'pa_actual'=>round($last_pa * $Inventorydet->qty_view,2)
,'qty_regulated' => $Inventorydet->qty_regulated ? $Inventorydet->qty_regulated : 0
);
}
echo '"'.implode('";"', $row).'"'."\r\n";
}
exit;
}
function generateODT(&$PDOdb, &$db, &$conf, &$langs, &$inventory)
{
$TBS=new TTemplateTBS();
$InventoryPrint = array(); // Tableau envoyé à la fonction render contenant les informations concernant l'inventaire
foreach($inventory->Inventorydet as $k => $v)
{
$prod = new Product($db);
$prod->fetch($v->fk_product);
//$prod->fetch_optionals($prod->id);
$InventoryPrint[] = array(
'product' => $prod->ref.' - '.$prod->label
, 'qty_view' => $v->qty_view
);
}
$warehouse = new Entrepot($db);
$warehouse->fetch($inventory->fk_warehouse);
$dirName = 'INVENTORY'.$inventory->getId().'('.date("d_m_Y").')';
$dir = DOL_DATA_ROOT.'/inventory/'.$dirName.'/';
@mkdir($dir, 0777, true);
$template = "templateINVENTORY.odt";
//$template = "templateOF.doc";
$file_gen = $TBS->render(dol_buildpath('inventory/exempleTemplate/'.$template)
,array(
'InventoryPrint'=>$InventoryPrint
)
,array(
'date_cre'=>$inventory->get_date('date_cre', 'd/m/Y')
,'date_maj'=>$inventory->get_date('date_maj', 'd/m/Y H:i')
,'date_inv'=>$inventory->get_date('date_inventory', 'd/m/Y')
,'numero'=>empty($inventory->title) ? 'Inventaire n°'.$inventory->getId() : $inventory->title
,'warehouse'=>$warehouse->libelle
,'status'=>($inventory->status ? $langs->transnoentitiesnoconv('inventoryValidate') : $langs->transnoentitiesnoconv('inventoryDraft'))
,'logo'=>DOL_DATA_ROOT."/mycompany/logos/".MAIN_INFO_SOCIETE_LOGO
)
,array()
,array(
'outFile'=>$dir.$inventory->getId().".odt"
,"convertToPDF"=>(!empty($conf->global->INVENTORY_GEN_PDF) ? true : false)
,'charset'=>OPENTBS_ALREADY_UTF8
)
);
header("Location: ".DOL_URL_ROOT."/document.php?modulepart=inventory&entity=".$conf->entity."&file=".$dirName."/".$inventory->getId(). (!empty($conf->global->INVENTORY_GEN_PDF) ? '.pdf' : '.odt') );
/*
$size = filesize("./" . basename($file_gen));
header("Content-Type: application/force-download; name=\"" . basename($file_gen) . "\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: $size");
header("Content-Disposition: attachment; filename=\"" . basename($file_gen) . "\"");
header("Expires: 0");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
readfile($file_gen);
*/
//header("Location: ".DOL_URL_ROOT."/document.php?modulepart=asset&entity=1&file=".$dirName."/".$assetOf->numero.".doc");
}
function _footerList($view,$total_pmp,$total_pmp_actual,$total_pa,$total_pa_actual, $total_current_pa,$total_current_pa_actual) {
global $conf,$user,$langs;
if ($view['can_validate'] == 1) { ?>
<tr style="background-color:#dedede;">
<th colspan="3">&nbsp;</th>
<?php if (! empty($conf->barcode->enabled)) { ?>
<th align="center">&nbsp;</td>
<?php } ?>
<th align="right"><?php echo price($total_pmp) ?></th>
<th align="right"><?php echo price($total_pa) ?></th>
<?php
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)){
echo '<th align="right">'.price($total_current_pa).'</th>';
}
?>
<th>&nbsp;</th>
<th align="right"><?php echo price($total_pmp_actual) ?></th>
<?php
if(!empty($user->rights->inventory->changePMP)) {
echo '<th>&nbsp;</th>';
}
?>
<th align="right"><?php echo price($total_pa_actual) ?></th>
<?php
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)){
echo '<th align="right">'.price($total_current_pa_actual).'</th>';
}
?>
<th>&nbsp;</th>
<?php if ($view['is_already_validate'] != 1) { ?>
<th>&nbsp;</th>
<?php } ?>
</tr>
<?php }
}
function _headerList($view) {
global $conf,$user,$langs;
?>
<tr style="background-color:#dedede;">
<th align="left" width="20%">&nbsp;&nbsp;Produit</th>
<th align="center">Entrepôt</td>
<?php if (! empty($conf->barcode->enabled)) { ?>
<th align="center">Code-barre</td>
<?php } ?>
<?php if ($view['can_validate'] == 1) { ?>
<th align="center" width="20%">Quantité théorique</th>
<?php
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)){
echo '<th align="center" width="20%" colspan="3">Valeur théorique</th>';
}
else {
echo '<th align="center" width="20%" colspan="2">Valeur théorique</th>';
}
?>
<?php } ?>
<th align="center" width="20%">Quantité réelle</th>
<?php if ($view['can_validate'] == 1) { ?>
<?php
$colspan = 2;
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)) $colspan++;
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)) $colspan++;
echo '<th align="center" width="20%" colspan="'.$colspan.'">Valeur réelle</th>';
?>
<th align="center" width="15%">Quantité régulée</th>
<?php } ?>
<?php if ($view['is_already_validate'] != 1) { ?>
<th align="center" width="5%">#</th>
<?php } ?>
<th align="center" width="5%"></th>
</tr>
<?php if ($view['can_validate'] == 1) { ?>
<tr style="background-color:#dedede;">
<th colspan="<?php echo empty($conf->barcode->enabled) ? 3 : 4; ?>">&nbsp;</th>
<th>PMP</th>
<th>Dernier PA</th>
<?php
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)){
echo '<th>PA courant</th>';
}
?>
<th>&nbsp;</th>
<th>PMP</th>
<?php
if(!empty($user->rights->inventory->changePMP)) {
echo '<th rel="newPMP">'.$langs->trans('ColumnNewPMP').'</th>';
}
?>
<th>Dernier PA</th>
<?php
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)){
echo '<th>PA courant</th>';
}
?>
<th>&nbsp;</th>
<?php if ($view['is_already_validate'] != 1) { ?>
<th>&nbsp;</th>
<?php } ?>
</tr>
<?php
}
}

View File

@ -0,0 +1,245 @@
<?php
/* <one line to give the program's name and a brief idea of what it does.>
* Copyright (C) 2015 ATM Consulting <support@atm-consulting.fr>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file lib/inventory.lib.php
* \ingroup inventory
* \brief This file is an example module library
* Put some comments here
*/
function inventoryAdminPrepareHead()
{
global $langs, $conf;
$langs->load("inventory@inventory");
$h = 0;
$head = array();
$head[$h][0] = dol_buildpath("/inventory/admin/inventory_setup.php", 1);
$head[$h][1] = $langs->trans("Parameters");
$head[$h][2] = 'settings';
$h++;
$head[$h][0] = dol_buildpath("/inventory/admin/inventory_about.php", 1);
$head[$h][1] = $langs->trans("About");
$head[$h][2] = 'about';
$h++;
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
//$this->tabs = array(
// 'entity:+tabname:Title:@inventory:/inventory/mypage.php?id=__ID__'
//); // to add new tab
//$this->tabs = array(
// 'entity:-tabname:Title:@inventory:/inventory/mypage.php?id=__ID__'
//); // to remove a tab
complete_head_from_modules($conf, $langs, $object, $head, $h, 'inventory');
return $head;
}
function inventoryPrepareHead(&$inventory, $title='Inventaire', $get='')
{
return array(
array(dol_buildpath('/inventory/inventory.php?id='.$inventory->id.$get, 1), $title,'inventaire')
);
}
function inventorySelectProducts(&$inventory)
{
global $conf,$db;
$except_product_id = array();
foreach ($inventory->Inventorydet as $Inventorydet)
{
$except_product_id[] = $Inventorydet->fk_product;
}
ob_start();
$form = new Form($db);
$form->select_produits(-1, 'fk_product');
// Il nous faut impérativement une liste custom car il ne faut que les entrepôts de la famille de celui qu'on inventorie
$TChildWarehouses = array($inventory->fk_warehouse);
$e = new Entrepot($db);
$e->fetch($inventory->fk_warehouse);
if(method_exists($e, 'get_children_warehouses')) $e->get_children_warehouses($e->id, $TChildWarehouses);
$Tab = array();
$sql = 'SELECT rowid, label
FROM '.MAIN_DB_PREFIX.'entrepot WHERE rowid IN('.implode(', ', $TChildWarehouses).')';
if(method_exists($e, 'get_children_warehouses')) $sql.= ' ORDER BY fk_parent';
$resql = $db->query($sql);
while($res = $db->fetch_object($resql)) {
$Tab[$res->rowid] = $res->label;
}
print '&nbsp;&nbsp;&nbsp;';
print 'Entrepôt : '.$form::selectarray('fk_warehouse', $Tab);
$select_html = ob_get_clean();
return $select_html;
}
function ajaxAutocompleter($selected, $htmlname, $url, $urloption='', $minLength=2, $autoselect=0, $ajaxoptions=array())
{
if (empty($minLength)) $minLength=1;
$script = '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="'.$selected.'" />';
$script.= '<script type="text/javascript">';
$script.= '$(document).ready(function() {
var autoselect = '.$autoselect.';
var options = '.json_encode($ajaxoptions).';
// Remove product id before select another product
// use keyup instead change to avoid loosing the product id
$("input#search_'.$htmlname.'").keydown(function() {
//console.log(\'purge_id_after_keydown\');
$("#'.$htmlname.'").val("");
});
$("input#search_'.$htmlname.'").change(function() {
//console.log(\'change\');
$("#'.$htmlname.'").trigger("change");
});
// Check when keyup
$("input#search_'.$htmlname.'").keyup(function() {
//console.log(\'keyup\');
if ($(this).val().length == 0)
{
$("#search_'.$htmlname.'").val("");
$("#'.$htmlname.'").val("").trigger("change");
if (options.option_disabled) {
$("#" + options.option_disabled).removeAttr("disabled");
}
if (options.disabled) {
$.each(options.disabled, function(key, value) {
$("#" + value).removeAttr("disabled");
});
}
if (options.update) {
$.each(options.update, function(key, value) {
$("#" + key).val("").trigger("change");
});
}
if (options.show) {
$.each(options.show, function(key, value) {
$("#" + value).hide().trigger("hide");
});
}
if (options.update_textarea) {
$.each(options.update_textarea, function(key, value) {
if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
CKEDITOR.instances[key].setData("");
} else {
$("#" + key).html("");
}
});
}
}
});
$("input#search_'.$htmlname.'").autocomplete({
source: function( request, response ) {
$.get("'.$url.($urloption?'?'.$urloption:'').'", { '.$htmlname.': request.term }, function(data){
response($.map( data, function( item ) {
if (autoselect == 1 && data.length == 1) {
$("#search_'.$htmlname.'").val(item.value);
$("#'.$htmlname.'").val(item.key).trigger("change");
}
var label = item.label.toString();
var update = {};
if (options.update) {
$.each(options.update, function(key, value) {
update[key] = item[value];
});
}
var textarea = {};
if (options.update_textarea) {
$.each(options.update_textarea, function(key, value) {
textarea[key] = item[value];
});
}
return { label: label, value: item.value, id: item.key, update: update, textarea: textarea, disabled: item.disabled }
}));
}, "json");
},
dataType: "json",
minLength: '.$minLength.',
select: function( event, ui ) { // Function ran when new value is selected into javascript combo
//console.log(\'set value of id with \'+ui.item.id);
$("#'.$htmlname.'").val(ui.item.id).trigger("change"); // Select new value
// Disable an element
if (options.option_disabled) {
if (ui.item.disabled) {
$("#" + options.option_disabled).attr("disabled", "disabled");
if (options.error) {
$.jnotify(options.error, "error", true); // Output with jnotify the error message
}
if (options.warning) {
$.jnotify(options.warning, "warning", false); // Output with jnotify the warning message
}
} else {
$("#" + options.option_disabled).removeAttr("disabled");
}
}
if (options.disabled) {
$.each(options.disabled, function(key, value) {
$("#" + value).attr("disabled", "disabled");
});
}
if (options.show) {
$.each(options.show, function(key, value) {
$("#" + value).show().trigger("show");
});
}
// Update an input
if (ui.item.update) {
// loop on each "update" fields
$.each(ui.item.update, function(key, value) {
$("#" + key).val(value).trigger("change");
});
}
if (ui.item.textarea) {
$.each(ui.item.textarea, function(key, value) {
if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
CKEDITOR.instances[key].setData(value);
CKEDITOR.instances[key].focus();
} else {
$("#" + key).html(value);
$("#" + key).focus();
}
});
}
$("#search_'.$htmlname.'").trigger("change"); // To tell that input text field was modified
}
}).data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( \'<a><span class="tag">\' + item.label + "</span></a>" )
.appendTo(ul);
};
});';
$script.= '</script>';
return $script;
}

View File

@ -0,0 +1,211 @@
<script type="text/javascript">
function save_qty(k) {
var $input = $('input[name="qty_to_add['+k+']"]');
var fk_det_inventory = $('input[name=det_id_'+k+']').val();
var qty = $input.val();
$('#a_save_qty_'+k).hide();
$.ajax({
url:"script/interface.php"
,data:{
'fk_det_inventory' : fk_det_inventory
,'qty': qty
,'put':'qty'
}
}).done(function(data) {
$('#qty_view_'+k).html(data);
$input.val(0);
$.jnotify("Quantité ajoutée : "+qty, "mesgs" );
$('#a_save_qty_'+k).show();
hide_save_button();
});
}
function save_pmp(k) {
var $input = $('input[name="new_pmp['+k+']"]');
var fk_det_inventory = $('input[name=det_id_'+k+']').val();
var pmp = $input.val();
$('#a_save_new_pmp_'+k).hide();
$.ajax({
url:"script/interface.php"
,data:{
'fk_det_inventory' : fk_det_inventory
,'pmp': pmp
,'put':'pmp'
}
}).done(function(data) {
$input.css({"background-color":"#66ff66"});
$.jnotify("PMP sauvegardé : "+pmp, "mesgs" );
$('#a_save_new_pmp_'+k).show();
});
}
function hide_save_button() {
var nb = 0;
$('input[name^="qty_to_add"]').each(function() {
nb += $(this).val();
});
if(nb>0) {
$('input[name=modify]').show();
}
else{
$('input[name=modify]').hide();
}
}
</script>
<?php if ($inventory->status != 1) { ?>
<strong><?php echo $langs->trans('AddInventoryProduct'); ?> : </strong>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<input type="hidden" name="action" value="add_line" />
<input type="hidden" name="id" value="<?php echo $inventory->id; ?>" />
<?php echo inventorySelectProducts($inventory); ?>
<input class="butAction" type="submit" value="<?php echo $langs->trans('AddProduct'); ?>" />
</form>
<?php } ?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<?php if ($view['is_already_validate'] == 1) { ?>
<div class="warning">Cet inventaire est validé</div>
<?php } ?>
<input type="hidden" name="action" value="save" />
<input type="hidden" name="id" value="<?php echo $inventory->id; ?>" />
<table width="100%" class="border workstation">
<?php
_headerList($view);
$total_pmp = $total_pa = $total_pmp_actual = $total_pa_actual =$total_current_pa=$total_current_pa_actual = 0;
$i=1;
foreach ($lines as $k=>$row) {
$total_pmp+=$row['pmp_stock'];
$total_pa+=$row['pa_stock'];
$total_pmp_actual+=$row['pmp_actual'];
$total_pa_actual+=$row['pa_actual'];
if($i%20 === 0)
{
_headerList($view);
} // Fin IF principal
?>
<tr style="background-color:<?php echo ($k%2 == 0) ? '#fff':'#eee'; ?>;">
<td align="left">&nbsp;&nbsp;<?php echo $row['produit']; ?></td>
<td align="center"><?php echo $row['entrepot']; ?></td>
<?php if (! empty($conf->barcode->enabled)) { ?>
<td align="center"><?php echo $row['barcode']; ?></td>
<?php } ?>
<?php if ($can_validate == 1) { ?>
<td align="center" style="background-color: #e8e8ff;"><?php echo $row['qty_stock']; ?></td>
<td align="right" style="background-color: #e8e8ff;"><?php echo price( $row['pmp_stock']); ?></td>
<td align="right" style="background-color: #e8e8ff;"><?php echo price( $row['pa_stock']); ?></td>
<?php
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)){
echo '<td align="right" style="background-color: #e8e8ff;">'.price($row['current_pa_stock']).'</td>';
$total_current_pa+=$row['current_pa_stock'];
}
?>
<?php } ?>
<td align="center"><?php echo $row['qty']; ?>&nbsp;&nbsp;<span id="qty_view_<?php echo $row['k']; ?>"><?php echo $row['qty_view']; ?></span>
<input type="hidden" name="det_id_<?php echo $row['k']; ?>" value="<?php echo $row['id']; ?>" />
</td>
<?php if ($can_validate == 1) { ?>
<td align="right"><?php echo price($row['pmp_actual']); ?></td>
<?php
if(!empty($user->rights->inventory->changePMP)) {
echo '<td>'.$row['pmp_new'].'</td>';
}
?>
<td align="right"><?php echo price($row['pa_actual']); ?></td>
<?php
if(!empty($conf->global->INVENTORY_USE_MIN_PA_IF_NO_LAST_PA)){
echo '<td align="right">'.price($row['current_pa_actual']).'</td>';
$total_current_pa_actual+=$row['current_pa_actual'];
}
?>
<td align="center"><?php echo $row['qty_regulated']; ?></td>
<?php } ?>
<?php if ($view['is_already_validate'] != 1) { ?>
<td align="center" width="20%"><?php echo $row['action']; ?></td>
<?php } ?>
</tr>
<?php $i++; ?>
<?php }
_footerList($view,$total_pmp,$total_pmp_actual,$total_pa,$total_pa_actual, $total_current_pa,$total_current_pa_actual);
?>
</table>
<?php if ($view['is_already_validate'] != 1) { ?>
<div class="tabsAction" style="height:30px;">
<?php if ($view['mode'] == 'view') { ?>
<a href="<?php echo $view_url; ?>?id=<?php echo $inventory->id; ?>&action=printDoc" class="butAction"><?php echo $langs->trans('Print') ?></a>
<a href="<?php echo $view_url; ?>?id=<?php echo $inventory->id; ?>&action=exportCSV" class="butAction"><?php echo $langs->trans('ExportCSV') ?></a>
<a href="<?php echo $view_url; ?>?id=<?php echo $inventory->id; ?>&action=edit" class="butAction"><?php echo $langs->trans('Modify') ?></a>
<?php
if(!empty($user->rights->inventory->changePMP)) {
echo '<a href="javascript:;" onclick="javascript:if (!confirm(\'Confirmez-vous l\\\'application du nouveau PMP ?\')) return false; else document.location.href=\''.$view_url
.'?id='.$inventory->id
.'&action=changePMP&token='.$view['token'].'\'; " class="butAction">'.$langs->trans('ApplyPMP').'</a>';
}
if ($can_validate == 1) { ?>
<a href="javascript:;" onclick="javascript:if (!confirm('Confirmez-vous la régulation ?')) return false; else document.location.href='<?php echo $view_url; ?>?id=<?php echo $inventory->id; ?>&action=regulate&token=<?php echo $view['token']; ?>'; " class="butAction">Réguler le stock</a>
<?php } ?>
<?php } ?>
<?php if ($view['mode'] == 'edit') { ?>
<input name="back" type="button" class="butAction" value="Quitter la saisie" onclick="document.location='?id=<?php echo $inventory->id; ?>&action=view';" />
<?php } ?>
<?php if ($can_validate == 1) { ?>
<a onclick="if (!confirm('Confirmez-vous la vidange ?')) return false;" href="<?php echo $view_url; ?>?id=<?php echo $inventory->id; ?>&action=flush" class="butActionDelete">Vider</a>
&nbsp;&nbsp;&nbsp;
<a onclick="if (!confirm('Confirmez-vous la suppression ?')) return false;" href="<?php echo $view_url; ?>?id=<?php echo $inventory->id; ?>&action=delete" class="butActionDelete">Supprimer</a>
<?php } ?>
</div>
<?php } ?>
<?php if ($view['is_already_validate'] == 1) { ?>
<div class="tabsAction">
<?php if ($can_validate == 1) { ?>
<a href="<?php echo $view_url; ?>?id=<?php echo $inventory->id; ?>&action=printDoc" class="butAction"><?php echo $langs->trans('Print') ?></a>
<a href="<?php echo $view_url; ?>?id=<?php echo $inventory->id; ?>&action=exportCSV" class="butAction"><?php echo $langs->trans('ExportCSV') ?></a>
<a href="#" title="Cet inventaire est validé" class="butActionRefused"><?php echo $langs->trans('Delete') ?></a>
<?php } ?>
</div>
<?php } ?>
</form>
<p>Date de création : <?php echo $inventory->get_date('datec') ?>
<br />Dernière mise à jour : <?php echo $inventory->get_date('tms') ?></p>