diff --git a/rma/README.rst b/rma/README.rst index dea2df0f..a0b89159 100644 --- a/rma/README.rst +++ b/rma/README.rst @@ -7,9 +7,9 @@ Return Merchandise Authorization Management !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png +.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png :target: https://odoo-community.org/page/development-status - :alt: Beta + :alt: Production/Stable .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 diff --git a/rma/__manifest__.py b/rma/__manifest__.py index d480190a..5eb036d3 100644 --- a/rma/__manifest__.py +++ b/rma/__manifest__.py @@ -1,10 +1,12 @@ # Copyright 2020 Tecnativa - Ernesto Tejeda +# Copyright 2020 Tecnativa - David Vidal +# Copyright 2020 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Return Merchandise Authorization Management", "summary": "Return Merchandise Authorization (RMA)", - "version": "12.0.1.6.1", - "development_status": "Beta", + "version": "12.0.2.0.0", + "development_status": "Production/Stable", "category": "RMA", "website": "https://github.com/OCA/rma", "author": "Tecnativa, Odoo Community Association (OCA)", diff --git a/rma/migrations/12.0.2.0.0/post-migration.py b/rma/migrations/12.0.2.0.0/post-migration.py index 77fe95b4..e36a2fec 100644 --- a/rma/migrations/12.0.2.0.0/post-migration.py +++ b/rma/migrations/12.0.2.0.0/post-migration.py @@ -8,3 +8,9 @@ def migrate(env, version): # Convert Text description field to Html openupgrade.convert_field_to_html( env.cr, "rma", "description", "description") + # Put the same shipping address than customer for existing RMAs + openupgrade.logged_query( + env.cr, + "UPDATE rma SET partner_shipping_id = partner_id " + "WHERE partner_shipping_id IS NULL" + ) diff --git a/rma/models/rma.py b/rma/models/rma.py index ee40d060..5ce84484 100644 --- a/rma/models/rma.py +++ b/rma/models/rma.py @@ -85,6 +85,13 @@ class Rma(models.Model): index=True, track_visibility='always' ) + partner_shipping_id = fields.Many2one( + string="Shipping Address", + comodel_name="res.partner", + readonly=True, + states={'draft': [('readonly', False)]}, + help="Shipping address for current RMA." + ) partner_invoice_id = fields.Many2one( string="Invoice Address", comodel_name="res.partner", @@ -416,7 +423,9 @@ class Rma(models.Model): record.access_url = '/my/rmas/{}'.format(record.id) # Constrains methods (@api.constrains) - @api.constrains('state', 'partner_id', 'partner_invoice_id', 'product_id') + @api.constrains( + 'state', 'partner_id', 'partner_invoice_id', + 'partner_shipping_id', 'product_id') def _check_required_after_draft(self): """ Check that RMAs are being created or edited with the necessary fields filled out. Only applies to 'Draft' and @@ -444,10 +453,13 @@ class Rma(models.Model): def _onchange_partner_id(self): self.picking_id = False partner_invoice_id = False + partner_shipping_id = False if self.partner_id: - address = self.partner_id.address_get(['invoice']) + address = self.partner_id.address_get(['invoice', 'delivery']) partner_invoice_id = address.get('invoice', False) + partner_shipping_id = address.get('delivery', False) self.partner_invoice_id = partner_invoice_id + self.partner_shipping_id = partner_shipping_id @api.onchange("picking_id") def _onchange_picking_id(self): @@ -718,7 +730,10 @@ class Rma(models.Model): # Validation business methods def _ensure_required_fields(self): """ This method is used to ensure the following fields are not empty: - ['partner_id', 'partner_invoice_id', 'product_id', 'location_id'] + [ + 'partner_id', 'partner_invoice_id', 'partner_shipping_id', + 'product_id', 'location_id' + ] This method is intended to be called on confirm RMA action and is invoked by: @@ -726,8 +741,10 @@ class Rma(models.Model): rma.action_confirm """ ir_translation = self.env['ir.translation'] - required = ['partner_id', 'partner_invoice_id', 'product_id', - 'location_id'] + required = [ + 'partner_id', 'partner_invoice_id', 'partner_shipping_id', + 'product_id', 'location_id' + ] for record in self: desc = "" for field in filter(lambda item: not record[item], required): @@ -854,7 +871,7 @@ class Rma(models.Model): def _prepare_picking(self, picking_form): picking_form.company_id = self.company_id picking_form.origin = self.name - picking_form.partner_id = self.partner_id + picking_form.partner_id = self.partner_shipping_id picking_form.location_dest_id = self.location_id with picking_form.move_ids_without_package.new() as move_form: move_form.product_id = self.product_id @@ -938,7 +955,7 @@ class Rma(models.Model): self._ensure_qty_to_return(qty, uom) group_dict = {} for record in self.filtered('can_be_returned'): - key = (record.partner_id.id, record.company_id.id, + key = (record.partner_shipping_id.id, record.company_id.id, record.warehouse_id) group_dict.setdefault(key, self.env['rma']) group_dict[key] |= record @@ -987,7 +1004,7 @@ class Rma(models.Model): picking_form.picking_type_id = self.warehouse_id.rma_out_type_id picking_form.company_id = self.company_id picking_form.origin = origin or self.name - picking_form.partner_id = self.partner_id + picking_form.partner_id = self.partner_shipping_id def _prepare_returning_move(self, move_form, scheduled_date, quantity=None, uom=None): @@ -1049,7 +1066,7 @@ class Rma(models.Model): self.procurement_group_id = self.env['procurement.group'].create({ 'name': self.name, 'move_type': 'direct', - 'partner_id': self.partner_id.id, + 'partner_id': self.partner_shipping_id.id, }).id values = self._prepare_procurement_values( self.procurement_group_id, scheduled_date, warehouse) @@ -1057,7 +1074,7 @@ class Rma(models.Model): product, qty, uom, - self.partner_id.property_stock_customer, + self.partner_shipping_id.property_stock_customer, self.product_id.display_name, self.procurement_group_id.name, values, @@ -1075,7 +1092,7 @@ class Rma(models.Model): 'group_id': group_id, 'date_planned': scheduled_date, 'warehouse_id': warehouse, - 'partner_id': self.partner_id.id, + 'partner_id': self.partner_shipping_id.id, 'rma_id': self.id, 'priority': self.priority, } diff --git a/rma/models/stock_move.py b/rma/models/stock_move.py index 217d4c6c..de27c20e 100644 --- a/rma/models/stock_move.py +++ b/rma/models/stock_move.py @@ -100,13 +100,18 @@ class StockMove(models.Model): partner = original_picking.partner_id if hasattr(original_picking, 'sale_id') and original_picking.sale_id: partner_invoice_id = original_picking.sale_id.partner_invoice_id.id + partner_shipping_id = ( + original_picking.sale_id.partner_shipping_id.id) else: partner_invoice_id = partner.address_get( - ['invoice']).get('invoice', False), + ['invoice']).get('invoice', False) + partner_shipping_id = partner.address_get( + ['delivery']).get('delivery', False) return { 'user_id': self.env.user.id, 'partner_id': partner.id, 'partner_invoice_id': partner_invoice_id, + 'partner_shipping_id': partner_shipping_id, 'origin': original_picking.name, 'picking_id': original_picking.id, 'move_id': self.origin_returned_move_id.id, diff --git a/rma/static/description/index.html b/rma/static/description/index.html index 88523ce3..f8c7e665 100644 --- a/rma/static/description/index.html +++ b/rma/static/description/index.html @@ -367,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/rma Translate me on Weblate Try me on Runbot

