diff --git a/rma/data/rma_operation.xml b/rma/data/rma_operation.xml index fea67f4f..5baa6fca 100644 --- a/rma/data/rma_operation.xml +++ b/rma/data/rma_operation.xml @@ -3,7 +3,6 @@ Replace After Receive RPLC - no ordered received customer @@ -14,7 +13,6 @@ Replace RPLS - no ordered ordered supplier @@ -22,30 +20,9 @@ - - Refund before receive - RFC - ordered - no - no - customer - - - - - Refund only - RFS - ordered - no - no - supplier - - - Replace deliver to vendor DSRPLB - no ordered no customer @@ -55,7 +32,6 @@ Replace receive in vendor DSRPLV - no no received customer @@ -65,7 +41,6 @@ Replace deliver to customer DSRPC - no no received supplier diff --git a/rma/models/product.py b/rma/models/product.py index d7f878bc..5ee028ec 100644 --- a/rma/models/product.py +++ b/rma/models/product.py @@ -8,7 +8,9 @@ from openerp import fields, models class ProductTemplate(models.Model): _inherit = 'product.template' - rma_operation_id = fields.Many2one( - comodel_name="rma.operation", string="RMA Operation") + rma_customer_operation_id = fields.Many2one( + comodel_name="rma.operation", string="Default RMA Customer Operation") + rma_supplier_operation_id = fields.Many2one( + comodel_name="rma.operation", string="Default RMA Supplier Operation") rma_approval_policy = fields.Selection( related="categ_id.rma_approval_policy", readonly=True) diff --git a/rma/models/product_category.py b/rma/models/product_category.py index decfce28..9674ad8d 100644 --- a/rma/models/product_category.py +++ b/rma/models/product_category.py @@ -16,5 +16,7 @@ class ProductCategory(models.Model): "products within categories with this policy.\n" "* Two steps: A RMA containing a product within a category with " "this policy will request the RMA manager approval.") - rma_operation_id = fields.Many2one( - comodel_name="rma.operation", string="RMA Operation") + rma_customer_operation_id = fields.Many2one( + comodel_name="rma.operation", string="Default RMA Customer Operation") + rma_supplier_operation_id = fields.Many2one( + comodel_name="rma.operation", string="Default RMA Supplier Operation") diff --git a/rma/models/rma_operation.py b/rma/models/rma_operation.py index 5d3b230d..4f295009 100644 --- a/rma/models/rma_operation.py +++ b/rma/models/rma_operation.py @@ -26,10 +26,7 @@ class RmaOperation(models.Model): name = fields.Char('Description', required=True) code = fields.Char('Code', required=True) - refund_policy = fields.Selection([ - ('no', 'No refund'), ('ordered', 'Based on Ordered Quantities'), - ('received', 'Based on Received Quantities')], string="Refund Policy", - default='no') + active = fields.Boolean(string='Active', default=True) receipt_policy = fields.Selection([ ('no', 'Not required'), ('ordered', 'Based on Ordered Quantities'), ('received', 'Based on Delivered Quantities')], @@ -58,6 +55,6 @@ class RmaOperation(models.Model): 'stock.location', 'Send To This Company Location') type = fields.Selection([ ('customer', 'Customer'), ('supplier', 'Supplier')], - string="Used in RMA of this type", required=True, default='customer') + string="Used in RMA of this type", required=True) rma_line_ids = fields.One2many('rma.order.line', 'operation_id', 'RMA lines') diff --git a/rma/models/rma_order.py b/rma/models/rma_order.py index 28a9ff8d..8061dea5 100644 --- a/rma/models/rma_order.py +++ b/rma/models/rma_order.py @@ -3,6 +3,7 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from openerp import api, fields, models +from datetime import datetime class RmaOrder(models.Model): @@ -38,8 +39,12 @@ class RmaOrder(models.Model): @api.multi def _compute_line_count(self): - self.ensure_one() - self.line_count = len(self._get_valid_lines()) + for rec in self: + rec.line_count = len(rec._get_valid_lines()) + + @api.model + def _default_date_rma(self): + return datetime.now() name = fields.Char( string='Order Number', index=True, readonly=True, @@ -55,8 +60,9 @@ class RmaOrder(models.Model): state = fields.Selection([('draft', 'Draft'), ('to_approve', 'To Approve'), ('approved', 'Approved'), ('done', 'Done')], string='State', index=True, - default='draft') - date_rma = fields.Datetime(string='Order Date', index=True, copy=False) + default='draft') + date_rma = fields.Datetime(string='Order Date', index=True, + default=_default_date_rma) partner_id = fields.Many2one('res.partner', string='Partner', required=True, readonly=True, states={'draft': [('readonly', False)]}) @@ -72,11 +78,9 @@ class RmaOrder(models.Model): out_shipment_count = fields.Integer(compute=_compute_out_shipment_count, string='# of Outgoing Shipments') line_count = fields.Integer(compute=_compute_line_count, - string='# of Outgoing Shipments', - copy=False) + string='# of Outgoing Shipments') supplier_line_count = fields.Integer(compute=_compute_supplier_line_count, - string='# of Outgoing Shipments', - copy=False) + string='# of Outgoing Shipments') company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.user.company_id) @@ -175,8 +179,8 @@ class RmaOrder(models.Model): def _get_valid_lines(self): """:return: A recordset of rma lines. """ - self.ensure_one() - return self.rma_line_ids + for rec in self: + return rec.rma_line_ids @api.multi def action_view_lines(self): @@ -205,7 +209,7 @@ class RmaOrder(models.Model): action = self.env.ref('rma.action_rma_supplier_lines') result = action.read()[0] lines = self.rma_line_ids - related_lines = [line.id for line in lines.children_ids] + related_lines = [line.id for line in lines.supplier_rma_line_ids] # choose the view_mode accordingly if len(related_lines) != 1: result['domain'] = "[('id', 'in', " + \ diff --git a/rma/models/rma_order_line.py b/rma/models/rma_order_line.py index 8eb1f917..6fddca53 100644 --- a/rma/models/rma_order_line.py +++ b/rma/models/rma_order_line.py @@ -308,8 +308,12 @@ class RmaOrderLine(models.Model): self.product_qty = 1 self.uom_id = self.product_id.uom_id.id self.price_unit = self.product_id.standard_price - self.operation_id = self.product_id.rma_operation_id or \ - self.product_id.categ_id.rma_operation_id + if self.type == 'customer': + self.operation_id = self.product_id.rma_customer_operation_id or \ + self.product_id.categ_id.rma_customer_operation_id + else: + self.operation_id = self.product_id.rma_supplier_operation_id or \ + self.product_id.categ_id.rma_supplier_operation_id return result @api.onchange('operation_id') diff --git a/rma/tests/__init__.py b/rma/tests/__init__.py index 1c2b27c0..dfa77946 100644 --- a/rma/tests/__init__.py +++ b/rma/tests/__init__.py @@ -2,3 +2,5 @@ # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) from . import test_rma +from . import test_supplier_rma +from . import test_rma_dropship diff --git a/rma/tests/test_rma.py b/rma/tests/test_rma.py index 95bbe572..2e36b989 100644 --- a/rma/tests/test_rma.py +++ b/rma/tests/test_rma.py @@ -13,61 +13,95 @@ class TestRma(common.TransactionCase): super(TestRma, self).setUp() self.rma_make_picking = self.env['rma_make_picking.wizard'] + self.make_supplier_rma = self.env["rma.order.line.make.supplier.rma"] self.rma_add_stock_move = self.env['rma_add_stock_move'] self.stockpicking = self.env['stock.picking'] self.rma = self.env['rma.order'] self.rma_line = self.env['rma.order.line'] self.rma_op = self.env['rma.operation'] - self.rma_op_id = self.env.ref('rma.rma_operation_customer_replace') + self.rma_cust_replace_op_id = self.env.ref( + 'rma.rma_operation_customer_replace') + self.rma_sup_replace_op_id = self.env.ref( + 'rma.rma_operation_supplier_replace') self.product_id = self.env.ref('product.product_product_4') self.product_1 = self.env.ref('product.product_product_25') self.product_2 = self.env.ref('product.product_product_30') self.product_3 = self.env.ref('product.product_product_33') self.uom_unit = self.env.ref('product.product_uom_unit') # assign an operation - self.product_1.write({'rma_operation_id': self.rma_op_id.id}) - self.product_2.write({'rma_operation_id': self.rma_op_id.id}) - self.product_3.write({'rma_operation_id': self.rma_op_id.id}) + self.product_1.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) + self.product_2.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) + self.product_3.write( + {'rma_customer_operation_id': self.rma_cust_replace_op_id.id, + 'rma_supplier_operation_id': self.rma_sup_replace_op_id.id}) self.partner_id = self.env.ref('base.res_partner_12') self.stock_location = self.env.ref('stock.stock_location_stock') self.stock_rma_location = self.env.ref('rma.location_rma') self.customer_location = self.env.ref( 'stock.stock_location_customers') + self.supplier_location = self.env.ref( + 'stock.stock_location_suppliers') self.product_uom_id = self.env.ref('product.product_uom_unit') - self.product_uom_id = self.env.ref('product.product_uom_unit') - moves = [] products2move = [(self.product_1, 3), (self.product_2, 5), (self.product_3, 2)] - for item in products2move: - move_values = self._prepare_move(item[0], item[1]) - moves.append(self.env['stock.move'].create(move_values)) + self.rma_customer_id = self._create_rma_from_move( + products2move, 'customer', self.env.ref('base.res_partner_2'), + dropship=False) + + def _create_rma_from_move(self, products2move, type, partner, dropship, + supplier_address_id=None): + moves = [] + if type == 'customer': + for item in products2move: + move_values = self._prepare_move( + item[0], item[1], self.stock_location, + self.customer_location) + moves.append(self.env['stock.move'].create(move_values)) + else: + for item in products2move: + move_values = self._prepare_move( + item[0], item[1], self.supplier_location, + self.stock_rma_location) + moves.append(self.env['stock.move'].create(move_values)) # Create the RMA from the stock_move - self.rma_id = self.rma.create( + rma_id = self.rma.create( { 'reference': '0001', - 'type': 'customer', - 'partner_id': self.env.ref('base.res_partner_2').id + 'type': type, + 'partner_id': partner.id, + 'company_id': self.env.ref('base.main_company').id }) for move in moves: - data = self.rma_add_stock_move.with_context( - {'stock_move_id': move.id} - )._prepare_rma_line_from_stock_move(move) - operation = self.rma_op.browse(data['operation_id']) - data.update( - rma_id=self.rma_id.id, - receipt_policy=operation.receipt_policy, - delivery_policy=operation.delivery_policy, - in_warehouse_id=operation.in_warehouse_id.id, - out_warehouse_id=operation.out_warehouse_id.id, - location_id=self.stock_rma_location.id, - in_route_id=operation.in_route_id.id, - out_route_id=operation.out_route_id.id) + if type == 'customer': + wizard = self.rma_add_stock_move.with_context( + {'stock_move_id': move.id, 'customer': True, + 'active_ids': rma_id.id, + 'active_model': 'rma.order', + } + ).create({}) + data = wizard._prepare_rma_line_from_stock_move(move) + else: + wizard = self.rma_add_stock_move.with_context( + {'stock_move_id': move.id, 'supplier': True, + 'active_ids': rma_id.id, + 'active_model': 'rma.order', + } + ).create({}) + data = wizard._prepare_rma_line_from_stock_move(move) + if dropship: + data.update(customer_to_supplier=dropship, + supplier_address_id=supplier_address_id.id) self.rma_line.create(data) # approve the RMA - self.rma_id.action_rma_to_approve() - self.rma_id.action_rma_approve() + rma_id.action_rma_to_approve() + rma_id.action_rma_approve() + return rma_id - def _prepare_move(self, product, qty): + def _prepare_move(self, product, qty, src, dest): res = { 'product_id': product.id, 'name': product.partner_ref, @@ -75,14 +109,14 @@ class TestRma(common.TransactionCase): 'product_uom': self.product_uom_id.id or product.uom_id.id, 'product_uom_qty': qty, 'origin': 'Test RMA', - 'location_id': self.stock_location.id, - 'location_dest_id': self.customer_location.id, + 'location_id': src.id, + 'location_dest_id': dest.id, } return res - def test_00_receive_items(self): + def test_customer_rma(self): wizard = self.rma_make_picking.with_context({ - 'active_ids': self.rma_id.rma_line_ids.ids, + 'active_ids': self.rma_customer_id.rma_line_ids.ids, 'active_model': 'rma.order.line', 'picking_type': 'incoming', 'active_id': 1 @@ -97,7 +131,7 @@ class TestRma(common.TransactionCase): moves = picking.move_lines self.assertEquals(len(moves), 3, "Incorrect number of moves created") - for line in self.rma_id.rma_line_ids: + for line in self.rma_customer_id.rma_line_ids: # common qtys for all products self.assertEquals(line.qty_received, 0, "Wrong qty received") @@ -125,7 +159,7 @@ class TestRma(common.TransactionCase): "Wrong qty incoming") picking.action_assign() picking.do_transfer() - for line in self.rma_id.rma_line_ids: + for line in self.rma_customer_id.rma_line_ids: self.assertEquals(line.qty_to_receive, 0, "Wrong qty to_receive") self.assertEquals(line.qty_incoming, 0, @@ -152,7 +186,7 @@ class TestRma(common.TransactionCase): wizard = self.rma_make_picking.with_context({ 'active_id': 1, - 'active_ids': self.rma_id.rma_line_ids.ids, + 'active_ids': self.rma_customer_id.rma_line_ids.ids, 'active_model': 'rma.order.line', 'picking_type': 'outgoing', }).create({}) @@ -167,7 +201,7 @@ class TestRma(common.TransactionCase): moves = picking_out.move_lines self.assertEquals(len(moves), 3, "Incorrect number of moves created") - for line in self.rma_id.rma_line_ids: + for line in self.rma_customer_id.rma_line_ids: self.assertEquals(line.qty_to_receive, 0, "Wrong qty to receive") self.assertEquals(line.qty_incoming, 0, @@ -197,7 +231,7 @@ class TestRma(common.TransactionCase): "Wrong qty outgoing") picking_out.action_assign() picking_out.do_transfer() - for line in self.rma_id.rma_line_ids: + for line in self.rma_customer_id.rma_line_ids: self.assertEquals(line.qty_to_receive, 0, "Wrong qty to receive") self.assertEquals(line.qty_incoming, 0, @@ -221,4 +255,6 @@ class TestRma(common.TransactionCase): "Wrong qty received") self.assertEquals(line.qty_delivered, 2, "Wrong qty delivered") - self.rma_id.action_rma_done() + self.rma_customer_id.action_rma_done() + self.assertEquals(self.rma_customer_id.state, 'done', + "Wrong State") diff --git a/rma/tests/test_rma_dropship.py b/rma/tests/test_rma_dropship.py new file mode 100644 index 00000000..a531734f --- /dev/null +++ b/rma/tests/test_rma_dropship.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from openerp.addons.rma.tests import test_rma + + +class TestRmaDropship(test_rma.TestRma): + + def setUp(self): + super(TestRmaDropship, self).setUp() + products2move = [(self.product_1, 3), (self.product_2, 5), + (self.product_3, 2)] + self.rma_droship_id = self._create_rma_from_move( + products2move, 'customer', self.env.ref('base.res_partner_2'), + dropship=True, + supplier_address_id=self.env.ref('base.res_partner_3')) + + def test_dropship(self): + wizard = self.make_supplier_rma.with_context({ + 'active_ids': self.rma_droship_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'active_id': 1 + }).create({}) + res = wizard.make_supplier_rma() + supplier_rma = self.rma.browse(res['res_id']) + supplier_rma.action_rma_to_approve() + supplier_rma.action_rma_approve() + wizard = self.rma_make_picking.with_context({ + 'active_id': 1, + 'active_ids': supplier_rma.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'picking_type': 'incoming', + }).create({}) + procurements = wizard._create_picking() + group_ids = set([proc.group_id.id for proc in procurements if + proc.group_id]) + domain = [('group_id', 'in', list(group_ids))] + picking = self.stockpicking.search(domain) + self.assertEquals(len(picking), 1, + "Incorrect number of pickings created") + moves = picking.move_lines + self.assertEquals(len(moves), 3, + "Incorrect number of moves created") + for line in supplier_rma.rma_line_ids: + # common qtys for all products + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + self.assertEquals(line.qty_outgoing, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 0, + "Wrong qty delivered") + # product specific + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 3, + "Wrong qty to deliver") + self.assertEquals(line.qty_incoming, 3, + "Wrong qty outgoing") + if line.product_id == self.product_2: + self.assertEquals(line.qty_to_receive, 5, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 5, + "Wrong qty to deliver") + self.assertEquals(line.qty_incoming, 5, + "Wrong qty outgoing") + if line.product_id == self.product_3: + self.assertEquals(line.qty_to_receive, 2, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 2, + "Wrong qty to deliver") + self.assertEquals(line.qty_incoming, 2, + "Wrong qty outgoing") + + for line in self.rma_droship_id.rma_line_ids: + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_supplier_rma, 0, + "Wrong qty to supplier rma") + self.assertEquals(line.qty_in_supplier_rma, 3, + "Wrong qty in supplier rma") + if line.product_id == self.product_2: + self.assertEquals(line.qty_to_supplier_rma, 0, + "Wrong qty to supplier rma") + self.assertEquals(line.qty_in_supplier_rma, 5, + "Wrong qty in supplier rma") + if line.product_id == self.product_3: + self.assertEquals(line.qty_to_supplier_rma, 0, + "Wrong qty to supplier rma") + self.assertEquals(line.qty_in_supplier_rma, 2, + "Wrong qty in supplier rma") diff --git a/rma/tests/test_supplier_rma.py b/rma/tests/test_supplier_rma.py new file mode 100644 index 00000000..e67b55ba --- /dev/null +++ b/rma/tests/test_supplier_rma.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- +# © 2017 Eficent Business and IT Consulting Services S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from openerp.addons.rma.tests import test_rma + + +class TestSupplierRma(test_rma.TestRma): + + def setUp(self): + super(TestSupplierRma, self).setUp() + products2move = [(self.product_1, 3), (self.product_2, 5), + (self.product_3, 2)] + self.rma_supplier_id = self._create_rma_from_move( + products2move, 'supplier', self.env.ref('base.res_partner_1'), + dropship=False) + + def test_supplier_rma(self): + wizard = self.rma_make_picking.with_context({ + 'active_ids': self.rma_supplier_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'picking_type': 'outgoing', + 'active_id': 1 + }).create({}) + procurements = wizard._create_picking() + group_ids = set([proc.group_id.id for proc in procurements if + proc.group_id]) + domain = [('group_id', 'in', list(group_ids))] + picking = self.stockpicking.search(domain) + self.assertEquals(len(picking), 1, + "Incorrect number of pickings created") + moves = picking.move_lines + self.assertEquals(len(moves), 3, + "Incorrect number of moves created") + for line in self.rma_supplier_id.rma_line_ids: + # common qtys for all products + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 0, + "Wrong qty delivered") + # product specific + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 3, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 3, + "Wrong qty outgoing") + if line.product_id == self.product_2: + self.assertEquals(line.qty_to_receive, 5, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 5, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 5, + "Wrong qty outgoing") + if line.product_id == self.product_3: + self.assertEquals(line.qty_to_receive, 2, + "Wrong qty to receive") + self.assertEquals(line.qty_to_deliver, 2, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 2, + "Wrong qty outgoing") + + picking.action_assign() + picking.do_transfer() + for line in self.rma_supplier_id.rma_line_ids: + self.assertEquals(line.qty_to_deliver, 0, + "Wrong qty to deliver") + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_outgoing, 0, + "Wrong qty outgoing") + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + if line.product_id == self.product_1: + self.assertEquals(line.qty_delivered, 3, + "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + if line.product_id == self.product_2: + self.assertEquals(line.qty_delivered, 5, + "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 5, + "Wrong qty to receive") + if line.product_id == self.product_3: + self.assertEquals(line.qty_delivered, 2, + "Wrong qty delivered") + self.assertEquals(line.qty_to_receive, 2, + "Wrong qty to receive") + wizard = self.rma_make_picking.with_context({ + 'active_id': 1, + 'active_ids': self.rma_supplier_id.rma_line_ids.ids, + 'active_model': 'rma.order.line', + 'picking_type': 'incoming', + }).create({}) + procurements = wizard._create_picking() + group_ids = set([proc.group_id.id for proc in procurements if + proc.group_id]) + domain = [('group_id', 'in', list(group_ids))] + pickings = self.stockpicking.search(domain) + self.assertEquals(len(pickings), 2, + "Incorrect number of pickings created") + picking_out = pickings[1] + moves = picking_out.move_lines + self.assertEquals(len(moves), 3, + "Incorrect number of moves created") + for line in self.rma_supplier_id.rma_line_ids: + self.assertEquals(line.qty_to_deliver, 0, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 0, + "Wrong qty outgoing") + self.assertEquals(line.qty_received, 0, + "Wrong qty received") + if line.product_id == self.product_1: + self.assertEquals(line.qty_to_receive, 3, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 3, + "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 3, + "Wrong qty delivered") + if line.product_id == self.product_2: + self.assertEquals(line.qty_to_receive, 5, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 5, + "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 5, + "Wrong qty delivered") + if line.product_id == self.product_3: + self.assertEquals(line.qty_to_receive, 2, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 2, + "Wrong qty incoming") + self.assertEquals(line.qty_delivered, 2, + "Wrong qty delivered") + picking_out.action_assign() + picking_out.do_transfer() + for line in self.rma_supplier_id.rma_line_ids: + self.assertEquals(line.qty_to_receive, 0, + "Wrong qty to receive") + self.assertEquals(line.qty_incoming, 0, + "Wrong qty incoming") + self.assertEquals(line.qty_to_deliver, 0, + "Wrong qty to deliver") + self.assertEquals(line.qty_outgoing, 0, + "Wrong qty outgoing") + if line.product_id == self.product_1: + self.assertEquals(line.qty_received, 3, + "Wrong qty received") + self.assertEquals(line.qty_delivered, 3, + "Wrong qty delivered") + if line.product_id == self.product_2: + self.assertEquals(line.qty_received, 5, + "Wrong qty received") + self.assertEquals(line.qty_delivered, 5, + "Wrong qty delivered") + if line.product_id == self.product_3: + self.assertEquals(line.qty_received, 2, + "Wrong qty received") + self.assertEquals(line.qty_delivered, 2, + "Wrong qty delivered") + self.rma_supplier_id.action_rma_done() + self.assertEquals(self.rma_supplier_id.state, 'done', + "Wrong State") diff --git a/rma/views/product_view.xml b/rma/views/product_view.xml index c14144a6..bb35950b 100644 --- a/rma/views/product_view.xml +++ b/rma/views/product_view.xml @@ -8,8 +8,11 @@ - - + + + + + @@ -22,7 +25,8 @@ - + + diff --git a/rma/views/rma_operation_view.xml b/rma/views/rma_operation_view.xml index 1fc26e7a..b9f55633 100644 --- a/rma/views/rma_operation_view.xml +++ b/rma/views/rma_operation_view.xml @@ -6,6 +6,7 @@ rma.operation + @@ -25,6 +26,7 @@ + @@ -50,20 +52,39 @@ - - Operations + + Customer Operations rma.operation form tree,form + {'default_type': "customer"} + [('type','=', 'customer')] - + Supplier Operations + rma.operation + form + tree,form + {'default_type': "supplier"} + [('type','=', 'supplier')] + + + + + action="action_rma_operation_customer"/> + + diff --git a/rma/views/rma_order_line_view.xml b/rma/views/rma_order_line_view.xml index 29d8797d..3b9399a8 100644 --- a/rma/views/rma_order_line_view.xml +++ b/rma/views/rma_order_line_view.xml @@ -332,8 +332,7 @@ Customer RMA Lines rma.order.line [('state','in', ['approved', 'done']), - ('type','=', 'customer'), - ('customer_to_supplier','=', False) + ('type','=', 'customer') ] {"search_default_assigned_to":uid} form diff --git a/rma/wizards/rma_add_stock_move.py b/rma/wizards/rma_add_stock_move.py index 64ce435f..fd6e2e18 100644 --- a/rma/wizards/rma_add_stock_move.py +++ b/rma/wizards/rma_add_stock_move.py @@ -2,7 +2,7 @@ # © 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from openerp import models, fields, api, _ +from openerp import api, fields, models from openerp.exceptions import ValidationError @@ -40,14 +40,18 @@ class RmaAddStockMove(models.TransientModel): domain="[('state', '=', 'done')]") def _prepare_rma_line_from_stock_move(self, sm, lot=False): - operation = sm.product_id.rma_operation_id or \ - sm.product_id.categ_id.rma_operation_id + if self.env.context.get('customer'): + operation = sm.product_id.rma_customer_operation_id or \ + sm.product_id.categ_id.rma_customer_operation_id + else: + operation = sm.product_id.rma_supplier_operation_id or \ + sm.product_id.categ_id.rma_supplier_operation_id data = { 'reference_move_id': sm.id, 'product_id': sm.product_id.id, 'lot_id': lot and lot.id or False, 'name': sm.product_id.name_template, - 'origin': sm.picking_id.name, + 'origin': sm.picking_id.name or sm.name, 'uom_id': sm.product_uom.id, 'operation_id': operation.id, 'product_qty': sm.product_uom_qty, @@ -64,20 +68,26 @@ class RmaAddStockMove(models.TransientModel): [('rma_selectable', '=', True)], limit=1) if not route: raise ValidationError("Please define an rma route") + + if not operation.in_warehouse_id or not operation.out_warehouse_id: + warehouse = self.env['stock.warehouse'].search( + [('company_id', '=', self.rma_id.company_id.id), + ('lot_rma_id', '!=', False)], limit=1) + if not warehouse: + raise ValidationError("Please define a warehouse with a " + "default rma location") data.update( - {'in_route_id': operation.in_route_id.id, - 'out_route_id': operation.out_route_id.id, - 'receipt_policy': operation.receipt_policy, + {'receipt_policy': operation.receipt_policy, 'operation_id': operation.id, - 'refund_policy': operation.refund_policy, - 'delivery_policy': operation.delivery_policy + 'delivery_policy': operation.delivery_policy, + 'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, + 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, + 'in_route_id': operation.in_route_id.id or route.id, + 'out_route_id': operation.out_route_id.id or route.id, + 'location_id': (operation.location_id.id or + operation.in_warehouse_id.lot_rma_id.id or + warehouse.lot_rma_id.id) }) - if operation.in_warehouse_id: - data['in_warehouse_id'] = operation.in_warehouse_id.id - if operation.out_warehouse_id: - data['out_warehouse_id'] = operation.out_warehouse_id.id - if operation.location_id: - data['location_id'] = operation.location_id.id return data @api.model diff --git a/rma/wizards/rma_order_line_make_supplier_rma.py b/rma/wizards/rma_order_line_make_supplier_rma.py index 2f258c68..59ae981e 100644 --- a/rma/wizards/rma_order_line_make_supplier_rma.py +++ b/rma/wizards/rma_order_line_make_supplier_rma.py @@ -4,6 +4,7 @@ import openerp.addons.decimal_precision as dp from openerp import _, api, exceptions, fields, models +from openerp.exceptions import ValidationError class RmaLineMakeSupplierRma(models.TransientModel): @@ -48,7 +49,10 @@ class RmaLineMakeSupplierRma(models.TransientModel): for line in lines: items.append([0, 0, self._prepare_item(line)]) suppliers = lines.mapped('supplier_address_id') - if len(suppliers) == 1: + if len(suppliers) == 0: + raise exceptions.Warning( + _('Please specify a supplier address')) + elif len(suppliers) == 1: res['partner_id'] = suppliers.id else: raise exceptions.Warning( @@ -73,7 +77,8 @@ class RmaLineMakeSupplierRma(models.TransientModel): def _prepare_supplier_rma_line(self, rma, item): operation = self.env['rma.operation'].search( [('type', '=', 'supplier')], limit=1) - return { + data = { + 'type': 'supplier', 'origin': item.line_id.rma_id.name, 'delivery_address_id': item.line_id.delivery_address_id.id, @@ -81,20 +86,38 @@ class RmaLineMakeSupplierRma(models.TransientModel): 'customer_rma_id': item.line_id.id, 'product_qty': item.product_qty, 'rma_id': rma.id, + 'uom_id': item.uom_id.id, 'operation_id': operation.id, 'receipt_policy': operation.receipt_policy, 'delivery_policy': operation.delivery_policy, - 'in_warehouse_id': operation.in_warehouse_id.id, - 'out_warehouse_id': operation.out_warehouse_id.id, - 'location_id': operation.location_id.id, 'supplier_to_customer': operation.supplier_to_customer, - 'in_route_id': operation.in_route_id.id, - 'out_route_id': operation.out_route_id.id, } + if not operation.in_route_id or not operation.out_route_id: + route = self.env['stock.location.route'].search( + [('rma_selectable', '=', True)], limit=1) + if not route: + raise ValidationError(_("Please define an rma route")) + if not operation.in_warehouse_id or not operation.out_warehouse_id: + warehouse = self.env['stock.warehouse'].search( + [('company_id', '=', self.rma_id.company_id.id), + ('lot_rma_id', '!=', False)], limit=1) + if not warehouse: + raise ValidationError(_("Please define a warehouse with a" + " default rma location")) + data.update( + {'in_warehouse_id': operation.in_warehouse_id.id or warehouse.id, + 'out_warehouse_id': operation.out_warehouse_id.id or warehouse.id, + 'in_route_id': operation.in_route_id.id or route.id, + 'out_route_id': operation.out_route_id.id or route.id, + 'location_id': (operation.location_id.id or + operation.in_warehouse_id.lot_rma_id.id or + warehouse.lot_rma_id.id) + }) + return data @api.multi def make_supplier_rma(self): - res = [] + self = self.with_context(supplier=True, customer=False) rma_obj = self.env['rma.order'] rma_line_obj = self.env['rma.order.line'] rma = False @@ -113,16 +136,15 @@ class RmaLineMakeSupplierRma(models.TransientModel): rma_line_data = self._prepare_supplier_rma_line(rma, item) rma_line_obj.create(rma_line_data) - res.append(rma.id) return { - 'domain': "[('id','in', ["+','.join(map(str, res))+"])]", 'name': _('Supplier RMA'), 'view_type': 'form', - 'view_mode': 'tree,form', + 'view_mode': 'form', 'res_model': 'rma.order', 'view_id': False, - 'context': {'supplier': 1}, + 'res_id': rma.id, + 'context': {'supplier': True, 'customer': False}, 'type': 'ir.actions.act_window' } @@ -137,7 +159,8 @@ class RmaLineMakeRmaOrderItem(models.TransientModel): readonly=True) line_id = fields.Many2one('rma.order.line', string='RMA Line', - required=True) + required=True, + ondelete='cascade') rma_id = fields.Many2one('rma.order', related='line_id.rma_id', string='RMA Order', readonly=True) product_id = fields.Many2one('product.product', diff --git a/rma/wizards/rma_order_line_make_supplier_rma_view.xml b/rma/wizards/rma_order_line_make_supplier_rma_view.xml index 85609494..e7ad43c6 100644 --- a/rma/wizards/rma_order_line_make_supplier_rma_view.xml +++ b/rma/wizards/rma_order_line_make_supplier_rma_view.xml @@ -13,7 +13,7 @@ - +