Some refectoring: more efficient code and bugfixes
This commit is contained in:
1 parent
8de6ce2093
commit
c63bc7d297
3 files changed
+84
-70
No files matched your search
+13
-12
@@ -216,26 +216,27 @@ class CompleteInventory(Wizard):
|
||||
else:
|
||||
pbl = product_obj.products_by_location(
|
||||
cursor, user, [inventory.location.id], context=context)
|
||||
|
||||
# Index some data
|
||||
uom_by_id = {}
|
||||
for uom in uom_obj.browse(
|
||||
cursor, user, [line['uom'] for line in pbl], context=context):
|
||||
uom_by_id[uom.id] = uom
|
||||
product2uom = {}
|
||||
for product in product_obj.read(cursor, user,
|
||||
[line[1] for line in pbl],
|
||||
['default_uom'], context=context):
|
||||
product2uom[product['id']] = product['default_uom']
|
||||
product_qty = {}
|
||||
for line in pbl:
|
||||
product_qty[line['product']] = (line['quantity'],
|
||||
uom_by_id[line['uom']])
|
||||
for (location, product), quantity in pbl.iteritems():
|
||||
product_qty[product] = (quantity, product2uom[product])
|
||||
# Update existing lines
|
||||
for line in inventory.lines:
|
||||
if line.product.id in product_qty:
|
||||
quantity, uom = product_qty[line.product.id]
|
||||
quantity, uom_id = product_qty[line.product.id]
|
||||
del product_qty[line.product.id]
|
||||
# if nothing as changed, continue
|
||||
if line.quantity == line.expected_quantity == quantity \
|
||||
and line.uom.id == uom.id:
|
||||
and line.uom.id == uom_id:
|
||||
continue
|
||||
values = {'expected_quantity': quantity,
|
||||
'uom': uom.id}
|
||||
'uom': uom_id}
|
||||
# update also quantity field if not edited
|
||||
if line.quantity == line.expected_quantity:
|
||||
values['quantity'] = quantity
|
||||
@@ -250,12 +251,12 @@ class CompleteInventory(Wizard):
|
||||
|
||||
# Create lines if needed
|
||||
for product in product_qty:
|
||||
quantity, uom = product_qty[product]
|
||||
quantity, uom_id = product_qty[product]
|
||||
values = {
|
||||
'product': product,
|
||||
'expected_quantity': quantity,
|
||||
'quantity': quantity,
|
||||
'uom': uom.id,
|
||||
'uom': uom_id,
|
||||
'inventory': inventory.id,
|
||||
}
|
||||
line_obj.create(
|
||||
|
||||
+4
-12
@@ -103,18 +103,10 @@ class Location(OSV):
|
||||
context = context.copy()
|
||||
del context['stock_date']
|
||||
pbl = product_obj.products_by_location(cursor, user, location_ids=ids,
|
||||
product_ids=[context['product']], with_childs=True,
|
||||
context=context)
|
||||
qty_by_ltn = dict([(i['location'], i['quantity']) for i in pbl])
|
||||
res = {}
|
||||
for location_id in ids:
|
||||
child_ids = self.search(cursor, user, [
|
||||
('parent', 'child_of', [location_id]),
|
||||
], context=context)
|
||||
res[location_id] = 0.0
|
||||
for child_id in {}.fromkeys(child_ids):
|
||||
res[location_id] += qty_by_ltn.get(child_id, 0.0)
|
||||
return res
|
||||
product_ids=[context['product']], with_childs=True, skip_zero=False,
|
||||
context=context).iteritems()
|
||||
|
||||
return dict( [(loc,qty) for (loc,prod), qty in pbl] )
|
||||
|
||||
def view_header_get(self, cursor, user, value, view_type='form',
|
||||
context=None):
|
||||
|
||||
+67
-46
@@ -24,11 +24,10 @@ class Product(OSV):
|
||||
pbl = self.products_by_location(cursor, user,
|
||||
location_ids=context['locations'], product_ids=ids,
|
||||
with_childs=True, context=context)
|
||||
res = {}
|
||||
for product_id in ids:
|
||||
res[product_id] = 0.0
|
||||
for line in pbl:
|
||||
res[line['product']] += line['quantity']
|
||||
|
||||
res = {}.fromkeys(ids, 0.0)
|
||||
for (location, product) in zip(context['locations'], ids):
|
||||
res[product] += pbl.get((location, product), 0.0)
|
||||
return res
|
||||
|
||||
def _search_quantity_eval_domain(self, line, domain):
|
||||
@@ -47,28 +46,22 @@ class Product(OSV):
|
||||
def search_quantity(self, cursor, user, name, domain=[], context=None):
|
||||
if not (context and context.get('locations')):
|
||||
return []
|
||||
if (name != 'forecast_quantity') and context.get('stock_date'):
|
||||
if context['stock_date'] != datetime.date.today():
|
||||
context = context.copy()
|
||||
del context['stock_date']
|
||||
|
||||
pbl = self.products_by_location(cursor, user,
|
||||
location_ids=context['locations'],
|
||||
forecast=(name == 'forecast_quantity'), with_childs=True,
|
||||
context=context)
|
||||
pbl = self.products_by_location(
|
||||
cursor, user, location_ids=context['locations'], with_childs=True,
|
||||
skip_zero=False, context=context).iteritems()
|
||||
|
||||
if name == 'forecast_quantity':
|
||||
pbl = self.products_by_location(cursor, user,
|
||||
location_ids=context['locations'], with_childs=True,
|
||||
skip_zero=False, context=context)
|
||||
for line in pbl:
|
||||
line['forecast_quantity'] = line['quantity']
|
||||
del line['quantity']
|
||||
else:
|
||||
if context.get('stock_date'):
|
||||
if context['stock_date'] != datetime.date.today():
|
||||
context = context.copy()
|
||||
del context['stock_date']
|
||||
pbl = self.products_by_location(cursor, user,
|
||||
location_ids=context['locations'], with_childs=True,
|
||||
skip_zero=False, context=context)
|
||||
res= [line['product'] for line in pbl \
|
||||
processed_lines = []
|
||||
for (location, product), quantity in pbl:
|
||||
processed_lines.append({'location': location, #XXX useful ?
|
||||
'product': product,
|
||||
name: quantity})
|
||||
|
||||
res= [line['product'] for line in processed_lines \
|
||||
if self._search_quantity_eval_domain(line, domain)]
|
||||
return [('id', 'in', res)]
|
||||
|
||||
@@ -145,13 +138,14 @@ class Product(OSV):
|
||||
where_date = [context['stock_date'], context['stock_date']]
|
||||
else:
|
||||
where_date = [datetime.date.today(), datetime.date.today()]
|
||||
|
||||
cursor.execute(select_clause % (
|
||||
",".join(["%s" for i in in_states]), where_clause,
|
||||
",".join(["%s" for i in out_states]), where_clause),
|
||||
in_states + where_vals + where_date + \
|
||||
out_states + where_vals + where_date)
|
||||
|
||||
return cursor.fetchall()
|
||||
res = cursor.fetchall()
|
||||
return res
|
||||
|
||||
def products_by_location(self, cursor, user, location_ids,
|
||||
product_ids=None, with_childs=False, skip_zero=True, context=None):
|
||||
@@ -163,9 +157,11 @@ class Product(OSV):
|
||||
date than today.
|
||||
If with_childs, childs locations are also computed.
|
||||
If skip_zero, list item with quantity equal to zero are not returned.
|
||||
If no product_ids are given the computation is done on all products.
|
||||
"""
|
||||
uom_obj = self.pool.get("product.uom")
|
||||
product_obj = self.pool.get("product.product")
|
||||
location_obj = self.pool.get("stock.location")
|
||||
|
||||
if not location_ids:
|
||||
return []
|
||||
@@ -174,12 +170,18 @@ class Product(OSV):
|
||||
raw_lines = self.raw_products_by_location(cursor, user, location_ids,
|
||||
product_ids, with_childs=with_childs, context=context)
|
||||
|
||||
res_location_ids = []
|
||||
uom_ids = []
|
||||
product_ids = []
|
||||
res_product_ids = []
|
||||
for line in raw_lines:
|
||||
uom_ids.append(line[2])
|
||||
product_ids.append(line[1])
|
||||
for id_list, position in ((res_location_ids, 0), (uom_ids, 1),
|
||||
(res_product_ids, 1)):
|
||||
if line[position] not in id_list:
|
||||
id_list.append(line[position])
|
||||
|
||||
if not product_ids:
|
||||
product_ids = self.pool.get("product.product").search(
|
||||
cursor, user, [], context=context)
|
||||
uom_by_id = dict([(x.id, x) for x in uom_obj.browse(
|
||||
cursor, user, uom_ids, context=context)])
|
||||
default_uom = dict((x.id, x.default_uom) for x in product_obj.browse(
|
||||
@@ -187,32 +189,51 @@ class Product(OSV):
|
||||
|
||||
for line in raw_lines:
|
||||
location, product, uom, quantity = line
|
||||
key = (location, product, default_uom[product].id)
|
||||
key = (location, product)
|
||||
res.setdefault(key, 0.0)
|
||||
res[key] += uom_obj.compute_qty(cursor, user, uom_by_id[uom],
|
||||
quantity, default_uom[product], context=context)
|
||||
# Remove seen products from product_ids
|
||||
if key[1] in product_ids:
|
||||
product_ids.remove(key[1])
|
||||
|
||||
res = [{'location': key[0],
|
||||
'product': key[1],
|
||||
'uom': key[2],
|
||||
'quantity': val} for key, val in res.iteritems()]
|
||||
# Propagate quantities on from child locations to their parents
|
||||
if with_childs:
|
||||
# Fetch all child locations
|
||||
all_location_ids = location_obj.search(
|
||||
cursor, user, [('parent', 'child_of', location_ids)],
|
||||
context=context)
|
||||
locations = location_obj.browse(cursor, user, all_location_ids,
|
||||
context=context)
|
||||
# Generate a set of locations without childs and a dict
|
||||
# giving the parent of each location.
|
||||
leafs = set(all_location_ids)
|
||||
parent = {}
|
||||
for location in locations:
|
||||
if not location.parent: continue
|
||||
if location.parent.id in leafs:
|
||||
leafs.remove(location.parent.id)
|
||||
parent[location.id] = location.parent.id
|
||||
|
||||
while leafs:
|
||||
next_leafs = set()
|
||||
for l in leafs:
|
||||
if l not in parent:
|
||||
continue
|
||||
next_leafs.add(parent[l])
|
||||
for product in res_product_ids:
|
||||
res.setdefault((parent[l], product), 0)
|
||||
res[(parent[l], product)] += res.get((l,product), 0)
|
||||
leafs = next_leafs
|
||||
|
||||
# Complete result with missing products if asked
|
||||
if not skip_zero:
|
||||
for location_id in location_ids:
|
||||
for product_id in product_ids:
|
||||
res.append({
|
||||
'location': location_id,
|
||||
'product': product_id,
|
||||
'uom': default_uom[product_id].id,
|
||||
'quantity': 0.0,
|
||||
})
|
||||
keys = ((l,p) for l in location_ids for p in product_ids)
|
||||
for location_id, product_id in keys:
|
||||
if (location_id, product_id) not in res:
|
||||
res[(location_id, product_id)] = 0.0
|
||||
|
||||
return res
|
||||
|
||||
|
||||
|
||||
def view_header_get(self, cursor, user, value, view_type='form',
|
||||
context=None):
|
||||
if not context.get('locations'):
|
||||
|
||||
Reference in new issue
Block a user