mirror of
https://github.com/OCA/rma.git
synced 2025-02-16 17:11:47 +02:00
[MIG] rma: Migration to 17.0
This commit is contained in:
@@ -87,8 +87,8 @@ To use this module, you need to:
|
|||||||
quantity to another RMA, preview the RMA in the website. All of these
|
quantity to another RMA, preview the RMA in the website. All of these
|
||||||
operations can be done by clicking on the buttons in the status bar.
|
operations can be done by clicking on the buttons in the status bar.
|
||||||
|
|
||||||
- If you click on 'Refund' button, a refund will be created, and it
|
- If you click on 'To Refund' button, a refund will be created, and
|
||||||
will be accessible via the smart button labeled Refund. The RMA
|
it will be accessible via the smart button labeled Refund. The RMA
|
||||||
will be set automatically to 'Refunded' state when the refund is
|
will be set automatically to 'Refunded' state when the refund is
|
||||||
validated.
|
validated.
|
||||||
- If you click on 'Replace' or 'Return to customer' button instead,
|
- If you click on 'Replace' or 'Return to customer' button instead,
|
||||||
@@ -171,6 +171,9 @@ Contributors
|
|||||||
|
|
||||||
- Chafique Delli <chafique.delli@akretion.com>
|
- Chafique Delli <chafique.delli@akretion.com>
|
||||||
- Giovanni Serra - Ooops <giovanni@ooops404.com>
|
- Giovanni Serra - Ooops <giovanni@ooops404.com>
|
||||||
|
- `APSL-Nagarro <https://www.apsl.tech>`__:
|
||||||
|
|
||||||
|
- Antoni Marroig <amarroig@apsl.net>
|
||||||
|
|
||||||
Maintainers
|
Maintainers
|
||||||
-----------
|
-----------
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Return Merchandise Authorization Management",
|
"name": "Return Merchandise Authorization Management",
|
||||||
"summary": "Return Merchandise Authorization (RMA)",
|
"summary": "Return Merchandise Authorization (RMA)",
|
||||||
"version": "16.0.1.2.0",
|
"version": "17.0.1.0.0",
|
||||||
"development_status": "Production/Stable",
|
"development_status": "Production/Stable",
|
||||||
"category": "RMA",
|
"category": "RMA",
|
||||||
"website": "https://github.com/OCA/rma",
|
"website": "https://github.com/OCA/rma",
|
||||||
|
|||||||
@@ -41,8 +41,7 @@
|
|||||||
<field
|
<field
|
||||||
name="subject"
|
name="subject"
|
||||||
>{{object.company_id.name}} RMA (Ref {{object.name or 'n/a' }})</field>
|
>{{object.company_id.name}} RMA (Ref {{object.name or 'n/a' }})</field>
|
||||||
<field name="report_template" ref="report_rma_action" />
|
<field name="report_template_ids" eval="[(4, ref('rma.report_rma_action'))]" />
|
||||||
<field name="report_name">{{(object.name or '')}}</field>
|
|
||||||
<field name="lang">{{object.partner_id.lang}}</field>
|
<field name="lang">{{object.partner_id.lang}}</field>
|
||||||
<field name="auto_delete" eval="True" />
|
<field name="auto_delete" eval="True" />
|
||||||
<field name="body_html" type="html">
|
<field name="body_html" type="html">
|
||||||
@@ -78,8 +77,7 @@
|
|||||||
<field
|
<field
|
||||||
name="subject"
|
name="subject"
|
||||||
>{{object.company_id.name}} RMA (Ref {{object.name or 'n/a' }}) products received</field>
|
>{{object.company_id.name}} RMA (Ref {{object.name or 'n/a' }}) products received</field>
|
||||||
<field name="report_template" ref="report_rma_action" />
|
<field name="report_template_ids" eval="[(4, ref('rma.report_rma_action'))]" />
|
||||||
<field name="report_name">{{(object.name or '')}}</field>
|
|
||||||
<field name="lang">{{object.partner_id.lang}}</field>
|
<field name="lang">{{object.partner_id.lang}}</field>
|
||||||
<field name="auto_delete" eval="True" />
|
<field name="auto_delete" eval="True" />
|
||||||
<field name="body_html" type="html">
|
<field name="body_html" type="html">
|
||||||
@@ -114,8 +112,7 @@
|
|||||||
<field
|
<field
|
||||||
name="subject"
|
name="subject"
|
||||||
>{{object.company_id.name}} Your RMA has been succesfully created (Ref {{object.name or 'n/a' }})</field>
|
>{{object.company_id.name}} Your RMA has been succesfully created (Ref {{object.name or 'n/a' }})</field>
|
||||||
<field name="report_template" ref="report_rma_action" />
|
<field name="report_template_ids" eval="[(4, ref('rma.report_rma_action'))]" />
|
||||||
<field name="report_name">{{(object.name or '')}}</field>
|
|
||||||
<field name="lang">{{object.partner_id.lang}}</field>
|
<field name="lang">{{object.partner_id.lang}}</field>
|
||||||
<field name="auto_delete" eval="True" />
|
<field name="auto_delete" eval="True" />
|
||||||
<field name="body_html" type="html">
|
<field name="body_html" type="html">
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
# Copyright 2020 Tecnativa - Ernesto Tejeda
|
# Copyright 2020 Tecnativa - Ernesto Tejeda
|
||||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import SUPERUSER_ID, api
|
|
||||||
|
|
||||||
|
|
||||||
def post_init_hook(cr, registry):
|
|
||||||
env = api.Environment(cr, SUPERUSER_ID, {})
|
|
||||||
|
|
||||||
|
def post_init_hook(env):
|
||||||
def _get_next_picking_type_color():
|
def _get_next_picking_type_color():
|
||||||
"""Choose the next available color for the operation types."""
|
"""Choose the next available color for the operation types."""
|
||||||
stock_picking_type = env["stock.picking.type"]
|
stock_picking_type = env["stock.picking.type"]
|
||||||
|
|||||||
@@ -35,60 +35,37 @@ class Rma(models.Model):
|
|||||||
sent = fields.Boolean()
|
sent = fields.Boolean()
|
||||||
name = fields.Char(
|
name = fields.Char(
|
||||||
index=True,
|
index=True,
|
||||||
readonly=True,
|
|
||||||
states={"draft": [("readonly", False)]},
|
|
||||||
copy=False,
|
copy=False,
|
||||||
default=lambda self: _("New"),
|
default=lambda self: _("New"),
|
||||||
)
|
)
|
||||||
origin = fields.Char(
|
origin = fields.Char(
|
||||||
string="Source Document",
|
string="Source Document",
|
||||||
states={
|
|
||||||
"locked": [("readonly", True)],
|
|
||||||
"cancelled": [("readonly", True)],
|
|
||||||
},
|
|
||||||
help="Reference of the document that generated this RMA.",
|
help="Reference of the document that generated this RMA.",
|
||||||
)
|
)
|
||||||
date = fields.Datetime(
|
date = fields.Datetime(
|
||||||
default=fields.Datetime.now,
|
default=fields.Datetime.now,
|
||||||
index=True,
|
index=True,
|
||||||
required=True,
|
required=True,
|
||||||
readonly=True,
|
|
||||||
states={"draft": [("readonly", False)]},
|
|
||||||
)
|
|
||||||
deadline = fields.Date(
|
|
||||||
states={
|
|
||||||
"locked": [("readonly", True)],
|
|
||||||
"cancelled": [("readonly", True)],
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
deadline = fields.Date()
|
||||||
user_id = fields.Many2one(
|
user_id = fields.Many2one(
|
||||||
comodel_name="res.users",
|
comodel_name="res.users",
|
||||||
string="Responsible",
|
string="Responsible",
|
||||||
index=True,
|
index=True,
|
||||||
tracking=True,
|
tracking=True,
|
||||||
states={
|
|
||||||
"locked": [("readonly", True)],
|
|
||||||
"cancelled": [("readonly", True)],
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
team_id = fields.Many2one(
|
team_id = fields.Many2one(
|
||||||
comodel_name="rma.team",
|
comodel_name="rma.team",
|
||||||
string="RMA team",
|
string="RMA team",
|
||||||
index=True,
|
index=True,
|
||||||
states={
|
|
||||||
"locked": [("readonly", True)],
|
|
||||||
"cancelled": [("readonly", True)],
|
|
||||||
},
|
|
||||||
compute="_compute_team_id",
|
compute="_compute_team_id",
|
||||||
store=True,
|
store=True,
|
||||||
readonly=False,
|
|
||||||
)
|
)
|
||||||
tag_ids = fields.Many2many(comodel_name="rma.tag", string="Tags")
|
tag_ids = fields.Many2many(comodel_name="rma.tag", string="Tags")
|
||||||
finalization_id = fields.Many2one(
|
finalization_id = fields.Many2one(
|
||||||
string="Finalization Reason",
|
string="Finalization Reason",
|
||||||
comodel_name="rma.finalization",
|
comodel_name="rma.finalization",
|
||||||
copy=False,
|
copy=False,
|
||||||
readonly=True,
|
|
||||||
domain=(
|
domain=(
|
||||||
"['|', ('company_id', '=', False), ('company_id', '='," " company_id)]"
|
"['|', ('company_id', '=', False), ('company_id', '='," " company_id)]"
|
||||||
),
|
),
|
||||||
@@ -97,16 +74,10 @@ class Rma(models.Model):
|
|||||||
company_id = fields.Many2one(
|
company_id = fields.Many2one(
|
||||||
comodel_name="res.company",
|
comodel_name="res.company",
|
||||||
default=lambda self: self.env.company,
|
default=lambda self: self.env.company,
|
||||||
states={
|
|
||||||
"locked": [("readonly", True)],
|
|
||||||
"cancelled": [("readonly", True)],
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
partner_id = fields.Many2one(
|
partner_id = fields.Many2one(
|
||||||
string="Customer",
|
string="Customer",
|
||||||
comodel_name="res.partner",
|
comodel_name="res.partner",
|
||||||
readonly=True,
|
|
||||||
states={"draft": [("readonly", False)]},
|
|
||||||
index=True,
|
index=True,
|
||||||
tracking=True,
|
tracking=True,
|
||||||
)
|
)
|
||||||
@@ -143,8 +114,6 @@ class Rma(models.Model):
|
|||||||
" ('partner_id', 'child_of', commercial_partner_id),"
|
" ('partner_id', 'child_of', commercial_partner_id),"
|
||||||
"]"
|
"]"
|
||||||
),
|
),
|
||||||
readonly=True,
|
|
||||||
states={"draft": [("readonly", False)]},
|
|
||||||
)
|
)
|
||||||
move_id = fields.Many2one(
|
move_id = fields.Many2one(
|
||||||
comodel_name="stock.move",
|
comodel_name="stock.move",
|
||||||
@@ -187,18 +156,10 @@ class Rma(models.Model):
|
|||||||
procurement_group_id = fields.Many2one(
|
procurement_group_id = fields.Many2one(
|
||||||
comodel_name="procurement.group",
|
comodel_name="procurement.group",
|
||||||
string="Procurement group",
|
string="Procurement group",
|
||||||
readonly=True,
|
|
||||||
states={
|
|
||||||
"draft": [("readonly", False)],
|
|
||||||
"confirmed": [("readonly", False)],
|
|
||||||
"received": [("readonly", False)],
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
priority = fields.Selection(
|
priority = fields.Selection(
|
||||||
selection=PROCUREMENT_PRIORITIES,
|
selection=PROCUREMENT_PRIORITIES,
|
||||||
default="1",
|
default="1",
|
||||||
readonly=True,
|
|
||||||
states={"draft": [("readonly", False)]},
|
|
||||||
)
|
)
|
||||||
operation_id = fields.Many2one(
|
operation_id = fields.Many2one(
|
||||||
comodel_name="rma.operation",
|
comodel_name="rma.operation",
|
||||||
@@ -222,12 +183,7 @@ class Rma(models.Model):
|
|||||||
copy=False,
|
copy=False,
|
||||||
tracking=True,
|
tracking=True,
|
||||||
)
|
)
|
||||||
description = fields.Html(
|
description = fields.Html()
|
||||||
states={
|
|
||||||
"locked": [("readonly", True)],
|
|
||||||
"cancelled": [("readonly", True)],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
# Reception fields
|
# Reception fields
|
||||||
location_id = fields.Many2one(
|
location_id = fields.Many2one(
|
||||||
comodel_name="stock.location",
|
comodel_name="stock.location",
|
||||||
@@ -249,12 +205,10 @@ class Rma(models.Model):
|
|||||||
# Refund fields
|
# Refund fields
|
||||||
refund_id = fields.Many2one(
|
refund_id = fields.Many2one(
|
||||||
comodel_name="account.move",
|
comodel_name="account.move",
|
||||||
readonly=True,
|
|
||||||
copy=False,
|
copy=False,
|
||||||
)
|
)
|
||||||
refund_line_id = fields.Many2one(
|
refund_line_id = fields.Many2one(
|
||||||
comodel_name="account.move.line",
|
comodel_name="account.move.line",
|
||||||
readonly=True,
|
|
||||||
copy=False,
|
copy=False,
|
||||||
)
|
)
|
||||||
can_be_refunded = fields.Boolean(compute="_compute_can_be_refunded")
|
can_be_refunded = fields.Boolean(compute="_compute_can_be_refunded")
|
||||||
@@ -263,7 +217,6 @@ class Rma(models.Model):
|
|||||||
comodel_name="stock.move",
|
comodel_name="stock.move",
|
||||||
inverse_name="rma_id",
|
inverse_name="rma_id",
|
||||||
string="Delivery reservation",
|
string="Delivery reservation",
|
||||||
readonly=True,
|
|
||||||
copy=False,
|
copy=False,
|
||||||
)
|
)
|
||||||
delivery_picking_count = fields.Integer(
|
delivery_picking_count = fields.Integer(
|
||||||
@@ -275,11 +228,6 @@ class Rma(models.Model):
|
|||||||
compute="_compute_delivered_qty",
|
compute="_compute_delivered_qty",
|
||||||
store=True,
|
store=True,
|
||||||
)
|
)
|
||||||
delivered_qty_done = fields.Float(
|
|
||||||
digits="Product Unit of Measure",
|
|
||||||
compute="_compute_delivered_qty",
|
|
||||||
compute_sudo=True,
|
|
||||||
)
|
|
||||||
can_be_returned = fields.Boolean(
|
can_be_returned = fields.Boolean(
|
||||||
compute="_compute_can_be_returned",
|
compute="_compute_can_be_returned",
|
||||||
)
|
)
|
||||||
@@ -297,11 +245,6 @@ class Rma(models.Model):
|
|||||||
digits="Product Unit of Measure",
|
digits="Product Unit of Measure",
|
||||||
compute="_compute_remaining_qty",
|
compute="_compute_remaining_qty",
|
||||||
)
|
)
|
||||||
remaining_qty_to_done = fields.Float(
|
|
||||||
string="Remaining delivered qty to done",
|
|
||||||
digits="Product Unit of Measure",
|
|
||||||
compute="_compute_remaining_qty",
|
|
||||||
)
|
|
||||||
uom_category_id = fields.Many2one(
|
uom_category_id = fields.Many2one(
|
||||||
related="product_id.uom_id.category_id", string="Category UoM"
|
related="product_id.uom_id.category_id", string="Category UoM"
|
||||||
)
|
)
|
||||||
@@ -312,7 +255,6 @@ class Rma(models.Model):
|
|||||||
origin_split_rma_id = fields.Many2one(
|
origin_split_rma_id = fields.Many2one(
|
||||||
comodel_name="rma",
|
comodel_name="rma",
|
||||||
string="Extracted from",
|
string="Extracted from",
|
||||||
readonly=True,
|
|
||||||
copy=False,
|
copy=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -335,8 +277,7 @@ class Rma(models.Model):
|
|||||||
"delivery_move_ids.state",
|
"delivery_move_ids.state",
|
||||||
"delivery_move_ids.scrapped",
|
"delivery_move_ids.scrapped",
|
||||||
"delivery_move_ids.product_uom_qty",
|
"delivery_move_ids.product_uom_qty",
|
||||||
"delivery_move_ids.reserved_availability",
|
"delivery_move_ids.quantity",
|
||||||
"delivery_move_ids.quantity_done",
|
|
||||||
"delivery_move_ids.product_uom",
|
"delivery_move_ids.product_uom",
|
||||||
"product_uom",
|
"product_uom",
|
||||||
)
|
)
|
||||||
@@ -355,29 +296,21 @@ class Rma(models.Model):
|
|||||||
"""
|
"""
|
||||||
for record in self:
|
for record in self:
|
||||||
delivered_qty = 0.0
|
delivered_qty = 0.0
|
||||||
delivered_qty_done = 0.0
|
|
||||||
for move in record.delivery_move_ids.filtered(
|
for move in record.delivery_move_ids.filtered(
|
||||||
lambda r: r.state != "cancel" and not r.scrapped
|
lambda r: r.state != "cancel" and not r.scrapped
|
||||||
):
|
):
|
||||||
if move.quantity_done:
|
if move.quantity:
|
||||||
quantity_done = move.product_uom._compute_quantity(
|
quantity = move.product_uom._compute_quantity(
|
||||||
move.quantity_done, record.product_uom
|
move.quantity, record.product_uom
|
||||||
)
|
|
||||||
if move.state == "done":
|
|
||||||
delivered_qty_done += quantity_done
|
|
||||||
delivered_qty += quantity_done
|
|
||||||
elif move.reserved_availability:
|
|
||||||
delivered_qty += move.product_uom._compute_quantity(
|
|
||||||
move.reserved_availability, record.product_uom
|
|
||||||
)
|
)
|
||||||
|
delivered_qty += quantity
|
||||||
elif move.product_uom_qty:
|
elif move.product_uom_qty:
|
||||||
delivered_qty += move.product_uom._compute_quantity(
|
delivered_qty += move.product_uom._compute_quantity(
|
||||||
move.product_uom_qty, record.product_uom
|
move.product_uom_qty, record.product_uom
|
||||||
)
|
)
|
||||||
record.delivered_qty = delivered_qty
|
record.delivered_qty = delivered_qty
|
||||||
record.delivered_qty_done = delivered_qty_done
|
|
||||||
|
|
||||||
@api.depends("product_uom_qty", "delivered_qty", "delivered_qty_done")
|
@api.depends("product_uom_qty", "delivered_qty")
|
||||||
def _compute_remaining_qty(self):
|
def _compute_remaining_qty(self):
|
||||||
"""Compute 'remaining_qty' and 'remaining_qty_to_done' fields.
|
"""Compute 'remaining_qty' and 'remaining_qty_to_done' fields.
|
||||||
|
|
||||||
@@ -392,7 +325,6 @@ class Rma(models.Model):
|
|||||||
"""
|
"""
|
||||||
for r in self:
|
for r in self:
|
||||||
r.remaining_qty = r.product_uom_qty - r.delivered_qty
|
r.remaining_qty = r.product_uom_qty - r.delivered_qty
|
||||||
r.remaining_qty_to_done = r.product_uom_qty - r.delivered_qty_done
|
|
||||||
|
|
||||||
@api.depends(
|
@api.depends(
|
||||||
"state",
|
"state",
|
||||||
@@ -443,7 +375,7 @@ class Rma(models.Model):
|
|||||||
and rma.remaining_qty > 0
|
and rma.remaining_qty > 0
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.depends("product_uom_qty", "state", "remaining_qty", "remaining_qty_to_done")
|
@api.depends("product_uom_qty", "state", "remaining_qty")
|
||||||
def _compute_can_be_split(self):
|
def _compute_can_be_split(self):
|
||||||
"""Compute 'can_be_split'. This field controls the
|
"""Compute 'can_be_split'. This field controls the
|
||||||
visibility of 'Split' button in the rma form view and
|
visibility of 'Split' button in the rma form view and
|
||||||
@@ -460,10 +392,10 @@ class Rma(models.Model):
|
|||||||
else:
|
else:
|
||||||
r.can_be_split = False
|
r.can_be_split = False
|
||||||
|
|
||||||
@api.depends("remaining_qty_to_done", "state")
|
@api.depends("state")
|
||||||
def _compute_can_be_locked(self):
|
def _compute_can_be_locked(self):
|
||||||
for r in self:
|
for r in self:
|
||||||
r.can_be_locked = r.remaining_qty_to_done > 0 and r.state in [
|
r.can_be_locked = r.remaining_qty > 0 and r.state in [
|
||||||
"received",
|
"received",
|
||||||
"waiting_return",
|
"waiting_return",
|
||||||
"waiting_replacement",
|
"waiting_replacement",
|
||||||
@@ -612,34 +544,41 @@ class Rma(models.Model):
|
|||||||
def _send_draft_email(self):
|
def _send_draft_email(self):
|
||||||
"""Send customer notifications they place the RMA from the portal"""
|
"""Send customer notifications they place the RMA from the portal"""
|
||||||
for rma in self.filtered("company_id.send_rma_draft_confirmation"):
|
for rma in self.filtered("company_id.send_rma_draft_confirmation"):
|
||||||
rma_template_id = rma.company_id.rma_mail_draft_confirmation_template_id.id
|
|
||||||
rma.with_context(
|
rma.with_context(
|
||||||
force_send=True,
|
force_send=True,
|
||||||
mark_rma_as_sent=True,
|
mark_rma_as_sent=True,
|
||||||
default_subtype_id=self.env.ref("rma.mt_rma_notification").id,
|
).message_post_with_source(
|
||||||
).message_post_with_template(rma_template_id)
|
rma.company_id.rma_mail_draft_confirmation_template_id.get_external_id()[
|
||||||
|
rma.company_id.rma_mail_draft_confirmation_template_id.id
|
||||||
|
],
|
||||||
|
subtype_xmlid="rma.mt_rma_notification",
|
||||||
|
)
|
||||||
|
|
||||||
def _send_confirmation_email(self):
|
def _send_confirmation_email(self):
|
||||||
"""Auto send notifications"""
|
"""Auto send notifications"""
|
||||||
for rma in self.filtered(lambda p: p.company_id.send_rma_confirmation):
|
for rma in self.filtered(lambda p: p.company_id.send_rma_confirmation):
|
||||||
rma_template_id = rma.company_id.rma_mail_confirmation_template_id.id
|
|
||||||
rma.with_context(
|
rma.with_context(
|
||||||
force_send=True,
|
force_send=True,
|
||||||
mark_rma_as_sent=True,
|
mark_rma_as_sent=True,
|
||||||
default_subtype_id=self.env.ref("rma.mt_rma_notification").id,
|
).message_post_with_source(
|
||||||
).message_post_with_template(rma_template_id)
|
rma.company_id.rma_mail_confirmation_template_id.get_external_id()[
|
||||||
|
rma.company_id.rma_mail_confirmation_template_id.id
|
||||||
|
],
|
||||||
|
subtype_xmlid="rma.mt_rma_notification",
|
||||||
|
)
|
||||||
|
|
||||||
def _send_receipt_confirmation_email(self):
|
def _send_receipt_confirmation_email(self):
|
||||||
"""Send customer notifications when the products are received"""
|
"""Send customer notifications when the products are received"""
|
||||||
for rma in self.filtered("company_id.send_rma_receipt_confirmation"):
|
for rma in self.filtered("company_id.send_rma_receipt_confirmation"):
|
||||||
rma_template_id = (
|
|
||||||
rma.company_id.rma_mail_receipt_confirmation_template_id.id
|
|
||||||
)
|
|
||||||
rma.with_context(
|
rma.with_context(
|
||||||
force_send=True,
|
force_send=True,
|
||||||
mark_rma_as_sent=True,
|
mark_rma_as_sent=True,
|
||||||
default_subtype_id=self.env.ref("rma.mt_rma_notification").id,
|
).message_post_with_source(
|
||||||
).message_post_with_template(rma_template_id)
|
rma.company_id.rma_mail_receipt_confirmation_template_id.get_external_id()[
|
||||||
|
rma.company_id.rma_mail_receipt_confirmation_template_id.id
|
||||||
|
],
|
||||||
|
subtype_xmlid="rma.mt_rma_notification",
|
||||||
|
)
|
||||||
|
|
||||||
# Action methods
|
# Action methods
|
||||||
def action_rma_send(self):
|
def action_rma_send(self):
|
||||||
@@ -682,6 +621,7 @@ class Rma(models.Model):
|
|||||||
reception_move = self._create_receptions_from_picking()
|
reception_move = self._create_receptions_from_picking()
|
||||||
else:
|
else:
|
||||||
reception_move = self._create_receptions_from_product()
|
reception_move = self._create_receptions_from_product()
|
||||||
|
reception_move.picked = True
|
||||||
self.write({"reception_move_id": reception_move.id, "state": "confirmed"})
|
self.write({"reception_move_id": reception_move.id, "state": "confirmed"})
|
||||||
self._add_message_subscribe_partner()
|
self._add_message_subscribe_partner()
|
||||||
self._send_confirmation_email()
|
self._send_confirmation_email()
|
||||||
@@ -703,10 +643,10 @@ class Rma(models.Model):
|
|||||||
(0, 0, rma._prepare_refund_line_vals())
|
(0, 0, rma._prepare_refund_line_vals())
|
||||||
)
|
)
|
||||||
refund = self.env["account.move"].sudo().create(refund_vals)
|
refund = self.env["account.move"].sudo().create(refund_vals)
|
||||||
refund.with_user(self.env.uid).message_post_with_view(
|
refund.with_user(self.env.uid).message_post_with_source(
|
||||||
"mail.message_origin_link",
|
"mail.message_origin_link",
|
||||||
values={"self": refund, "origin": rmas},
|
render_values={"self": refund, "origin": rmas},
|
||||||
subtype_id=self.env.ref("mail.mt_note").id,
|
subtype_id=self.env["ir.model.data"]._xmlid_to_res_id("mail.mt_note"),
|
||||||
)
|
)
|
||||||
for line in refund.invoice_line_ids:
|
for line in refund.invoice_line_ids:
|
||||||
line.rma_id.write(
|
line.rma_id.write(
|
||||||
@@ -1027,10 +967,10 @@ class Rma(models.Model):
|
|||||||
picking = self.env["stock.picking"].create(self._prepare_picking_vals())
|
picking = self.env["stock.picking"].create(self._prepare_picking_vals())
|
||||||
picking.action_confirm()
|
picking.action_confirm()
|
||||||
picking.action_assign()
|
picking.action_assign()
|
||||||
picking.message_post_with_view(
|
picking.message_post_with_source(
|
||||||
"mail.message_origin_link",
|
"mail.message_origin_link",
|
||||||
values={"self": picking, "origin": self},
|
render_values={"self": picking, "origin": self},
|
||||||
subtype_id=self.env.ref("mail.mt_note").id,
|
subtype_id=self.env["ir.model.data"]._xmlid_to_res_id("mail.mt_note"),
|
||||||
)
|
)
|
||||||
return picking.move_ids
|
return picking.move_ids
|
||||||
|
|
||||||
@@ -1068,7 +1008,7 @@ class Rma(models.Model):
|
|||||||
self._ensure_can_be_split()
|
self._ensure_can_be_split()
|
||||||
self._ensure_qty_to_extract(qty, uom)
|
self._ensure_qty_to_extract(qty, uom)
|
||||||
self.product_uom_qty -= uom._compute_quantity(qty, self.product_uom)
|
self.product_uom_qty -= uom._compute_quantity(qty, self.product_uom)
|
||||||
if self.remaining_qty_to_done <= 0:
|
if self.remaining_qty <= 0:
|
||||||
if self.state == "waiting_return":
|
if self.state == "waiting_return":
|
||||||
self.state = "returned"
|
self.state = "returned"
|
||||||
elif self.state == "waiting_replacement":
|
elif self.state == "waiting_replacement":
|
||||||
@@ -1083,10 +1023,10 @@ class Rma(models.Model):
|
|||||||
"origin_split_rma_id": self.id,
|
"origin_split_rma_id": self.id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
extracted_rma.message_post_with_view(
|
extracted_rma.message_post_with_source(
|
||||||
"mail.message_origin_link",
|
"mail.message_origin_link",
|
||||||
values={"self": extracted_rma, "origin": self},
|
render_values={"self": extracted_rma, "origin": self},
|
||||||
subtype_id=self.env.ref("mail.mt_note").id,
|
subtype_id=self.env["ir.model.data"]._xmlid_to_res_id("mail.mt_note"),
|
||||||
)
|
)
|
||||||
self.message_post(
|
self.message_post(
|
||||||
body=_(
|
body=_(
|
||||||
@@ -1175,10 +1115,10 @@ class Rma(models.Model):
|
|||||||
)
|
)
|
||||||
picking.action_confirm()
|
picking.action_confirm()
|
||||||
picking.action_assign()
|
picking.action_assign()
|
||||||
picking.message_post_with_view(
|
picking.message_post_with_source(
|
||||||
"mail.message_origin_link",
|
"mail.message_origin_link",
|
||||||
values={"self": picking, "origin": rmas},
|
render_values={"self": picking, "origin": rmas},
|
||||||
subtype_id=self.env.ref("mail.mt_note").id,
|
subtype_id=self.env["ir.model.data"]._xmlid_to_res_id("mail.mt_note"),
|
||||||
)
|
)
|
||||||
rmas_to_return.write({"state": "waiting_return"})
|
rmas_to_return.write({"state": "waiting_return"})
|
||||||
|
|
||||||
@@ -1234,7 +1174,7 @@ class Rma(models.Model):
|
|||||||
% (
|
% (
|
||||||
{
|
{
|
||||||
"move_id": new_move.id,
|
"move_id": new_move.id,
|
||||||
"move_name": new_move.name_get()[0][1],
|
"move_name": new_move.display_name,
|
||||||
"picking_id": new_move.picking_id.id,
|
"picking_id": new_move.picking_id.id,
|
||||||
"picking_name": new_move.picking_id.name,
|
"picking_name": new_move.picking_id.name,
|
||||||
}
|
}
|
||||||
@@ -1427,10 +1367,7 @@ class Rma(models.Model):
|
|||||||
[stock.move]._action_cancel
|
[stock.move]._action_cancel
|
||||||
"""
|
"""
|
||||||
rma = self.filtered(
|
rma = self.filtered(
|
||||||
lambda r: (
|
lambda r: (r.state == "waiting_replacement" and 0 >= r.remaining_qty)
|
||||||
r.state == "waiting_replacement"
|
|
||||||
and 0 >= r.remaining_qty_to_done == r.remaining_qty
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
if rma:
|
if rma:
|
||||||
rma.write({"state": "replaced"})
|
rma.write({"state": "replaced"})
|
||||||
@@ -1438,7 +1375,7 @@ class Rma(models.Model):
|
|||||||
def update_returned_state(self):
|
def update_returned_state(self):
|
||||||
"""Invoked by [stock.move]._action_done"""
|
"""Invoked by [stock.move]._action_done"""
|
||||||
rma = self.filtered(
|
rma = self.filtered(
|
||||||
lambda r: (r.state == "waiting_return" and r.remaining_qty_to_done <= 0)
|
lambda r: (r.state == "waiting_return" and r.remaining_qty <= 0)
|
||||||
)
|
)
|
||||||
if rma:
|
if rma:
|
||||||
rma.write({"state": "returned"})
|
rma.write({"state": "returned"})
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class StockMove(models.Model):
|
|||||||
"""
|
"""
|
||||||
for move in self.filtered(lambda r: r.state not in ("done", "cancel")):
|
for move in self.filtered(lambda r: r.state not in ("done", "cancel")):
|
||||||
rma_receiver = move.sudo().rma_receiver_ids
|
rma_receiver = move.sudo().rma_receiver_ids
|
||||||
if rma_receiver and move.quantity_done != rma_receiver.product_uom_qty:
|
if rma_receiver and move.quantity != rma_receiver.product_uom_qty:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_(
|
_(
|
||||||
"The quantity done for the product '%(id)s' must "
|
"The quantity done for the product '%(id)s' must "
|
||||||
|
|||||||
@@ -5,3 +5,5 @@
|
|||||||
- Víctor Martínez
|
- Víctor Martínez
|
||||||
- Chafique Delli \<<chafique.delli@akretion.com>\>
|
- Chafique Delli \<<chafique.delli@akretion.com>\>
|
||||||
- Giovanni Serra - Ooops \<<giovanni@ooops404.com>\>
|
- Giovanni Serra - Ooops \<<giovanni@ooops404.com>\>
|
||||||
|
- [APSL-Nagarro](https://www.apsl.tech):
|
||||||
|
- Antoni Marroig \<<amarroig@apsl.net>\>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ To use this module, you need to:
|
|||||||
quantity to another RMA, preview the RMA in the website. All of
|
quantity to another RMA, preview the RMA in the website. All of
|
||||||
these operations can be done by clicking on the buttons in the
|
these operations can be done by clicking on the buttons in the
|
||||||
status bar.
|
status bar.
|
||||||
- If you click on 'Refund' button, a refund will be created, and it
|
- If you click on 'To Refund' button, a refund will be created, and it
|
||||||
will be accessible via the smart button labeled Refund. The RMA
|
will be accessible via the smart button labeled Refund. The RMA
|
||||||
will be set automatically to 'Refunded' state when the refund is
|
will be set automatically to 'Refunded' state when the refund is
|
||||||
validated.
|
validated.
|
||||||
|
|||||||
@@ -434,8 +434,8 @@ return to the customer the same product or another product as a
|
|||||||
replacement, split the RMA by extracting a part of the remaining
|
replacement, split the RMA by extracting a part of the remaining
|
||||||
quantity to another RMA, preview the RMA in the website. All of these
|
quantity to another RMA, preview the RMA in the website. All of these
|
||||||
operations can be done by clicking on the buttons in the status bar.<ul>
|
operations can be done by clicking on the buttons in the status bar.<ul>
|
||||||
<li>If you click on ‘Refund’ button, a refund will be created, and it
|
<li>If you click on ‘To Refund’ button, a refund will be created, and
|
||||||
will be accessible via the smart button labeled Refund. The RMA
|
it will be accessible via the smart button labeled Refund. The RMA
|
||||||
will be set automatically to ‘Refunded’ state when the refund is
|
will be set automatically to ‘Refunded’ state when the refund is
|
||||||
validated.</li>
|
validated.</li>
|
||||||
<li>If you click on ‘Replace’ or ‘Return to customer’ button instead,
|
<li>If you click on ‘Replace’ or ‘Return to customer’ button instead,
|
||||||
@@ -523,6 +523,10 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|||||||
</li>
|
</li>
|
||||||
<li>Chafique Delli <<a class="reference external" href="mailto:chafique.delli@akretion.com">chafique.delli@akretion.com</a>></li>
|
<li>Chafique Delli <<a class="reference external" href="mailto:chafique.delli@akretion.com">chafique.delli@akretion.com</a>></li>
|
||||||
<li>Giovanni Serra - Ooops <<a class="reference external" href="mailto:giovanni@ooops404.com">giovanni@ooops404.com</a>></li>
|
<li>Giovanni Serra - Ooops <<a class="reference external" href="mailto:giovanni@ooops404.com">giovanni@ooops404.com</a>></li>
|
||||||
|
<li><a class="reference external" href="https://www.apsl.tech">APSL-Nagarro</a>:<ul>
|
||||||
|
<li>Antoni Marroig <<a class="reference external" href="mailto:amarroig@apsl.net">amarroig@apsl.net</a>></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="maintainers">
|
<div class="section" id="maintainers">
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ class TestRma(TransactionCase):
|
|||||||
vals["product_uom_qty"] = qty
|
vals["product_uom_qty"] = qty
|
||||||
if location:
|
if location:
|
||||||
vals["location_id"] = location.id
|
vals["location_id"] = location.id
|
||||||
|
|
||||||
|
vals["user_id"] = self.env.user.id
|
||||||
return self.env["rma"].create(vals)
|
return self.env["rma"].create(vals)
|
||||||
|
|
||||||
def _create_confirm_receive(
|
def _create_confirm_receive(
|
||||||
@@ -92,7 +94,7 @@ class TestRma(TransactionCase):
|
|||||||
):
|
):
|
||||||
rma = self._create_rma(partner, product, qty, location)
|
rma = self._create_rma(partner, product, qty, location)
|
||||||
rma.action_confirm()
|
rma.action_confirm()
|
||||||
rma.reception_move_id.quantity_done = rma.product_uom_qty
|
rma.reception_move_id.quantity = rma.product_uom_qty
|
||||||
rma.reception_move_id.picking_id._action_done()
|
rma.reception_move_id.picking_id._action_done()
|
||||||
return rma
|
return rma
|
||||||
|
|
||||||
@@ -107,7 +109,7 @@ class TestRma(TransactionCase):
|
|||||||
limit=1,
|
limit=1,
|
||||||
)
|
)
|
||||||
picking_form = Form(
|
picking_form = Form(
|
||||||
recordp=self.env["stock.picking"].with_context(
|
record=self.env["stock.picking"].with_context(
|
||||||
default_picking_type_id=picking_type.id
|
default_picking_type_id=picking_type.id
|
||||||
),
|
),
|
||||||
view="stock.view_picking_form",
|
view="stock.view_picking_form",
|
||||||
@@ -124,7 +126,7 @@ class TestRma(TransactionCase):
|
|||||||
picking = picking_form.save()
|
picking = picking_form.save()
|
||||||
picking.action_confirm()
|
picking.action_confirm()
|
||||||
for move in picking.move_ids:
|
for move in picking.move_ids:
|
||||||
move.quantity_done = move.product_uom_qty
|
move.quantity = move.product_uom_qty
|
||||||
picking.button_validate()
|
picking.button_validate()
|
||||||
return picking
|
return picking
|
||||||
|
|
||||||
@@ -157,7 +159,7 @@ class TestRmaCase(TestRma):
|
|||||||
limit=1,
|
limit=1,
|
||||||
)
|
)
|
||||||
picking_form = Form(
|
picking_form = Form(
|
||||||
recordp=self.env["stock.picking"].with_context(
|
record=self.env["stock.picking"].with_context(
|
||||||
default_picking_type_id=outgoing_picking_type.id
|
default_picking_type_id=outgoing_picking_type.id
|
||||||
),
|
),
|
||||||
view="stock.view_picking_form",
|
view="stock.view_picking_form",
|
||||||
@@ -203,13 +205,13 @@ class TestRmaCase(TestRma):
|
|||||||
self.assertEqual(rma.reception_move_id.product_uom_qty, 10)
|
self.assertEqual(rma.reception_move_id.product_uom_qty, 10)
|
||||||
self.assertEqual(rma.reception_move_id.product_uom, rma.product_uom)
|
self.assertEqual(rma.reception_move_id.product_uom, rma.product_uom)
|
||||||
self.assertEqual(rma.state, "confirmed")
|
self.assertEqual(rma.state, "confirmed")
|
||||||
rma.reception_move_id.quantity_done = 9
|
rma.reception_move_id.quantity = 9
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
rma.reception_move_id.picking_id._action_done()
|
rma.reception_move_id.picking_id._action_done()
|
||||||
rma.reception_move_id.quantity_done = 10
|
rma.reception_move_id.quantity = 10
|
||||||
rma.reception_move_id.picking_id._action_done()
|
rma.reception_move_id.picking_id._action_done()
|
||||||
self.assertEqual(rma.reception_move_id.picking_id.state, "done")
|
self.assertEqual(rma.reception_move_id.picking_id.state, "done")
|
||||||
self.assertEqual(rma.reception_move_id.quantity_done, 10)
|
self.assertEqual(rma.reception_move_id.quantity, 10)
|
||||||
self.assertEqual(rma.state, "received")
|
self.assertEqual(rma.state, "received")
|
||||||
|
|
||||||
def test_cancel(self):
|
def test_cancel(self):
|
||||||
@@ -386,8 +388,6 @@ class TestRmaCase(TestRma):
|
|||||||
self.assertTrue(rma.can_be_replaced)
|
self.assertTrue(rma.can_be_replaced)
|
||||||
self.assertEqual(rma.delivered_qty, 2)
|
self.assertEqual(rma.delivered_qty, 2)
|
||||||
self.assertEqual(rma.remaining_qty, 8)
|
self.assertEqual(rma.remaining_qty, 8)
|
||||||
self.assertEqual(rma.delivered_qty_done, 0)
|
|
||||||
self.assertEqual(rma.remaining_qty_to_done, 10)
|
|
||||||
first_move = rma.delivery_move_ids
|
first_move = rma.delivery_move_ids
|
||||||
picking = first_move.picking_id
|
picking = first_move.picking_id
|
||||||
# Replace again with another product with the remaining quantity
|
# Replace again with another product with the remaining quantity
|
||||||
@@ -413,18 +413,13 @@ class TestRmaCase(TestRma):
|
|||||||
self.assertTrue(picking.state, "waiting")
|
self.assertTrue(picking.state, "waiting")
|
||||||
self.assertEqual(rma.delivered_qty, 10)
|
self.assertEqual(rma.delivered_qty, 10)
|
||||||
self.assertEqual(rma.remaining_qty, 0)
|
self.assertEqual(rma.remaining_qty, 0)
|
||||||
self.assertEqual(rma.delivered_qty_done, 0)
|
|
||||||
self.assertEqual(rma.remaining_qty_to_done, 10)
|
|
||||||
# remaining_qty is 0 but rma is not set to 'replaced' until
|
# remaining_qty is 0 but rma is not set to 'replaced' until
|
||||||
# remaining_qty_to_done is less than or equal to 0
|
first_move.quantity = 2
|
||||||
first_move.quantity_done = 2
|
second_move.quantity = 8
|
||||||
second_move.quantity_done = 8
|
|
||||||
picking.button_validate()
|
picking.button_validate()
|
||||||
self.assertEqual(picking.state, "done")
|
self.assertEqual(picking.state, "done")
|
||||||
self.assertEqual(rma.delivered_qty, 10)
|
self.assertEqual(rma.delivered_qty, 10)
|
||||||
self.assertEqual(rma.remaining_qty, 0)
|
self.assertEqual(rma.remaining_qty, 0)
|
||||||
self.assertEqual(rma.delivered_qty_done, 10)
|
|
||||||
self.assertEqual(rma.remaining_qty_to_done, 0)
|
|
||||||
# The RMA is now in 'replaced' state
|
# The RMA is now in 'replaced' state
|
||||||
self.assertEqual(rma.state, "replaced")
|
self.assertEqual(rma.state, "replaced")
|
||||||
self.assertFalse(rma.can_be_refunded)
|
self.assertFalse(rma.can_be_refunded)
|
||||||
@@ -457,18 +452,14 @@ class TestRmaCase(TestRma):
|
|||||||
self.assertTrue(rma.can_be_returned)
|
self.assertTrue(rma.can_be_returned)
|
||||||
self.assertEqual(rma.delivered_qty, 2)
|
self.assertEqual(rma.delivered_qty, 2)
|
||||||
self.assertEqual(rma.remaining_qty, 8)
|
self.assertEqual(rma.remaining_qty, 8)
|
||||||
self.assertEqual(rma.delivered_qty_done, 0)
|
|
||||||
self.assertEqual(rma.remaining_qty_to_done, 10)
|
|
||||||
first_move = rma.delivery_move_ids
|
first_move = rma.delivery_move_ids
|
||||||
picking = first_move.picking_id
|
picking = first_move.picking_id
|
||||||
# Validate the picking
|
# Validate the picking
|
||||||
first_move.quantity_done = 2
|
first_move.quantity = 2
|
||||||
picking.button_validate()
|
picking.button_validate()
|
||||||
self.assertEqual(picking.state, "done")
|
self.assertEqual(picking.state, "done")
|
||||||
self.assertEqual(rma.delivered_qty, 2)
|
self.assertEqual(rma.delivered_qty, 2)
|
||||||
self.assertEqual(rma.remaining_qty, 8)
|
self.assertEqual(rma.remaining_qty, 8)
|
||||||
self.assertEqual(rma.delivered_qty_done, 2)
|
|
||||||
self.assertEqual(rma.remaining_qty_to_done, 8)
|
|
||||||
# Return the remaining quantity to the customer
|
# Return the remaining quantity to the customer
|
||||||
delivery_form = Form(
|
delivery_form = Form(
|
||||||
self.env["rma.delivery.wizard"].with_context(
|
self.env["rma.delivery.wizard"].with_context(
|
||||||
@@ -479,21 +470,16 @@ class TestRmaCase(TestRma):
|
|||||||
delivery_wizard = delivery_form.save()
|
delivery_wizard = delivery_form.save()
|
||||||
delivery_wizard.action_deliver()
|
delivery_wizard.action_deliver()
|
||||||
second_move = rma.delivery_move_ids - first_move
|
second_move = rma.delivery_move_ids - first_move
|
||||||
second_move.quantity_done = 8
|
second_move.quantity = 8
|
||||||
self.assertEqual(rma.delivered_qty, 10)
|
self.assertEqual(rma.delivered_qty, 10)
|
||||||
self.assertEqual(rma.remaining_qty, 0)
|
self.assertEqual(rma.remaining_qty, 0)
|
||||||
self.assertEqual(rma.delivered_qty_done, 2)
|
|
||||||
self.assertEqual(rma.remaining_qty_to_done, 8)
|
|
||||||
self.assertEqual(rma.state, "waiting_return")
|
self.assertEqual(rma.state, "waiting_return")
|
||||||
# remaining_qty is 0 but rma is not set to 'returned' until
|
# remaining_qty is 0 but rma is not set to 'returned' until
|
||||||
# remaining_qty_to_done is less than or equal to 0
|
|
||||||
picking_2 = second_move.picking_id
|
picking_2 = second_move.picking_id
|
||||||
picking_2.button_validate()
|
picking_2.button_validate()
|
||||||
self.assertEqual(picking_2.state, "done")
|
self.assertEqual(picking_2.state, "done")
|
||||||
self.assertEqual(rma.delivered_qty, 10)
|
self.assertEqual(rma.delivered_qty, 10)
|
||||||
self.assertEqual(rma.remaining_qty, 0)
|
self.assertEqual(rma.remaining_qty, 0)
|
||||||
self.assertEqual(rma.delivered_qty_done, 10)
|
|
||||||
self.assertEqual(rma.remaining_qty_to_done, 0)
|
|
||||||
# The RMA is now in 'returned' state
|
# The RMA is now in 'returned' state
|
||||||
self.assertEqual(rma.state, "returned")
|
self.assertEqual(rma.state, "returned")
|
||||||
self.assertFalse(rma.can_be_refunded)
|
self.assertFalse(rma.can_be_refunded)
|
||||||
@@ -579,7 +565,7 @@ class TestRmaCase(TestRma):
|
|||||||
self.assertEqual(rma.product_id, rma.delivery_move_ids.product_id)
|
self.assertEqual(rma.product_id, rma.delivery_move_ids.product_id)
|
||||||
self.assertEqual(rma.product_uom_qty, rma.delivery_move_ids.product_uom_qty)
|
self.assertEqual(rma.product_uom_qty, rma.delivery_move_ids.product_uom_qty)
|
||||||
self.assertEqual(rma.product_uom, rma.delivery_move_ids.product_uom)
|
self.assertEqual(rma.product_uom, rma.delivery_move_ids.product_uom)
|
||||||
rma.delivery_move_ids.quantity_done = rma.product_uom_qty
|
rma.delivery_move_ids.quantity = rma.product_uom_qty
|
||||||
pick_1.button_validate()
|
pick_1.button_validate()
|
||||||
pick_2.button_validate()
|
pick_2.button_validate()
|
||||||
self.assertEqual(all_rmas.mapped("state"), ["returned"] * 4)
|
self.assertEqual(all_rmas.mapped("state"), ["returned"] * 4)
|
||||||
@@ -643,8 +629,8 @@ class TestRmaCase(TestRma):
|
|||||||
self.assertTrue(reception_moves[1].rma_receiver_ids)
|
self.assertTrue(reception_moves[1].rma_receiver_ids)
|
||||||
self.assertEqual(reception_moves.mapped("rma_receiver_ids"), rmas)
|
self.assertEqual(reception_moves.mapped("rma_receiver_ids"), rmas)
|
||||||
# Validate the reception picking to set rmas to 'received' state
|
# Validate the reception picking to set rmas to 'received' state
|
||||||
reception_moves[0].quantity_done = reception_moves[0].product_uom_qty
|
reception_moves[0].quantity = reception_moves[0].product_uom_qty
|
||||||
reception_moves[1].quantity_done = reception_moves[1].product_uom_qty
|
reception_moves[1].quantity = reception_moves[1].product_uom_qty
|
||||||
reception.button_validate()
|
reception.button_validate()
|
||||||
self.assertEqual(rmas.mapped("state"), ["received"] * 2)
|
self.assertEqual(rmas.mapped("state"), ["received"] * 2)
|
||||||
|
|
||||||
@@ -658,7 +644,7 @@ class TestRmaCase(TestRma):
|
|||||||
)
|
)
|
||||||
rma = rma_form.save()
|
rma = rma_form.save()
|
||||||
rma.action_confirm()
|
rma.action_confirm()
|
||||||
rma.reception_move_id.quantity_done = 10
|
rma.reception_move_id.quantity = 10
|
||||||
rma.reception_move_id.picking_id._action_done()
|
rma.reception_move_id.picking_id._action_done()
|
||||||
# Return quantity 4 of the same product to the customer
|
# Return quantity 4 of the same product to the customer
|
||||||
delivery_form = Form(
|
delivery_form = Form(
|
||||||
@@ -670,7 +656,7 @@ class TestRmaCase(TestRma):
|
|||||||
delivery_form.product_uom_qty = 4
|
delivery_form.product_uom_qty = 4
|
||||||
delivery_wizard = delivery_form.save()
|
delivery_wizard = delivery_form.save()
|
||||||
delivery_wizard.action_deliver()
|
delivery_wizard.action_deliver()
|
||||||
rma.delivery_move_ids.quantity_done = 4
|
rma.delivery_move_ids.quantity = 4
|
||||||
rma.delivery_move_ids.picking_id.button_validate()
|
rma.delivery_move_ids.picking_id.button_validate()
|
||||||
self.assertEqual(rma.state, "waiting_return")
|
self.assertEqual(rma.state, "waiting_return")
|
||||||
# Extract the remaining quantity to another RMA
|
# Extract the remaining quantity to another RMA
|
||||||
@@ -690,8 +676,6 @@ class TestRmaCase(TestRma):
|
|||||||
self.assertEqual(new_rma.origin_split_rma_id, rma)
|
self.assertEqual(new_rma.origin_split_rma_id, rma)
|
||||||
self.assertEqual(new_rma.delivered_qty, 0)
|
self.assertEqual(new_rma.delivered_qty, 0)
|
||||||
self.assertEqual(new_rma.remaining_qty, 6)
|
self.assertEqual(new_rma.remaining_qty, 6)
|
||||||
self.assertEqual(new_rma.delivered_qty_done, 0)
|
|
||||||
self.assertEqual(new_rma.remaining_qty_to_done, 6)
|
|
||||||
self.assertEqual(new_rma.state, "received")
|
self.assertEqual(new_rma.state, "received")
|
||||||
self.assertTrue(new_rma.can_be_refunded)
|
self.assertTrue(new_rma.can_be_refunded)
|
||||||
self.assertTrue(new_rma.can_be_returned)
|
self.assertTrue(new_rma.can_be_returned)
|
||||||
@@ -699,8 +683,8 @@ class TestRmaCase(TestRma):
|
|||||||
self.assertEqual(new_rma.move_id, rma.move_id)
|
self.assertEqual(new_rma.move_id, rma.move_id)
|
||||||
self.assertEqual(new_rma.reception_move_id, rma.reception_move_id)
|
self.assertEqual(new_rma.reception_move_id, rma.reception_move_id)
|
||||||
self.assertEqual(new_rma.product_uom_qty + rma.product_uom_qty, 10)
|
self.assertEqual(new_rma.product_uom_qty + rma.product_uom_qty, 10)
|
||||||
self.assertEqual(new_rma.move_id.quantity_done, 10)
|
self.assertEqual(new_rma.move_id.quantity, 10)
|
||||||
self.assertEqual(new_rma.reception_move_id.quantity_done, 10)
|
self.assertEqual(new_rma.reception_move_id.quantity, 10)
|
||||||
|
|
||||||
def test_rma_to_receive_on_delete_invoice(self):
|
def test_rma_to_receive_on_delete_invoice(self):
|
||||||
rma = self._create_confirm_receive(self.partner, self.product, 10, self.rma_loc)
|
rma = self._create_confirm_receive(self.partner, self.product, 10, self.rma_loc)
|
||||||
@@ -763,7 +747,7 @@ class TestRmaCase(TestRma):
|
|||||||
)
|
)
|
||||||
# Now we'll confirm the incoming goods picking and the automatic
|
# Now we'll confirm the incoming goods picking and the automatic
|
||||||
# reception notification should be sent
|
# reception notification should be sent
|
||||||
rma.reception_move_id.quantity_done = rma.product_uom_qty
|
rma.reception_move_id.quantity = rma.product_uom_qty
|
||||||
rma.reception_move_id.picking_id.button_validate()
|
rma.reception_move_id.picking_id.button_validate()
|
||||||
mail_receipt = (
|
mail_receipt = (
|
||||||
self.env["mail.message"].search([("partner_ids", "in", self.partner.ids)])
|
self.env["mail.message"].search([("partner_ids", "in", self.partner.ids)])
|
||||||
|
|||||||
@@ -5,154 +5,85 @@
|
|||||||
<field name="inherit_id" ref="stock.res_config_settings_view_form" />
|
<field name="inherit_id" ref="stock.res_config_settings_view_form" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath
|
<xpath
|
||||||
expr="//div[@data-key='stock']/div[hasclass('o_settings_container')]"
|
expr="//block[@name='operations_setting_container']"
|
||||||
position="inside"
|
position="inside"
|
||||||
>
|
>
|
||||||
<div class="col-12 col-lg-6 o_setting_box" title="Finish RMAs manually">
|
<setting
|
||||||
<div class="o_setting_left_pane">
|
title="Finish RMAs manually"
|
||||||
|
help=" When the RMA is receive, allow to finsish it manually choosing a finalization reason."
|
||||||
|
>
|
||||||
<field name="group_rma_manual_finalization" />
|
<field name="group_rma_manual_finalization" />
|
||||||
</div>
|
</setting>
|
||||||
<div class="o_setting_right_pane">
|
<setting
|
||||||
<label
|
title="Values set here are company-specific."
|
||||||
for="group_rma_manual_finalization"
|
help="Group RMA returns by customer and warehouse."
|
||||||
string="RMA Manual Finalization"
|
>
|
||||||
/>
|
|
||||||
<div class="text-muted">
|
|
||||||
When the RMA is receive, allow to finsish it manually choosing
|
|
||||||
a finalization reason.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-lg-6 o_setting_box">
|
|
||||||
<div class="o_setting_left_pane">
|
|
||||||
<field name="rma_return_grouping" />
|
<field name="rma_return_grouping" />
|
||||||
</div>
|
</setting>
|
||||||
<div class="o_setting_right_pane">
|
<setting
|
||||||
<label for="rma_return_grouping" />
|
|
||||||
<span
|
|
||||||
class="fa fa-lg fa-building-o"
|
|
||||||
title="Values set here are company-specific."
|
|
||||||
groups="base.group_multi_company"
|
|
||||||
/>
|
|
||||||
<div class="text-muted">
|
|
||||||
Group RMA returns by customer and warehouse.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="col-12 col-lg-6 o_setting_box"
|
|
||||||
title="Send automatic RMA info to customer"
|
title="Send automatic RMA info to customer"
|
||||||
|
help="When the RMA is confirmed, send an automatic information email."
|
||||||
>
|
>
|
||||||
<div class="o_setting_left_pane">
|
|
||||||
<field name="send_rma_confirmation" />
|
<field name="send_rma_confirmation" />
|
||||||
</div>
|
<div class="row mt16" invisible="not send_rma_confirmation">
|
||||||
<div class="o_setting_right_pane">
|
|
||||||
<label
|
|
||||||
for="send_rma_confirmation"
|
|
||||||
string="RMA Confirmation Email"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
class="fa fa-lg fa-building-o"
|
|
||||||
title="Values set here are company-specific."
|
|
||||||
groups="base.group_multi_company"
|
|
||||||
/>
|
|
||||||
<div class="text-muted">
|
|
||||||
When the RMA is confirmed, send an automatic information email.
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="row mt16"
|
|
||||||
attrs="{'invisible': [('send_rma_confirmation', '=', False)]}"
|
|
||||||
>
|
|
||||||
<label
|
<label
|
||||||
for="rma_mail_confirmation_template_id"
|
for="rma_mail_confirmation_template_id"
|
||||||
string="Email Template"
|
string="Email Template"
|
||||||
class="col-lg-4 o_light_label"
|
class="col-lg-4 o_light_label"
|
||||||
/>
|
/>
|
||||||
<field
|
<field
|
||||||
name="rma_mail_confirmation_template_id"
|
name="rma_mail_confirmation_template_id"
|
||||||
class="oe_inline"
|
class="oe_inline"
|
||||||
attrs="{'required': [('send_rma_confirmation', '=', True)]}"
|
required="send_rma_confirmation"
|
||||||
context="{'default_model': 'rma'}"
|
context="{'default_model': 'rma'}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</setting>
|
||||||
</div>
|
<setting
|
||||||
<div
|
|
||||||
class="col-12 col-lg-6 o_setting_box"
|
|
||||||
title="Send automatic RMA products reception notification to customer"
|
title="Send automatic RMA products reception notification to customer"
|
||||||
|
help="When the RMA products are received, send an automatic information email."
|
||||||
>
|
>
|
||||||
<div class="o_setting_left_pane">
|
|
||||||
<field name="send_rma_receipt_confirmation" />
|
<field name="send_rma_receipt_confirmation" />
|
||||||
</div>
|
|
||||||
<div class="o_setting_right_pane">
|
|
||||||
<label
|
|
||||||
for="send_rma_receipt_confirmation"
|
|
||||||
string="RMA Receipt Confirmation Email"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
class="fa fa-lg fa-building-o"
|
|
||||||
title="Values set here are company-specific."
|
|
||||||
groups="base.group_multi_company"
|
|
||||||
/>
|
|
||||||
<div class="text-muted">
|
|
||||||
When the RMA products are received, send an automatic information email.
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="row mt16"
|
class="row mt16"
|
||||||
attrs="{'invisible': [('send_rma_receipt_confirmation', '=', False)]}"
|
invisible="not send_rma_receipt_confirmation"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
for="rma_mail_receipt_confirmation_template_id"
|
for="rma_mail_receipt_confirmation_template_id"
|
||||||
string="Email Template"
|
string="Email Template"
|
||||||
class="col-lg-4 o_light_label"
|
class="col-lg-4 o_light_label"
|
||||||
/>
|
/>
|
||||||
<field
|
|
||||||
name="rma_mail_receipt_confirmation_template_id"
|
<field
|
||||||
class="oe_inline"
|
name="rma_mail_receipt_confirmation_template_id"
|
||||||
attrs="{'required': [('send_rma_receipt_confirmation', '=', True)]}"
|
class="oe_inline"
|
||||||
context="{'default_model': 'rma'}"
|
required="send_rma_receipt_confirmation"
|
||||||
/>
|
context="{'default_model': 'rma'}"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</setting>
|
||||||
</div>
|
<setting
|
||||||
<div
|
|
||||||
class="col-12 col-lg-6 o_setting_box"
|
|
||||||
title="Send automatic notification when the customer places an RMA"
|
title="Send automatic notification when the customer places an RMA"
|
||||||
|
help="When customers themselves place an RMA from the portal, send an automatic notification acknowleging it."
|
||||||
>
|
>
|
||||||
<div class="o_setting_left_pane">
|
|
||||||
<field name="send_rma_draft_confirmation" />
|
<field name="send_rma_draft_confirmation" />
|
||||||
</div>
|
|
||||||
<div class="o_setting_right_pane">
|
|
||||||
<label
|
|
||||||
for="send_rma_draft_confirmation"
|
|
||||||
string="RMA draft notification Email"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
class="fa fa-lg fa-building-o"
|
|
||||||
title="Values set here are company-specific."
|
|
||||||
groups="base.group_multi_company"
|
|
||||||
/>
|
|
||||||
<div class="text-muted">
|
|
||||||
When customers themselves place an RMA from the portal, send an automatic notification acknowleging it.
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="row mt16"
|
class="row mt16"
|
||||||
attrs="{'invisible': [('send_rma_draft_confirmation', '=', False)]}"
|
invisible="not send_rma_draft_confirmation"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
for="rma_mail_draft_confirmation_template_id"
|
for="rma_mail_draft_confirmation_template_id"
|
||||||
string="Email Template"
|
string="Email Template"
|
||||||
class="col-lg-4 o_light_label"
|
class="col-lg-4 o_light_label"
|
||||||
/>
|
/>
|
||||||
<field
|
<field
|
||||||
name="rma_mail_draft_confirmation_template_id"
|
name="rma_mail_draft_confirmation_template_id"
|
||||||
class="oe_inline"
|
class="oe_inline"
|
||||||
attrs="{'required': [('send_rma_draft_confirmation', '=', True)]}"
|
required="send_rma_draft_confirmation"
|
||||||
context="{'default_model': 'rma'}"
|
context="{'default_model': 'rma'}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</setting>
|
||||||
</div>
|
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
type="object"
|
type="object"
|
||||||
class="oe_stat_button"
|
class="oe_stat_button"
|
||||||
icon="fa-reply"
|
icon="fa-reply"
|
||||||
attrs="{'invisible': [('rma_count', '=', 0)]}"
|
invisible="rma_count == 0"
|
||||||
groups="rma.rma_group_user_own"
|
groups="rma.rma_group_user_own"
|
||||||
>
|
>
|
||||||
<field name="rma_count" widget="statinfo" string="RMA" />
|
<field name="rma_count" widget="statinfo" string="RMA" />
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
name="web_ribbon"
|
name="web_ribbon"
|
||||||
title="Archived"
|
title="Archived"
|
||||||
bg_color="bg-danger"
|
bg_color="bg-danger"
|
||||||
attrs="{'invisible': [('active', '=', True)]}"
|
invisible="active"
|
||||||
/>
|
/>
|
||||||
<group>
|
<group>
|
||||||
<field name="name" />
|
<field name="name" />
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<field name="name" />
|
<field name="name" />
|
||||||
<field name="user_id" />
|
<field name="user_id" />
|
||||||
<field name="company_id" groups="base.group_multi_company" />
|
<field name="company_id" groups="base.group_multi_company" />
|
||||||
<field name="company_id" invisible="1" />
|
<field name="company_id" column_invisible="1" />
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
@@ -81,11 +81,7 @@
|
|||||||
</kanban>
|
</kanban>
|
||||||
</field>
|
</field>
|
||||||
</page>
|
</page>
|
||||||
<page
|
<page name="emails" string="Email" invisible="not alias_domain">
|
||||||
name="emails"
|
|
||||||
string="Email"
|
|
||||||
attrs="{'invisible': [('alias_domain', '=', False)]}"
|
|
||||||
>
|
|
||||||
<group name="group_alias">
|
<group name="group_alias">
|
||||||
<label for="alias_name" string="Email Alias" />
|
<label for="alias_name" string="Email Alias" />
|
||||||
<div name="alias_def">
|
<div name="alias_def">
|
||||||
|
|||||||
@@ -120,73 +120,73 @@
|
|||||||
type="object"
|
type="object"
|
||||||
string="Send by Email"
|
string="Send by Email"
|
||||||
name="action_rma_send"
|
name="action_rma_send"
|
||||||
attrs="{'invisible':['|', ('sent','=',True), ('state', 'not in', ['draft', 'confirmed', 'received'])]}"
|
invisible="sent or state not in ['draft', 'confirmed', 'received']"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="Send by Mail"
|
string="Send by Mail"
|
||||||
name="action_rma_send"
|
name="action_rma_send"
|
||||||
attrs="{'invisible':['|', ('sent','=',False), ('state', 'not in', ['draft', 'confirmed', 'received'])]}"
|
invisible="not sent or state not in ['draft', 'confirmed', 'received']"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="Confirm"
|
string="Confirm"
|
||||||
name="action_confirm"
|
name="action_confirm"
|
||||||
states="draft"
|
invisible="state != 'draft'"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="To Refund"
|
string="To Refund"
|
||||||
name="action_refund"
|
name="action_refund"
|
||||||
attrs="{'invisible': [('can_be_refunded', '=', False)]}"
|
invisible="not can_be_refunded"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="Replace"
|
string="Replace"
|
||||||
name="action_replace"
|
name="action_replace"
|
||||||
attrs="{'invisible': [('can_be_replaced', '=', False)]}"
|
invisible="not can_be_replaced"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="Return to customer"
|
string="Return to customer"
|
||||||
name="action_return"
|
name="action_return"
|
||||||
attrs="{'invisible': [('can_be_returned', '=', False)]}"
|
invisible="not can_be_returned"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="Split"
|
string="Split"
|
||||||
name="action_split"
|
name="action_split"
|
||||||
attrs="{'invisible': [('can_be_split', '=', False)]}"
|
invisible="not can_be_split"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="Cancel"
|
string="Cancel"
|
||||||
name="action_cancel"
|
name="action_cancel"
|
||||||
confirm="Are you sure you want to cancel this RMA"
|
confirm="Are you sure you want to cancel this RMA"
|
||||||
states="draft,confirmed"
|
invisible="state not in ['draft', 'confirmed']"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="Set to draft"
|
string="Set to draft"
|
||||||
name="action_draft"
|
name="action_draft"
|
||||||
states="cancelled"
|
invisible="state != 'cancelled'"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="Lock"
|
string="Lock"
|
||||||
name="action_lock"
|
name="action_lock"
|
||||||
attrs="{'invisible': [('can_be_locked', '=', False)]}"
|
invisible="not can_be_locked"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="object"
|
type="object"
|
||||||
string="Unlock"
|
string="Unlock"
|
||||||
name="action_unlock"
|
name="action_unlock"
|
||||||
states="locked"
|
invisible="state != 'locked'"
|
||||||
/>
|
/>
|
||||||
<button type="object" string="Preview" name="action_preview" />
|
<button type="object" string="Preview" name="action_preview" />
|
||||||
<field
|
<field
|
||||||
@@ -203,7 +203,7 @@
|
|||||||
string="Receipt"
|
string="Receipt"
|
||||||
class="oe_stat_button"
|
class="oe_stat_button"
|
||||||
icon="fa-truck"
|
icon="fa-truck"
|
||||||
attrs="{'invisible': [('reception_move_id', '=', False)]}"
|
invisible="not reception_move_id"
|
||||||
>
|
>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
name="action_view_delivery"
|
name="action_view_delivery"
|
||||||
class="oe_stat_button"
|
class="oe_stat_button"
|
||||||
icon="fa-truck"
|
icon="fa-truck"
|
||||||
attrs="{'invisible': [('delivery_picking_count', '=', 0)]}"
|
invisible="delivery_picking_count == 0"
|
||||||
>
|
>
|
||||||
<field
|
<field
|
||||||
name="delivery_picking_count"
|
name="delivery_picking_count"
|
||||||
@@ -225,13 +225,13 @@
|
|||||||
name="action_view_refund"
|
name="action_view_refund"
|
||||||
class="oe_stat_button"
|
class="oe_stat_button"
|
||||||
icon="fa-pencil-square-o"
|
icon="fa-pencil-square-o"
|
||||||
attrs="{'invisible': [('refund_id', '=', False)]}"
|
invisible="not refund_id"
|
||||||
>
|
>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_title">
|
<div class="oe_title">
|
||||||
<h1>
|
<h1>
|
||||||
<field name="name" readonly="1" />
|
<field name="name" readonly="state != 'draft'" />
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<group>
|
<group>
|
||||||
@@ -240,101 +240,133 @@
|
|||||||
name="partner_id"
|
name="partner_id"
|
||||||
widget="res_partner_many2one"
|
widget="res_partner_many2one"
|
||||||
context="{'search_default_customer':1, 'show_address': 1, 'show_vat': True}"
|
context="{'search_default_customer':1, 'show_address': 1, 'show_vat': True}"
|
||||||
attrs="{'readonly': [('state', '!=', 'draft')]}"
|
readonly="state != 'draft'"
|
||||||
options="{'always_reload': True}"
|
options="{'always_reload': True}"
|
||||||
/>
|
/>
|
||||||
<field
|
<field
|
||||||
name="partner_shipping_id"
|
name="partner_shipping_id"
|
||||||
attrs="{'readonly': [('state', '!=', 'draft')]}"
|
readonly="state != 'draft'"
|
||||||
force_save="1"
|
force_save="1"
|
||||||
/>
|
/>
|
||||||
<field
|
<field
|
||||||
name="partner_invoice_id"
|
name="partner_invoice_id"
|
||||||
attrs="{'readonly': [('state', 'not in', ['draft', 'confirmed', 'received'])]}"
|
readonly="state not in ['draft', 'confirmed', 'received']"
|
||||||
force_save="1"
|
force_save="1"
|
||||||
/>
|
/>
|
||||||
<field name="picking_id" options="{'no_create': True}" />
|
<field
|
||||||
|
name="picking_id"
|
||||||
|
options="{'no_create': True}"
|
||||||
|
readonly="state != 'draft'"
|
||||||
|
/>
|
||||||
<field
|
<field
|
||||||
name="move_id"
|
name="move_id"
|
||||||
attrs="{'required': [('picking_id', '!=', False)], 'readonly': ['|', ('picking_id', '=', False), ('state', '!=', 'draft')]}"
|
required="picking_id"
|
||||||
|
readonly="not picking_id or state != 'draft'"
|
||||||
options="{'no_create': True}"
|
options="{'no_create': True}"
|
||||||
force_save="1"
|
force_save="1"
|
||||||
/>
|
/>
|
||||||
<field
|
<field
|
||||||
name="product_id"
|
name="product_id"
|
||||||
force_save="1"
|
force_save="1"
|
||||||
attrs="{'readonly': ['|', ('picking_id', '!=', False), ('state', '!=', 'draft')]}"
|
readonly="picking_id or state != 'draft'"
|
||||||
/>
|
/>
|
||||||
<field name="uom_category_id" invisible="1" />
|
<field name="uom_category_id" invisible="1" />
|
||||||
<label for="product_uom_qty" />
|
<label for="product_uom_qty" />
|
||||||
<div class="o_row">
|
<div class="o_row">
|
||||||
<field
|
<field
|
||||||
name="product_uom_qty"
|
name="product_uom_qty"
|
||||||
attrs="{'readonly': [('state', '!=', 'draft')]}"
|
readonly="state != 'draft'"
|
||||||
force_save="1"
|
force_save="1"
|
||||||
/>
|
/>
|
||||||
<field
|
<field
|
||||||
name="product_uom"
|
name="product_uom"
|
||||||
groups="uom.group_uom"
|
groups="uom.group_uom"
|
||||||
domain="[('category_id', '=', uom_category_id)]"
|
domain="[('category_id', '=', uom_category_id)]"
|
||||||
attrs="{'readonly': [('state', '!=', 'draft')]}"
|
readonly="state != 'draft'"
|
||||||
force_save="1"
|
force_save="1"
|
||||||
/>
|
/>
|
||||||
<field name="product_uom" invisible="1" />
|
<field name="product_uom" invisible="1" />
|
||||||
</div>
|
</div>
|
||||||
<field
|
<field
|
||||||
name="delivered_qty"
|
name="delivered_qty"
|
||||||
attrs="{'invisible': [('delivered_qty', '=', 0.0)]}"
|
invisible="delivered_qty == 0.0"
|
||||||
/>
|
/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="date" />
|
<field name="date" readonly="state != 'draft'" />
|
||||||
<field name="user_id" />
|
<field
|
||||||
<field name="team_id" />
|
name="user_id"
|
||||||
|
readonly="state in ['locked', 'cancelled']"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="team_id"
|
||||||
|
readonly="state in ['locked', 'cancelled']"
|
||||||
|
/>
|
||||||
<field
|
<field
|
||||||
name="tag_ids"
|
name="tag_ids"
|
||||||
widget="many2many_tags"
|
widget="many2many_tags"
|
||||||
options="{'color_field': 'color', 'no_create_edit': True}"
|
options="{'color_field': 'color', 'no_create_edit': True}"
|
||||||
placeholder="Tags..."
|
placeholder="Tags..."
|
||||||
/>
|
/>
|
||||||
<field name="origin" />
|
<field
|
||||||
|
name="origin"
|
||||||
|
readonly="state in ['locked', 'cancelled']"
|
||||||
|
/>
|
||||||
<field name="operation_id" />
|
<field name="operation_id" />
|
||||||
<field
|
<field
|
||||||
name="finalization_id"
|
name="finalization_id"
|
||||||
attrs="{'invisible': [('state', '!=', 'finished')]}"
|
readonly="1"
|
||||||
|
invisible="state != 'finished'"
|
||||||
/>
|
/>
|
||||||
<field
|
<field
|
||||||
name="company_id"
|
name="company_id"
|
||||||
options="{'no_create': True}"
|
options="{'no_create': True}"
|
||||||
groups="base.group_multi_company"
|
groups="base.group_multi_company"
|
||||||
|
readonly="state in ['locked', 'cancelled']"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="company_id"
|
||||||
|
invisible="1"
|
||||||
|
readonly="state in ['locked', 'cancelled']"
|
||||||
/>
|
/>
|
||||||
<field name="company_id" invisible="1" />
|
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page name="page_other" string="Other Information">
|
<page name="page_other" string="Other Information">
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="procurement_group_id" />
|
<field
|
||||||
|
name="procurement_group_id"
|
||||||
|
readonly="state not in ['draft', 'confirmed', 'received']"
|
||||||
|
/>
|
||||||
<field
|
<field
|
||||||
name="location_id"
|
name="location_id"
|
||||||
options="{'no_create': True, 'no_open': True}"
|
options="{'no_create': True, 'no_open': True}"
|
||||||
groups="stock.group_stock_multi_locations"
|
groups="stock.group_stock_multi_locations"
|
||||||
attrs="{'readonly': [('state', '!=', 'draft')]}"
|
readonly="state != 'draft'"
|
||||||
/>
|
/>
|
||||||
<field name="location_id" invisible="1" />
|
<field name="location_id" invisible="1" />
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="deadline" />
|
|
||||||
<field name="priority" widget="priority" />
|
|
||||||
<field
|
<field
|
||||||
name="origin_split_rma_id"
|
name="deadline"
|
||||||
attrs="{'invisible': [('origin_split_rma_id', '=', False)]}"
|
readonly="state in ['locked', 'cancelled']"
|
||||||
/>
|
/>
|
||||||
|
<field
|
||||||
|
name="priority"
|
||||||
|
widget="priority"
|
||||||
|
readonly="state != 'draft'"
|
||||||
|
/>
|
||||||
|
<field name="origin_split_rma_id" invisible="1" />
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="description" widget="html" colspan="4" />
|
<field
|
||||||
|
name="description"
|
||||||
|
widget="html"
|
||||||
|
colspan="4"
|
||||||
|
readonly="state in ['locked', 'cancelled']"
|
||||||
|
/>
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
@@ -371,7 +403,7 @@
|
|||||||
string="Finish"
|
string="Finish"
|
||||||
name="action_finish"
|
name="action_finish"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
attrs="{'invisible': [('can_be_finished', '=', False)]}"
|
invisible="not can_be_finished"
|
||||||
groups="rma.group_rma_manual_finalization"
|
groups="rma.group_rma_manual_finalization"
|
||||||
/>
|
/>
|
||||||
</xpath>
|
</xpath>
|
||||||
@@ -392,7 +424,7 @@
|
|||||||
<field name="name">rma.calendar</field>
|
<field name="name">rma.calendar</field>
|
||||||
<field name="model">rma</field>
|
<field name="model">rma</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<calendar date_start="date" mode="month" color="state" quick_add="False">
|
<calendar date_start="date" mode="month" color="state">
|
||||||
<field name="name" />
|
<field name="name" />
|
||||||
<field name="partner_id" />
|
<field name="partner_id" />
|
||||||
<field name="product_id" />
|
<field name="product_id" />
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
type="object"
|
type="object"
|
||||||
class="oe_stat_button"
|
class="oe_stat_button"
|
||||||
icon="fa-reply"
|
icon="fa-reply"
|
||||||
attrs="{'invisible': [('rma_count', '=', 0)]}"
|
invisible="rma_count == 0"
|
||||||
groups="rma.rma_group_user_own"
|
groups="rma.rma_group_user_own"
|
||||||
>
|
>
|
||||||
<field name="rma_count" widget="statinfo" string="RMA" />
|
<field name="rma_count" widget="statinfo" string="RMA" />
|
||||||
|
|||||||
@@ -11,37 +11,26 @@
|
|||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="scheduled_date" />
|
<field name="scheduled_date" />
|
||||||
<field
|
<field name="warehouse_id" invisible="type != 'replace'" />
|
||||||
name="warehouse_id"
|
|
||||||
attrs="{'invisible': [('type', '!=', 'replace')]}"
|
|
||||||
/>
|
|
||||||
<field
|
<field
|
||||||
name="rma_return_grouping"
|
name="rma_return_grouping"
|
||||||
attrs="{'invisible': ['|', ('type', '=', 'replace'), ('rma_count', '=', 1)]}"
|
invisible="type == 'replace' or rma_count == 1"
|
||||||
/>
|
/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="uom_category_id" invisible="1" />
|
<field name="uom_category_id" invisible="1" />
|
||||||
<field
|
<field
|
||||||
name="product_id"
|
name="product_id"
|
||||||
attrs="{'invisible': ['|', ('type', '!=', 'replace'), ('rma_count', '>', 1)], 'required': [('type', '=', 'replace'), ('rma_count', '=', 1)]}"
|
invisible="type != 'replace' or rma_count > 1"
|
||||||
|
required="type == 'replace' and rma_count == 1"
|
||||||
/>
|
/>
|
||||||
<label
|
<label for="product_uom_qty" invisible="rma_count > 1" />
|
||||||
for="product_uom_qty"
|
<div class="o_row" invisible="rma_count > 1">
|
||||||
attrs="{'invisible': [('rma_count', '>', 1)]}"
|
<field name="product_uom_qty" required="rma_count == 1" />
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="o_row"
|
|
||||||
attrs="{'invisible': [('rma_count', '>', 1)]}"
|
|
||||||
>
|
|
||||||
<field
|
|
||||||
name="product_uom_qty"
|
|
||||||
attrs="{'required': [('rma_count', '=', 1)]}"
|
|
||||||
/>
|
|
||||||
<field
|
<field
|
||||||
name="product_uom"
|
name="product_uom"
|
||||||
groups="uom.group_uom"
|
groups="uom.group_uom"
|
||||||
attrs="{'required': [('rma_count', '=', 1)]}"
|
required="rma_count == 1"
|
||||||
domain="[('category_id', '=', uom_category_id)]"
|
domain="[('category_id', '=', uom_category_id)]"
|
||||||
/>
|
/>
|
||||||
<field name="product_uom" invisible="1" />
|
<field name="product_uom" invisible="1" />
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<group name="group_rma">
|
<group name="group_rma">
|
||||||
<field
|
<field
|
||||||
name="create_rma"
|
name="create_rma"
|
||||||
attrs="{'invisible': [('picking_type_code', '!=', 'outgoing')]}"
|
invisible="picking_type_code != 'outgoing'"
|
||||||
/>
|
/>
|
||||||
<field name="rma_location_ids" invisible="1" />
|
<field name="rma_location_ids" invisible="1" />
|
||||||
<field name="picking_id" invisible="1" />
|
<field name="picking_id" invisible="1" />
|
||||||
|
|||||||
Reference in New Issue
Block a user