Merge lp:~gbaconnier-c2c/magentoerpconnect/magentoerpconnectv6-c2c into lp:magentoerpconnect/oerp6.0-stable

Proposed by Guewen Baconnier @ Camptocamp
Status: Merged
Merge reported by: Guewen Baconnier @ Camptocamp
Merged at revision: not available
Proposed branch: lp:~gbaconnier-c2c/magentoerpconnect/magentoerpconnectv6-c2c
Merge into: lp:magentoerpconnect/oerp6.0-stable
Diff against target: 412 lines (+180/-68)
6 files modified
magerp_data.xml (+22/-2)
product.py (+54/-19)
product_view.xml (+3/-0)
sale.py (+75/-40)
settings/external.mappinglines.template.csv (+9/-3)
stock.py (+17/-4)
To merge this branch: bzr merge lp:~gbaconnier-c2c/magentoerpconnect/magentoerpconnectv6-c2c
Reviewer Review Type Date Requested Status
Raphaël Valyi - http://www.akretion.com Pending
Review via email: mp+55476@code.launchpad.net

Description of the change

Hi,

Here is some proposal for the connector.

Revno 396: (Rationalized import of extra sales orders lines like shipping, discount, cash on delivery,... into one single method instead of a method for each one.)
On the sale order's creation, there's a method to add shipping fees. A new method appears to add gift certificates, and there is still the case of the discount coupons and the cash on delivery fees (and maybe other fees/rebates).
The behavior is the same for each of them : get the amount in the magento's data, get a product, get a tax if a tax amount is found in the magento's data and add the line to the order.
That's why instead of having 4 methods doing nearly the same things, I propose you to use the same.
I couldn't test the gift certificate and cash on delivery because I have not them on Magento, but the shipping and discount coupons are ok. I'm also not sure with my methods definitions (I first started with one method with a loop on each type and a dict to define types, but I think the version I propose here let more space for overridings) so don't put your priority on this proposal if you have not a lot of time.

Revno 398: (include_in_menu and page_layout attributes on product categories)
Configure these 2 magento's attributes from OpenERP.

Revno 399: (hooks and small refactoring to allow management of configurable products from a module)
We are going to release our module to manage configurable products very soon (as soon as you approve the hooks in magentoerpconnect in fact).
I added a hook in the method ext_export to export configurable products, the reason is clear.
A little more explanation why I modified the method create_ext_partial_shipping in stock.py :
When you order a configurable product in Magento, and do a "sales_order.info" on the API, it gives you 2 items : the configurable and the simple product. We put the configurable as a service, so it doesn't appear in the picking. But when you want to create the (partial) shipping on Magento, it expects the configurable and the simple product.
So I added the method "add_picking_line" which basically just add the line of the picking. But in our module, I do a super on that method and then I add a second line with the configurable product if so.

There is also a proposal on base_sale_multichannels in that branch :
https://code.launchpad.net/~gbaconnier-c2c/openobject-addons/extra-6.0-c2c-magento-improvements
revno 5352 : (base_sale_multichannels: configure a different payment term for each base_sale_payment_type)

Apply a payment term on sales orders based on payment types.

I'm open to change things that bother you.

Thanks !

Guewen

To post a comment you must log in.
400. By Guewen Baconnier @ CampToCamp <email address hidden>

[FIX] mapping for discount

Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote :

Seems Good Guewen!
Sebastien already merged the base_sale_multichannels thing and we will merge the other part as soon as we can. Thank you very much, always a pleasure to get all those improvements from CampToCamp.

401. By Guewen Baconnier @ CampToCamp <email address hidden>

[FIX] replaced options parameter by context

402. By Guewen Baconnier @ CampToCamp <email address hidden>

[IMP] translations on product categories

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

