Merge lp:~cv.clearcorp/openerp-ccorp-addons/6.1-sneldev_magento into lp:openerp-ccorp-addons/6.1

Proposed by Carlos Vásquez (ClearCorp)
Status: Merged
Merged at revision: 595
Proposed branch: lp:~cv.clearcorp/openerp-ccorp-addons/6.1-sneldev_magento
Merge into: lp:openerp-ccorp-addons/6.1
Diff against target: 3360 lines (+3197/-0)
29 files modified
sneldev_magento/__init__.py (+31/-0)
sneldev_magento/__openerp__.py (+52/-0)
sneldev_magento/common_tools.py (+116/-0)
sneldev_magento/i18n/es_CR.po (+439/-0)
sneldev_magento/security/ir.model.access.csv (+2/-0)
sneldev_magento/sneldev_magento.py (+1528/-0)
sneldev_magento/sneldev_magento_data.xml (+6/-0)
sneldev_magento/sneldev_magento_view.xml (+131/-0)
sneldev_magento/sneldev_magento_wizard.xml (+114/-0)
sneldev_magento/wizard/__init__.py (+10/-0)
sneldev_magento/wizard/export_tools.py (+54/-0)
sneldev_magento/wizard/sneldev_magento_categories_import.py (+49/-0)
sneldev_magento/wizard/sneldev_magento_categories_import.xml (+30/-0)
sneldev_magento/wizard/sneldev_magento_customers_import.py (+51/-0)
sneldev_magento/wizard/sneldev_magento_customers_import.xml (+27/-0)
sneldev_magento/wizard/sneldev_magento_orders_import.py (+54/-0)
sneldev_magento/wizard/sneldev_magento_orders_import.xml (+30/-0)
sneldev_magento/wizard/sneldev_magento_products_export.py (+50/-0)
sneldev_magento/wizard/sneldev_magento_products_export.xml (+30/-0)
sneldev_magento/wizard/sneldev_magento_products_import.py (+50/-0)
sneldev_magento/wizard/sneldev_magento_products_import.xml (+30/-0)
sneldev_magento/wizard/sneldev_magento_stock_export.py (+50/-0)
sneldev_magento/wizard/sneldev_magento_stock_export.xml (+30/-0)
sneldev_magento/wizard/sneldev_magento_stock_init.py (+49/-0)
sneldev_magento/wizard/sneldev_magento_stock_init.xml (+30/-0)
sneldev_magento/wizard/sneldev_magento_sync_start.py (+47/-0)
sneldev_magento/wizard/sneldev_magento_sync_start.xml (+30/-0)
sneldev_magento/wizard/sneldev_magento_sync_stop.py (+47/-0)
sneldev_magento/wizard/sneldev_magento_sync_stop.xml (+30/-0)
To merge this branch: bzr merge lp:~cv.clearcorp/openerp-ccorp-addons/6.1-sneldev_magento
Reviewer Review Type Date Requested Status
ClearCorp drivers Pending
Review via email: mp+123579@code.launchpad.net

Description of the change

[ADD] module connector for openerp 6.1 and magento 1.7

To post a comment you must log in.
596. By diana rodriguez <email address hidden>

