Merge lp:~sebastien.beau/e-commerce-addons/oerp6.1-stable-improve-stock-export into lp:~extra-addons-commiter/e-commerce-addons/oerp6.1-stable

Proposed by Sébastien BEAU - http://www.akretion.com
Status: Work in progress
Proposed branch: lp:~sebastien.beau/e-commerce-addons/oerp6.1-stable-improve-stock-export
Merge into: lp:~extra-addons-commiter/e-commerce-addons/oerp6.1-stable
Diff against target: 136 lines (+71/-34)
2 files modified
base_sale_multichannels/sale.py (+63/-34)
base_sale_multichannels/stock.py (+8/-0)
To merge this branch: bzr merge lp:~sebastien.beau/e-commerce-addons/oerp6.1-stable-improve-stock-export
Reviewer Review Type Date Requested Status
Maxime Chambreuil (http://www.savoirfairelinux.com) code review Needs Fixing
Guewen Baconnier @ Camptocamp Approve
Review via email: mp+168290@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Sébastien BEAU - http://www.akretion.com (sebastien.beau) wrote :

Improve the stock export.
Export in chronologic order in order to update the last export date after each export. This is a life saver when you need to export a lot of product in one time. Indeed before if the export failed, you had to start again from the beginning.

Thanks

Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) :
review: Approve
Revision history for this message
Maxime Chambreuil (http://www.savoirfairelinux.com) (max3903) wrote :

Thanks Sébastien.

Please update the translation file as you add a new field l135.

review: Needs Fixing (code review)

Unmerged revisions

286. By Sébastien BEAU - http://www.akretion.com

[REF] refactor the stock export, export the product with chronologic order and commit the last export date after each export

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'base_sale_multichannels/sale.py'
2--- base_sale_multichannels/sale.py 2013-06-08 20:04:37 +0000
3+++ base_sale_multichannels/sale.py 2013-06-09 15:19:31 +0000
4@@ -36,6 +36,7 @@
5 from base_external_referentials.external_osv import ExternalSession
6 from base_external_referentials.decorator import open_report
7 from base_external_referentials.decorator import catch_error_in_report
8+from framework_helpers.context_managers import new_cursor, commit_now
9
10 #TODO use external_session.logger when it's posible
11 import logging
12@@ -279,46 +280,74 @@
13 self._export_inventory(cr, uid, external_session, ids, context=context)
14 return True
15
16- def _get_product_ids_for_stock_to_export(self, cr, uid, shop, context=None):
17- return [product.id for product in shop.exportable_product_ids]
18+ def _get_product_stock_ids_and_update_date(self, cr, uid, external_session,
19+ product_ids, last_exported_date=None, context=None):
20+ """This function will return the list of ids and the update date of each
21+ product that should be updated in the external system
22+
23+ :param ExternalSession external_session : External_session that contain
24+ all params of connection
25+ :param str last_exported_date : last exported date
26+ :rtype: tuple
27+ :return: an tuple of ids and ids_2_dates
28+ (dict with key => 'id' and val => 'last_update_date')
29+ """
30+ move_obj = self.pool.get('stock.move')
31+
32+ domain = [
33+ ('product_id', 'in', product_ids),
34+ ('product_id.type', '!=', 'service'),
35+ ('state', '!=', 'draft'),
36+ ]
37+
38+ if last_exported_date:
39+ domain += [('write_date', '>=', last_exported_date)]
40+
41+ move_ids = move_obj.search(cr, uid, domain, context=context)
42+
43+ product_ids_to_date = {}
44+ product_ids = []
45+ for move in move_obj.browse(cr, uid, move_ids, context=context):
46+ if product_ids_to_date.get(move.product_id.id) <= move.write_date:
47+ product_ids_to_date[move.product_id.id] = move.write_date
48+
49+ #Now we build an ordered list (by date) of product to update
50+ product_ids = product_ids_to_date.keys()
51+ date_to_product = []
52+ for product_id in product_ids_to_date:
53+ date_to_product.append((product_ids_to_date[product_id], product_id))
54+ date_to_product.sort()
55+ product_ids = [product_id for date, product_id in date_to_product]
56+ return product_ids, product_ids_to_date
57+
58
59 def _export_inventory(self, cr, uid, external_session, ids, context=None):
60+ shop_obj = self.pool.get('sale.shop')
61 shop = external_session.sync_from_object
62- stock_move_obj = self.pool.get('stock.move')
63 for shop in self.browse(cr, uid, ids):
64+ start_time = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
65 external_session = ExternalSession(shop.referential_id, shop)
66-
67- product_ids = self._get_product_ids_for_stock_to_export(cr, uid, shop, context=context)
68-
69- if shop.last_inventory_export_date:
70- # we do not exclude canceled moves because it means
71- # some stock levels could have increased since last export
72- recent_move_ids = stock_move_obj.search(
73- cr, uid,
74- [('write_date', '>', shop.last_inventory_export_date),
75- ('product_id', 'in', product_ids),
76- ('product_id.type', '!=', 'service'),
77- ('state', '!=', 'draft')],
78- context=context)
79- else:
80- recent_move_ids = stock_move_obj.search(
81- cr, uid,
82- [('product_id', 'in', product_ids)],
83- context=context)
84-
85- recent_moves = stock_move_obj.browse(
86- cr, uid, recent_move_ids, context=context)
87-
88- product_ids = [move.product_id.id
89- for move
90- in recent_moves
91- if move.product_id.state != 'obsolete']
92- product_ids = list(set(product_ids))
93+ product_ids = [product.id for product in shop.exportable_product_ids]
94+ product_ids, product_ids_to_date = \
95+ self._get_product_stock_ids_and_update_date(cr, uid, external_session,
96+ product_ids = product_ids,
97+ last_exported_date = shop.last_inventory_export_date,
98+ context=context)
99 external_session.logger.info('Export Stock for %s products' %len(product_ids))
100- self.pool.get('product.product').export_inventory(
101- cr, uid, external_session, product_ids, context=context)
102- shop.write({'last_inventory_export_date':
103- time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)})
104+ for product_id in product_ids:
105+ self.pool.get('product.product').export_inventory(
106+ cr, uid, external_session, [product_id], context=context)
107+ with new_cursor(cr, external_session.logger) as new_cr:
108+ with commit_now(new_cr, external_session.logger) as new_cr:
109+ shop_obj.write(new_cr, uid, shop.id, {
110+ 'last_inventory_export_date': product_ids_to_date[product_id],
111+ })
112+ #Update date when finish the process
113+ with new_cursor(cr, external_session.logger) as new_cr:
114+ with commit_now(new_cr, external_session.logger) as new_cr:
115+ shop_obj.write(new_cr, uid, shop.id, {
116+ 'last_inventory_export_date': start_time,
117+ })
118 return True
119
120 def import_catalog(self, cr, uid, ids, context):
121
122=== modified file 'base_sale_multichannels/stock.py'
123--- base_sale_multichannels/stock.py 2012-08-21 13:57:44 +0000
124+++ base_sale_multichannels/stock.py 2013-06-09 15:19:31 +0000
125@@ -44,3 +44,11 @@
126 inv_type, journal_id, context=context)
127 vals['shop_id'] = picking.shop_id.id
128 return vals
129+
130+
131+class stock_move(Model):
132+ _inherit="stock.move"
133+
134+ _columns = {
135+ 'write_date': fields.datetime('Write Date'),
136+ }