+

Production/Stable License: AGPL-3 OCA/rma Translate me on Weblate Try me on Runbot

This module allows you to manage Return Merchandise Authorization (RMA). RMA documents can be created from scratch, from a delivery order or from an incoming email. Product receptions and returning delivery operations diff --git a/rma/tests/test_rma.py b/rma/tests/test_rma.py index 106f639d..03463721 100644 --- a/rma/tests/test_rma.py +++ b/rma/tests/test_rma.py @@ -52,6 +52,11 @@ class TestRma(SavepointCase): 'parent_id': cls.partner.id, 'type': 'invoice', }) + cls.partner_shipping = cls.res_partner.create({ + 'name': 'Partner shipping test', + 'parent_id': cls.partner.id, + 'type': 'delivery', + }) def _create_rma(self, partner=None, product=None, qty=None, location=None): rma_form = Form(self.env['rma']) @@ -187,7 +192,8 @@ class TestRma(SavepointCase): rma.action_confirm() self.assertEqual( e.exception.name, - "Required field(s):\nCustomer\nInvoice Address\nProduct\nLocation" + "Required field(s):\nCustomer\nInvoice Address\n" + "Shipping Address\nProduct\nLocation" ) with Form(rma) as rma_form: rma_form.partner_id = self.partner @@ -532,7 +538,7 @@ class TestRma(SavepointCase): self.assertNotEqual(pick_1.partner_id, pick_2.partner_id) self.assertEqual( pick_1.partner_id, - (rma_1 | rma_2 | rma_3).mapped('partner_id'), + (rma_1 | rma_2 | rma_3).mapped('partner_shipping_id'), ) self.assertEqual(pick_2.partner_id, rma_4.partner_id) # Each RMA of (rma_1, rma_2 and rma_3) is linked to a different diff --git a/rma/views/rma_views.xml b/rma/views/rma_views.xml index 6885d52b..bec30fbd 100644 --- a/rma/views/rma_views.xml +++ b/rma/views/rma_views.xml @@ -172,6 +172,7 @@ + diff --git a/rma_sale/controllers/sale_portal.py b/rma_sale/controllers/sale_portal.py index 95c0460a..d63fe6da 100644 --- a/rma_sale/controllers/sale_portal.py +++ b/rma_sale/controllers/sale_portal.py @@ -20,6 +20,7 @@ class CustomerPortal(CustomerPortal): wizard_obj = request.env['sale.order.rma.wizard'] # Set wizard line vals mapped_vals = {} + partner_shipping_id = post.pop("partner_shipping_id", False) for name, value in post.items(): row, field_name = name.split('-', 1) mapped_vals.setdefault(row, {}).update({field_name: value}) @@ -32,7 +33,8 @@ class CustomerPortal(CustomerPortal): location_id = order.warehouse_id.rma_loc_id.id wizard = wizard_obj.with_context(active_id=order_id).create({ 'line_ids': line_vals, - 'location_id': location_id + 'location_id': location_id, + 'partner_shipping_id': partner_shipping_id, }) rma = wizard.sudo().create_rma() for rec in rma: diff --git a/rma_sale/views/sale_portal_template.xml b/rma_sale/views/sale_portal_template.xml index c361b63f..3d999a16 100644 --- a/rma_sale/views/sale_portal_template.xml +++ b/rma_sale/views/sale_portal_template.xml @@ -30,6 +30,30 @@ + + +

