Merge lp:~akretion-team/openerp-connector-magento/7.0-export-partner-and-address into lp:~openerp-connector-core-editors/openerp-connector-magento/7.0

Proposed by Florian da Costa
Status: Superseded
Proposed branch: lp:~akretion-team/openerp-connector-magento/7.0-export-partner-and-address
Merge into: lp:~openerp-connector-core-editors/openerp-connector-magento/7.0
Diff against target: 427 lines (+301/-7)
7 files modified
magentoerpconnect/partner.py (+7/-1)
magentoerpconnect/unit/export_synchronizer.py (+5/-0)
magentoerpconnect_export_partner/__init__.py (+1/-0)
magentoerpconnect_export_partner/consumer.py (+16/-3)
magentoerpconnect_export_partner/partner.py (+113/-3)
magentoerpconnect_export_partner/tests/__init__.py (+29/-0)
magentoerpconnect_export_partner/tests/test_synchronization.py (+130/-0)
To merge this branch: bzr merge lp:~akretion-team/openerp-connector-magento/7.0-export-partner-and-address
Reviewer Review Type Date Requested Status
Guewen Baconnier @ Camptocamp Needs Fixing
Sébastien BEAU - http://www.akretion.com Pending
Review via email: mp+222825@code.launchpad.net

This proposal has been superseded by a proposal from 2014-06-23.

Description of the change

I have completed the magentoerpconnect_export_partner module to fix the export of partners and add the export of addresses.

I have added a method '_after_export' in MagentoExporter so we do not need to manually add the magento bind address for each partner and contact.

I still have to implement some tests.

What do you think?

To post a comment you must log in.
1003. By Florian da Costa

[IMP] Add tests

Revision history for this message
Florian da Costa (florian-dacosta) wrote :

here, I have added the tests.

Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

Hi Florian,

Thanks for your proposal.
I left some comments in the diff.

review: Needs Fixing
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

Also, you should take a look at: https://code.launchpad.net/~camptocamp/openerp-connector-magento/7.0-export-dependency+lock/+merge/223508
And use this branch as base, I left some comments in the diff where you should use some of my branch's features.

Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

What about the password?

1004. By Florian da Costa

[MERGE]

1005. By Florian da Costa

[FIX]Remove useless code + improve basic stuff to export partner

Revision history for this message
Florian da Costa (florian-dacosta) :
1006. By Florian da Costa

[FIX] add change_by decorator on mapping methods

1007. By Florian da Costa

[FIX]change method _validate_data to make 2 different method, one for create a record, one for update + do not export a partner like an address if it is a company

1008. By Florian da Costa

[FIX] Remove password field, it will be handle by a wizard

Unmerged revisions

1008. By Florian da Costa

[FIX] Remove password field, it will be handle by a wizard

1007. By Florian da Costa

[FIX]change method _validate_data to make 2 different method, one for create a record, one for update + do not export a partner like an address if it is a company

1006. By Florian da Costa

[FIX] add change_by decorator on mapping methods

1005. By Florian da Costa

[FIX]Remove useless code + improve basic stuff to export partner

1004. By Florian da Costa

[MERGE]

1003. By Florian da Costa

[IMP] Add tests

1002. By Florian da Costa

