Merge lp:~akretion-team/openerp-connector-magento/openerp-connector-magento-bundle-split into lp:~openerp-connector-core-editors/openerp-connector-magento/7.0
- openerp-connector-magento-bundle-split
- Merge into 7.0
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
OpenERP Connector Core Editors | Pending | ||
Review via email: mp+214048@code.launchpad.net |
Commit message
Description of the change
Add module for importing sale order with bundle
- 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.SaleOrderI
mport connector_unit. Thanks to Guewen for the idea
Preview Diff
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): |