From f41749ce0c2189028b68999717369e95f1a97959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 18 Nov 2008 18:34:02 +0100 Subject: [PATCH 01/64] Increase version number --- __tryton__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tryton__.py b/__tryton__.py index eade2b9ea6..ee79b7fd19 100644 --- a/__tryton__.py +++ b/__tryton__.py @@ -5,7 +5,7 @@ 'name_de_DE': 'Lagerverwaltung', 'name_fr_FR': 'Gestion des stocks', 'name_es_ES': 'Inventarios', - 'version': '1.0.0', + 'version': '1.0.1', 'author': 'B2CK', 'email': 'info@b2ck.com', 'website': 'http://www.tryton.org/', From 7ec5951e2d1117e4a0e7b0f58a1cf6b22b7fe28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 18 Nov 2008 18:35:11 +0100 Subject: [PATCH 02/64] Allow egg installation --- CHANGELOG | 2 ++ setup.py | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index eacaaefa7d..44de11f380 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,2 +1,4 @@ +* Allow egg installation + Version 1.0.0 - 2008-11-17 * Initial release diff --git a/setup.py b/setup.py index aa566ac1ff..a08dfd77a3 100644 --- a/setup.py +++ b/setup.py @@ -27,6 +27,8 @@ setup(name='trytond_stock', author=info.get('author', ''), author_email=info.get('email', ''), url=info.get('website', ''), + download_url="http://downloads.tryton.org/" + \ + info.get('version', '0.0.1').rsplit('.', 1)[0] + '/', package_dir={'trytond.modules.stock': '.'}, packages=[ 'trytond.modules.stock', @@ -54,4 +56,9 @@ setup(name='trytond_stock', ], license='GPL-3', install_requires=requires, + zip_safe=False, + entry_points=""" + [trytond.modules] + stock = trytond.modules.stock + """, ) From 5f91227f347db21998a1a1bd44de95570d46db51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 1 Dec 2008 14:02:36 +0100 Subject: [PATCH 03/64] Prepare changelog for release 1.0.1 --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 44de11f380..9801fce04d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +Version 1.0.1 - 2008-12-01 * Allow egg installation Version 1.0.0 - 2008-11-17 From 0c8d8d9e5e0c27f11815c757598fc1cc8a3d3ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 1 Dec 2008 14:03:06 +0100 Subject: [PATCH 04/64] Added tag 1.0.1 for changeset c934dee8797d --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 00d6644f31..0238a144f6 100644 --- a/.hgtags +++ b/.hgtags @@ -1 +1,2 @@ 36cc8c10a10e0df5e7a0ef2cb6d6cdda706c0180 1.0.0 +c934dee8797de27a032afe262a64152873124f0e 1.0.1 From a821944b10c6b810fdc494a329acc7cabef1eb9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 1 Dec 2008 14:03:47 +0100 Subject: [PATCH 05/64] Increase version number --- __tryton__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tryton__.py b/__tryton__.py index ee79b7fd19..33faf605eb 100644 --- a/__tryton__.py +++ b/__tryton__.py @@ -5,7 +5,7 @@ 'name_de_DE': 'Lagerverwaltung', 'name_fr_FR': 'Gestion des stocks', 'name_es_ES': 'Inventarios', - 'version': '1.0.1', + 'version': '1.0.2', 'author': 'B2CK', 'email': 'info@b2ck.com', 'website': 'http://www.tryton.org/', From 4159314331b05b5b2f6efb36f56794e6e2c016e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 2 Dec 2008 20:10:35 +0100 Subject: [PATCH 06/64] Change type into futur unit_price_required --- move.py | 213 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 107 insertions(+), 106 deletions(-) diff --git a/move.py b/move.py index 12071cf942..d685550592 100644 --- a/move.py +++ b/move.py @@ -16,7 +16,8 @@ class Move(OSV): _description = __doc__ product = fields.Many2One("product.product", "Product", required=True, select=1, states=STATES, - on_change=['product', 'type', 'currency', 'uom', 'company'], + on_change=['product', 'currency', 'uom', 'company', + 'from_location', 'to_location'], domain=[('type', '!=', 'service')]) uom = fields.Many2One("product.uom", "Uom", required=True, states=STATES, domain="[('category', '=', " \ @@ -28,12 +29,10 @@ class Move(OSV): digits="(16, unit_digits)", states=STATES) from_location = fields.Many2One("stock.location", "From Location", select=1, required=True, states=STATES, - domain=[('type', '!=', 'warehouse')], - on_change=['from_location', 'to_location']) + domain=[('type', '!=', 'warehouse')]) to_location = fields.Many2One("stock.location", "To Location", select=1, required=True, states=STATES, - domain=[('type', '!=', 'warehouse')], - on_change=['from_location', 'to_location']) + domain=[('type', '!=', 'warehouse')]) packing_in = fields.Many2One('stock.packing.in', 'Supplier Packing', readonly=True, select=1) packing_out = fields.Many2One('stock.packing.out', 'Customer Packing', @@ -54,22 +53,19 @@ class Move(OSV): }) unit_price = fields.Numeric('Unit Price', digits=(16, 4), states={ - 'invisible': "type not in ('input', 'output')", - 'required': "type in ('input', 'output')", - 'readonly': "state not in ('draft',)", + 'invisible': "not type", + 'required': "type", + 'readonly': "state != 'draft'", }) currency = fields.Many2One('currency.currency', 'Currency', states={ - 'invisible': "type not in ('input', 'output')", - 'required': "type in ('input', 'output')", - 'readonly': "state not in ('draft',)", + 'invisible': "not type", + 'required': "type", + 'readonly': "state != 'draft'", }) - type = fields.Function('get_type', type='selection', - selection=[ - ('input', 'Input'), - ('output', 'Output'), - ('internal', 'Internal'), - ], string='Type') + type = fields.Function('get_unit_price_required', + type='boolean', string='Unit Price Required', + on_change_with=['from_location', 'to_location']) def __init__(self): super(Move, self).__init__() @@ -147,6 +143,96 @@ class Move(OSV): context=context)[0] return False + def on_change_with_unit_digits(self, cursor, user, ids, vals, + context=None): + uom_obj = self.pool.get('product.uom') + if vals.get('uom'): + uom = uom_obj.browse(cursor, user, vals['uom'], + context=context) + return uom.digits + return 2 + + def get_unit_digits(self, cursor, user, ids, name, arg, context=None): + res = {} + for move in self.browse(cursor, user, ids, context=context): + res[move.id] = move.uom.digits + return res + + def on_change_product(self, cursor, user, ids, vals, context=None): + product_obj = self.pool.get('product.product') + uom_obj = self.pool.get('product.uom') + currency_obj = self.pool.get('currency.currency') + company_obj = self.pool.get('company.company') + location_obj = self.pool.get('stock.location') + + if context is None: + context = {} + + res = { + 'unit_price': Decimal('0.0'), + } + + if vals.get('product'): + product = product_obj.browse(cursor, user, vals['product'], + context=context) + res['uom'] = uom_obj.name_get(cursor, user, + product.default_uom.id, context=context)[0] + res['unit_digits'] = product.default_uom.digits + to_location = None + if vals.get('to_location'): + to_location = location_obj.browse(cursor, user, + vals['to_location'], context=context) + if to_location and to_location.type == 'storage': + unit_price = product.cost_price + if vals.get('uom') and vals['uom'] != product.default_uom.id: + uom = uom_obj.browse(cursor, user, vals['uom'], + context=context) + unit_price = uom_obj.compute_price(cursor, user, + product.default_uom, unit_price, uom, + context=context) + if vals.get('currency') and vals.get('company'): + currency = currency_obj.browse(cursor, user, + vals['currency'], context=context) + company = company_obj.browse(cursor, user, + vals['company'], context=context) + unit_price = currency_obj.compute(cursor, user, + company.currency, unit_price, currency, + context=context) + res['unit_price'] = unit_price + return res + + def on_change_with_type(self, cursor, user, ids, vals, + context=None): + location_obj = self.pool.get('stock.location') + if vals.get('from_location'): + from_location = location_obj.browse(cursor, user, + vals['from_location'], context=context) + if from_location.type == 'supplier': + return True + if vals.get('to_location'): + to_location = location_obj.browse(cursor, user, + vals['to_location'], context=context) + if to_location.type == 'customer': + return True + return False + + def get_unit_price_required(self, cursor, user, ids, name, arg, + context=None): + res = {} + for move in self.browse(cursor, user, ids, context=context): + res[move.id] = False + if move.from_location.type == 'supplier': + res[move.id] = True + if move.to_location.type == 'customer': + res[move.id] = True + return res + + def check_product_type(self, cursor, user, ids): + for move in self.browse(cursor, user, ids): + if move.product.type == 'service': + return False + return True + def name_search(self, cursor, user, name='', args=None, operator='ilike', context=None, limit=None): if not args: @@ -170,93 +256,6 @@ class Move(OSV): ) return res - def get_type(self, cursor, user, ids, name, args, context=None): - res = {} - for move in self.browse(cursor, user, ids, context=context): - res[move.id] = 'internal' - if move.from_location.type == 'supplier': - res[move.id] = 'input' - if move.to_location.type == 'customer': - res[move.id] = 'output' - return res - - def on_change_with_unit_digits(self, cursor, user, ids, vals, - context=None): - uom_obj = self.pool.get('product.uom') - if vals.get('uom'): - uom = uom_obj.browse(cursor, user, vals['uom'], - context=context) - return uom.digits - return 2 - - def get_unit_digits(self, cursor, user, ids, name, arg, context=None): - res = {} - for move in self.browse(cursor, user, ids, context=context): - res[move.id] = move.uom.digits - return res - - def on_change_product(self, cursor, user, ids, vals, context=None): - product_obj = self.pool.get('product.product') - uom_obj = self.pool.get('product.uom') - currency_obj = self.pool.get('currency.currency') - company_obj = self.pool.get('company.company') - if context is None: - context = {} - res = {'unit_price': Decimal('0.0')} - if vals.get('product'): - product = product_obj.browse(cursor, user, vals['product'], - context=context) - res['uom'] = uom_obj.name_get(cursor, user, - product.default_uom.id, context=context)[0] - res['unit_digits'] = product.default_uom.digits - if vals.get('type', 'internal') == 'input': - unit_price = product.cost_price - if vals.get('uom') and vals['uom'] != product.default_uom.id: - uom = uom_obj.browse(cursor, user, vals['uom'], - context=context) - unit_price = uom_obj.compute_price(cursor, user, - product.default_uom, unit_price, uom, - context=context) - if vals.get('currency') and vals.get('company'): - currency = currency_obj.browse(cursor, user, - vals['currency'], context=context) - company = company_obj.browse(cursor, user, - vals['company'], context=context) - unit_price = currency_obj.compute(cursor, user, - company.currency, unit_price, currency, - context=context) - res['unit_price'] = unit_price - return res - - def _on_change_location(self, cursor, user, ids, vals, context=None): - location_obj = self.pool.get('stock.location') - res = {'type': 'internal'} - if vals.get('from_location'): - location = location_obj.browse(cursor, user, vals['from_location'], - context=context) - if location.type == 'supplier': - res['type'] = 'input' - if vals.get('to_location'): - location = location_obj.browse(cursor, user, vals['to_location'], - context=context) - if location.type == 'customer': - res['type'] = 'output' - return res - - def check_product_type(self, cursor, user, ids): - for move in self.browse(cursor, user, ids): - if move.product.type == 'service': - return False - return True - - def on_change_from_location(self, cursor, user, ids, vals, context=None): - return self._on_change_location(cursor, user, ids, vals, - context=context) - - def on_change_to_location(self, cursor, user, ids, vals, context=None): - return self._on_change_location(cursor, user, ids, vals, - context=context) - def search(self, cursor, user, args, offset=0, limit=None, order=None, context=None, count=False, query_string=False): location_obj = self.pool.get('stock.location') @@ -366,7 +365,8 @@ class Move(OSV): for move in self.browse(cursor, user, ids, context=context): if vals['state'] == 'cancel': vals['effective_date'] = False - if move.type == 'input' and move.state != 'cancel' \ + if move.from_location.type == 'supplier' \ + and move.state != 'cancel' \ and move.product.cost_price_method == 'average': self._update_product_cost_price( cursor, user, move.product.id, -move.quantity, @@ -387,7 +387,8 @@ class Move(OSV): context=context) vals['effective_date'] = datetime.date.today() - if move.type == 'input' and move.state != 'done' \ + if move.from_location.type == 'supplier' \ + and move.state != 'done' \ and move.product.cost_price_method == 'average': self._update_product_cost_price( cursor, user, move.product.id, move.quantity, From 16e5e8ec15d56adb62ac1e7ec7d116ef3de0c624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 3 Dec 2008 00:25:50 +0100 Subject: [PATCH 07/64] Rename index_en into index --- doc/{index_en.rst => index.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/{index_en.rst => index.rst} (100%) diff --git a/doc/index_en.rst b/doc/index.rst similarity index 100% rename from doc/index_en.rst rename to doc/index.rst From ad256e232150c70e561c67ec8c8728d793e9dc0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 3 Dec 2008 00:42:13 +0100 Subject: [PATCH 08/64] Add bullet in doc --- doc/index.rst | 56 +++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/doc/index.rst b/doc/index.rst index 677cd6caff..1bf1982e98 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -12,12 +12,12 @@ Location Location are generic places where products are physically or virtually stored. There are six types of locations: -Storage +* Storage Storage locations define real places where products are stored. -Warehouse +* Warehouse Warehouses are meta-locations which define input, storage and output locations. These locations are all of type Storage. Input and Output @@ -26,17 +26,17 @@ Warehouse biggest location where products are stored for middle or long periods of time. -Customer +* Customer Customer locations are virtual locations accumulating products that have been sent to customers. -Supplier +* Supplier Supplier locations are virtual locations accumulating products that have been received from suppliers. -Lost And Found +* Lost And Found Lost And Found locations collects inventory gaps. See :ref:inventory for details. @@ -57,22 +57,22 @@ actually made). A move can be in one of this states: -Draft +* Draft The initial state, used when the move is created and to define future stock movement that are planned, but still subject to modifications. -Assigned +* Assigned An assigned move allow to reserve some products. Thus preventing other user to assign them. -Done +* Done The move is in state Done when the real movement is made. -Cancel +* Cancel A cancelled move will be ignored by the system. Only Draft or Assigned move can be cancelled. To revert a move in state Done, an @@ -105,12 +105,12 @@ A supplier packing is used when products are received from a supplier. It is mainly composed of a party (the supplier), a location (the warehouse in which the products are coming) and two list of moves: -Incoming moves +* Incoming moves The moves between the supplier location and the input location (as defined on the warehouse). -Inventory moves +* Inventory moves The inventory moves are between the input location and the storage location (or one of his child locations). @@ -118,20 +118,20 @@ Inventory moves The supplier packing can be in one of this states: -Draft +* Draft Incoming moves and inventory moves (if they exist) are in draft. -Received +* Received Incoming move are set in state Done, inventory moves are created if necessary. -Done +* Done Inventory moves are in state Done. -Cancel +* Cancel All moves are cancelled. @@ -143,12 +143,12 @@ A customer packing is used for sending products to customer. It is mainly composed of a party (the customer), a location (the warehouse out of which the product are going) and two list of moves: -Inventory moves: +* Inventory moves The moves between a storage location and the output location of the warehouse -Outgoing moves +* Outgoing moves The moves between the output location of the warehouse and a customer location. @@ -156,33 +156,33 @@ Outgoing moves The customer packing can be in one of this states: -Draft +* Draft Outgoing moves and inventory moves (if they exist) are in draft. -Waiting +* Waiting When a customer packing is set to waiting, the inventory moves are created (or completed) to balance the outgoing moves. The waiting state also means that the packing should be processed. -Assigned +* Assigned The assigned state is when products have been assigned (or reserved) from the storage locations. -Packed +* Packed The packed state is when the inventory moves have been made, i.e when the products have been physically moved to the outgoing locations. -Done +* Done The packing is Done when the outgoing moves have been made, e.g. when a truck left the warehouse. -Cancel +* Cancel A packing which is not yet completed (not in state Done) can be cancelled at any time. This also cancel all the moves. @@ -196,23 +196,23 @@ inside the company. It is mainly composed of two locations and a list of moves. It can be in one of these states: -Draft +* Draft The moves (if they exist) are in draft. -Waiting +* Waiting The waiting state means that the packing should be processed. -Assigned +* Assigned The assigned state is when products have been assigned. -Done +* Done The packing is Done when the moves have been made. -Cancel +* Cancel A packing which is not yet completed (not in state Done) can be cancelled at any time. This also cancel all the moves. From 48f6689ba928fd9a777549729e0fe2f5088c0e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 3 Dec 2008 12:44:33 +0100 Subject: [PATCH 09/64] Handle average price for products return to supplier --- move.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/move.py b/move.py index d685550592..472bd42efb 100644 --- a/move.py +++ b/move.py @@ -344,6 +344,8 @@ class Move(OSV): vals['effective_date'] = datetime.date.today() 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) if from_location.type == 'supplier' \ @@ -352,6 +354,12 @@ class Move(OSV): cursor, user, vals['product'], vals['quantity'], vals['uom'], vals['unit_price'], vals['currency'], vals['company'], context=context) + if to_location.type == 'supplier' \ + and product.cost_price_method == 'average': + self._update_product_cost_price( + cursor, user, vals['product'], -vals['quantity'], + vals['uom'], vals['unit_price'], vals['currency'], + vals['company'], context=context) return super(Move, self).create(cursor, user, vals, context=context) def write(self, cursor, user, ids, vals, context=None): @@ -372,6 +380,13 @@ class Move(OSV): cursor, user, move.product.id, -move.quantity, move.uom, move.unit_price, move.currency, move.company, context=context) + if move.to_location.type == 'supplier' \ + and move.state != 'cancel' \ + and move.product.cost_price_method == 'average': + self._update_product_cost_price( + cursor, user, move.product.id, move.quantity, + move.uom, move.unit_price, move.currency, + move.company, context=context) elif vals['state'] == 'draft': if move.state == 'done': @@ -394,6 +409,13 @@ class Move(OSV): cursor, user, move.product.id, move.quantity, move.uom, move.unit_price, move.currency, move.company, context=context) + if move.to_location.type == 'supplier' \ + and move.state != 'done' \ + and move.product.cost_price_method == 'average': + self._update_product_cost_price( + cursor, user, move.product.id, -move.quantity, + move.uom, move.unit_price, move.currency, + move.company, context=context) return super(Move, self).write(cursor, user, ids, vals, context=context) From 1f7fb86b064b1eacd8de390a20757dc9d9149631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 3 Dec 2008 12:45:38 +0100 Subject: [PATCH 10/64] Add missing changelog --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 9801fce04d..74ad6f10f8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Handle average price for products return to supplier + Version 1.0.1 - 2008-12-01 * Allow egg installation From de1800256f696f15adb81319e6b39df513bc6b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 4 Dec 2008 18:34:30 +0100 Subject: [PATCH 11/64] Fix set_xxx_moves when value is False --- packing.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packing.py b/packing.py index fbcbb65f8f..22b1359ee0 100644 --- a/packing.py +++ b/packing.py @@ -113,6 +113,10 @@ class PackingIn(OSV): def set_incoming_moves(self, cursor, user, packing_id, name, value, arg, context=None): move_obj = self.pool.get('stock.move') + + if not value: + return + packing = self.browse(cursor, user, packing_id, context=context) for act in value: if act[0] == 'create': @@ -156,6 +160,10 @@ class PackingIn(OSV): def set_inventory_moves(self, cursor, user, packing_id, name, value, arg, context=None): move_obj = self.pool.get('stock.move') + + if not value: + return + packing = self.browse(cursor, user, packing_id, context=context) for act in value: if act[0] == 'create': @@ -381,6 +389,10 @@ class PackingOut(OSV): def set_outgoing_moves(self, cursor, user, packing_id, name, value, arg, context=None): move_obj = self.pool.get('stock.move') + + if not value: + return + packing = self.browse(cursor, user, packing_id, context=context) for act in value: if act[0] == 'create': @@ -425,6 +437,10 @@ class PackingOut(OSV): def set_inventory_moves(self, cursor, user, packing_id, name, value, arg, context=None): move_obj = self.pool.get('stock.move') + + if not value: + return + packing = self.browse(cursor, user, packing_id, context=context) for act in value: if act[0] == 'create': From 38fb52a964cd0a235fa0239a4bce9d85ee6f50fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 5 Dec 2008 13:53:30 +0100 Subject: [PATCH 12/64] Fix complete_lines to set only stockable products --- inventory.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/inventory.py b/inventory.py index 3be3009228..7b43b3df70 100644 --- a/inventory.py +++ b/inventory.py @@ -137,9 +137,12 @@ class Inventory(OSV): # Index some data product2uom = {} - for product in product_obj.browse( - cursor, user, [line[1] for line in pbl], context=context): + product2type = {} + for product in product_obj.browse(cursor, user, + [line[1] for line in pbl], context=context): product2uom[product.id] = product.default_uom.id + product2type[product.id] = product.type + product_qty = {} for (location, product), quantity in pbl.iteritems(): product_qty[product] = (quantity, product2uom[product]) @@ -169,6 +172,8 @@ class Inventory(OSV): # Create lines if needed for product in product_qty: + if product2type[product] != 'stockable': + continue quantity, uom_id = product_qty[product] values = { 'product': product, From 61342919767d877ab48dc28c5ce18249d2ece7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 10 Dec 2008 16:55:51 +0100 Subject: [PATCH 13/64] Fix location domain for internal packing --- packing.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packing.py b/packing.py index 22b1359ee0..83c09db5e6 100644 --- a/packing.py +++ b/packing.py @@ -701,11 +701,13 @@ class PackingInternal(OSV): from_location = fields.Many2One( 'stock.location', "From Location", required=True, states={ 'readonly': "state != 'draft' or bool(moves)", }, - domain="[('type', '=', 'storage')]", ) + domain="[('type', 'not in', " \ + "('supplier', 'customer', 'warehouse'))]") to_location = fields.Many2One('stock.location', "To Location", required=True, states={ 'readonly': "state != 'draft' or bool(moves)", - }, domain="[('type', '=', 'storage')]") + }, domain="[('type', 'not in', " \ + "('supplier', 'customer', 'warehouse'))]") moves = fields.One2Many( 'stock.move', 'packing_internal', 'Moves', states={'readonly': "state != 'draft' or "\ From e8385d6f17e9ac7b116e27638be3b4998ccf90ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 12 Dec 2008 17:09:08 +0100 Subject: [PATCH 14/64] Fix loop in warehouse creation for issue664 --- location.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/location.py b/location.py index 446df6e0be..951485a294 100644 --- a/location.py +++ b/location.py @@ -42,21 +42,27 @@ class Location(OSV): 'readonly': "not active", 'required': "type == 'warehouse'", }, - domain="[('type','=','storage'), ('parent', 'child_of', [active_id])]") + domain="[('type','=','storage'), ['OR', " \ + "('parent', 'child_of', [active_id]), " \ + "('parent', '=', False)]]") output_location = fields.Many2One( "stock.location", "Output", states={ 'invisible': "type != 'warehouse'", 'readonly': "not active", 'required': "type == 'warehouse'", }, - domain="[('type','=','storage'), ('parent', 'child_of', [active_id])]") + domain="[('type','=','storage'), ['OR', " \ + "('parent', 'child_of', [active_id]), " \ + "('parent', '=', False)]]") storage_location = fields.Many2One( "stock.location", "Storage", states={ 'invisible': "type != 'warehouse'", 'readonly': "not active", 'required': "type == 'warehouse'", }, - domain="[('type','=','storage'), ('parent', 'child_of', [active_id])]") + domain="[('type','=','storage'), ['OR', " \ + "('parent', 'child_of', [active_id]), " \ + "('parent', '=', False)]]") quantity = fields.Function('get_quantity', type='float', string='Quantity') forecast_quantity = fields.Function('get_quantity', type='float', string='Forecast Quantity') @@ -143,6 +149,46 @@ class Location(OSV): return value + ': ' + product_name + ' (' + uom_name + ')' return False + def _set_warehouse_parent(self, cursor, user, locations, context=None): + ''' + Set the parent of child location of warehouse if not set + + :param cursor: the database cursor + :param user: the user id + :param locations: a BrowseRecordList of locations + :param context: the context + :return: a list with updated location ids + ''' + location_ids = set() + for location in locations: + if location.type == 'warehouse': + if not location.input_location.parent: + location_ids.add(location.input_location.id) + if not location.output_location.parent: + location_ids.add(location.output_location.id) + if not location.storage_location.parent: + location_ids.add(location.storage_location.id) + location_ids = list(location_ids) + if location_ids: + self.write(cursor, user, location_ids, { + 'parent': location.id, + }, context=context) + + def create(self, cursor, user, vals, context=None): + res = super(Location, self).create(cursor, user, vals, context=context) + locations = self.browse(cursor, user, [res], context=context) + self._set_warehouse_parent(cursor, user, locations, context=context) + return res + + def write(self, cursor, user, ids, vals, context=None): + res = super(Location, self).write(cursor, user, ids, vals, + context=context) + if isinstance(ids, (int, long)): + ids = [ids] + locations = self.browse(cursor, user, ids, context=context) + self._set_warehouse_parent(cursor, user, locations, context=context) + return res + Location() From 25118c481c428bf72378ba8874dbb7d65dbc5165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 17 Dec 2008 23:03:43 +0100 Subject: [PATCH 15/64] Fix creation of warehouse and set noupdate to location data for issue682 --- location.xml | 86 +++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/location.xml b/location.xml index 9e7b31f0e1..029913bc22 100644 --- a/location.xml +++ b/location.xml @@ -127,51 +127,6 @@ this repository contains the full copyright notices and license terms. --> - - - Warehouse - - - Input Zone - IN - storage - - - - Output Zone - OUT - storage - - - - Storage Zone - STO - storage - - - - Warehouse - WH - warehouse - - - - - - Supplier - SUP - supplier - - - Customer - CUS - customer - - - Lost and Found - lost_found - - party.party @@ -206,6 +161,47 @@ this repository contains the full copyright notices and license terms. --> + + + + + Input Zone + IN + storage + + + Output Zone + OUT + storage + + + Storage Zone + STO + storage + + + Warehouse + WH + warehouse + + + + + + Supplier + SUP + supplier + + + Customer + CUS + customer + + + Lost and Found + lost_found + + supplier_location Date: Thu, 18 Dec 2008 16:02:27 +0100 Subject: [PATCH 16/64] Fix quantities computation, added missing parentheses --- product.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/product.py b/product.py index d8b7165098..6a52df3f74 100644 --- a/product.py +++ b/product.py @@ -167,11 +167,11 @@ class Product(OSV): (context['stock_date_end'] == \ date_obj.today(cursor, user, context=context) \ and not context.get('forecast')): - state_date_clause = '(state in (%s, %s)) AND ('\ + state_date_clause = '((state in (%s, %s)) AND ('\ '(effective_date IS NULL '\ 'AND ( planned_date <= %s or planned_date IS NULL)) '\ 'OR effective_date <= %s'\ - ')' + '))' state_date_vals = ["done", context.get('stock_assign') and 'assigned' or 'done', context['stock_date_end'], @@ -185,7 +185,7 @@ class Product(OSV): # before today, or on all state and date between today and # date_end. else: - state_date_clause = '(' + \ + state_date_clause = '((' + \ '(state in (%s, %s)) AND ('\ '(effective_date IS NULL '\ 'AND ( planned_date <= %s or planned_date IS NULL)) '\ @@ -198,7 +198,7 @@ class Product(OSV): 'OR planned_date IS NULL)) '\ 'OR (effective_date <= %s AND effective_date >= %s)'\ ')'\ - ')' + '))' today = date_obj.today(cursor, user, context=context) state_date_vals = [ 'done', 'assigned', today, today, @@ -210,33 +210,33 @@ class Product(OSV): if context.get('stock_date_start'): if context['stock_date_start'] > date_obj.today(cursor, user, context=context): - state_date_clause += ' AND (state in (%s, %s, %s)) AND ('\ + state_date_clause += ' AND ((state in (%s, %s, %s)) AND ('\ '(effective_date IS NULL '\ - 'AND ( planned_date >= %s or planned_date IS NULL)) '\ + 'AND ( planned_date >= %s)) '\ 'OR effective_date >= %s'\ - ')' + '))' state_date_vals.extend( ['done', 'assigned', 'draft', context['stock_date_start'], context['stock_date_start']]) else: tmp_clause = '(state in (%s, %s, %s)) AND ('\ '(effective_date IS NULL '\ - 'AND ( planned_date >= %s or planned_date IS NULL)) '\ + 'AND ( planned_date >= %s)) '\ 'OR effective_date >= %s'\ ')' today = date_obj.today(cursor, user, context=context) state_date_vals.extend( ['done', 'assigned', 'draft', today, today]) - state_date_clause += ' AND (' + tmp_clause + \ + state_date_clause += ' AND ((' + tmp_clause + \ ') OR (' + \ '(state in (%s, %s)) AND ('\ '(effective_date IS NULL '\ 'AND (( planned_date >= %s AND planned_date < %s ) '\ - 'OR planned_date IS NULL)) '\ + ')) '\ 'OR (effective_date >= %s AND effective_date < %s)'\ ')'\ - ')' + '))' state_date_vals.extend([ 'done', context.get('stock_assign') and 'assigned' or 'done', From 715ed9dede9fd2fc37c58239220df50b2e300470 Mon Sep 17 00:00:00 2001 From: Bertrand Chenal Date: Thu, 18 Dec 2008 20:12:47 +0100 Subject: [PATCH 17/64] Fix null date handling --- product.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/product.py b/product.py index 6a52df3f74..4f70a80283 100644 --- a/product.py +++ b/product.py @@ -169,7 +169,7 @@ class Product(OSV): and not context.get('forecast')): state_date_clause = '((state in (%s, %s)) AND ('\ '(effective_date IS NULL '\ - 'AND ( planned_date <= %s or planned_date IS NULL)) '\ + 'AND ( planned_date <= %s)) '\ 'OR effective_date <= %s'\ '))' state_date_vals = ["done", @@ -188,14 +188,14 @@ class Product(OSV): state_date_clause = '((' + \ '(state in (%s, %s)) AND ('\ '(effective_date IS NULL '\ - 'AND ( planned_date <= %s or planned_date IS NULL)) '\ + 'AND ( planned_date <= %s )) '\ 'OR effective_date <= %s)' \ + \ ') OR (' + \ '(state in (%s, %s, %s)) AND ('\ '(effective_date IS NULL '\ - 'AND (( planned_date <= %s AND planned_date >= %s ) '\ - 'OR planned_date IS NULL)) '\ + 'AND ( planned_date <= %s AND planned_date >= %s '\ + ')) '\ 'OR (effective_date <= %s AND effective_date >= %s)'\ ')'\ '))' @@ -212,7 +212,7 @@ class Product(OSV): context=context): state_date_clause += ' AND ((state in (%s, %s, %s)) AND ('\ '(effective_date IS NULL '\ - 'AND ( planned_date >= %s)) '\ + 'AND ( planned_date >= %s OR planned_date IS NULL)) '\ 'OR effective_date >= %s'\ '))' state_date_vals.extend( @@ -221,7 +221,7 @@ class Product(OSV): else: tmp_clause = '(state in (%s, %s, %s)) AND ('\ '(effective_date IS NULL '\ - 'AND ( planned_date >= %s)) '\ + 'AND ( planned_date >= %s OR planned_date IS NULL)) '\ 'OR effective_date >= %s'\ ')' today = date_obj.today(cursor, user, context=context) @@ -233,7 +233,7 @@ class Product(OSV): '(state in (%s, %s)) AND ('\ '(effective_date IS NULL '\ 'AND (( planned_date >= %s AND planned_date < %s ) '\ - ')) '\ + 'OR planned_date IS NULL)) '\ 'OR (effective_date >= %s AND effective_date < %s)'\ ')'\ '))' From 4eba00272ae2945d413ecce683b72b8bd97c48cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 6 Jan 2009 13:51:49 +0100 Subject: [PATCH 18/64] Prepare changelog for release 1.0.2 --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 74ad6f10f8..bf64720d2d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,6 @@ +Version 1.0.2 - 2009-01-06 * Handle average price for products return to supplier +* Some bug fixes (see mercurial logs for details) Version 1.0.1 - 2008-12-01 * Allow egg installation From 31ba84f7a498901ded87d217c31f4d52c78fa6ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 6 Jan 2009 13:51:55 +0100 Subject: [PATCH 19/64] Added tag 1.0.2 for changeset 00f417866b68 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 0238a144f6..d70d083a4f 100644 --- a/.hgtags +++ b/.hgtags @@ -1,2 +1,3 @@ 36cc8c10a10e0df5e7a0ef2cb6d6cdda706c0180 1.0.0 c934dee8797de27a032afe262a64152873124f0e 1.0.1 +00f417866b683fb9126c53af02e2f72b2d1330b3 1.0.2 From 35a2a9db24e85c6db9b672df4498f277ac7020d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 6 Jan 2009 13:53:30 +0100 Subject: [PATCH 20/64] Increase version number --- __tryton__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tryton__.py b/__tryton__.py index 33faf605eb..c4582971cb 100644 --- a/__tryton__.py +++ b/__tryton__.py @@ -5,7 +5,7 @@ 'name_de_DE': 'Lagerverwaltung', 'name_fr_FR': 'Gestion des stocks', 'name_es_ES': 'Inventarios', - 'version': '1.0.2', + 'version': '1.0.3', 'author': 'B2CK', 'email': 'info@b2ck.com', 'website': 'http://www.tryton.org/', From ca09aa6cbeb94d7511ed22393d8ed80f7d5cde5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 8 Jan 2009 13:39:52 +0100 Subject: [PATCH 21/64] Improve test on product in context and fix some guidelines --- location.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/location.py b/location.py index 951485a294..da8622909b 100644 --- a/location.py +++ b/location.py @@ -110,7 +110,11 @@ class Location(OSV): product_obj = self.pool.get('product.product') date_obj = self.pool.get('ir.date') - if (not context) or (not context.get('product')): + if not context: + context = {} + + if (not context.get('product')) \ + or not (isinstance(context['product'], (int, long))): return dict([(i,0) for i in ids]) if name == 'quantity' and \ @@ -131,7 +135,7 @@ class Location(OSV): product_ids=[context['product']], with_childs=True, skip_zero=False, context=context).iteritems() - return dict( [(loc,qty) for (loc,prod), qty in pbl] ) + return dict([(loc,qty) for (loc,prod), qty in pbl]) def view_header_get(self, cursor, user, value, view_type='form', context=None): @@ -139,7 +143,8 @@ class Location(OSV): uom_obj = self.pool.get('product.uom') if context is None: context = {} - if context.get('product'): + if context.get('product') \ + and isinstance(context['product'], (int, long)): product_name = product_obj.name_get(cursor, user, context['product'], context=context)[0][1] product = product_obj.browse(cursor, user, context['product'], From 1397ab9cf0093359c75e0d4bbc20a9a092e64466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 8 Jan 2009 14:45:17 +0100 Subject: [PATCH 22/64] Fix typo in pick_product consumable for issue736 --- product.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product.py b/product.py index 4f70a80283..48366d080d 100644 --- a/product.py +++ b/product.py @@ -402,7 +402,7 @@ class Product(OSV): needed_qty -= available_qty # Force assignation for consumables: if move.product.type == "consumable": - to_pick.append((move.from_location.id, needed_qty)) + to_pick.append((move.from_location, needed_qty)) return to_pick return None From 9abe1e6d147805aa47ac1937cf2844ad485c0a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 8 Jan 2009 14:47:43 +0100 Subject: [PATCH 23/64] Update copyright --- COPYRIGHT | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index 37fef2d645..da277a9b35 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,7 +1,7 @@ Copyright (C) 2004-2008 Tiny SPRL. -Copyright (C) 2008 Cédric Krier. -Copyright (C) 2008 Bertrand Chenal. -Copyright (C) 2008 B2CK SPRL. +Copyright (C) 2008-2009 Cédric Krier. +Copyright (C) 2008-2009 Bertrand Chenal. +Copyright (C) 2008-2009 B2CK SPRL. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 60ec0ed970c260a696b0ebeba2fb5c89416dfcd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 16 Jan 2009 18:49:18 +0100 Subject: [PATCH 24/64] Add on_change_uom to handle unit_price and don't round unit_price when calling currency.compute --- move.py | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/move.py b/move.py index 472bd42efb..545aa11980 100644 --- a/move.py +++ b/move.py @@ -22,7 +22,9 @@ class Move(OSV): uom = fields.Many2One("product.uom", "Uom", required=True, states=STATES, domain="[('category', '=', " \ "(product, 'product.default_uom.category'))]", - context="{'category': (product, 'product.default_uom.category')}") + context="{'category': (product, 'product.default_uom.category')}", + on_change=['product', 'currency', 'uom', 'company', + 'from_location', 'to_location']) unit_digits = fields.Function('get_unit_digits', type='integer', string='Unit Digits', on_change_with=['uom']) quantity = fields.Float("Quantity", required=True, @@ -197,7 +199,46 @@ class Move(OSV): vals['company'], context=context) unit_price = currency_obj.compute(cursor, user, company.currency, unit_price, currency, + round=False, context=context) + res['unit_price'] = unit_price + return res + + def on_change_uom(self, cursor, user, ids, vals, context=None): + product_obj = self.pool.get('product.product') + uom_obj = self.pool.get('product.uom') + currency_obj = self.pool.get('currency.currency') + company_obj = self.pool.get('company.company') + location_obj = self.pool.get('stock.location') + + if context is None: + context = {} + + res = { + 'unit_price': Decimal('0.0'), + } + if vals.get('product'): + product = product_obj.browse(cursor, user, vals['product'], + context=context) + to_location = None + if vals.get('to_location'): + to_location = location_obj.browse(cursor, user, + vals['to_location'], context=context) + if to_location and to_location.type == 'storage': + unit_price = product.cost_price + if vals.get('uom') and vals['uom'] != product.default_uom.id: + uom = uom_obj.browse(cursor, user, vals['uom'], context=context) + unit_price = uom_obj.compute_price(cursor, user, + product.default_uom, unit_price, uom, + context=context) + if vals.get('currency') and vals.get('company'): + currency = currency_obj.browse(cursor, user, + vals['currency'], context=context) + company = company_obj.browse(cursor, user, + vals['company'], context=context) + unit_price = currency_obj.compute(cursor, user, + company.currency, unit_price, currency, + round=False, context=context) res['unit_price'] = unit_price return res @@ -321,7 +362,7 @@ class Move(OSV): # convert wrt currency unit_price = currency_obj.compute( cursor, user, currency, unit_price, company.currency, - context=context) + round=False, context=context) # convert wrt to the uom unit_price = uom_obj.compute_price( cursor, user, uom, unit_price, product.default_uom, context=context) From a56432bfec3e539c3d44b14a5030488831ab2c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 20 Jan 2009 01:13:32 +0100 Subject: [PATCH 25/64] Fix assign_try to work on all child locations Use copy in assign_try to be more generic --- product.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/product.py b/product.py index 48366d080d..c7fb3b2412 100644 --- a/product.py +++ b/product.py @@ -411,6 +411,7 @@ class Product(OSV): product_obj = self.pool.get('product.product') uom_obj = self.pool.get('product.uom') date_obj = self.pool.get('ir.date') + location_obj = self.pool.get('stock.location') if context is None: context = {} @@ -421,8 +422,11 @@ class Product(OSV): local_ctx['stock_date_end'] = date_obj.today(cursor, user, context=context) local_ctx['stock_assign'] = True + location_ids = location_obj.search(cursor, user, [ + ('parent', 'child_of', [x.from_location.id for x in moves]), + ], context=context) pbl = product_obj.products_by_location(cursor, user, - location_ids=[m.from_location.id for m in moves], + location_ids=location_ids, product_ids=[m.product.id for m in moves], context=local_ctx) @@ -432,8 +436,11 @@ class Product(OSV): continue to_location = move.to_location location_qties = {} - childs = [m for m in move.from_location.childs] + [move.from_location] - for location in childs: + child_ids = location_obj.search(cursor, user, [ + ('parent', 'child_of', [move.from_location.id]), + ], context=context) + for location in location_obj.browse(cursor, user, child_ids, + context=context): if (location.id, move.product.id) in pbl: location_qties[location] = uom_obj.compute_qty( cursor, user, move.product.default_uom, @@ -450,24 +457,16 @@ class Product(OSV): for from_location, qty in to_pick: values = { 'from_location': from_location.id, - 'to_location': to_location.id, - 'product': move.product.id, - 'uom': move.uom.id, 'quantity': qty, 'state': 'assigned', - 'company': move.company.id, } - for field in ('packing_out', 'packing_in', 'packing_internal'): - if move[field]: - values.update({field: move[field].id}) - break - if first: move_obj.write(cursor, user, move.id, values, context=context) first = False else: - move_obj.create(cursor, user, values, context=context) + move_id = move_obj.copy(cursor, user, move.id, + default=values, context=context) qty_defaut_uom = uom_obj.compute_qty( cursor, user, move.uom, qty, move.product.default_uom, From d8f2d8139dca06319eef58fa3b8a746d01ab3486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 21 Jan 2009 01:49:18 +0100 Subject: [PATCH 26/64] Add priority to tree view of stock.location for product stock for issue755 --- product.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/product.xml b/product.xml index 4469bdb8aa..8013b1e677 100644 --- a/product.xml +++ b/product.xml @@ -24,6 +24,7 @@ stock.location tree childs + From ebf19fda2107a56071a8f3ba9f19994c32f49994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 26 Jan 2009 19:08:12 +0100 Subject: [PATCH 27/64] Missing context in assign_force of internal packing --- packing.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packing.py b/packing.py index 83c09db5e6..cc397dba58 100644 --- a/packing.py +++ b/packing.py @@ -795,8 +795,9 @@ class PackingInternal(OSV): def assign_force(self, cursor, user, packing_id, context=None): packing = self.browse(cursor, user, packing_id, context=context) move_obj = self.pool.get('stock.move') - move_obj.write( - cursor, user, [m.id for m in packing.moves], {'state': 'assigned'}) + move_obj.write(cursor, user, [m.id for m in packing.moves], { + 'state': 'assigned', + }, context=context) return True PackingInternal() From 086a9e7259aebf312598c1939acd94eec295d73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 26 Jan 2009 19:08:38 +0100 Subject: [PATCH 28/64] Set effective_date also for assigned moves --- move.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/move.py b/move.py index 545aa11980..5c8a9c078c 100644 --- a/move.py +++ b/move.py @@ -401,6 +401,9 @@ class Move(OSV): cursor, user, vals['product'], -vals['quantity'], vals['uom'], vals['unit_price'], vals['currency'], vals['company'], context=context) + elif vals.get('state') == 'assigned': + if not vals.get('effective_date'): + vals['effective_date'] = datetime.date.today() return super(Move, self).create(cursor, user, vals, context=context) def write(self, cursor, user, ids, vals, context=None): @@ -437,6 +440,7 @@ class Move(OSV): if move.state in ('cancel', 'done'): self.raise_user_error(cursor, 'set_state_assigned', context=context) + vals['effective_date'] = datetime.date.today() elif vals['state'] == 'done': if move.state in ('cancel'): self.raise_user_error(cursor, 'set_state_done', From af6c5cbe3f39b037ff9034d1de54fcd4ce626c58 Mon Sep 17 00:00:00 2001 From: Bertrand Chenal Date: Mon, 26 Jan 2009 22:29:00 +0100 Subject: [PATCH 29/64] Fix warehouse default value: use list instead of string for domain. --- packing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packing.py b/packing.py index cc397dba58..c518eb9821 100644 --- a/packing.py +++ b/packing.py @@ -316,7 +316,7 @@ class PackingOut(OSV): warehouse = fields.Many2One('stock.location', "Warehouse", required=True, states={ 'readonly': "state != 'draft'", - }, domain="[('type', '=', 'warehouse')]") + }, domain=[('type', '=', 'warehouse')]) customer_location = fields.Many2One('stock.location', "Customer Location", required=True, states={ 'readonly': "state != 'draft'", From 10dce84903881e7c52cf243e5dab59bf7595b58c Mon Sep 17 00:00:00 2001 From: Bertrand Chenal Date: Tue, 27 Jan 2009 14:57:46 +0100 Subject: [PATCH 30/64] Fix on_change: clean location and address when custome/supplier is unset. --- packing.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packing.py b/packing.py index c518eb9821..42a8a31e1f 100644 --- a/packing.py +++ b/packing.py @@ -95,7 +95,7 @@ class PackingIn(OSV): def on_change_supplier(self, cursor, user, ids, values, context=None): if not values.get('supplier'): - return {} + return {'contact_address': False} party_obj = self.pool.get("party.party") address_id = party_obj.address_get(cursor, user, values['supplier'], context=context) @@ -366,7 +366,8 @@ class PackingOut(OSV): def on_change_customer(self, cursor, user, ids, values, context=None): if not values.get('customer'): - return {} + return {'delivery_address': False, + 'customer_location': False} party_obj = self.pool.get("party.party") address_id = party_obj.address_get(cursor, user, values['customer'], type='delivery', context=context) From 4467bf9db03851dd71bf96aa8fcf237bcbee632d Mon Sep 17 00:00:00 2001 From: Bertrand Chenal Date: Tue, 27 Jan 2009 14:59:29 +0100 Subject: [PATCH 31/64] Fix: use sequence on inventory packing creation. --- packing.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packing.py b/packing.py index 42a8a31e1f..bb8115a903 100644 --- a/packing.py +++ b/packing.py @@ -742,6 +742,13 @@ class PackingInternal(OSV): ] self._order[0] = ('id', 'DESC') + def create(self, cursor, user, values, context=None): + values = values.copy() + values['code'] = self.pool.get('ir.sequence').get( + cursor, user, 'stock.packing.internal', context=context) + return super(PackingInternal, self).create( + cursor, user, values, context=context) + def set_state_draft(self, cursor, user, packing_id, context=None): move_obj = self.pool.get('stock.move') packing = self.browse(cursor, user, packing_id, context=context) From c90a2b43788c6d5264508da18ef601bbd4654ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 4 Feb 2009 13:57:11 +0100 Subject: [PATCH 32/64] Check context value in get_quantity on stock.location Verify that the product id from context has a real product record --- location.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/location.py b/location.py index da8622909b..a06df97120 100644 --- a/location.py +++ b/location.py @@ -115,7 +115,14 @@ class Location(OSV): if (not context.get('product')) \ or not (isinstance(context['product'], (int, long))): - return dict([(i,0) for i in ids]) + return dict([(i, 0) for i in ids]) + + ctx = context.copy() + ctx['active_test'] = False + if not product_obj.search(cursor, user, [ + ('id', '=', context['product']), + ], context=ctx): + return dict([(i, 0) for i in ids]) if name == 'quantity' and \ context.get('stock_date_end') > \ From c63190fc3d2a5751cfec95b05c9bf5375cecb800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 4 Feb 2009 17:48:46 +0100 Subject: [PATCH 33/64] Check context value in view_header_get on stock.location --- location.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/location.py b/location.py index a06df97120..b859a7d298 100644 --- a/location.py +++ b/location.py @@ -150,8 +150,13 @@ class Location(OSV): uom_obj = self.pool.get('product.uom') if context is None: context = {} + ctx = context.copy() + ctx['active_test'] = False if context.get('product') \ - and isinstance(context['product'], (int, long)): + and isinstance(context['product'], (int, long)) \ + and product_obj.search(cursor, user, [ + ('id', '=', context['product']), + ], context=ctx): product_name = product_obj.name_get(cursor, user, context['product'], context=context)[0][1] product = product_obj.browse(cursor, user, context['product'], From bc455a10354ddeaffe3f6084fc87f3b0ff0800d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 2 Mar 2009 10:26:38 +0100 Subject: [PATCH 34/64] Prepare changelog for release 1.0.3 --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index bf64720d2d..72ad7b86b5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +Version 1.0.3 - 2009-03-02 +* Some bug fixes (see mercurial logs for details) + Version 1.0.2 - 2009-01-06 * Handle average price for products return to supplier * Some bug fixes (see mercurial logs for details) From 9af35737aba667679d4657fe2432687fdb403f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 2 Mar 2009 10:26:48 +0100 Subject: [PATCH 35/64] Added tag 1.0.3 for changeset 7b355cbccd4b --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index d70d083a4f..5341848ec1 100644 --- a/.hgtags +++ b/.hgtags @@ -1,3 +1,4 @@ 36cc8c10a10e0df5e7a0ef2cb6d6cdda706c0180 1.0.0 c934dee8797de27a032afe262a64152873124f0e 1.0.1 00f417866b683fb9126c53af02e2f72b2d1330b3 1.0.2 +7b355cbccd4bc63835bac801fe87bcdd18967f50 1.0.3 From 84e4b8fd3e4a4c5256ee36bf48b8bff68273f721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 2 Mar 2009 10:27:20 +0100 Subject: [PATCH 36/64] Increase version number --- __tryton__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tryton__.py b/__tryton__.py index c4582971cb..d5fb8df2eb 100644 --- a/__tryton__.py +++ b/__tryton__.py @@ -5,7 +5,7 @@ 'name_de_DE': 'Lagerverwaltung', 'name_fr_FR': 'Gestion des stocks', 'name_es_ES': 'Inventarios', - 'version': '1.0.3', + 'version': '1.0.4', 'author': 'B2CK', 'email': 'info@b2ck.com', 'website': 'http://www.tryton.org/', From 4fc62ea1b598430410630e12d09f16a43bc3aea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 26 Mar 2009 00:47:22 +0100 Subject: [PATCH 37/64] Don't round compute_qty in set_state_packed for internal quantity counter for issue899 --- packing.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packing.py b/packing.py index bb8115a903..a749b50e09 100644 --- a/packing.py +++ b/packing.py @@ -513,7 +513,7 @@ class PackingOut(OSV): if move.state == 'cancel': continue quantity = uom_obj.compute_qty( cursor, user, move.uom, move.quantity, move.product.default_uom, - context=context) + round=False, context=context) outgoing_qty.setdefault(move.product.id, 0.0) outgoing_qty[move.product.id] += quantity @@ -521,7 +521,7 @@ class PackingOut(OSV): if move.state == 'cancel': continue qty_default_uom = uom_obj.compute_qty( cursor, user, move.uom, move.quantity, move.product.default_uom, - context=context) + round=False, context=context) # Check if the outgoing move doesn't exist already if outgoing_qty.get(move.product.id): # If it exist, decrease the sum @@ -567,7 +567,7 @@ class PackingOut(OSV): }, context=context) removed_qty = uom_obj.compute_qty( cursor, user, move.uom, min(exc_qty, move.quantity), - move.product.default_uom, context=context) + move.product.default_uom, round=False, context=context) outgoing_qty[move.product.id] -= removed_qty From c5f6e6942028cb30902c3333ab23c59a678604a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 26 Mar 2009 00:58:49 +0100 Subject: [PATCH 38/64] Fix states of supplier on packing.in when there is no value set for issue901 --- packing.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packing.py b/packing.py index a749b50e09..34ff32cd86 100644 --- a/packing.py +++ b/packing.py @@ -25,7 +25,8 @@ class PackingIn(OSV): states={'readonly': "state != 'draft'",}) supplier = fields.Many2One('party.party', 'Supplier', states={ - 'readonly': "state != 'draft' or bool(incoming_moves)", + 'readonly': "(state != 'draft' or bool(incoming_moves)) " \ + "and bool(supplier)", }, on_change=['supplier'], required=True) contact_address = fields.Many2One('party.address', 'Contact Address', states={ From 7fe5bbdc5c24151519537b9ad29fe46039090039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 8 May 2009 00:23:48 +0200 Subject: [PATCH 39/64] Set default value for left and right when copying location --- location.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/location.py b/location.py index b859a7d298..8615117115 100644 --- a/location.py +++ b/location.py @@ -206,6 +206,14 @@ class Location(OSV): self._set_warehouse_parent(cursor, user, locations, context=context) return res + def copy(self, cursor, user, ids, default=None, context=None): + if default is None: + default = {} + default['left'] = 0 + default['right'] = 0 + return super(Location, self).copy(cursor, user, ids, default=default, + context=context) + Location() From 5a470da62ecb1bdbf7ba0afd04c620e6e77878d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 11 May 2009 19:22:34 +0200 Subject: [PATCH 40/64] Prepare changelog for release 1.0.4 --- CHANGELOG | 3 +++ location.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 72ad7b86b5..9e3e2698e3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +Version 1.0.4 - 2009-05-11 +* Some bug fixes (see mercurial logs for details) + Version 1.0.3 - 2009-03-02 * Some bug fixes (see mercurial logs for details) diff --git a/location.py b/location.py index 8615117115..057e7f2a75 100644 --- a/location.py +++ b/location.py @@ -209,10 +209,56 @@ class Location(OSV): def copy(self, cursor, user, ids, default=None, context=None): if default is None: default = {} + int_id = False + if isinstance(ids, (int, long)): + int_id = True + ids = [ids] + default['left'] = 0 default['right'] = 0 - return super(Location, self).copy(cursor, user, ids, default=default, - context=context) + + res = [] + locations = self.browse(cursor, user, ids, context=context) + for location in locations: + if location.type == 'warehouse': + + wh_default = default.copy() + wh_default['type'] = 'view' + wh_default['input_location'] = False + wh_default['output_location'] = False + wh_default['storage_location'] = False + wh_default['childs'] = False + + new_id = super(Location, self).copy( + cursor, user, location.id, default=wh_default, + context=context) + + child_context = context and context.copy() or {} + child_context['cp_warehouse_locations'] = { + 'input_location': location.input_location.id, + 'output_location': location.output_location.id, + 'storage_location': location.storage_location.id} + child_context['cp_warehouse_id'] = new_id + + self.copy( + cursor, user, [c.id for c in location.childs], + default={'parent':new_id}, context=child_context) + self.write( + cursor, user, new_id, {'type': 'warehouse'}, context=context) + else: + new_id = super(Location, self).copy( + cursor, user, location.id, default=default, context=context) + warehouse_locations = context.get('cp_warehouse_locations', {}) + if location.id in warehouse_locations.values(): + for field, loc_id in warehouse_locations.iteritems(): + if loc_id == location.id: + self.write( + cursor, user, context['cp_warehouse_id'], + {field: new_id}, context=context) + + res.append(new_id) + + return int_id and res[0] or res Location() From abca888e3b6b640dce11f028e5aa07858a1756a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 11 May 2009 19:22:38 +0200 Subject: [PATCH 41/64] Added tag 1.0.4 for changeset 237ce9cb917d --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 5341848ec1..6290b184cd 100644 --- a/.hgtags +++ b/.hgtags @@ -2,3 +2,4 @@ c934dee8797de27a032afe262a64152873124f0e 1.0.1 00f417866b683fb9126c53af02e2f72b2d1330b3 1.0.2 7b355cbccd4bc63835bac801fe87bcdd18967f50 1.0.3 +237ce9cb917d9d15c07db9c95af61f7ed5215c71 1.0.4 From 80cfc0eaf1e192a11b22a306d81833fd4ca49baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 11 May 2009 19:23:07 +0200 Subject: [PATCH 42/64] Increase version number --- __tryton__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tryton__.py b/__tryton__.py index d5fb8df2eb..dce940dedd 100644 --- a/__tryton__.py +++ b/__tryton__.py @@ -5,7 +5,7 @@ 'name_de_DE': 'Lagerverwaltung', 'name_fr_FR': 'Gestion des stocks', 'name_es_ES': 'Inventarios', - 'version': '1.0.4', + 'version': '1.0.5', 'author': 'B2CK', 'email': 'info@b2ck.com', 'website': 'http://www.tryton.org/', From 582d61c85490d12522416d143c6d553275222f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 20 Jun 2009 14:26:01 +0200 Subject: [PATCH 43/64] Don't set date in set_state_done for issue1087 --- inventory.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/inventory.py b/inventory.py index 7b43b3df70..efd10194ee 100644 --- a/inventory.py +++ b/inventory.py @@ -90,11 +90,9 @@ class Inventory(OSV): for line in inventory.lines: line_obj.create_move(cursor, user, line, context=context) - self.write( - cursor, user, inventory_id, - {'state': 'done', - 'date': date_obj.today(cursor, user, context=context)}, - context=context) + self.write(cursor, user, inventory_id, { + 'state': 'done', + }, context=context) def copy(self, cursor, user, inventory_id, default=None, context=None): date_obj = self.pool.get('ir.date') From b2a633958424d1f323c7093116b0603b11b3a5e9 Mon Sep 17 00:00:00 2001 From: Korbinian Preisler Date: Sat, 20 Jun 2009 14:31:36 +0200 Subject: [PATCH 44/64] Fix effective_date of stock move from inventory for issue 1087 --- inventory.py | 1 + 1 file changed, 1 insertion(+) diff --git a/inventory.py b/inventory.py index efd10194ee..d2ea22c065 100644 --- a/inventory.py +++ b/inventory.py @@ -278,6 +278,7 @@ class InventoryLine(OSV): 'uom': line.uom.id, 'company': line.inventory.company.id, 'state': 'done', + 'effective_date': line.inventory.date, }, context=context) self.write(cursor, user, line.id, {'move': move_id}, context=context) From cf30dbfe3938fc5791adeb0f954a71e3c37997e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 6 Jul 2009 10:44:06 +0200 Subject: [PATCH 45/64] Prepare changelog for release 1.0.5 --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 9e3e2698e3..0431b34ee9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +Version 1.0.5 - 2009-07-06 +* Some bug fixes (see mercurial logs for details) + Version 1.0.4 - 2009-05-11 * Some bug fixes (see mercurial logs for details) From ec5c034e32d0466ae4283ab1cdffce2c556d118c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 6 Jul 2009 10:44:12 +0200 Subject: [PATCH 46/64] Added tag 1.0.5 for changeset 6e9e2e472d0e --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 6290b184cd..9026774aca 100644 --- a/.hgtags +++ b/.hgtags @@ -3,3 +3,4 @@ c934dee8797de27a032afe262a64152873124f0e 1.0.1 00f417866b683fb9126c53af02e2f72b2d1330b3 1.0.2 7b355cbccd4bc63835bac801fe87bcdd18967f50 1.0.3 237ce9cb917d9d15c07db9c95af61f7ed5215c71 1.0.4 +6e9e2e472d0eceb901e04f4cce5cb2168961cc47 1.0.5 From f4928f5832aa339e399c8257db36d9535cf3374c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 6 Jul 2009 10:44:40 +0200 Subject: [PATCH 47/64] Increase version number --- __tryton__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tryton__.py b/__tryton__.py index dce940dedd..09a0831f7b 100644 --- a/__tryton__.py +++ b/__tryton__.py @@ -5,7 +5,7 @@ 'name_de_DE': 'Lagerverwaltung', 'name_fr_FR': 'Gestion des stocks', 'name_es_ES': 'Inventarios', - 'version': '1.0.5', + 'version': '1.0.6', 'author': 'B2CK', 'email': 'info@b2ck.com', 'website': 'http://www.tryton.org/', From 498e266b8dbd81d921fc9b4ab182d43831cb12c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 21 Sep 2009 10:47:38 +0200 Subject: [PATCH 48/64] Don't use global context as default value of act_window for issue1183 (transplanted from 6f0af488dd359668d01dfa8990066d3301287413) --- location.py | 10 +++++----- product.py | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/location.py b/location.py index 057e7f2a75..e04543391b 100644 --- a/location.py +++ b/location.py @@ -331,13 +331,13 @@ class OpenProduct(Wizard): context=context) res = act_window_obj.read(cursor, user, model_data.db_id, context=context) - if context == None: context = {} - context['locations'] = data['ids'] + ctx = {} + ctx['locations'] = data['ids'] if data['form']['forecast_date']: - context['stock_date_end'] = data['form']['forecast_date'] + ctx['stock_date_end'] = data['form']['forecast_date'] else: - context['stock_date_end'] = datetime.date.max - res['context'] = str(context) + ctx['stock_date_end'] = datetime.date.max + res['context'] = str(ctx) return res diff --git a/product.py b/product.py index c7fb3b2412..d8961017e7 100644 --- a/product.py +++ b/product.py @@ -532,13 +532,13 @@ class OpenLocation(Wizard): context=context) res = act_window_obj.read(cursor, user, model_data.db_id, context=context) - if context == None: context = {} - context['product'] = data['id'] + ctx = {} + ctx['product'] = data['id'] if data['form']['forecast_date']: - context['stock_date_end'] = data['form']['forecast_date'] + ctx['stock_date_end'] = data['form']['forecast_date'] else: - context['stock_date_end'] = datetime.date.max - res['context'] = str(context) + ctx['stock_date_end'] = datetime.date.max + res['context'] = str(ctx) return res From 2472adefc3e984ce0765aea038d058c270edcf55 Mon Sep 17 00:00:00 2001 From: Ian Wilson Date: Thu, 24 Sep 2009 23:58:33 -0700 Subject: [PATCH 49/64] Return dictionary when given no locations for issue1190. (transplanted from ce2a2525700133cba8b85f5c483147f3a8ccc21e) --- product.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product.py b/product.py index d8961017e7..86edf7043e 100644 --- a/product.py +++ b/product.py @@ -135,7 +135,7 @@ class Product(OSV): date_obj = self.pool.get('ir.date') if not location_ids: - return [] + return {} if context is None: context= {} # Skip warehouse location in favor of their storage location From dda6b3fe3028c2ad133dc3aedf7dff355e5c1f43 Mon Sep 17 00:00:00 2001 From: Bertrand Chenal Date: Tue, 29 Sep 2009 12:14:07 +0200 Subject: [PATCH 50/64] Use local context instead of editing global one (transplanted from efd54bea6af8b7f6cce82bcdeced7a64c2fb36eb) --- inventory.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/inventory.py b/inventory.py index d2ea22c065..38d44947c3 100644 --- a/inventory.py +++ b/inventory.py @@ -125,10 +125,11 @@ class Inventory(OSV): for inventory in inventories: # Compute product quantities if inventory.date: - context['stock_date_end'] = inventory.date + ctx = context and context.copy() or {} + ctx['stock_date_end'] = inventory.date pbl = product_obj.products_by_location( cursor, user, [inventory.location.id], - context=context) + context=ctx) else: pbl = product_obj.products_by_location( cursor, user, [inventory.location.id], context=context) From 968ca6393a462d223a317fc78ed6084271271d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 27 Oct 2009 10:17:57 +0100 Subject: [PATCH 51/64] Test stock_date_end in context before comparing with today (transplanted from 25baf0c9daa6d35033b21ff41311384b43179833) --- product.py | 1 + 1 file changed, 1 insertion(+) diff --git a/product.py b/product.py index 86edf7043e..63b986ba36 100644 --- a/product.py +++ b/product.py @@ -40,6 +40,7 @@ class Product(OSV): return dict([(id, 0.0) for id in ids]) if name == 'quantity' and \ + context.get('stock_date_end') and \ context.get('stock_date_end') > \ date_obj.today(cursor, user, context=context): From c1674aa78942e87f2e2de7681a83333b8d318a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 27 Oct 2009 10:19:07 +0100 Subject: [PATCH 52/64] Fix search_quantity to compute product_by_location like get_quantity (transplanted from 21e928e05ca37a6ce97164d0933463fa26922e40) --- product.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/product.py b/product.py index 63b986ba36..050fc0ccbd 100644 --- a/product.py +++ b/product.py @@ -81,15 +81,21 @@ class Product(OSV): if not (context and context.get('locations') and domain): return [] - if (name != 'forecast_quantity') and context.get('stock_date_end'): - if context['stock_date_end'] != date_obj.today(cursor, user, - context=context): - context = context.copy() - del context['stock_date_end'] - if name == 'forecast_quantity' and not context.get('stock_date_end'): + if name == 'quantity' and \ + context.get('stock_date_end') and \ + context.get('stock_date_end') > \ + date_obj.today(cursor, user, context=context): + context = context.copy() - context['stock_date_end'] = datetime.date.max + context['stock_date_end'] = date_obj.today( + cursor, user, context=context) + + if name == 'forecast_quantity': + context = context.copy() + context['forecast'] = True + if not context.get('stock_date_end'): + context['stock_date_end'] = datetime.date.max pbl = self.products_by_location( cursor, user, location_ids=context['locations'], with_childs=True, From eb652b39b843a2e18c7bffebfcb5e464938c6f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 28 Oct 2009 09:15:20 +0100 Subject: [PATCH 53/64] Set planned date on inventory moves of shipments for issue1259 (transplanted from de0012795f472c56e5f5484f8c4deec1e1b6c093) --- packing.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packing.py b/packing.py index 34ff32cd86..43c190ca58 100644 --- a/packing.py +++ b/packing.py @@ -267,6 +267,9 @@ class PackingIn(OSV): res['to_location'] = incoming_move.packing_in.warehouse.\ storage_location.id res['state'] = 'draft' + # Product will be considered in stock only when the inventory + # move will be made: + res['planned_date'] = False res['company'] = incoming_move.company.id return res @@ -550,6 +553,7 @@ class PackingOut(OSV): 'quantity': out_quantity, 'packing_out': packing.id, 'state': 'draft', + 'planned_date': shipment.planned_date, 'company': move.company.id, 'currency': move.company.currency.id, 'unit_price': unit_price, @@ -631,6 +635,7 @@ class PackingOut(OSV): 'uom': move.uom.id, 'quantity': inv_quantity, 'packing_out': packing.id, + 'planned_date': move.planned_date, 'state': 'draft', 'company': move.company.id, }, context=context) From 9fbe8b54b65689fca6c46fb96bfd73fbc96f125f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 28 Oct 2009 09:17:16 +0100 Subject: [PATCH 54/64] Use stock_assign to compute product by location with future date (transplanted from c934d6713653bd9a46ba1c1d566a172b9f055ccc) --- product.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/product.py b/product.py index 050fc0ccbd..199df27e08 100644 --- a/product.py +++ b/product.py @@ -208,7 +208,8 @@ class Product(OSV): '))' today = date_obj.today(cursor, user, context=context) state_date_vals = [ - 'done', 'assigned', today, today, + 'done', context.get('stock_assign') and 'assigned' or 'done', + today, today, 'done', 'assigned', 'draft', context['stock_date_end'], today, context['stock_date_end'], today, From 547d9b2bfc5ec6a12cd8ed78fcb3ecbcd2ccfb52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 28 Oct 2009 09:18:00 +0100 Subject: [PATCH 55/64] Compute infinite date end like a future date for issue1259 (transplanted from 2e24870d23762982a4ee045671c371bdd37f0d1a) --- product.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/product.py b/product.py index 199df27e08..d5a95117de 100644 --- a/product.py +++ b/product.py @@ -184,10 +184,6 @@ class Product(OSV): context['stock_date_end'], context['stock_date_end'], ] - # infinite date end: take all states for the moves - elif context['stock_date_end'] == datetime.date.max: - state_date_clause = 'state in (%s, %s, %s)' - state_date_vals = ['done', 'assigned', 'draft'] # future date end: filter move on state done and date # before today, or on all state and date between today and # date_end. From 4a15a8a3e4c70287b039b704fd6c97268ba38082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 24 Nov 2009 18:18:03 +0100 Subject: [PATCH 56/64] Prepare release 1.0.6 --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 0431b34ee9..bedc61ddfa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +Version 1.0.6 - 2009-11-24 +* Some bug fixes (see mercurial logs for details) + Version 1.0.5 - 2009-07-06 * Some bug fixes (see mercurial logs for details) From 8f5d11b8a4aff35e32c0cd4f74ee40ab02cc0bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 24 Nov 2009 18:18:07 +0100 Subject: [PATCH 57/64] Added tag 1.0.6 for changeset 7cf30dc88bbd --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 9026774aca..9a5188538a 100644 --- a/.hgtags +++ b/.hgtags @@ -4,3 +4,4 @@ c934dee8797de27a032afe262a64152873124f0e 1.0.1 7b355cbccd4bc63835bac801fe87bcdd18967f50 1.0.3 237ce9cb917d9d15c07db9c95af61f7ed5215c71 1.0.4 6e9e2e472d0eceb901e04f4cce5cb2168961cc47 1.0.5 +7cf30dc88bbdd1716448f5627d3790b1a09cb32a 1.0.6 From e67efa11362ae09b230c8f865f7a43de2a2637e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 24 Nov 2009 18:19:18 +0100 Subject: [PATCH 58/64] Increase version number --- __tryton__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tryton__.py b/__tryton__.py index 09a0831f7b..1f83571313 100644 --- a/__tryton__.py +++ b/__tryton__.py @@ -5,7 +5,7 @@ 'name_de_DE': 'Lagerverwaltung', 'name_fr_FR': 'Gestion des stocks', 'name_es_ES': 'Inventarios', - 'version': '1.0.6', + 'version': '1.0.7', 'author': 'B2CK', 'email': 'info@b2ck.com', 'website': 'http://www.tryton.org/', From bba53cba1cb6466e7a5d249c2ae47314349a3ef4 Mon Sep 17 00:00:00 2001 From: Bertrand Chenal Date: Mon, 7 Dec 2009 10:18:06 +0100 Subject: [PATCH 59/64] Removed duplicate set_state_cancel on inventory (issue1323) (transplanted from 10dfa28e1cbe76b7a5f0bf11920ecc2243fecd49) --- inventory.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/inventory.py b/inventory.py index 38d44947c3..78efde716f 100644 --- a/inventory.py +++ b/inventory.py @@ -65,11 +65,6 @@ class Inventory(OSV): context=context)[0] return False - def set_state_cancel(self, cursor, user, ids, context=None): - self.write(cursor, user, ids, { - 'state': 'cancel', - }, context=context) - def set_state_draft(self, cursor, user, inventory_id, context=None): self.write(cursor, user, inventory_id, { 'state': 'draft', From 25dac7424e2f8f3d5d1ff1a0cc45da1de314ce76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 19 Jan 2010 14:12:13 +0100 Subject: [PATCH 60/64] Fix test on to_location_warehouse for XML-RPC for issue1380 Tuple in XML-RPC are list (transplanted from 5522087017922d66c30097f6000a484559395abe) --- move.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/move.py b/move.py index 5c8a9c078c..0e51b5daeb 100644 --- a/move.py +++ b/move.py @@ -1,7 +1,7 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of #this repository contains the full copyright notices and license terms. "Move" -from trytond.osv import fields, OSV +from trytond.osv import fields, OSV, OPERATORS from decimal import Decimal import datetime @@ -305,10 +305,11 @@ class Move(OSV): def process_args(args): i = 0 while i < len(args): - if isinstance(args[i], list): - process_args(args[i]) - if isinstance(args[i], tuple) \ - and args[i][0] == 'to_location_warehouse': + #add test for xmlrpc that doesn't handle tuple + if (isinstance(args[i], tuple) or \ + (isinstance(args[i], list) and len(args[i]) > 2 and \ + args[i][1] in OPERATORS)) and \ + args[i][0] == 'to_location_warehouse': location_id = False if args[i][2]: location = location_obj.browse(cursor, user, @@ -316,6 +317,8 @@ class Move(OSV): if location.type == 'warehouse': location_id = location.input_location.id args[i] = ('to_location', args[i][1], location_id) + elif isinstance(args[i], list): + process_args(args[i]) i += 1 process_args(args) return super(Move, self).search(cursor, user, args, offset=offset, From 7f86b4cd71eba9b9fdcca5e520e519c6ce6c9a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 25 Jan 2010 09:54:21 +0100 Subject: [PATCH 61/64] Update COPYRIGHT --- COPYRIGHT | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index da277a9b35..94a43fbe61 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,7 +1,7 @@ Copyright (C) 2004-2008 Tiny SPRL. -Copyright (C) 2008-2009 Cédric Krier. -Copyright (C) 2008-2009 Bertrand Chenal. -Copyright (C) 2008-2009 B2CK SPRL. +Copyright (C) 2008-2010 Cédric Krier. +Copyright (C) 2008-2010 Bertrand Chenal. +Copyright (C) 2008-2010 B2CK SPRL. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 162fef5b73390ad9b601a22bd04989b501acf88b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sun, 21 Feb 2010 15:57:49 +0100 Subject: [PATCH 62/64] Prepare release 1.0.7 --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index bedc61ddfa..448a1c0f13 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +Version 1.0.7 - 2010-02-21 +* Some bug fixes (see mercurial logs for details) + Version 1.0.6 - 2009-11-24 * Some bug fixes (see mercurial logs for details) From aab239c2e08cbbb29567bcac4ef0e798530e277d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sun, 21 Feb 2010 15:57:54 +0100 Subject: [PATCH 63/64] Added tag 1.0.7 for changeset bb72e254de7b --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 9a5188538a..88d3a07551 100644 --- a/.hgtags +++ b/.hgtags @@ -5,3 +5,4 @@ c934dee8797de27a032afe262a64152873124f0e 1.0.1 237ce9cb917d9d15c07db9c95af61f7ed5215c71 1.0.4 6e9e2e472d0eceb901e04f4cce5cb2168961cc47 1.0.5 7cf30dc88bbdd1716448f5627d3790b1a09cb32a 1.0.6 +bb72e254de7b73b1f73872ff86a7315c7a5bcfa3 1.0.7 From d028cd8abbc2e6fde7cf1ece04e6882f5f56ea0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sun, 21 Feb 2010 15:59:07 +0100 Subject: [PATCH 64/64] Increase version number --- __tryton__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tryton__.py b/__tryton__.py index 1f83571313..a403dc0ec1 100644 --- a/__tryton__.py +++ b/__tryton__.py @@ -5,7 +5,7 @@ 'name_de_DE': 'Lagerverwaltung', 'name_fr_FR': 'Gestion des stocks', 'name_es_ES': 'Inventarios', - 'version': '1.0.7', + 'version': '1.0.8', 'author': 'B2CK', 'email': 'info@b2ck.com', 'website': 'http://www.tryton.org/',