+
+ +
+
diff --git a/rma_sale/wizard/sale_order_rma_wizard.py b/rma_sale/wizard/sale_order_rma_wizard.py index 30142fad..96410bd8 100644 --- a/rma_sale/wizard/sale_order_rma_wizard.py +++ b/rma_sale/wizard/sale_order_rma_wizard.py @@ -28,6 +28,16 @@ class SaleOrderRmaWizard(models.TransientModel): domain=_domain_location_id, default=lambda r: r.order_id.warehouse_id.rma_loc_id.id, ) + commercial_partner_id = fields.Many2one( + comodel_name="res.partner", + related="order_id.partner_id.commercial_partner_id", + string="Commercial entity", + ) + partner_shipping_id = fields.Many2one( + comodel_name="res.partner", + string="Shipping Address", + help="Will be used to return the goods when the RMA is completed", + ) def create_rma(self, from_portal=None): self.ensure_one() @@ -151,9 +161,13 @@ class SaleOrderLineRmaWizard(models.TransientModel): def _prepare_rma_values(self): self.ensure_one() + partner_shipping = ( + self.wizard_id.partner_shipping_id or + self.order_id.partner_shipping_id) return { 'partner_id': self.order_id.partner_id.id, 'partner_invoice_id': self.order_id.partner_invoice_id.id, + 'partner_shipping_id': partner_shipping.id, 'origin': self.order_id.name, 'company_id': self.order_id.company_id.id, 'location_id': self.wizard_id.location_id.id, diff --git a/rma_sale/wizard/sale_order_rma_wizard_views.xml b/rma_sale/wizard/sale_order_rma_wizard_views.xml index 86a3997a..8d7a7e22 100644 --- a/rma_sale/wizard/sale_order_rma_wizard_views.xml +++ b/rma_sale/wizard/sale_order_rma_wizard_views.xml @@ -31,6 +31,8 @@ + +