# Copyright (C) 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from odoo import _, api, fields, models class StockWarehouse(models.Model): _inherit = "stock.warehouse" lot_rma_id = fields.Many2one( comodel_name='stock.location', string='RMA Location', ) # not readonly to have the possibility to edit location and # propagate to rma rules (add a auto-update when writing this field?) rma_cust_out_type_id = fields.Many2one( comodel_name='stock.picking.type', string='RMA Customer out Type', readonly=True, ) rma_sup_out_type_id = fields.Many2one( comodel_name='stock.picking.type', string='RMA Supplier out Type', readonly=True, ) rma_cust_in_type_id = fields.Many2one( comodel_name='stock.picking.type', string='RMA Customer in Type', readonly=True, ) rma_sup_in_type_id = fields.Many2one( comodel_name='stock.picking.type', string='RMA Supplier in Type', readonly=True, ) rma_in_this_wh = fields.Boolean( string='RMA in this Warehouse', help="If set, it will create RMA location, picking types and routes " "for this warehouse.", ) rma_customer_in_pull_id = fields.Many2one( comodel_name='stock.rule', string="RMA Customer In Rule", ) rma_customer_out_pull_id = fields.Many2one( comodel_name='stock.rule', string="RMA Customer Out Rule", ) rma_supplier_in_pull_id = fields.Many2one( comodel_name='stock.rule', string="RMA Supplier In Rule", ) rma_supplier_out_pull_id = fields.Many2one( comodel_name='stock.rule', string="RMA Supplier Out Rule", ) @api.multi def _get_rma_types(self): return [ self.rma_cust_out_type_id, self.rma_sup_out_type_id, self.rma_cust_in_type_id, self.rma_sup_in_type_id] @api.multi def _rma_types_available(self): self.ensure_one() rma_types = self._get_rma_types() for type in rma_types: if not type: return False return True @api.multi def write(self, vals): if 'rma_in_this_wh' in vals: if vals.get("rma_in_this_wh"): for wh in self: # RMA location: if not wh.lot_rma_id: wh.lot_rma_id = self.env['stock.location'].create({ 'name': 'RMA', 'usage': 'internal', 'location_id': wh.lot_stock_id.id, 'company_id': wh.company_id.id, }) # RMA types if not wh._rma_types_available(): wh._create_rma_picking_types() else: for type in wh._get_rma_types(): if type: type.active = True # RMA rules: wh._create_or_update_rma_pull() else: for wh in self: for type in wh._get_rma_types(): if type: type.active = False # Unlink rules: self.mapped('rma_customer_in_pull_id').unlink() self.mapped('rma_customer_out_pull_id').unlink() self.mapped('rma_supplier_in_pull_id').unlink() self.mapped('rma_supplier_out_pull_id').unlink() return super(StockWarehouse, self).write(vals) def _create_rma_picking_types(self): picking_type_obj = self.env['stock.picking.type'] customer_loc, supplier_loc = self._get_partner_locations() for wh in self: other_pick_type = picking_type_obj.search( [('warehouse_id', '=', wh.id)], order='sequence desc', limit=1) color = other_pick_type.color if other_pick_type else 0 max_sequence = other_pick_type and other_pick_type.sequence or 0 # create rma_cust_out_type_id: rma_cust_out_type_id = picking_type_obj.create({ 'name': _('Customer RMA Deliveries'), 'warehouse_id': wh.id, 'code': 'outgoing', 'use_create_lots': True, 'use_existing_lots': False, 'sequence_id': self.env.ref( 'rma.seq_picking_type_rma_cust_out').id, 'default_location_src_id': wh.lot_rma_id.id, 'default_location_dest_id': customer_loc.id, 'sequence': max_sequence, 'color': color, }) # create rma_sup_out_type_id: rma_sup_out_type_id = picking_type_obj.create({ 'name': _('Supplier RMA Deliveries'), 'warehouse_id': wh.id, 'code': 'outgoing', 'use_create_lots': True, 'use_existing_lots': False, 'sequence_id': self.env.ref( 'rma.seq_picking_type_rma_sup_out').id, 'default_location_src_id': wh.lot_rma_id.id, 'default_location_dest_id': supplier_loc.id, 'sequence': max_sequence, 'color': color, }) # create rma_cust_in_type_id: rma_cust_in_type_id = picking_type_obj.create({ 'name': _('Customer RMA Receipts'), 'warehouse_id': wh.id, 'code': 'incoming', 'use_create_lots': True, 'use_existing_lots': False, 'sequence_id': self.env.ref( 'rma.seq_picking_type_rma_cust_in').id, 'default_location_src_id': customer_loc.id, 'default_location_dest_id': wh.lot_rma_id.id, 'sequence': max_sequence, 'color': color, }) # create rma_sup_in_type_id: rma_sup_in_type_id = picking_type_obj.create({ 'name': _('Supplier RMA Receipts'), 'warehouse_id': wh.id, 'code': 'incoming', 'use_create_lots': True, 'use_existing_lots': False, 'sequence_id': self.env.ref( 'rma.seq_picking_type_rma_sup_in').id, 'default_location_src_id': supplier_loc.id, 'default_location_dest_id': wh.lot_rma_id.id, 'sequence': max_sequence, 'color': color, }) wh.write({ 'rma_cust_out_type_id': rma_cust_out_type_id.id, 'rma_sup_out_type_id': rma_sup_out_type_id.id, 'rma_cust_in_type_id': rma_cust_in_type_id.id, 'rma_sup_in_type_id': rma_sup_in_type_id.id, }) return True @api.multi def get_rma_rules_dict(self): self.ensure_one() rma_rules = dict() customer_loc, supplier_loc = self._get_partner_locations() rma_rules['rma_customer_in'] = { 'name': self._format_rulename(self, customer_loc, self.lot_rma_id.name), 'action': 'pull', 'warehouse_id': self.id, 'company_id': self.company_id.id, 'location_src_id': customer_loc.id, 'location_id': self.lot_rma_id.id, 'procure_method': 'make_to_stock', 'route_id': self.env.ref('rma.route_rma_customer').id, 'picking_type_id': self.rma_cust_in_type_id.id, 'active': True, } rma_rules['rma_customer_out'] = { 'name': self._format_rulename(self, self.lot_rma_id, customer_loc.name), 'action': 'pull', 'warehouse_id': self.id, 'company_id': self.company_id.id, 'location_src_id': self.lot_rma_id.id, 'location_id': customer_loc.id, 'procure_method': 'make_to_stock', 'route_id': self.env.ref('rma.route_rma_customer').id, 'picking_type_id': self.rma_cust_out_type_id.id, 'active': True, } rma_rules['rma_supplier_in'] = { 'name': self._format_rulename(self, supplier_loc, self.lot_rma_id.name), 'action': 'pull', 'warehouse_id': self.id, 'company_id': self.company_id.id, 'location_src_id': supplier_loc.id, 'location_id': self.lot_rma_id.id, 'procure_method': 'make_to_stock', 'route_id': self.env.ref('rma.route_rma_supplier').id, 'picking_type_id': self.rma_sup_in_type_id.id, 'active': True, } rma_rules['rma_supplier_out'] = { 'name': self._format_rulename(self, self.lot_rma_id, supplier_loc.name), 'action': 'pull', 'warehouse_id': self.id, 'company_id': self.company_id.id, 'location_src_id': self.lot_rma_id.id, 'location_id': supplier_loc.id, 'procure_method': 'make_to_stock', 'route_id': self.env.ref('rma.route_rma_supplier').id, 'picking_type_id': self.rma_sup_out_type_id.id, 'active': True, } return rma_rules def _create_or_update_rma_pull(self): rule_obj = self.env['stock.rule'] for wh in self: rules_dict = wh.get_rma_rules_dict() if wh.rma_customer_in_pull_id: wh.rma_customer_in_pull_id.write(rules_dict['rma_customer_in']) else: wh.rma_customer_in_pull_id = rule_obj.create( rules_dict['rma_customer_in']) if wh.rma_customer_out_pull_id: wh.rma_customer_out_pull_id.write( rules_dict['rma_customer_out']) else: wh.rma_customer_out_pull_id = rule_obj.create( rules_dict['rma_customer_out']) if wh.rma_supplier_in_pull_id: wh.rma_supplier_in_pull_id.write(rules_dict['rma_supplier_in']) else: wh.rma_supplier_in_pull_id = rule_obj.create( rules_dict['rma_supplier_in']) if wh.rma_supplier_out_pull_id: wh.rma_supplier_out_pull_id.write( rules_dict['rma_supplier_out']) else: wh.rma_supplier_out_pull_id = rule_obj.create( rules_dict['rma_supplier_out']) return True class StockLocationRoute(models.Model): _inherit = "stock.location.route" rma_selectable = fields.Boolean(string="Selectable on RMA Lines")