Last commit enable the translations of product categories on stores.
It correct also this bug :
- If your Magento Instance is configured with a default language of "French" and someone with an english account launch the export of catalog, or it is launched by the cron, translations are english translation instead of using the good one.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'magerp_data.xml'
2--- magerp_data.xml 2011-01-18 18:22:58 +0000
3+++ magerp_data.xml 2011-04-11 07:44:24 +0000
4@@ -14,7 +14,17 @@
5 <field name="standard_price">0.0</field>
6 <field name="type">service</field>
7 <field name="name">Shipping and Handling</field>
8- <field name="exportable" eval="False" />
9+ <field name="magento_exportable" eval="False" />
10+ <field name="categ_id" ref="mag0"/>
11+ </record>
12+
13+ <record id="product_product_cash_on_delivery" model="product.product">
14+ <field name="default_code">CASH ON DELIVERY MAGENTO</field>
15+ <field name="list_price">0.0</field>
16+ <field name="standard_price">0.0</field>
17+ <field name="type">service</field>
18+ <field name="name">Cash on delivery</field>
19+ <field name="magento_exportable" eval="False" />
20 <field name="categ_id" ref="mag0"/>
21 </record>
22
23@@ -24,10 +34,20 @@
24 <field name="standard_price">0.0</field>
25 <field name="type">service</field>
26 <field name="name">Gift Certificate</field>
27- <field name="exportable" eval="False" />
28+ <field name="magento_exportable" eval="False" />
29 <field name="categ_id" ref="mag0"/>
30 </record>
31
32+ <record id="product_product_discount" model="product.product">
33+ <field name="default_code">DISCOUNT MAGENTO</field>
34+ <field name="list_price">0.0</field>
35+ <field name="standard_price">0.0</field>
36+ <field name="type">service</field>
37+ <field name="name">Discount coupon</field>
38+ <field name="magento_exportable" eval="False" />
39+ <field name="categ_id" ref="mag0"/>
40+ </record>
41+
42 <record forcecreate="True" id="ir_cron_import_orders_scheduler_action" model="ir.cron">
43 <field name="name">Magento Import Orders</field>
44 <field eval="False" name="active"/>
45
46=== modified file 'product.py'
47--- product.py 2011-03-10 10:36:25 +0000
48+++ product.py 2011-04-11 07:44:24 +0000
49@@ -75,13 +75,24 @@
50 ('name', 'Name'),
51 ('price', 'Price')
52 ], 'Default Product Listing Sort (Sort By)'),
53- 'magerp_stamp':fields.datetime('Magento stamp')
54+ 'magerp_stamp':fields.datetime('Magento stamp'),
55+ 'include_in_menu': fields.boolean('Include in Navigation Menu'),
56+ 'page_layout': fields.selection([
57+ ('None', 'No layout updates'),
58+ ('empty', 'Empty'),
59+ ('one_column', '1 column'),
60+ ('two_columns_left', '2 columns with left bar'),
61+ ('two_columns_right', '2 columns with right bar'),
62+ ('three_columns', '3 columns'),
63+ ], 'Page Layout'),
64 }
65 _defaults = {
66 'display_mode':lambda * a:'PRODUCTS',
67 'available_sort_by':lambda * a:'None',
68 'default_sort_by':lambda * a:'None',
69- 'level':lambda * a:1
70+ 'level':lambda * a:1,
71+ 'include_in_menu': lambda * a:True,
72+ 'page_layout': lambda * a:'None'
73 }
74
75 def write(self, cr, uid, ids, vals, context=None):
76@@ -114,27 +125,45 @@
77 ids = [id for id in ids if id in ids_exportable] #we need to kept the order of the categories
78
79 shop = self.pool.get('sale.shop').browse(cr, uid, context['shop_id'])
80-
81+
82+ context_dic = [context.copy()]
83+ context_dic[0]['export_url'] = True # for the magento version 1.3.2.4, only one url is autorized by category, so we only export with the MAPPING TEMPLATE the url of the default language
84+ context_dic[0]['lang'] = shop.referential_id.default_lang_id.code
85+
86+ for storeview in shop.storeview_ids:
87+ if storeview.lang_id and storeview.lang_id.code != shop.referential_id.default_lang_id.code:
88+ context_dic += [context.copy()]
89+ context_dic[len(context_dic)-1].update({'storeview_code': storeview.code, 'lang': storeview.lang_id.code})
90+
91 if shop.last_products_export_date:
92 last_exported_time = datetime.datetime.fromtimestamp(time.mktime(time.strptime(shop.last_products_export_date, '%Y-%m-%d %H:%M:%S')))
93 else:
94 last_exported_time = False
95-
96- cr.execute("select write_date, create_date from product_category where id in %s", (tuple(ids),))
97- read = cr.fetchall()
98- for categ in read:
99- last_updated_categ = categ[0] and categ[0].split('.')[0] or categ[1] and categ[1].split('.')[0] or False
100- last_updated_categ_time = datetime.datetime.fromtimestamp(time.mktime(time.strptime(last_updated_categ, '%Y-%m-%d %H:%M:%S')))
101- if last_updated_categ_time and last_exported_time:
102- if last_exported_time - datetime.timedelta(seconds=1) < last_updated_categ_time:
103- context['force'] = True
104- res = super(product_category, self).ext_export(cr, uid, ids, external_referential_ids, defaults, context)
105- break
106- if not res:
107- context['force'] = True
108- res = super(product_category, self).ext_export(cr, uid, ids, external_referential_ids, defaults, context)
109+
110+ if not last_exported_time:
111+ for ctx_storeview in context_dic:
112+ ctx_storeview['force'] = True
113+ res = super(product_category, self).ext_export(cr, uid, ids, external_referential_ids, defaults, ctx_storeview)
114+ else:
115+ cr.execute("select write_date, create_date from product_category where id in %s", (tuple(ids),))
116+ read = cr.fetchall()
117+ for categ in read:
118+ last_updated_categ = categ[0] and categ[0].split('.')[0] or categ[1] and categ[1].split('.')[0] or False
119+ last_updated_categ_time = datetime.datetime.fromtimestamp(time.mktime(time.strptime(last_updated_categ, '%Y-%m-%d %H:%M:%S')))
120+ if last_updated_categ_time and last_exported_time:
121+ if last_exported_time - datetime.timedelta(seconds=1) < last_updated_categ_time:
122+ for ctx_storeview in context_dic:
123+ ctx_storeview['force'] = True
124+ res = super(product_category, self).ext_export(cr, uid, ids, external_referential_ids, defaults, ctx_storeview)
125+ break
126 return res
127-
128+
129+ def try_ext_update(self, cr, uid, data, conn, method, oe_id, external_id, ir_model_data_id, create_method, context):
130+ if context.get('storeview_code', False):
131+ return conn.call(method, [external_id, data, context.get('storeview_code', False)])
132+ else:
133+ return conn.call(method, [external_id, data])
134+
135 product_category()
136
137
138@@ -899,7 +928,10 @@
139 res = super(magerp_osv.magerp_osv, self).ext_create(cr, uid, [product_type, attr_set_id, sku, data], conn, method, oe_id, context)
140 self.write(cr, uid, oe_id, {'magento_sku': sku})
141 return res
142-
143+
144+ def ext_export_configurable(self, cr, uid, id, external_referential_ids=None, defaults=None, context=None):
145+ raise osv.except_osv(_("Not Implemented"), _("Configurable products are not implemented."))
146+
147 def ext_export(self, cr, uid, ids, external_referential_ids=None, defaults=None, context=None):
148 if context is None:
149 context = {}
150@@ -999,6 +1031,8 @@
151 self.ext_export(cr, uid, child_ids, external_referential_ids, defaults, context) #so we export them
152 else:
153 logger.notifyChannel('ext synchro', netsvc.LOG_ERROR, "OpenERP 'grouped' products will export to Magento as 'grouped products' only if they have a BOM and if the 'mrp' BOM module is installed")
154+ elif product_type == 'configurable':
155+ self.ext_export_configurable(cr, uid, id, external_referential_ids, defaults, context)
156 for context_storeview in context_dic:
157 temp_result = super(magerp_osv.magerp_osv, self).ext_export(cr, uid, [id], external_referential_ids, defaults, context_storeview)
158 if child_ids:
159@@ -1030,6 +1064,7 @@
160 is_in_stock = int(virtual_available > 0)
161 context['conn_obj'].call('product_stock.update', [product.magento_sku, {'qty': virtual_available, 'is_in_stock': is_in_stock}])
162 logger.notifyChannel('ext synchro', netsvc.LOG_INFO, "Successfully updated stock level at %s for product with SKU %s " %(virtual_available, product.magento_sku))
163+ return True
164
165 def ext_grouped_product_assign(self, cr, uid, parent_id, child_ids, quantities, context):
166 logger = netsvc.Logger()
167
168=== modified file 'product_view.xml'
169--- product_view.xml 2011-03-18 16:31:46 +0000
170+++ product_view.xml 2011-04-11 07:44:24 +0000
171@@ -22,6 +22,7 @@
172 <field name="meta_description" colspan="2" />
173 <field name="url_key" colspan="2" />
174 <field name="level" colspan="2" />
175+ <field name="include_in_menu" colspan="2" />
176 </group>
177 <group col="1" colspan="1">
178 <separator string="Category Image" />
179@@ -51,6 +52,8 @@
180 <separator string="Sorting method" colspan="4" />
181 <field name="available_sort_by" />
182 <field name="default_sort_by" />
183+ <separator string="Page Layout" colspan="4" />
184+ <field name="page_layout" nolabel="1" />
185 </page>
186 </notebook>
187 </group>
188
189=== modified file 'sale.py'
190--- sale.py 2011-04-02 14:58:57 +0000
191+++ sale.py 2011-04-11 07:44:24 +0000
192@@ -384,49 +384,83 @@
193 res['order_line'] = lines_vals
194 return res
195
196- def add_gift_certificates(self, cursor, user, order_values,
197- magento_order_data, context):
198- '''Add gift certificate as a separate line item with single quantity
199- and negative amount. Known to work with Unigry gift certificates also
200- '''
201- product_obj = self.pool.get('product.product')
202- if ('giftcert_amount' in magento_order_data) and \
203- (float(magento_order_data.get('giftcert_amount', 0)) > 0):
204- gift_product_ids = product_obj.search(cursor, user,
205- [('default_code', '=', 'GIFT CERTIFICATE')], context=context)
206- if gift_product_ids:
207- gift_product = product_obj.browse(
208- cursor, user, gift_product_ids[0], context)
209- gift_cert_code = magento_order_data['giftcert_code']
210- order_values['order_line'].append((0, 0, {
211- 'product_id': gift_product.id,
212- 'name': 'Gift Certificate %s' % gift_cert_code,
213- 'product_uom': gift_product.uom_id.id,
214- 'product_uom_qty': 1,
215- 'price_unit': -float(magento_order_data['giftcert_amount']),
216- }))
217- return order_values
218-
219- def get_order_shipping(self, cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context):
220- ship_product_id = self.pool.get('product.product').search(cr, uid, [('default_code', '=', 'SHIP MAGENTO')])[0]
221- ship_product = self.pool.get('product.product').browse(cr, uid, ship_product_id, context)
222-
223- #simple VAT tax on shipping (else override method):
224+ def add_order_extra_line(self, cr, uid, res, data_record, ext_field, product_code, context):
225+ """ Add or substract amount on order as a separate line item with single quantity for each type of amounts like :
226+ shipping, cash on delivery, discount, gift certificates...
227+ Arguments :
228+ ext_field: name of the field in data_record where the amount is stored
229+ product_code: code of the product to use in the sale order line
230+ Optional arguments in kwargs:
231+ sign: multiply the amount with the sign to add or substract it from the sale order
232+ ext_tax_field: name of the field in data_record where the tax amount is stored
233+ ext_code_field: name of the field in data_record containing a code (for coupons and gift certificates) which will be printed on the product name
234+ """
235+ sign = 'sign' in context and context['sign'] or 1
236+ ext_tax_field = 'ext_tax_field' in context and context['ext_tax_field'] or None
237+ ext_code_field = 'ext_code_field' in context and context['ext_code_field'] or None
238+
239+ product_id = self.pool.get('product.product').search(cr, uid, [('default_code', '=', product_code)])[0]
240+ product = self.pool.get('product.product').browse(cr, uid, product_id, context)
241+ amount = float(data_record[ext_field]) * sign
242+
243 tax_id = []
244- if data_record['shipping_tax_amount'] and float(data_record['shipping_tax_amount']) != 0:
245- ship_tax_vat = float(data_record['shipping_tax_amount'])/float(data_record['shipping_amount'])
246- ship_tax_ids = self.pool.get('account.tax').search(cr, uid, [('type_tax_use', '=', 'sale'), ('amount', '>=', ship_tax_vat - 0.001), ('amount', '<=', ship_tax_vat + 0.001)])
247- if ship_tax_ids and len(ship_tax_ids) > 0:
248- tax_id = [(6, 0, [ship_tax_ids[0]])]
249+ if ext_tax_field:
250+ if data_record[ext_tax_field] and float(data_record[ext_tax_field]) != 0:
251+ tax_vat = abs(float(data_record[ext_tax_field]) / amount)
252+ tax_ids = self.pool.get('account.tax').search(cr, uid, [('type_tax_use', '=', 'sale'), ('amount', '>=', tax_vat - 0.001), ('amount', '<=', tax_vat + 0.001)])
253+ if tax_ids and len(tax_ids) > 0:
254+ tax_id = [(6, 0, [tax_ids[0]])]
255+
256+ name = product.name
257+ if ext_code_field and data_record.get(ext_code_field, False):
258+ name = "%s [%s]" % (name, data_record[ext_code_field])
259+
260 res['order_line'].append((0, 0, {
261- 'product_id': ship_product.id,
262- 'name': ship_product.name,
263- 'product_uom': ship_product.uom_id.id,
264+ 'product_id': product.id,
265+ 'name': name,
266+ 'product_uom': product.uom_id.id,
267 'product_uom_qty': 1,
268- 'price_unit': float(data_record['shipping_amount']),
269+ 'price_unit': amount,
270 'tax_id': tax_id
271 }))
272 return res
273+
274+ def add_order_shipping(self, cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context):
275+ if data_record.get('shipping_amount', False) and float(data_record.get('shipping_amount', False)) > 0:
276+ ctx = context.copy()
277+ ctx.update({
278+ 'ext_tax_field': 'shipping_tax_amount',
279+ })
280+ res = self.add_order_extra_line(cr, uid, res, data_record, 'shipping_amount', 'SHIP MAGENTO', ctx)
281+ return res
282+
283+ def add_gift_certificates(self, cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context):
284+ if data_record.get('giftcert_amount', False) and float(data_record.get('giftcert_amount', False)) > 0:
285+ ctx = context.copy()
286+ ctx.update({
287+ 'ext_code_field': 'giftcert_code',
288+ 'sign': -1,
289+ })
290+ res = self.add_order_extra_line(cr, uid, res, data_record, 'giftcert_amount', 'GIFT CERTIFICATE', ctx)
291+ return res
292+
293+ def add_discount(self, cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context):
294+ if data_record.get('discount_amount', False) and float(data_record.get('discount_amount', False)) < 0:
295+ ctx = context.copy()
296+ ctx.update({
297+ 'ext_code_field': 'coupon_code',
298+ })
299+ res = self.add_order_extra_line(cr, uid, res, data_record, 'discount_amount', 'DISCOUNT MAGENTO', ctx)
300+ return res
301+
302+ def add_cash_on_delivery(self, cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context):
303+ if data_record.get('cod_fee', False) and float(data_record.get('cod_fee', False)) > 0:
304+ ctx = context.copy()
305+ ctx.update({
306+ 'ext_tax_field': 'cod_tax_amount',
307+ })
308+ res = self.add_order_extra_line(cr, uid, res, data_record, 'cod_fee', 'CASH ON DELIVERY MAGENTO', ctx)
309+ return res
310
311 def oevals_from_extdata(self, cr, uid, external_referential_id, data_record, key_field, mapping_lines, defaults, context):
312 if not context.get('one_by_one', False):
313@@ -439,9 +473,10 @@
314 if data_record.get('items', False):
315 try:
316 res = self.get_order_lines(cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context)
317- if data_record.get('shipping_amount', False) and float(data_record.get('shipping_amount', False)) > 0:
318- res = self.get_order_shipping(cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context)
319- res = self.add_gift_certificates(cr, uid, res, data_record, context)
320+ res = self.add_order_shipping(cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context)
321+ res = self.add_gift_certificates(cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context)
322+ res = self.add_discount(cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context)
323+ res = self.add_cash_on_delivery(cr, uid, res, external_referential_id, data_record, key_field, mapping_lines, defaults, context)
324 except Exception, e:
325 print "order has errors with items lines, data are: ", data_record
326 print e
327
328=== modified file 'settings/external.mappinglines.template.csv'
329--- settings/external.mappinglines.template.csv 2010-12-14 21:01:23 +0000
330+++ settings/external.mappinglines.template.csv 2011-04-11 07:44:24 +0000
331@@ -35,7 +35,7 @@
332 "mag_erp_soline_uomqty","magento1324","sale.model_sale_order_line","qty_ordered","in_out","str","result=[('product_uom_qty',ifield)]",
333 "mag_erp_soline_uosqty","magento1324","sale.model_sale_order_line","qty_ordered","in","str","result=[('product_uos_qty',ifield)]",
334 "mag_erp_soline_price","magento1324","sale.model_sale_order_line","price","in","str","result=[('price_unit', float(data['row_total'])/float(data['qty_ordered']))]",
335-"mag_erp_soline_disc","magento1324","sale.model_sale_order_line","discount_amount","in","str","result=[('discount', float(data['price']) != 0 and float(data['qty_ordered']) != 0 and float(100*float(ifield))/(float(data['price'])*float(data['qty_ordered'])) or 0)]",
336+"mag_erp_soline_disc","magento1324","sale.model_sale_order_line","discount_amount","in","str","result=[('discount', 0.0)]",
337 "mag_erp_procat_2","magento1324","product.model_product_category","level","in","int","result=[('sequence',ifield),('level',ifield)]",
338 "mag_erp_procat_3","magento1324","product.model_product_category","parent_id","in_out","int","record_id = self.pool.get('ir.model.data').search(cr, uid, [('model', '=', self._name), ('name', '=', self.prefixed_id(ifield))])
339 parent_id = False
340@@ -46,7 +46,7 @@
341 if record.get('parent_id',False):
342 magento_parent_id = self.oeid_to_extid(cr, uid, record.get('parent_id')[0], external_referential_id)
343 if not magento_parent_id:
344- self.ext_export(cr,uid,[record.get('parent_id',[False])[0]],[external_referential_id],{},{'conn_obj':conn})
345+ self.ext_export(cr,uid,[record.get('parent_id',[False])[0]],[external_referential_id],{},context=context)
346 magento_parent_id = self.oeid_to_extid(cr, uid, record.get('parent_id')[0], external_referential_id)
347 if magento_parent_id:
348 result = [('parent_id',magento_parent_id)]"
349@@ -55,7 +55,8 @@
350 "mag_erp_procat_6","magento1324","product.model_product_category","meta_title","in_out","str","result=[('meta_title',ifield)]","result=[('meta_title',record['meta_title'])]"
351 "mag_erp_procat_7","magento1324","product.model_product_category","meta_keywords","in_out","str","result=[('meta_keywords',ifield)]","result=[('meta_keywords',record['meta_keywords'])]"
352 "mag_erp_procat_8","magento1324","product.model_product_category","meta_description","in_out","str","result=[('meta_description',ifield)]","result=[('meta_description',record['meta_description'])]"
353-"mag_erp_procat_9","magento1324","product.model_product_category","url_key","in_out","str","result=[('url_key',ifield)]","result=[('url_key',record['url_key'])]"
354+"mag_erp_procat_9","magento1324","product.model_product_category","url_key","in_out","str","result=[('url_key',ifield)]","if context.get('export_url', False) :
355+ result=[('url_key',record['url_key'])]"
356 "mag_erp_procat_10","magento1324","product.model_product_category","name","in_out","str","result=[('name',ifield or 'UNDEFINED'),('magento_exportable',True)]","result=[('name',record['name'])]"
357 "mag_erp_procat_11","magento1324","product.model_product_category","is_anchor","in_out","str","result=[('is_anchor',ifield and bool(eval(ifield)) or False)]","result=[('is_anchor',record['is_anchor'])]"
358 "mag_erp_procat_12","magento1324","product.model_product_category","available_sort_by","in_out","str","result=[('available_sort_by',ifield)]","result=[('available_sort_by',record['available_sort_by'] or 'name')]"
359@@ -77,6 +78,11 @@
360 result = [('image',record['image_name'])]
361 else:
362 result=[]"
363+"mag_erp_procat_16","magento1324","product.model_product_category","include_in_menu","in_out","str","result=[('include_in_menu', ifield and (eval(ifield)) or False)]","result=[('include_in_menu',record['include_in_menu'])]"
364+"mag_erp_procat_17","magento1324","product.model_product_category","page_layout","in_out","str","if ifield:
365+ result=[('page_layout',ifield)]
366+else:
367+ result=[('page_layout','None')]","result=[('page_layout', record['page_layout'] or '')]"
368 "mag_erp_attrgrp_2","magento1324","model_magerp_product_attribute_groups","attribute_set_id","in_out","int","result=[('attribute_set_id', ifield)]","result=[('attribute_set_id', record['attribute_set_id'])]"
369 "mag_erp_attrgrp_3","magento1324","model_magerp_product_attribute_groups","attribute_group_name","in_out","str","result=[('attribute_group_name', ifield)]","result=[('attribute_group_name', record['attribute_group_name'])]"
370 "mag_erp_attrgrp_4","magento1324","model_magerp_product_attribute_groups","sort_order","in_out","int","result=[('sort_order', ifield)]","result=[('sort_order', record['sort_order'])]"
371
372=== modified file 'stock.py'
373--- stock.py 2010-11-15 20:46:10 +0000
374+++ stock.py 2011-04-11 07:44:24 +0000
375@@ -35,8 +35,15 @@
376 ext_shipping_id = conn.call('sales_order_shipment.create', [magento_incrementid, {}, _("Shipping Created"), True, True])
377 except Exception, e:
378 logger.notifyChannel(_("Magento Call"), netsvc.LOG_ERROR, _("The picking from the order %s can't be created on Magento, please attach it manually, %s") % (magento_incrementid, e))
379- return ext_shipping_id
380+ return ext_shipping_id
381
382+ def add_picking_line(self, cr, uid, lines, picking_line, context):
383+ """ A line to add in the shipping is a dict with : product_id and product_qty keys."""
384+ line_info = {'product_id': picking_line.product_id.id,
385+ 'product_qty': picking_line.product_qty,
386+ }
387+ lines.append(line_info)
388+ return lines
389
390 def create_ext_partial_shipping(self, cr, uid, id, external_referential_id, magento_incrementid, context):
391 logger = netsvc.Logger()
392@@ -48,11 +55,17 @@
393 product_2_item.update({self.pool.get('product.product').extid_to_oeid(cr, uid, item['product_id'], external_referential_id, context={}): item['item_id']})
394 picking = self.pool.get('stock.picking').browse(cr, uid, id, context)
395 item_qty = {}
396+
397+ lines = []
398+ # get product and quantities to ship from the picking
399 for line in picking.move_lines:
400- if item_qty.get(product_2_item[line.product_id.id], False):
401- item_qty[product_2_item[line.product_id.id]] += line.product_qty
402+ lines = self.add_picking_line(cr, uid, lines, line, context)
403+
404+ for line in lines:
405+ if item_qty.get(product_2_item[line['product_id']], False):
406+ item_qty[product_2_item[line['product_id']]] += line['product_qty']
407 else:
408- item_qty.update({product_2_item[line.product_id.id]:line.product_qty})
409+ item_qty.update({product_2_item[line['product_id']]: line['product_qty']})
410 try:
411 ext_shipping_id = conn.call('sales_order_shipment.create', [magento_incrementid, item_qty, _("Shipping Created"), True, True])
412 except Exception, e: