Merge PR #181 into 12.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot
2020-11-09 12:30:40 +00:00
12 changed files with 99 additions and 20 deletions

View File

@@ -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

View File

@@ -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)",

View File

@@ -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"
)

View File

@@ -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,
}

View File

@@ -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,

View File

@@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/rma/tree/12.0/rma"><img alt="OCA/rma" src="https://img.shields.io/badge/github-OCA%2Frma-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/rma-12-0/rma-12-0-rma"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/145/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/rma/tree/12.0/rma"><img alt="OCA/rma" src="https://img.shields.io/badge/github-OCA%2Frma-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/rma-12-0/rma-12-0-rma"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/145/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module allows you to manage <a class="reference external" href="https://en.wikipedia.org/wiki/Return_merchandise_authorization">Return Merchandise Authorization (RMA)</a>.
RMA documents can be created from scratch, from a delivery order or from
an incoming email. Product receptions and returning delivery operations

View File

@@ -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

View File

@@ -172,6 +172,7 @@
<group>
<group>
<field name="partner_id" widget="res_partner_many2one" context="{'search_default_customer':1, 'show_address': 1, 'show_vat': True}" options="{'always_reload': True}"/>
<field name="partner_shipping_id"/>
<field name="partner_invoice_id"/>
<field name="picking_id"
options="{'no_create': True}"/>

View File

@@ -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:

View File

@@ -30,6 +30,30 @@
</ul>
</span>
</div>
<t
t-set="delivery_addresses"
t-value="sale_order.partner_id.commercial_partner_id.mapped('child_ids').filtered(lambda x: x.type in ['contact', 'delivery'])"
/>
<button
class="btn btn-primary btn-block mb8"
type="button" data-toggle="collapse"
data-target="#delivery_address_picker"
aria-expanded="false"
><i class="fa fa-truck" /> Choose a delivery address</button>
<div class="col-lg-12 collapse mt8" id="delivery_address_picker">
<div data-toggle="buttons" class="row">
<label t-attf-class="card mr4 btn btn-light" t-foreach="delivery_addresses" t-as="address">
<input class="d-none" type="radio" name="partner_shipping_id" t-att-value="address.id">
<strong>
<i t-attf-class="text-secondary fa #{address.type == 'delivery' and 'fa-truck' or 'fa-user'}" />
<t t-esc="address.name"/>
</strong>
<pre><h6 t-esc="address.contact_address" /></pre>
</input>
</label>
</div>
</div>
<t t-set="data_list" t-value="sale_order.get_delivery_rma_data()"/>
<t t-set="operations" t-value="sale_order.env['rma.operation'].search([])"/>
<table class="table table-sm" id="request-rma-table">

View File

@@ -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,

View File

@@ -31,6 +31,8 @@
</field>
</group>
<group>
<field name="commercial_partner_id" invisible="1" />
<field name="partner_shipping_id" domain="[('id', 'child_of', commercial_partner_id)]" />
<field name="location_id"
options="{'no_create': True, 'no_open': True}"
groups="stock.group_stock_multi_locations"