diff --git a/addons/stock/product.py b/addons/stock/product.py index fec2d66f3df..f3637002368 100644 --- a/addons/stock/product.py +++ b/addons/stock/product.py @@ -73,6 +73,7 @@ class product_product(osv.osv): 'property_stock_valuation_account_id': account_valuation } + # FP Note:;too complex, not good, should be implemented at quant level TODO def do_change_standard_price(self, cr, uid, ids, datas, context=None): """ Changes the Standard Price of Product and creates an account move accordingly. @param datas : dict. contain default datas like new_price, stock_output_account, stock_input_account, stock_journal @@ -196,7 +197,7 @@ class product_product(osv.osv): return _('Products: ')+self.pool.get('stock.location').browse(cr, user, context['active_id'], context).name return res - def _get_locations_from_context(self, cr, uid, ids, context=None): + def _get_domain_locations(self, cr, uid, ids, context=None): ''' Parses the context and returns a list of location_ids based on it. It will return all stock locations when no parameters are given @@ -226,174 +227,56 @@ class product_product(osv.osv): wh = warehouse_obj.browse(cr, uid, wids, context=context) for w in warehouse_obj.browse(cr, uid, wids, context=context): - if not context.get('force_company', False) or w.lot_stock_id.company_id.id == context['force_company']: - location_ids.append(w.lot_stock_id.id) + location_ids.append(w.lot_stock_id.id) - # build the list of ids of children of the location given by id - if context.get('compute_child',True): - if context.get('force_company', False): - child_location_ids = location_obj.search(cr, uid, [('location_id', 'child_of', location_ids), ('company_id', '=', context['force_company'])]) - else: - child_location_ids = location_obj.search(cr, uid, [('location_id', 'child_of', location_ids)]) - location_ids = child_location_ids or location_ids - return location_ids + operator = context.get('compute_child',True) and 'child_of' or 'in' + domain = context.get('force_company', False) and ['&', ('company_id', '=', context['force_company'])] or [] + return ( + domain + [('location_id', operator, location_ids)], + domain + ['&', ('location_src_id', operator, location_ids), '!', ('location_dest_id', operator, location_ids)], + domain + ['&', ('location_dest_id', operator, location_ids), '!', ('location_src_id', operator, location_ids)] + ) - def _get_date_query(self, cr, uid, ids, context): - ''' - Parses the context and returns the dates query string needed to be processed in _get_product_available - It searches for a from_date and to_date - ''' + def _get_domain_dates(self, cr, uid, ids, context): from_date = context.get('from_date',False) to_date = context.get('to_date',False) - date_str = False - whereadd = [] - if from_date and to_date: - date_str = "date>=%s and date<=%s" - whereadd.append(tuple([from_date])) - whereadd.append(tuple([to_date])) - elif from_date: - date_str = "date>=%s" - whereadd.append(tuple([from_date])) - elif to_date: - date_str = "date<=%s" - whereadd.append(tuple([to_date])) - return (whereadd, date_str) - - def get_product_available(self, cr, uid, ids, context=None): - """ Finds the quantity available of product(s) depending on parameters in the context - for what, states, locations (company, warehouse, ), date, lot, - states: state of the move - what: in (dest in locations) or out (source in locations) moves - LOCATIONS: - shop: warehouse of the shop - warehouse: stock location of the warehouse - location: name (ilike) or id of the location - force_company: if not warehouse or shop given: will only take from this company - compute_child (True if not specified): will also include child locations of locations above - (when force_company only from that company) - - from_date and to_date: dates from or to for the date of the stock move to include (=scheduled of effective date) - prodlot: lot of the move - - @return: Dictionary of values for every product id - """ - if context is None: - context = {} - - states = context.get('states',[]) - what = context.get('what',()) - if not ids: - ids = self.search(cr, uid, []) - res = {}.fromkeys(ids, 0.0) - if not ids: - return res - #set_context: refactor code here - location_ids = self._get_locations_from_context(cr, uid, ids, context=context) - if not location_ids: #in case of no locations, query will be empty anyways - return res - - # this will be a dictionary of the product UoM by product id - product2uom = {} - uom_ids = [] - for product in self.read(cr, uid, ids, ['uom_id'], context=context): - product2uom[product['id']] = product['uom_id'][0] - uom_ids.append(product['uom_id'][0]) - # this will be a dictionary of the UoM resources we need for conversion purposes, by UoM id - uoms_o = {} - for uom in self.pool.get('product.uom').browse(cr, uid, uom_ids, context=context): - uoms_o[uom.id] = uom - - results = [] - results2 = [] - - where = [tuple(location_ids),tuple(location_ids),tuple(ids),tuple(states)] - - where_add, date_str = self._get_date_query(cr, uid, ids, context=context) - if where_add: - where += where_add - - - lot_id = context.get('lot_id', False) - prodlot_clause = '' - if lot_id: - prodlot_clause = ' and lot_id = %s ' - where += [lot_id] - - # TODO: perhaps merge in one query. - if 'in' in what: - # all moves from a location out of the set to a location in the set - cr.execute( - 'select sum(product_qty), product_id, product_uom '\ - 'from stock_move '\ - 'where location_id NOT IN %s '\ - 'and location_dest_id IN %s '\ - 'and product_id IN %s '\ - 'and state IN %s ' + (date_str and 'and '+date_str+' ' or '') +' '\ - + prodlot_clause + - 'group by product_id,product_uom',tuple(where)) - results = cr.fetchall() - if 'out' in what: - # all moves from a location in the set to a location out of the set - cr.execute( - 'select sum(product_qty), product_id, product_uom '\ - 'from stock_move '\ - 'where location_id IN %s '\ - 'and location_dest_id NOT IN %s '\ - 'and product_id IN %s '\ - 'and state in %s ' + (date_str and 'and '+date_str+' ' or '') + ' '\ - + prodlot_clause + - 'group by product_id,product_uom',tuple(where)) - results2 = cr.fetchall() - - # Get the missing UoM resources - uom_obj = self.pool.get('product.uom') - uoms = map(lambda x: x[2], results) + map(lambda x: x[2], results2) - if context.get('uom', False): - uoms += [context['uom']] - uoms = filter(lambda x: x not in uoms_o.keys(), uoms) - if uoms: - uoms = uom_obj.browse(cr, uid, list(set(uoms)), context=context) - for o in uoms: - uoms_o[o.id] = o - - #TOCHECK: before change uom of product, stock move line are in old uom. - context.update({'raise-exception': False}) - # Count the incoming quantities - for amount, prod_id, prod_uom in results: - amount = uom_obj._compute_qty_obj(cr, uid, uoms_o[prod_uom], amount, - uoms_o[context.get('uom', False) or product2uom[prod_id]], context=context) - res[prod_id] += amount - # Count the outgoing quantities - for amount, prod_id, prod_uom in results2: - amount = uom_obj._compute_qty_obj(cr, uid, uoms_o[prod_uom], amount, - uoms_o[context.get('uom', False) or product2uom[prod_id]], context=context) - res[prod_id] -= amount - return res + domain = [] + if from_date: + domain.append(('date','>=',from_date)) + if to_date: + domain.append(('date','<=',to_date)) + return domain def _product_available(self, cr, uid, ids, field_names=None, arg=False, context=None): - """ Finds the incoming and outgoing quantity of product. - @return: Dictionary of values - """ - if not field_names: - field_names = [] - if context is None: - context = {} + context = context or {} + field_names = field_names or [] + + domain_quant, domain_move_in, domain_move_out = self._get_domain_locations(cr, uid, ids, key='location_id', context=context) + domain_move_in += self._get_domain_dates(cr, uid, ids, context=context) + domain_move_out += self._get_domain_dates(cr, uid, ids, context=context) + + if context.get('lot_id', False): + domain_quants.append(('lot_id','=',context['lot_id'])) + moves_in = [] + moves_out = [] + else: + moves_in = self.pool.get('stock.move').read_group(cr, uid, domain_move_in, ['product_id', 'product_qty'], ['product_id'], context=context) + moves_out = self.pool.get('stock.move').read_group(cr, uid, domain_move_out, ['product_id', 'product_qty'], ['product_id'], context=context) + + quants = self.pool.get('stock.quant').read_group(cr, uid, domain_quant, ['product_id', 'qty'], ['product_id'], context=context) + + quants = dict(map(lambda x: (x['product_id'], x['qty']), quants)) + moves_in = dict(map(lambda x: (x['product_id'], x['product_qty']), moves_in)) + moves_out = dict(map(lambda x: (x['product_id'], x['product_qty']), moves_out)) + res = {} for id in ids: - res[id] = {}.fromkeys(field_names, 0.0) - for f in field_names: - c = context.copy() - if f == 'qty_available': - c.update({ 'states': ('done',), 'what': ('in', 'out') }) - if f == 'virtual_available': - c.update({ 'states': ('confirmed','waiting','assigned','done'), 'what': ('in', 'out') }) - if f == 'incoming_qty': - c.update({ 'states': ('confirmed','waiting','assigned'), 'what': ('in',) }) - if f == 'outgoing_qty': - c.update({ 'states': ('confirmed','waiting','assigned'), 'what': ('out',) }) - stock = self.get_product_available(cr, uid, ids, context=c) - for id in ids: - res[id][f] = stock.get(id, 0.0) + res[id] = { + 'qty_available': quants.get(id, 0.0), + 'incoming_qty': moves_in.get(id, 0.0), + 'outgoing_qty': moves_out.get(id, 0.0), + 'virtual_available': quants.get(id, 0.0) + moves_in.get(id, 0.0) - moves_out.get(id, 0.0), + } return res _columns = { diff --git a/addons/stock/report/lot_move_label.xml b/addons/stock/report/lot_move_label.xml index 62f26c0a800..cad14e70f68 100644 --- a/addons/stock/report/lot_move_label.xml +++ b/addons/stock/report/lot_move_label.xml @@ -5,7 +5,7 @@ - + diff --git a/addons/stock/report/picking.rml b/addons/stock/report/picking.rml index c0172e2efdc..e8e1268063b 100644 --- a/addons/stock/report/picking.rml +++ b/addons/stock/report/picking.rml @@ -257,7 +257,7 @@ [[ (move_lines.location_id and move_lines.location_id.name) or '' ]] - [[ formatLang(move_lines.product_qty) ]] [[ move_lines.product_uom.name ]] + [[ formatLang(move_lines.product_uom_qty) ]] [[ move_lines.product_uom.name ]] [[ move_lines.product_id.ean13 ]] @@ -287,7 +287,7 @@ [[ (move_lines.location_id and move_lines.location_id.name) or '' ]] - [[ formatLang(move_lines.product_qty) ]] [[ move_lines.product_uom.name ]] + [[ formatLang(move_lines.product_uom_qty) ]] [[ move_lines.product_uom.name ]] [[ move_lines.product_id.ean13 ]] diff --git a/addons/stock/report/product_stock.py b/addons/stock/report/product_stock.py index d213db673dc..db6ac9b5a02 100644 --- a/addons/stock/report/product_stock.py +++ b/addons/stock/report/product_stock.py @@ -42,6 +42,8 @@ class external_pdf(render): return self.pdf +# FP Note: change to use product_qty instead of product_uom_qty to avoid doing conversions + class report_stock(report_int): def create(self, cr, uid, ids, datas, context=None): if context is None: diff --git a/addons/stock/report/report_stock_move.py b/addons/stock/report/report_stock_move.py index 4cb9c0f04e8..c00031e47e5 100644 --- a/addons/stock/report/report_stock_move.py +++ b/addons/stock/report/report_stock_move.py @@ -23,123 +23,6 @@ from openerp import tools from openerp.osv import fields,osv from openerp.addons.decimal_precision import decimal_precision as dp -class report_stock_move(osv.osv): - _name = "report.stock.move" - _description = "Moves Statistics" - _auto = False - _columns = { - 'date': fields.date('Date', readonly=True), - 'year': fields.char('Year', size=4, readonly=True), - 'day': fields.char('Day', size=128, 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), - 'company_id':fields.many2one('res.company', 'Company', readonly=True), - 'picking_id':fields.many2one('stock.picking', 'Shipment', readonly=True), - 'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal'), ('other', 'Others')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."), - 'location_id': fields.many2one('stock.location', 'Source Location', readonly=True, select=True, help="Sets a location if you produce at a fixed location. This can be a partner location if you subcontract the manufacturing operations."), - 'location_dest_id': fields.many2one('stock.location', 'Dest. Location', readonly=True, select=True, help="Location where the system will stock the finished products."), - 'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Confirmed'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Status', readonly=True, select=True), - 'product_qty':fields.integer('Quantity',readonly=True), - 'categ_id': fields.many2one('product.category', 'Product Category', ), - 'product_qty_in':fields.integer('In Qty',readonly=True), - 'product_qty_out':fields.integer('Out Qty',readonly=True), - 'value' : fields.float('Total Value', required=True), - 'day_diff2':fields.float('Lag (Days)',readonly=True, digits_compute=dp.get_precision('Shipping Delay'), group_operator="avg"), - 'day_diff1':fields.float('Planned Lead Time (Days)',readonly=True, digits_compute=dp.get_precision('Shipping Delay'), group_operator="avg"), - '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(""" - CREATE OR REPLACE view report_stock_move AS ( - SELECT - min(sm_id) as id, - date_trunc('day',al.dp) as date, - al.curr_year as year, - al.curr_month as month, - al.curr_day as day, - al.curr_day_diff as day_diff, - al.curr_day_diff1 as day_diff1, - al.curr_day_diff2 as day_diff2, - al.location_id as location_id, - al.picking_id as picking_id, - al.company_id as company_id, - al.location_dest_id as location_dest_id, - al.product_qty, - al.out_qty as product_qty_out, - al.in_qty as product_qty_in, - al.partner_id as partner_id, - al.product_id as product_id, - al.state as state , - al.product_uom as product_uom, - al.categ_id as categ_id, - coalesce(al.type, 'other') as type, - al.stock_journal as stock_journal, - sum(al.in_value - al.out_value) as value - FROM (SELECT - CASE WHEN sp.type in ('out') THEN - sum(sm.product_qty * pu.factor / pu2.factor) - ELSE 0.0 - END AS out_qty, - CASE WHEN sp.type in ('in') THEN - sum(sm.product_qty * pu.factor / pu2.factor) - ELSE 0.0 - END AS in_qty, - CASE WHEN sp.type in ('out') THEN - sum(sm.product_qty * sm.price_unit) - ELSE 0.0 - END AS out_value, - CASE WHEN sp.type in ('in') THEN - sum(sm.product_qty * sm.price_unit) - ELSE 0.0 - END AS in_value, - min(sm.id) as sm_id, - sm.date as dp, - to_char(date_trunc('day',sm.date), 'YYYY') as curr_year, - to_char(date_trunc('day',sm.date), 'MM') as curr_month, - to_char(date_trunc('day',sm.date), 'YYYY-MM-DD') as curr_day, - avg(date(sm.date)-date(sm.create_date)) as curr_day_diff, - avg(date(sm.date_expected)-date(sm.create_date)) as curr_day_diff1, - avg(date(sm.date)-date(sm.date_expected)) as curr_day_diff2, - sm.location_id as location_id, - sm.location_dest_id as location_dest_id, - sum(sm.product_qty) as product_qty, - pt.categ_id as categ_id , - sm.partner_id as partner_id, - sm.product_id as product_id, - sm.picking_id as picking_id, - sm.company_id as company_id, - sm.state as state, - sm.product_uom as product_uom, - sp.type as type, - sp.stock_journal_id AS stock_journal - FROM - stock_move sm - LEFT JOIN stock_picking sp ON (sm.picking_id=sp.id) - LEFT JOIN product_product pp ON (sm.product_id=pp.id) - LEFT JOIN product_uom pu ON (sm.product_uom=pu.id) - LEFT JOIN product_uom pu2 ON (sm.product_uom=pu2.id) - LEFT JOIN product_template pt ON (pp.product_tmpl_id=pt.id) - GROUP BY - sm.id,sp.type, sm.date,sm.partner_id, - sm.product_id,sm.state,sm.product_uom,sm.date_expected, - sm.product_id, sm.picking_id, sm.product_qty, - sm.company_id,sm.product_qty, sm.location_id,sm.location_dest_id,pu.factor,pt.categ_id, sp.stock_journal_id) - AS al - GROUP BY - al.out_qty,al.in_qty,al.curr_year,al.curr_month, - al.curr_day,al.curr_day_diff,al.curr_day_diff1,al.curr_day_diff2,al.dp,al.location_id,al.location_dest_id, - al.partner_id,al.product_id,al.state,al.product_uom, - al.picking_id,al.company_id,al.type,al.product_qty, al.categ_id, al.stock_journal - ) - """) - - - # FP Note: TODO: drop this table and use the stock.move table instead class report_stock_inventory(osv.osv): _name = "report.stock.inventory" diff --git a/addons/stock/report/report_stock_move_view.xml b/addons/stock/report/report_stock_move_view.xml index 4675f555860..82f7a8c4b70 100644 --- a/addons/stock/report/report_stock_move_view.xml +++ b/addons/stock/report/report_stock_move_view.xml @@ -9,97 +9,6 @@ parent="base.menu_reporting" groups="group_stock_manager"/> - - report.stock.move.tree - report.stock.move - - - - - - - - - - - - - - - - - - - - - - - - - - - - report.stock.move.graph - report.stock.move - - - - - - - - - - report.stock.move.search - report.stock.move - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Moves Analysis - report.stock.move - form - tree,graph - - {'contact_display': 'partner','search_default_done':1,'search_default_year':1, 'search_default_month':1, 'search_default_group_type':1, 'group_by': [], 'group_by_no_leaf':1,} - Moves Analysis allows you to easily check and analyse your company stock moves. Use this report when you want to analyse the different routes taken by your products and inventory management performance. - - - report.stock.inventory.tree diff --git a/addons/stock/security/ir.model.access.csv b/addons/stock/security/ir.model.access.csv index e955071f606..9f743dfaafd 100644 --- a/addons/stock/security/ir.model.access.csv +++ b/addons/stock/security/ir.model.access.csv @@ -26,8 +26,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_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 access_product_product_stock_user,product_product_stock_user,product.model_product_product,stock.group_stock_user,1,1,0,0 access_product_template_stock_user,product.template stock user,product.model_product_template,stock.group_stock_user,1,1,0,0 diff --git a/addons/stock/static/src/js/widgets.js b/addons/stock/static/src/js/widgets.js index e1c377d2ecc..dfa6774cc08 100644 --- a/addons/stock/static/src/js/widgets.js +++ b/addons/stock/static/src/js/widgets.js @@ -18,7 +18,7 @@ function openerp_picking_widgets(instance){ _.each( model.movelines, function(moveline){ rows.push({ cols: { product: moveline.product_id[1], - qty: moveline.product_qty, + qty: moveline.product_uom_qty, rem: moveline.remaining_qty, uom: moveline.product_uom[1], loc: moveline.location_id[1], @@ -49,7 +49,7 @@ function openerp_picking_widgets(instance){ cols: { product: op.product_id[1], uom: op.product_uom ? product_uom[1] : '', - qty: op.product_qty, + qty: op.product_uom_qty, } }); }); diff --git a/addons/stock/stock.py b/addons/stock/stock.py index cb1f4379471..a2f01c1f5e2 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -351,9 +351,8 @@ class stock_quant(osv.osv): def _location_owner(self, cr, uid, quant, location, context=None): return location and (location.usage == 'internal') and location.company_id or False - - - # FP Note: all accounting valuation stuff must be on the quant + # TODO: move this code on the _account_entry_move method above. Should be simpler + # #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 @@ -1574,6 +1573,13 @@ class stock_move(osv.osv): # return False # return True + def _quantity_normalize(self, cr, uid, ids, name, args, context=None): + uom_obj = self.pool.get('product.uom') + res = {} + for m in self.browse(cr, uid, ids, context=context): + res[m.id] = uom_obj._compute_qty_obj(cr, uid, m.product_uom, product_qty, m.product_id.uom_id) + return res + _columns = { 'name': fields.char('Description', required=True, select=True), 'priority': fields.selection([('0', 'Not urgent'), ('1', 'Urgent')], 'Priority'), @@ -1581,7 +1587,9 @@ class stock_move(osv.osv): 'date': fields.datetime('Date', required=True, select=True, help="Move date: scheduled date until move is done, then date of actual move processing", states={'done': [('readonly', True)]}), 'date_expected': fields.datetime('Scheduled Date', states={'done': [('readonly', True)]},required=True, select=True, help="Scheduled date for the processing of this move"), 'product_id': fields.many2one('product.product', 'Product', required=True, select=True, domain=[('type','<>','service')],states={'done': [('readonly', True)]}), - 'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), + 'product_qty': fields.function(_quantity_normalize, type='float', store=True, string='Quantity', + digits_compute=dp.get_precision('Product Unit of Measure'), 'Quantity in the default UoM of the product'), + 'product_uom_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True,states={'done': [('readonly', True)]}, help="This is the quantity of products from an inventory " "point of view. For moves in the state 'done', this is the " @@ -1888,7 +1896,6 @@ 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'], - 'lot_id' : False, } if not ids: result['name'] = product.partner_ref @@ -2508,12 +2515,12 @@ class stock_inventory_line(osv.osv): @return: Dictionary of changed values """ if not product: - return {'value': {'product_qty': 0.0, 'product_uom': False, 'prod_lot_id': False}} + return {'value': {'product_qty': 0.0, 'product_uom': False}} obj_product = self.pool.get('product.product').browse(cr, uid, product) uom = uom or obj_product.uom_id.id # FP Note: read quantity on product amount = 0 - result = {'product_qty': amount, 'product_uom': uom, 'prod_lot_id': False} + result = {'product_qty': amount, 'product_uom': uom} return {'value': result} diff --git a/addons/stock/stock_demo.xml b/addons/stock/stock_demo.xml index b21757cd814..2722fd67209 100644 --- a/addons/stock/stock_demo.xml +++ b/addons/stock/stock_demo.xml @@ -53,14 +53,6 @@ - - - - - 14.0 - - - diff --git a/addons/stock/stock_demo.yml b/addons/stock/stock_demo.yml index 99565f0c08c..36ffb3037b0 100644 --- a/addons/stock/stock_demo.yml +++ b/addons/stock/stock_demo.yml @@ -80,7 +80,7 @@ picking_id: outgoing_shipment product_id: product_icecream product_uom: product.product_uom_kgm - product_qty: 130.0 + product_uom_qty: 130.0 location_id: location_refrigerator location_dest_id: location_delivery_counter - @@ -94,6 +94,6 @@ picking_id: incomming_shipment product_id: product_icecream product_uom: product.product_uom_kgm - product_qty: 50.0 + product_uom_qty: 50.0 location_id: location_convenience_shop location_dest_id: location_refrigerator diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 175366f4a27..f45f0b976bf 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -42,7 +42,7 @@ - + @@ -55,7 +55,7 @@
- +