mirror of
https://github.com/OCA/rma.git
synced 2025-02-16 17:11:47 +02:00
[IMP] rma, rma_sale: shipping address
Allow to set the desired shipping address where the goods must be returned after the RMA is processed.
This commit is contained in:
@@ -73,6 +73,13 @@ class Rma(models.Model):
|
|||||||
index=True,
|
index=True,
|
||||||
tracking=True,
|
tracking=True,
|
||||||
)
|
)
|
||||||
|
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(
|
partner_invoice_id = fields.Many2one(
|
||||||
string="Invoice Address",
|
string="Invoice Address",
|
||||||
comodel_name="res.partner",
|
comodel_name="res.partner",
|
||||||
@@ -385,7 +392,9 @@ class Rma(models.Model):
|
|||||||
record.access_url = "/my/rmas/{}".format(record.id)
|
record.access_url = "/my/rmas/{}".format(record.id)
|
||||||
|
|
||||||
# Constrains methods (@api.constrains)
|
# Constrains methods (@api.constrains)
|
||||||
@api.constrains("state", "partner_id", "partner_invoice_id", "product_id")
|
@api.constrains(
|
||||||
|
"state", "partner_id", "partner_shipping_id", "partner_invoice_id", "product_id"
|
||||||
|
)
|
||||||
def _check_required_after_draft(self):
|
def _check_required_after_draft(self):
|
||||||
""" Check that RMAs are being created or edited with the
|
""" Check that RMAs are being created or edited with the
|
||||||
necessary fields filled out. Only applies to 'Draft' and
|
necessary fields filled out. Only applies to 'Draft' and
|
||||||
@@ -420,10 +429,13 @@ class Rma(models.Model):
|
|||||||
def _onchange_partner_id(self):
|
def _onchange_partner_id(self):
|
||||||
self.picking_id = False
|
self.picking_id = False
|
||||||
partner_invoice_id = False
|
partner_invoice_id = False
|
||||||
|
partner_shipping_id = False
|
||||||
if self.partner_id:
|
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_invoice_id = address.get("invoice", False)
|
||||||
|
partner_shipping_id = address.get("delivery", False)
|
||||||
self.partner_invoice_id = partner_invoice_id
|
self.partner_invoice_id = partner_invoice_id
|
||||||
|
self.partner_shipping_id = partner_shipping_id
|
||||||
|
|
||||||
@api.onchange("picking_id")
|
@api.onchange("picking_id")
|
||||||
def _onchange_picking_id(self):
|
def _onchange_picking_id(self):
|
||||||
@@ -723,7 +735,10 @@ class Rma(models.Model):
|
|||||||
# Validation business methods
|
# Validation business methods
|
||||||
def _ensure_required_fields(self):
|
def _ensure_required_fields(self):
|
||||||
""" This method is used to ensure the following fields are not empty:
|
""" 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
|
This method is intended to be called on confirm RMA action and is
|
||||||
invoked by:
|
invoked by:
|
||||||
@@ -731,7 +746,13 @@ class Rma(models.Model):
|
|||||||
rma.action_confirm
|
rma.action_confirm
|
||||||
"""
|
"""
|
||||||
ir_translation = self.env["ir.translation"]
|
ir_translation = self.env["ir.translation"]
|
||||||
required = ["partner_id", "partner_invoice_id", "product_id", "location_id"]
|
required = [
|
||||||
|
"partner_id",
|
||||||
|
"partner_shipping_id",
|
||||||
|
"partner_invoice_id",
|
||||||
|
"product_id",
|
||||||
|
"location_id",
|
||||||
|
]
|
||||||
for record in self:
|
for record in self:
|
||||||
desc = ""
|
desc = ""
|
||||||
for field in filter(lambda item: not record[item], required):
|
for field in filter(lambda item: not record[item], required):
|
||||||
@@ -863,7 +884,7 @@ class Rma(models.Model):
|
|||||||
|
|
||||||
def _prepare_picking(self, picking_form):
|
def _prepare_picking(self, picking_form):
|
||||||
picking_form.origin = self.name
|
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
|
picking_form.location_dest_id = self.location_id
|
||||||
with picking_form.move_ids_without_package.new() as move_form:
|
with picking_form.move_ids_without_package.new() as move_form:
|
||||||
move_form.product_id = self.product_id
|
move_form.product_id = self.product_id
|
||||||
@@ -962,7 +983,11 @@ class Rma(models.Model):
|
|||||||
group_dict = {}
|
group_dict = {}
|
||||||
rmas_to_return = self.filtered("can_be_returned")
|
rmas_to_return = self.filtered("can_be_returned")
|
||||||
for record in rmas_to_return:
|
for record in rmas_to_return:
|
||||||
key = (record.partner_id.id, record.company_id.id, record.warehouse_id)
|
key = (
|
||||||
|
record.partner_shipping_id.id,
|
||||||
|
record.company_id.id,
|
||||||
|
record.warehouse_id,
|
||||||
|
)
|
||||||
group_dict.setdefault(key, self.env["rma"])
|
group_dict.setdefault(key, self.env["rma"])
|
||||||
group_dict[key] |= record
|
group_dict[key] |= record
|
||||||
for rmas in group_dict.values():
|
for rmas in group_dict.values():
|
||||||
@@ -1010,7 +1035,7 @@ class Rma(models.Model):
|
|||||||
def _prepare_returning_picking(self, picking_form, origin=None):
|
def _prepare_returning_picking(self, picking_form, origin=None):
|
||||||
picking_form.picking_type_id = self.warehouse_id.rma_out_type_id
|
picking_form.picking_type_id = self.warehouse_id.rma_out_type_id
|
||||||
picking_form.origin = origin or self.name
|
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(
|
def _prepare_returning_move(
|
||||||
self, move_form, scheduled_date, quantity=None, uom=None
|
self, move_form, scheduled_date, quantity=None, uom=None
|
||||||
@@ -1076,7 +1101,7 @@ class Rma(models.Model):
|
|||||||
{
|
{
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"move_type": "direct",
|
"move_type": "direct",
|
||||||
"partner_id": self.partner_id.id,
|
"partner_id": self.partner_shipping_id.id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.id
|
.id
|
||||||
@@ -1088,7 +1113,7 @@ class Rma(models.Model):
|
|||||||
product,
|
product,
|
||||||
qty,
|
qty,
|
||||||
uom,
|
uom,
|
||||||
self.partner_id.property_stock_customer,
|
self.partner_shipping_id.property_stock_customer,
|
||||||
self.product_id.display_name,
|
self.product_id.display_name,
|
||||||
self.procurement_group_id.name,
|
self.procurement_group_id.name,
|
||||||
self.company_id,
|
self.company_id,
|
||||||
@@ -1106,7 +1131,7 @@ class Rma(models.Model):
|
|||||||
"group_id": group_id,
|
"group_id": group_id,
|
||||||
"date_planned": scheduled_date,
|
"date_planned": scheduled_date,
|
||||||
"warehouse_id": warehouse,
|
"warehouse_id": warehouse,
|
||||||
"partner_id": self.partner_id.id,
|
"partner_id": self.partner_shipping_id.id,
|
||||||
"rma_id": self.id,
|
"rma_id": self.id,
|
||||||
"priority": self.priority,
|
"priority": self.priority,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,13 +96,16 @@ class StockMove(models.Model):
|
|||||||
partner = original_picking.partner_id
|
partner = original_picking.partner_id
|
||||||
if hasattr(original_picking, "sale_id") and original_picking.sale_id:
|
if hasattr(original_picking, "sale_id") and original_picking.sale_id:
|
||||||
partner_invoice_id = original_picking.sale_id.partner_invoice_id.id
|
partner_invoice_id = original_picking.sale_id.partner_invoice_id.id
|
||||||
|
partner_shipping_id = original_picking.sale_id.partner_shipping_id.id
|
||||||
else:
|
else:
|
||||||
partner_invoice_id = (
|
partner_invoice_id = partner.address_get(["invoice"]).get("invoice", False)
|
||||||
partner.address_get(["invoice"]).get("invoice", False),
|
partner_shipping_id = partner.address_get(["delivery"]).get(
|
||||||
|
"delivery", False
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
"user_id": self.env.user.id,
|
"user_id": self.env.user.id,
|
||||||
"partner_id": partner.id,
|
"partner_id": partner.id,
|
||||||
|
"partner_shipping_id": partner_shipping_id,
|
||||||
"partner_invoice_id": partner_invoice_id,
|
"partner_invoice_id": partner_invoice_id,
|
||||||
"origin": original_picking.name,
|
"origin": original_picking.name,
|
||||||
"picking_id": original_picking.id,
|
"picking_id": original_picking.id,
|
||||||
|
|||||||
@@ -44,6 +44,13 @@ class TestRma(SavepointCase):
|
|||||||
"type": "invoice",
|
"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):
|
def _create_rma(self, partner=None, product=None, qty=None, location=None):
|
||||||
rma_form = Form(self.env["rma"])
|
rma_form = Form(self.env["rma"])
|
||||||
@@ -181,7 +188,8 @@ class TestRma(SavepointCase):
|
|||||||
rma.action_confirm()
|
rma.action_confirm()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
e.exception.name,
|
e.exception.name,
|
||||||
"Required field(s):\nCustomer\nInvoice Address\nProduct\nLocation",
|
"Required field(s):\nCustomer\nShipping Address\nInvoice Address\n"
|
||||||
|
"Product\nLocation",
|
||||||
)
|
)
|
||||||
with Form(rma) as rma_form:
|
with Form(rma) as rma_form:
|
||||||
rma_form.partner_id = self.partner
|
rma_form.partner_id = self.partner
|
||||||
@@ -531,7 +539,7 @@ class TestRma(SavepointCase):
|
|||||||
# One picking per partner
|
# One picking per partner
|
||||||
self.assertNotEqual(pick_1.partner_id, pick_2.partner_id)
|
self.assertNotEqual(pick_1.partner_id, pick_2.partner_id)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
pick_1.partner_id, (rma_1 | rma_2 | rma_3).mapped("partner_id"),
|
pick_1.partner_id, (rma_1 | rma_2 | rma_3).mapped("partner_shipping_id"),
|
||||||
)
|
)
|
||||||
self.assertEqual(pick_2.partner_id, rma_4.partner_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
|
# Each RMA of (rma_1, rma_2 and rma_3) is linked to a different
|
||||||
|
|||||||
@@ -239,6 +239,7 @@
|
|||||||
context="{'search_default_customer':1, 'show_address': 1, 'show_vat': True}"
|
context="{'search_default_customer':1, 'show_address': 1, 'show_vat': True}"
|
||||||
options="{'always_reload': True}"
|
options="{'always_reload': True}"
|
||||||
/>
|
/>
|
||||||
|
<field name="partner_shipping_id" />
|
||||||
<field name="partner_invoice_id" />
|
<field name="partner_invoice_id" />
|
||||||
<field name="picking_id" options="{'no_create': True}" />
|
<field name="picking_id" options="{'no_create': True}" />
|
||||||
<field
|
<field
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class CustomerPortal(CustomerPortal):
|
|||||||
wizard_obj = request.env["sale.order.rma.wizard"]
|
wizard_obj = request.env["sale.order.rma.wizard"]
|
||||||
# Set wizard line vals
|
# Set wizard line vals
|
||||||
mapped_vals = {}
|
mapped_vals = {}
|
||||||
|
partner_shipping_id = post.pop("partner_shipping_id", False)
|
||||||
for name, value in post.items():
|
for name, value in post.items():
|
||||||
row, field_name = name.split("-", 1)
|
row, field_name = name.split("-", 1)
|
||||||
mapped_vals.setdefault(row, {}).update({field_name: value})
|
mapped_vals.setdefault(row, {}).update({field_name: value})
|
||||||
@@ -38,7 +39,11 @@ class CustomerPortal(CustomerPortal):
|
|||||||
order = order_obj.browse(order_id).sudo()
|
order = order_obj.browse(order_id).sudo()
|
||||||
location_id = order.warehouse_id.rma_loc_id.id
|
location_id = order.warehouse_id.rma_loc_id.id
|
||||||
wizard = wizard_obj.with_context(active_id=order_id).create(
|
wizard = wizard_obj.with_context(active_id=order_id).create(
|
||||||
{"line_ids": line_vals, "location_id": location_id}
|
{
|
||||||
|
"line_ids": line_vals,
|
||||||
|
"location_id": location_id,
|
||||||
|
"partner_shipping_id": partner_shipping_id,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
rma = wizard.sudo().create_rma(from_portal=True)
|
rma = wizard.sudo().create_rma(from_portal=True)
|
||||||
for rec in rma:
|
for rec in rma:
|
||||||
|
|||||||
@@ -67,6 +67,48 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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
|
||||||
t-set="data_list"
|
t-set="data_list"
|
||||||
t-value="sale_order.get_delivery_rma_data()"
|
t-value="sale_order.get_delivery_rma_data()"
|
||||||
|
|||||||
@@ -27,6 +27,16 @@ class SaleOrderRmaWizard(models.TransientModel):
|
|||||||
domain=_domain_location_id,
|
domain=_domain_location_id,
|
||||||
default=lambda r: r.order_id.warehouse_id.rma_loc_id.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):
|
def create_rma(self, from_portal=None):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
@@ -147,9 +157,13 @@ class SaleOrderLineRmaWizard(models.TransientModel):
|
|||||||
|
|
||||||
def _prepare_rma_values(self):
|
def _prepare_rma_values(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
|
partner_shipping = (
|
||||||
|
self.wizard_id.partner_shipping_id or self.order_id.partner_shipping_id
|
||||||
|
)
|
||||||
return {
|
return {
|
||||||
"partner_id": self.order_id.partner_id.id,
|
"partner_id": self.order_id.partner_id.id,
|
||||||
"partner_invoice_id": self.order_id.partner_invoice_id.id,
|
"partner_invoice_id": self.order_id.partner_invoice_id.id,
|
||||||
|
"partner_shipping_id": partner_shipping.id,
|
||||||
"origin": self.order_id.name,
|
"origin": self.order_id.name,
|
||||||
"company_id": self.order_id.company_id.id,
|
"company_id": self.order_id.company_id.id,
|
||||||
"location_id": self.wizard_id.location_id.id,
|
"location_id": self.wizard_id.location_id.id,
|
||||||
|
|||||||
@@ -31,6 +31,11 @@
|
|||||||
</field>
|
</field>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
|
<field name="commercial_partner_id" invisible="1" />
|
||||||
|
<field
|
||||||
|
name="partner_shipping_id"
|
||||||
|
domain="[('id', 'child_of', commercial_partner_id)]"
|
||||||
|
/>
|
||||||
<field
|
<field
|
||||||
name="location_id"
|
name="location_id"
|
||||||
options="{'no_create': True, 'no_open': True}"
|
options="{'no_create': True, 'no_open': True}"
|
||||||
|
|||||||
Reference in New Issue
Block a user