[FIX] Import customers and contact
[FIX] Export stock from Magento

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'sneldev_magento'
2=== added file 'sneldev_magento/__init__.py'
3--- sneldev_magento/__init__.py 1970-01-01 00:00:00 +0000
4+++ sneldev_magento/__init__.py 2012-09-11 15:12:19 +0000
5@@ -0,0 +1,31 @@
6+# -*- encoding: utf-8 -*-
7+##############################################################################
8+#
9+# Copyright (c) 2009 SnelDev (http://www.sneldev.com) All Rights Reserved.
10+#
11+# WARNING: This program as such is intended to be used by professional
12+# programmers who take the whole responsability of assessing all potential
13+# consequences resulting from its eventual inadequacies and bugs
14+# End users who are looking for a ready-to-use solution with commercial
15+# garantees and support are strongly adviced to contract a Free Software
16+# Service Company
17+#
18+# This program is Free Software; you can redistribute it and/or
19+# modify it under the terms of the GNU General Public License
20+# as published by the Free Software Foundation; either version 2
21+# of the License, or (at your option) any later version.
22+#
23+# This program is distributed in the hope that it will be useful,
24+# but WITHOUT ANY WARRANTY; without even the implied warranty of
25+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26+# GNU General Public License for more details.
27+#
28+# You should have received a copy of the GNU General Public License
29+# along with this program; if not, write to the Free Software
30+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31+#
32+##############################################################################
33+
34+import sneldev_magento
35+import wizard
36+import report
37\ No newline at end of file
38
39=== added file 'sneldev_magento/__openerp__.py'
40--- sneldev_magento/__openerp__.py 1970-01-01 00:00:00 +0000
41+++ sneldev_magento/__openerp__.py 2012-09-11 15:12:19 +0000
42@@ -0,0 +1,52 @@
43+# -*- encoding: utf-8 -*-
44+##############################################################################
45+#
46+# Copyright (c) 2009 SnelDev (http://www.sneldev.com) All Rights Reserved.
47+#
48+# WARNING: This program as such is intended to be used by professional
49+# programmers who take the whole responsability of assessing all potential
50+# consequences resulting from its eventual inadequacies and bugs
51+# End users who are looking for a ready-to-use solution with commercial
52+# garantees and support are strongly adviced to contract a Free Software
53+# Service Company
54+#
55+# This program is Free Software; you can redistribute it and/or
56+# modify it under the terms of the GNU General Public License
57+# as published by the Free Software Foundation; either version 2
58+# of the License, or (at your option) any later version.
59+#
60+# This program is distributed in the hope that it will be useful,
61+# but WITHOUT ANY WARRANTY; without even the implied warranty of
62+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63+# GNU General Public License for more details.
64+#
65+# You should have received a copy of the GNU General Public License
66+# along with this program; if not, write to the Free Software
67+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
68+#
69+##############################################################################
70+{
71+ "name" : "Magento-OpenERP Interface",
72+ "version" : "0.9.2.6",
73+ "author" : "SnelDev",
74+ "category" : "Interfaces/CMS & eCommerce",
75+ "website" : "http://www.sneldev.com/",
76+ "depends" : ["product", "stock", "sale", "account", "account_analytic_default"],
77+ "description": "Magento-OpenERP Interface from SnelDev (info@sneldev.com)\n\nExternal contributors:\n\tArnold Ligtvoet (arnold@birp.nl)",
78+ "init_xml" : [],
79+ "icon" : "icon.png",
80+ "demo_xml" : [],
81+ "update_xml" : ['security/ir.model.access.csv',
82+ 'wizard/sneldev_magento_categories_import.xml',
83+ 'wizard/sneldev_magento_orders_import.xml',
84+ 'wizard/sneldev_magento_products_import.xml',
85+ 'wizard/sneldev_magento_customers_import.xml',
86+ 'wizard/sneldev_magento_stock_init.xml',
87+ 'wizard/sneldev_magento_products_export.xml',
88+ 'wizard/sneldev_magento_stock_export.xml',
89+ 'wizard/sneldev_magento_sync_start.xml',
90+ 'wizard/sneldev_magento_sync_stop.xml',
91+ 'sneldev_magento_view.xml'],
92+ "active": False,
93+ "installable": True
94+}
95
96=== added file 'sneldev_magento/common_tools.py'
97--- sneldev_magento/common_tools.py 1970-01-01 00:00:00 +0000
98+++ sneldev_magento/common_tools.py 2012-09-11 15:12:19 +0000
99@@ -0,0 +1,116 @@
100+#!/usr/bin/env python
101+# -*- encoding: utf-8 -*-
102+##############################################################################
103+#
104+# Copyright (c) 2009 SnelDev (http://www.sneldev.com) All Rights Reserved.
105+#
106+# WARNING: This program as such is intended to be used by professional
107+# programmers who take the whole responsability of assessing all potential
108+# consequences resulting from its eventual inadequacies and bugs
109+# End users who are looking for a ready-to-use solution with commercial
110+# garantees and support are strongly adviced to contract a Free Software
111+# Service Company
112+#
113+# This program is Free Software; you can redistribute it and/or
114+# modify it under the terms of the GNU General Public License
115+# as published by the Free Software Foundation; either version 2
116+# of the License, or (at your option) any later version.
117+#
118+# This program is distributed in the hope that it will be useful,
119+# but WITHOUT ANY WARRANTY; without even the implied warranty of
120+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
121+# GNU General Public License for more details.
122+#
123+# You should have received a copy of the GNU General Public License
124+# along with this program; if not, write to the Free Software
125+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
126+#
127+##############################################################################
128+
129+import sys
130+import traceback
131+import wizard
132+import pooler
133+import os
134+import xmlrpclib
135+from xmlrpclib import ServerProxy, Error
136+from mx import DateTime
137+import datetime
138+import threading
139+
140+#Globals for syncrhonisation
141+export_lock=threading.Lock();
142+export_running=False;
143+
144+#Thread safe version of export_running
145+def export_is_running():
146+ global export_running
147+
148+ retVal=False
149+ export_lock.acquire()
150+ if (export_running == False):
151+ export_running=True
152+ retVal=False
153+ else:
154+ retVal=True
155+ export_lock.release()
156+ return retVal
157+
158+def set_export_finished():
159+ global export_running
160+ export_running=False
161+
162+def magento_connect(self, cr, uid):
163+ try:
164+ ids = self.pool.get('sneldev.magento').search(cr, uid, [])
165+ export = self.pool.get('sneldev.magento').browse(cr, uid, [ids[0]])
166+ server_address = export[0]['url']
167+ if not server_address[-1:] == '/':
168+ server_address = server_address + "/"
169+ server_address = server_address + "index.php/api/xmlrpc/?wsdl"
170+ server = ServerProxy(server_address)
171+ session = server.login(export[0]['api_user'], export[0]['api_pwd'])
172+ return [True, server, session]
173+ except:
174+ traceback.print_exc()
175+ return [False, sys.exc_info()[0], False]
176+
177+def to_proper_uni( text):
178+ return text.encode('iso-8859-1', 'replace')
179+
180+def to_uni( text ):
181+ return unicode(text, 'iso-8859-1')
182+
183+class sneldev_log:
184+ _logfile = None
185+ _logs = False
186+
187+ def __init__(self, filename):
188+ try:
189+ self._logfile = open('/var/log/openerp/'+filename , 'a')
190+ except:
191+ # Oops
192+ self._logfile = False
193+
194+ def define(self, logs, cr, uid):
195+ self._logs = logs
196+ self._cr = cr
197+ self._uid = uid
198+
199+ def append(self, log_line):
200+ try:
201+ log_line = unicode(log_line).encode('iso-8859-1', 'replace')
202+ except:
203+ pass
204+
205+ log_line = str(datetime.datetime.now()).split('.',1)[0] + " " + log_line + "\n"
206+ if (self._logfile):
207+ self._logfile.write(log_line)
208+ self._logfile.flush()
209+
210+ if (self._logs):
211+ self._logs.create(self._cr, self._uid, {'text': log_line})
212+
213+ def print_traceback(self):
214+ traceback.print_exc(file=self._logfile)
215+ self._logfile.flush()
216\ No newline at end of file
217
218=== added directory 'sneldev_magento/i18n'
219=== added file 'sneldev_magento/i18n/es_CR.po'
220--- sneldev_magento/i18n/es_CR.po 1970-01-01 00:00:00 +0000
221+++ sneldev_magento/i18n/es_CR.po 2012-09-11 15:12:19 +0000
222@@ -0,0 +1,439 @@
223+# Translation of OpenERP Server.
224+# This file contains the translation of the following modules:
225+# * sneldev_magento
226+#
227+msgid ""
228+msgstr ""
229+"Project-Id-Version: OpenERP Server 6.1\n"
230+"Report-Msgid-Bugs-To: \n"
231+"POT-Creation-Date: 2012-08-20 16:14+0000\n"
232+"PO-Revision-Date: 2012-08-20 16:14+0000\n"
233+"Last-Translator: <>\n"
234+"Language-Team: \n"
235+"MIME-Version: 1.0\n"
236+"Content-Type: text/plain; charset=UTF-8\n"
237+"Content-Transfer-Encoding: \n"
238+"Plural-Forms: \n"
239+
240+#. module: sneldev_magento
241+#: sql_constraint:sale.order:0
242+msgid "Order Reference must be unique per Company!"
243+msgstr "¡La referencia de la compra debe ser única por compañía!"
244+
245+#. module: sneldev_magento
246+#: model:ir.actions.act_window,name:sneldev_magento.action_magento_form
247+msgid "Magento"
248+msgstr "Magento"
249+
250+#. module: sneldev_magento
251+#: view:sneldev.stock.export:0
252+msgid "This wizard will export stock to Magento."
253+msgstr "Esta opción exportará las existencias a Magento."
254+
255+#. module: sneldev_magento
256+#: field:sneldev.magento,inital_stock_location:0
257+msgid "Location for stock initialization"
258+msgstr "Localización para la inicialización de existencias"
259+
260+#. module: sneldev_magento
261+#: view:sneldev.customers.import:0
262+msgid "This wizard will import customers from Magento."
263+msgstr "Este asistente importará los clientes desde Magento ."
264+
265+#. module: sneldev_magento
266+#: field:sneldev.magento,import_credit_memos:0
267+msgid "Import credit memos after importing orders"
268+msgstr "Importar notas de crédito después de importar las órdenes"
269+
270+#. module: sneldev_magento
271+#: model:ir.actions.act_window,name:sneldev_magento.action_sneldev_products_import
272+msgid "Import Products"
273+msgstr "Importar productos"
274+
275+#. module: sneldev_magento
276+#: model:ir.actions.act_window,name:sneldev_magento.action_sneldev_orders_import
277+msgid "Import Orders"
278+msgstr "Importar órdenes"
279+
280+#. module: sneldev_magento
281+#: view:sneldev.sync.stop:0
282+msgid "You will now stop the automatic synchronization."
283+msgstr "Se detendrá ahora la sincronización automática."
284+
285+#. module: sneldev_magento
286+#: field:product.category,modified:0
287+#: field:product.product,modified:0
288+msgid "Modified since last synchronization"
289+msgstr "Modificado desde la última sincronización"
290+
291+#. module: sneldev_magento
292+#: field:sneldev.magento,api_pwd:0
293+msgid "API Password"
294+msgstr "Contraseña API"
295+
296+#. module: sneldev_magento
297+#: field:product.product,qty_magento:0
298+msgid "Magento Stock"
299+msgstr "Existencias en Magento"
300+
301+#. module: sneldev_magento
302+#: constraint:sneldev.magento:0
303+msgid "Only one website supported at this time."
304+msgstr "Sólo un sitio web es compatible en este momento."
305+
306+#. module: sneldev_magento
307+#: view:sneldev.orders.import:0
308+msgid "This wizard will import orders from Magento. It will first import categories and products."
309+msgstr "Este asistente importará las órdenes de Magento. En primer lugar, se importarán las categorías y productos."
310+
311+#. module: sneldev_magento
312+#: field:product.product,export_to_magento:0
313+#: field:res.partner,export_to_magento:0
314+msgid "Export to Magento"
315+msgstr "Exportar a Magento"
316+
317+#. module: sneldev_magento
318+#: view:sneldev.categories.import:0
319+#: view:sneldev.customers.import:0
320+#: view:sneldev.orders.import:0
321+#: view:sneldev.products.import:0
322+msgid "Import"
323+msgstr "Importar"
324+
325+#. module: sneldev_magento
326+#: model:ir.actions.act_window,name:sneldev_magento.action_sneldev_stock_init
327+#: view:sneldev.stock.init:0
328+msgid "Initialize stock"
329+msgstr "Initializar existencias"
330+
331+#. module: sneldev_magento
332+#: view:sneldev.products.export:0
333+msgid "Export products"
334+msgstr "Exportar productos"
335+
336+#. module: sneldev_magento
337+#: view:sneldev.magento:0
338+msgid "Automatic Synchronization Settings"
339+msgstr "Configuración de la sincronización automática"
340+
341+#. module: sneldev_magento
342+#: model:ir.actions.act_window,name:sneldev_magento.action_sneldev_categories_import
343+msgid "Compute Categories"
344+msgstr "Calcular categorías"
345+
346+#. module: sneldev_magento
347+#: model:ir.actions.act_window,name:sneldev_magento.action_sneldev_customers_import
348+#: model:ir.model,name:sneldev_magento.model_sneldev_customers_import
349+#: view:sneldev.customers.import:0
350+msgid "Import customers"
351+msgstr "Importar clientes"
352+
353+#. module: sneldev_magento
354+#: model:ir.model,name:sneldev_magento.model_product_product
355+msgid "Product"
356+msgstr "Producto"
357+
358+#. module: sneldev_magento
359+#: model:ir.model,name:sneldev_magento.model_product_category
360+msgid "Product Category"
361+msgstr "Categoría de producto"
362+
363+#. module: sneldev_magento
364+#: field:sneldev.magento,auto_import_credit_memos:0
365+msgid "Automatic credit memos import"
366+msgstr "Importar automáticamente notas de crédito"
367+
368+#. module: sneldev_magento
369+#: field:product.category,magento_id:0
370+#: field:product.product,magento_id:0
371+#: field:res.partner,magento_id:0
372+#: field:sale.order,magento_id:0
373+msgid "Magento ID"
374+msgstr "Magento ID"
375+
376+#. module: sneldev_magento
377+#: view:sneldev.products.import:0
378+msgid "This wizard will import products from Magento. It will first import categories."
379+msgstr "Este asistente importará productos de Magento. En primer lugar, va a importar categorías."
380+
381+#. module: sneldev_magento
382+#: view:sneldev.categories.import:0
383+msgid "This wizard will import categories from Magento."
384+msgstr "Este asistente importará categorías de Magento."
385+
386+#. module: sneldev_magento
387+#: field:sneldev.magento,auto_invoice_open:0
388+msgid "Imported invoices automatically goes to Open state"
389+msgstr "Facturas importadas pasarán automáticamente a estado abierto"
390+
391+#. module: sneldev_magento
392+#: field:sneldev.magento,auto_import_orders:0
393+msgid "Automatic orders import"
394+msgstr "Importar órdenes automáticamente"
395+
396+#. module: sneldev_magento
397+#: view:sneldev.stock.init:0
398+msgid "This wizard will create an inventory from Magento stock. This will remove all current stock information in OpenERP !"
399+msgstr "Este asistente creará un inventario de las existencias de Magento. Esto eliminará toda la información actual de las existencias en OpenERP!"
400+
401+#. module: sneldev_magento
402+#: field:sneldev.magento,auto_export_stock:0
403+msgid "Automatic stock export"
404+msgstr "Exportar existencias automáticamente"
405+
406+#. module: sneldev_magento
407+#: field:sneldev.magento,sync_script_pid:0
408+msgid "PID of Sync Script"
409+msgstr "PID del script Sync"
410+
411+#. module: sneldev_magento
412+#: field:sneldev.magento,sync_sleep:0
413+msgid "Time between synchronizations"
414+msgstr "Tiempo entre sincronizaciones"
415+
416+#. module: sneldev_magento
417+#: view:sneldev.sync.start:0
418+msgid "You will now start the automatic synchronization."
419+msgstr "Ahora se iniciará la sincronización automática."
420+
421+#. module: sneldev_magento
422+#: model:ir.model,name:sneldev_magento.model_sneldev_orders_import
423+#: model:ir.model,name:sneldev_magento.model_sneldev_products_import
424+#: view:sneldev.orders.import:0
425+msgid "Import orders"
426+msgstr "Importar órdenes"
427+
428+#. module: sneldev_magento
429+#: model:ir.model,name:sneldev_magento.model_sneldev_categories_import
430+#: view:sneldev.categories.import:0
431+msgid "Import categories"
432+msgstr "Importar categorías"
433+
434+#. module: sneldev_magento
435+#: model:ir.model,name:sneldev_magento.model_sneldev_products_export
436+msgid "Export orders"
437+msgstr "Exportar órdenes"
438+
439+#. module: sneldev_magento
440+#: model:ir.actions.act_window,name:sneldev_magento.action_sneldev_products_export
441+msgid "Export Products"
442+msgstr "Exportar Productos"
443+
444+#. module: sneldev_magento
445+#: field:sneldev.magento,last_imported_category_timestamp:0
446+msgid "Timestamp of latest imported category"
447+msgstr "Fecha y hora de la última categoría importada"
448+
449+#. module: sneldev_magento
450+#: model:ir.actions.act_window,name:sneldev_magento.action_sneldev_sync_start
451+#: model:ir.model,name:sneldev_magento.model_sneldev_sync_start
452+#: view:sneldev.sync.start:0
453+msgid "Start Synchronization"
454+msgstr "Iniciar sincronización"
455+
456+#. module: sneldev_magento
457+#: model:ir.model,name:sneldev_magento.model_sneldev_stock_export
458+#: view:sneldev.stock.export:0
459+msgid "Export stock"
460+msgstr "Exportar existencias"
461+
462+#. module: sneldev_magento
463+#: field:sneldev.magento,default_category:0
464+msgid "Default category for imported products"
465+msgstr "Categoría por defecto para productos importados"
466+
467+#. module: sneldev_magento
468+#: field:sneldev.magento,name:0
469+msgid "Name"
470+msgstr "Nombre"
471+
472+#. module: sneldev_magento
473+#: field:sneldev.magento,sync_status:0
474+msgid "Synchronisation status"
475+msgstr "Estado de la sincronización"
476+
477+#. module: sneldev_magento
478+#: field:sneldev.magento,api_user:0
479+msgid "API User"
480+msgstr "Usuario API"
481+
482+#. module: sneldev_magento
483+#: view:sneldev.magento:0
484+msgid "Initial Inventory"
485+msgstr "Inventario inicial"
486+
487+#. module: sneldev_magento
488+#: view:sneldev.products.export:0
489+msgid "This wizard will export products to Magento. It will first export categories."
490+msgstr "Este asistente exportar productos a Magento. En primer lugar, se exportará categorías."
491+
492+#. module: sneldev_magento
493+#: model:ir.model,name:sneldev_magento.model_sneldev_magento
494+msgid "Magento website infos"
495+msgstr "Magento website infos"
496+
497+#. module: sneldev_magento
498+#: model:ir.model,name:sneldev_magento.model_sneldev_stock_init
499+msgid "Initialize stock from Magento"
500+msgstr "Inicializar existencias desde Magento"
501+
502+#. module: sneldev_magento
503+#: view:sneldev.magento:0
504+msgid "Product Import Settings"
505+msgstr "Configuración de importación de productos"
506+
507+#. module: sneldev_magento
508+#: field:sneldev.magento,last_imported_product_timestamp:0
509+msgid "Timestamp of latest imported product"
510+msgstr "Fecha y hora del último producto importado"
511+
512+#. module: sneldev_magento
513+#: code:addons/sneldev_magento/sneldev_magento.py:819
514+#, python-format
515+msgid "Error"
516+msgstr "Error"
517+
518+#. module: sneldev_magento
519+#: view:sneldev.sync.stop:0
520+msgid "Stop"
521+msgstr "Alto"
522+
523+#. module: sneldev_magento
524+#: field:sneldev.magento,auto_invoice_paid:0
525+msgid "Imported invoices automatically goes to Paid state"
526+msgstr "Facturas importados automáticamente pasa al estado Pagado"
527+
528+#. module: sneldev_magento
529+#: field:sneldev.magento,payment_journal:0
530+msgid "Payment Journal"
531+msgstr "Pago del diario"
532+
533+#. module: sneldev_magento
534+#: field:sneldev.magento,shipping_product:0
535+msgid "Shipping Product"
536+msgstr "Envío del producto"
537+
538+#. module: sneldev_magento
539+#: model:ir.actions.act_window,name:sneldev_magento.action_sneldev_stock_export
540+msgid "Export Stock"
541+msgstr "Exportar existencias"
542+
543+#. module: sneldev_magento
544+#: model:ir.actions.act_window,name:sneldev_magento.action_sneldev_sync_stop
545+#: model:ir.model,name:sneldev_magento.model_sneldev_sync_stop
546+#: view:sneldev.sync.stop:0
547+msgid "Stop Synchronization"
548+msgstr "Detener sincronización"
549+
550+#. module: sneldev_magento
551+#: model:ir.ui.menu,name:sneldev_magento.menu_magento_form
552+#: view:sneldev.magento:0
553+msgid "Magento Settings"
554+msgstr "Configuración"
555+
556+#. module: sneldev_magento
557+#: field:sneldev.magento,auto_import_products:0
558+msgid "Automatic products import"
559+msgstr "Importación de productos automáticamente"
560+
561+#. module: sneldev_magento
562+#: field:sneldev.magento,auto_script_path:0
563+msgid "Syncronization Script Path"
564+msgstr "Ruta del script de sincronización"
565+
566+#. module: sneldev_magento
567+#: field:sneldev.magento,auto_export_products:0
568+msgid "Automatic products export"
569+msgstr "Exportar productos automáticamente"
570+
571+#. module: sneldev_magento
572+#: view:sneldev.stock.init:0
573+#: view:sneldev.sync.start:0
574+msgid "Start"
575+msgstr "Inicio"
576+
577+#. module: sneldev_magento
578+#: field:sneldev.magento,last_imported_invoice_timestamp:0
579+msgid "Timestamp of latest imported invoice"
580+msgstr "Fecha y hora de la última importación de facturas"
581+
582+#. module: sneldev_magento
583+#: view:sneldev.products.import:0
584+msgid "Import products"
585+msgstr "Importar productos"
586+
587+#. module: sneldev_magento
588+#: view:sneldev.magento:0
589+msgid "Magento website"
590+msgstr "Sitio web de Magento"
591+
592+#. module: sneldev_magento
593+#: constraint:product.category:0
594+msgid "Error ! You cannot create recursive categories."
595+msgstr "¡Error! No puede crear categorías recursivas"
596+
597+#. module: sneldev_magento
598+#: field:sneldev.magento,magento_root_cat_id:0
599+msgid "Magento Root category ID"
600+msgstr "Magento Root category ID"
601+
602+#. module: sneldev_magento
603+#: field:sneldev.magento,last_creditmemo_id:0
604+msgid "Last imported credit memo"
605+msgstr "Última importación de notas de crédito"
606+
607+#. module: sneldev_magento
608+#: view:sneldev.magento:0
609+msgid "Orders Import Settings"
610+msgstr "Configuración de importación de órdenes"
611+
612+#. module: sneldev_magento
613+#: code:addons/sneldev_magento/sneldev_magento.py:819
614+#, python-format
615+msgid "Import already running"
616+msgstr "La importación ya se está ejecutando"
617+
618+#. module: sneldev_magento
619+#: constraint:product.product:0
620+msgid "Error: Invalid ean code"
621+msgstr "Error: Código EAN erróneo"
622+
623+#. module: sneldev_magento
624+#: view:sneldev.products.export:0
625+#: view:sneldev.stock.export:0
626+msgid "Export"
627+msgstr "Exportar"
628+
629+#. module: sneldev_magento
630+#: field:sneldev.magento,last_invoice_id:0
631+msgid "Last imported sale order"
632+msgstr "Úlitma orden de compra importada"
633+
634+#. module: sneldev_magento
635+#: model:ir.model,name:sneldev_magento.model_res_partner
636+msgid "Partner"
637+msgstr "Empresa"
638+
639+#. module: sneldev_magento
640+#: view:sneldev.categories.import:0
641+#: view:sneldev.customers.import:0
642+#: view:sneldev.orders.import:0
643+#: view:sneldev.products.export:0
644+#: view:sneldev.products.import:0
645+#: view:sneldev.stock.export:0
646+#: view:sneldev.stock.init:0
647+#: view:sneldev.sync.start:0
648+#: view:sneldev.sync.stop:0
649+msgid "Cancel"
650+msgstr "Cancelar"
651+
652+#. module: sneldev_magento
653+#: field:sneldev.magento,url:0
654+msgid "Magento base URL"
655+msgstr "URL de la tienda de Magento"
656+
657+#. module: sneldev_magento
658+#: model:ir.model,name:sneldev_magento.model_sale_order
659+msgid "Sales Order"
660+msgstr "Pedido de venta"
661+
662
663=== added directory 'sneldev_magento/security'
664=== added file 'sneldev_magento/security/ir.model.access.csv'
665--- sneldev_magento/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
666+++ sneldev_magento/security/ir.model.access.csv 2012-09-11 15:12:19 +0000
667@@ -0,0 +1,2 @@
668+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
669+"access_sneldev_magento","Magento Settings","model_sneldev_magento","base.group_user",1,0,0,0
670
671=== added file 'sneldev_magento/sneldev_magento.py'
672--- sneldev_magento/sneldev_magento.py 1970-01-01 00:00:00 +0000
673+++ sneldev_magento/sneldev_magento.py 2012-09-11 15:12:19 +0000
674@@ -0,0 +1,1528 @@
675+#!/usr/bin/env python
676+# -*- encoding: utf-8 -*-
677+##############################################################################
678+#
679+# Copyright (c) 2009 SnelDev (http://www.sneldev.com) All Rights Reserved.
680+#
681+# WARNING: This program as such is intended to be used by professional
682+# programmers who take the whole responsability of assessing all potential
683+# consequences resulting from its eventual inadequacies and bugs
684+# End users who are looking for a ready-to-use solution with commercial
685+# garantees and support are strongly adviced to contract a Free Software
686+# Service Company
687+#
688+# This program is Free Software; you can redistribute it and/or
689+# modify it under the terms of the GNU General Public License
690+# as published by the Free Software Foundation; either version 2
691+# of the License, or (at your option) any later version.
692+#
693+# This program is distributed in the hope that it will be useful,
694+# but WITHOUT ANY WARRANTY; without even the implied warranty of
695+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
696+# GNU General Public License for more details.
697+#
698+# You should have received a copy of the GNU General Public License
699+# along with this program; if not, write to the Free Software
700+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
701+#
702+##############################################################################
703+
704+from osv import fields,osv
705+from mx import DateTime
706+import netsvc
707+import tools
708+import pooler
709+import time
710+import datetime
711+import math
712+import os
713+import traceback
714+from common_tools import *
715+import traceback
716+from pprint import pprint
717+
718+from tools.translate import _
719+
720+log = sneldev_log("magento_export.log");
721+
722+class sneldev_magento(osv.osv):
723+ _name = 'sneldev.magento'
724+ _description = 'Magento website infos'
725+ _columns = {
726+ 'name': fields.char('Name', size=128),
727+ 'url': fields.char('Magento base URL', size=128),
728+ 'api_user': fields.char('API User', size=64),
729+ 'api_pwd': fields.char('API Password', size=64),
730+ 'auto_export_stock': fields.boolean('Automatic stock export'),
731+ 'auto_export_products': fields.boolean('Automatic products export'),
732+ 'auto_import_products': fields.boolean('Automatic products import'),
733+ 'auto_import_orders': fields.boolean('Automatic orders import'),
734+ 'auto_import_credit_memos': fields.boolean('Automatic credit memos import'),
735+ 'auto_script_path': fields.char('Syncronization Script Path', size=256),
736+ 'sync_sleep': fields.integer('Time between synchronizations'),
737+ 'sync_script_pid': fields.integer('PID of Sync Script'),
738+ 'sync_status': fields.char('Synchronisation status', size=128),
739+ 'shipping_product': fields.many2one('product.product', 'Shipping Product', required=True, change_default=True),
740+ 'default_category': fields.many2one('product.category', 'Default category for imported products', required=True, change_default=True),
741+ 'magento_root_cat_id': fields.integer('Magento Root category ID'),
742+ 'last_imported_product_timestamp': fields.char('Timestamp of latest imported product', size=128),
743+ 'last_imported_category_timestamp': fields.char('Timestamp of latest imported category', size=128),
744+ 'last_imported_invoice_timestamp': fields.char('Timestamp of latest imported invoice', size=128),
745+ 'payment_journal': fields.many2one('account.journal', 'Payment Journal'),
746+ 'last_invoice_id': fields.integer('Last imported sale order'),
747+ 'last_creditmemo_id': fields.integer('Last imported credit memo'),
748+ 'auto_invoice_open': fields.boolean('Imported invoices automatically goes to Open state'),
749+ 'auto_invoice_paid': fields.boolean('Imported invoices automatically goes to Paid state'),
750+ 'inital_stock_location': fields.many2one('stock.location', 'Location for stock initialization'),
751+ 'import_credit_memos': fields.boolean('Import credit memos after importing orders'),
752+ }
753+
754+ _defaults = {
755+ 'auto_export_stock': lambda *a: False,
756+ 'auto_export_products': lambda *a: False,
757+ 'auto_import_products': lambda *a: False,
758+ 'auto_import_orders': lambda *a: False,
759+ 'auto_import_credit_memos': lambda *a: False,
760+ 'sync_sleep': lambda *a: 300,
761+ 'sync_script_pid': lambda *a: -1,
762+ 'last_creditmemo_id' : lambda *a: -1,
763+ 'last_invoice_id': lambda *a: -1,
764+ 'sync_status': lambda *a: 'Idle',
765+ 'last_imported_invoice_timestamp': lambda *a: '2011-01-01',
766+ 'magento_root_cat_id': lambda *a: -1,
767+ 'auto_invoice_open': lambda *a: False,
768+ 'auto_invoice_paid': lambda *a: False,
769+ }
770+
771+ def _unique(self, cr, uid, ids):
772+ res = self.pool.get('sneldev.magento').search(cr, uid,[])
773+ if len(res) > 1 :
774+ return False
775+ else :
776+ return True
777+
778+ _constraints = [
779+ (_unique, 'Only one website supported at this time.', [])
780+ ]
781+
782+
783+ ##################################################################
784+ # Common functions
785+ ##################################################################
786+ def get_magento_params(self, cr, uid):
787+ try:
788+ website_ids = self.pool.get('sneldev.magento').search(cr, uid, [])
789+ magento_params = self.pool.get('sneldev.magento').browse(cr, uid, [website_ids[0]])
790+ return magento_params
791+ except:
792+ log.append('Cannot find Magento shop')
793+ raise osv.except_osv(_('Error !'), _('Cannot find Magento shop'))
794+
795+ ##################################################################
796+ # Scheduler
797+ ##################################################################
798+ def get_params(self, cr, uid):
799+ try:
800+ website_ids = self.pool.get('sneldev.magento').search(cr, uid, [])
801+ magento_params = self.pool.get('sneldev.magento').get_magento_params(cr, uid)
802+ return {
803+ 'sync_sleep': magento_params[0].sync_sleep,
804+ 'auto_export_stock': magento_params[0].auto_export_stock,
805+ 'auto_export_products': magento_params[0].auto_export_products,
806+ 'auto_export_partners': magento_params[0].auto_export_partners,
807+ 'auto_import_products': magento_params[0].auto_import_products,
808+ 'auto_import_orders': magento_params[0].auto_import_orders,
809+ 'auto_import_partners':magento_params[0].auto_import_partners,
810+ 'auto_import_credit_memos': magento_params[0].auto_import_credit_memos,
811+ 'sync_script_pid': magento_params[0].sync_script_pid,
812+ }
813+ except:
814+ return -1
815+
816+ def set_status(self, cr, uid, status):
817+ ids = self.pool.get('sneldev.magento').search(cr, uid, [])
818+ self.pool.get('sneldev.magento').write(cr, uid, ids[0], {'sync_status': str(status)})
819+ return 0
820+
821+ def set_pid(self, cr, uid, pid):
822+ ids = self.pool.get('sneldev.magento').search(cr, uid, [])
823+ self.pool.get('sneldev.magento').write(cr, uid, ids[0], {'sync_script_pid': pid})
824+ return 0
825+
826+ def sync_start(self, cr, uid):
827+ try:
828+ log.append('===== Sync start')
829+ website_ids = self.pool.get('sneldev.magento').search(cr, uid, [])
830+ magento_params = self.pool.get('sneldev.magento').get_magento_params(cr, uid)
831+ if (magento_params[0].auto_script_path):
832+ pid = os.spawnl(os.P_NOWAIT, magento_params[0].auto_script_path)
833+ else:
834+ log.append('Script not found in scheduler loop')
835+ raise osv.except_osv(_('Error !'), _('Script not found in scheduler loop'))
836+ except:
837+ log.append('Unknown error in scheduler loop')
838+ raise osv.except_osv(_('Error !'), _('Unknown error in scheduler loop'))
839+ return 0
840+
841+ def sync_stop(self, cr, uid):
842+ log.append('===== Sync stop')
843+ ids = self.pool.get('sneldev.magento').search(cr, uid, [])
844+ self.pool.get('sneldev.magento').write(cr, uid, ids[0], {'sync_script_pid': -1})
845+
846+ ##################################################################
847+ # Categories export
848+ ##################################################################
849+ def export_categories(self, cr, uid):
850+ log.define(self.pool.get('sneldev.logs'), cr, uid)
851+ if (export_is_running() == False):
852+ try:
853+ log.append('===== Category export')
854+ website_ids = self.pool.get('sneldev.magento').search(cr, uid, [])
855+ magento_params = self.pool.get('sneldev.magento').get_magento_params(cr, uid)
856+ [status, server, session] = magento_connect(self, cr, uid)
857+ if not status:
858+ log.append('Cannot connect ' + str(server))
859+ set_export_finished()
860+ return -1
861+ cat_ids = self.pool.get('product.category').search(cr, uid, [('modified', '=', 'True')])
862+ cats = self.pool.get('product.category').browse(cr, uid, cat_ids)
863+ except:
864+ set_export_finished()
865+ return -1
866+
867+ for cat in cats:
868+ try:
869+ log.append('Category: ' + cat.name)
870+ if cat.magento_id == -1:
871+ log.append('New')
872+ category_data = {
873+ 'name': cat.name,
874+ 'is_active': 1,
875+ 'available_sort_by': 'name,price',
876+ 'default_sort_by': 'price',
877+ 'include_in_menu': False,
878+ }
879+ log.append("Parent : " + str(cat.parent_id.magento_id))
880+ magento_id = server.call(session, 'category.create', [1, category_data])
881+ self.pool.get('product.category').write(cr, uid, cat.id, {'magento_id': magento_id, 'modified': False})
882+ if cat.parent_id.magento_id and (cat.parent_id.magento_id != -1):
883+ server.call(session, 'category.move', [magento_id, cat.parent_id.magento_id])
884+ elif magento_params[0].magento_root_cat_id != -1:
885+ server.call(session, 'category.move', [magento_id, magento_params[0].magento_root_cat_id])
886+ log.append(magento_id)
887+ else:
888+ log.append('Old')
889+ log.append(cat.magento_id)
890+ category_data = {
891+ 'name': cat.name,
892+ 'available_sort_by': 'name,price',
893+ }
894+ server.call(session, 'category.update', [cat.magento_id, category_data])
895+ if cat.parent_id.magento_id and (cat.parent_id.magento_id != -1):
896+ server.call(session, 'category.move', [cat.magento_id, cat.parent_id.magento_id])
897+ self.pool.get('product.category').write(cr, uid, cat.id, {'modified': False})
898+ log.append('Done')
899+ except:
900+ log.append('Error')
901+ log.print_traceback()
902+ log.append('-----')
903+ set_export_finished()
904+ return 0
905+ log.append('Export already running')
906+ raise osv.except_osv(_('Error !'), _('Export already running'))
907+ return -1
908+
909+
910+ ##################################################################
911+ # Products export
912+ ##################################################################
913+ def export_products(self, cr, uid):
914+ log.define(self.pool.get('sneldev.logs'), cr, uid)
915+ if (export_is_running() == False):
916+ log.append('===== Product export')
917+ [status, server, session] = magento_connect(self, cr, uid)
918+ if not status:
919+ log.append('Cannot connect ' + str(server))
920+ set_export_finished()
921+ return -1
922+ prod_ids = self.pool.get('product.product').search(cr, uid, [('modified', '=', 'True')])
923+ prods = self.pool.get('product.product').browse(cr, uid, prod_ids)
924+ for prod in prods:
925+ try:
926+ log.append('Product: ' + prod.name)
927+ if prod.code and prod.export_to_magento:
928+ attribute_sets = server.call(session, 'product_attribute_set.list');
929+ product_data = {
930+ 'status': True,
931+ 'name': prod.name,
932+ 'sku': prod.code,
933+ }
934+ if prod.list_price:
935+ product_data['price'] = str(prod.list_price)
936+ if prod.weight:
937+ product_data['weight'] = str(prod.weight)
938+ if prod.magento_id == -1:
939+ log.append('New')
940+ magento_id = server.call(session, 'catalog_product.create', ['simple', attribute_sets[0]['set_id'], prod.code, product_data]);
941+ self.pool.get('product.product').write(cr, uid, prod.id, {'magento_id': magento_id, 'modified': False})
942+ log.append(magento_id)
943+ if not prod.categ_id.magento_id == -1:
944+ server.call(session, 'category.assignProduct', [prod.categ_id.magento_id, magento_id]);
945+ else:
946+ log.append('Old')
947+ server.call(session, 'catalog_product.update', [prod.magento_id, product_data]);
948+ self.pool.get('product.product').write(cr, uid, prod.id, {'modified': False})
949+ log.append('Done')
950+ else:
951+ log.append('Not set for export or no valid code')
952+ self.pool.get('product.product').write(cr, uid, prod.id, {'modified': False})
953+ except:
954+ log.append('Error')
955+ log.print_traceback()
956+ log.append('-----')
957+ set_export_finished()
958+ return 0
959+ log.append('Export already running')
960+ raise osv.except_osv(_('Error !'), _('Export already running'))
961+ return -1
962+
963+ ##################################################################
964+ # Stock export
965+ ##################################################################
966+ def export_stock(self, cr, uid):
967+ log.define(self.pool.get('sneldev.logs'), cr, uid)
968+ if (export_is_running() == False):
969+ log.append('===== Stock export')
970+ [status, server, session] = magento_connect(self, cr, uid)
971+ if not status:
972+ log.append('Cannot connect ' + str(server))
973+ set_export_finished()
974+ return -1
975+ prod_ids = self.pool.get('product.product').search(cr, uid, [('magento_id', '!=', -1)])
976+ prods = self.pool.get('product.product').browse(cr, uid, prod_ids)
977+
978+ sku_list = []
979+ for prod in prods:
980+ sku_list.append(prod.code)
981+ res = server.call(session, 'product_stock.list', [sku_list])
982+ magento_stock = {}
983+ for magento_prod in res:
984+ magento_stock[unicode(magento_prod['sku'])] = magento_prod['qty']
985+
986+ for i in range(0, len(prod_ids)):
987+ try:
988+ try:
989+ if float(prods[i]['qty_magento']) != float(magento_stock[prods[i]['code']]):
990+ entry = [prods[i]['code'], {'qty': prods[i]['qty_magento'], 'is_in_stock': 1}]
991+ server.call(session,'product_stock.update', entry)
992+ log.append(entry)
993+ log.append('-----')
994+ except:
995+ log.append('Creating new stock entry')
996+ entry = [prods[i]['code'], {'qty': prods[i]['qty_magento'], 'is_in_stock': 1}]
997+ server.call(session,'product_stock.update', entry)
998+ log.append(entry)
999+ log.append('-----')
1000+ except:
1001+ log.append('ERROR : ' + prods[i]['code'])
1002+ log.print_traceback()
1003+ log.append('-----')
1004+ raise osv.except_osv(_('Error !'), _('Error with product import'))
1005+ set_export_finished()
1006+ return 0
1007+
1008+ log.append('Export already running')
1009+ raise osv.except_osv(_('Error !'), _('Export already running'))
1010+
1011+ return -1
1012+
1013+
1014+ ##################################################################
1015+ # Update customer
1016+ ##################################################################
1017+ def update_customer(self, cr, uid, infos):
1018+ try:
1019+ infos['customer_is_guest']
1020+ except:
1021+ infos['customer_is_guest'] = '0'
1022+
1023+ if infos['customer_is_guest'] == '1':
1024+ infos['customer_id'] = '0'
1025+
1026+ erp_customer = { 'magento_id' : infos['customer_id'],
1027+ 'name' : infos['firstname'] + ' ' + infos['lastname'],
1028+ #'email' : infos['email'],
1029+ 'customer' : True,
1030+ 'supplier' : False}
1031+
1032+ log.append('\tUpdating customer ' + infos['firstname'] + ' ' + infos['lastname'])
1033+ new_shipping_address = infos['shipping_address']
1034+ new_billing_address = infos['billing_address']
1035+
1036+ # check to see if customer is guest, if so always create
1037+ if infos['customer_is_guest'] == '1':
1038+ cust_ids = []
1039+ else:
1040+ cust_ids = self.pool.get('res.partner').search(cr, uid, [('magento_id', '=', erp_customer['magento_id'])])
1041+
1042+ if cust_ids == []:
1043+ cust_ids = [self.pool.get('res.partner').create(cr, uid, erp_customer)]
1044+ log.append("\t\tCustomer not found in OpenErp -> creation")
1045+ else:
1046+ self.pool.get('res.partner').write(cr, uid, [cust_ids[0]], erp_customer )
1047+ log.append("\t\tCustomer exists in OpenErp -> updating its info")
1048+
1049+ if cust_ids == []:
1050+ log.append("\t\tError! Customer not found and creation failed !!!")
1051+ return [None , None, None]
1052+
1053+ # Billing country
1054+ try:
1055+ new_billing_address_country = self.pool.get('res.country').name_search(cr, uid, new_billing_address['country_id'])[0][0]
1056+ except:
1057+ new_country = { 'name': new_billing_address['country_id'],
1058+ 'code': new_billing_address['country_id']}
1059+ new_billing_address_country = self.pool.get('res.country').create(cr, uid, new_country)
1060+
1061+ new_billing_address['street'] = new_billing_address['street'] + "\n "
1062+ new_billing_address['street'] = new_billing_address['street'].split('\n')
1063+ erp_contact_billing = { 'partner_id' : cust_ids[0],
1064+ 'type' : 'invoice',
1065+ 'name': new_billing_address['firstname'] + ' ' + new_billing_address['lastname'],
1066+ 'street' : new_billing_address['street'][0],
1067+ 'street2' : new_billing_address['street'][1],
1068+ 'zip' : new_billing_address['postcode'],
1069+ 'city' : new_billing_address['city'],
1070+ 'country_id' : new_billing_address_country,
1071+ 'phone' : new_billing_address['telephone']}
1072+ # Shipping country
1073+ try:
1074+ new_shipping_address_country = self.pool.get('res.country').name_search(cr, uid, new_shipping_address['country_id'])[0][0]
1075+ except:
1076+ new_country = { 'name': new_shipping_address['country_id'],
1077+ 'code': new_shipping_address['country_id']}
1078+ new_shipping_address_country = self.pool.get('res.country').create(cr, uid, new_country)
1079+
1080+ new_shipping_address['street'] = new_shipping_address['street'] + "\n "
1081+ new_shipping_address['street'] = new_shipping_address['street'].split('\n')
1082+ erp_contact_shipping = { 'partner_id' : cust_ids[0],
1083+ 'type' : 'delivery',
1084+ 'name': new_shipping_address['firstname'] + ' ' + new_shipping_address['lastname'],
1085+ 'street' : new_shipping_address['street'][0],
1086+ 'street2' : new_shipping_address['street'][1],
1087+ 'zip' : new_shipping_address['postcode'],
1088+ 'city' : new_shipping_address['city'],
1089+ 'country_id' : new_shipping_address_country,
1090+ 'phone' : new_shipping_address['telephone']}
1091+
1092+ contact_ids = self.pool.get('res.partner.address').search(cr, uid, [('partner_id', '=', cust_ids[0])])
1093+ if (contact_ids != []):
1094+ contacts = self.pool.get('res.partner.address').browse(cr, uid, contact_ids)
1095+ else:
1096+ contacts = []
1097+
1098+ new_contact_ids = []
1099+
1100+ for new_contact in [erp_contact_billing , erp_contact_shipping]:
1101+ if (new_contact == {}):
1102+ continue
1103+ skip_contact_creation = False
1104+ i = 0
1105+ for _contact in contacts:
1106+ is_contact_same = True
1107+ contact={}
1108+ #for key in ['first_name','last_name','street','street2','zip','country_id','city','phone']:
1109+ for key in ['name','street','street2','zip','country_id','city','phone']:
1110+ if (key == 'country_id'):
1111+ if (_contact[key]['id'] != new_contact[key]):
1112+ is_contact_same = False
1113+ break
1114+ else:
1115+ if (_contact[key] != new_contact[key]):
1116+ is_contact_same = False
1117+ break
1118+
1119+ if (is_contact_same == True):
1120+ skip_contact_creation = True
1121+ log.append("\t\tSkipping creation of " + new_contact['type'] + " contact address (already existing)")
1122+ break
1123+
1124+ i = i + 1
1125+
1126+ if (skip_contact_creation == False):
1127+ log.append("\t\tCreation of new " + new_contact['type'] + " contact address")
1128+ id_address = self.pool.get('res.partner.address').create(cr, uid, new_contact)
1129+ new_contact_ids.append(id_address)
1130+ else:
1131+ new_contact_ids.append(contact_ids[i])
1132+
1133+ return { 'id' : cust_ids[0] , 'billing_id' : new_contact_ids[0] , 'shipping_id' : new_contact_ids[1] }
1134+
1135+ ##################################################################
1136+ # Get Tax ID
1137+ ##################################################################
1138+ def get_tax_id(self, cr, uid, rate_percent):
1139+ rate = float(rate_percent) / 100
1140+ int_rate = float(rate_percent) * 10
1141+ low_rate = math.floor(int_rate + 0.5) / 1000
1142+ high_rate = math.ceil(int_rate - 0.5) / 1000
1143+ list_tax_ids = self.pool.get('account.tax').search(cr, uid, [('amount' , "<=", high_rate),('amount' , ">=", low_rate), ('type_tax_use', "=", 'sale')])
1144+ if (list_tax_ids == []):
1145+ # Need to add flag for TVA creation
1146+ log.append('\t\t\tNo sale tax found with rate ' + str(rate) + '/' + str(low_rate) + '/' + str(high_rate))
1147+ tax = {'name': ('Tax ' + str(rate*100) + '%'),
1148+ 'amount': rate,
1149+ 'type': 'percent',
1150+ 'description': ('Magento' + str(rate*100) + '%'),
1151+ 'price_include': False,
1152+ 'type_tax_use': 'sale',
1153+ }
1154+ tax_id = self.pool.get('account.tax').create(cr, uid, tax)
1155+ log.append('\t\t\tCreated tax ' + str(tax_id))
1156+ else:
1157+ #should add a check in case of sevral taxes
1158+ tax_id = list_tax_ids[0]
1159+ return tax_id
1160+
1161+ ##################################################################
1162+ # Categories import
1163+ ##################################################################
1164+ def _create_category(self, cr, uid, info_category, magento_params):
1165+ category = { 'magento_id' : info_category['category_id'],
1166+ 'name' : info_category['name'],
1167+ 'modified' : False,
1168+ }
1169+ log.append('Updating category ' + info_category['category_id'] + ' ' + info_category['name'])
1170+ if (info_category['level'] != '0'):
1171+ if info_category['parent_id'] == str(magento_params[0].magento_root_cat_id):
1172+ category['parent_id'] = False
1173+ log.append("Parent is root")
1174+ else:
1175+ cat_ids = self.pool.get('product.category').search(cr, uid, [('magento_id', '=', info_category['parent_id'])])
1176+ if cat_ids == []:
1177+ log.append("Parent not found")
1178+ else:
1179+ category['parent_id'] = cat_ids[0]
1180+ log.append("Parent found " + str(cat_ids[0]))
1181+ else:
1182+ log.append("Root found " + str(category['magento_id']))
1183+ self.pool.get('sneldev.magento').write(cr, uid, [magento_params[0].id], {'magento_root_cat_id':category['magento_id']})
1184+
1185+ cat_ids = self.pool.get('product.category').search(cr, uid, [('magento_id', '=', category['magento_id'])])
1186+ if cat_ids == []:
1187+ cat_ids = [self.pool.get('product.category').create(cr, uid, category)]
1188+ log.append("\tCategory not found in OpenErp -> creation")
1189+ else:
1190+ self.pool.get('product.category').write(cr, uid, [cat_ids[0]], category)
1191+ log.append("\tCategory exists in OpenErp -> updating its info")
1192+ if cat_ids == []:
1193+ log.append("\tError! Category not found and creation failed !!!")
1194+ return -1
1195+ log.append('-------------')
1196+ for child in info_category['children']:
1197+ self.pool.get('sneldev.magento')._create_category(cr, uid, child, magento_params)
1198+ return 0
1199+
1200+ def import_categories(self, cr, uid):
1201+ log.define(self.pool.get('sneldev.logs'), cr, uid)
1202+ if (export_is_running() == False):
1203+ try:
1204+ log.append('===== Categories import')
1205+ start_timestamp = str(DateTime.utc())
1206+ website_ids = self.pool.get('sneldev.magento').search(cr, uid, [])
1207+ magento_params = self.pool.get('sneldev.magento').get_magento_params(cr, uid)
1208+ # Get latest categories from Magento
1209+ self.pool = pooler.get_pool(cr.dbname)
1210+ [status, server, session] = magento_connect(self, cr, uid)
1211+ if not status:
1212+ log.append('Cannot connect ' + str(server))
1213+ set_export_finished()
1214+ return -1
1215+ log.append('Logged in to Magento')
1216+ info_category = server.call(session, 'category.tree',[])
1217+ self.pool.get('sneldev.magento')._create_category(cr, uid, info_category, magento_params)
1218+ self.pool.get('sneldev.magento').write(cr, uid, [website_ids[0]], {'last_imported_category_timestamp':start_timestamp})
1219+ except:
1220+ log.append('Cannot get categories, check Magento web user config')
1221+ log.print_traceback()
1222+ set_export_finished()
1223+ return -1
1224+ set_export_finished()
1225+ log.append('Import done')
1226+ return 0
1227+ log.append('Import already running')
1228+ raise osv.except_osv(_('Error !'), _('Import already running'))
1229+ return -1
1230+
1231+ ##################################################################
1232+ # Product import
1233+ ##################################################################
1234+ def import_products(self, cr, uid):
1235+ log.define(self.pool.get('sneldev.logs'), cr, uid)
1236+ if (export_is_running() == False):
1237+ try:
1238+ log.append('===== Products import')
1239+ start_timestamp = str(DateTime.utc())
1240+ website_ids = self.pool.get('sneldev.magento').search(cr, uid, [])
1241+ magento_params = self.pool.get('sneldev.magento').get_magento_params(cr, uid)
1242+ # Last update
1243+ last_import = magento_params[0].last_imported_product_timestamp
1244+ # Get latest products from Magento
1245+ self.pool = pooler.get_pool(cr.dbname)
1246+ [status, server, session] = magento_connect(self, cr, uid)
1247+ if not status:
1248+ log.append('Cannot connect ' + str(server))
1249+ set_export_finished()
1250+ return -1
1251+ attribute_sets = server.call(session, 'product_attribute_set.list');
1252+ log.append('Logged in to Magento')
1253+ except:
1254+ set_export_finished()
1255+ raise osv.except_osv(_('Error !'), _('Connection error!!!'))
1256+ return -1
1257+
1258+ increment = 300
1259+ index = 1
1260+ while True:
1261+ stop = index + increment - 1
1262+ log.append('Products ID from ' + str(index) + ' to ' + str(stop))
1263+ all_products = server.call(session, 'product.list',[{'product_id': {'from': str(index), 'to': str(stop)}}])
1264+ if last_import:
1265+ products = server.call(session, 'product.list',[{'updated_at': {'from': last_import}, 'product_id': {'from': str(index), 'to': str(stop)}}])
1266+ log.append('Last import: ' + last_import)
1267+ else:
1268+ products = all_products
1269+ index = stop + 1
1270+
1271+ for prod in products:
1272+ try:
1273+ log.append('Loading product ' + to_proper_uni(prod['sku']))
1274+ info_product = server.call(session, 'product.info',[prod['product_id']])
1275+ product = { 'magento_id' : info_product['product_id'],
1276+ 'name' : info_product['name'],
1277+ 'default_code' : prod['sku'],
1278+ 'modified' : False,
1279+ 'export_to_magento': True,
1280+ }
1281+ try:
1282+ product['list_price'] = info_product['price']
1283+ except:
1284+ product['list_price'] = '0.00'
1285+ try:
1286+ product['weight'] = info_product['weight']
1287+ except:
1288+ product['weight'] = '0.00'
1289+
1290+
1291+ if info_product.has_key('category_ids'):
1292+ magento_cat_ids = info_product['category_ids']
1293+ elif info_product.has_key('categories'):
1294+ magento_cat_ids = info_product['categories']
1295+ else:
1296+ magento_cat_ids = []
1297+ if magento_cat_ids:
1298+ cat_ids = self.pool.get('product.category').search(cr, uid, [('magento_id', '=', magento_cat_ids[0])])
1299+ if (cat_ids[0]):
1300+ product['categ_id'] = cat_ids[0]
1301+ else:
1302+ product['categ_id'] = magento_params[0].default_category.id
1303+ else:
1304+ log.append('Default category')
1305+ product['categ_id'] = magento_params[0].default_category.id
1306+ log.append('Updating product ' + product['default_code'] + ' ' + product['name'])
1307+ prod_ids = self.pool.get('product.product').search(cr, uid, [('magento_id', '=', product['magento_id'])])
1308+ if prod_ids == []:
1309+ prod_ids = [self.pool.get('product.product').create(cr, uid, product)]
1310+ log.append("Product not found in OpenErp -> creation")
1311+ else:
1312+ self.pool.get('product.product').write(cr, uid, [prod_ids[0]], product)
1313+ log.append("Product exists in OpenErp -> updating its info")
1314+
1315+ if prod_ids == []:
1316+ log.append("Error! Product not found and creation failed !!!")
1317+ set_export_finished()
1318+ return -1
1319+ except:
1320+ log.append("Error")
1321+ log.print_traceback()
1322+ raise osv.except_osv(_('Error !'), _('View log'))
1323+
1324+ # If no products we can leave
1325+ if (all_products == []):
1326+ self.pool.get('sneldev.magento').write(cr, uid, [website_ids[0]], {'last_imported_product_timestamp':start_timestamp})
1327+ set_export_finished()
1328+ log.append("Done")
1329+ return 0
1330+ log.append('Import already running')
1331+ raise osv.except_osv(_('Error !'), _('Import already running'))
1332+ return -1
1333+
1334+ ##################################################################
1335+ # Customer import
1336+ ##################################################################
1337+
1338+ def import_customers(self, cr, uid):
1339+ flag = False
1340+ list = []
1341+
1342+ if (export_is_running() == False):
1343+ try:
1344+ start_timestamp = str(DateTime.utc())
1345+ website_ids = self.pool.get('sneldev.magento').search(cr, uid, [])
1346+ magento_params = self.pool.get('sneldev.magento').get_magento_params(cr, uid)
1347+ self.pool = pooler.get_pool(cr.dbname)
1348+ [status, server, session] = magento_connect(self, cr, uid)
1349+ if not status:
1350+ log.append('Cannot connect ' + str(server))
1351+ set_export_finished()
1352+ return -1
1353+ log.append('Logged in to Magento')
1354+ except:
1355+ log.append('Cannot get customers, check Magento web user config')
1356+ log.print_traceback()
1357+ set_export_finished()
1358+ raise osv.except_osv(_('Error !'), _('Cannot get customers, check Magento web user config'))
1359+ return -1
1360+
1361+ customers = server.call(session, 'customer.list')
1362+
1363+ for cust in customers:
1364+ try:
1365+ log.append('Loading customers ' + cust['customer_id'])
1366+ info_cust = server.call(session, 'customer.info',[cust['customer_id']])
1367+
1368+ ##### <<<<< check to see if customer is guest, if so always create >>>>> ######
1369+ try:
1370+ info_cust['customer_is_guest']
1371+ except:
1372+ info_cust['customer_is_guest'] = '0'
1373+
1374+ if info_cust['customer_is_guest'] == '1':
1375+ info_cust['customer_id'] = '0'
1376+
1377+ erp_customer = {
1378+ 'magento_id' : int(info_cust['customer_id']),
1379+ 'name' : info_cust['firstname'] + ' ' + info_cust['lastname'],
1380+ 'email': str(info_cust['email']),
1381+ 'customer' : True,
1382+ 'supplier' : False,
1383+ }
1384+
1385+ if info_cust['customer_is_guest'] == '1':
1386+ cust_ids = []
1387+ else:
1388+ cust_ids = self.pool.get('res.partner').search(cr, uid, [('magento_id', '=', erp_customer['magento_id'])])
1389+
1390+ if cust_ids == []:
1391+ cust_ids = [self.pool.get('res.partner').create(cr, uid, erp_customer)]
1392+ log.append("\t\tCustomer not found in OpenErp -> creation")
1393+ else:
1394+ self.pool.get('res.partner').write(cr, uid, [cust_ids[0]], erp_customer )
1395+ log.append("\t\tCustomer exists in OpenErp -> updating its info")
1396+
1397+ if cust_ids == []:
1398+ log.append("\t\tError! Customer not found and creation failed !!!")
1399+ return [None , None, None]
1400+ ####################################################################################################
1401+
1402+ info_address = server.call(session, 'customer_address.list', [cust['customer_id']])
1403+
1404+ if (info_address != []):
1405+ ########## <<<<<<<CUSTOMERS ADDRESS>>>>>>> ##########################
1406+ list = []
1407+ try:
1408+ info_address = server.call(session, 'customer_address.list', [cust['customer_id']])
1409+
1410+ for address in info_address:
1411+
1412+ try:
1413+ new_address_country = self.pool.get('res.country').name_search(cr, uid, address['country_id'])[0][0]
1414+ except:
1415+ new_country = { 'name': address['country_id'],
1416+ 'code': address['country_id']}
1417+ address = self.pool.get('res.country').create(cr, uid, new_country)
1418+
1419+ address['street'] = address['street'] + "\n "
1420+ address['street'] = address['street'].split('\n')
1421+
1422+ #if the billing and shipping address are the same...
1423+ if address['is_default_shipping'] and address['is_default_billing']:
1424+ flag = True;
1425+ #BILLING
1426+ erp_contact_billing = { 'partner_id' : cust_ids[0],
1427+ 'type':'invoice',
1428+ 'name': address['firstname'] + ' ' + address['lastname'],
1429+ 'street' : address['street'][0],
1430+ 'street2' : address['street'][1],
1431+ 'zip' : address['postcode'],
1432+ 'city' : address['city'],
1433+ 'country_id' : new_address_country,
1434+ 'phone' : address['telephone']}
1435+
1436+ #SHIPPING
1437+ erp_contact_shipping = { 'partner_id' : cust_ids[0],
1438+ 'type':'delivery',
1439+ 'name': address['firstname'] + ' ' + address['lastname'],
1440+ 'street' : address['street'][0],
1441+ 'street2' : address['street'][1],
1442+ 'zip' : address['postcode'],
1443+ 'city' : address['city'],
1444+ 'country_id' : new_address_country,
1445+ 'phone' : address['telephone']}
1446+
1447+ list.append(erp_contact_billing)
1448+ list.append(erp_contact_shipping)
1449+
1450+ #if the billing and shipping address are different ...
1451+ else:
1452+ #Address type (Billing - Shipping)
1453+ if address['is_default_shipping']:
1454+ type = 'delivery'
1455+ elif address['is_default_billing']:
1456+ type ='invoice'
1457+ else:
1458+ type = 'default'
1459+
1460+ erp_contact = { 'partner_id' : cust_ids[0],
1461+ #'type' : 'default',
1462+ 'type':type,
1463+ 'name': address['firstname'] + ' ' + address['lastname'],
1464+ 'street' : address['street'][0],
1465+ 'street2' : address['street'][1],
1466+ 'zip' : address['postcode'],
1467+ 'city' : address['city'],
1468+ 'country_id' : new_address_country,
1469+ 'phone' : address['telephone']}
1470+
1471+ list.append(erp_contact)
1472+
1473+ contact_ids = self.pool.get('res.partner.address').search(cr, uid, [('partner_id', '=', cust_ids[0])])
1474+
1475+ if (contact_ids != []):
1476+ contacts = self.pool.get('res.partner.address').browse(cr, uid, contact_ids)
1477+ else:
1478+ contacts = []
1479+
1480+ new_contact_ids = []
1481+ is_contact_same = False
1482+
1483+ #for new_contact in [erp_contact]:
1484+ for new_contact in list:
1485+ if (new_contact == {}):
1486+ continue
1487+ skip_contact_creation = False
1488+ i = 0
1489+
1490+ for _contact in contacts:
1491+ is_contact_same = True
1492+ contact={}
1493+ for key in ['name','street','street2','zip','country_id','city','phone']:
1494+ if (key == 'country_id'):
1495+ if (_contact[key]['id'] != new_contact[key]):
1496+ is_contact_same = False
1497+ break
1498+ else:
1499+ if (_contact[key] != new_contact[key]):
1500+ is_contact_same = False
1501+ break
1502+
1503+ if (is_contact_same == True):
1504+ skip_contact_creation = True
1505+ log.append("\t\tSkipping creation of " + new_contact['type'] + " contact address (already existing)")
1506+ break
1507+
1508+ i = i + 1
1509+
1510+ if (skip_contact_creation == False):
1511+ log.append("\t\tCreation of new " + new_contact['type'] + " contact address")
1512+ id_address = self.pool.get('res.partner.address').create(cr, uid, new_contact)
1513+ new_contact_ids.append(id_address)
1514+
1515+ if flag is False:
1516+ list.remove(new_contact)
1517+ else:
1518+ new_contact_ids.append(contact_ids[i])
1519+
1520+ except:
1521+ log.append('Cannot get customers, check Magento web user config')
1522+ log.print_traceback()
1523+ set_export_finished()
1524+ raise osv.except_osv(_('Error !'), _('Cannot get customers, check Magento web user config'))
1525+ return -1
1526+
1527+ else:
1528+ contact_ids = self.pool.get('res.partner.address').search(cr, uid, [('partner_id', '=', cust_ids[0])])
1529+
1530+ if (contact_ids == []):
1531+ erp_contact = { 'partner_id' : cust_ids[0],
1532+ 'type' : 'other',
1533+ 'name' : info_cust['firstname'] + ' ' + info_cust['lastname'],
1534+ 'street' : None,
1535+ 'street2' : None,
1536+ 'zip' : None,
1537+ 'city' : None,
1538+ 'country_id' : None,
1539+ 'phone' : None}
1540+ self.pool.get('res.partner.address').create(cr, uid, erp_contact)
1541+
1542+ except:
1543+ log.append('Cannot get customers, check Magento web user config')
1544+ log.print_traceback()
1545+ set_export_finished()
1546+ raise osv.except_osv(_('Error !'), _('Cannot get customers, check Magento web user config'))
1547+
1548+ if (customers == []):
1549+ #self.pool.get('sneldev.magento').write(cr, uid, [website_ids[0]], {'last_imported_product_timestamp':start_timestamp})
1550+ set_export_finished()
1551+ log.append("Done")
1552+ return 0
1553+
1554+ else:
1555+ log.append('Import already running')
1556+ raise osv.except_osv(_('Error'), _('Import already running')% ('error') )
1557+ return -1
1558+
1559+ ##################################################################
1560+ # Initialize OpenERP stock
1561+ ##################################################################
1562+ def init_stock(self, cr, uid):
1563+ log.define(self.pool.get('sneldev.logs'), cr, uid)
1564+ if (export_is_running() == False):
1565+ try:
1566+ log.append('===== Stock init')
1567+ [status, server, session] = magento_connect(self, cr, uid)
1568+ if not status:
1569+ log.append('Cannot connect ' + str(server))
1570+ set_export_finished()
1571+ return -1
1572+ prod_ids = self.pool.get('product.product').search(cr, uid, [('magento_id', '!=', -1)])
1573+ prods = self.pool.get('product.product').browse(cr, uid, prod_ids)
1574+
1575+ sku_list = []
1576+ for prod in prods:
1577+ sku_list.append(prod.code)
1578+ res = server.call(session, 'product_stock.list', [sku_list])
1579+ magento_stock = {}
1580+ for magento_prod in res:
1581+ magento_stock[unicode(magento_prod['sku'])] = magento_prod['qty']
1582+ except:
1583+ log.append('Could not get stock from Magento')
1584+ log.print_traceback()
1585+ log.append('-----')
1586+ raise osv.except_osv(_('Error !'), _('Could not get stock from Magento'))
1587+
1588+ #try:
1589+ magento_params = self.pool.get('sneldev.magento').get_magento_params(cr, uid)
1590+ location_id = magento_params[0].inital_stock_location.id
1591+ inventry_obj = self.pool.get('stock.inventory')
1592+ inventry_line_obj = self.pool.get('stock.inventory.line')
1593+ name = 'Initial Magento Inventory'
1594+ inventory_id = inventry_obj.create(cr , uid, {'name': name})
1595+ log.append('New inventory ' + str(inventory_id) + ' / Location id : ' + str(location_id))
1596+ for prod in prods:
1597+ try:
1598+ log.append('\tAdding line : ' + prod['code'] + ' / ' + magento_stock[prod.code])
1599+ line_data ={
1600+ 'inventory_id' : inventory_id,
1601+ 'product_qty' : magento_stock[prod.code],
1602+ 'location_id' : location_id,
1603+ 'product_id' : prod.id,
1604+ 'product_uom' : prod.uom_id.id,
1605+ }
1606+ inventry_line_obj.create(cr , uid, line_data)
1607+ except:
1608+ log.append('\tSkipping : ' + prod['code'])
1609+ log.print_traceback()
1610+
1611+ inventry_obj.action_confirm(cr, uid, [inventory_id])
1612+ inventry_obj.action_done(cr, uid, [inventory_id])
1613+ #except:
1614+ #log.append('ERROR')
1615+ #log.print_traceback()
1616+ #log.append('-----')
1617+ #raise osv.except_osv(_('Error !'), _('Error, check log files'))
1618+ set_export_finished()
1619+ return 0
1620+
1621+ else:
1622+ log.append('Export already running')
1623+ raise osv.except_osv(_('Error !'), _('Export already running'))
1624+ return -1
1625+
1626+ ##################################################################
1627+ # Orders import
1628+ ##################################################################
1629+ def import_orders(self, cr, uid):
1630+ log.define(self.pool.get('sneldev.logs'), cr, uid)
1631+ wf_service = netsvc.LocalService('workflow')
1632+ if (export_is_running() == False):
1633+ failed_order = False
1634+ try:
1635+ log.append('===== Orders import')
1636+ ids = self.pool.get('sneldev.magento').search(cr, uid, [])
1637+ magento_params = self.pool.get('sneldev.magento').get_magento_params(cr, uid)
1638+
1639+ # Get latest sales orders in Magento
1640+ self.pool = pooler.get_pool(cr.dbname)
1641+ [status, server, session] = magento_connect(self, cr, uid)
1642+ if not status:
1643+ log.append('Cannot connect ' + str(server))
1644+ set_export_finished()
1645+ return -1
1646+ log.append('Logged in to Magento')
1647+ log.append('Last import from ' + magento_params[0].last_imported_invoice_timestamp)
1648+ listinvoices = server.call(session, 'sales_order_invoice.list',[{'updated_at': {'from': magento_params[0].last_imported_invoice_timestamp}}])
1649+# if (magento_params[0].last_invoice_id == -1):
1650+# listinvoices = server.call(session, 'sales_order_invoice.list',[{'updated_at': {'from': '2011-05-01'}}])
1651+# else:
1652+# listinvoices = server.call(session, 'sales_order_invoice.list',[{'updated_at': {'from': '2011-05-01'}}])
1653+# #listinvoices = server.call(session, 'sales_order_invoice.list',[{'entity_id': {'gt': magento_params[0].last_invoice_id}}])
1654+ log.append('Looking for invoives to import')
1655+ log.append("Found " + str(len(listinvoices)) + " new invoice(s) created")
1656+
1657+ orders_magento=[]
1658+ for invoice in listinvoices:
1659+ try:
1660+ log.append("Invoice "+ invoice['increment_id'] + " - Order " + invoice['order_id'] + " - Created " + invoice['created_at'])
1661+ log.append("\tGetting Info invoice " + str(invoice['increment_id']) )
1662+ info_invoice = server.call(session, 'sales_order_invoice.info',[invoice['increment_id']]);
1663+ log.append("\tGetting Info order " + str(invoice['order_id']))
1664+ try:
1665+ info_order = server.call(session, 'sales_order.list', [{'order_id': {'eq': invoice['order_id']}}])
1666+ info_order = info_order[0]
1667+ info_order = server.call(session, 'sales_order.info',[info_order['increment_id']]);
1668+ except:
1669+ info_order = server.call(session, 'sales_order.info',[invoice['order_increment_id']]);
1670+
1671+ name_sales_order = str(info_order['increment_id'])
1672+ name_invoice = str(info_invoice['increment_id'])
1673+ id_orders = self.pool.get('sale.order').search(cr, uid, [('magento_id', '=', info_order['order_id'])])
1674+ if (id_orders != []):
1675+ log.append("\tSales order " + name_sales_order + " already exists in ERP. Skipping")
1676+ continue
1677+
1678+ log.append("\tGetting Info customer " + str(info_order['customer_id']))
1679+ try:
1680+ info_customer = server.call(session, 'customer.info' , [info_order['customer_id'] ])
1681+ except:
1682+ log.append("\t\tCustomer is guest")
1683+ info_customer = {
1684+ 'customer_id' : '0'
1685+ }
1686+ except:
1687+ log.append("\tERROR ! Invoice Skipped")
1688+ log.print_traceback()
1689+ failed_order = True
1690+ continue
1691+
1692+# orders_magento.append( { 'order' : info_order , 'invoice' : info_invoice , 'customer' : info_customer} )
1693+# new_last_invoice_id = magento_params[0].last_invoice_id
1694+#
1695+# # Import orders one by one
1696+# for info in orders_magento:
1697+ try:
1698+# info_customer = info['customer']
1699+# info_order = info['order']
1700+# info_invoice = info['invoice']
1701+# new_last_invoice_id = max(int(new_last_invoice_id) , int(info_invoice["invoice_id"]))
1702+
1703+ pricelist_ids = self.pool.get('product.pricelist').search(cr, uid,[])
1704+
1705+ if (info_order['customer_is_guest'] == '1'):
1706+ info_customer['store_id'] = info_order['store_id']
1707+ info_customer['website_id'] = '1'
1708+ info_customer['email'] = info_order['customer_email']
1709+ info_customer['firstname'] = info_order['billing_address']['firstname']
1710+ info_customer['lastname'] = info_order['billing_address']['lastname']
1711+ info_customer['customer_is_guest'] = '1'
1712+
1713+ info_customer['shipping_address'] = info_order['shipping_address']
1714+ info_customer['billing_address'] = info_order['billing_address']
1715+ erp_customer_info = self.pool.get('sneldev.magento').update_customer(cr, uid, info_customer)
1716+
1717+ try:
1718+ #comments = u"Infos paiement\n"
1719+ comments = ""
1720+ for comment in info_order['status_history']:
1721+ if comment.has_key('comment') and len(comment['comment']) > 0:
1722+ comments = comments + comment['comment'] + u"\n"
1723+ #Adding customer note
1724+ if (info_order.has_key("giftMessage")):
1725+ #comments = comments + u"Infos commande\n"
1726+ comments = comments + info_order["giftMessage"] + u"\n"
1727+ except:
1728+ pass
1729+
1730+ # Creating sales order
1731+ erp_sales_order = { 'name' : name_sales_order,
1732+ 'order_policy' : 'manual',
1733+ 'client_order_ref' : name_invoice,
1734+ 'state' : 'draft',
1735+ 'partner_id' : erp_customer_info['id'],
1736+ 'partner_invoice_id' : erp_customer_info['billing_id'],
1737+ 'partner_order_id' : erp_customer_info['billing_id'],
1738+ 'partner_shipping_id' : erp_customer_info['shipping_id'],
1739+ 'pricelist_id' : pricelist_ids[0],
1740+ 'magento_id' : info_order['order_id'],
1741+ 'date_order' : invoice['created_at'][:10],
1742+ 'note' : comments
1743+ }
1744+ log.append("\tCreation of sales order in OpenErp " + name_sales_order)
1745+ id_order = self.pool.get('sale.order').create(cr, uid, erp_sales_order)
1746+
1747+ # Sale order lines
1748+ missing_products_in_openerp = False
1749+ parents = {}
1750+ for item in info_order['items']:
1751+ if item.has_key('product_type') and (item['product_type'] == 'configurable'):
1752+ parents[item['item_id']] = {
1753+ 'base_price': item['base_price'],
1754+ 'tax_percent': item['tax_percent'],
1755+ }
1756+ log.append("\t\tParent product " + str(item['sku']))
1757+ continue
1758+ if item.has_key('parent_item_id'):
1759+ try:
1760+ item['base_price'] = str(float(item['base_price']) + float(parents[item['parent_item_id']]['base_price']))
1761+ item['tax_percent'] = parents[item['parent_item_id']]['tax_percent']
1762+ except:
1763+ log.append("\t\tNo parent price")
1764+ product_ids = self.pool.get('product.product').search(cr, uid, [('magento_id', '=', item['product_id'])])
1765+ if (product_ids == []):
1766+ log.append("\t\tProduct with magento_id " + str(item['product_id']) + " not found in ERP - skipping")
1767+ missing_products_in_openerp = True
1768+ continue
1769+ product_id = product_ids[0]
1770+ my_product = self.pool.get('product.product').browse(cr, uid, product_id)
1771+ log.append("\t\tCreation of sale order line for qty " + str(item['qty_ordered']) + " product " + my_product['name'])
1772+ try:
1773+ if (item['tax_percent'] != '0.0000'):
1774+ tax_id = self.pool.get('sneldev.magento').get_tax_id(cr, uid, item['tax_percent'])
1775+ if (tax_id == 0):
1776+ raise
1777+ else:
1778+ tax_ids = [[6,0,[tax_id]]]
1779+ else:
1780+ tax_ids = []
1781+ log.append("\t\t\tNo tax " + item['tax_percent'])
1782+ except:
1783+ log.append("\t\t\tError Found unsupported tax rate - skipping tax")
1784+ tax_ids = []
1785+
1786+ erp_sales_order_line = {'order_id' : id_order,
1787+ 'product_id' : product_id,
1788+ 'name' : my_product['name'],
1789+ 'tax_id' : tax_ids,
1790+ 'price_unit' : item['base_price'],
1791+ 'product_uom' : my_product['uom_id']['id'],
1792+ 'product_uom_qty' : item['qty_ordered']
1793+ }
1794+ id_order_line = self.pool.get('sale.order.line').create(cr, uid, erp_sales_order_line)
1795+
1796+ #Shipping costs
1797+ log.append("\t\tCreating shipping costs :" + str(info_order['shipping_amount']))
1798+ try:
1799+ my_shipping = magento_params[0].shipping_product
1800+ try:
1801+ if (info_order['shipping_tax_amount'] != '0.0000'):
1802+ tax_percent = 100 * float(info_order['shipping_tax_amount']) / float(info_order['shipping_amount'])
1803+ tax_id = self.pool.get('sneldev.magento').get_tax_id(cr, uid, tax_percent)
1804+ if (tax_id == 0):
1805+ raise
1806+ else:
1807+ log.append("\t\t\tTax added, id: " + str(tax_id))
1808+ tax_ids = [[6,0,[tax_id]]]
1809+ else:
1810+ tax_ids = []
1811+ except:
1812+ tax_ids = []
1813+ log.append("\t\t\tError Found unsupported tax rate - skipping tax")
1814+
1815+ erp_shipping_line = {
1816+ 'order_id' : id_order,
1817+ 'name': my_shipping['name'],
1818+ 'product_id' : my_shipping['id'],
1819+ 'price_unit':info_order['shipping_amount'],
1820+ 'product_uom': my_shipping['uom_id']['id'],
1821+ 'product_uom_qty' : 1,
1822+ 'tax_id' : tax_ids
1823+ }
1824+ id_order_line = self.pool.get('sale.order.line').create(cr, uid, erp_shipping_line)
1825+ except:
1826+ log.append("\t\t\tNo Shipping costs")
1827+ pass
1828+
1829+ if missing_products_in_openerp:
1830+ log.append("\tMissing products in openERP, leaving in order in draft state")
1831+ failed_order = True
1832+ continue
1833+
1834+ log.append("\tConfirming Sales Order (Draft -> In progress)" )
1835+ wf_service.trg_validate(uid, 'sale.order', id_order, 'order_confirm', cr)
1836+
1837+ # Creation of invoice
1838+ try:
1839+ log.append("\tCreating Invoice")
1840+ self.pool.get('sale.order').manual_invoice(cr, uid, [id_order])
1841+ erp_invoice_id = self.pool.get('sale.order').browse(cr, uid, id_order).invoice_ids[0]['id']
1842+ log.append("\t\tInvoice created : " + str(erp_invoice_id))
1843+ self.pool.get('account.invoice').write(cr,uid,[erp_invoice_id],{ "date_invoice" : invoice['created_at'][:10]})
1844+
1845+ #Promo Code
1846+ erp_invoice_lines = self.pool.get('account.invoice').browse(cr, uid, erp_invoice_id).invoice_line
1847+ for erp_item in erp_invoice_lines:
1848+ erp_product_id = erp_item.product_id['id']
1849+ erp_product_magento_id = erp_item.product_id['magento_id']
1850+
1851+ for item in info_order['items']:
1852+ if (str(item["product_id"])==str(erp_product_magento_id)):
1853+ if (item.has_key('discount_percent') and item["discount_percent"] != '0.0000'):
1854+ log.append('\t\tAppending Discount to line with product magento id '+str(erp_product_magento_id))
1855+ self.pool.get('account.invoice.line').write(cr,uid,[erp_item["id"]],{ "discount" : item["discount_percent"]})
1856+ elif (item.has_key('discount_invoiced') and item['discount_invoiced']!='0.0000'):
1857+ #Managing fixed coupon reduction as a percentage also
1858+ if (item.has_key('row_invoiced') and item['row_invoiced']!='0.0000'):
1859+ discount = float(item['discount_invoiced'])
1860+ total_price = float(item['row_invoiced'])
1861+ discount_percent = discount / total_price * 100.0
1862+ log.append('\t\tAppending Discount '+str(discount_percent)+' to line with product magento id '+str(erp_product_magento_id))
1863+ self.pool.get('account.invoice.line').write(cr,uid,[erp_item["id"]],{ "discount" : discount_percent})
1864+ else:
1865+ log.append("Unsupported Promo Code type!")
1866+ #END MANAGEMENT PROMO CODE
1867+
1868+ #Update Tax Base after promo codes
1869+ self.pool.get('account.invoice').button_reset_taxes(cr,uid,[erp_invoice_id])
1870+
1871+ journal_code = info_order['payment']['method']
1872+ log.append("\t\tPayment method " + journal_code)
1873+ #invoice_from_draft_to_paid(self, cr,uid, erp_invoice_id, info_invoice['created_at'] , name_invoice, journal_code ,context)
1874+
1875+ except:
1876+ log.append("\t\tError: Unable to create invoice")
1877+ log.print_traceback()
1878+ continue
1879+
1880+ # Invoice from Draft to Open
1881+ try:
1882+ if magento_params[0].auto_invoice_open:
1883+ log.append("\tConfirming Invoice (Draft -> Open)")
1884+ wf_service.trg_validate(uid, 'account.invoice', erp_invoice_id, 'invoice_open', cr)
1885+ else:
1886+ log.append("\tInvoice left in Draft")
1887+ except:
1888+ log.append("\tError: Unable to move invoice to Open status")
1889+ traceback.print_exc(file=sys.stdout)
1890+ continue
1891+
1892+ # Invoice from Open to Paid
1893+ try:
1894+ if magento_params[0].auto_invoice_paid and magento_params[0].auto_invoice_open:
1895+ if magento_params[0].payment_journal:
1896+ journal = magento_params[0].payment_journal
1897+ log.append("\tPaying Invoice (Open -> Paid)")
1898+ else:
1899+ log.append("\tNo journal set - Skipping invoice payment")
1900+ continue
1901+
1902+ #from wizard_pay_invoice.py
1903+ log.append("\tGetting account period")
1904+ ids = self.pool.get('account.period').find(cr, uid, None)
1905+ period_id = False
1906+ if len(ids):
1907+ period_id = ids[0]
1908+ else:
1909+ log.append("\t\tNO ACCOUNT PERIOD AVAILABLE - SKIP invoice payment")
1910+ raise
1911+
1912+ invoice = self.pool.get('account.invoice').browse(cr, uid, erp_invoice_id)
1913+
1914+ # Need to change partner
1915+ log.append("\tMake customer reconcilable")
1916+ data = {'reconcile': True}
1917+ self.pool.get('account.account').write(cr, uid, [invoice.partner_id.property_account_receivable.id], data)
1918+
1919+ amount = invoice.amount_total
1920+ ecriture_name = 'Order payment'
1921+
1922+ writeoff_account_id = False
1923+ writeoff_journal_id = False
1924+ context={'date_p': info_invoice['created_at'], 'comment':''}
1925+ acc_id = journal.default_credit_account_id and journal.default_credit_account_id.id
1926+ if acc_id == []:
1927+ log.append("\t\tERROR The journal does not have default credit - debit account")
1928+ else:
1929+ self.pool.get('account.invoice').pay_and_reconcile(cr,uid,[erp_invoice_id], amount, acc_id, period_id, journal.id, writeoff_account_id, period_id, writeoff_journal_id, context, ecriture_name)
1930+ log.append("\t\tPayment done")
1931+ else:
1932+ log.append("\tInvoice not moved to Paid state")
1933+ except:
1934+ pass
1935+
1936+ except:
1937+ log.append("Invoice/Order skipped")
1938+ failed_order = True
1939+ log.print_traceback()
1940+ if not failed_order:
1941+ today = str(datetime.date.today())
1942+ log.append("Update last import : " + today)
1943+ self.pool.get('sneldev.magento').write(cr, uid, [magento_params[0].id], {'last_imported_invoice_timestamp':today})
1944+# log.append("Last invoice_id " + str(new_last_invoice_id))
1945+# self.pool.get('sneldev.magento').write(cr, uid, [magento_params[0].id], {'last_invoice_id':new_last_invoice_id})
1946+ set_export_finished()
1947+ log.append("Done")
1948+ return 0
1949+ except:
1950+ log.append('Cannot import orders')
1951+ traceback.print_exc(file=sys.stdout)
1952+ set_export_finished()
1953+ return -1
1954+ log.append('Import already running')
1955+ return -1
1956+
1957+ def _invoice_from_draft_to_paid(self, cr, uid, erp_invoice_id,invoice_created_at, name_invoice, journal_code):
1958+ log.append("Invoice from draft to Open")
1959+ wf_service = netsvc.LocalService('workflow')
1960+ wf_service.trg_validate(uid, 'account.invoice', erp_invoice_id, 'invoice_open', cr)
1961+
1962+ # Invoice from Open to Paid
1963+ log.append("Invoice from Open to Paid")
1964+
1965+ #from wizard_pay_invoice.py
1966+ log.append("-getting account.period")
1967+ ids = self.pool.get('account.period').find(cr, uid, None)
1968+ period_id = False
1969+ if len(ids):
1970+ period_id = ids[0]
1971+ else:
1972+ log.append("NO ACCOUNT PERIOD AVAILABLE - SKIP invoice payment")
1973+ return False
1974+
1975+ invoice = self.pool.get('account.invoice').browse(cr, uid, erp_invoice_id)
1976+ # Need to change partner
1977+ log.append("Make customer reconcilable")
1978+ data = {'reconcile': True}
1979+ self.pool.get('account.account').write(cr, uid, [invoice.partner_id.property_account_receivable.id], data)
1980+
1981+ amount = invoice.amount_total
1982+ ecriture_name = 'Paiement effectue'
1983+ journals = self.pool.get('account.journal').search(cr, uid, [("code" , "=" , journal_code)])
1984+ if len(journals) > 0:
1985+ journal_id = journals[0]
1986+ else:
1987+ self.pool.get('account.journal').create_payment_methods(cr, uid, [])
1988+ journals = self.pool.get('account.journal').search(cr, uid, [("code" , "=" , journal_code)])
1989+ journal_id = journals[0]
1990+ journal = self.pool.get('account.journal').browse(cr, uid, journal_id, None)
1991+
1992+ writeoff_account_id = False
1993+ writeoff_journal_id = False
1994+ context={'date_p': invoice_created_at, 'comment':''}
1995+ acc_id = journal.default_credit_account_id and journal.default_credit_account_id.id
1996+ if acc_id == []:
1997+ log.append("The journal does not have default credit - debit account")
1998+ else:
1999+ self.pool.get('account.invoice').pay_and_reconcile(cr,uid,[erp_invoice_id], amount, acc_id, period_id, journal_id, writeoff_account_id, period_id, writeoff_journal_id, context, ecriture_name)
2000+ log.append("Payment done")
2001+
2002+ return True
2003+
2004+
2005+ ##################################################################
2006+ # Credit memo import
2007+ ##################################################################
2008+ def import_credit_memos(self, cr, uid):
2009+ log.define(self.pool.get('sneldev.logs'), cr, uid)
2010+ wf_service = netsvc.LocalService('workflow')
2011+ if (export_is_running() == False):
2012+ try:
2013+ log.append('===== Credit memo import')
2014+ ids = self.pool.get('sneldev.magento').search(cr, uid, [])
2015+ magento_params = self.pool.get('sneldev.magento').get_magento_params(cr, uid)
2016+ if not magento_params[0].import_credit_memos:
2017+ log.append('Credit memo import disabled')
2018+ set_export_finished()
2019+ return 0
2020+
2021+ self.pool = pooler.get_pool(cr.dbname)
2022+ [status, server, session] = magento_connect(self, cr, uid)
2023+ if not status:
2024+ log.append('Cannot connect ' + str(server))
2025+ set_export_finished()
2026+ return -1
2027+ log.append('Logged in to Magento')
2028+
2029+ #get all credit memos from Magento created after last sync date
2030+ listcreditmemos = server.call(session,'creditmemoapi.list', [{'entity_id': {'gt': magento_params[0].last_creditmemo_id}}])
2031+
2032+ credits_memos = []
2033+ log.append("Found " + str(len(listcreditmemos)) + " credit memos: id - order_id - created_at")
2034+ for cm in listcreditmemos:
2035+ log.append("credit_memo:" + cm['increment_id'] + " - " + cm['order_id'] + " - " + cm['created_at'])
2036+ credits_memos.append({ 'creditmemo_id' : cm['creditmemo_id'],'increment_id' : cm['increment_id'] , 'order_id' : cm['order_id'] , 'created_at' : cm['created_at']} )
2037+
2038+ new_last_creditmemo_id = magento_params[0].last_creditmemo_id
2039+ except:
2040+ log.append('Could not retreive Magento credit memos. Did you install the Magento module ?')
2041+ set_export_finished()
2042+ return -1
2043+
2044+ try:
2045+ for credits_memo in credits_memos:
2046+ #get invoice id whose origine is the related order
2047+ new_last_creditmemo_id = max(int(new_last_creditmemo_id), int(credits_memo['creditmemo_id']))
2048+ id_orders_related_to_cm = self.pool.get('sale.order').search(cr, uid, [('magento_id', '=', credits_memo['order_id'])])
2049+ if (id_orders_related_to_cm == []):
2050+ #Skip
2051+ log.append("\tOrignial Magento order was not imported :" + str(credits_memo['order_id']))
2052+ continue
2053+
2054+ order = self.pool.get('sale.order').browse(cr, uid, id_orders_related_to_cm[0], None)
2055+ id_invoices_related_to_order = self.pool.get('account.invoice').search(cr, uid, [('origin', '=', order['name'])])
2056+ if (id_invoices_related_to_order == []):
2057+ #Skip
2058+ log.append("\tNo invoice with origin:" + order['name'])
2059+ continue
2060+
2061+ # Current date and period
2062+ period_ids = self.pool.get('account.period').find(cr, uid, credits_memo['created_at'][:10])
2063+ date = credits_memo['created_at'][:10]
2064+ description = 'credit memo' + str(credits_memo['increment_id'])
2065+ period = period_ids[0]
2066+ log.append("\tCreate Refund Invoice for invoice " + str(id_invoices_related_to_order))
2067+ for inv in self.pool.get('account.invoice').browse(cr, uid, id_invoices_related_to_order):
2068+ journal_id = inv.journal_id.id
2069+ refund_id = self.pool.get('account.invoice').refund(cr, uid, [inv.id], date, period, description, journal_id)
2070+ #self.pool.get('account.invoice').write(cr, uid, [refund_id], {'date_due': date, 'check_total': inv.check_total})
2071+ self.pool.get('account.invoice').button_compute(cr, uid, refund_id)
2072+ # Get payment method from original invoice
2073+ invoices_related_to_order = self.pool.get('account.invoice').browse(cr, uid, id_invoices_related_to_order)
2074+ if len(invoices_related_to_order[0].payment_ids) > 0:
2075+ journal_code = invoices_related_to_order[0].payment_ids[0].journal_id.code
2076+ else:
2077+ journal_code = 'checkmo'
2078+ #self.pool.get('sneldev.magento')._invoice_from_draft_to_paid(cr,uid, id,credits_memo['created_at'], str(credits_memo['increment_id']), journal_code)
2079+
2080+ # Return products
2081+ log.append("\tReturning goods for " + invoices_related_to_order[0].origin)
2082+ package_ids = self.pool.get('stock.picking').search(cr, uid, [('origin', '=', invoices_related_to_order[0].origin), ('type', '=', 'out')])
2083+ date_cur = time.strftime('%Y-%m-%d %H:%M:%S')
2084+ for package_id in package_ids:
2085+ package = self.pool.get('stock.picking').browse(cr, uid, package_id)
2086+ if not package.state == 'done':
2087+ wf_service.trg_validate(uid, 'stock.picking', package_id, 'button_cancel', cr)
2088+ else:
2089+ log.append("\tReturning ID " + str(package_id))
2090+ new_picking = self.pool.get('stock.picking').copy(cr, uid, package_id, {'name': package.name, 'state':'draft', 'type':'in', 'move_lines':[], 'date':date_cur})
2091+ log.append("\tNew ID " + str(new_picking))
2092+ for move in package.move_lines:
2093+ new_move = self.pool.get('stock.move').copy(cr, uid, move.id, {
2094+ 'picking_id':new_picking,
2095+ 'state':'draft',
2096+ 'date':date_cur,
2097+ 'location_id':move.location_dest_id.id,
2098+ 'location_dest_id':move.location_id.id,
2099+ 'date_planned':date_cur,})
2100+ self.pool.get('stock.picking').draft_validate(cr, uid, [new_picking], [])
2101+
2102+ log.append("Last credit memo id " + str(new_last_creditmemo_id))
2103+ self.pool.get('sneldev.magento').write(cr, uid, [magento_params[0].id], {'last_creditmemo_id':new_last_creditmemo_id})
2104+ set_export_finished()
2105+ return 0
2106+ except:
2107+ log.print_traceback()
2108+ set_export_finished()
2109+ return -1
2110+ log.append('Import already running')
2111+ return 0
2112+
2113+sneldev_magento()
2114+
2115+# Categories
2116+class product_category(osv.osv):
2117+ _name = 'product.category'
2118+ _inherit ='product.category'
2119+ _columns = {
2120+ 'modified':fields.boolean('Modified since last synchronization'),
2121+ 'magento_id':fields.integer('Magento ID'),
2122+ }
2123+
2124+ _defaults = {
2125+ 'modified': lambda *a: True,
2126+ 'magento_id': lambda *a: -1,
2127+ }
2128+
2129+ def write(self, cr, uid, ids, vals, context={}):
2130+ if not vals.has_key('modified'):
2131+ vals['modified'] = True
2132+ return super(product_category, self).write(cr, uid, ids, vals, context)
2133+
2134+product_category()
2135+
2136+# Products
2137+class product_product(osv.osv):
2138+ _name = 'product.product'
2139+ _inherit ='product.product'
2140+
2141+ def _product_qty_magento(self, cr, uid, ids, name, arg, context={}):
2142+ qtys = super(product_product, self).read(cr,uid,ids,['qty_available','virtual_available','incoming_qty','outgoing_qty'],context)
2143+ magento = {}
2144+ for element in qtys:
2145+ magento[element['id']]=element['virtual_available']-element['incoming_qty']
2146+
2147+ return magento
2148+
2149+ _columns = {
2150+ 'modified':fields.boolean('Modified since last synchronization'),
2151+ 'magento_id':fields.integer('Magento ID'),
2152+ 'qty_magento': fields.function(_product_qty_magento, method=True, type='float', string='Magento Stock'),
2153+ 'export_to_magento': fields.boolean('Export to Magento'),
2154+ }
2155+
2156+ _defaults = {
2157+ 'modified': lambda *a: True,
2158+ 'magento_id': lambda *a: -1,
2159+ 'export_to_magento': lambda *a: False,
2160+ }
2161+
2162+ def write(self, cr, uid, ids, vals, context={}):
2163+ if not vals.has_key('modified'):
2164+ vals['modified'] = True
2165+ return super(product_product, self).write(cr, uid, ids, vals, context)
2166+
2167+product_product()
2168+
2169+# Sale orders
2170+class sale_order(osv.osv):
2171+ _name = "sale.order"
2172+ _inherit = "sale.order"
2173+
2174+ _columns = {
2175+ 'magento_id' : fields.integer('Magento ID')
2176+ }
2177+sale_order()
2178+
2179+# Partner
2180+class res_partner(osv.osv):
2181+ _name = 'res.partner'
2182+ _inherit = 'res.partner'
2183+
2184+ _columns = {
2185+ 'magento_id':fields.integer('Magento ID'),
2186+ 'email':fields.char('Email', size=128),
2187+ 'export_to_magento': fields.boolean('Export to Magento'),
2188+ }
2189+
2190+ _defaults = {
2191+ 'magento_id': lambda *a: -1,
2192+ 'export_to_magento': lambda *a: False,
2193+ }
2194+ """
2195+ def write(self, cr, uid, ids, vals, context={}):
2196+ if not vals.has_key('modified'):
2197+ vals['modified'] = True
2198+ return super(product_product, self).write(cr, uid, ids, vals, context)
2199+ """
2200+res_partner()
2201+
2202+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2203
2204=== added file 'sneldev_magento/sneldev_magento_data.xml'
2205--- sneldev_magento/sneldev_magento_data.xml 1970-01-01 00:00:00 +0000
2206+++ sneldev_magento/sneldev_magento_data.xml 2012-09-11 15:12:19 +0000
2207@@ -0,0 +1,6 @@
2208+<?xml version="1.0"?>
2209+<openerp>
2210+ <data>
2211+
2212+ </data>
2213+</openerp>
2214\ No newline at end of file
2215
2216=== added file 'sneldev_magento/sneldev_magento_view.xml'
2217--- sneldev_magento/sneldev_magento_view.xml 1970-01-01 00:00:00 +0000
2218+++ sneldev_magento/sneldev_magento_view.xml 2012-09-11 15:12:19 +0000
2219@@ -0,0 +1,131 @@
2220+<?xml version="1.0" encoding="UTF-8"?>
2221+<openerp>
2222+ <data>
2223+ <!-- Magento / View -->
2224+ <record model="ir.actions.act_window" id="action_magento_form">
2225+ <field name="name">Magento</field>
2226+ <field name="res_model">sneldev.magento</field>
2227+ <field name="view_mode">tree,form</field>
2228+ </record>
2229+
2230+ <menuitem id="base.menu_magento" name="Magento" web_icon="static/src/img/magento.png" web_icon_hover="static/src/img/magento.png" />
2231+ <menuitem name="Magento Settings" id="menu_magento_form" parent="base.menu_magento" action="action_magento_form" />
2232+
2233+ <menuitem id="base.import_menu_magento" name="Import" parent="base.menu_magento"/>
2234+ <menuitem name="Import categories from Magento" action="action_sneldev_categories_import" parent="base.import_menu_magento" id="base.menu_magento_categories_import" />
2235+ <menuitem name="Import products from Magento" action="action_sneldev_products_import" parent="base.import_menu_magento" id="base.menu_magento_products_import" />
2236+ <menuitem name="Import orders from Magento" action="action_sneldev_orders_import" parent="base.import_menu_magento" id="base.menu_magento_orders_import" />
2237+ <menuitem name="Import customers from Magento" action="action_sneldev_customers_import" parent="base.import_menu_magento" id="base.menu_magento_clients_import" />
2238+
2239+ <menuitem id="base.export_menu_magento" name="Export" parent="base.menu_magento"/>
2240+ <menuitem name="Export categories and products to Magento" action="action_sneldev_products_export" parent="base.export_menu_magento" id="base.menu_magento_products_export" />
2241+ <menuitem name="Export stock to Magento" action="action_sneldev_stock_export" parent="base.export_menu_magento" id="base.menu_magento_stock_export" />
2242+
2243+ <menuitem name="Initialize stock from Magento" action="action_sneldev_stock_init" parent="base.menu_magento" id="base.menu_magento_stock_init" />
2244+ <menuitem name="Start automatic synchronization" action="action_sneldev_sync_start" parent="base.menu_magento" id="base.menu_magento_sync_start" />
2245+ <menuitem name="Stop automatic synchronization" action="action_sneldev_sync_stop" parent="base.menu_magento" id="base.menu_magento_sync_stop" />
2246+
2247+ <record model="ir.ui.view" id="view_magento_form">
2248+ <field name="name">sneldev.magento.form</field>
2249+ <field name="model">sneldev.magento</field>
2250+ <field name="type">form</field>
2251+ <field name="arch" type="xml">
2252+ <form string="Magento website">
2253+ <separator string="Magento Settings" colspan="4" />
2254+ <newline />
2255+ <field name="name" />
2256+ <field name="url" />
2257+ <newline />
2258+ <field name="api_user" />
2259+ <field name="api_pwd" password="True" />
2260+ <separator string="Product Import Settings" colspan="4" />
2261+ <field name="default_category" />
2262+ <separator string="Orders Import Settings" colspan="4" />
2263+ <field name="shipping_product" />
2264+ <field name="payment_journal" />
2265+ <field name="auto_invoice_open" />
2266+ <field name="auto_invoice_paid" />
2267+ <field name="import_credit_memos" />
2268+ <separator string="Automatic Synchronization Settings" colspan="4" />
2269+ <field name="auto_import_products" />
2270+ <field name="auto_export_products" />
2271+ <field name="auto_export_stock" />
2272+ <field name="auto_import_orders" />
2273+ <field name="auto_import_credit_memos" />
2274+ <newline />
2275+ <field name="sync_sleep" />
2276+ <newline />
2277+ <field name="auto_script_path" />
2278+ <separator string="Initial Inventory" colspan="4" />
2279+ <!--This field must be required, because it's necessary to init the stock -->
2280+ <field name="inital_stock_location" attrs="{'required':True}" />
2281+ </form>
2282+ </field>
2283+ </record>
2284+ <record model="ir.ui.view" id="view_magento_tree">
2285+ <field name="name">sneldev.magento.tree</field>
2286+ <field name="model">sneldev.magento</field>
2287+ <field name="type">tree</field>
2288+ <field name="arch" type="xml">
2289+ <tree string="Magento website">
2290+ <field name="name" />
2291+ <field name="url" />
2292+ </tree>
2293+ </field>
2294+ </record>
2295+
2296+ <record model="ir.ui.view" id="product_product_tree_view_inherited">
2297+ <field name="name">product.product.tree.inherit</field>
2298+ <field name="model">product.product</field>
2299+ <field name="type">tree</field>
2300+ <field name="inherit_id" ref="product.product_product_tree_view"/>
2301+ <field name="arch" type="xml">
2302+ <field name="virtual_available" position="after">
2303+ <field name="qty_magento"/>
2304+ </field>
2305+ </field>
2306+ </record>
2307+
2308+ <record model="ir.ui.view" id="product_product_tree_view_inherited">
2309+ <field name="name">product.product.tree.inherit</field>
2310+ <field name="model">product.product</field>
2311+ <field name="type">tree</field>
2312+ <field name="inherit_id" ref="product.product_product_tree_view"/>
2313+ <field name="arch" type="xml">
2314+ <field name="variants" position="after">
2315+ <field name="export_to_magento"/>
2316+ </field>
2317+ </field>
2318+ </record>
2319+
2320+ <record model="ir.ui.view" id="product_normal_stock_form_inherit_inherit">
2321+ <field name="name">product.normal.stock.form.inherit.inherit</field>
2322+ <field name="model">product.product</field>
2323+ <field name="type">form</field>
2324+ <field name="inherit_id" ref="stock.view_normal_property_acc_form"/>
2325+ <field name="arch" type="xml">
2326+ <field name="virtual_available" position="after">
2327+ <field name="qty_magento"/>
2328+ </field>
2329+ </field>
2330+ </record>
2331+
2332+ <record model="ir.ui.view" id="product_normal_form_view_inherited">
2333+ <field name="name">product.normal.form.inherit.inherit</field>
2334+ <field name="model">product.product</field>
2335+ <field name="type">form</field>
2336+ <field name="inherit_id" ref="product.product_normal_form_view"/>
2337+ <field name="arch" type="xml">
2338+ <field name="variants" position="after">
2339+ <field name="export_to_magento"/>
2340+ </field>
2341+ <!-- You need this field to be required for the export to run magento
2342+                     Those products that have no reference (default_code) are not exported -->
2343+ <field name="default_code" position="attributes">
2344+ <attribute name="attrs">{'required':True}</attribute>
2345+ </field>
2346+ </field>
2347+ </record>
2348+
2349+ </data>
2350+</openerp>
2351
2352=== added file 'sneldev_magento/sneldev_magento_wizard.xml'
2353--- sneldev_magento/sneldev_magento_wizard.xml 1970-01-01 00:00:00 +0000
2354+++ sneldev_magento/sneldev_magento_wizard.xml 2012-09-11 15:12:19 +0000
2355@@ -0,0 +1,114 @@
2356+<?xml version="1.0" encoding="utf-8"?>
2357+<openerp>
2358+ <data>
2359+ <menuitem
2360+ id="base.menu_magento"
2361+ name="Magento" />
2362+ <wizard
2363+ string="Export categories and products to Magento"
2364+ model="product.product"
2365+ name="sneldev.products.export"
2366+ id="wizard_sneldev_products_export" />
2367+ <menuitem
2368+ name="Export categories and products to Magento"
2369+ action="wizard_sneldev_products_export"
2370+ type="wizard"
2371+ parent="base.menu_magento"
2372+ id="base.menu_magento_products_export" />
2373+
2374+ <wizard
2375+ string="Export stock to Magento"
2376+ model="product.product"
2377+ name="sneldev.stock.export"
2378+ id="wizard_sneldev_stock_export" />
2379+ <menuitem
2380+ name="Export stock to Magento"
2381+ action="wizard_sneldev_stock_export"
2382+ type="wizard"
2383+ parent="base.menu_magento"
2384+ id="base.menu_magento_stock_export" />
2385+
2386+ <wizard
2387+ string="Import orders and credit memos from Magento"
2388+ model="sale.order"
2389+ name="sneldev.orders.import"
2390+ id="wizard_sneldev_orders_import" />
2391+ <menuitem
2392+ name="Import orders from Magento"
2393+ action="wizard_sneldev_orders_import"
2394+ type="wizard"
2395+ parent="base.menu_magento"
2396+ id="base.menu_magento_orders_import" />
2397+ <wizard
2398+ string="Import categories and products from Magento"
2399+ model="product.product"
2400+ name="sneldev.products.import"
2401+ id="wizard_sneldev_products_import" />
2402+ <menuitem
2403+ name="Import categories and products from Magento"
2404+ action="wizard_sneldev_products_import"
2405+ type="wizard"
2406+ parent="base.menu_magento"
2407+ id="base.menu_magento_products_import" />
2408+
2409+ <wizard
2410+ string="Import categories from Magento"
2411+ model="product.category"
2412+ name="sneldev.categories.import"
2413+ id="wizard_sneldev_categories_import" />
2414+ <menuitem
2415+ name="Import categories from Magento"
2416+ action="wizard_sneldev_categories_import"
2417+ type="wizard"
2418+ parent="base.menu_magento"
2419+ id="base.menu_magento_categories_import" />
2420+
2421+ <wizard
2422+ string="Initialize stock from Magento"
2423+ model="product.product"
2424+ name="sneldev.stock.init"
2425+ id="wizard_sneldev_stock_init" />
2426+ <menuitem
2427+ name="Initialize stock from Magento"
2428+ action="wizard_sneldev_stock_init"
2429+ type="wizard"
2430+ parent="base.menu_magento"
2431+ id="base.menu_magento_stock_init" />
2432+
2433+ <wizard
2434+ string="Start automatic synchronization"
2435+ model="sneldev.magento"
2436+ name="sneldev.sync.start"
2437+ id="wizard_sneldev_sync_start" />
2438+ <menuitem
2439+ name="Start automatic synchronization"
2440+ action="wizard_sneldev_sync_start"
2441+ type="wizard"
2442+ parent="base.menu_magento"
2443+ id="base.menu_magento_sync_start" />
2444+
2445+ <wizard
2446+ string="Stop automatic synchronization"
2447+ model="sneldev.magento"
2448+ name="sneldev.sync.stop"
2449+ id="wizard_sneldev_sync_stop" />
2450+ <menuitem
2451+ name="Stop automatic synchronization"
2452+ action="wizard_sneldev_sync_stop"
2453+ type="wizard"
2454+ parent="base.menu_magento"
2455+ id="base.menu_magento_sync_stop" />
2456+
2457+ <wizard
2458+ string="Import customers from magento"
2459+ model="res.partner"
2460+ name="res.partner"
2461+ id="wizard_sneldev_customers" />
2462+ <menuitem
2463+ name="Import customers from magento"
2464+ action="wizard_sneldev_customers"
2465+ type="wizard"
2466+ parent="base.menu_magento"
2467+ id="base.menu_magento_customers_import" />
2468+ </data>
2469+</openerp>
2470
2471=== added directory 'sneldev_magento/static'
2472=== added directory 'sneldev_magento/static/src'
2473=== added directory 'sneldev_magento/static/src/img'
2474=== added file 'sneldev_magento/static/src/img/icon.png'
2475Binary files sneldev_magento/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and sneldev_magento/static/src/img/icon.png 2012-09-11 15:12:19 +0000 differ
2476=== added file 'sneldev_magento/static/src/img/magento.png'
2477Binary files sneldev_magento/static/src/img/magento.png 1970-01-01 00:00:00 +0000 and sneldev_magento/static/src/img/magento.png 2012-09-11 15:12:19 +0000 differ
2478=== added directory 'sneldev_magento/wizard'
2479=== added file 'sneldev_magento/wizard/__init__.py'
2480--- sneldev_magento/wizard/__init__.py 1970-01-01 00:00:00 +0000
2481+++ sneldev_magento/wizard/__init__.py 2012-09-11 15:12:19 +0000
2482@@ -0,0 +1,10 @@
2483+import export_tools
2484+import sneldev_magento_products_export
2485+import sneldev_magento_stock_export
2486+import sneldev_magento_products_import
2487+import sneldev_magento_categories_import
2488+import sneldev_magento_orders_import
2489+import sneldev_magento_customers_import
2490+import sneldev_magento_stock_init
2491+import sneldev_magento_sync_start
2492+import sneldev_magento_sync_stop
2493
2494=== added file 'sneldev_magento/wizard/export_tools.py'
2495--- sneldev_magento/wizard/export_tools.py 1970-01-01 00:00:00 +0000
2496+++ sneldev_magento/wizard/export_tools.py 2012-09-11 15:12:19 +0000
2497@@ -0,0 +1,54 @@
2498+#!/usr/bin/env python
2499+# -*- encoding: utf-8 -*-
2500+##############################################################################
2501+#
2502+# Copyright (c) 2009 SnelDev (http://www.sneldev.com) All Rights Reserved.
2503+#
2504+# WARNING: This program as such is intended to be used by professional
2505+# programmers who take the whole responsability of assessing all potential
2506+# consequences resulting from its eventual inadequacies and bugs
2507+# End users who are looking for a ready-to-use solution with commercial
2508+# garantees and support are strongly adviced to contract a Free Software
2509+# Service Company
2510+#
2511+# This program is Free Software; you can redistribute it and/or
2512+# modify it under the terms of the GNU General Public License
2513+# as published by the Free Software Foundation; either version 2
2514+# of the License, or (at your option) any later version.
2515+#
2516+# This program is distributed in the hope that it will be useful,
2517+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2518+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2519+# GNU General Public License for more details.
2520+#
2521+# You should have received a copy of the GNU General Public License
2522+# along with this program; if not, write to the Free Software
2523+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2524+#
2525+##############################################################################
2526+
2527+import wizard
2528+import pooler
2529+import threading
2530+
2531+#Globals for syncrhonisation
2532+export_lock=threading.Lock();
2533+export_running=False;
2534+
2535+#Thread safe version of export_running
2536+def export_is_running():
2537+ global export_running
2538+
2539+ retVal=False
2540+ export_lock.acquire()
2541+ if (export_running == False):
2542+ export_running=True
2543+ retVal=False
2544+ else:
2545+ retVal=True
2546+ export_lock.release()
2547+ return retVal
2548+
2549+def set_export_finished():
2550+ global export_running
2551+ export_running=False
2552
2553=== added file 'sneldev_magento/wizard/sneldev_magento_categories_import.py'
2554--- sneldev_magento/wizard/sneldev_magento_categories_import.py 1970-01-01 00:00:00 +0000
2555+++ sneldev_magento/wizard/sneldev_magento_categories_import.py 2012-09-11 15:12:19 +0000
2556@@ -0,0 +1,49 @@
2557+# -*- coding: utf-8 -*-
2558+##############################################################################
2559+#
2560+# OpenERP, Open Source Management Solution
2561+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2562+#
2563+# This program is free software: you can redistribute it and/or modify
2564+# it under the terms of the GNU Affero General Public License as
2565+# published by the Free Software Foundation, either version 3 of the
2566+# License, or (at your option) any later version.
2567+#
2568+# This program is distributed in the hope that it will be useful,
2569+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2570+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2571+# GNU Affero General Public License for more details.
2572+#
2573+# You should have received a copy of the GNU Affero General Public License
2574+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2575+#
2576+##############################################################################
2577+
2578+
2579+import pooler
2580+import wizard
2581+import pooler
2582+import os
2583+
2584+from export_tools import *
2585+from osv import osv, fields
2586+
2587+class wiz_sneldev_categories_import(osv.osv_memory):
2588+ _name = 'sneldev.categories.import'
2589+ _description = 'Import categories'
2590+
2591+ _columns = {
2592+ }
2593+
2594+ _defaults = {
2595+ }
2596+
2597+ def do_categories_import(self, cr, uid, ids, context=None):
2598+ if (self.pool.get('sneldev.magento').import_categories(cr, uid) < 0):
2599+ raise osv.except_osv(('Warning'), ('Import failed, please refer to log file for failure details.'))
2600+
2601+ return {'type': 'ir.actions.act_window_close'}
2602+
2603+wiz_sneldev_categories_import()
2604+
2605+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2606\ No newline at end of file
2607
2608=== added file 'sneldev_magento/wizard/sneldev_magento_categories_import.xml'
2609--- sneldev_magento/wizard/sneldev_magento_categories_import.xml 1970-01-01 00:00:00 +0000
2610+++ sneldev_magento/wizard/sneldev_magento_categories_import.xml 2012-09-11 15:12:19 +0000
2611@@ -0,0 +1,30 @@
2612+<?xml version="1.0" encoding="utf-8"?>
2613+<openerp>
2614+ <data>
2615+ <record id="view_sneldev_categories_import" model="ir.ui.view">
2616+ <field name="name">Import categories</field>
2617+ <field name="model">sneldev.categories.import</field>
2618+ <field name="type">form</field>
2619+ <field name="arch" type="xml">
2620+ <form string="Import categories">
2621+ <label string="This wizard will import categories from Magento." colspan="4"/>
2622+ <separator colspan="4"/>
2623+ <group col="2" colspan="4">
2624+ <button icon='gtk-cancel' special="cancel"
2625+ string="Cancel" />
2626+ <button name="do_categories_import" string="Import"
2627+ colspan="1" type="object" icon="gtk-ok" />
2628+ </group>
2629+ </form>
2630+ </field>
2631+ </record>
2632+
2633+ <act_window name="Compute Categories"
2634+ res_model="sneldev.categories.import"
2635+ view_mode="form"
2636+ target="new"
2637+ key2="client_action_multi"
2638+ id="action_sneldev_categories_import"/>
2639+
2640+ </data>
2641+</openerp>
2642
2643=== added file 'sneldev_magento/wizard/sneldev_magento_customers_import.py'
2644--- sneldev_magento/wizard/sneldev_magento_customers_import.py 1970-01-01 00:00:00 +0000
2645+++ sneldev_magento/wizard/sneldev_magento_customers_import.py 2012-09-11 15:12:19 +0000
2646@@ -0,0 +1,51 @@
2647+# -*- coding: utf-8 -*-
2648+##############################################################################
2649+#
2650+# OpenERP, Open Source Management Solution
2651+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2652+#
2653+# This program is free software: you can redistribute it and/or modify
2654+# it under the terms of the GNU Affero General Public License as
2655+# published by the Free Software Foundation, either version 3 of the
2656+# License, or (at your option) any later version.
2657+#
2658+# This program is distributed in the hope that it will be useful,
2659+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2660+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2661+# GNU Affero General Public License for more details.
2662+#
2663+# You should have received a copy of the GNU Affero General Public License
2664+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2665+#
2666+##############################################################################
2667+
2668+import pooler
2669+import wizard
2670+import pooler
2671+import os
2672+
2673+from export_tools import *
2674+from osv import osv, fields
2675+
2676+class wiz_sneldev_customers_import(osv.osv_memory):
2677+ _name = 'sneldev.customers.import'
2678+ _description = 'Import customers'
2679+
2680+ _columns = {
2681+ }
2682+
2683+ _defaults = {
2684+ }
2685+
2686+ def do_customers_import(self, cr, uid, ids, context=None):
2687+ try:
2688+ self.pool.get('sneldev.magento').import_customers(cr, uid)
2689+
2690+ except:
2691+ raise osv.except_osv(('Warning'), ('Import failed, please refer to log file for failure details.'))
2692+
2693+ return {'type': 'ir.actions.act_window_close'}
2694+
2695+wiz_sneldev_customers_import()
2696+
2697+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2698
2699=== added file 'sneldev_magento/wizard/sneldev_magento_customers_import.xml'
2700--- sneldev_magento/wizard/sneldev_magento_customers_import.xml 1970-01-01 00:00:00 +0000
2701+++ sneldev_magento/wizard/sneldev_magento_customers_import.xml 2012-09-11 15:12:19 +0000
2702@@ -0,0 +1,27 @@
2703+<?xml version="1.0" encoding="utf-8"?>
2704+<openerp>
2705+ <data>
2706+ <record id="view_sneldev_customers_import" model="ir.ui.view">
2707+ <field name="name">Import customers</field>
2708+ <field name="model">sneldev.customers.import</field>
2709+ <field name="type">form</field>
2710+ <field name="arch" type="xml">
2711+ <form string="Import customers">
2712+ <label string="This wizard will import customers from Magento." colspan="4"/>
2713+ <separator colspan="4"/>
2714+ <group col="2" colspan="4">
2715+ <button icon='gtk-cancel' special="cancel" string="Cancel" />
2716+ <button name="do_customers_import" string="Import" colspan="1" type="object" icon="gtk-ok" />
2717+ </group>
2718+ </form>
2719+ </field>
2720+ </record>
2721+
2722+ <act_window name="Import customers"
2723+ res_model="sneldev.customers.import"
2724+ view_mode="form"
2725+ target="new"
2726+ key2="client_action_multi"
2727+ id="action_sneldev_customers_import"/>
2728+ </data>
2729+</openerp>
2730
2731=== added file 'sneldev_magento/wizard/sneldev_magento_orders_import.py'
2732--- sneldev_magento/wizard/sneldev_magento_orders_import.py 1970-01-01 00:00:00 +0000
2733+++ sneldev_magento/wizard/sneldev_magento_orders_import.py 2012-09-11 15:12:19 +0000
2734@@ -0,0 +1,54 @@
2735+# -*- coding: utf-8 -*-
2736+##############################################################################
2737+#
2738+# OpenERP, Open Source Management Solution
2739+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2740+#
2741+# This program is free software: you can redistribute it and/or modify
2742+# it under the terms of the GNU Affero General Public License as
2743+# published by the Free Software Foundation, either version 3 of the
2744+# License, or (at your option) any later version.
2745+#
2746+# This program is distributed in the hope that it will be useful,
2747+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2748+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2749+# GNU Affero General Public License for more details.
2750+#
2751+# You should have received a copy of the GNU Affero General Public License
2752+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2753+#
2754+##############################################################################
2755+
2756+
2757+import pooler
2758+import wizard
2759+import pooler
2760+import os
2761+
2762+from export_tools import *
2763+from osv import osv, fields
2764+
2765+class wiz_sneldev_orders_import(osv.osv_memory):
2766+ _name = 'sneldev.orders.import'
2767+ _description = 'Import orders'
2768+
2769+ _columns = {
2770+ }
2771+
2772+ _defaults = {
2773+ }
2774+
2775+ def do_orders_import(self, cr, uid, ids, context=None):
2776+ self.pool.get('sneldev.magento').import_categories(cr, uid)
2777+ self.pool.get('sneldev.magento').import_products(cr, uid)
2778+ if (self.pool.get('sneldev.magento').import_orders(cr, uid) < 0):
2779+ raise osv.except_osv(('Warning'), ('Import failed, please refer to log file for failure details.'))
2780+
2781+ if (self.pool.get('sneldev.magento').import_credit_memos(cr, uid) < 0):
2782+ raise osv.except_osv(('Warning'), ('Import failed, please refer to log file for failure details.'))
2783+
2784+ return {'type': 'ir.actions.act_window_close'}
2785+
2786+wiz_sneldev_orders_import()
2787+
2788+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2789\ No newline at end of file
2790
2791=== added file 'sneldev_magento/wizard/sneldev_magento_orders_import.xml'
2792--- sneldev_magento/wizard/sneldev_magento_orders_import.xml 1970-01-01 00:00:00 +0000
2793+++ sneldev_magento/wizard/sneldev_magento_orders_import.xml 2012-09-11 15:12:19 +0000
2794@@ -0,0 +1,30 @@
2795+<?xml version="1.0" encoding="utf-8"?>
2796+<openerp>
2797+ <data>
2798+ <record id="view_sneldev_orders_import" model="ir.ui.view">
2799+ <field name="name">Import orders</field>
2800+ <field name="model">sneldev.orders.import</field>
2801+ <field name="type">form</field>
2802+ <field name="arch" type="xml">
2803+ <form string="Import orders">
2804+ <label string="This wizard will import orders from Magento. It will first import categories and products." colspan="4"/>
2805+ <separator colspan="4"/>
2806+ <group col="2" colspan="4">
2807+ <button icon='gtk-cancel' special="cancel"
2808+ string="Cancel" />
2809+ <button name="do_orders_import" string="Import"
2810+ colspan="1" type="object" icon="gtk-ok" />
2811+ </group>
2812+ </form>
2813+ </field>
2814+ </record>
2815+
2816+ <act_window name="Import Orders"
2817+ res_model="sneldev.orders.import"
2818+ view_mode="form"
2819+ target="new"
2820+ key2="client_action_multi"
2821+ id="action_sneldev_orders_import"/>
2822+
2823+ </data>
2824+</openerp>
2825
2826=== added file 'sneldev_magento/wizard/sneldev_magento_products_export.py'
2827--- sneldev_magento/wizard/sneldev_magento_products_export.py 1970-01-01 00:00:00 +0000
2828+++ sneldev_magento/wizard/sneldev_magento_products_export.py 2012-09-11 15:12:19 +0000
2829@@ -0,0 +1,50 @@
2830+# -*- coding: utf-8 -*-
2831+##############################################################################
2832+#
2833+# OpenERP, Open Source Management Solution
2834+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2835+#
2836+# This program is free software: you can redistribute it and/or modify
2837+# it under the terms of the GNU Affero General Public License as
2838+# published by the Free Software Foundation, either version 3 of the
2839+# License, or (at your option) any later version.
2840+#
2841+# This program is distributed in the hope that it will be useful,
2842+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2843+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2844+# GNU Affero General Public License for more details.
2845+#
2846+# You should have received a copy of the GNU Affero General Public License
2847+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2848+#
2849+##############################################################################
2850+
2851+
2852+import pooler
2853+import wizard
2854+import pooler
2855+import os
2856+
2857+from export_tools import *
2858+from osv import osv, fields
2859+
2860+class wiz_sneldev_products_export(osv.osv_memory):
2861+ _name = 'sneldev.products.export'
2862+ _description = 'Export orders'
2863+
2864+ _columns = {
2865+ }
2866+
2867+ _defaults = {
2868+ }
2869+
2870+ def do_products_export(self, cr, uid, ids, context=None):
2871+ self.pool.get('sneldev.magento').export_categories(cr, uid)
2872+ if (self.pool.get('sneldev.magento').export_products(cr, uid) < 0):
2873+ raise osv.except_osv(('Warning'), ('Export failed, please refer to log file for failure details.'))
2874+
2875+ return {'type': 'ir.actions.act_window_close'}
2876+
2877+wiz_sneldev_products_export()
2878+
2879+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2880
2881=== added file 'sneldev_magento/wizard/sneldev_magento_products_export.xml'
2882--- sneldev_magento/wizard/sneldev_magento_products_export.xml 1970-01-01 00:00:00 +0000
2883+++ sneldev_magento/wizard/sneldev_magento_products_export.xml 2012-09-11 15:12:19 +0000
2884@@ -0,0 +1,30 @@
2885+<?xml version="1.0" encoding="utf-8"?>
2886+<openerp>
2887+ <data>
2888+ <record id="view_sneldev_products_export" model="ir.ui.view">
2889+ <field name="name">Export products</field>
2890+ <field name="model">sneldev.products.export</field>
2891+ <field name="type">form</field>
2892+ <field name="arch" type="xml">
2893+ <form string="Export products">
2894+ <label string="This wizard will export products to Magento. It will first export categories." colspan="4"/>
2895+ <separator colspan="4"/>
2896+ <group col="2" colspan="4">
2897+ <button icon='gtk-cancel' special="cancel"
2898+ string="Cancel" />
2899+ <button name="do_products_export" string="Export"
2900+ colspan="1" type="object" icon="gtk-ok" />
2901+ </group>
2902+ </form>
2903+ </field>
2904+ </record>
2905+
2906+ <act_window name="Export Products"
2907+ res_model="sneldev.products.export"
2908+ view_mode="form"
2909+ target="new"
2910+ key2="client_action_multi"
2911+ id="action_sneldev_products_export"/>
2912+
2913+ </data>
2914+</openerp>
2915
2916=== added file 'sneldev_magento/wizard/sneldev_magento_products_import.py'
2917--- sneldev_magento/wizard/sneldev_magento_products_import.py 1970-01-01 00:00:00 +0000
2918+++ sneldev_magento/wizard/sneldev_magento_products_import.py 2012-09-11 15:12:19 +0000
2919@@ -0,0 +1,50 @@
2920+# -*- coding: utf-8 -*-
2921+##############################################################################
2922+#
2923+# OpenERP, Open Source Management Solution
2924+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2925+#
2926+# This program is free software: you can redistribute it and/or modify
2927+# it under the terms of the GNU Affero General Public License as
2928+# published by the Free Software Foundation, either version 3 of the
2929+# License, or (at your option) any later version.
2930+#
2931+# This program is distributed in the hope that it will be useful,
2932+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2933+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2934+# GNU Affero General Public License for more details.
2935+#
2936+# You should have received a copy of the GNU Affero General Public License
2937+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2938+#
2939+##############################################################################
2940+
2941+
2942+import pooler
2943+import wizard
2944+import pooler
2945+import os
2946+
2947+from export_tools import *
2948+from osv import osv, fields
2949+
2950+class wiz_sneldev_products_import(osv.osv_memory):
2951+ _name = 'sneldev.products.import'
2952+ _description = 'Import orders'
2953+
2954+ _columns = {
2955+ }
2956+
2957+ _defaults = {
2958+ }
2959+
2960+ def do_products_import(self, cr, uid, ids, context=None):
2961+ self.pool.get('sneldev.magento').import_categories(cr, uid)
2962+ if (self.pool.get('sneldev.magento').import_products(cr, uid) < 0):
2963+ raise osv.except_osv(('Warning'), ('Import failed, please refer to log file for failure details.'))
2964+
2965+ return {'type': 'ir.actions.act_window_close'}
2966+
2967+wiz_sneldev_products_import()
2968+
2969+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2970
2971=== added file 'sneldev_magento/wizard/sneldev_magento_products_import.xml'
2972--- sneldev_magento/wizard/sneldev_magento_products_import.xml 1970-01-01 00:00:00 +0000
2973+++ sneldev_magento/wizard/sneldev_magento_products_import.xml 2012-09-11 15:12:19 +0000
2974@@ -0,0 +1,30 @@
2975+<?xml version="1.0" encoding="utf-8"?>
2976+<openerp>
2977+ <data>
2978+ <record id="view_sneldev_products_import" model="ir.ui.view">
2979+ <field name="name">Import products</field>
2980+ <field name="model">sneldev.products.import</field>
2981+ <field name="type">form</field>
2982+ <field name="arch" type="xml">
2983+ <form string="Import products">
2984+ <label string="This wizard will import products from Magento. It will first import categories." colspan="4"/>
2985+ <separator colspan="4"/>
2986+ <group col="2" colspan="4">
2987+ <button icon='gtk-cancel' special="cancel"
2988+ string="Cancel" />
2989+ <button name="do_products_import" string="Import"
2990+ colspan="1" type="object" icon="gtk-ok" />
2991+ </group>
2992+ </form>
2993+ </field>
2994+ </record>
2995+
2996+ <act_window name="Import Products"
2997+ res_model="sneldev.products.import"
2998+ view_mode="form"
2999+ target="new"
3000+ key2="client_action_multi"
3001+ id="action_sneldev_products_import"/>
3002+
3003+ </data>
3004+</openerp>
3005
3006=== added file 'sneldev_magento/wizard/sneldev_magento_stock_export.py'
3007--- sneldev_magento/wizard/sneldev_magento_stock_export.py 1970-01-01 00:00:00 +0000
3008+++ sneldev_magento/wizard/sneldev_magento_stock_export.py 2012-09-11 15:12:19 +0000
3009@@ -0,0 +1,50 @@
3010+# -*- coding: utf-8 -*-
3011+##############################################################################
3012+#
3013+# OpenERP, Open Source Management Solution
3014+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
3015+#
3016+# This program is free software: you can redistribute it and/or modify
3017+# it under the terms of the GNU Affero General Public License as
3018+# published by the Free Software Foundation, either version 3 of the
3019+# License, or (at your option) any later version.
3020+#
3021+# This program is distributed in the hope that it will be useful,
3022+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3023+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3024+# GNU Affero General Public License for more details.
3025+#
3026+# You should have received a copy of the GNU Affero General Public License
3027+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3028+#
3029+##############################################################################
3030+
3031+
3032+import pooler
3033+import wizard
3034+import pooler
3035+import os
3036+
3037+from export_tools import *
3038+from osv import osv, fields
3039+
3040+class wiz_sneldev_stock_export(osv.osv_memory):
3041+ _name = 'sneldev.stock.export'
3042+ _description = 'Export stock'
3043+
3044+ _columns = {
3045+ }
3046+
3047+ _defaults = {
3048+ }
3049+
3050+ def do_stock_export(self, cr, uid, ids, context=None):
3051+ if (self.pool.get('sneldev.magento').export_stock(cr, uid) < 0):
3052+ raise osv.except_osv(('Warning'), ('Export failed, please refer to log file for failure details.'))
3053+
3054+ else:
3055+ return {'type': 'ir.actions.act_window_close'}
3056+
3057+wiz_sneldev_stock_export()
3058+
3059+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3060\ No newline at end of file
3061
3062=== added file 'sneldev_magento/wizard/sneldev_magento_stock_export.xml'
3063--- sneldev_magento/wizard/sneldev_magento_stock_export.xml 1970-01-01 00:00:00 +0000
3064+++ sneldev_magento/wizard/sneldev_magento_stock_export.xml 2012-09-11 15:12:19 +0000
3065@@ -0,0 +1,30 @@
3066+<?xml version="1.0" encoding="utf-8"?>
3067+<openerp>
3068+ <data>
3069+ <record id="view_sneldev_stock_export" model="ir.ui.view">
3070+ <field name="name">Export stock</field>
3071+ <field name="model">sneldev.stock.export</field>
3072+ <field name="type">form</field>
3073+ <field name="arch" type="xml">
3074+ <form string="Export stock">
3075+ <label string="This wizard will export stock to Magento." colspan="4"/>
3076+ <separator colspan="4"/>
3077+ <group col="2" colspan="4">
3078+ <button icon='gtk-cancel' special="cancel"
3079+ string="Cancel" />
3080+ <button name="do_stock_export" string="Export"
3081+ colspan="1" type="object" icon="gtk-ok" />
3082+ </group>
3083+ </form>
3084+ </field>
3085+ </record>
3086+
3087+ <act_window name="Export Stock"
3088+ res_model="sneldev.stock.export"
3089+ view_mode="form"
3090+ target="new"
3091+ key2="client_action_multi"
3092+ id="action_sneldev_stock_export"/>
3093+
3094+ </data>
3095+</openerp>
3096
3097=== added file 'sneldev_magento/wizard/sneldev_magento_stock_init.py'
3098--- sneldev_magento/wizard/sneldev_magento_stock_init.py 1970-01-01 00:00:00 +0000
3099+++ sneldev_magento/wizard/sneldev_magento_stock_init.py 2012-09-11 15:12:19 +0000
3100@@ -0,0 +1,49 @@
3101+# -*- coding: utf-8 -*-
3102+##############################################################################
3103+#
3104+# OpenERP, Open Source Management Solution
3105+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
3106+#
3107+# This program is free software: you can redistribute it and/or modify
3108+# it under the terms of the GNU Affero General Public License as
3109+# published by the Free Software Foundation, either version 3 of the
3110+# License, or (at your option) any later version.
3111+#
3112+# This program is distributed in the hope that it will be useful,
3113+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3114+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3115+# GNU Affero General Public License for more details.
3116+#
3117+# You should have received a copy of the GNU Affero General Public License
3118+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3119+#
3120+##############################################################################
3121+
3122+
3123+import pooler
3124+import wizard
3125+import pooler
3126+import os
3127+
3128+from export_tools import *
3129+from osv import osv, fields
3130+
3131+class wiz_sneldev_stock_init(osv.osv_memory):
3132+ _name = 'sneldev.stock.init'
3133+ _description = 'Initialize stock from Magento'
3134+
3135+ _columns = {
3136+ }
3137+
3138+ _defaults = {
3139+ }
3140+
3141+ def do_stock_init(self, cr, uid, ids, context=None):
3142+ if (self.pool.get('sneldev.magento').init_stock(cr, uid) < 0):
3143+ raise osv.except_osv(('Warning'), ('Init failed, please refer to log file for failure details.'))
3144+
3145+ return {'type': 'ir.actions.act_window_close'}
3146+
3147+wiz_sneldev_stock_init()
3148+
3149+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3150
3151=== added file 'sneldev_magento/wizard/sneldev_magento_stock_init.xml'
3152--- sneldev_magento/wizard/sneldev_magento_stock_init.xml 1970-01-01 00:00:00 +0000
3153+++ sneldev_magento/wizard/sneldev_magento_stock_init.xml 2012-09-11 15:12:19 +0000
3154@@ -0,0 +1,30 @@
3155+<?xml version="1.0" encoding="utf-8"?>
3156+<openerp>
3157+ <data>
3158+ <record id="view_sneldev_stock_init" model="ir.ui.view">
3159+ <field name="name">Initialize stock from Magento</field>
3160+ <field name="model">sneldev.stock.init</field>
3161+ <field name="type">form</field>
3162+ <field name="arch" type="xml">
3163+ <form string="Initialize stock">
3164+ <label string="This wizard will create an inventory from Magento stock. This will remove all current stock information in OpenERP !" colspan="4"/>
3165+ <separator colspan="4"/>
3166+ <group col="2" colspan="4">
3167+ <button icon='gtk-cancel' special="cancel"
3168+ string="Cancel" />
3169+ <button name="do_stock_init" string="Start"
3170+ colspan="1" type="object" icon="gtk-ok" />
3171+ </group>
3172+ </form>
3173+ </field>
3174+ </record>
3175+
3176+ <act_window name="Initialize stock"
3177+ res_model="sneldev.stock.init"
3178+ view_mode="form"
3179+ target="new"
3180+ key2="client_action_multi"
3181+ id="action_sneldev_stock_init"/>
3182+
3183+ </data>
3184+</openerp>
3185
3186=== added file 'sneldev_magento/wizard/sneldev_magento_sync_start.py'
3187--- sneldev_magento/wizard/sneldev_magento_sync_start.py 1970-01-01 00:00:00 +0000
3188+++ sneldev_magento/wizard/sneldev_magento_sync_start.py 2012-09-11 15:12:19 +0000
3189@@ -0,0 +1,47 @@
3190+# -*- coding: utf-8 -*-
3191+##############################################################################
3192+#
3193+# OpenERP, Open Source Management Solution
3194+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
3195+#
3196+# This program is free software: you can redistribute it and/or modify
3197+# it under the terms of the GNU Affero General Public License as
3198+# published by the Free Software Foundation, either version 3 of the
3199+# License, or (at your option) any later version.
3200+#
3201+# This program is distributed in the hope that it will be useful,
3202+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3203+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3204+# GNU Affero General Public License for more details.
3205+#
3206+# You should have received a copy of the GNU Affero General Public License
3207+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3208+#
3209+##############################################################################
3210+
3211+
3212+import pooler
3213+import wizard
3214+import pooler
3215+import os
3216+
3217+from export_tools import *
3218+from osv import osv, fields
3219+
3220+class wiz_sneldev_sync_start(osv.osv_memory):
3221+ _name = 'sneldev.sync.start'
3222+ _description = 'Start Synchronization'
3223+
3224+ _columns = {
3225+ }
3226+
3227+ _defaults = {
3228+ }
3229+
3230+ def do_sync_start(self, cr, uid, ids, context=None):
3231+ self.pool.get('sneldev.magento').sync_start(cr, uid)
3232+ return {'type': 'ir.actions.act_window_close'}
3233+
3234+wiz_sneldev_sync_start()
3235+
3236+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3237\ No newline at end of file
3238
3239=== added file 'sneldev_magento/wizard/sneldev_magento_sync_start.xml'
3240--- sneldev_magento/wizard/sneldev_magento_sync_start.xml 1970-01-01 00:00:00 +0000
3241+++ sneldev_magento/wizard/sneldev_magento_sync_start.xml 2012-09-11 15:12:19 +0000
3242@@ -0,0 +1,30 @@
3243+<?xml version="1.0" encoding="utf-8"?>
3244+<openerp>
3245+ <data>
3246+ <record id="view_sneldev_sync_start" model="ir.ui.view">
3247+ <field name="name">Start synchronization</field>
3248+ <field name="model">sneldev.sync.start</field>
3249+ <field name="type">form</field>
3250+ <field name="arch" type="xml">
3251+ <form string="Start Synchronization">
3252+ <label string="You will now start the automatic synchronization." colspan="4"/>
3253+ <separator colspan="4"/>
3254+ <group col="2" colspan="4">
3255+ <button icon='gtk-cancel' special="cancel"
3256+ string="Cancel" />
3257+ <button name="do_sync_start" string="Start"
3258+ colspan="1" type="object" icon="gtk-ok" />
3259+ </group>
3260+ </form>
3261+ </field>
3262+ </record>
3263+
3264+ <act_window name="Start Synchronization"
3265+ res_model="sneldev.sync.start"
3266+ view_mode="form"
3267+ target="new"
3268+ key2="client_action_multi"
3269+ id="action_sneldev_sync_start"/>
3270+
3271+ </data>
3272+</openerp>
3273
3274=== added file 'sneldev_magento/wizard/sneldev_magento_sync_stop.py'
3275--- sneldev_magento/wizard/sneldev_magento_sync_stop.py 1970-01-01 00:00:00 +0000
3276+++ sneldev_magento/wizard/sneldev_magento_sync_stop.py 2012-09-11 15:12:19 +0000
3277@@ -0,0 +1,47 @@
3278+# -*- coding: utf-8 -*-
3279+##############################################################################
3280+#
3281+# OpenERP, Open Source Management Solution
3282+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
3283+#
3284+# This program is free software: you can redistribute it and/or modify
3285+# it under the terms of the GNU Affero General Public License as
3286+# published by the Free Software Foundation, either version 3 of the
3287+# License, or (at your option) any later version.
3288+#
3289+# This program is distributed in the hope that it will be useful,
3290+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3291+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3292+# GNU Affero General Public License for more details.
3293+#
3294+# You should have received a copy of the GNU Affero General Public License
3295+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3296+#
3297+##############################################################################
3298+
3299+
3300+import pooler
3301+import wizard
3302+import pooler
3303+import os
3304+
3305+from export_tools import *
3306+from osv import osv, fields
3307+
3308+class wiz_sneldev_sync_stop(osv.osv_memory):
3309+ _name = 'sneldev.sync.stop'
3310+ _description = 'Stop Synchronization'
3311+
3312+ _columns = {
3313+ }
3314+
3315+ _defaults = {
3316+ }
3317+
3318+ def do_sync_stop(self, cr, uid, ids, context=None):
3319+ self.pool.get('sneldev.magento').sync_stop(cr, uid)
3320+ return {'type': 'ir.actions.act_window_close'}
3321+
3322+wiz_sneldev_sync_stop()
3323+
3324+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3325\ No newline at end of file
3326
3327=== added file 'sneldev_magento/wizard/sneldev_magento_sync_stop.xml'
3328--- sneldev_magento/wizard/sneldev_magento_sync_stop.xml 1970-01-01 00:00:00 +0000
3329+++ sneldev_magento/wizard/sneldev_magento_sync_stop.xml 2012-09-11 15:12:19 +0000
3330@@ -0,0 +1,30 @@
3331+<?xml version="1.0" encoding="utf-8"?>
3332+<openerp>
3333+ <data>
3334+ <record id="view_sneldev_sync_stop" model="ir.ui.view">
3335+ <field name="name">Stop synchronization</field>
3336+ <field name="model">sneldev.sync.stop</field>
3337+ <field name="type">form</field>
3338+ <field name="arch" type="xml">
3339+ <form string="Stop Synchronization">
3340+ <label string="You will now stop the automatic synchronization." colspan="4"/>
3341+ <separator colspan="4"/>
3342+ <group col="2" colspan="4">
3343+ <button icon='gtk-cancel' special="cancel"
3344+ string="Cancel" />
3345+ <button name="do_sync_stop" string="Stop"
3346+ colspan="1" type="object" icon="gtk-ok" />
3347+ </group>
3348+ </form>
3349+ </field>
3350+ </record>
3351+
3352+ <act_window name="Stop Synchronization"
3353+ res_model="sneldev.sync.stop"
3354+ view_mode="form"
3355+ target="new"
3356+ key2="client_action_multi"
3357+ id="action_sneldev_sync_stop"/>
3358+
3359+ </data>
3360+</openerp>

Subscribers

People subscribed via source and target branches