~openerp-commiter/openobject-addons/extra-6.0

« back to all changes in this revision

Viewing changes to magento_connect_product_variant/product.py

  • Committer: Raimon Esteve
  • Date: 2012-04-11 15:38:03 UTC
  • Revision ID: resteve@zikzakmedia.com-20120411153803-3u1ls7h4h4gpaszu
[ADD] Mangento Connect. Mangento Products and orders sync in your OpenERP

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- encoding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
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>
 
7
#    $Id$
 
8
#
 
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.
 
13
#
 
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.
 
18
#
 
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/>.
 
21
#
 
22
##############################################################################
 
23
 
 
24
from osv import osv, fields
 
25
from tools.translate import _
 
26
 
 
27
from magento import *
 
28
 
 
29
import netsvc
 
30
import unicodedata
 
31
import re
 
32
 
 
33
LOGGER = netsvc.Logger()
 
34
 
 
35
def slugify(value):
 
36
    """
 
37
    Normalizes string, converts to lowercase, removes non-alpha characters,
 
38
    and converts spaces to hyphens.
 
39
    """
 
40
 
 
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)
 
44
 
 
45
class product_template(osv.osv):
 
46
    _inherit = "product.template"
 
47
 
 
48
    def onchange_name(self, cr, uid, ids, name, slug):
 
49
        value = {}
 
50
        if not slug:
 
51
            slug = slugify(unicode(name,'UTF-8'))
 
52
            value = {'magento_tpl_url_key': slug}
 
53
        return {'value':value}
 
54
 
 
55
    def _check_magento_sku(self, cr, uid, magento_sku, id=False):
 
56
        """Check if this Magento SKU exists another product
 
57
        :param id int
 
58
        :magento_sku = str
 
59
        :return True/False
 
60
        """
 
61
        condition = [('magento_tpl_sku','=',magento_sku),('magento_tpl_exportable','=',True)]
 
62
        if id:
 
63
            condition.append(('id','!=',id))
 
64
        prods = self.search(cr, uid, condition)
 
65
        if len(prods)>0:
 
66
            return True
 
67
        return False
 
68
 
 
69
    def _magento_tax_class(self, cr, uid, context=None):
 
70
        """Get Taxes Magento. Selection values are available in Product Attributes
 
71
        :return [('','')]
 
72
        """
 
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)
 
75
        if len(ids)>0:
 
76
            taxes = product_attributes_obj.browse(cr, uid, ids[0])
 
77
            if taxes.selection:
 
78
                return eval(taxes.selection.encode('utf8'))
 
79
        return [('','')]
 
80
 
 
81
    _columns = {
 
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'),
 
94
    }
 
95
 
 
96
    _defaults = {
 
97
        'magento_tpl_status':lambda * a:True,
 
98
        'magento_tpl_visibility': '4',
 
99
    }
 
100
 
 
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']))
 
105
 
 
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')
 
110
            slug = slugify(slug)
 
111
            vals['magento_tpl_url_key'] = slug
 
112
 
 
113
        return super(product_template, self).create(cr, uid, vals, context)
 
114
 
 
115
    # def write(self, cr, uid, ids, vals, context):
 
116
        # """Convert url key slug line"""
 
117
 
118
        # result = True
 
119
        # if not isinstance(ids, list):
 
120
            # ids = [ids]
 
121
 
122
        # for id in ids:
 
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']))
 
126
 
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
 
130
 
131
            # result = result and super(product_template, self).write(cr, uid, [id], vals, context)
 
132
 
133
        # return result
 
134
 
 
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)
 
140
 
 
141
    def copy(self, cr, uid, id, default={}, context=None, done_list=[], local=False):
 
142
        """ 
 
143
        When copy, magento url key add -copy if exist magento_url_key
 
144
        """
 
145
 
 
146
        product = self.browse(cr, uid, id, context=context)
 
147
        if not default:
 
148
            default = {}
 
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)]):
 
153
                slug += _('-copy')
 
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)
 
158
 
 
159
    def product_product_variants_vals(self, cr, uid, product_temp, variant, context):
 
160
        """Return Dicc to Product Product Values
 
161
        :product_temp Object
 
162
        :return vals"""
 
163
        
 
164
        vals = super(product_template, self).product_product_variants_vals(cr, uid, product_temp, variant, context)
 
165
 
 
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
 
170
 
 
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])]
 
180
 
 
181
        #some data are also written
 
182
        vals['magento_product_type'] = 'simple'
 
183
        vals['magento_status'] = True
 
184
        vals['magento_visibility'] = '1' #Nowhere
 
185
 
 
186
        return vals
 
187
 
 
188
product_template()
 
189
 
 
190
class product_product(osv.osv):
 
191
    _inherit = "product.product"
 
192
 
 
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
 
196
        :magento_app object
 
197
        :product dicc
 
198
        :store_view ID
 
199
        :return product_product_oerp_id
 
200
        """
 
201
        LOGGER.notifyChannel('Magento Sync API', netsvc.LOG_INFO, "Waitting... %s" % (product['product_id']))
 
202
 
 
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']))
 
213
 
 
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'])
 
218
 
 
219
            #create product simples
 
220
            context = {
 
221
                'generate_from_template' : True,
 
222
                'product_tmpl_id' : product_template_oerp_id,
 
223
            }
 
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)
 
229
 
 
230
            product_template_obj = self.pool.get('product.template').browse(cr, uid, product_template_oerp_id, context)
 
231
 
 
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)
 
236
 
 
237
            # Vals add
 
238
            vals['magento_tpl_exportable'] = True
 
239
 
 
240
            dimesion_types = []
 
241
            if product_attributes:
 
242
                for product_attribute in product_attributes:
 
243
                    # Dimension type
 
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)
 
248
                    
 
249
                    # Dimension Option
 
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)
 
255
 
 
256
            if len(dimesion_types)>0:
 
257
                vals['dimension_type_ids'] = [(6,0,dimesion_types)]
 
258
 
 
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']))
 
261
 
 
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)
 
265
 
 
266
            cr.commit()
 
267
        else:
 
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']))
 
269
 
 
270
        return product_template_oerp_id
 
271
 
 
272
product_product()