diff --git a/addons/stock/i18n/stock.pot b/addons/stock/i18n/stock.pot
index 962314de988..7836e552681 100644
--- a/addons/stock/i18n/stock.pot
+++ b/addons/stock/i18n/stock.pot
@@ -2675,7 +2675,7 @@ msgid "Scrap Move"
msgstr ""
#. module: stock
-#: help:stock.move,prodlot_id:0
+#: help:stock.move,lot_id:0
msgid "Serial number is used to put a serial number on the production"
msgstr ""
@@ -2790,7 +2790,7 @@ msgstr ""
#. module: stock
#: view:report.stock.inventory:0
-#: field:report.stock.inventory,prodlot_id:0
+#: field:report.stock.inventory,lot_id:0
#: report:stock.picking.list:0
msgid "Lot"
msgstr ""
@@ -3453,21 +3453,21 @@ msgstr ""
#: model:ir.model,name:stock.model_stock_production_lot
#: model:ir.ui.menu,name:stock.menu_action_production_lot_form
#: model:res.request.link,name:stock.req_link_tracking
-#: field:stock.change.product.qty,prodlot_id:0
+#: field:stock.change.product.qty,lot_id:0
#: field:stock.inventory.line,prod_lot_id:0
#: field:stock.inventory.line.split.lines,name:0
-#: field:stock.inventory.line.split.lines,prodlot_id:0
-#: field:stock.move,prodlot_id:0
+#: field:stock.inventory.line.split.lines,lot_id:0
+#: field:stock.move,lot_id:0
#: view:stock.move.split:0
#: field:stock.move.split.lines,name:0
-#: field:stock.move.split.lines,prodlot_id:0
-#: field:stock.partial.move.line,prodlot_id:0
-#: field:stock.partial.picking.line,prodlot_id:0
+#: field:stock.move.split.lines,lot_id:0
+#: field:stock.partial.move.line,lot_id:0
+#: field:stock.partial.picking.line,lot_id:0
#: report:stock.picking.list:0
#: view:stock.production.lot:0
#: field:stock.production.lot,name:0
#: field:stock.production.lot.revision,lot_id:0
-#: field:stock.report.prodlots,prodlot_id:0
+#: field:stock.report.prodlots,lot_id:0
msgid "Serial Number"
msgstr ""
diff --git a/addons/stock/partner.py b/addons/stock/partner.py
index 3aaf1c663e5..3b193cb447e 100644
--- a/addons/stock/partner.py
+++ b/addons/stock/partner.py
@@ -29,7 +29,6 @@ class res_partner(osv.osv):
relation='stock.location',
string="Customer Location",
help="This stock location will be used, instead of the default one, as the destination location for goods you send to this partner"),
-
'property_stock_supplier': fields.property(
type='many2one',
relation='stock.location',
@@ -37,5 +36,3 @@ class res_partner(osv.osv):
help="This stock location will be used, instead of the default one, as the source location for goods you receive from the current partner"),
}
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock/product.py b/addons/stock/product.py
index 9ba8001b525..fec2d66f3df 100644
--- a/addons/stock/product.py
+++ b/addons/stock/product.py
@@ -313,11 +313,11 @@ class product_product(osv.osv):
where += where_add
- prodlot_id = context.get('prodlot_id', False)
+ lot_id = context.get('lot_id', False)
prodlot_clause = ''
- if prodlot_id:
- prodlot_clause = ' and prodlot_id = %s '
- where += [prodlot_id]
+ if lot_id:
+ prodlot_clause = ' and lot_id = %s '
+ where += [lot_id]
# TODO: perhaps merge in one query.
if 'in' in what:
diff --git a/addons/stock/report/picking.rml b/addons/stock/report/picking.rml
index 084f2a8381d..c0172e2efdc 100644
--- a/addons/stock/report/picking.rml
+++ b/addons/stock/report/picking.rml
@@ -246,7 +246,7 @@
[[ get_product_desc(move_lines) ]]
- [[ (move_lines.prodlot_id and move_lines.prodlot_id.name) or '' ]]
+ [[ (move_lines.lot_id and move_lines.lot_id.name) or '' ]]
Waiting Availability[[ move_lines.state == 'confirmed' and ' ' or removeParentNode('para') ]]
@@ -276,7 +276,7 @@
[[ get_product_desc(move_lines) ]]
- [[ (move_lines.prodlot_id and move_lines.prodlot_id.name) or '' ]]
+ [[ (move_lines.lot_id and move_lines.lot_id.name) or '' ]]
[[ (picking.type == 'in' or removeParentNode('para')) ]][[ move_lines.state == 'done' and 'Received' or move_lines.state]]
diff --git a/addons/stock/report/report_stock.py b/addons/stock/report/report_stock.py
index d4bbb3ab127..8d5229815c2 100644
--- a/addons/stock/report/report_stock.py
+++ b/addons/stock/report/report_stock.py
@@ -21,118 +21,8 @@
from openerp.osv import fields, osv
from openerp.tools.translate import _
-from openerp import tools
from openerp.tools.sql import drop_view_if_exists
-class stock_report_prodlots(osv.osv):
- _name = "stock.report.prodlots"
- _description = "Stock report by serial number"
- _auto = False
- _columns = {
- 'qty': fields.float('Quantity', readonly=True),
- 'location_id': fields.many2one('stock.location', 'Location', readonly=True, select=True),
- 'product_id': fields.many2one('product.product', 'Product', readonly=True, select=True),
- 'prodlot_id': fields.many2one('stock.production.lot', 'Serial Number', readonly=True, select=True),
- }
-
- def init(self, cr):
- drop_view_if_exists(cr, 'stock_report_prodlots')
- cr.execute("""
- create or replace view stock_report_prodlots as (
- select max(id) as id,
- location_id,
- product_id,
- prodlot_id,
- sum(qty) as qty
- from (
- select -max(sm.id) as id,
- sm.location_id,
- sm.product_id,
- sm.prodlot_id,
- -sum(sm.product_qty /uo.factor) as qty
- from stock_move as sm
- left join stock_location sl
- on (sl.id = sm.location_id)
- left join product_uom uo
- on (uo.id=sm.product_uom)
- where state = 'done'
- group by sm.location_id, sm.product_id, sm.product_uom, sm.prodlot_id
- union all
- select max(sm.id) as id,
- sm.location_dest_id as location_id,
- sm.product_id,
- sm.prodlot_id,
- sum(sm.product_qty /uo.factor) as qty
- from stock_move as sm
- left join stock_location sl
- on (sl.id = sm.location_dest_id)
- left join product_uom uo
- on (uo.id=sm.product_uom)
- where sm.state = 'done'
- group by sm.location_dest_id, sm.product_id, sm.product_uom, sm.prodlot_id
- ) as report
- group by location_id, product_id, prodlot_id
- )""")
-
- def unlink(self, cr, uid, ids, context=None):
- raise osv.except_osv(_('Error!'), _('You cannot delete any record!'))
-
-
-class stock_report_tracklots(osv.osv):
- _name = "stock.report.tracklots"
- _description = "Stock report by logistic serial number"
- _auto = False
- _columns = {
- 'name': fields.float('Quantity', readonly=True),
- 'location_id': fields.many2one('stock.location', 'Location', readonly=True, select=True),
- 'product_id': fields.many2one('product.product', 'Product', readonly=True, select=True),
- 'tracking_id': fields.many2one('stock.tracking', 'Logistic Serial Number', readonly=True, select=True),
- }
-
- def init(self, cr):
- drop_view_if_exists(cr, 'stock_report_tracklots')
- cr.execute("""
- create or replace view stock_report_tracklots as (
-
- select max(id) as id,
- location_id,
- product_id,
- tracking_id,
- sum(qty) as name
- from (
- select -max(sm.id) as id,
- sm.location_id,
- sm.product_id,
- sm.tracking_id,
- -sum(sm.product_qty /uo.factor) as qty
- from stock_move as sm
- left join stock_location sl
- on (sl.id = sm.location_id)
- left join product_uom uo
- on (uo.id=sm.product_uom)
- where state = 'done'
- group by sm.location_id, sm.product_id, sm.product_uom, sm.tracking_id
- union all
- select max(sm.id) as id,
- sm.location_dest_id as location_id,
- sm.product_id,
- sm.tracking_id,
- sum(sm.product_qty /uo.factor) as qty
- from stock_move as sm
- left join stock_location sl
- on (sl.id = sm.location_dest_id)
- left join product_uom uo
- on (uo.id=sm.product_uom)
- where sm.state = 'done'
- group by sm.location_dest_id, sm.product_id, sm.product_uom, sm.tracking_id
- ) as report
- group by location_id, product_id, tracking_id
- )""")
-
- def unlink(self, cr, uid, ids, context=None):
- raise osv.except_osv(_('Error!'), _('You cannot delete any record!'))
-
-
class report_stock_lines_date(osv.osv):
_name = "report.stock.lines.date"
_description = "Dates of Inventories"
diff --git a/addons/stock/report/report_stock_move.py b/addons/stock/report/report_stock_move.py
index b6b3b91facf..4cb9c0f04e8 100644
--- a/addons/stock/report/report_stock_move.py
+++ b/addons/stock/report/report_stock_move.py
@@ -52,8 +52,6 @@ class report_stock_move(osv.osv):
'day_diff':fields.float('Execution Lead Time (Days)',readonly=True, digits_compute=dp.get_precision('Shipping Delay'), group_operator="avg"),
'stock_journal': fields.many2one('stock.journal','Stock Journal', select=True),
}
-
-
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_stock_move')
cr.execute("""
@@ -142,12 +140,12 @@ class report_stock_move(osv.osv):
+# FP Note: TODO: drop this table and use the stock.move table instead
class report_stock_inventory(osv.osv):
_name = "report.stock.inventory"
_description = "Stock Statistics"
_auto = False
_order = 'date desc'
-
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
res = super(report_stock_inventory, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)
product_obj = self.pool.get("product.product")
@@ -188,205 +186,37 @@ class report_stock_inventory(osv.osv):
else:
res[line.id] = prodbrow[(line.company_id.id, line.product_id.id)].standard_price * line.product_qty
return res
-
_columns = {
- 'date': fields.datetime('Date', readonly=True),
- 'year': fields.char('Year', size=4, readonly=True),
- 'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
- ('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
- ('10','October'), ('11','November'), ('12','December')], 'Month', readonly=True),
- 'partner_id':fields.many2one('res.partner', 'Partner', readonly=True),
'product_id':fields.many2one('product.product', 'Product', readonly=True),
'product_categ_id':fields.many2one('product.category', 'Product Category', readonly=True),
'location_id': fields.many2one('stock.location', 'Location', readonly=True),
- 'prodlot_id': fields.many2one('stock.production.lot', 'Lot', readonly=True),
+ 'lot_id': fields.many2one('stock.production.lot', 'Lot', readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'product_qty':fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), help="Qty Remaining", readonly=True),
'value' : fields.float('Total Value', digits_compute=dp.get_precision('Account'), required=True),
- 'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Confirmed'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Status', readonly=True, select=True,
- help='When the stock move is created it is in the \'Draft\' state.\n After that it is set to \'Confirmed\' state.\n If stock is available state is set to \'Avaiable\'.\n When the picking it done the state is \'Done\'.\
- \nThe state is \'Waiting\' if the move is waiting for another one.'),
- 'location_type': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Type', required=True),
'scrap_location': fields.boolean('scrap'),
'inventory_value': fields.function(_calc_moves, string="Inventory Value", type='float', readonly=True),
- 'ref':fields.text('Reference', readonly=True),
- 'location_dest_type': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Destination Type'),
- 'location_src_type': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Source Type'),
+ 'location_type': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Source Type'),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_stock_inventory')
cr.execute("""
CREATE OR REPLACE view report_stock_inventory AS (
SELECT
- sq.id as id, sq.in_date as date,
- to_char(sq.in_date, 'YYYY') as year,
- to_char(sq.in_date, 'MM') as month,
- m.partner_id as partner_id, sq.location_id as location_id,
- sq.product_id as product_id, pt.categ_id as product_categ_id, location.usage as location_type, location.scrap_location as scrap_location,
+ sq.id as id,
+ sq.in_date as date,
+ sq.location_id as location_id,
+ sq.product_id as product_id,
+ pt.categ_id as product_categ_id,
+ location.scrap_location as scrap_location,
sq.company_id,
- m.state as state, sq.prodlot_id as prodlot_id,
- sq.price_unit * sq.qty as value,
+ sq.lot_id as lot_id,
+ sq.cost * sq.qty as value,
sq.qty as product_qty,
- p.name as ref,
- location_dest.usage as location_dest_type,
- location.usage as location_src_type
+ location.usage as location_type
FROM stock_quant sq
- LEFT JOIN stock_quant_move_rel qm ON (qm.quant_id = sq.id)
- LEFT JOIN stock_move m ON (qm.move_id = m.id)
- LEFT JOIN stock_picking p ON (m.picking_id=p.id)
- LEFT JOIN stock_location location ON (m.location_id = location.id)
- LEFT JOIN stock_location location_dest ON (m.location_dest_id = location_dest.id)
+ LEFT JOIN stock_location location ON (sq.location_id = location.id)
LEFT JOIN product_template pt ON (sq.product_id=pt.id)
- WHERE (location_dest.usage = 'internal' and location.usage <> 'internal') or (sq.qty < 0) or (sq.propagated_from_id IS NOT NULL)
- GROUP BY
- sq.id, sq.product_id, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id,
- sq.prodlot_id, sq.in_date, m.state, location.usage, location_dest.usage, location.scrap_location, sq.company_id, to_char(sq.in_date, 'YYYY'), to_char(sq.in_date, 'MM'), p.name
);
""")
-
-
-#
-# CREATE OR REPLACE view report_stock_inventory AS (
-#
-# SELECT
-# m.id as id, m.date as date,
-# to_char(m.date, 'YYYY') as year,
-# to_char(m.date, 'MM') as month,
-# m.partner_id as partner_id, m.location_dest_id as location_id,
-# m.product_id as product_id, pt.categ_id as product_categ_id, l.usage as location_type, l.scrap_location as scrap_location,
-# m.company_id,
-# m.state as state, m.prodlot_id as prodlot_id,
-# coalesce(sum(m.price_unit * m.qty_remaining)::decimal, 0.0) as value,
-# coalesce(sum(m.qty_remaining * pu.factor / pu2.factor)::decimal, 0.0) as product_qty,
-# p.name as ref,
-# l.usage as location_dest_type,
-# l_other.usage as location_src_type
-# FROM
-# stock_move m
-# LEFT JOIN stock_picking p ON (m.picking_id=p.id)
-# LEFT JOIN product_product pp ON (m.product_id=pp.id)
-# LEFT JOIN product_template pt ON (pp.product_tmpl_id=pt.id)
-# LEFT JOIN product_uom pu ON (pt.uom_id=pu.id)
-# LEFT JOIN product_uom pu2 ON (m.product_uom=pu2.id)
-# LEFT JOIN product_uom u ON (m.product_uom=u.id)
-# LEFT JOIN stock_location l ON (m.location_dest_id=l.id)
-# LEFT JOIN stock_location l_other ON (m.location_id=l_other.id)
-# WHERE m.state != 'cancel'
-# GROUP BY
-# m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id,
-# m.prodlot_id, m.date, m.state, l.usage, l_other.usage, l.scrap_location, m.company_id, pt.uom_id, to_char(m.date, 'YYYY'), to_char(m.date, 'MM'), p.name
-# );
-
-
-
-
-
-class report_stock_valuation(osv.osv):
- _name = "report.stock.valuation"
- _description = "Stock Valuation Statistics"
- _auto = False
-
-
-
-
- _order = 'date desc'
- _columns = {
- 'date': fields.datetime('Date', readonly=True),
- 'year': fields.char('Year', size=4, readonly=True),
- 'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
- ('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
- ('10','October'), ('11','November'), ('12','December')], 'Month', readonly=True),
- 'partner_id':fields.many2one('res.partner', 'Partner', readonly=True),
- 'product_id':fields.many2one('product.product', 'Product', readonly=True),
- 'product_categ_id':fields.many2one('product.category', 'Product Category', readonly=True),
- 'location_id': fields.many2one('stock.location', 'Location', readonly=True),
- 'prodlot_id': fields.many2one('stock.production.lot', 'Lot', readonly=True),
- 'company_id': fields.many2one('res.company', 'Company', readonly=True),
- 'product_qty':fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), readonly=True),
- 'value' : fields.float('Value', digits_compute=dp.get_precision('Account'), required=True),
- 'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Confirmed'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Status', readonly=True, select=True,
- help='When the stock move is created it is in the \'Draft\' state.\n After that it is set to \'Confirmed\' state.\n If stock is available state is set to \'Avaiable\'.\n When the picking it done the state is \'Done\'.\
- \nThe state is \'Waiting\' if the move is waiting for another one.'),
- 'location_type': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Type', required=True),
- 'scrap_location': fields.boolean('scrap'),
- 'name': fields.text('Reference', readonly=True),
- 'price_unit': fields.float('Unit price', digits_compute=dp.get_precision('Account')),
- 'qty_remaining': fields.float('Qty remaining'),
- 'location_dest_type': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Destination Type'),
- 'location_src_type': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Source Type'),
- 'match': fields.many2one('stock.move', 'Match', readonly=True),
- 'related_move_in': fields.related('match', 'picking_id', 'name', type='text', string="Original move", readonly=True),
- }
-
-
-
- def init(self, cr):
- tools.drop_view_if_exists(cr, 'report_stock_valuation')
- cr.execute("""
-CREATE OR REPLACE view report_stock_valuation AS (
- (SELECT
- min(mm.id) as id, m.date as date,
- to_char(m.date, 'YYYY') as year,
- to_char(m.date, 'MM') as month,
- m.partner_id as partner_id, m.location_id as location_id,
- m.product_id as product_id, pt.categ_id as product_categ_id, l.usage as location_type, l.scrap_location as scrap_location,
- m.company_id, m.qty_remaining as qty_remaining,
- m.state as state, m.prodlot_id as prodlot_id,
- p.name as name,
- mm.move_in_id as match,
- coalesce(mm.price_unit_out * pu2.factor / pu.factor, 0.0) as price_unit,
- coalesce(sum(-mm.price_unit_out * mm.qty)::decimal, 0.0) as value,
- coalesce(sum(-mm.qty * pu.factor / pu2.factor)::decimal, 0.0) as product_qty,
- l_other.usage as location_dest_type,
- l.usage as location_src_type
- FROM
- stock_move_matching mm, stock_move m
- LEFT JOIN stock_picking p ON (m.picking_id=p.id)
- LEFT JOIN product_product pp ON (m.product_id=pp.id)
- LEFT JOIN product_template pt ON (pp.product_tmpl_id=pt.id)
- LEFT JOIN product_uom pu ON (pt.uom_id=pu.id)
- LEFT JOIN product_uom pu2 ON (m.product_uom=pu2.id)
- LEFT JOIN product_uom u ON (m.product_uom=u.id)
- LEFT JOIN stock_location l ON (m.location_id=l.id)
- LEFT JOIN stock_location l_other ON (m.location_dest_id=l_other.id)
- WHERE m.state != 'cancel' and mm.move_out_id=m.id
- GROUP BY
- p.name, mm.id, mm.move_out_id, m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id,
- m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id, to_char(m.date, 'YYYY'), to_char(m.date, 'MM'),
- pu2.factor, pu.factor, m.qty_remaining, l_other.usage
-) UNION ALL (
- SELECT
- -min(m.id) as id, m.date as date,
- to_char(m.date, 'YYYY') as year,
- to_char(m.date, 'MM') as month,
- m.partner_id as partner_id, m.location_dest_id as location_id,
- m.product_id as product_id, pt.categ_id as product_categ_id, l.usage as location_type, l.scrap_location as scrap_location,
- m.company_id, m.qty_remaining as qty_remaining,
- m.state as state, m.prodlot_id as prodlot_id,
- p.name as name, 0 as match,
- coalesce(m.price_unit * pu2.factor / pu.factor, 0.0) as price_unit,
- coalesce(sum(m.price_unit * m.product_qty)::decimal, 0.0) as value,
- coalesce(sum(m.product_qty * pu.factor / pu2.factor)::decimal, 0.0) as product_qty,
- l.usage as location_dest_type,
- l_other.usage as location_src_type
- FROM
- stock_move m
- LEFT JOIN stock_picking p ON (m.picking_id=p.id)
- LEFT JOIN product_product pp ON (m.product_id=pp.id)
- LEFT JOIN product_template pt ON (pp.product_tmpl_id=pt.id)
- LEFT JOIN product_uom pu ON (pt.uom_id=pu.id)
- LEFT JOIN product_uom pu2 ON (m.product_uom=pu2.id)
- LEFT JOIN product_uom u ON (m.product_uom=u.id)
- LEFT JOIN stock_location l ON (m.location_dest_id=l.id)
- LEFT JOIN stock_location l_other ON (m.location_id=l_other.id)
- WHERE m.state != 'cancel'
- GROUP BY
- p.name, m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id,
- m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id, to_char(m.date, 'YYYY'), to_char(m.date, 'MM'),
- pu2.factor, pu.factor, m.qty_remaining, l_other.usage
- )
-);
- """)
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock/report/report_stock_move_view.xml b/addons/stock/report/report_stock_move_view.xml
index 06412df790e..4675f555860 100644
--- a/addons/stock/report/report_stock_move_view.xml
+++ b/addons/stock/report/report_stock_move_view.xml
@@ -106,19 +106,12 @@
report.stock.inventory
-
-
-
-
-
-
-
-
+
@@ -141,37 +134,22 @@
report.stock.inventory
-
-
-
-
-
-
-
+
-
-
-
+
-
-
-
-
@@ -190,97 +168,5 @@
id="menu_action_stock_inventory_report"
parent="next_id_61" sequence="4"/>
-
-
- report.stock.valuation.tree
- report.stock.valuation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- report.stock.valuation.graph
- report.stock.valuation
-
-
-
-
-
-
-
-
-
- report.stock.valuation.search
- report.stock.valuation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Valuation History
- report.stock.valuation
- form
- tree,graph
-
- {'contact_display': 'partner', 'search_default_real':1,
-'search_default_location_type_internal':1,'group_by':[]}
- Stock Valuation Analysis allows you to easily check and analyse your company stock levels. The difference with the Inventory Analysis, is that
- the stock is calculated based on the prices of the stock moves depending on the cost method of the product (FIFO/LIFO/Average/standard) and not just the standard price of the product.
- Sort and group by selection criteria in order to better analyse and manage your company activities.
-
-
-
\ No newline at end of file
+
diff --git a/addons/stock/report/report_stock_view.xml b/addons/stock/report/report_stock_view.xml
index e8bb6621355..b5e1f0bcb21 100644
--- a/addons/stock/report/report_stock_view.xml
+++ b/addons/stock/report/report_stock_view.xml
@@ -2,12 +2,6 @@
-
-
report.stock.lines.date.tree
@@ -59,16 +53,5 @@
-
- stock.location.graph
- stock.location
-
-
-
-
-
-
-
-
diff --git a/addons/stock/security/ir.model.access.csv b/addons/stock/security/ir.model.access.csv
index 963ed736b12..eb3738cd002 100644
--- a/addons/stock/security/ir.model.access.csv
+++ b/addons/stock/security/ir.model.access.csv
@@ -8,9 +8,6 @@ access_stock_location_manager,stock.location.manager,model_stock_location,stock.
access_stock_location_user,stock.location.user,model_stock_location,base.group_user,1,0,0,0
access_stock_journal_user,stock.journal.user,model_stock_journal,base.group_user,1,0,0,0
access_stock_journal_manager,stock.journal.manager,model_stock_journal,stock.group_stock_manager,1,1,1,1
-access_stock_tracking_user,stock.tracking user,model_stock_tracking,stock.group_stock_user,1,1,1,1
-access_stock_tracking_manager,stock.tracking manager,model_stock_tracking,stock.group_stock_manager,1,0,0,0
-access_stock_tracking_sales_user,stock.tracking sales.user,model_stock_tracking,base.group_sale_salesman,1,1,1,0
access_stock_picking_user,stock.picking user,model_stock_picking,stock.group_stock_user,1,1,1,1
access_stock_picking_in_user,stock.picking.in,model_stock_picking_in,stock.group_stock_user,1,1,1,1
access_stock_picking_out_user,stock.picking.out,model_stock_picking_out,stock.group_stock_user,1,1,1,1
@@ -30,7 +27,6 @@ access_stock_location_sale_manager,stock.location sale manager,model_stock_locat
access_stock_location_stock_manager,stock.location stock manager,model_stock_location,stock.group_stock_manager,1,0,0,0
access_stock_lines_date_user,report.stock.lines.date user,model_report_stock_lines_date,stock.group_stock_user,1,0,0,0
access_stock_lines_date_manager,report.stock.lines.date manager,model_report_stock_lines_date,stock.group_stock_manager,1,1,1,1
-access_stock_report_tracklots,stock.report.tracklots,model_stock_report_tracklots,stock.group_stock_user,1,1,1,1
access_report_stock_move_user,report.stock.move user,model_report_stock_move,stock.group_stock_user,1,0,0,0
access_report_stock_move_manager,report.stock.move manager,model_report_stock_move,stock.group_stock_manager,1,1,1,1
access_report_stock_inventory_user,report.stock.inventory user,model_report_stock_inventory,stock.group_stock_user,1,1,1,1
@@ -60,5 +56,3 @@ access_product_pricelist_version_stock_manager,product.pricelist.version stock_m
access_product_pricelist_item_stock_manager,product.pricelist.item stock_manager,product.model_product_pricelist_item,stock.group_stock_manager,1,1,1,1
access_account_account_stock_manager,account.account stock manager,account.model_account_account,stock.group_stock_manager,1,0,0,0
access_board_stock_user,board.board user,board.model_board_board,stock.group_stock_user,1,1,0,0
-access_stock_move_matching_manager,stock.move.matching manager,model_stock_move_matching,stock.group_stock_manager,1,1,1,1
-access_stock_move_matching_user,stock.move.matching user,model_stock_move_matching,stock.group_stock_user,1,1,1,0
diff --git a/addons/stock/security/stock_security.xml b/addons/stock/security/stock_security.xml
index fd5a607e98e..10ae6a16d59 100644
--- a/addons/stock/security/stock_security.xml
+++ b/addons/stock/security/stock_security.xml
@@ -80,11 +80,5 @@
['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
-
- Stock move matching
-
-
- [('1','=','1')]
-
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 95c8f6099a3..4816069884e 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -163,7 +163,7 @@ class stock_quant(osv.osv):
'qty': fields.float('Quantity', required=True, help="Quantity of products in this quant, in the default unit of measure of the product"),
'package_id': fields.many2one('stock.quant.package', help="The package containing this quant"),
'reservation_id': fields.many2one('stock.move', 'Reserved for Move', help="Is this quant reserved for a stock.move?"),
- 'prodlot_id': fields.many2one('stock.production.lot', 'Lot'),
+ 'lot_id': fields.many2one('stock.production.lot', 'Lot'),
'cost': fields.float('Unit Cost'),
'create_date': fields.datetime('Creation Date'),
@@ -177,7 +177,7 @@ class stock_quant(osv.osv):
'propagated_to_ids': fields.one2many('stock.quant', 'propagated_from_id', 'Linked Quants', help = 'The negative quant this is coming from'),
}
- def quants_reserve(self, cr, uid, quants, move_id, context=None):
+ def quants_reserve(self, cr, uid, quants, move, context=None):
toreserve = []
for quant,qty in quants:
if not quant: continue
@@ -185,19 +185,26 @@ class stock_quant(osv.osv):
toreserve.append(quant.id)
return self.write(cr, uid, toreserve, {'reservation_id': move.id}, context=context)
- def quants_move(self, cr, uid, quants, move_id, context=None):
+ def quants_move(self, cr, uid, quants, move, context=None):
for quant,qty in quants:
+ location_from = quant and quant.location_id
if not quant:
- quant = self._quant_create(cr, uid, qty, move_id, context=context)
+ quant = self._quant_create(cr, uid, qty, move, context=context)
else:
self._quant_split(cr, uid, quant, qty, context=context)
self._quant_reconcile_negative(cr, uid, quant, context=context)
+
+ # FP Note: improve this using preferred locations
+ location_to = move.location_dest_id
+
self.write(cr, uid, [quant.id], {
- 'location_id': move.location_dest_id.id,
+ 'location_id': location_to.id,
'reservation_id': move.move_dest_id and move.move_dest_id.id or False,
'history_ids': [(4, move.id)]
})
+ self._account_entry_move(cr, uid, quant, location_from, location_to, move, context=context)
+
# FP Note: TODO: implement domain preference that tries to retrieve first with this domain
def quants_get(self, cr, uid, location_id, product_id, qty, domain=[('qty','>',0.0)], domain_preference=[], context=None):
"""
@@ -206,7 +213,7 @@ class stock_quant(osv.osv):
:location_id: child_of this location_id
:product_id: id of product
:qty in UoM of product
- :prodlot_id NOT USED YET !
+ :lot_id NOT USED YET !
"""
removal_strategy = self.pool.get('stock.location').get_removal_strategy(cr, uid, location_id, product_id, context=context) or 'fifo'
if removal_strategy=='fifo':
@@ -230,7 +237,7 @@ class stock_quant(osv.osv):
'qty': product_uom_qty,
'history_ids': [(4, move.id)],
'in_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- 'prodlot_id': move.prodlot_id.id,
+ 'lot_id': move.lot_id.id,
'company_id': move.company_id.id,
}
quant_id = self.create(cr, uid, vals, context=context)
@@ -313,6 +320,243 @@ class stock_quant(osv.osv):
return self._quants_get_order(cr, uid, location_id, product_id, quantity,
domain, 'in_date desc', context=context)
+ """
+ Accounting Valuation Entries
+
+ location_from: can be None if it's a new quant
+ """
+ def _account_entry_move(cr, uid, quant, location_from, location_to, move, context=None):
+ pass
+
+ def _account_entry_price_adjusment(cr, uid, quant, newprice, context=None):
+ pass
+
+
+ # Return the company owning the location if any
+ def _location_owner(cr, uid, quant, location, context=context):
+ return location and (location.usage == 'internal') and location.company_id or False
+
+ def _account_entry_move(cr, uid, quant, location_from, location_to, move, context=None):
+ if quant.product_id.valuation <> 'realtime':
+ return False
+ company_from = self._location_owner(cr, uid, quant, location_from, context=context)
+ company_to = self._location_owner(cr, uid, quant, location_to, context=context)
+ if company_from == company_to:
+ return False
+
+ # Products arriving in the company
+ if company_to:
+ pass
+
+
+ # Products leaving the company
+ if company_from:
+ pass
+
+
+ # FP Note: all accounting valuation stuff must be on the quant
+ #def _get_accounting_data_for_valuation(self, cr, uid, move, context=None):
+ # """
+ # Return the accounts and journal to use to post Journal Entries for the real-time
+ # valuation of the move.
+
+ # :param context: context dictionary that can explicitly mention the company to consider via the 'force_company' key
+ # :raise: osv.except_osv() is any mandatory account or journal is not defined.
+ # """
+ # product_obj=self.pool.get('product.product')
+ # accounts = product_obj.get_product_accounts(cr, uid, move.product_id.id, context)
+ # if move.location_id.valuation_out_account_id:
+ # acc_src = move.location_id.valuation_out_account_id.id
+ # else:
+ # acc_src = accounts['stock_account_input']
+
+ # if move.location_dest_id.valuation_in_account_id:
+ # acc_dest = move.location_dest_id.valuation_in_account_id.id
+ # else:
+ # acc_dest = accounts['stock_account_output']
+
+ # acc_valuation = accounts.get('property_stock_valuation_account_id', False)
+ # journal_id = accounts['stock_journal']
+
+ # if acc_dest == acc_valuation:
+ # raise osv.except_osv(_('Error!'), _('Cannot create Journal Entry, Output Account of this product and Valuation account on category of this product are same.'))
+
+ # if acc_src == acc_valuation:
+ # raise osv.except_osv(_('Error!'), _('Cannot create Journal Entry, Input Account of this product and Valuation account on category of this product are same.'))
+
+ # if not acc_src:
+ # raise osv.except_osv(_('Error!'), _('Please define stock input account for this product or its category: "%s" (id: %d)') % \
+ # (move.product_id.name, move.product_id.id,))
+ # if not acc_dest:
+ # raise osv.except_osv(_('Error!'), _('Please define stock output account for this product or its category: "%s" (id: %d)') % \
+ # (move.product_id.name, move.product_id.id,))
+ # if not journal_id:
+ # raise osv.except_osv(_('Error!'), _('Please define journal on the product category: "%s" (id: %d)') % \
+ # (move.product_id.categ_id.name, move.product_id.categ_id.id,))
+ # if not acc_valuation:
+ # raise osv.except_osv(_('Error!'), _('Please define inventory valuation account on the product category: "%s" (id: %d)') % \
+ # (move.product_id.categ_id.name, move.product_id.categ_id.id,))
+ # return journal_id, acc_src, acc_dest, acc_valuation
+
+
+ ##We can use a preliminary type
+ #def get_reference_amount(self, cr, uid, move, qty, context=None):
+ # # if product is set to average price and a specific value was entered in the picking wizard,
+ # # we use it
+
+ # # by default the reference currency is that of the move's company
+ # reference_currency_id = move.company_id.currency_id.id
+ #
+ # #I use
+ # if move.product_id.cost_method != 'standard' and move.price_unit:
+ # reference_amount = move.product_qty * move.price_unit #Using move.price_qty instead of qty to have correct amount
+ # reference_currency_id = move.price_currency_id.id or reference_currency_id
+
+ # # Otherwise we default to the company's valuation price type, considering that the values of the
+ # # valuation field are expressed in the default currency of the move's company.
+ # else:
+ # if context is None:
+ # context = {}
+ # currency_ctx = dict(context, currency_id = move.company_id.currency_id.id)
+ # amount_unit = move.product_id.price_get('standard_price', context=currency_ctx)[move.product_id.id]
+ # reference_amount = amount_unit * qty
+ #
+ # return reference_amount, reference_currency_id
+
+
+ #def _get_reference_accounting_values_for_valuation(self, cr, uid, move, context=None):
+ # """
+ # Return the reference amount and reference currency representing the inventory valuation for this move.
+ # These reference values should possibly be converted before being posted in Journals to adapt to the primary
+ # and secondary currencies of the relevant accounts.
+ # """
+ # product_uom_obj = self.pool.get('product.uom')
+
+ # default_uom = move.product_id.uom_id.id
+ # qty = product_uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, default_uom)
+ #
+ # reference_amount, reference_currency_id = self.get_reference_amount(cr, uid, move, qty, context=context)
+ # return reference_amount, reference_currency_id
+
+
+ #
+
+
+ #def _create_product_valuation_moves(self, cr, uid, move, matches, context=None):
+ # """
+ # Generate the appropriate accounting moves if the product being moved is subject
+ # to real_time valuation tracking, and the source or the destination location is internal (not both)
+ # This means an in or out move.
+ #
+ # Depending on the matches it will create the necessary moves
+ # """
+ # ctx = context.copy()
+ # ctx['force_company'] = move.company_id.id
+ # valuation = self.pool.get("product.product").browse(cr, uid, move.product_id.id, context=ctx).valuation
+ # move_obj = self.pool.get('account.move')
+ # if valuation == 'real_time':
+ # if context is None:
+ # context = {}
+ # company_ctx = dict(context,force_company=move.company_id.id)
+ # journal_id, acc_src, acc_dest, acc_valuation = self._get_accounting_data_for_valuation(cr, uid, move, context=company_ctx)
+ # reference_amount, reference_currency_id = self._get_reference_accounting_values_for_valuation(cr, uid, move, context=company_ctx)
+ # account_moves = []
+ # # Outgoing moves (or cross-company output part)
+ # if move.location_id.company_id \
+ # and (move.location_id.usage == 'internal' and move.location_dest_id.usage != 'internal'):
+ # #returning goods to supplier
+ # if move.location_dest_id.usage == 'supplier':
+ # account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, matches, acc_valuation, acc_src, reference_amount, reference_currency_id, 'out', context=company_ctx))]
+ # else:
+ # account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, matches, acc_valuation, acc_dest, reference_amount, reference_currency_id, 'out', context=company_ctx))]
+
+ # # Incoming moves (or cross-company input part)
+ # if move.location_dest_id.company_id \
+ # and (move.location_id.usage != 'internal' and move.location_dest_id.usage == 'internal'):
+ # #goods return from customer
+ # if move.location_id.usage == 'customer':
+ # account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, matches, acc_dest, acc_valuation, reference_amount, reference_currency_id, 'in', context=company_ctx))]
+ # else:
+ # account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, matches, acc_src, acc_valuation, reference_amount, reference_currency_id, 'in', context=company_ctx))]
+ # if matches and move.product_id.cost_method in ('fifo', 'lifo'):
+ # outs = {}
+ # match_obj = self.pool.get("stock.move.matching")
+ # for match in match_obj.browse(cr, uid, matches, context=context):
+ # if match.move_out_id.id in outs:
+ # outs[match.move_out_id.id] += [match.id]
+ # else:
+ # outs[match.move_out_id.id] = [match.id]
+ # #When in stock was negative, you will get matches for the in also:
+ # account_moves_neg = []
+ # for out_mov in self.browse(cr, uid, outs.keys(), context=context):
+ # journal_id_out, acc_src_out, acc_dest_out, acc_valuation_out = self._get_accounting_data_for_valuation(cr, uid, out_mov, context=company_ctx)
+ # reference_amount_out, reference_currency_id_out = self._get_reference_accounting_values_for_valuation(cr, uid, out_mov, context=company_ctx)
+ # if out_mov.location_dest_id.usage == 'supplier':
+ # # Is not the way it should be with acc_valuation
+ # account_moves_neg += [(journal_id_out, self._create_account_move_line(cr, uid, out_mov, outs[out_mov.id], acc_valuation_out, acc_src_out, reference_amount_out, reference_currency_id_out, 'out', context=company_ctx))]
+ # else:
+ # account_moves_neg += [(journal_id_out, self._create_account_move_line(cr, uid, out_mov, outs[out_mov.id], acc_valuation_out, acc_dest_out, reference_amount_out, reference_currency_id_out, 'out', context=company_ctx))]
+ # #Create account moves for outs which made stock go negative
+ # for j_id, move_lines in account_moves_neg:
+ # move_obj.create(cr, uid,
+ # {'journal_id': j_id,
+ # 'line_id': move_lines,
+ # 'ref': out_mov.picking_id and out_mov.picking_id.name,
+ # })
+ # for j_id, move_lines in account_moves:
+ # move_obj.create(cr, uid,
+ # {
+ # 'journal_id': j_id,
+ # 'line_id': move_lines,
+ # 'ref': move.picking_id and move.picking_id.name})
+
+ #def _create_account_move_line(self, cr, uid, quant, src_account_id, dest_account_id, context=None):
+ # """
+ # Generate the account.move.line values to post to track the stock valuation difference due to the
+ # processing of the given stock move.
+ # """
+ # move_list = []
+ # # Consists of access rights
+ # # TODO Check if amount_currency is not needed
+ # match_obj = self.pool.get("stock.move.matching")
+ # if type == 'out' and move.product_id.cost_method in ['real']:
+ # for match in match_obj.browse(cr, uid, matches, context=context):
+ # move_list += [(match.qty, match.qty * match.price_unit_out)]
+ # elif type == 'in' and move.product_id.cost_method in ['real']:
+ # move_list = [(move.product_qty, reference_amount)]
+ # else:
+ # move_list = [(move.product_qty, reference_amount)]
+
+ # res = []
+ # for item in move_list:
+ # # prepare default values considering that the destination accounts have the reference_currency_id as their main currency
+ # partner_id = (move.picking_id.partner_id and self.pool.get('res.partner')._find_accounting_partner(move.picking_id.partner_id).id) or False
+ # debit_line_vals = {
+ # 'name': move.name,
+ # 'product_id': move.product_id and move.product_id.id or False,
+ # 'quantity': item[0],
+ # 'product_uom_id': move.product_uom.id,
+ # 'ref': move.picking_id and move.picking_id.name or False,
+ # 'date': time.strftime('%Y-%m-%d'),
+ # 'partner_id': partner_id,
+ # 'debit': item[1],
+ # 'account_id': dest_account_id,
+ # }
+ # credit_line_vals = {
+ # 'name': move.name,
+ # 'product_id': move.product_id and move.product_id.id or False,
+ # 'quantity': item[0],
+ # 'product_uom_id': move.product_uom.id,
+ # 'ref': move.picking_id and move.picking_id.name or False,
+ # 'date': time.strftime('%Y-%m-%d'),
+ # 'partner_id': partner_id,
+ # 'credit': item[1],
+ # 'account_id': src_account_id,
+ # }
+ # res += [(0, 0, debit_line_vals), (0, 0, credit_line_vals)]
+ # return res
+
+
#----------------------------------------------------------
# Stock Picking
@@ -969,7 +1213,7 @@ class stock_picking(osv.osv):
for pick in self.browse(cr, uid, ids, context=context):
new_picking = None
complete, too_many, too_few = [], [], []
- move_product_qty, prodlot_ids, partial_qty, product_uoms = {}, {}, {}, {}
+ move_product_qty, lot_ids, partial_qty, product_uoms = {}, {}, {}, {}
for move in pick.move_lines:
@@ -980,8 +1224,8 @@ class stock_picking(osv.osv):
move_product_qty[move.id] = product_qty
product_uom = partial_data.get('product_uom',False)
product_price = partial_data.get('product_price',0.0)
- prodlot_id = partial_data.get('prodlot_id')
- prodlot_ids[move.id] = prodlot_id
+ lot_id = partial_data.get('lot_id')
+ lot_ids[move.id] = lot_id
product_uoms[move.id] = product_uom
partial_qty[move.id] = uom_obj._compute_qty(cr, uid, product_uoms[move.id], product_qty, move.product_uom.id)
if move.product_qty == partial_qty[move.id]:
@@ -1031,9 +1275,9 @@ class stock_picking(osv.osv):
'product_uom': product_uoms[move.id],
'reserved_quant_ids': list(done_reserved_quants)
}
- prodlot_id = prodlot_ids[move.id]
- if prodlot_id:
- defaults.update(prodlot_id=prodlot_id)
+ lot_id = lot_ids[move.id]
+ if lot_id:
+ defaults.update(lot_id=lot_id)
backorder_move_id = move_obj.copy(cr, uid, move.id, defaults)
self.make_packaging(cr, uid, pick.id, move_obj.browse(cr, uid, backorder_move_id, context=context), list(done_reserved_quants), context=context)
#modify the existing stock move
@@ -1042,7 +1286,7 @@ class stock_picking(osv.osv):
{
'product_qty': move.product_qty - partial_qty[move.id],
'product_uos_qty': move.product_qty - partial_qty[move.id], #TODO: put correct uos_qty
- 'prodlot_id': False,
+ 'lot_id': False,
'tracking_id': False,
'reserved_quant_ids': list(set(possible_quants) - done_reserved_quants),
})
@@ -1051,8 +1295,8 @@ class stock_picking(osv.osv):
move_obj.write(cr, uid, [c.id for c in complete], {'picking_id': new_picking})
for move in complete:
defaults = {'product_uom': product_uoms[move.id], 'product_qty': move_product_qty[move.id]}
- if prodlot_ids.get(move.id):
- defaults.update({'prodlot_id': prodlot_ids[move.id]})
+ if lot_ids.get(move.id):
+ defaults.update({'lot_id': lot_ids[move.id]})
move_obj.write(cr, uid, [move.id], defaults)
@@ -1070,9 +1314,9 @@ class stock_picking(osv.osv):
'product_uos_qty': product_qty, #TODO: put correct uos_qty
'product_uom': product_uoms[move.id]
}
- prodlot_id = prodlot_ids.get(move.id)
- if prodlot_ids.get(move.id):
- defaults.update(prodlot_id=prodlot_id)
+ lot_id = lot_ids.get(move.id)
+ if lot_ids.get(move.id):
+ defaults.update(lot_id=lot_id)
if new_picking:
defaults.update(picking_id=new_picking)
move_obj.write(cr, uid, [move.id], defaults)
@@ -1257,6 +1501,7 @@ class stock_production_lot(osv.osv):
'ref': fields.char('Internal Reference', size=256, help="Internal reference number in case it differs from the manufacturer's serial number"),
'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type', '<>', 'service')]),
'quant_ids': fields.one2many('stock.quant', 'lot_id', 'Quants'),
+ 'create_date': fields.datetime('Creation Date'),
}
_defaults = {
'name': lambda x, y, z, c: x.pool.get('ir.sequence').get(y, z, 'stock.lot.serial'),
@@ -1325,7 +1570,7 @@ class stock_move(osv.osv):
# @return: True or False
# """
# for move in self.browse(cr, uid, ids, context=context):
- # if not move.prodlot_id and \
+ # if not move.lot_id and \
# (move.state == 'done' and \
# ( \
# (move.product_id.track_production and move.location_id.usage == 'production') or \
@@ -1336,15 +1581,6 @@ class stock_move(osv.osv):
# )):
# return False
# return True
- #
- # def _check_product_lot(self, cr, uid, ids, context=None):
- # """ Checks whether move is done or not and production lot is assigned to that move.
- # @return: True or False
- # """
- # for move in self.browse(cr, uid, ids, context=context):
- # if move.prodlot_id and move.state == 'done' and (move.prodlot_id.product_id.id != move.product_id.id):
- # return False
- # return True
_columns = {
'name': fields.char('Description', required=True, select=True),
@@ -1658,7 +1894,7 @@ class stock_move(osv.osv):
'product_uos': uos_id,
'product_qty': 1.00,
'product_uos_qty' : self.pool.get('stock.move').onchange_quantity(cr, uid, ids, prod_id, 1.00, product.uom_id.id, uos_id)['value']['product_uos_qty'],
- 'prodlot_id' : False,
+ 'lot_id' : False,
}
if not ids:
result['name'] = product.partner_ref
@@ -1765,7 +2001,7 @@ class stock_move(osv.osv):
for q in m2.quant_ids:
dp.append(q.id)
quants = quant_obj.quants_get(cr, uid, move.location_id.id, move.product_id.id, qty, domain_preference=dp and [('id', 'in', dp)], context=context)
- quant_obj.quants_reserve(cr, uid, quants, move.id, context=context)
+ quant_obj.quants_reserve(cr, uid, quants, move, context=context)
self.write(cr, uid, done, {'state': 'assigned'})
# FP Note: remove this line
@@ -1788,162 +2024,6 @@ class stock_move(osv.osv):
self.write(cr, uid, [move.move_dest_id.id], {'state': 'confirmed'})
return self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False})
- # FP Note: all accounting valuation stuff must be on the quant
- def _get_accounting_data_for_valuation(self, cr, uid, move, context=None):
- """
- Return the accounts and journal to use to post Journal Entries for the real-time
- valuation of the move.
-
- :param context: context dictionary that can explicitly mention the company to consider via the 'force_company' key
- :raise: osv.except_osv() is any mandatory account or journal is not defined.
- """
- product_obj=self.pool.get('product.product')
- accounts = product_obj.get_product_accounts(cr, uid, move.product_id.id, context)
- if move.location_id.valuation_out_account_id:
- acc_src = move.location_id.valuation_out_account_id.id
- else:
- acc_src = accounts['stock_account_input']
-
- if move.location_dest_id.valuation_in_account_id:
- acc_dest = move.location_dest_id.valuation_in_account_id.id
- else:
- acc_dest = accounts['stock_account_output']
-
- acc_valuation = accounts.get('property_stock_valuation_account_id', False)
- journal_id = accounts['stock_journal']
-
- if acc_dest == acc_valuation:
- raise osv.except_osv(_('Error!'), _('Cannot create Journal Entry, Output Account of this product and Valuation account on category of this product are same.'))
-
- if acc_src == acc_valuation:
- raise osv.except_osv(_('Error!'), _('Cannot create Journal Entry, Input Account of this product and Valuation account on category of this product are same.'))
-
- if not acc_src:
- raise osv.except_osv(_('Error!'), _('Please define stock input account for this product or its category: "%s" (id: %d)') % \
- (move.product_id.name, move.product_id.id,))
- if not acc_dest:
- raise osv.except_osv(_('Error!'), _('Please define stock output account for this product or its category: "%s" (id: %d)') % \
- (move.product_id.name, move.product_id.id,))
- if not journal_id:
- raise osv.except_osv(_('Error!'), _('Please define journal on the product category: "%s" (id: %d)') % \
- (move.product_id.categ_id.name, move.product_id.categ_id.id,))
- if not acc_valuation:
- raise osv.except_osv(_('Error!'), _('Please define inventory valuation account on the product category: "%s" (id: %d)') % \
- (move.product_id.categ_id.name, move.product_id.categ_id.id,))
- return journal_id, acc_src, acc_dest, acc_valuation
-
-
- #We can use a preliminary type
- def get_reference_amount(self, cr, uid, move, qty, context=None):
- # if product is set to average price and a specific value was entered in the picking wizard,
- # we use it
-
- # by default the reference currency is that of the move's company
- reference_currency_id = move.company_id.currency_id.id
-
- #I use
- if move.product_id.cost_method != 'standard' and move.price_unit:
- reference_amount = move.product_qty * move.price_unit #Using move.price_qty instead of qty to have correct amount
- reference_currency_id = move.price_currency_id.id or reference_currency_id
-
- # Otherwise we default to the company's valuation price type, considering that the values of the
- # valuation field are expressed in the default currency of the move's company.
- else:
- if context is None:
- context = {}
- currency_ctx = dict(context, currency_id = move.company_id.currency_id.id)
- amount_unit = move.product_id.price_get('standard_price', context=currency_ctx)[move.product_id.id]
- reference_amount = amount_unit * qty
-
- return reference_amount, reference_currency_id
-
-
- def _get_reference_accounting_values_for_valuation(self, cr, uid, move, context=None):
- """
- Return the reference amount and reference currency representing the inventory valuation for this move.
- These reference values should possibly be converted before being posted in Journals to adapt to the primary
- and secondary currencies of the relevant accounts.
- """
- product_uom_obj = self.pool.get('product.uom')
-
- default_uom = move.product_id.uom_id.id
- qty = product_uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, default_uom)
-
- reference_amount, reference_currency_id = self.get_reference_amount(cr, uid, move, qty, context=context)
- return reference_amount, reference_currency_id
-
-
-
-
-
- def _create_product_valuation_moves(self, cr, uid, move, matches, context=None):
- """
- Generate the appropriate accounting moves if the product being moved is subject
- to real_time valuation tracking, and the source or the destination location is internal (not both)
- This means an in or out move.
-
- Depending on the matches it will create the necessary moves
- """
- ctx = context.copy()
- ctx['force_company'] = move.company_id.id
- valuation = self.pool.get("product.product").browse(cr, uid, move.product_id.id, context=ctx).valuation
- move_obj = self.pool.get('account.move')
- if valuation == 'real_time':
- if context is None:
- context = {}
- company_ctx = dict(context,force_company=move.company_id.id)
- journal_id, acc_src, acc_dest, acc_valuation = self._get_accounting_data_for_valuation(cr, uid, move, context=company_ctx)
- reference_amount, reference_currency_id = self._get_reference_accounting_values_for_valuation(cr, uid, move, context=company_ctx)
- account_moves = []
- # Outgoing moves (or cross-company output part)
- if move.location_id.company_id \
- and (move.location_id.usage == 'internal' and move.location_dest_id.usage != 'internal'):
- #returning goods to supplier
- if move.location_dest_id.usage == 'supplier':
- account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, matches, acc_valuation, acc_src, reference_amount, reference_currency_id, 'out', context=company_ctx))]
- else:
- account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, matches, acc_valuation, acc_dest, reference_amount, reference_currency_id, 'out', context=company_ctx))]
-
- # Incoming moves (or cross-company input part)
- if move.location_dest_id.company_id \
- and (move.location_id.usage != 'internal' and move.location_dest_id.usage == 'internal'):
- #goods return from customer
- if move.location_id.usage == 'customer':
- account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, matches, acc_dest, acc_valuation, reference_amount, reference_currency_id, 'in', context=company_ctx))]
- else:
- account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, matches, acc_src, acc_valuation, reference_amount, reference_currency_id, 'in', context=company_ctx))]
- if matches and move.product_id.cost_method in ('fifo', 'lifo'):
- outs = {}
- match_obj = self.pool.get("stock.move.matching")
- for match in match_obj.browse(cr, uid, matches, context=context):
- if match.move_out_id.id in outs:
- outs[match.move_out_id.id] += [match.id]
- else:
- outs[match.move_out_id.id] = [match.id]
- #When in stock was negative, you will get matches for the in also:
- account_moves_neg = []
- for out_mov in self.browse(cr, uid, outs.keys(), context=context):
- journal_id_out, acc_src_out, acc_dest_out, acc_valuation_out = self._get_accounting_data_for_valuation(cr, uid, out_mov, context=company_ctx)
- reference_amount_out, reference_currency_id_out = self._get_reference_accounting_values_for_valuation(cr, uid, out_mov, context=company_ctx)
- if out_mov.location_dest_id.usage == 'supplier':
- # Is not the way it should be with acc_valuation
- account_moves_neg += [(journal_id_out, self._create_account_move_line(cr, uid, out_mov, outs[out_mov.id], acc_valuation_out, acc_src_out, reference_amount_out, reference_currency_id_out, 'out', context=company_ctx))]
- else:
- account_moves_neg += [(journal_id_out, self._create_account_move_line(cr, uid, out_mov, outs[out_mov.id], acc_valuation_out, acc_dest_out, reference_amount_out, reference_currency_id_out, 'out', context=company_ctx))]
- #Create account moves for outs which made stock go negative
- for j_id, move_lines in account_moves_neg:
- move_obj.create(cr, uid,
- {'journal_id': j_id,
- 'line_id': move_lines,
- 'ref': out_mov.picking_id and out_mov.picking_id.name,
- })
- for j_id, move_lines in account_moves:
- move_obj.create(cr, uid,
- {
- 'journal_id': j_id,
- 'line_id': move_lines,
- 'ref': move.picking_id and move.picking_id.name})
-
def _get_quants_from_pack(self, cr, uid, ids, context=None):
"""
Suppose for the moment we don't have any packaging
@@ -1954,65 +2034,15 @@ class stock_move(osv.osv):
res[move.id] = [x.id for x in move.reserved_quant_ids]
return res
-
- def check_total_qty(self, cr, uid, ids, context=None):
- """
- This will check if the necessary quants for the moves have been reserved.
- If not, it will retry to find the quants.
- If it can not find it, it will have to create a negative quant
-
- """
- quant_obj = self.pool.get("stock.quant")
- uom_obj = self.pool.get("product.uom")
- for move in self.browse(cr, uid, ids, context=context):
- product_qty = 0.0
- for quant in move.reserved_quant_ids:
- product_qty += quant.qty
- qty_from_move = uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, move.product_id.uom_id.id)
- #Check if the entire quantity has been transformed in to quants
- if qty_from_move > product_qty:
- quant_tuples = quant_obj.quants_get(cr, uid, move.location_id.id, move.product_id.id, qty_from_move - product_qty, prodlot_id = move.prodlot_id.id, context=context)
- print quant_tuples
- create_neg_quant = True
- if quant_tuples:
- quant_obj.split_and_assign_quants(cr, uid, quant_tuples, move, context=context)
- product_qty = 0.0
- #Reread move:
- move = self.browse(cr, uid, move.id, context=context)
- for quant in move.reserved_quant_ids:
- product_qty += quant.qty
- if qty_from_move <= product_qty:
- create_neg_quant = False
- if create_neg_quant:
- #To solve this, we should create a negative quant at destination and a positive quant at the source
- vals_neg = {
- 'product_id': move.product_id.id,
- 'location_id': move.location_id.id,
- 'qty': -(qty_from_move - product_qty),
- 'in_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- }
- quant_id_neg = quant_obj.create(cr, uid, vals_neg, context=context)
- vals_pos = {
- 'product_id': move.product_id.id,
- 'location_id': move.location_dest_id.id,
- 'qty': qty_from_move - product_qty,
- 'history_ids': [(4, move.id)],
- 'propagated_from_id': quant_id_neg,
- 'in_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- }
- quant_id_pos = quant_obj.create(cr, uid, vals_pos, context=context)
-
- return True
-
def action_done(self, cr, uid, ids, context=None):
""" Makes the move done and if all moves are done, it will finish the picking.
@return:
"""
- picking_ids = []
- move_ids = []
+ context = context or {}
+ quant_obj = self.pool.get("stock.quant")
+ uom_obj = self.pool.get("product.uom")
+
wf_service = netsvc.LocalService("workflow")
- if context is None:
- context = {}
todo = []
for move in self.browse(cr, uid, ids, context=context):
@@ -2020,120 +2050,21 @@ class stock_move(osv.osv):
todo.append(move.id)
if todo:
self.action_confirm(cr, uid, todo, context=context)
- todo = []
- uom_obj = self.pool.get("product.uom")
- quant_obj = self.pool.get("stock.quant")
- #Do price calc on move
- quants = {}
- for move in self.browse(cr, uid, ids, context=context):
- quants[move.id] = []
- if (move.location_id.usage in ['supplier', 'inventory']):
- #Create quants
- reconciled_quants = self.pool.get("stock.quant").create_quants(cr, uid, move, context=context)
- quants[move.id] += reconciled_quants
- else:
- #move quants should resolve negative quants in destination
- self.check_total_qty(cr, uid, ids, context=context)
- move = self.browse(cr, uid, move.id, context=context)
- reconciled_quants = self.pool.get("stock.quant").move_quants(cr, uid, [x.id for x in move.reserved_quant_ids], move, context=context)
- quants[move.id] += reconciled_quants
-
- #Do price calculation on move -> Should pass reconciled Quants -> is a dictionary
- matchresults = self.price_calculation(cr, uid, ids, quants, context=context)
-
- for move in self.browse(cr, uid, ids, context=context):
- if move.state in ['done','cancel']:
- continue
- move_ids.append(move.id)
-
- if move.picking_id:
- picking_ids.append(move.picking_id.id)
- if move.move_dest_id.id and (move.state != 'done'):
- # Downstream move should only be triggered if this move is the last pending upstream move
- other_upstream_move_ids = self.search(cr, uid, [('id','!=',move.id),('state','not in',['done','cancel']),
- ('move_dest_id','=',move.move_dest_id.id)], context=context)
- if not other_upstream_move_ids:
- if move.move_dest_id.state in ('waiting', 'confirmed'):
- self.force_assign(cr, uid, [move.move_dest_id.id], context=context)
- #We can take over used quants in this move to be propagated to next move
- #TODO should take into account split quantities?
- quants = quant_obj.search(cr, uid, [('history_ids', 'in', move.id), ('location_id', '=', move.location_dest_id.id), ('reservation_id', '=', False)], context=context)
- if quants:
- print "PROPAGATE QUANTS: ", quants
- quant_obj.write(cr, uid, quants, {'reservation_id':move.move_dest_id.id}, context=context)
- if move.move_dest_id.picking_id:
- wf_service.trg_write(uid, 'stock.picking', move.move_dest_id.picking_id.id, cr)
- if move.move_dest_id.auto_validate:
- self.action_done(cr, uid, [move.move_dest_id.id], context=context)
-
- self._create_product_valuation_moves(cr, uid, move, move.id in matchresults and matchresults[move.id] or [], context=context)
- if move.state not in ('confirmed','done','assigned'):
- todo.append(move.id)
-
- if todo:
- self.action_confirm(cr, uid, todo, context=context)
+ qty = uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, move.product_id.uom_id.id)
+ quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, context=context)
+ quant_obj.quants_move(cr, uid, quants, move, context=context)
self.write(cr, uid, move_ids, {'state': 'done', 'date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context)
+ # Not sure we need this? If yes, put it in the write method of stock.move
for id in move_ids:
wf_service.trg_trigger(uid, 'stock.move', id, cr)
- for pick_id in picking_ids:
- wf_service.trg_write(uid, 'stock.picking', pick_id, cr)
-
- ids = self.pool.get("stock.quant").search(cr, uid, [])
- for x in self.pool.get("stock.quant").browse(cr, uid, ids):
- print (x.id, x.product_id.id, x.qty, x.price_unit, x.location_id.name, x.in_date)
- print " ", [(y.id, y.product_qty, y.price_unit) for y in x.history_ids]
+ # Done automatically by write
+ #for pick_id in picking_ids:
+ # wf_service.trg_write(uid, 'stock.picking', pick_id, cr)
return True
- def _create_account_move_line(self, cr, uid, move, matches, src_account_id, dest_account_id, reference_amount, reference_currency_id, type='', context=None):
- """
- Generate the account.move.line values to post to track the stock valuation difference due to the
- processing of the given stock move.
- """
- move_list = []
- # Consists of access rights
- # TODO Check if amount_currency is not needed
- match_obj = self.pool.get("stock.move.matching")
- if type == 'out' and move.product_id.cost_method in ['real']:
- for match in match_obj.browse(cr, uid, matches, context=context):
- move_list += [(match.qty, match.qty * match.price_unit_out)]
- elif type == 'in' and move.product_id.cost_method in ['real']:
- move_list = [(move.product_qty, reference_amount)]
- else:
- move_list = [(move.product_qty, reference_amount)]
-
- res = []
- for item in move_list:
- # prepare default values considering that the destination accounts have the reference_currency_id as their main currency
- partner_id = (move.picking_id.partner_id and self.pool.get('res.partner')._find_accounting_partner(move.picking_id.partner_id).id) or False
- debit_line_vals = {
- 'name': move.name,
- 'product_id': move.product_id and move.product_id.id or False,
- 'quantity': item[0],
- 'product_uom_id': move.product_uom.id,
- 'ref': move.picking_id and move.picking_id.name or False,
- 'date': time.strftime('%Y-%m-%d'),
- 'partner_id': partner_id,
- 'debit': item[1],
- 'account_id': dest_account_id,
- }
- credit_line_vals = {
- 'name': move.name,
- 'product_id': move.product_id and move.product_id.id or False,
- 'quantity': item[0],
- 'product_uom_id': move.product_uom.id,
- 'ref': move.picking_id and move.picking_id.name or False,
- 'date': time.strftime('%Y-%m-%d'),
- 'partner_id': partner_id,
- 'credit': item[1],
- 'account_id': src_account_id,
- }
- res += [(0, 0, debit_line_vals), (0, 0, credit_line_vals)]
- return res
-
-
def unlink(self, cr, uid, ids, context=None):
if context is None:
context = {}
@@ -2144,15 +2075,6 @@ class stock_move(osv.osv):
return super(stock_move, self).unlink(
cr, uid, ids, context=ctx)
- # _create_lot function is not used anywhere
- def _create_lot(self, cr, uid, ids, product_id):
- """ Creates production lot
- @return: Production lot id
- """
- prodlot_obj = self.pool.get('stock.production.lot')
- prodlot_id = prodlot_obj.create(cr, uid, {'product_id': product_id})
- return prodlot_id
-
def action_scrap(self, cr, uid, ids, quantity, location_id, context=None):
""" Move the scrap/damaged product into scrap location
@param cr: the database cursor
@@ -2184,7 +2106,7 @@ class stock_move(osv.osv):
'scrapped': True,
'location_dest_id': location_id,
'tracking_id': move.tracking_id.id,
- 'prodlot_id': move.prodlot_id.id,
+ 'lot_id': move.lot_id.id,
}
new_move = self.copy(cr, uid, move.id, default_val)
@@ -2199,69 +2121,6 @@ class stock_move(osv.osv):
self.action_done(cr, uid, res, context=context)
return res
- # action_split function is not used anywhere
- # FIXME: deprecate this method
- def action_split(self, cr, uid, ids, quantity, split_by_qty=1, with_lot=True, context=None):
- """ Split Stock Move lines into production lot which specified split by quantity.
- @param cr: the database cursor
- @param uid: the user id
- @param ids: ids of stock move object to be splited
- @param split_by_qty : specify split by qty
- @param with_lot : if true, prodcution lot will assign for split line otherwise not.
- @param context: context arguments
- @return: Splited move lines
- """
-
- if context is None:
- context = {}
- if quantity <= 0:
- raise osv.except_osv(_('Warning!'), _('Please provide proper quantity.'))
-
- res = []
-
- for move in self.browse(cr, uid, ids, context=context):
- if split_by_qty <= 0 or quantity == 0:
- return res
-
- uos_qty = split_by_qty / move.product_qty * move.product_uos_qty
-
- quantity_rest = quantity % split_by_qty
- uos_qty_rest = split_by_qty / move.product_qty * move.product_uos_qty
-
- update_val = {
- 'product_qty': split_by_qty,
- 'product_uos_qty': uos_qty,
- }
- for idx in range(int(quantity//split_by_qty)):
- if not idx and move.product_qty<=quantity:
- current_move = move.id
- else:
- current_move = self.copy(cr, uid, move.id, {'state': move.state})
- res.append(current_move)
- if with_lot:
- update_val['prodlot_id'] = self._create_lot(cr, uid, [current_move], move.product_id.id)
-
- self.write(cr, uid, [current_move], update_val)
-
-
- if quantity_rest > 0:
- idx = int(quantity//split_by_qty)
- update_val['product_qty'] = quantity_rest
- update_val['product_uos_qty'] = uos_qty_rest
- if not idx and move.product_qty<=quantity:
- current_move = move.id
- else:
- current_move = self.copy(cr, uid, move.id, {'state': move.state})
-
- res.append(current_move)
-
-
- if with_lot:
- update_val['prodlot_id'] = self._create_lot(cr, uid, [current_move], move.product_id.id)
-
- self.write(cr, uid, [current_move], update_val)
- return res
-
def action_consume(self, cr, uid, ids, quantity, location_id=False, context=None):
""" Consumed product with specific quatity from specific source location
@param cr: the database cursor
@@ -2317,65 +2176,6 @@ class stock_move(osv.osv):
self.write(cr, uid, [move.id], update_val)
self.action_done(cr, uid, res, context=context)
-
- return res
-
-
- def _generate_negative_stock_matchings(self, cr, uid, ids, product, quants, context=None):
- """
- This method generates the stock move matches for out moves of product with qty remaining
- according to the in move
- force_company should be in context already
- | ids : id of in move
- | product: browse record of product
- Returns:
- | List of matches
- """
- assert len(ids) == 1, _("Only generate negative stock matchings one by one")
- move = self.browse(cr, uid, ids, context=context)[0]
- cost_method = product.cost_method
- matching_obj = self.pool.get("stock.move.matching")
- product_obj = self.pool.get("product.product")
- uom_obj = self.pool.get("product.uom")
- res = []
-#
-# #Search for the most recent out moves
-# moves = self.search(cr, uid, [('company_id', '=', move.company_id.id), ('state','=', 'done'), ('location_id.usage','=','internal'), ('location_dest_id.usage', '!=', 'internal'),
-# ('product_id', '=', move.product_id.id), ('qty_remaining', '>', 0.0)], order='date, id', context=context)
-# qty_to_go = move.product_qty
-# for out_mov in self.browse(cr, uid, moves, context=context):
-# if qty_to_go <= 0.0:
-# break
-# out_qty_converted = uom_obj._compute_qty(cr, uid, out_mov.product_uom.id, out_mov.qty_remaining, move.product_uom.id, round=False)
-# qty = 0.0
-# if out_qty_converted <= qty_to_go:
-# qty = out_qty_converted
-# elif qty_to_go > 0.0:
-# qty = qty_to_go
-# revert_qty = (qty / out_qty_converted) * out_mov.qty_remaining
-# matchvals = {'move_in_id': move.id, 'qty': revert_qty,
-# 'move_out_id': out_mov.id}
-# match_id = matching_obj.create(cr, uid, matchvals, context=context)
-# res.append(match_id)
-# qty_to_go -= qty
- #Need to re-calculate total price of every out_move if FIFO/LIFO
- #Search out moves from quants
-
- quant_obj = self.pool.get("stock.quant")
- if cost_method in ['real']:
- quants_dict = quant_obj.get_out_moves_from_quants(cr, uid, quants, context=context)
- for out_mov in self.browse(cr, uid, quants_dict.keys(), context=context):
- quants_from_move = quant_obj.search(cr, uid, [('history_ids', 'in', out_mov.id), ('propagated_from_id', '=', False)], context=context)
- out_qty_converted = uom_obj._compute_qty(cr, uid, out_mov.product_uom.id, out_mov.product_qty, move.product_uom.id, round=False)
- amount = 0.0
- total_price = 0.0
- for qua in quant_obj.browse(cr, uid, quants_from_move, context=context):
- amount += qua.qty
- total_price += qua.qty * qua.price_unit
- if amount > 0.0:
- self.write(cr, uid, [out_mov.id], {'price_unit': total_price / amount}, context=context)
- if amount >= out_qty_converted:
- product_obj.write(cr, uid, [product.id], {'standard_price': total_price / amount}, context=context)
return res
def price_calculation(self, cr, uid, ids, quants, context=None):
@@ -2493,7 +2293,7 @@ class stock_move(osv.osv):
context = {}
complete, too_many, too_few = [], [], []
- move_product_qty, prodlot_ids, partial_qty, product_uoms = {}, {}, {}, {}
+ move_product_qty, lot_ids, partial_qty, product_uoms = {}, {}, {}, {}
for move in self.browse(cr, uid, ids, context=context):
@@ -2505,8 +2305,8 @@ class stock_move(osv.osv):
product_uom = partial_data.get('product_uom',False)
product_price = partial_data.get('product_price',0.0)
product_currency = partial_data.get('product_currency',False)
- prodlot_id = partial_data.get('prodlot_id')
- prodlot_ids[move.id] = prodlot_id
+ lot_id = partial_data.get('lot_id')
+ lot_ids[move.id] = lot_id
product_uoms[move.id] = product_uom
partial_qty[move.id] = uom_obj._compute_qty(cr, uid, product_uoms[move.id], product_qty, move.product_uom.id)
if move.product_qty == partial_qty[move.id]:
@@ -2527,16 +2327,16 @@ class stock_move(osv.osv):
'move_dest_id': False,
'price_unit': product_price,
}
- prodlot_id = prodlot_ids[move.id]
- if prodlot_id:
- defaults.update(prodlot_id=prodlot_id)
+ lot_id = lot_ids[move.id]
+ if lot_id:
+ defaults.update(lot_id=lot_id)
new_move = self.copy(cr, uid, move.id, defaults)
complete.append(self.browse(cr, uid, new_move))
self.write(cr, uid, [move.id],
{
'product_qty': move.product_qty - product_qty,
'product_uos_qty': move.product_qty - product_qty,
- 'prodlot_id': False,
+ 'lot_id': False,
'tracking_id': False,
})
@@ -2550,8 +2350,8 @@ class stock_move(osv.osv):
complete.append(move)
for move in complete:
- if prodlot_ids.get(move.id):
- self.write(cr, uid, [move.id],{'prodlot_id': prodlot_ids.get(move.id)})
+ if lot_ids.get(move.id):
+ self.write(cr, uid, [move.id],{'lot_id': lot_ids.get(move.id)})
self.action_done(cr, uid, [move.id], context=context)
if move.picking_id.id :
# TOCHECK : Done picking if all moves are done
@@ -2629,8 +2429,9 @@ class stock_inventory(osv.osv):
move_ids = []
for line in inv.inventory_line_id:
pid = line.product_id.id
- product_context.update(uom=line.product_uom.id, to_date=inv.date, date=inv.date, prodlot_id=line.prod_lot_id.id)
- amount = location_obj._product_get(cr, uid, line.location_id.id, [pid], product_context)[pid]
+ product_context.update(uom=line.product_uom.id, to_date=inv.date, date=inv.date, lot_id=line.prod_lot_id.id)
+ # FP Note: TODO check if it does not take recursive values
+ amount = line.product_id.qty_available
change = line.product_qty - amount
lot_id = line.prod_lot_id.id
if change:
@@ -2639,7 +2440,7 @@ class stock_inventory(osv.osv):
'name': _('INV:') + (line.inventory_id.name or ''),
'product_id': line.product_id.id,
'product_uom': line.product_uom.id,
- 'prodlot_id': lot_id,
+ 'lot_id': lot_id,
'date': inv.date,
'company_id': line.location_id.company_id.id
}
@@ -2725,7 +2526,8 @@ class stock_inventory_line(osv.osv):
return {'value': {'product_qty': 0.0, 'product_uom': False, 'prod_lot_id': False}}
obj_product = self.pool.get('product.product').browse(cr, uid, product)
uom = uom or obj_product.uom_id.id
- amount = self.pool.get('stock.location')._product_get(cr, uid, location_id, [product], {'uom': uom, 'to_date': to_date, 'compute_child': False})[product]
+ # FP Note: read quantity on product
+ amount = 0
result = {'product_qty': amount, 'product_uom': uom, 'prod_lot_id': False}
return {'value': result}
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 5a9a7bc5ce1..175366f4a27 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -44,10 +44,6 @@
-
-
@@ -61,7 +57,6 @@
-
-
-
@@ -166,19 +153,7 @@
-
-
-
-
+
@@ -221,96 +196,17 @@
-
- stock.tracking.form
- stock.tracking
-
-
-
-
-
- stock.tracking.tree
- stock.tracking
-
-
-
-
-
-
-
-
-
- Packs
- ir.actions.act_window
- stock.tracking
- form
-
-
-
- Click to add a tracking number.
-
- This is the list of all your packs. When you select a Pack, you
- can get the upstream or downstream traceability of the products
- contained in the pack.
-