Merge lp:~akretion-team/openerp-connector-magento/openerp-connector-magento-bundle-split into lp:~openerp-connector-core-editors/openerp-connector-magento/7.0

Proposed by Chafique DELLI
Status: Work in progress
Proposed branch: lp:~akretion-team/openerp-connector-magento/openerp-connector-magento-bundle-split
Merge into: lp:~openerp-connector-core-editors/openerp-connector-magento/7.0
Prerequisite: lp:~akretion-team/openerp-connector-magento/add-comment-order-module-dbl
Diff against target: 1100 lines (+531/-84)
27 files modified
magentoerpconnect/AUTHORS (+1/-0)
magentoerpconnect/CHANGES.rst (+11/-0)
magentoerpconnect/__init__.py (+1/-0)
magentoerpconnect/__openerp__.py (+1/-0)
magentoerpconnect/doc/guides/tutorial_customize.rst (+3/-7)
magentoerpconnect/invoice.py (+6/-1)
magentoerpconnect/magento_model.py (+17/-4)
magentoerpconnect/partner.py (+2/-15)
magentoerpconnect/payment_invoice.py (+17/-0)
magentoerpconnect/payment_invoice.xml (+21/-0)
magentoerpconnect/product.py (+18/-9)
magentoerpconnect/product_view.xml (+1/-1)
magentoerpconnect/sale.py (+4/-6)
magentoerpconnect/tests/__init__.py (+0/-1)
magentoerpconnect/tests/test_data.py (+19/-19)
magentoerpconnect/tests/test_data_address_book.py (+11/-11)
magentoerpconnect/tests/test_export_invoice.py (+62/-4)
magentoerpconnect/unit/backend_adapter.py (+13/-2)
magentoerpconnect/unit/export_synchronizer.py (+3/-1)
magentoerpconnect/unit/import_synchronizer.py (+35/-1)
magentoerpconnect/unit/mapper.py (+31/-0)
magentoerpconnect_bundle_split/__init__.py (+5/-0)
magentoerpconnect_bundle_split/__openerp__.py (+49/-0)
magentoerpconnect_bundle_split/connector.py (+25/-0)
magentoerpconnect_bundle_split/product.py (+64/-0)
magentoerpconnect_bundle_split/sale.py (+105/-0)
magentoerpconnect_order_comment/sale.py (+6/-2)
To merge this branch: bzr merge lp:~akretion-team/openerp-connector-magento/openerp-connector-magento-bundle-split
Reviewer Review Type Date Requested Status
OpenERP Connector Core Editors Pending
Review via email: mp+214048@code.launchpad.net

Description of the change

Add module for importing sale order with bundle

To post a comment you must log in.
985. By Chafique DELLI

[REF]:refactoring import sale order with product bundle

986. By Chafique DELLI

[IMP] cleaning code

987. By Chafique DELLI

[MERGE] merge with next release branch

Unmerged revisions

987. By Chafique DELLI

[MERGE] merge with next release branch

986. By Chafique DELLI

[IMP] cleaning code

985. By Chafique DELLI

[REF]:refactoring import sale order with product bundle

984. By Chafique DELLI

[IMP]: modify export mapping for status and add default value for display_price_bundle_parent

983. By Chafique DELLI

[ADD]: add module for manage product bundle

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

[PEP] pep-8 clean up

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

[REF] refactor code, the subject should be build in the mapping

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

[REF] refactor code, use @on_record_create and read directly the option on the store as I can access to the storeview from the sale order

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

[IMP] add the storeview_id on the sale order. This simplify the access on the object magento storeview and store

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

