forked from Wavyzz/dolibarr
Several fix in warehouse stock change (rounding, api rest)
This commit is contained in:
@@ -93,13 +93,31 @@ class DolibarrApi
|
||||
// Remove linkedObjects. We should already have linkedObjectIds that avoid huge responses
|
||||
unset($object->linkedObjects);
|
||||
|
||||
unset($object->lignes); // should be lines
|
||||
unset($object->lignes); // should be ->lines
|
||||
unset($object->oldline);
|
||||
|
||||
unset($object->error);
|
||||
unset($object->errors);
|
||||
|
||||
unset($object->ref_previous);
|
||||
unset($object->ref_next);
|
||||
unset($object->ref_int);
|
||||
|
||||
unset($object->projet); // Should be fk_project
|
||||
unset($object->project); // Should be fk_project
|
||||
unset($object->author); // Should be fk_user_author
|
||||
|
||||
unset($object->statuts);
|
||||
unset($object->statuts_short);
|
||||
unset($object->statuts_logo);
|
||||
unset($object->statuts_long);
|
||||
|
||||
unset($object->element);
|
||||
unset($object->fk_element);
|
||||
unset($object->table_element);
|
||||
unset($object->table_element_line);
|
||||
unset($object->picto);
|
||||
|
||||
// Remove the $oldcopy property because it is not supported by the JSON
|
||||
// encoder. The following error is generated when trying to serialize
|
||||
// it: "Error encoding/decoding JSON: Type is not supported"
|
||||
|
||||
@@ -151,7 +151,7 @@ class Categories extends DolibarrApi
|
||||
$obj = $db->fetch_object($result);
|
||||
$category_static = new Categorie($db);
|
||||
if($category_static->fetch($obj->rowid)) {
|
||||
$obj_ret[] = parent::_cleanObjectDatas($category_static);
|
||||
$obj_ret[] = $this->_cleanObjectDatas($category_static);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
@@ -237,7 +237,7 @@ class Categories extends DolibarrApi
|
||||
$obj = $db->fetch_object($result);
|
||||
$category_static = new Categorie($db);
|
||||
if($category_static->fetch($obj->rowid)) {
|
||||
$obj_ret[] = parent::_cleanObjectDatas($category_static);
|
||||
$obj_ret[] = $this->_cleanObjectDatas($category_static);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
@@ -339,6 +339,26 @@ class Categories extends DolibarrApi
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean sensible object datas
|
||||
*
|
||||
* @param object $object Object to clean
|
||||
* @return array Array of cleaned object properties
|
||||
*
|
||||
* @todo use an array for properties to clean
|
||||
*
|
||||
*/
|
||||
function _cleanObjectDatas($object) {
|
||||
|
||||
$object = parent::_cleanObjectDatas($object);
|
||||
|
||||
// Remove the subscriptions because they are handled as a subresource.
|
||||
//unset($object->subscriptions);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate fields before create or update object
|
||||
*
|
||||
|
||||
@@ -3488,7 +3488,7 @@ function price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerou
|
||||
* @param string $rounding ''=No rounding
|
||||
* 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT)
|
||||
* 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT)
|
||||
* 'MS'=Round to Max Shown (MAIN_MAX_DECIMALS_SHOWN)
|
||||
* 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK)
|
||||
* @param int $alreadysqlnb Put 1 if you know that content is already universal format number
|
||||
* @return string Amount with universal numeric format (Example: '99.99999') or unchanged text if conversion fails.
|
||||
*
|
||||
@@ -3538,7 +3538,7 @@ function price2num($amount,$rounding='',$alreadysqlnb=0)
|
||||
$nbofdectoround='';
|
||||
if ($rounding == 'MU') $nbofdectoround=$conf->global->MAIN_MAX_DECIMALS_UNIT;
|
||||
elseif ($rounding == 'MT') $nbofdectoround=$conf->global->MAIN_MAX_DECIMALS_TOT;
|
||||
elseif ($rounding == 'MS') $nbofdectoround=$conf->global->MAIN_MAX_DECIMALS_SHOWN;
|
||||
elseif ($rounding == 'MS') $nbofdectoround=empty($conf->global->MAIN_MAX_DECIMALS_STOCK)?5:$conf->global->MAIN_MAX_DECIMALS_STOCK;
|
||||
elseif (is_numeric($rounding)) $nbofdectoround=$rounding; // For admin info page
|
||||
//print "RR".$amount.' - '.$nbofdectoround.'<br>';
|
||||
if (dol_strlen($nbofdectoround)) $amount = round($amount,$nbofdectoround); // $nbofdectoround can be 0.
|
||||
|
||||
@@ -332,7 +332,8 @@ else
|
||||
|
||||
// Nb of products
|
||||
print '<tr><td>'.$langs->trans("NumberOfProducts").'</td><td>';
|
||||
print empty($calcproducts['nb'])?'0':$calcproducts['nb'];
|
||||
$valtoshow=price2num($calcproducts['nb'], 'MS');
|
||||
print empty($valtoshow)?'0':$valtoshow;
|
||||
print "</td></tr>";
|
||||
|
||||
print '</table>';
|
||||
@@ -485,13 +486,19 @@ else
|
||||
$productstatic->entity=$objp->entity;
|
||||
print $productstatic->getNomUrl(1,'stock',16);
|
||||
print '</td>';
|
||||
|
||||
// Label
|
||||
print '<td>'.$objp->produit.'</td>';
|
||||
|
||||
print '<td align="right">'.$objp->value.'</td>';
|
||||
print '<td align="right">';
|
||||
$valtoshow=price2num($objp->value, 'MS');
|
||||
print empty($valtoshow)?'0':$valtoshow;
|
||||
print '</td>';
|
||||
$totalunit+=$objp->value;
|
||||
|
||||
// Price buy PMP
|
||||
print '<td align="right">'.price(price2num($objp->ppmp,'MU')).'</td>';
|
||||
|
||||
// Total PMP
|
||||
print '<td align="right">'.price(price2num($objp->ppmp*$objp->value,'MT')).'</td>';
|
||||
$totalvalue+=price2num($objp->ppmp*$objp->value,'MT');
|
||||
@@ -530,7 +537,10 @@ else
|
||||
$db->free($resql);
|
||||
|
||||
print '<tr class="liste_total"><td class="liste_total" colspan="2">'.$langs->trans("Total").'</td>';
|
||||
print '<td class="liste_total" align="right">'.$totalunit.'</td>';
|
||||
print '<td class="liste_total" align="right">';
|
||||
$valtoshow=price2num($totalunit, 'MS');
|
||||
print empty($valtoshow)?'0':$valtoshow;
|
||||
print '</td>';
|
||||
print '<td class="liste_total"> </td>';
|
||||
print '<td class="liste_total" align="right">'.price(price2num($totalvalue,'MT')).'</td>';
|
||||
if (empty($conf->global->PRODUIT_MULTIPRICES))
|
||||
|
||||
349
htdocs/product/stock/class/api_stockmovements.class.php
Normal file
349
htdocs/product/stock/class/api_stockmovements.class.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
/* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
use Luracast\Restler\RestException;
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
|
||||
|
||||
|
||||
/**
|
||||
* API class for stock movements
|
||||
*
|
||||
* @access protected
|
||||
* @class DolibarrApiAccess {@requires user,external}
|
||||
*/
|
||||
class StockMovements extends DolibarrApi
|
||||
{
|
||||
/**
|
||||
* @var array $FIELDS Mandatory fields, checked when create and update object
|
||||
*/
|
||||
static $FIELDS = array(
|
||||
'product_id',
|
||||
'warehouse_id',
|
||||
'qty'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var MouvmeentStock $stockmovement {@type MouvementStock}
|
||||
*/
|
||||
public $stockmovement;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
global $db, $conf;
|
||||
$this->db = $db;
|
||||
$this->stockmovement = new MouvementStock($this->db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get properties of a stock movement object
|
||||
*
|
||||
* Return an array with stock movement informations
|
||||
*
|
||||
* @param int $id ID of movement
|
||||
* @return array|mixed data without useless information
|
||||
*
|
||||
* @throws RestException
|
||||
*/
|
||||
/*
|
||||
function get($id)
|
||||
{
|
||||
if(! DolibarrApiAccess::$user->rights->stock->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$result = $this->stockmovement->fetch($id);
|
||||
if( ! $result ) {
|
||||
throw new RestException(404, 'warehouse not found');
|
||||
}
|
||||
|
||||
if( ! DolibarrApi::_checkAccessToResource('warehouse',$this->stockmovement->id)) {
|
||||
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
return $this->_cleanObjectDatas($this->stockmovement);
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Get a list of stock movement
|
||||
*
|
||||
* @param string $sortfield Sort field
|
||||
* @param string $sortorder Sort order
|
||||
* @param int $limit Limit for list
|
||||
* @param int $page Page number
|
||||
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.product_id:=:1) and (t.date_creation:<:'20160101')"
|
||||
* @return array Array of warehouse objects
|
||||
*
|
||||
* @throws RestException
|
||||
*/
|
||||
function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $sqlfilters = '') {
|
||||
global $db, $conf;
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
if(! DolibarrApiAccess::$user->rights->stock->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$sql = "SELECT t.rowid";
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."stock_mouvement as t";
|
||||
//$sql.= ' WHERE t.entity IN ('.getEntity('stock', 1).')';
|
||||
$sql.= ' WHERE 1 = 1';
|
||||
// Add sql filters
|
||||
if ($sqlfilters)
|
||||
{
|
||||
if (! DolibarrApi::_checkFilters($sqlfilters))
|
||||
{
|
||||
throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
|
||||
}
|
||||
$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
|
||||
$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
|
||||
}
|
||||
|
||||
$sql.= $db->order($sortfield, $sortorder);
|
||||
if ($limit) {
|
||||
if ($page < 0)
|
||||
{
|
||||
$page = 0;
|
||||
}
|
||||
$offset = $limit * $page;
|
||||
|
||||
$sql.= $db->plimit($limit + 1, $offset);
|
||||
}
|
||||
|
||||
$result = $db->query($sql);
|
||||
if ($result)
|
||||
{
|
||||
$i=0;
|
||||
$num = $db->num_rows($result);
|
||||
while ($i < min($num, ($limit <= 0 ? $num : $limit)))
|
||||
{
|
||||
$obj = $db->fetch_object($result);
|
||||
$stockmovement_static = new MouvementStock($db);
|
||||
if($stockmovement_static->fetch($obj->rowid)) {
|
||||
$obj_ret[] = $this->_cleanObjectDatas($stockmovement_static);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new RestException(503, 'Error when retrieve stock movement list : '.$stockmovement_static->error);
|
||||
}
|
||||
if( ! count($obj_ret)) {
|
||||
throw new RestException(404, 'No stock movement found');
|
||||
}
|
||||
return $obj_ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param int $product_id Id product id {@min 1}
|
||||
* @param int $warehouse_id Id warehouse {@min 1}
|
||||
* @param float $qty Qty to add (Use negative value for a stock decrease) {@min 0} {@message qty must be higher than 0}
|
||||
* @param string $lot Lot
|
||||
* @param string $movementcode Movement code {@example INV123}
|
||||
* @param string $movementlabel Movement label {@example Inventory number 123}
|
||||
* @param string $price To update AWP (Average Weighted Price) when you make a stock increase (qty must be higher then 0).
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Create stock movement object.
|
||||
* You can use the following message to test this RES API:
|
||||
* { "product_id": 1, "warehouse_id": 1, "qty": 1, "lot": "", "movementcode": "INV123", "movementlabel": "Inventory 123", "price": 0 }
|
||||
*
|
||||
* @param array $request_data Request data
|
||||
* @return int ID of stock movement
|
||||
*/
|
||||
//function post($product_id, $warehouse_id, $qty, $lot='', $movementcode='', $movementlabel='', $price=0)
|
||||
function post($request_data = NULL)
|
||||
{
|
||||
if(! DolibarrApiAccess::$user->rights->stock->creer) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
// Check mandatory fields
|
||||
//$result = $this->_validate($request_data);
|
||||
|
||||
foreach($request_data as $field => $value) {
|
||||
//$this->stockmovement->$field = $value;
|
||||
if ($field == 'product_id') $product_id = $value;
|
||||
if ($field == 'warehouse_id') $warehouse_id = $value;
|
||||
if ($field == 'qty') $qty = $value;
|
||||
if ($field == 'lot') $lot = $value;
|
||||
if ($field == 'movementcode') $movementcode = $value;
|
||||
if ($field == 'movementlabel') $movementlabel = $value;
|
||||
if ($field == 'price') $price = $value;
|
||||
}
|
||||
|
||||
// Type increase or decrease
|
||||
if ($qty >= 0) $type = 3;
|
||||
else $type = 2;
|
||||
|
||||
if($this->stockmovement->_create(DolibarrApiAccess::$user, $product_id, $warehouse_id, $qty, $type, $price, $movementlabel, $movementcode, '', '', '', $lot) <= 0) {
|
||||
throw new RestException(503, 'Error when create stock movement : '.$this->stockmovement->error);
|
||||
}
|
||||
|
||||
return $this->stockmovement->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update stock movement
|
||||
*
|
||||
* @param int $id Id of warehouse to update
|
||||
* @param array $request_data Datas
|
||||
* @return int
|
||||
*/
|
||||
/*
|
||||
function put($id, $request_data = NULL)
|
||||
{
|
||||
if(! DolibarrApiAccess::$user->rights->stock->creer) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
$result = $this->stockmovement->fetch($id);
|
||||
if( ! $result ) {
|
||||
throw new RestException(404, 'stock movement not found');
|
||||
}
|
||||
|
||||
if( ! DolibarrApi::_checkAccessToResource('stock',$this->stockmovement->id)) {
|
||||
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
foreach($request_data as $field => $value) {
|
||||
$this->stockmovement->$field = $value;
|
||||
}
|
||||
|
||||
if($this->stockmovement->update($id, DolibarrApiAccess::$user))
|
||||
return $this->get ($id);
|
||||
|
||||
return false;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Delete stock movement
|
||||
*
|
||||
* @param int $id Stock movement ID
|
||||
* @return array
|
||||
*/
|
||||
/*
|
||||
function delete($id)
|
||||
{
|
||||
if(! DolibarrApiAccess::$user->rights->stock->supprimer) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
$result = $this->stockmovement->fetch($id);
|
||||
if( ! $result ) {
|
||||
throw new RestException(404, 'stock movement not found');
|
||||
}
|
||||
|
||||
if( ! DolibarrApi::_checkAccessToResource('stock',$this->stockmovement->id)) {
|
||||
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
if (! $this->stockmovement->delete(DolibarrApiAccess::$user)) {
|
||||
throw new RestException(401,'error when delete stock movement');
|
||||
}
|
||||
|
||||
return array(
|
||||
'success' => array(
|
||||
'code' => 200,
|
||||
'message' => 'Warehouse deleted'
|
||||
)
|
||||
);
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clean sensible object datas
|
||||
*
|
||||
* @param object $object Object to clean
|
||||
* @return array Array of cleaned object properties
|
||||
*
|
||||
* @todo use an array for properties to clean
|
||||
*
|
||||
*/
|
||||
function _cleanObjectDatas($object) {
|
||||
|
||||
$object = parent::_cleanObjectDatas($object);
|
||||
|
||||
// Remove useless data
|
||||
unset($object->civility_id);
|
||||
unset($object->firstname);
|
||||
unset($object->lastname);
|
||||
unset($object->name);
|
||||
unset($object->location_incoterms);
|
||||
unset($object->libelle_incoterms);
|
||||
unset($object->fk_incoterms);
|
||||
unset($object->lines);
|
||||
unset($object->total_ht);
|
||||
unset($object->total_ttc);
|
||||
unset($object->total_tva);
|
||||
unset($object->total_localtax1);
|
||||
unset($object->total_localtax2);
|
||||
unset($object->note);
|
||||
unset($object->note_private);
|
||||
unset($object->note_public);
|
||||
unset($object->shipping_method_id);
|
||||
unset($object->fk_account);
|
||||
unset($object->modelpdf);
|
||||
unset($object->fk_delivery_address);
|
||||
unset($object->cond_reglement);
|
||||
unset($object->cond_reglement_id);
|
||||
unset($object->mode_reglement_id);
|
||||
unset($object->barcode_type_coder);
|
||||
unset($object->barcode_type_label);
|
||||
unset($object->barcode_type_code);
|
||||
unset($object->barcode_type);
|
||||
unset($object->country_code);
|
||||
unset($object->country_id);
|
||||
unset($object->country);
|
||||
unset($object->thirdparty);
|
||||
unset($object->contact);
|
||||
unset($object->contact_id);
|
||||
unset($object->user);
|
||||
unset($object->fk_project);
|
||||
unset($object->project);
|
||||
|
||||
//unset($object->eatby); Filled correctly in read mode
|
||||
//unset($object->sellby); Filled correctly in read mode
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate fields before create or update object
|
||||
*
|
||||
* @param array|null $data Data to validate
|
||||
* @return array
|
||||
*
|
||||
* @throws RestException
|
||||
*/
|
||||
function _validate($data)
|
||||
{
|
||||
$stockmovement = array();
|
||||
foreach (Warehouses::$FIELDS as $field) {
|
||||
if (!isset($data[$field]))
|
||||
throw new RestException(400, "$field field missing");
|
||||
$stockmovement[$field] = $data[$field];
|
||||
}
|
||||
return $stockmovement;
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,7 @@ class Warehouses extends DolibarrApi
|
||||
$obj = $db->fetch_object($result);
|
||||
$warehouse_static = new Entrepot($db);
|
||||
if($warehouse_static->fetch($obj->rowid)) {
|
||||
$obj_ret[] = parent::_cleanObjectDatas($warehouse_static);
|
||||
$obj_ret[] = $this->_cleanObjectDatas($warehouse_static);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
@@ -169,7 +169,7 @@ class Warehouses extends DolibarrApi
|
||||
foreach($request_data as $field => $value) {
|
||||
$this->warehouse->$field = $value;
|
||||
}
|
||||
if($this->warehouse->create(DolibarrApiAccess::$user) < 0) {
|
||||
if($this->warehouse->create(DolibarrApiAccess::$user) <= 0) {
|
||||
throw new RestException(503, 'Error when create warehouse : '.$this->warehouse->error);
|
||||
}
|
||||
return $this->warehouse->id;
|
||||
@@ -193,7 +193,7 @@ class Warehouses extends DolibarrApi
|
||||
throw new RestException(404, 'warehouse not found');
|
||||
}
|
||||
|
||||
if( ! DolibarrApi::_checkAccessToResource('warehouse',$this->warehouse->id)) {
|
||||
if( ! DolibarrApi::_checkAccessToResource('stock',$this->warehouse->id)) {
|
||||
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ class Warehouses extends DolibarrApi
|
||||
throw new RestException(404, 'warehouse not found');
|
||||
}
|
||||
|
||||
if( ! DolibarrApi::_checkAccessToResource('warehouse',$this->warehouse->id)) {
|
||||
if( ! DolibarrApi::_checkAccessToResource('stock',$this->warehouse->id)) {
|
||||
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
@@ -239,6 +239,27 @@ class Warehouses extends DolibarrApi
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean sensible object datas
|
||||
*
|
||||
* @param object $object Object to clean
|
||||
* @return array Array of cleaned object properties
|
||||
*
|
||||
* @todo use an array for properties to clean
|
||||
*
|
||||
*/
|
||||
function _cleanObjectDatas($object) {
|
||||
|
||||
$object = parent::_cleanObjectDatas($object);
|
||||
|
||||
// Remove the subscriptions because they are handled as a subresource.
|
||||
//unset($object->subscriptions);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate fields before create or update object
|
||||
*
|
||||
|
||||
@@ -30,10 +30,31 @@
|
||||
*/
|
||||
class MouvementStock extends CommonObject
|
||||
{
|
||||
var $product_id;
|
||||
var $entrepot_id;
|
||||
var $qty;
|
||||
var $type;
|
||||
/**
|
||||
* @var string Id to identify managed objects
|
||||
*/
|
||||
public $element = 'stockmouvement';
|
||||
/**
|
||||
* @var string Name of table without prefix where object is stored
|
||||
*/
|
||||
public $table_element = 'stock_mouvement';
|
||||
|
||||
|
||||
public $product_id;
|
||||
public $warehouse_id;
|
||||
public $qty;
|
||||
public $type;
|
||||
|
||||
public $tms = '';
|
||||
public $datem = '';
|
||||
public $price;
|
||||
public $fk_user_author;
|
||||
public $label;
|
||||
public $fk_origin;
|
||||
public $origintype;
|
||||
public $inventorycode;
|
||||
public $batch;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -46,6 +67,7 @@ class MouvementStock extends CommonObject
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a movement of stock (in one direction only)
|
||||
*
|
||||
@@ -54,18 +76,18 @@ class MouvementStock extends CommonObject
|
||||
* @param int $entrepot_id Id of warehouse
|
||||
* @param int $qty Qty of movement (can be <0 or >0 depending on parameter type)
|
||||
* @param int $type Direction of movement:
|
||||
* 0=input (stock increase after stock transfert), 1=output (stock decrease after stock transfer),
|
||||
* 0=input (stock increase by a stock transfer), 1=output (stock decrease after by a stock transfer),
|
||||
* 2=output (stock decrease), 3=input (stock increase)
|
||||
* Note that qty should be > 0 with 0 or 3, < 0 with 1 or 2.
|
||||
* @param int $price Unit price HT of product, used to calculate average weighted price (PMP in french). If 0, average weighted price is not changed.
|
||||
* @param string $label Label of stock movement
|
||||
* @param string $inventorycode Inventory code
|
||||
* @param string $datem Force date of movement
|
||||
* @param date $eatby eat-by date
|
||||
* @param date $sellby sell-by date
|
||||
* @param date $eatby eat-by date. Will be used if lot does not exists yet and will be created.
|
||||
* @param date $sellby sell-by date. Will be used if lot does not exists yet and will be created.
|
||||
* @param string $batch batch number
|
||||
* @param boolean $skip_batch If set to true, stock movement is done without impacting batch record
|
||||
* @param int $id_product_batch Id product_batch (when skip_batch is flase and we already know which record of product_batch to use)
|
||||
* @param int $id_product_batch Id product_batch (when skip_batch is false and we already know which record of product_batch to use)
|
||||
* @return int <0 if KO, 0 if fk_product is null, >0 if OK
|
||||
*/
|
||||
function _create($user, $fk_product, $entrepot_id, $qty, $type, $price=0, $label='', $inventorycode='', $datem='',$eatby='',$sellby='',$batch='',$skip_batch=false, $id_product_batch=0)
|
||||
@@ -75,7 +97,7 @@ class MouvementStock extends CommonObject
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
|
||||
$error = 0;
|
||||
dol_syslog(get_class($this)."::_create start userid=$user->id, fk_product=$fk_product, warehouse=$entrepot_id, qty=$qty, type=$type, price=$price, label=$label, inventorycode=$inventorycode, datem=".$datem.", eatby=".$eatby.", sellby=".$sellby.", batch=".$batch.", skip_batch=".$skip_batch);
|
||||
dol_syslog(get_class($this)."::_create start userid=$user->id, fk_product=$fk_product, warehouse_id=$entrepot_id, qty=$qty, type=$type, price=$price, label=$label, inventorycode=$inventorycode, datem=".$datem.", eatby=".$eatby.", sellby=".$sellby.", batch=".$batch.", skip_batch=".$skip_batch);
|
||||
|
||||
// Clean parameters
|
||||
if (empty($price)) $price=0;
|
||||
@@ -90,7 +112,7 @@ class MouvementStock extends CommonObject
|
||||
}
|
||||
if ($sellby < 0)
|
||||
{
|
||||
$this->errors[]='ErrorBadValueForParameterEatBy';
|
||||
$this->errors[]='ErrorBadValueForParameterSellBy';
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -315,7 +337,7 @@ class MouvementStock extends CommonObject
|
||||
$sql.= " '".$origintype."'";
|
||||
$sql.= ")";
|
||||
|
||||
dol_syslog(get_class($this)."::_create", LOG_DEBUG);
|
||||
dol_syslog(get_class($this)."::_create insert record into stock_mouvement", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql)
|
||||
{
|
||||
@@ -340,7 +362,7 @@ class MouvementStock extends CommonObject
|
||||
$sql = "SELECT rowid, reel FROM ".MAIN_DB_PREFIX."product_stock";
|
||||
$sql.= " WHERE fk_entrepot = ".$entrepot_id." AND fk_product = ".$fk_product; // This is a unique key
|
||||
|
||||
dol_syslog(get_class($this)."::_create", LOG_DEBUG);
|
||||
dol_syslog(get_class($this)."::_create check if a record already exists in product_stock", LOG_DEBUG);
|
||||
$resql=$this->db->query($sql);
|
||||
if ($resql)
|
||||
{
|
||||
@@ -405,7 +427,7 @@ class MouvementStock extends CommonObject
|
||||
$sql.= " (".$qty.", ".$entrepot_id.", ".$fk_product.")";
|
||||
}
|
||||
|
||||
dol_syslog(get_class($this)."::_create", LOG_DEBUG);
|
||||
dol_syslog(get_class($this)."::_create update stock value", LOG_DEBUG);
|
||||
$resql=$this->db->query($sql);
|
||||
if (! $resql)
|
||||
{
|
||||
@@ -444,7 +466,7 @@ class MouvementStock extends CommonObject
|
||||
$sql.= " stock=(SELECT SUM(ps.reel) FROM ".MAIN_DB_PREFIX."product_stock as ps WHERE ps.fk_product = p.rowid)";
|
||||
$sql.= " WHERE rowid = ".$fk_product;
|
||||
|
||||
dol_syslog(get_class($this)."::_create", LOG_DEBUG);
|
||||
dol_syslog(get_class($this)."::_create update AWP", LOG_DEBUG);
|
||||
$resql=$this->db->query($sql);
|
||||
if (! $resql)
|
||||
{
|
||||
@@ -488,6 +510,96 @@ class MouvementStock extends CommonObject
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load object in memory from the database
|
||||
*
|
||||
* @param int $id Id object
|
||||
*
|
||||
* @return int <0 if KO, 0 if not found, >0 if OK
|
||||
*/
|
||||
public function fetch($id)
|
||||
{
|
||||
dol_syslog(__METHOD__, LOG_DEBUG);
|
||||
|
||||
$sql = 'SELECT';
|
||||
$sql .= ' t.rowid,';
|
||||
$sql .= " t.tms,";
|
||||
$sql .= " t.datem,";
|
||||
$sql .= " t.fk_product,";
|
||||
$sql .= " t.fk_entrepot,";
|
||||
$sql .= " t.value,";
|
||||
$sql .= " t.price,";
|
||||
$sql .= " t.type_mouvement,";
|
||||
$sql .= " t.fk_user_author,";
|
||||
$sql .= " t.label,";
|
||||
$sql .= " t.fk_origin,";
|
||||
$sql .= " t.origintype,";
|
||||
$sql .= " t.inventorycode,";
|
||||
$sql .= " t.batch,";
|
||||
$sql .= " t.eatby,";
|
||||
$sql .= " t.sellby";
|
||||
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
|
||||
$sql.= ' WHERE 1 = 1';
|
||||
//if (null !== $ref) {
|
||||
//$sql .= ' AND t.ref = ' . '\'' . $ref . '\'';
|
||||
//} else {
|
||||
$sql .= ' AND t.rowid = ' . $id;
|
||||
//}
|
||||
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$numrows = $this->db->num_rows($resql);
|
||||
if ($numrows) {
|
||||
$obj = $this->db->fetch_object($resql);
|
||||
|
||||
$this->id = $obj->rowid;
|
||||
|
||||
$this->product_id = $obj->fk_product;
|
||||
$this->warehouse_id = $obj->fk_entrepot;
|
||||
$this->qty = $obj->value;
|
||||
$this->type = $obj->type_mouvement;
|
||||
|
||||
$this->tms = $this->db->jdate($obj->tms);
|
||||
$this->datem = $this->db->jdate($obj->datem);
|
||||
$this->price = $obj->price;
|
||||
$this->fk_user_author = $obj->fk_user_author;
|
||||
$this->label = $obj->label;
|
||||
$this->fk_origin = $obj->fk_origin;
|
||||
$this->origintype = $obj->origintype;
|
||||
$this->inventorycode = $obj->inventorycode;
|
||||
$this->batch = $obj->batch;
|
||||
$this->eatby = $this->db->jdate($obj->eatby);
|
||||
$this->sellby = $this->db->jdate($obj->sellby);
|
||||
}
|
||||
|
||||
// Retrieve all extrafields for invoice
|
||||
// fetch optionals attributes and labels
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
|
||||
$extrafields=new ExtraFields($this->db);
|
||||
$extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true);
|
||||
$this->fetch_optionals($this->id,$extralabels);
|
||||
|
||||
// $this->fetch_lines();
|
||||
|
||||
$this->db->free($resql);
|
||||
|
||||
if ($numrows) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
$this->errors[] = 'Error ' . $this->db->lasterror();
|
||||
dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
|
||||
|
||||
return - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create movement in database for all subproducts
|
||||
*
|
||||
@@ -592,8 +704,10 @@ class MouvementStock extends CommonObject
|
||||
*
|
||||
* @param int $id Id of product
|
||||
* @return int <0 if KO, nb of subproducts if OK
|
||||
* @deprecated A count($product->getChildsArbo($id,1)) is same. No reason to have this in this class.
|
||||
*/
|
||||
function nbOfSubProdcuts($id)
|
||||
/*
|
||||
function nbOfSubProducts($id)
|
||||
{
|
||||
$nbSP=0;
|
||||
|
||||
@@ -605,7 +719,7 @@ class MouvementStock extends CommonObject
|
||||
$nbSP=$obj->nb;
|
||||
}
|
||||
return $nbSP;
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Count number of product in stock before a specific date
|
||||
|
||||
@@ -534,7 +534,8 @@ if ($resql)
|
||||
|
||||
// Nb of products
|
||||
print '<tr><td>'.$langs->trans("NumberOfProducts").'</td><td>';
|
||||
print empty($calcproducts['nb'])?'0':$calcproducts['nb'];
|
||||
$valtoshow=price2num($calcproducts['nb'], 'MS');
|
||||
print empty($valtoshow)?'0':$valtoshow;
|
||||
print "</td></tr>";
|
||||
|
||||
print '</table>';
|
||||
|
||||
Reference in New Issue
Block a user