def icops(self, record): if not self._backend_to: raise MappingError("Could not find an ICOPS backend") sess = self.session backend = self._backend_to ic_uid = backend.icops_uid.id company = backend.company_id partner_pool = sess.pool.get('res.partner') partner_id = record.company_id.partner_id.id partner = partner_pool.browse(sess.cr, ic_uid, partner_id) pricelist = (partner.property_product_pricelist.id if partner.property_product_pricelist else False) fiscal_position = partner.property_account_position payment_term = partner.property_payment_term shop = self._backend_to.icops_shop_id if company.partner_id.id != record.partner_id.id: raise MappingError("Wrong partner") return { 'company_id': company.id, 'partner_id': partner.id, 'pricelist_id': pricelist, 'fiscal_position': fiscal_position.id, 'payment_term': payment_term.id, 'user_id': ic_uid, 'shop_id': shop.id }
def so2po_icops(self, record): if not self._backend_to: raise MappingError("Could not find an ICOPS backend") backend = self._backend_to company = backend.company_id shop = backend.icops_shop_id warehouse = shop.warehouse_id location = warehouse.lot_stock_id if company.partner_id.id != record.partner_id.id: raise MappingError("Wrong partner") return {'company_id': company.id, 'location_id': location.id}
def modifier(self, record, to_attr): if not record[field] or not int(record[field]): return False column = self.model._fields[to_attr] if column.type != 'many2one': raise ValueError('The column %s should be a Many2one, got %s' % (to_attr, type(column))) rel_id = record[field] if binding is None: binding_model = column.comodel_name else: binding_model = binding binder = self.binder_for(binding_model) # if we want the normal record, not a binding, # we ask to the binder to unwrap the binding unwrap = bool(binding) with self.session.change_context(active_test=False): record = binder.to_openerp(rel_id, unwrap=unwrap) if not record: raise MappingError( "Can not find an existing %s for external " "record %s %s unwrapping" % (binding_model, rel_id, 'with' if unwrap else 'without')) if isinstance(record, models.BaseModel): return record.id else: _logger.debug( 'Binder for %s returned an id, ' 'returning a record should be preferred.', binding_model) return record
def ic_supplier_id(self, record): ic_id = self.binder_for('odooconnector.res.partner').to_backend( record.partner_id.id, wrap=True) if not ic_id: raise MappingError('The partner has no binding for this backend') return {'ic_supplier_id': ic_id}
def journal(self, record): journal = self.backend_record.refund_journal_id if not journal: raise MappingError( _('The refund journal must be configured on ' 'the PrestaShop Backend.')) return {'journal_id': journal.id}
def categories(self, record): mag_categories = record['categories'] binder = self.binder_for('magento.product.category') category_ids = [] main_categ_id = None for mag_category_id in mag_categories: cat_id = binder.to_openerp(mag_category_id, unwrap=True) if cat_id is None: raise MappingError("The product category with " "magento id %s is not imported." % mag_category_id) category_ids.append(cat_id) if category_ids: main_categ_id = category_ids.pop(0) if main_categ_id is None: default_categ = self.backend_record.default_category_id if default_categ: main_categ_id = default_categ.id result = {'categ_ids': [(6, 0, category_ids)]} if main_categ_id: # OpenERP assign 'All Products' if not specified result['categ_id'] = main_categ_id return result
def prod_brand_id(self, record): prod_brand = record['manufacturer'] binder = self.get_binder_for_model('magento.product.manufacturer') prod_brand_ids = [] main_brand_id = None if prod_brand: brand_id = binder.to_openerp(record['manufacturer'], unwrap=True) if prod_brand is None: raise MappingError("The product brand with " "magento id %s is not imported." % prod_brand) prod_brand_ids.append(brand_id) if prod_brand_ids: main_brand_id = prod_brand_ids.pop(0) # if main_brand_id is None: # default_categ = self.backend_record.default_category_id # if default_categ: # main_categ_id = default_categ.id result = main_brand_id #if prod_brand_id: # OpenERP assign 'All Products' if not specified # result['product_brand_id'] = main_brand_id return result
def categories(self, record): sw_categories = record['categories'] binder = self.binder_for('shopware.product.category') category_ids = [] main_categ_id = None for sw_category in sw_categories: cat_id = binder.to_openerp(sw_category['id'], unwrap=True) if cat_id is None: raise MappingError("The product category with " "shopware id %s is not imported." % sw_category['id']) category_ids.append(cat_id) if category_ids: main_categ_id = category_ids.pop(0) if main_categ_id is None: default_categ = self.backend_record.default_category_id if default_categ: main_categ_id = default_categ.id else: # The article has no categories, and there is no default category set # so take the root category, which has in Shopware always the id 1 main_categ_id = binder.to_openerp(1, unwrap=True) result = {'categ_ids': [(6, 0, category_ids)]} if main_categ_id: # OpenERP assign 'All Products' if not specified result['categ_id'] = main_categ_id return result
def product_uom(self, record): ic_id = self.binder_for('odooconnector.product.uom').to_backend( record.product_uom.id, wrap=True) if not ic_id: raise MappingError('The UoM has no binding for this backend') _logger.debug('Using Product UoM %s for %s and line %s', ic_id, record.product_uom, record.id) return {'product_uom': ic_id}
def price(self, record): # only import the EK price, because this one always exists prices = record['prices'] for price in prices: if price['from'] == 1 and price['customerGroup']['key'] == 'EK': return {'list_price': price['price']} raise MappingError( "Could not store the price for the article detail with shopware id %s" % record['id'])
def author(self, record): jira_author = record['author'] jira_author_key = jira_author['key'] binder = self.binder_for('jira.res.users') user = binder.to_openerp(jira_author_key, unwrap=True) if not user: email = jira_author['emailAddress'] raise MappingError( _('No user found with login "%s" or email "%s".' 'You must create a user or link it manually if the ' 'login/email differs.') % (jira_author_key, email)) return {'user_id': user.id}
def parent_id(self, record): if not record.get('parent_id'): return binder = self.binder_for() category_id = binder.to_openerp(record['parent_id'], unwrap=True) mag_cat_id = binder.to_openerp(record['parent_id']) if category_id is None: raise MappingError("The product category with " "magento id %s is not imported." % record['parent_id']) return {'parent_id': category_id, 'magento_parent_id': mag_cat_id}
def to_backend(self, record_id, wrap=False): '''Export the SKU to Bots from the OpenERP product. Since product master sync is not yet implimented we will attempt to match directly on SKU with overrides''' # Attempt to get overriding mappings bots_product_ids = self.session.search('bots.product', [('product_id', '=', record_id), ('backend_id', '=', self.backend_record.id)]) if bots_product_ids: bots_record = self.session.read('bots.product', bots_product_ids[0], ['bots_id'])['bots_id'] else: values = self.session.read("product.product", record_id, ['default_code', 'magento_prism_sku']) bots_record = values.get('magento_prism_sku') #or values.get('default_code') # Do not default to default_code, only use the value imported from 3rd party site (magento_prism_sku) if not bots_record: raise MappingError(_('Missing PRISM product mapping for product %s [%s].') % (values.get('default_code'), record_id,)) return bots_record
def parent_id(self, record): if record['product_category']: rec = record['product_category'] if not rec['parent']: return binder = self.binder_for() category_id = binder.to_openerp(rec['parent'], unwrap=True) Ymk_cat_id = binder.to_openerp(rec['parent']) if category_id is None: raise MappingError("The product category with " "Ymk id %s is not imported." % rec['parent']) return {'parent_id': category_id, 'Ymk_parent_id': Ymk_cat_id}
def customer_group_id(self, record): # import customer groups binder = self.binder_for(model='magento.res.partner.category') category_id = binder.to_openerp(record['group_id'], unwrap=True) if category_id is None: raise MappingError("The partner category with " "magento id %s does not exist" % record['group_id']) # FIXME: should remove the previous tag (all the other tags from # the same backend) return {'category_id': [(4, category_id)]}
def assignee(self, record): assignee = record['fields'].get('assignee') if not assignee: return {'user_id': False} jira_key = assignee['key'] binder = self.binder_for('jira.res.users') user = binder.to_openerp(jira_key, unwrap=True) if not user: email = assignee['emailAddress'] raise MappingError( _('No user found with login "%s" or email "%s".' 'You must create a user or link it manually if the ' 'login/email differs.') % (jira_key, email)) return {'user_id': user.id}
def categories(self, record): if record['product']: rec = record['product'] woo_categories = rec['categories'] binder = self.binder_for('woo.product.category') category_ids = [] main_categ_id = None for woo_category_id in woo_categories: cat_id = binder.to_openerp(woo_category_id, unwrap=True) if cat_id is None: raise MappingError("The product category with " "woo id %s is not imported." % woo_category_id) category_ids.append(cat_id) if category_ids: main_categ_id = category_ids.pop(0) result = {'woo_categ_ids': [(6, 0, category_ids)]} if main_categ_id: # OpenERP assign 'All Products' if not specified result['categ_id'] = main_categ_id return result
def so2so_icops(self, record): if not self._backend_to: raise MappingError("Could not find an ICOPS backend") backend = self._backend_to icops_uid = backend.icops_uid.id company = backend.company_id partner = company.partner_id pricelist = partner.property_product_pricelist fiscal_position = partner.property_account_position payment_term = partner.property_payment_term shop = self._backend_to.icops_shop_id return { 'company_id': company.id, 'partner_id': partner.id, 'pricelist_id': pricelist.id, 'fiscal_position': fiscal_position.id, 'payment_term': payment_term.id, 'user_id': icops_uid, 'shop_id': shop.id }
def shopware_article(self, record): article = self.env['shopware.article'].search([('shopware_id', '=', record['articleId'])]) if article is None: raise MappingError("The shopware article with " "shopware id %s does not exist" % record['articleId']) category_ids = [] for category in article.categ_ids: category_ids.append(category.id) return { 'name': article.name, 'description': article.description_long, 'shopware_article_id': article.id, 'categ_ids': [(6, 0, category_ids)], 'categ_id': article.categ_id.id, 'changed': article.changed }
def create(self, picking_id): product_binder = self.get_binder_for_model('highjump.product.product') picking_binder = self.get_binder_for_model( 'highjump.stock.picking.out') hj_picking_obj = self.session.pool.get('highjump.stock.picking.out') picking_obj = self.session.pool.get('stock.picking') hj_warehouse_obj = self.session.pool.get('highjump.warehouse') wf_service = netsvc.LocalService("workflow") picking = hj_picking_obj.browse(self.session.cr, self.session.uid, picking_id, context=self.session.context) order_number = picking.sale_id and picking.sale_id.name or picking.name address = picking.partner_id or picking.sale_id and picking.sale_id.partner_shipping_id if picking.highjump_id: raise JobError( _('The High Jump picking %s already has an external ID. Will not export again.' ) % (picking.id, )) if not address: raise MappingError( _('Missing address when attempting to export High Jump picking %s.' ) % (picking_id, )) # Select which moves we will ship picking_complete = True moves_to_ship = {} order_lines = [] for move in picking.move_lines: if move.state != 'assigned': picking_complete = False continue product_hjid = move.product_id and product_binder.to_backend( move.product_id.id) if not product_hjid: picking_complete = False continue moves_to_ship['move%s' % (move.id)] = { 'product_id': move.product_id.id, 'product_qty': move.product_qty, 'product_uom': move.product_uom.id, 'prodlot_id': move.prodlot_id.id, } order_lines.append({ 'OrderSKU': { 'PartNumber': product_hjid, 'Quantity': int(move.product_qty), } }) if not order_lines: raise MappingError( _('Unable to export any order lines on export of High Jump picking %s.' ) % (picking_id, )) # Split picking depending on order policy if not picking_complete: picking_policy = picking.sale_id and picking.sale_id.picking_policy or 'direct' if picking_policy != 'direct': raise InvalidDataError( _('Unable to export picking %s. Picking policy does not allow it to be split and is not fully complete or some products are not mapped for export.' ) % (picking_id, )) # Split the picking split = picking_obj.do_partial(self.session.cr, self.session.uid, [picking.openerp_id.id], moves_to_ship, context=self.session.context) picking.refresh() if picking.openerp_id.backorder_id: hj_picking_obj.write( self.session.cr, self.session.uid, picking.id, {'openerp_id': picking.openerp_id.backorder_id.id}, context=self.session.context) else: wf_service.trg_validate(self.session.uid, 'stock.picking', picking.openerp_id.id, 'button_done', self.session.cr) picking.refresh() # Assert the picking we are about to export is now marked as done if picking.state != 'done': raise JobError( _('The High Jump picking %s was not able to be completed, cannot be exported.' ) % (picking_id, )) highjump_warehouse = hj_warehouse_obj.read(self.session.cr, self.session.uid, picking.warehouse_id.id, ['name'])['name'] highjump_id = '%s%s' % ( self.highjump.hj_order_prefix, order_number, ) # Test if this ID is unique, if not increment it suffix_counter = 0 existing_id = picking_binder.to_openerp(highjump_id) orig_highjump_id = highjump_id while existing_id: suffix_counter += 1 highjump_id = "%s_%s" % (orig_highjump_id, suffix_counter) existing_id = picking_binder.to_openerp(highjump_id) data = { 'orderRequest': { 'ClientCode': self.highjump.username, 'OrderNumber': highjump_id, 'PO': highjump_id, 'Shipper': highjump_warehouse, 'ShipDate': datetime.now().strftime('%Y-%m-%d'), 'DeliveryDate': datetime.now().strftime('%Y-%m-%d'), 'Priority': self.highjump.hj_priority, 'ServiceLevel': self.highjump.hj_service_level, 'DeliveryInstructions': picking.note or picking.sale_id and picking.sale_id.note or '', 'Consignee': { 'Name': address.name or '', 'Address': address.street or '', 'Address2': address.street2 or '', 'City': address.city or '', 'State': address.state_id and address.state_id.code or '', 'Zip': address.zip or '', 'Country': address.country_id and address.country_id.code or '', 'Phone': address.phone or '', }, 'SKUs': order_lines, }, } res = self._call('PlaceOrder', data) messages = 'Messages' in res and [x for x in res.Messages] or [] errors = 'ErrorMessages' in res and [x for x in res.ErrorMessages] or [] success = 'Success' in res and res.Success or False if success: log_level = errors and logging.ERROR or messages and logging.WARN or logging.INFO _logger.log( log_level, _('Exported High Jump picking %s, order %s successfully: Messages: %s, Errors: %s' ) % (picking_id, highjump_id, messages, errors)) else: _logger.error( _('Failed to export High Jump picking %s: Messages: %s, Errors: %s' ) % (picking_id, messages, errors)) raise JobError( _('Failed to export High Jump picking %s: Messages: %s, Errors: %s' ) % (picking_id, messages, errors)) return highjump_id
def _prepare_crossdock(self, picking_id): picking_binder = self.get_binder_for_model('bots.stock.picking.in') bots_picking_obj = self.session.pool.get('bots.stock.picking.out') move_obj = self.session.pool.get('stock.move') purchase_line_obj = self.session.pool.get('purchase.order.line') picking = bots_picking_obj.browse(self.session.cr, self.session.uid, picking_id) if not picking.bots_id: raise JobError( _('The Bots picking %s is not exported. A join file cannot be exported for it.' ) % (picking.id, )) order_lines = [] for move in picking.move_lines: if move.state not in ( 'waiting', 'confirmed', 'assigned', ): raise MappingError( _('Unable to export cross-dock details for a move which is in state %s.' ) % (move.state, )) po_name = "" pol_ids = purchase_line_obj.search( self.session.cr, self.session.uid, [('move_dest_id', '=', move.id), ('state', '!=', 'cancel'), ('order_id.state', '!=', 'cancel'), ('product_id', '=', move.product_id.id)], context=self.session.context) if len(pol_ids) > 1: raise MappingError( _('Unable to export cross-dock details for a move which is incorrectly linked to multiple purchases %s.' ) % (move.id, )) elif len(pol_ids) == 1: move_ids = move_obj.search( self.session.cr, self.session.uid, [('move_dest_id', '=', move.id), ('purchase_line_id', '=', pol_ids[0]), ('state', '!=', 'cancel')], context=self.session.context) if move_ids: move_po = move_obj.browse(self.session.cr, self.session.uid, move_ids[0], self.session.context) if move_po.picking_id: po_name = picking_binder.to_backend( move_po.picking_id.id, wrap=True) or "" if not po_name: raise NoExternalId( "No PO ID found, try again later") order_line = { "move_id": move.id, "product_qty": int(move.product_qty), "po_id": po_name, } order_lines.append(order_line) if not order_lines: raise MappingError( _('Unable to export any cross dock lines on export of Bots picking %s.' ) % (picking_id, )) data = { 'crossdock': { 'crossdock_line': order_lines, 'header': [{ 'partner_to': picking.backend_id.name_to, 'partner_from': picking.backend_id.name_from, 'message_id': '0', 'date_msg': datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'), }], }, } FILENAME = 'cross_dock_%s.json' return data, FILENAME
def sku(self, record): sku = record.default_code if not sku: raise MappingError( "The product attribute default code cannot be empty.") return {'sku': sku}
def customer_and_addresses(self, record): partner_name = record.get('partner_name', False) partner_name = self._format_partner_name(partner_name) customer_email = record['partner_email'] matching_customer_id = self.session.search( 'res.partner', [('email', '=', customer_email)]) address = False for partner_address in record['partner']: if partner_address.get('type', False) == 'delivery': address = partner_address break else: address = record['partner'] and record['partner'][0] or False if not address: raise MappingError('No address found for sale order') addr_country = False addr_state = False if address.get('country'): addr_country = self.session.search( 'res.country', [('code', '=', address['country'])]) addr_country = addr_country and addr_country[0] or False if address.get('state'): addr_state = self.session.search('res.country.state', [('code', '=', address['state'])]) addr_state = addr_state and addr_state[0] or False company_id = self.backend_record.shop_id.company_id and self.backend_record.shop_id.company_id.id or False if matching_customer_id: matching_customer_id = matching_customer_id[0] # TODO: Should the address search match by contact name and partner company name as well? matching_address_id = self.session.search('res.partner', [ ('country_id', '=', addr_country), ('state_id', '=', addr_state), ('zip', '=', address.get('zip', False)), ('city', '=', address.get('city', False)), ('street', '=', address.get('address1', False)), ]) if matching_address_id: shipping_invoice_address = matching_address_id[0] else: new_address_vals = { 'parent_id': matching_customer_id, 'name': partner_name, 'street': address.get('address1', False), 'street2': address.get('address2', False), 'city': address.get('city', False), 'state_id': addr_state, 'zip': address.get('zip', False), 'country_id': addr_country, 'email': customer_email, 'lang': self.backend_record.lang_id.code, 'company_id': company_id, 'customer': True, } shipping_invoice_address = self.session.create( 'res.partner', new_address_vals) return { 'partner_id': matching_customer_id, 'partner_invoice_id': shipping_invoice_address, 'partner_shipping_id': shipping_invoice_address } else: new_partner_vals = { 'name': partner_name, 'street': address.get('address1', False), 'street2': address.get('address2', False), 'city': address.get('city', False), 'state_id': addr_state, 'zip': address.get('zip', False), 'country_id': addr_country, 'email': customer_email, 'lang': self.backend_record.lang_id.code, 'company_id': company_id, 'customer': True, } additional_partner_attributes = self._get_partner_attributes( record) new_partner_vals.update(additional_partner_attributes) new_partner_id = self.session.create('res.partner', new_partner_vals) return { 'partner_id': new_partner_id, 'partner_invoice_id': new_partner_id, 'partner_shipping_id': new_partner_id }