[REF] refactor code in order to not replace the sale.SaleOrderImport connector_unit. Thanks to Guewen for the idea

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'magentoerpconnect/AUTHORS'
2--- magentoerpconnect/AUTHORS 2014-01-14 14:18:48 +0000
3+++ magentoerpconnect/AUTHORS 2014-04-22 13:40:24 +0000
4@@ -13,3 +13,4 @@
5 * Alexis de Lattre at Akretion (tiny change)
6 * Olivier Distexhe at Akilon (tiny change)
7 * Romain Deheele at Camptocamp
8+* Jan-Philipp Fischer at Greencoding
9
10=== modified file 'magentoerpconnect/CHANGES.rst'
11--- magentoerpconnect/CHANGES.rst 2014-01-23 08:14:03 +0000
12+++ magentoerpconnect/CHANGES.rst 2014-04-22 13:40:24 +0000
13@@ -1,6 +1,17 @@
14 Changelog
15 ---------
16
17+2.3.1.dev0 (unreleased)
18+~~~~~~~~~~~~~~~~~~~~~~~
19+
20+* New helper in importer to import dependencies
21+* allow to customize the available versions without overriding the 'version' field
22+* Products deactivated on Magento are imported as not sellable / purchasable
23+* New option 'Create Invoice On' on payment methods with options 'on paid', 'on validate'
24+* Using Magento on PHP 5.4 without using the compatibility patch would
25+ break syncs'. Correct solution is to install the patch on Magento
26+ though! http://magento.com/blog/magento-news/magento-now-supports-php-54
27+
28
29 2.3.1 (2014-01-23)
30 ~~~~~~~~~~~~~~~~~~
31
32=== modified file 'magentoerpconnect/__init__.py'
33--- magentoerpconnect/__init__.py 2013-05-02 12:30:40 +0000
34+++ magentoerpconnect/__init__.py 2014-04-22 13:40:24 +0000
35@@ -13,5 +13,6 @@
36 import delivery
37 import stock_picking
38 import stock_tracking
39+import payment_invoice
40
41 import consumer
42
43=== modified file 'magentoerpconnect/__openerp__.py'
44--- magentoerpconnect/__openerp__.py 2014-01-23 08:14:03 +0000
45+++ magentoerpconnect/__openerp__.py 2014-04-22 13:40:24 +0000
46@@ -132,6 +132,7 @@
47 'delivery_view.xml',
48 'stock_view.xml',
49 'security/ir.model.access.csv',
50+ 'payment_invoice.xml',
51 ],
52 'installable': True,
53 'application': True,
54
55=== modified file 'magentoerpconnect/doc/guides/tutorial_customize.rst'
56--- magentoerpconnect/doc/guides/tutorial_customize.rst 2014-01-14 13:47:28 +0000
57+++ magentoerpconnect/doc/guides/tutorial_customize.rst 2014-04-22 13:40:24 +0000
58@@ -130,19 +130,15 @@
59 class magento_backend(orm.Model):
60 _inherit = 'magento.backend'
61
62- def _select_versions(self, cr, uid, context=None):
63- """ Available versions
64+ def select_versions(self, cr, uid, context=None):
65+ """ Available versions in the backend.
66
67 Can be inherited to add custom versions.
68 """
69- versions = super(magento_backend, self)._select_versions(cr, uid, context=context)
70+ versions = super(magento_backend, self).select_versions(cr, uid, context=context)
71 versions.append(('1.7-myversion', '1.7 - My Version'))
72 return versions
73
74- _columns = {
75- 'version': fields.selection(_select_versions, string='Version', required=True),
76- }
77-
78 Things to note:
79
80 * The ``parent`` argument of my version is the 1.7 version. You have to
81
82=== modified file 'magentoerpconnect/invoice.py'
83--- magentoerpconnect/invoice.py 2013-10-09 19:41:58 +0000
84+++ magentoerpconnect/invoice.py 2014-04-22 13:40:24 +0000
85@@ -222,7 +222,12 @@
86 if store.backend_id.id == magento_sale.backend_id.id),
87 None)
88 assert magento_store
89- create_invoice = magento_store.create_invoice_on
90+
91+ payment_method = sale.payment_method_id
92+ if payment_method and payment_method.create_invoice_on:
93+ create_invoice = payment_method.create_invoice_on
94+ else:
95+ create_invoice = magento_store.create_invoice_on
96
97 if create_invoice == invoice.state:
98 session.create('magento.account.invoice',
99
100=== modified file 'magentoerpconnect/magento_model.py'
101--- magentoerpconnect/magento_model.py 2013-08-15 08:01:46 +0000
102+++ magentoerpconnect/magento_model.py 2014-04-22 13:40:24 +0000
103@@ -52,12 +52,22 @@
104
105 _backend_type = 'magento'
106
107+ def select_versions(self, cr, uid, context=None):
108+ """ Available versions in the backend.
109+
110+ Can be inherited to add custom versions. Using this method
111+ to add a version from an ``_inherit`` does not constrain
112+ to redefine the ``version`` field in the ``_inherit`` model.
113+ """
114+ return [('1.7', '1.7')]
115+
116 def _select_versions(self, cr, uid, context=None):
117- """ Available versions
118+ """ Available versions in the backend.
119
120- Can be inherited to add custom versions.
121+ If you want to add a version, do not override this
122+ method, but ``select_version``.
123 """
124- return [('1.7', '1.7')]
125+ return self.select_versions(cr, uid, context=context)
126
127 def _get_stock_field_id(self, cr, uid, context=None):
128 stock_field = 'virtual_available'
129@@ -382,7 +392,10 @@
130 'Create invoice on action',
131 required=True,
132 help="Should the invoice be created in Magento "
133- "when it is validated or when it is paid in OpenERP?"),
134+ "when it is validated or when it is paid in OpenERP?\n"
135+ "This only takes effect if the sales order's related "
136+ "payment method is not giving an option for this by "
137+ "itself. (See Payment Methods)"),
138 }
139
140 _defaults = {
141
142=== modified file 'magentoerpconnect/partner.py'
143--- magentoerpconnect/partner.py 2014-01-14 11:00:20 +0000
144+++ magentoerpconnect/partner.py 2014-04-22 13:40:24 +0000
145@@ -266,13 +266,8 @@
146 def _import_dependencies(self):
147 """ Import the dependencies for the record"""
148 record = self.magento_record
149-
150- # import customer groups
151- binder = self.get_binder_for_model('magento.res.partner.category')
152- if binder.to_openerp(record['group_id']) is None:
153- importer = self.get_connector_unit_for_model(MagentoImportSynchronizer,
154- 'magento.res.partner.category')
155- importer.run(record['group_id'])
156+ self._import_dependency(record['group_id'],
157+ 'magento.res.partner.category')
158
159 @property
160 def mapper(self):
161@@ -349,10 +344,6 @@
162 return {'website_id': website_id}
163
164 @mapping
165- def backend_id(self, record):
166- return {'backend_id': self.backend_record.id}
167-
168- @mapping
169 def lang(self, record):
170 binder = self.get_binder_for_model('magento.storeview')
171 binding_id = binder.to_openerp(record['store_id'])
172@@ -641,10 +632,6 @@
173 return {'name': ' '.join(parts)}
174
175 @mapping
176- def backend_id(self, record):
177- return {'backend_id': self.backend_record.id}
178-
179- @mapping
180 def use_parent_address(self, record):
181 return {'use_parent_address': False}
182
183
184=== added file 'magentoerpconnect/payment_invoice.py'
185--- magentoerpconnect/payment_invoice.py 1970-01-01 00:00:00 +0000
186+++ magentoerpconnect/payment_invoice.py 2014-04-22 13:40:24 +0000
187@@ -0,0 +1,17 @@
188+# -*- coding: utf-8 -*-
189+from openerp.osv import orm, fields
190+
191+
192+class payment_invoice(orm.Model):
193+ _inherit = "payment.method"
194+
195+ _columns = {
196+ 'create_invoice_on': fields.selection(
197+ [('open', 'Validate'),
198+ ('paid', 'Paid')],
199+ 'Create invoice on action',
200+ help="Should the invoice be created in Magento "
201+ "when it is validated or when it is paid in OpenERP?\n"
202+ "If nothing is set, the option falls back to the same option "
203+ "on the Magento store related to the sales order."),
204+ }
205
206=== added file 'magentoerpconnect/payment_invoice.xml'
207--- magentoerpconnect/payment_invoice.xml 1970-01-01 00:00:00 +0000
208+++ magentoerpconnect/payment_invoice.xml 2014-04-22 13:40:24 +0000
209@@ -0,0 +1,21 @@
210+<?xml version ="1.0" encoding="utf-8"?>
211+
212+<openerp>
213+ <data>
214+
215+ <record id="payment_method_view_form" model="ir.ui.view">
216+ <field name="model">payment.method</field>
217+ <field name="inherit_id" ref="connector_ecommerce.payment_method_view_form"/>
218+ <field name="arch" type="xml">
219+
220+ <group name="import_rule" position="after">
221+ <group name="magento" string="Magento">
222+ <field name="create_invoice_on" string="Create invoice on"/>
223+ </group>
224+ </group>
225+
226+ </field>
227+ </record>
228+
229+ </data>
230+</openerp>
231
232=== modified file 'magentoerpconnect/product.py'
233--- magentoerpconnect/product.py 2014-01-14 10:41:05 +0000
234+++ magentoerpconnect/product.py 2014-04-22 13:40:24 +0000
235@@ -41,6 +41,7 @@
236 ImportMapper,
237 )
238 from .unit.backend_adapter import GenericAdapter
239+from .unit.mapper import normalize_datetime
240 from .unit.import_synchronizer import (DelayedBatchImport,
241 MagentoImportSynchronizer,
242 TranslationImporter,
243@@ -280,7 +281,7 @@
244 return sorted(images, key=priority)
245
246 def _get_binary_image(self, image_data):
247- url = image_data['url']
248+ url = image_data['url'].encode('utf8')
249 try:
250 binary = urllib2.urlopen(url)
251 except urllib2.HTTPError as err:
252@@ -318,13 +319,9 @@
253 """ Import the dependencies for the record"""
254 record = self.magento_record
255 # import related categories
256- binder = self.get_binder_for_model('magento.product.category')
257 for mag_category_id in record['categories']:
258- if binder.to_openerp(mag_category_id) is None:
259- importer = self.get_connector_unit_for_model(
260- MagentoImportSynchronizer,
261- model='magento.product.category')
262- importer.run(mag_category_id)
263+ self._import_dependency(mag_category_id,
264+ 'magento.product.category')
265
266 def _validate_product_type(self, data):
267 """ Check if the product type is in the selection (so we can
268@@ -395,11 +392,23 @@
269 ('short_description', 'description_sale'),
270 ('sku', 'default_code'),
271 ('type_id', 'product_type'),
272- ('created_at', 'created_at'),
273- ('updated_at', 'updated_at'),
274+ (normalize_datetime('created_at'), 'created_at'),
275+ (normalize_datetime('updated_at'), 'updated_at'),
276 ]
277
278 @mapping
279+ def is_active(self, record):
280+ """ If the product is not active in Magento, it sets
281+ sale_ok and purchase_ok to False.
282+
283+ '1' is a constant value in Magento, which means that the product
284+ is active
285+ """
286+ if record.get('status') != '1':
287+ return {'sale_ok': False,
288+ 'purchase_ok': False}
289+
290+ @mapping
291 def price(self, record):
292 """ The price is imported at the creation of
293 the product, then it is only modified and exported
294
295=== modified file 'magentoerpconnect/product_view.xml'
296--- magentoerpconnect/product_view.xml 2013-10-14 09:29:39 +0000
297+++ magentoerpconnect/product_view.xml 2014-04-22 13:40:24 +0000
298@@ -49,7 +49,7 @@
299 <record id="product_normal_form_view" model="ir.ui.view">
300 <field name="name">product.product.form</field>
301 <field name="model">product.product</field>
302- <field name="inherit_id" ref="connector_ecommerce.product_normal_form_view"/>
303+ <field name="inherit_id" ref="connector_base_product.product_normal_form_view"/>
304 <field name="arch" type="xml">
305 <page name="connector" position="attributes">
306 <attribute name="invisible">0</attribute>
307
308=== modified file 'magentoerpconnect/sale.py'
309--- magentoerpconnect/sale.py 2014-04-22 13:40:24 +0000
310+++ magentoerpconnect/sale.py 2014-04-22 13:40:24 +0000
311@@ -680,13 +680,11 @@
312
313 self._import_addresses()
314
315- prod_binder = self.get_binder_for_model('magento.product.product')
316- prod_importer = self.get_connector_unit_for_model(MagentoImportSynchronizer,
317- 'magento.product.product')
318 for line in record.get('items', []):
319- _logger.info('line: %s', line)
320- if 'product_id' in line and prod_binder.to_openerp(line['product_id']) is None:
321- prod_importer.run(line['product_id'])
322+ _logger.debug('line: %s', line)
323+ if 'product_id' in line:
324+ self._import_dependency(line['product_id'],
325+ 'magento.product.product')
326
327
328 @magento
329
330=== modified file 'magentoerpconnect/tests/__init__.py'
331--- magentoerpconnect/tests/__init__.py 2013-09-03 09:55:45 +0000
332+++ magentoerpconnect/tests/__init__.py 2014-04-22 13:40:24 +0000
333@@ -23,7 +23,6 @@
334 import test_address_book
335 import test_export_invoice
336 import test_import_product_image
337-
338 fast_suite = [
339 ]
340
341
342=== modified file 'magentoerpconnect/tests/test_data.py'
343--- magentoerpconnect/tests/test_data.py 2014-04-22 13:40:24 +0000
344+++ magentoerpconnect/tests/test_data.py 2014-04-22 13:40:24 +0000
345@@ -22134,7 +22134,7 @@
346 'sku': 'HTC Touch Diamond',
347 'type': 'simple',
348 'website_ids': ['1']}],
349- ('customer.info', (1, None)): {'confirmation': None,
350+ ('customer.info', (1,)): {'confirmation': None,
351 'created_at': '2007-08-30 23:23:13',
352 'created_in': None,
353 'customer_id': '1',
354@@ -22161,19 +22161,19 @@
355 ('customer_address.list', (frozenset([('customer_id', frozenset([('eq', '1')]))]),)): [],
356 ('ol_customer.search', (frozenset([('website_id', frozenset([('in', (u'0',))]))]),)): [],
357 ('ol_customer.search', (frozenset([('website_id', frozenset([('in', (u'1',))]))]),)): ['1'],
358- ('ol_customer_groups.info', (0, None)): {'customer_group_code': 'NOT LOGGED IN',
359+ ('ol_customer_groups.info', (0,)): {'customer_group_code': 'NOT LOGGED IN',
360 'customer_group_id': '0',
361 'tax_class_id': '3'},
362- ('ol_customer_groups.info', (1, None)): {'customer_group_code': 'General',
363+ ('ol_customer_groups.info', (1,)): {'customer_group_code': 'General',
364 'customer_group_id': '1',
365 'tax_class_id': '3'},
366- ('ol_customer_groups.info', (2, None)): {'customer_group_code': 'Wholesale',
367+ ('ol_customer_groups.info', (2,)): {'customer_group_code': 'Wholesale',
368 'customer_group_id': '2',
369 'tax_class_id': '3'},
370- ('ol_customer_groups.info', (3, None)): {'customer_group_code': 'Retailer',
371+ ('ol_customer_groups.info', (3,)): {'customer_group_code': 'Retailer',
372 'customer_group_id': '3',
373 'tax_class_id': '3'},
374- ('ol_customer_groups.info', (4, None)): {'customer_group_code': 'QAAAA',
375+ ('ol_customer_groups.info', (4,)): {'customer_group_code': 'QAAAA',
376 'customer_group_id': '4',
377 'tax_class_id': '3'},
378 ('ol_customer_groups.list', (frozenset([]),)): [{'customer_group_code': 'NOT LOGGED IN',
379@@ -22191,39 +22191,39 @@
380 {'customer_group_code': 'QAAAA',
381 'customer_group_id': '4',
382 'tax_class_id': '3'}],
383- ('ol_groups.info', (0, None)): {'default_store_id': '0',
384+ ('ol_groups.info', (0,)): {'default_store_id': '0',
385 'group_id': '0',
386 'name': 'Default',
387 'root_category_id': '0',
388 'website_id': '0'},
389- ('ol_groups.info', (1, None)): {'default_store_id': '1',
390+ ('ol_groups.info', (1,)): {'default_store_id': '1',
391 'group_id': '1',
392 'name': 'Main Store',
393 'root_category_id': '3',
394 'website_id': '1'},
395 ('ol_groups.search', (frozenset([]),)): ['0', '1'],
396- ('ol_storeviews.info', (0, None)): {'code': 'admin',
397+ ('ol_storeviews.info', (0,)): {'code': 'admin',
398 'group_id': '0',
399 'is_active': '1',
400 'name': 'Admin',
401 'sort_order': '0',
402 'store_id': '0',
403 'website_id': '0'},
404- ('ol_storeviews.info', (1, None)): {'code': 'default',
405+ ('ol_storeviews.info', (1,)): {'code': 'default',
406 'group_id': '1',
407 'is_active': '1',
408 'name': 'English',
409 'sort_order': '0',
410 'store_id': '1',
411 'website_id': '1'},
412- ('ol_storeviews.info', (2, None)): {'code': 'german',
413+ ('ol_storeviews.info', (2,)): {'code': 'german',
414 'group_id': '1',
415 'is_active': '1',
416 'name': 'German',
417 'sort_order': '0',
418 'store_id': '2',
419 'website_id': '1'},
420- ('ol_storeviews.info', (3, None)): {'code': 'french',
421+ ('ol_storeviews.info', (3,)): {'code': 'french',
422 'group_id': '1',
423 'is_active': '1',
424 'name': 'French',
425@@ -22231,13 +22231,13 @@
426 'store_id': '3',
427 'website_id': '1'},
428 ('ol_storeviews.search', (frozenset([]),)): ['0', '1', '2', '3'],
429- ('ol_websites.info', (0, None)): {'code': 'admin',
430+ ('ol_websites.info', (0,)): {'code': 'admin',
431 'default_group_id': '0',
432 'is_default': '0',
433 'name': 'Admin',
434 'sort_order': '0',
435 'website_id': '0'},
436- ('ol_websites.info', (1, None)): {'code': 'base',
437+ ('ol_websites.info', (1,)): {'code': 'base',
438 'default_group_id': '1',
439 'is_default': '1',
440 'name': 'Main Website',
441@@ -25473,7 +25473,7 @@
442 'can_ship_partially_item': None,
443 'coupon_code': None,
444 'coupon_rule_name': None,
445- 'created_at': '2013-10-14 13:20:56',
446+ 'created_at': time.strftime(FMT),
447 'customer_dob': None,
448 'customer_email': 'john@doe.fr',
449 'customer_firstname': 'John',
450@@ -25511,7 +25511,7 @@
451 'hold_before_state': None,
452 'hold_before_status': None,
453 'imported': '0',
454- 'increment_id': '100005281',
455+ 'increment_id': '900000695',
456 'is_virtual': '0',
457 'items': [{'additional_data': None,
458 'amount_refunded': '0.0000',
459@@ -25539,7 +25539,7 @@
460 'base_weee_tax_applied_row_amount': '0.0000',
461 'base_weee_tax_disposition': '0.0000',
462 'base_weee_tax_row_disposition': '0.0000',
463- 'created_at': '2013-10-14 13:20:56',
464+ 'created_at': time.strftime(FMT),
465 'description': None,
466 'discount_amount': '0.0000',
467 'discount_invoiced': '0.0000',
468@@ -25594,7 +25594,7 @@
469 'tax_invoiced': '6.5900',
470 'tax_percent': '8.0000',
471 'tax_refunded': None,
472- 'updated_at': '2013-10-14 13:22:00',
473+ 'updated_at': time.strftime(FMT),
474 'weee_tax_applied': 'a:0:{}',
475 'weee_tax_applied_amount': '0.0000',
476 'weee_tax_applied_row_amount': '0.0000',
477@@ -25767,7 +25767,7 @@
478 'total_paid': '97.5000',
479 'total_qty_ordered': '1.0000',
480 'total_refunded': None,
481- 'updated_at': '2013-10-14 13:22:00',
482+ 'updated_at': time.strftime(FMT),
483 'website_id': u'1',
484 'weight': '0.0000',
485 'x_forwarded_for': None},
486
487=== modified file 'magentoerpconnect/tests/test_data_address_book.py'
488--- magentoerpconnect/tests/test_data_address_book.py 2013-06-28 15:27:26 +0000
489+++ magentoerpconnect/tests/test_data_address_book.py 2014-04-22 13:40:24 +0000
490@@ -34,7 +34,7 @@
491
492 # customer without address
493 no_address = {
494- ('customer.info', (9999253, None)): {'confirmation': None,
495+ ('customer.info', (9999253,)): {'confirmation': None,
496 'created_at': '2013-06-28 12:35:33',
497 'created_in': 'English',
498 'customer_id': '9999253',
499@@ -64,7 +64,7 @@
500
501 # individual customer with 1 address
502 individual_1_address = \
503-{ ('customer.info', (9999254, None)): {'confirmation': None,
504+{ ('customer.info', (9999254,)): {'confirmation': None,
505 'created_at': '2013-06-28 12:43:49',
506 'created_in': 'English',
507 'customer_id': '9999254',
508@@ -88,7 +88,7 @@
509 'taxvat': None,
510 'updated_at': '2013-06-28 12:43:49',
511 'website_id': '1'},
512- ('customer_address.info', (9999253, None)): {'city': u'Boutin-la-Forêt',
513+ ('customer_address.info', (9999253,)): {'city': u'Boutin-la-Forêt',
514 'company': None,
515 'country_id': 'FR',
516 'created_at': '2013-06-28 12:43:49',
517@@ -134,7 +134,7 @@
518
519 # individual customer with 2 addresses
520 individual_2_addresses = \
521-{('customer.info', (9999255, None)): {'confirmation': None,
522+{('customer.info', (9999255,)): {'confirmation': None,
523 'created_at': '2013-06-28 12:56:40',
524 'created_in': 'English',
525 'customer_id': '9999255',
526@@ -158,7 +158,7 @@
527 'taxvat': None,
528 'updated_at': '2013-06-28 13:00:23',
529 'website_id': '1'},
530- ('customer_address.info', (9999254, None)): {'city': 'Perez',
531+ ('customer_address.info', (9999254,)): {'city': 'Perez',
532 'company': None,
533 'country_id': 'FR',
534 'created_at': '2013-06-28 12:56:43',
535@@ -183,7 +183,7 @@
536 'vat_request_date': None,
537 'vat_request_id': None,
538 'vat_request_success': None},
539- ('customer_address.info', (9999255, None)): {'city': 'Bugarach',
540+ ('customer_address.info', (9999255,)): {'city': 'Bugarach',
541 'company': None,
542 'country_id': 'FR',
543 'created_at': '2013-06-28 13:00:23',
544@@ -243,7 +243,7 @@
545
546 # company with 1 address
547 company_1_address = \
548-{('customer.info', (9999256, None)): {'confirmation': None,
549+{('customer.info', (9999256,)): {'confirmation': None,
550 'created_at': '2013-06-28 13:10:21',
551 'created_in': 'English',
552 'customer_id': '9999256',
553@@ -267,7 +267,7 @@
554 'taxvat': None,
555 'updated_at': '2013-06-28 13:10:22',
556 'website_id': '1'},
557- ('customer_address.info', (9999256, None)): {'city': 'Launaynec',
558+ ('customer_address.info', (9999256,)): {'city': 'Launaynec',
559 'company': 'Marechal',
560 'country_id': 'FR',
561 'created_at': '2013-06-28 13:10:22',
562@@ -313,7 +313,7 @@
563
564 # company with 2 addresses
565 company_2_addresses = \
566-{('customer.info', (9999257, None)): {'confirmation': None,
567+{('customer.info', (9999257,)): {'confirmation': None,
568 'created_at': '2013-06-28 13:23:01',
569 'created_in': 'English',
570 'customer_id': '9999257',
571@@ -337,7 +337,7 @@
572 'taxvat': None,
573 'updated_at': '2013-06-28 13:25:28',
574 'website_id': '1'},
575- ('customer_address.info', (9999257, None)): {'city': 'Raynauddan',
576+ ('customer_address.info', (9999257,)): {'city': 'Raynauddan',
577 'company': 'Bertin',
578 'country_id': 'FR',
579 'created_at': '2013-06-28 13:23:01',
580@@ -362,7 +362,7 @@
581 'vat_request_date': None,
582 'vat_request_id': None,
583 'vat_request_success': None},
584- ('customer_address.info', (9999258, None)): {'city': 'Cailla',
585+ ('customer_address.info', (9999258,)): {'city': 'Cailla',
586 'company': None,
587 'country_id': 'FR',
588 'created_at': '2013-06-28 13:25:28',
589
590=== modified file 'magentoerpconnect/tests/test_export_invoice.py'
591--- magentoerpconnect/tests/test_export_invoice.py 2013-08-09 21:14:23 +0000
592+++ magentoerpconnect/tests/test_export_invoice.py 2014-04-22 13:40:24 +0000
593@@ -64,12 +64,13 @@
594 'manual_validation')
595 __, journal_id = self.get_ref('account',
596 'check_journal')
597- self.registry('payment.method').create(
598+ self.payment_method_id = self.registry('payment.method').create(
599 cr, uid,
600 {'name': 'checkmo',
601- 'workflow_process_id': workflow_id,
602- 'import_rule': 'always',
603- 'journal_id': journal_id})
604+ 'create_invoice_on': False,
605+ 'workflow_process_id': workflow_id,
606+ 'import_rule': 'always',
607+ 'journal_id': journal_id})
608 __, self.journal_id = self.get_ref('account', 'bank_journal')
609 __, self.pay_account_id = self.get_ref('account', 'cash')
610 __, self.period_id = self.get_ref('account', 'period_10')
611@@ -149,6 +150,63 @@
612 mock.ANY, 'magento.account.invoice',
613 self.invoice.magento_bind_ids[0].id)
614
615+ def test_export_invoice_on_payment_method_validate(self):
616+ """ Exporting an invoice: when it is validated with payment method """
617+ cr, uid = self.cr, self.uid
618+ store_ids = [store.id for website in self.backend.website_ids
619+ for store in website.store_ids]
620+ # we setup the stores so they export the invoices as soon
621+ # as they are validated (open)
622+ self.registry('payment.method').write(
623+ cr, uid, self.payment_method_id, {'create_invoice_on': 'open'})
624+ # ensure we use the option of the payment method, not store
625+ self.registry('magento.store').write(
626+ cr, uid, store_ids, {'create_invoice_on': 'paid'})
627+ # this is the consumer called when a 'magento.account.invoice'
628+ # is created, it delay a job to export the invoice
629+ patched = 'openerp.addons.magentoerpconnect.invoice.export_invoice'
630+ with mock.patch(patched) as export_invoice: # prevent to create the job
631+ self._invoice_open()
632+
633+ assert len(self.invoice.magento_bind_ids) == 1
634+ export_invoice.delay.assert_called_with(mock.ANY,
635+ 'magento.account.invoice',
636+ self.invoice.magento_bind_ids[0].id)
637+
638+ # pay and verify it is NOT called
639+ with mock.patch(patched) as export_invoice: # prevent to create the job
640+ self._pay_and_reconcile()
641+ self.assertEqual(self.invoice.state, 'paid')
642+ assert not export_invoice.delay.called
643+
644+ def test_export_invoice_on_payment_method_paid(self):
645+ """ Exporting an invoice: when it is paid on payment method """
646+ cr, uid = self.cr, self.uid
647+ store_ids = [store.id for website in self.backend.website_ids
648+ for store in website.store_ids]
649+ # we setup the stores so they export the invoices as soon
650+ # as they are validated (open)
651+ self.registry('payment.method').write(
652+ cr, uid, self.payment_method_id, {'create_invoice_on': 'paid'})
653+ # ensure we use the option of the payment method, not store
654+ self.registry('magento.store').write(
655+ cr, uid, store_ids, {'create_invoice_on': 'open'})
656+ # this is the consumer called when a 'magento.account.invoice'
657+ # is created, it delay a job to export the invoice
658+ patched = 'openerp.addons.magentoerpconnect.invoice.export_invoice'
659+ with mock.patch(patched) as export_invoice: # prevent to create the job
660+ self._invoice_open()
661+ assert not export_invoice.delay.called
662+
663+ # pay and verify it is NOT called
664+ with mock.patch(patched) as export_invoice: # prevent to create the job
665+ self._pay_and_reconcile()
666+ self.assertEqual(self.invoice.state, 'paid')
667+ assert len(self.invoice.magento_bind_ids) == 1
668+ export_invoice.delay.assert_called_with(
669+ mock.ANY, 'magento.account.invoice',
670+ self.invoice.magento_bind_ids[0].id)
671+
672 def _invoice_open(self):
673 wf_service = netsvc.LocalService("workflow")
674 wf_service.trg_validate(self.uid, 'account.invoice',
675
676=== modified file 'magentoerpconnect/unit/backend_adapter.py'
677--- magentoerpconnect/unit/backend_adapter.py 2013-06-26 06:36:58 +0000
678+++ magentoerpconnect/unit/backend_adapter.py 2014-04-22 13:40:24 +0000
679@@ -128,7 +128,7 @@
680 self.magento.password) as api:
681 result = api.call(method, arguments)
682 # Uncomment to record requests/responses in ``recorder``
683- # record(method, arguments, result)
684+ #record(method, arguments, result)
685 _logger.debug("api.call(%s, %s) returned %s",
686 method, arguments, result)
687 return result
688@@ -168,8 +168,19 @@
689
690 :rtype: dict
691 """
692+ arguments = [int(id)]
693+ if attributes:
694+ # Avoid to pass Null values in attributes. Workaround for
695+ # https://bugs.launchpad.net/openerp-connector-magento/+bug/1210775
696+ # When Magento is installed on PHP 5.4 and the compatibility patch
697+ # (http://magento.com/blog/magento-news/magento-now-supports-php-54)
698+ # is not installed, calling info() with None in attributes
699+ # would return a wrong result (almost empty list of
700+ # attributes). The right correction is to install the
701+ # compatibility patch on Magento.
702+ arguments.append(attributes)
703 return self._call('%s.info' % self._magento_model,
704- [int(id), attributes])
705+ arguments)
706
707 def search_read(self, filters=None):
708 """ Search records according to some criterias
709
710=== modified file 'magentoerpconnect/unit/export_synchronizer.py'
711--- magentoerpconnect/unit/export_synchronizer.py 2013-11-12 08:43:40 +0000
712+++ magentoerpconnect/unit/export_synchronizer.py 2014-04-22 13:40:24 +0000
713@@ -83,7 +83,9 @@
714 return True
715 record = self.backend_adapter.read(self.magento_id,
716 attributes=['updated_at'])
717-
718+ if not record['updated_at']:
719+ # in rare case it can be empty, in doubt, import it
720+ return False
721 fmt = DEFAULT_SERVER_DATETIME_FORMAT
722 sync_date = datetime.strptime(sync, fmt)
723 magento_date = datetime.strptime(record['updated_at'], fmt)
724
725=== modified file 'magentoerpconnect/unit/import_synchronizer.py'
726--- magentoerpconnect/unit/import_synchronizer.py 2013-11-09 22:56:22 +0000
727+++ magentoerpconnect/unit/import_synchronizer.py 2014-04-22 13:40:24 +0000
728@@ -87,8 +87,42 @@
729 # miss changes done in Magento
730 return magento_date < sync_date
731
732+ def _import_dependency(self, magento_id, binding_model,
733+ importer_class=None, always=False):
734+ """ Import a dependency.
735+
736+ The importer class is a class or subclass of
737+ :class:`MagentoImportSynchronizer`. A specific class can be defined.
738+
739+ :param magento_id: id of the related binding to import
740+ :param binding_model: name of the binding model for the relation
741+ :type binding_model: str | unicode
742+ :param importer_cls: :class:`openerp.addons.connector.connector.ConnectorUnit`
743+ class or parent class to use for the export.
744+ By default: MagentoImportSynchronizer
745+ :type importer_cls: :class:`openerp.addons.connector.connector.MetaConnectorUnit`
746+ :param always: if True, the record is updated even if it already exists,
747+ note that it is still skipped if it has not been
748+ modified on Magento since the last update. When False,
749+ it will import it only when it does not yet exist.
750+ :type always: boolean
751+ """
752+ if not magento_id:
753+ return
754+ if importer_class is None:
755+ importer_class = MagentoImportSynchronizer
756+ binder = self.get_binder_for_model(binding_model)
757+ if always or binder.to_openerp(magento_id) is None:
758+ importer = self.get_connector_unit_for_model(
759+ importer_class, model=binding_model)
760+ importer.run(magento_id)
761+
762 def _import_dependencies(self):
763- """ Import the dependencies for the record"""
764+ """ Import the dependencies for the record
765+
766+ Import of dependencies can be done manually or by calling
767+ :meth:`_import_dependency` for each dependency.
768+ """
769 return
770
771 def _map_data(self):
772
773=== added file 'magentoerpconnect/unit/mapper.py'
774--- magentoerpconnect/unit/mapper.py 1970-01-01 00:00:00 +0000
775+++ magentoerpconnect/unit/mapper.py 2014-04-22 13:40:24 +0000
776@@ -0,0 +1,31 @@
777+# -*- coding: utf-8 -*-
778+##############################################################################
779+#
780+# Author: Guewen Baconnier
781+# Copyright 2013 Camptocamp SA
782+#
783+# This program is free software: you can redistribute it and/or modify
784+# it under the terms of the GNU Affero General Public License as
785+# published by the Free Software Foundation, either version 3 of the
786+# License, or (at your option) any later version.
787+#
788+# This program is distributed in the hope that it will be useful,
789+# but WITHOUT ANY WARRANTY; without even the implied warranty of
790+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
791+# GNU Affero General Public License for more details.
792+#
793+# You should have received a copy of the GNU Affero General Public License
794+# along with this program. If not, see <http://www.gnu.org/licenses/>.
795+#
796+##############################################################################
797+
798+
799+def normalize_datetime(field):
800+ """Change a invalid date which comes from Magento, if
801+ no real date is set to null for correct import to
802+ OpenERP"""
803+ def modifier(self, record, to_attr):
804+ if record[field] == '0000-00-00 00:00:00':
805+ return None
806+ return record[field]
807+ return modifier
808
809=== added directory 'magentoerpconnect_bundle_split'
810=== added file 'magentoerpconnect_bundle_split/__init__.py'
811--- magentoerpconnect_bundle_split/__init__.py 1970-01-01 00:00:00 +0000
812+++ magentoerpconnect_bundle_split/__init__.py 2014-04-22 13:40:24 +0000
813@@ -0,0 +1,5 @@
814+# -*- coding: utf-8 -*-
815+
816+import connector
817+import sale
818+import product
819
820=== added file 'magentoerpconnect_bundle_split/__openerp__.py'
821--- magentoerpconnect_bundle_split/__openerp__.py 1970-01-01 00:00:00 +0000
822+++ magentoerpconnect_bundle_split/__openerp__.py 2014-04-22 13:40:24 +0000
823@@ -0,0 +1,49 @@
824+# -*- coding: utf-8 -*-
825+##############################################################################
826+#
827+# Author: Chafique DELLI
828+# Copyright 2014 Akretion
829+#
830+# This program is free software: you can redistribute it and/or modify
831+# it under the terms of the GNU Affero General Public License as
832+# published by the Free Software Foundation, either version 3 of the
833+# License, or (at your option) any later version.
834+#
835+# This program is distributed in the hope that it will be useful,
836+# but WITHOUT ANY WARRANTY; without even the implied warranty of
837+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
838+# GNU Affero General Public License for more details.
839+#
840+# You should have received a copy of the GNU Affero General Public License
841+# along with this program. If not, see <http://www.gnu.org/licenses/>.
842+#
843+##############################################################################
844+
845+{'name': 'Magentoerpconnect Bundle Split',
846+ 'version': '1.0.0',
847+ 'category': 'Connector',
848+ 'depends': [
849+ 'magentoerpconnect',
850+ 'sale_stock_relation_line',
851+ 'sale_invoice_relation_line',
852+ ],
853+ 'author': 'MagentoERPconnect Core Editors',
854+ 'license': 'AGPL-3',
855+ 'description': """
856+Magento Connector - BUNDLE SPLIT
857+=======================================
858+Extension for **Magento Connector**, add management of bundle products
859+
860+Simple management of bundle items imported from Magento.
861+
862+Each item choosed in a bundle is imported as a sale order line, so you are able to have correct margin and products turnover.
863+
864+The bundle product is imported with a price of 0.0 or with the total price and is a service.
865+
866+For the shipment, the first item which was part of the bundle create the full shipment on Magento (limitation because Magento wait for the bundle product).
867+The side effect is that the order will be marked as fully shipped on Magento even if the packing is sent in 2 times in OpenERP.
868+ """,
869+ 'data': [],
870+ 'installable': True,
871+ 'application': False,
872+}
873
874=== added file 'magentoerpconnect_bundle_split/connector.py'
875--- magentoerpconnect_bundle_split/connector.py 1970-01-01 00:00:00 +0000
876+++ magentoerpconnect_bundle_split/connector.py 2014-04-22 13:40:24 +0000
877@@ -0,0 +1,25 @@
878+# -*- coding: utf-8 -*-
879+##############################################################################
880+#
881+# Author: Chafique DELLI
882+# Copyright 2014 Akretion SA
883+#
884+# This program is free software: you can redistribute it and/or modify
885+# it under the terms of the GNU Affero General Public License as
886+# published by the Free Software Foundation, either version 3 of the
887+# License, or (at your option) any later version.
888+#
889+# This program is distributed in the hope that it will be useful,
890+# but WITHOUT ANY WARRANTY; without even the implied warranty of
891+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
892+# GNU Affero General Public License for more details.
893+#
894+# You should have received a copy of the GNU Affero General Public License
895+# along with this program. If not, see <http://www.gnu.org/licenses/>.
896+#
897+##############################################################################
898+
899+from openerp.addons.connector.connector import install_in_connector
900+
901+
902+install_in_connector()
903
904=== added file 'magentoerpconnect_bundle_split/product.py'
905--- magentoerpconnect_bundle_split/product.py 1970-01-01 00:00:00 +0000
906+++ magentoerpconnect_bundle_split/product.py 2014-04-22 13:40:24 +0000
907@@ -0,0 +1,64 @@
908+# -*- coding: utf-8 -*-
909+##############################################################################
910+#
911+# Author: Guewen Baconnier, David Beal, Chafique Delli
912+# Copyright 2013 Camptocamp SA
913+# Copyright 2013-14 Akretion
914+#
915+# This program is free software: you can redistribute it and/or modify
916+# it under the terms of the GNU Affero General Public License as
917+# published by the Free Software Foundation, either version 3 of the
918+# License, or (at your option) any later version.
919+#
920+# This program is distributed in the hope that it will be useful,
921+# but WITHOUT ANY WARRANTY; without even the implied warranty of
922+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
923+# GNU Affero General Public License for more details.
924+#
925+# You should have received a copy of the GNU Affero General Public License
926+# along with this program. If not, see <http://www.gnu.org/licenses/>.
927+#
928+##############################################################################
929+
930+from openerp.osv import orm, fields
931+from openerp.addons.magentoerpconnect import product
932+from openerp.addons.magentoerpconnect.backend import magento
933+from openerp.addons.connector.unit.mapper import mapping
934+
935+
936+class magento_product_product(orm.Model):
937+ _inherit = 'magento.product.product'
938+
939+ _columns = {
940+ 'price_type': fields.selection([('dynamic', 'Dynamic'),('fixed', 'Fixed')],
941+ 'Price Type'),
942+ }
943+
944+ def product_type_get(self, cr, uid, context=None):
945+ option = ('bundle', 'Bundle Product')
946+ type_selection = super(magento_product_product, self).product_type_get(
947+ cr, uid, context=context)
948+ if option not in type_selection:
949+ type_selection.append(option)
950+ return type_selection
951+
952+
953+@magento(replacing=product.ProductImportMapper)
954+class BundleProductImportMapper(product.ProductImportMapper):
955+ _model_name = 'magento.product.product'
956+
957+ @mapping
958+ def type(self, record):
959+ if record['type_id'] == 'bundle':
960+ return {'type': 'service'}
961+ return super(BundleProductImportMapper,self).type(record)
962+
963+ @mapping
964+ def price_type(self, record):
965+ if 'price_type' in record:
966+ if record['price_type'] == '0':
967+ price_type = 'dynamic'
968+ else:
969+ price_type = 'fixed'
970+ return {'price_type': price_type}
971+ return {}
972
973=== added file 'magentoerpconnect_bundle_split/sale.py'
974--- magentoerpconnect_bundle_split/sale.py 1970-01-01 00:00:00 +0000
975+++ magentoerpconnect_bundle_split/sale.py 2014-04-22 13:40:24 +0000
976@@ -0,0 +1,105 @@
977+# -*- coding: utf-8 -*-
978+##############################################################################
979+#
980+# Author: Chafique Delli
981+# Copyright 2014 Akretion SA
982+#
983+# This program is free software: you can redistribute it and/or modify
984+# it under the terms of the GNU Affero General Public License as
985+# published by the Free Software Foundation, either version 3 of the
986+# License, or (at your option) any later version.
987+#
988+# This program is distributed in the hope that it will be useful,
989+# but WITHOUT ANY WARRANTY; without even the implied warranty of
990+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
991+# GNU Affero General Public License for more details.
992+#
993+# You should have received a copy of the GNU Affero General Public License
994+# along with this program. If not, see <http://www.gnu.org/licenses/>.
995+#
996+##############################################################################
997+
998+from openerp.addons.magentoerpconnect import sale
999+from openerp.addons.magentoerpconnect.backend import magento
1000+from openerp.osv import fields, orm
1001+from openerp.addons.connector.unit.mapper import mapping
1002+
1003+
1004+
1005+@magento(replacing=sale.SaleOrderLineImportMapper)
1006+class BundleSaleOrderLineImportMapper(sale.SaleOrderLineImportMapper):
1007+ _model_name = 'magento.sale.order.line'
1008+
1009+ direct = sale.SaleOrderLineImportMapper.direct + [
1010+ ('parent_item_id', 'magento_parent_item_id'),
1011+ ]
1012+
1013+ @mapping
1014+ def price(self, record):
1015+ sess = self.session
1016+ mag_product_model = sess.pool['magento.product.product']
1017+ mag_product_ids = mag_product_model.search(
1018+ sess.cr, sess.uid,
1019+ [('magento_id', '=', record['product_id'])])
1020+ mag_product = mag_product_model.browse(sess.cr,
1021+ sess.uid,
1022+ mag_product_ids[0])
1023+ result = {}
1024+ if record['product_type'] == 'bundle' and mag_product.price_type == 'dynamic':
1025+ result['price_unit'] = 0.0
1026+ else:
1027+ result = super(BundleSaleOrderLineImportMapper, self).price(record)
1028+ return result
1029+
1030+
1031+@magento(replacing=sale.SaleOrderImport)
1032+class BundleSaleOrderImport(sale.SaleOrderImport):
1033+ _model_name = ['magento.sale.order']
1034+
1035+
1036+ def _merge_sub_items(self, product_type, top_item, child_items):
1037+ """
1038+ In the module magentoerpconnect_bundle_split, instead of merging
1039+ the child items, we create a sale order line for each of them.
1040+ As the bundle item price is the same
1041+ as the sum of all the items, we set its price at 0.0
1042+
1043+ :param top_item: main item (bundle, configurable)
1044+ :param child_items: list of childs of the top item
1045+ :return: list of items
1046+ """
1047+ if product_type == 'bundle':
1048+ items = []
1049+ bundle_item = top_item.copy()
1050+ items = [child for child in child_items]
1051+ items.insert(0, bundle_item)
1052+ return items
1053+ return super(BundleSaleOrderImport, self)._merge_sub_items(
1054+ product_type, top_item, child_items)
1055+
1056+ def _create(self, data):
1057+ session = self.session
1058+ order_id = super(BundleSaleOrderImport, self)._create(data)
1059+ order_line_ids = session.search(
1060+ 'magento.sale.order.line',
1061+ [('magento_order_id', '=', order_id)])
1062+ bundle_ids = {}
1063+ mag_id_2_openerp_id = {}
1064+ for line in session.browse('magento.sale.order.line', order_line_ids):
1065+ if line.magento_parent_item_id:
1066+ bundle_ids.setdefault(line.magento_parent_item_id, []).append(line.id)
1067+ mag_id_2_openerp_id[line.magento_id] = line.openerp_id.id
1068+ for mag_parent_item_id, mag_child_line_ids in bundle_ids.iteritems():
1069+ parent_line_id = mag_id_2_openerp_id[str(mag_parent_item_id)]
1070+ session.write('magento.sale.order.line', mag_child_line_ids, {
1071+ 'line_parent_id': parent_line_id,
1072+ })
1073+ return order_id
1074+
1075+
1076+class magento_sale_order_line(orm.Model):
1077+ _inherit = 'magento.sale.order.line'
1078+
1079+ _columns = {
1080+ 'magento_parent_item_id': fields.integer('Magento Parent Item ID'),
1081+ }
1082
1083=== modified file 'magentoerpconnect_order_comment/sale.py'
1084--- magentoerpconnect_order_comment/sale.py 2014-04-22 13:40:24 +0000
1085+++ magentoerpconnect_order_comment/sale.py 2014-04-22 13:40:24 +0000
1086@@ -283,8 +283,12 @@
1087
1088 @mapping
1089 def status(self, record):
1090- state = record.magento_sale_order_id.openerp_id.state
1091- return {'status': sale.ORDER_STATUS_MAPPING.get(state, 'pending')}
1092+ if record.status:
1093+ status = record.status
1094+ else:
1095+ state = record.magento_sale_order_id.openerp_id.state
1096+ status = sale.ORDER_STATUS_MAPPING.get(state, 'pending')
1097+ return {'status': status}
1098
1099 @mapping
1100 def order_increment(self, record):