[IMP] fix partner export + add address export

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'magentoerpconnect/partner.py'
2--- magentoerpconnect/partner.py 2014-05-26 09:37:00 +0000
3+++ magentoerpconnect/partner.py 2014-06-12 13:48:52 +0000
4@@ -78,7 +78,7 @@
5 _inherits = {'res.partner': 'openerp_id'}
6 _description = 'Magento Partner'
7
8- _rec_name = 'website_id'
9+ _rec_name = 'name'
10
11 def _get_mag_partner_from_website(self, cr, uid, ids, context=None):
12 mag_partner_obj = self.pool['magento.res.partner']
13@@ -568,6 +568,11 @@
14 [filters] if filters else [{}])]
15
16
17+ def create(self, data):
18+ """ Create a record on the external system """
19+ partner_id = data.pop('partner_id')
20+ return self._call('%s.create' % self._magento_model, [partner_id, data])
21+
22 @magento
23 class AddressImport(MagentoImportSynchronizer):
24 _model_name = ['magento.address']
25@@ -624,6 +629,7 @@
26 ('company', 'company'),
27 ]
28
29+
30 @mapping
31 def names(self, record):
32 # TODO create a glue module for base_surname
33
34=== modified file 'magentoerpconnect/unit/export_synchronizer.py'
35--- magentoerpconnect/unit/export_synchronizer.py 2014-05-26 09:37:00 +0000
36+++ magentoerpconnect/unit/export_synchronizer.py 2014-06-12 13:48:52 +0000
37@@ -149,6 +149,10 @@
38 """
39 return self.mapper.map_record(self.binding_record)
40
41+
42+ def _after_export(self):
43+ return True
44+
45 def _validate_data(self, data):
46 """ Check if the values to import are correct
47
48@@ -206,6 +210,7 @@
49 if not record:
50 return _('Nothing to export.')
51 self.magento_id = self._create(record)
52+ self._after_export()
53 return _('Record exported with ID %s on Magento.') % self.magento_id
54
55
56
57=== modified file 'magentoerpconnect_export_partner/__init__.py'
58--- magentoerpconnect_export_partner/__init__.py 2013-03-19 16:53:26 +0000
59+++ magentoerpconnect_export_partner/__init__.py 2014-06-12 13:48:52 +0000
60@@ -1,4 +1,5 @@
61 # -*- coding: utf-8 -*-
62
63+import connector
64 import consumer
65 import partner
66
67=== modified file 'magentoerpconnect_export_partner/consumer.py'
68--- magentoerpconnect_export_partner/consumer.py 2013-10-09 19:41:58 +0000
69+++ magentoerpconnect_export_partner/consumer.py 2014-06-12 13:48:52 +0000
70@@ -28,8 +28,8 @@
71 import openerp.addons.magentoerpconnect.consumer as magentoerpconnect
72
73
74-@on_record_create(model_names='magento.res.partner')
75-@on_record_write(model_names='magento.res.partner')
76+@on_record_create(model_names=['magento.address', 'magento.res.partner'])
77+@on_record_write(model_names=['magento.address', 'magento.res.partner'])
78 def delay_export(session, model_name, record_id, vals):
79 magentoerpconnect.delay_export(session, model_name,
80 record_id, vals)
81@@ -41,6 +41,19 @@
82 record_id, vals)
83
84
85-@on_record_unlink(model_names='magento.res.partner')
86+@on_record_write(model_names='res.partner')
87+def delay_export_all_bindings_for_address(session, model_name,
88+ record_id, vals):
89+ if session.context.get('connector_no_export'):
90+ return
91+ model = session.pool.get(model_name)
92+ record = model.browse(session.cr, session.uid,
93+ record_id, context=session.context)
94+ for binding in record.magento_address_bind_ids:
95+ export_record.delay(session, binding._model._name, binding.id,
96+ vals)
97+
98+
99+@on_record_unlink(model_names=['magento.res.partner', 'magento.address'])
100 def delay_unlink(session, model_name, record_id):
101 magentoerpconnect.delay_unlink(session, model_name, record_id)
102
103=== modified file 'magentoerpconnect_export_partner/partner.py'
104--- magentoerpconnect_export_partner/partner.py 2013-05-01 09:54:36 +0000
105+++ magentoerpconnect_export_partner/partner.py 2014-06-12 13:48:52 +0000
106@@ -23,34 +23,90 @@
107 from openerp.addons.connector.unit.mapper import (mapping,
108 changed_by,
109 ExportMapper)
110+from openerp.addons.connector.exception import InvalidDataError
111 from openerp.addons.magentoerpconnect.unit.delete_synchronizer import (
112 MagentoDeleteSynchronizer)
113 from openerp.addons.magentoerpconnect.unit.export_synchronizer import (
114 MagentoExporter)
115+from openerp.addons.magentoerpconnect.partner import (
116+ AddressAdapter)
117 from openerp.addons.magentoerpconnect.backend import magento
118
119
120 @magento
121 class PartnerDeleteSynchronizer(MagentoDeleteSynchronizer):
122 """ Partner deleter for Magento """
123- _model_name = ['magento.res.partner']
124+ _model_name = ['magento.res.partner',
125+ 'magento.address']
126
127
128 @magento
129 class PartnerExport(MagentoExporter):
130 _model_name = ['magento.res.partner']
131
132+ def _after_export(self):
133+ address_ids = []
134+ data = {
135+ 'magento_partner_id': self.binding_id,
136+ }
137+ if not self.binding_record.magento_address_bind_ids:
138+ data['openerp_id'] = self.binding_record.openerp_id.id
139+ data['is_default_billing'] = True
140+ data['is_default_shipping'] = True
141+ address_ids.append(self.session.create('magento.address', data))
142+ for child in self.binding_record.child_ids:
143+ if not child.magento_address_bind_ids:
144+ data['is_default_billing'] = False
145+ data['is_default_shipping'] = False
146+ data['openerp_id'] = child.id
147+ address_ids.append(self.session.create('magento.address', data))
148+ return True
149+
150+
151+ def _validate_data(self, data):
152+ """ Check if the values to import are correct
153+
154+ Pro-actively check before the ``Model.create`` or
155+ ``Model.update`` if some fields are missing
156+
157+ Raise `InvalidDataError`
158+ """
159+ if not data.get('email', False):
160+ raise InvalidDataError("The partner does not have email "
161+ "but it is mandatory for magento")
162+ return
163+
164+
165+@magento
166+class AddressExport(MagentoExporter):
167+ _model_name = ['magento.address']
168+
169+
170+ def _validate_data(self, data):
171+ """ Check if the values to import are correct
172+
173+ Pro-actively check before the ``Model.create`` or
174+ ``Model.update`` if some fields are missing
175+
176+ Raise `InvalidDataError`
177+ """
178+ for required_key in ('city', 'street', 'postcode', 'country_id', 'telephone'):
179+ if not data.get(required_key, False):
180+ raise InvalidDataError("The address does not contain %s "
181+ "but it is mandatory for magento" %
182+ required_key)
183+ return
184+
185
186 @magento
187 class PartnerExportMapper(ExportMapper):
188 _model_name = 'magento.res.partner'
189
190 direct = [
191- ('emailid', 'email'),
192+ ('email', 'email'),
193 ('birthday', 'dob'),
194 ('created_at', 'created_at'),
195 ('updated_at', 'updated_at'),
196- ('emailid', 'email'),
197 ('taxvat', 'taxvat'),
198 ('group_id', 'group_id'),
199 ('website_id', 'website_id'),
200@@ -68,3 +124,57 @@
201 lastname = record.name
202 firstname = '-'
203 return {'firstname': firstname, 'lastname': lastname}
204+
205+
206+@magento
207+class PartnerAddressExportMapper(ExportMapper):
208+ _model_name = 'magento.address'
209+
210+ direct = [('zip', 'postcode'),
211+ ('city', 'city'),
212+ ('is_default_billing', 'is_default_billing'),
213+ ('is_default_shipping', 'is_default_shipping'),
214+ ]
215+
216+
217+ @mapping
218+ def partner(self, record):
219+ return {'partner_id': int(record.magento_partner_id.magento_id)}
220+
221+
222+ @mapping
223+ def names(self, record):
224+ # FIXME base_surname needed
225+ if ' ' in record.name:
226+ parts = record.name.split()
227+ firstname = parts[0]
228+ lastname = ' '.join(parts[1:])
229+ else:
230+ lastname = record.name
231+ firstname = '-'
232+ return {'firstname': firstname, 'lastname': lastname}
233+
234+
235+ @mapping
236+ def phone(self, record):
237+ return {'telephone': record.phone or record.mobile}
238+
239+
240+ @mapping
241+ def country(self, record):
242+ if record.country_id:
243+ return {'country_id': record.country_id.code}
244+
245+
246+ @mapping
247+ def region(self, record):
248+ if record.state_id:
249+ return {'region': record.state_id.name}
250+
251+
252+ @mapping
253+ def street(self, record):
254+ if record.street:
255+ street = [record.street]
256+ return {'street': street}
257+
258
259=== added directory 'magentoerpconnect_export_partner/tests'
260=== added file 'magentoerpconnect_export_partner/tests/__init__.py'
261--- magentoerpconnect_export_partner/tests/__init__.py 1970-01-01 00:00:00 +0000
262+++ magentoerpconnect_export_partner/tests/__init__.py 2014-06-12 13:48:52 +0000
263@@ -0,0 +1,29 @@
264+# -*- coding: utf-8 -*-
265+##############################################################################
266+#
267+# Author: Florian da Costa
268+# Copyright 2014 Akretion
269+#
270+# This program is free software: you can redistribute it and/or modify
271+# it under the terms of the GNU Affero General Public License as
272+# published by the Free Software Foundation, either version 3 of the
273+# License, or (at your option) any later version.
274+#
275+# This program is distributed in the hope that it will be useful,
276+# but WITHOUT ANY WARRANTY; without even the implied warranty of
277+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
278+# GNU Affero General Public License for more details.
279+#
280+# You should have received a copy of the GNU Affero General Public License
281+# along with this program. If not, see <http://www.gnu.org/licenses/>.
282+#
283+##############################################################################
284+
285+import test_synchronization
286+
287+fast_suite = [
288+]
289+
290+checks = [
291+ test_synchronization,
292+]
293
294=== added file 'magentoerpconnect_export_partner/tests/test_synchronization.py'
295--- magentoerpconnect_export_partner/tests/test_synchronization.py 1970-01-01 00:00:00 +0000
296+++ magentoerpconnect_export_partner/tests/test_synchronization.py 2014-06-12 13:48:52 +0000
297@@ -0,0 +1,130 @@
298+# -*- coding: utf-8 -*-
299+##############################################################################
300+#
301+# Author: Florian da Costa
302+# Copyright 2014 Akretion
303+#
304+# This program is free software: you can redistribute it and/or modify
305+# it under the terms of the GNU Affero General Public License as
306+# published by the Free Software Foundation, either version 3 of the
307+# License, or (at your option) any later version.
308+#
309+# This program is distributed in the hope that it will be useful,
310+# but WITHOUT ANY WARRANTY; without even the implied warranty of
311+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
312+# GNU Affero General Public License for more details.
313+#
314+# You should have received a copy of the GNU Affero General Public License
315+# along with this program. If not, see <http://www.gnu.org/licenses/>.
316+#
317+##############################################################################
318+
319+from openerp.addons.magentoerpconnect.tests.test_synchronization import (
320+ SetUpMagentoSynchronized)
321+from openerp.addons.magentoerpconnect.tests.test_data import (
322+ magento_base_responses)
323+from openerp.addons.magentoerpconnect.tests.common import (
324+ mock_api,
325+ mock_urlopen_image)
326+from openerp.addons.magentoerpconnect.unit.export_synchronizer import (
327+ export_record)
328+
329+
330+class SetUpMagentoWithPartner(SetUpMagentoSynchronized):
331+
332+ def setUp(self):
333+ super(SetUpMagentoWithPartner, self).setUp()
334+ cr = self.cr
335+ uid = self.uid
336+ self.website_id = self.registry('magento.website').search(cr, uid, [
337+ ('backend_id', '=', self.backend_id)])[0]
338+ oe_partner_model = self.registry('res.partner')
339+ country_id = self.registry('res.country').search(cr, uid, [
340+ ('code', '=', 'BE')])[0]
341+ self.partner_id = oe_partner_model.create(
342+ cr, uid,
343+ {'name': 'Partner Partner2',
344+ 'is_company': True,
345+ 'email': 'partner@odoo.com',
346+ 'street': '15, test street',
347+ 'phone': '0000000000',
348+ 'zip': '00000',
349+ 'country_id': country_id,
350+ 'city': 'City test'})
351+ self.contact_id = oe_partner_model.create(
352+ cr, uid,
353+ {'name': 'Contact',
354+ 'parent_id': self.partner_id,
355+ 'street': '15, contact test street',
356+ 'phone': '111111111',
357+ 'zip': '11111',
358+ 'country_id': country_id,
359+ 'city': 'City contact test'})
360+
361+
362+class TestMagentoPartnerExport(SetUpMagentoWithPartner):
363+ """ Test the export from a Magento Mock.
364+ """
365+
366+ def test_1_export_partner(self):
367+ """ Test export of partner"""
368+ response = {
369+ 'customer.create': True,
370+ }
371+ cr = self.cr
372+ uid = self.uid
373+ with mock_api(response, key_func=lambda m, a: m) as calls_done:
374+ mag_address_model = self.registry('magento.address')
375+ mag_partner_model = self.registry('magento.res.partner')
376+ mag_partner_id = mag_partner_model.create(cr, uid, {
377+ 'website_id': self.website_id,
378+ 'openerp_id': self.partner_id,
379+ })
380+ export_record(self.session, 'magento.res.partner', mag_partner_id)
381+
382+ self.assertEqual(len(calls_done), 1)
383+ method, [values] = calls_done[0]
384+ self.assertEqual(method, 'customer.create')
385+ self.assertEqual(values['email'], 'partner@odoo.com')
386+ self.assertEqual(values['firstname'], 'Partner')
387+ self.assertEqual(values['lastname'], 'Partner2')
388+
389+ mag_address_ids = mag_address_model.search(cr, uid, [
390+ ('magento_partner_id', '=', mag_partner_id)])
391+ self.assertEqual(len(mag_address_ids), 2)
392+
393+
394+ def test_2_export_partner_address(self):
395+ """ Test export of address"""
396+ response = {
397+ 'customer_address.create': True,
398+ }
399+ cr = self.cr
400+ uid = self.uid
401+ with mock_api(response, key_func=lambda m, a: m) as calls_done:
402+ mag_address_model = self.registry('magento.address')
403+ mag_partner_model = self.registry('magento.res.partner')
404+ mag_partner_id = mag_partner_model.create(cr, uid, {
405+ 'website_id': self.website_id,
406+ 'openerp_id': self.partner_id,
407+ 'magento_id': 1,
408+ })
409+ mag_address_id = mag_address_model.create(cr, uid, {
410+ 'magento_partner_id': mag_partner_id,
411+ 'openerp_id': self.partner_id,
412+ })
413+ export_record(self.session, 'magento.address', mag_address_id)
414+
415+ self.assertEqual(len(calls_done), 1)
416+
417+ method, [partner, values] = calls_done[0]
418+
419+ self.assertEqual(method, 'customer_address.create')
420+ self.assertEqual(partner, 1)
421+ self.assertEqual(values['postcode'], '00000')
422+ self.assertEqual(values['city'], 'City test')
423+ self.assertEqual(values['street'], '15, test street')
424+ self.assertEqual(values['country_id'], 'BE')
425+ self.assertEqual(values['telephone'], '0000000000')
426+
427+