Update for new Transaction

This commit is contained in:
Cédric Krier committed 2010-08-19 22:16:13 +02:00
1 parent 11c2a87ccb
commit 397f836684
3 files changed
+67 -91

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@ Installing trytond_product_cost_fifo
Prerequisites
-------------
* Python 2.4 or later (http://www.python.org/)
* Python 2.5 or later (http://www.python.org/)
* trytond (http://www.tryton.org/)
* trytond_product (http://www.tryton.org/)
* trytond_stock (http://www.tryton.org/)
+51 -71
View File
@@ -1,8 +1,8 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from decimal import Decimal
from trytond.model import ModelView, ModelSQL, fields
from trytond.pyson import Eval
from decimal import Decimal
class Move(ModelSQL, ModelView):
@@ -22,22 +22,18 @@ class Move(ModelSQL, ModelView):
'for FIFO cost price!',
})
def default_fifo_quantity_out(self, cursor, user, context=None):
def default_fifo_quantity_out(self):
return 0.0
def _update_fifo_out_product_cost_price(self, cursor, user, product,
quantity, uom, context=None):
def _update_fifo_out_product_cost_price(self, product, quantity, uom):
'''
Update the product cost price of the given product. Update
fifo_quantity on the concerned incomming moves. Return the
cost price for outputing the given product and quantity.
:param cursor: the database cursor
:param user: the user id
:param product: a BrowseRecord of the product
:param quantity: the quantity of the outgoing product
:param uom: the uom id or a BrowseRecord of the uom
:param context: the context
:return: cost_price (of type decimal)
'''
@@ -45,14 +41,12 @@ class Move(ModelSQL, ModelView):
uom_obj = self.pool.get('product.uom')
if isinstance(uom, (int, long)):
uom = uom_obj.browse(cursor, user, uom, context=context)
uom = uom_obj.browse(uom)
total_qty = uom_obj.compute_qty(
cursor, user, uom, quantity, product.default_uom, round=False,
context=context)
total_qty = uom_obj.compute_qty(uom, quantity, product.default_uom,
round=False)
fifo_moves = template_obj.get_fifo_move(
cursor, user, product.template.id, total_qty, context=context)
fifo_moves = template_obj.get_fifo_move(product.template.id, total_qty)
cost_price = Decimal("0.0")
@@ -60,22 +54,19 @@ class Move(ModelSQL, ModelView):
for move, move_qty in fifo_moves:
consumed_qty += move_qty
move_unit_price = uom_obj.compute_price(
cursor, user, move.uom, move.unit_price,
move.product.default_uom, context=context)
move_unit_price = uom_obj.compute_price(move.uom, move.unit_price,
move.product.default_uom)
cost_price += move_unit_price * Decimal(str(move_qty))
self._update_product_cost_price(
cursor, user, product.id, -move_qty, product.default_uom,
move_unit_price, move.currency, move.company, context=context)
self._update_product_cost_price(product.id, -move_qty,
product.default_uom, move_unit_price, move.currency,
move.company)
move_qty = uom_obj.compute_qty(
cursor, user, product.default_uom, move_qty, move.uom,
round=False, context=context)
self.write(
cursor, user, move.id,
{'fifo_quantity': (move.fifo_quantity or 0.0) + move_qty},
context=context)
move_qty = uom_obj.compute_qty(product.default_uom, move_qty,
move.uom, round=False)
self.write(move.id, {
'fifo_quantity': (move.fifo_quantity or 0.0) + move_qty,
})
if Decimal(str(consumed_qty)) != Decimal("0"):
@@ -88,93 +79,82 @@ class Move(ModelSQL, ModelView):
else:
return product.cost_price
def create(self, cursor, user, vals, context=None):
def create(self, vals):
location_obj = self.pool.get('stock.location')
product_obj = self.pool.get('product.product')
uom_obj = self.pool.get('product.uom')
if vals.get('state') == 'done':
from_location = location_obj.browse(cursor, user,
vals['from_location'], context=context)
to_location = location_obj.browse(cursor, user,
vals['to_location'], context=context)
product = product_obj.browse(cursor, user, vals['product'],
context=context)
from_location = location_obj.browse(vals['from_location'])
to_location = location_obj.browse(vals['to_location'])
product = product_obj.browse(vals['product'])
if from_location.type == 'supplier' \
and product.cost_price_method == 'fifo':
self._update_product_cost_price(cursor, user,
vals['product'], vals['quantity'], vals['uom'],
vals['unit_price'], vals['currency'],
context=context)
self._update_product_cost_price(vals['product'],
vals['quantity'], vals['uom'], vals['unit_price'],
vals['currency'])
if to_location.type == 'supplier' \
and product.cost_price_method == 'fifo':
self._update_product_cost_price(cursor, user,
vals['product'], -vals['quantity'], vals['uom'],
vals['unit_price'], vals['currency'],
context=context)
self._update_product_cost_price(vals['product'],
-vals['quantity'], vals['uom'], vals['unit_price'],
vals['currency'])
if to_location.type != 'storage' \
and to_location.type != 'supplier' \
and product.cost_price_method == 'fifo':
cost_price = self._update_fifo_out_product_cost_price(
cursor, user, product, vals['quantity'], vals['uom'],
context=context)
cost_price = self._update_fifo_out_product_cost_price(product,
vals['quantity'], vals['uom'])
if not vals.get('cost_price'):
vals['cost_price'] = cost_price
return super(Move, self).create(cursor, user, vals, context=context)
return super(Move, self).create(vals)
def write(self, cursor, user, ids, vals, context=None):
def write(self, ids, vals):
if isinstance(ids, (int, long)):
ids = [ids]
if 'state' in vals and vals['state'] == 'done':
for move in self.browse(cursor, user, ids, context=context):
for move in self.browse(ids):
if vals['state'] == 'cancel':
if move.from_location.type == 'supplier' \
and move.state != 'cancel' \
and move.product.cost_price_method == 'fifo':
self._update_product_cost_price(cursor, user,
move.product.id, -move.quantity, move.uom,
move.unit_price, move.currency, move.company,
context=context)
self._update_product_cost_price(move.product.id,
-move.quantity, move.uom, move.unit_price,
move.currency, move.company)
if move.to_location.type == 'supplier' \
and move.state != 'cancel' \
and move.product.cost_price_method == 'fifo':
self._update_product_cost_price(cursor, user,
move.product.id, move.quantity, move.uom,
move.unit_price, move.currency, move.company,
context=context)
self._update_product_cost_price(move.product.id,
move.quantity, move.uom, move.unit_price,
move.currency, move.company)
elif vals['state'] == 'done':
if move.from_location.type == 'supplier' \
and move.state != 'done' \
and move.product.cost_price_method == 'fifo':
self._update_product_cost_price(cursor, user,
move.product.id, move.quantity, move.uom,
move.unit_price, move.currency, move.company,
context=context)
self._update_product_cost_price(move.product.id,
move.quantity, move.uom, move.unit_price,
move.currency, move.company)
if move.to_location.type == 'supplier' \
and move.state != 'done' \
and move.product.cost_price_method == 'fifo':
self._update_product_cost_price(cursor, user,
move.product.id, -move.quantity, move.uom,
move.unit_price, move.currency, move.company,
context=context)
self._update_product_cost_price(move.product.id,
-move.quantity, move.uom, move.unit_price,
move.currency, move.company)
if move.to_location.type != 'storage' \
and move.to_location.type != 'supplier' \
and move.product.cost_price_method == 'fifo':
cost_price = self._update_fifo_out_product_cost_price(
cursor, user, move.product, move.quantity,
move.uom, context=context)
move.product, move.quantity, move.uom)
if not vals.get('cost_price'):
vals['cost_price'] = cost_price
return super(Move, self).write(cursor, user, ids, vals, context=context)
return super(Move, self).write(ids, vals)
def delete(self, cursor, user, ids, context=None):
if self.search(cursor, user, [
def delete(self, ids):
if self.search([
('id', 'in', ids),
('fifo_quantity', '!=', 0.0),
], context=context):
self.raise_user_error(cursor, 'del_move_fifo', context=context)
return super(Move, self).delete(cursor, user, ids, context=context)
]):
self.raise_user_error('del_move_fifo')
return super(Move, self).delete(ids)
Move()
+15 -19
View File
@@ -1,8 +1,9 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, fields
from __future__ import with_statement
import copy
import datetime
from trytond.model import ModelView, ModelSQL, fields
class Template(ModelSQL, ModelView):
@@ -16,19 +17,15 @@ class Template(ModelSQL, ModelView):
self.cost_price_method.selection.append(new_sel)
self._reset_columns()
def get_fifo_move(self, cursor, user, template_id, quantity=0.0,
context=None):
def get_fifo_move(self, template_id, quantity=0.0):
'''
Return a list of (move, qty) where move is the move to be
consumed and qty is the quantity (in the product default uom)
to be consumed on this move. The list contains the "first in"
moves for the given quantity.
:param cursor: the database cursor
:param user: the user id
:param template_id: the product template id
:param quantity: the quantity to be removed from the stock
:param context: the context
:return: list of (move, qty) where move is a browse record,
qty is a float
'''
@@ -36,35 +33,34 @@ class Template(ModelSQL, ModelView):
uom_obj = self.pool.get('product.uom')
location_obj = self.pool.get('stock.location')
ctx = context and context.copy() or {}
ctx['locations'] = location_obj.search(cursor, user, [
locations = location_obj.search([
('type', '=', 'storage'),
], context=context)
ctx['stock_date_end'] = datetime.date.today()
])
stock_date_end = datetime.date.today()
template = self.browse(cursor, user, template_id, context=ctx)
with Transaction().set_context(locations=locations,
stock_date_end=stock_date_end):
template = self.browse(template_id)
offset = 0
limit = cursor.IN_MAX
limit = Transaction().cursor.IN_MAX
avail_qty = template.quantity
fifo_moves = []
while avail_qty > 0.0:
move_ids = move_obj.search(cursor, user, [
move_ids = move_obj.search([
('product.template.id', '=', template.id),
('state', '=', 'done'),
('from_location.type', '=', 'supplier'),
], offset=offset, limit=limit,
order=[('effective_date', 'DESC'), ('id', 'DESC')],
context=context)
order=[('effective_date', 'DESC'), ('id', 'DESC')])
if not move_ids:
break
offset += limit
for move in move_obj.browse(cursor, user, move_ids,
context=context):
qty = uom_obj.compute_qty(cursor, user, move.uom,
for move in move_obj.browse(move_ids):
qty = uom_obj.compute_qty(move.uom,
move.quantity - move.fifo_quantity,
template.default_uom, round=False, context=context)
template.default_uom, round=False)
avail_qty -= qty
if avail_qty <= quantity: