1
# -*- encoding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (c) 2011 Zikzakmedia S.L. (http://zikzakmedia.com) All Rights Reserved.
6
# Raimon Esteve <resteve@zikzakmedia.com>
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU Affero General Public License as
11
# published by the Free Software Foundation, either version 3 of the
12
# License, or (at your option) any later version.
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU Affero General Public License for more details.
19
# You should have received a copy of the GNU Affero General Public License
20
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
##############################################################################
24
from osv import osv, fields
25
from tools.translate import _
33
LOGGER = netsvc.Logger()
37
Normalizes string, converts to lowercase, removes non-alpha characters,
38
and converts spaces to hyphens.
41
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
42
value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
43
return re.sub('[-\s]+', '-', value)
45
class product_template(osv.osv):
46
_inherit = "product.template"
48
def onchange_name(self, cr, uid, ids, name, slug):
51
slug = slugify(unicode(name,'UTF-8'))
52
value = {'magento_tpl_url_key': slug}
53
return {'value':value}
55
def _check_magento_sku(self, cr, uid, magento_sku, id=False):
56
"""Check if this Magento SKU exists another product
61
condition = [('magento_tpl_sku','=',magento_sku),('magento_tpl_exportable','=',True)]
63
condition.append(('id','!=',id))
64
prods = self.search(cr, uid, condition)
69
def _magento_tax_class(self, cr, uid, context=None):
70
"""Get Taxes Magento. Selection values are available in Product Attributes
73
product_attributes_obj = self.pool.get('product.attributes')
74
ids = product_attributes_obj.search(cr, uid, [('name','=','x_tax_class_id')]) #TODO: Use multimagento app (servers)
76
taxes = product_attributes_obj.browse(cr, uid, ids[0])
78
return eval(taxes.selection.encode('utf8'))
82
'magento_tpl_sku':fields.char('Magento SKU', size=64),
83
'magento_tpl_exportable':fields.boolean('Exported to Magento?', change_default=True, help='If check this value, this product is publishing in Magento Store. For disable this product in your Magento Store, change visibility option to Nowhere.'),
84
'magento_tpl_sale_shop': fields.many2many('sale.shop', 'magento_configurable_sale_shop_rel', 'product_template_id', 'sale_shop_id', 'Websites', help='Select yours Sale Shops available this product (configurable product)'),
85
'magento_tpl_status':fields.boolean('Status'),
86
'magento_tpl_visibility': fields.selection([('0','Select Option'),('1','Nowhere'),('2','Catalog'),('3','Search'),('4','Catalog,Search')], 'Visibility'),
87
'magento_tpl_url_key': fields.char('Url Key', size=256, translate=True),
88
'magento_tpl_shortdescription': fields.text('Short Description', translate=True),
89
'magento_tpl_metadescription': fields.text('Description', translate=True),
90
'magento_tpl_metakeyword': fields.text('Keyword', translate=True),
91
'magento_tpl_metatitle': fields.char('Title', size=256, translate=True),
92
'magento_tpl_attribute_group_id': fields.many2one('product.attributes.group', 'Attribute'),
93
'magento_tpl_tax_class': fields.selection(_magento_tax_class, 'Magento Tax'),
97
'magento_tpl_status':lambda * a:True,
98
'magento_tpl_visibility': '4',
101
def create(self, cr, uid, vals, context):
102
if 'magento_tpl_sku' in vals:
103
if self._check_magento_sku(cr, uid, vals['magento_tpl_sku']):
104
raise osv.except_osv(_("Alert"), _("Error! Magento SKU %s must be unique") % (vals['magento_tpl_sku']))
106
if 'magento_tpl_url_key' in vals:
107
slug = vals['magento_tpl_url_key']
108
if not isinstance(slug, unicode):
109
slug = unicode(slug,'UTF-8')
111
vals['magento_tpl_url_key'] = slug
113
return super(product_template, self).create(cr, uid, vals, context)
115
# def write(self, cr, uid, ids, vals, context):
116
# """Convert url key slug line"""
119
# if not isinstance(ids, list):
123
## if 'magento_tpl_sku' in vals:
124
## if self._check_magento_sku(cr, uid, vals['magento_tpl_sku'], id):
125
## raise osv.except_osv(_("Alert"), _("Error! Magento SKU %s must be unique") % (vals['magento_tpl_sku']))
127
# if 'magento_tpl_url_key' in vals:
128
# slug = slugify(unicode(vals['magento_tpl_url_key'],'UTF-8'))
129
# vals['magento_tpl_url_key'] = slug
131
# result = result and super(product_template, self).write(cr, uid, [id], vals, context)
135
def unlink(self, cr, uid, ids, context=None):
136
for val in self.browse(cr, uid, ids):
137
if val.magento_tpl_exportable:
138
raise osv.except_osv(_("Alert"), _("Template '%s' not allow to delete because are active in Magento Shop") % (val.name))
139
return super(product_template, self).unlink(cr, uid, ids, context)
141
def copy(self, cr, uid, id, default={}, context=None, done_list=[], local=False):
143
When copy, magento url key add -copy if exist magento_url_key
146
product = self.browse(cr, uid, id, context=context)
149
if product.magento_tpl_url_key:
150
default = default.copy()
151
slug = product.magento_tpl_url_key
152
while self.search(cr, uid, [('magento_tpl_url_key','=',slug)]):
154
default['magento_tpl_url_key'] = slug
155
if product.magento_tpl_sku:
156
default['magento_tpl_sku'] = "%s-copy" % (product.magento_tpl_sku)
157
return super(product_template, self).copy(cr, uid, id, default, context=context)
159
def product_product_variants_vals(self, cr, uid, product_temp, variant, context):
160
"""Return Dicc to Product Product Values
164
vals = super(product_template, self).product_product_variants_vals(cr, uid, product_temp, variant, context)
166
if product_temp.magento_tpl_exportable:
167
variant = self.pool.get('product.variant.dimension.value').browse(cr, uid, variant[0])
168
code = variant.option_id.code and variant.option_id.code or variant.option_id.name
169
code_slug = slugify(code) and slugify(code) or code
171
vals['magento_exportable'] = True
172
vals['magento_sku'] = "%s-%s" % (product_temp.magento_tpl_sku, code)
173
vals['magento_url_key'] = "%s-%s" % (product_temp.magento_tpl_url_key, code_slug)
174
vals['magento_shortdescription'] = product_temp.magento_tpl_shortdescription
175
vals['magento_metadescription'] = product_temp.magento_tpl_metadescription
176
vals['magento_metakeyword'] = product_temp.magento_tpl_metakeyword
177
vals['magento_metatitle'] = product_temp.magento_tpl_metatitle
178
vals['attribute_group_id'] = product_temp.magento_tpl_attribute_group_id.id
179
vals['magento_sale_shop'] = [(6,0, [x.id for x in product_temp.magento_tpl_sale_shop])]
181
#some data are also written
182
vals['magento_product_type'] = 'simple'
183
vals['magento_status'] = True
184
vals['magento_visibility'] = '1' #Nowhere
190
class product_product(osv.osv):
191
_inherit = "product.product"
193
def magento_create_product_configurable(self, cr, uid, magento_app, product, store_view, context = None):
194
"""Create Product Variant (configurable) from Magento Values
195
This method is better defined product.template, but product.product have dinamic methos to call, it's available in product.product
199
:return product_product_oerp_id
201
LOGGER.notifyChannel('Magento Sync API', netsvc.LOG_INFO, "Waitting... %s" % (product['product_id']))
203
product_template_oerp_id = None
204
product_template_id = self.pool.get('magento.external.referential').check_mgn2oerp(cr, uid, magento_app, 'product.template', product['product_id'])
205
if not product_template_id:
206
values = self.magento_product_values(cr, uid, magento_app, product, context)
207
values['is_multi_variants'] = True
208
product_template_name = values['name']
209
product_template_magento_id = product['product_id']
210
product_template_oerp_id = self.pool.get('product.template').create(cr, uid, values, context)
211
self.pool.get('magento.external.referential').create_external_referential(cr, uid, magento_app, 'product.template', product_template_oerp_id, product_template_magento_id)
212
LOGGER.notifyChannel('Magento Sync API', netsvc.LOG_INFO, "Create Product Template: magento app %s, openerp id %s, magento product id %s." % (magento_app.name, product_template_oerp_id, product['product_id']))
214
#~ Update product.template dicc
215
with ProductConfigurable(magento_app.uri, magento_app.username, magento_app.password) as productconfigurable_api:
216
product_info = productconfigurable_api.info(product['product_id'])
217
product_attributes = productconfigurable_api.getSuperAttributes(product['product_id'])
219
#create product simples
221
'generate_from_template' : True,
222
'product_tmpl_id' : product_template_oerp_id,
224
with Product(magento_app.uri, magento_app.username, magento_app.password) as product_api:
225
product_template_info = product_api.info(product_template_magento_id)
226
for prod in product_info:
227
product = product_api.info(prod['stock_item']['product_id'])
228
self.magento_create_product(cr, uid, magento_app, product, store_view, context)
230
product_template_obj = self.pool.get('product.template').browse(cr, uid, product_template_oerp_id, context)
232
# Base External Mapping
233
context['magento_app'] = magento_app
234
context['product_info'] = product_template_info
235
vals = self.pool.get('base.external.mapping').get_external_to_oerp(cr, uid, 'magento.product.configurable', product_template_obj.id, product_template_info, context)
238
vals['magento_tpl_exportable'] = True
241
if product_attributes:
242
for product_attribute in product_attributes:
244
type_name = product_attribute['attribute_code']
245
magento_id = product_attribute['attribute_id']
246
dimesion_type = self.pool.get('product.variant.dimension.type').magento_dimension_type(cr, uid, magento_app, type_name, magento_id)
247
dimesion_types.append(dimesion_type)
250
dimension_options = []
251
for prod_values in product_attribute['values']:
252
dimension_options.append({'value': prod_values['product_super_attribute_id'], 'label': prod_values['label']})
253
if len(dimension_options)>0:
254
dimension_option = self.pool.get('product.variant.dimension.option').magento_dimension_option(cr, uid, magento_app, dimesion_type, dimension_options)
256
if len(dimesion_types)>0:
257
vals['dimension_type_ids'] = [(6,0,dimesion_types)]
259
self.pool.get('product.template').write(cr, uid, [product_template_oerp_id], vals, context)
260
LOGGER.notifyChannel('Magento Sync API', netsvc.LOG_INFO, "Write Product Template: magento %s, openerp id %s, magento product id %s." % (magento_app.name, product_template_oerp_id, product['product_id']))
262
# Add all options dimension value
263
if len(dimesion_types)>0:
264
self.pool.get('product.template').add_all_option(cr, uid, [product_template_oerp_id], context)
268
LOGGER.notifyChannel('Magento Sync API', netsvc.LOG_INFO, "Skip! Product Template exists: magento %s, magento product id %s. Not create" % (magento_app.name, product['product_id']))
270
return product_template_oerp_id