Merge PR #256 into 14.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot
2022-02-01 22:17:27 +00:00
23 changed files with 809 additions and 255 deletions

View File

@@ -51,6 +51,11 @@ If you want RMAs to be created from incoming emails, you need to:
one.
#. Go to 'Email' tab and set an 'Email Alias'.
If you want to manually finish RMAs, you need to:
#. Go to *Settings > Inventory*.
#. Set *Finish RMAs manually* checkbox on.
Usage
=====
@@ -79,6 +84,11 @@ To use this module, you need to:
The RMA will be set automatically to 'Replaced' or 'Returned' state when
the RMA quantity is equal or lower than the quantity in done delivery
orders linked to it.
#. You can also finish the RMA without further ado. To do so click on the *Finish*
button. A wizard will ask you for the reason from a selection of preconfigured ones.
Be sure to configure them in advance on *RMA > Configuration > Finalization Reasons*.
Once the RMA is finished, it will be set to that state and the reason will be
registered.
An RMA can also be created from a return of a delivery order:

View File

@@ -10,7 +10,7 @@
"author": "Tecnativa, Odoo Community Association (OCA)",
"maintainers": ["ernestotejeda"],
"license": "AGPL-3",
"depends": ["account", "stock"],
"depends": ["stock_account"],
"data": [
"views/report_rma.xml",
"report/report.xml",
@@ -21,9 +21,11 @@
"security/ir.model.access.csv",
"wizard/stock_picking_return_views.xml",
"wizard/rma_delivery_views.xml",
"wizard/rma_finalization_wizard_views.xml",
"wizard/rma_split_views.xml",
"views/menus.xml",
"views/res_partner_views.xml",
"views/rma_finalization_views.xml",
"views/rma_portal_templates.xml",
"views/rma_team_views.xml",
"views/rma_views.xml",

View File

@@ -56,15 +56,10 @@ def post_init_hook(cr, registry):
)
data[picking_type] = stock_picking_type.create(values).id
rma_out_type = stock_picking_type.browse(data["rma_out_type_id"])
rma_out_type.write(
{"return_picking_type_id": data.get("rma_in_type_id", False)}
)
rma_in_type = stock_picking_type.browse(data["rma_in_type_id"])
rma_in_type.write(
{"return_picking_type_id": data.get("rma_out_type_id", False)}
)
whs.write(data)
if data:
whs.write(data)
whs.rma_in_type_id.return_picking_type_id = whs.rma_out_type_id.id
whs.rma_out_type_id.return_picking_type_id = whs.rma_in_type_id.id
# Create rma locations and picking types
warehouses = env["stock.warehouse"].search([])

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-01-21 09:33+0000\n"
"PO-Revision-Date: 2022-01-21 09:33+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -226,11 +228,6 @@ msgstr ""
msgid "<strong>Delivered quantity</strong>"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.report_rma_document
msgid "<strong>Invoicing address:</strong>"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.report_rma_document
msgid "<strong>Move:</strong>"
@@ -292,6 +289,16 @@ msgstr ""
msgid "<strong>Responsible:</strong>"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.report_rma_document
msgid "<strong>Shipping Address:</strong>"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.portal_rma_page
msgid "<strong>Shipping address:</strong>"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.report_rma_document
msgid "<strong>State:</strong>"
@@ -321,9 +328,11 @@ msgid "Action Needed"
msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma_finalization__active
#: model:ir.model.fields,field_description:rma.field_rma_operation__active
#: model:ir.model.fields,field_description:rma.field_rma_tag__active
#: model:ir.model.fields,field_description:rma.field_rma_team__active
#: model_terms:ir.ui.view,arch_db:rma.rma_finalization_view_search
#: model_terms:ir.ui.view,arch_db:rma.rma_tag_view_search
msgid "Active"
msgstr ""
@@ -374,7 +383,9 @@ msgid "Aliased Model"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.rma_finalization_view_search
#: model_terms:ir.ui.view,arch_db:rma.rma_tag_view_search
#: model_terms:ir.ui.view,arch_db:rma.view_rma_finalization_form
msgid "Archived"
msgstr ""
@@ -394,6 +405,11 @@ msgstr ""
msgid "Avatar"
msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__can_be_finished
msgid "Can Be Finished"
msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__can_be_locked
msgid "Can Be Locked"
@@ -420,6 +436,7 @@ msgid "Can Be Split"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.rma_finalization_wizard_view_form
#: model_terms:ir.ui.view,arch_db:rma.rma_redelivery_wizard_view_form
#: model_terms:ir.ui.view,arch_db:rma.rma_split_wizard_view_form2
#: model_terms:ir.ui.view,arch_db:rma.rma_view_form
@@ -469,6 +486,7 @@ msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__company_id
#: model:ir.model.fields,field_description:rma.field_rma_finalization__company_id
#: model:ir.model.fields,field_description:rma.field_rma_team__company_id
msgid "Company"
msgstr ""
@@ -513,6 +531,11 @@ msgstr ""
msgid "Create RMAs"
msgstr ""
#. module: rma
#: model_terms:ir.actions.act_window,help:rma.action_rma_finalization
msgid "Create a new RMA finalization"
msgstr ""
#. module: rma
#: model_terms:ir.actions.act_window,help:rma.action_rma_tag
msgid "Create a new RMA tag"
@@ -521,6 +544,8 @@ msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__create_uid
#: model:ir.model.fields,field_description:rma.field_rma_delivery_wizard__create_uid
#: model:ir.model.fields,field_description:rma.field_rma_finalization__create_uid
#: model:ir.model.fields,field_description:rma.field_rma_finalization_wizard__create_uid
#: model:ir.model.fields,field_description:rma.field_rma_operation__create_uid
#: model:ir.model.fields,field_description:rma.field_rma_split_wizard__create_uid
#: model:ir.model.fields,field_description:rma.field_rma_tag__create_uid
@@ -531,6 +556,8 @@ msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__create_date
#: model:ir.model.fields,field_description:rma.field_rma_delivery_wizard__create_date
#: model:ir.model.fields,field_description:rma.field_rma_finalization__create_date
#: model:ir.model.fields,field_description:rma.field_rma_finalization_wizard__create_date
#: model:ir.model.fields,field_description:rma.field_rma_operation__create_date
#: model:ir.model.fields,field_description:rma.field_rma_split_wizard__create_date
#: model:ir.model.fields,field_description:rma.field_rma_tag__create_date
@@ -625,6 +652,8 @@ msgstr ""
#: model:ir.model.fields,field_description:rma.field_res_users__display_name
#: model:ir.model.fields,field_description:rma.field_rma__display_name
#: model:ir.model.fields,field_description:rma.field_rma_delivery_wizard__display_name
#: model:ir.model.fields,field_description:rma.field_rma_finalization__display_name
#: model:ir.model.fields,field_description:rma.field_rma_finalization_wizard__display_name
#: model:ir.model.fields,field_description:rma.field_rma_operation__display_name
#: model:ir.model.fields,field_description:rma.field_rma_split_wizard__display_name
#: model:ir.model.fields,field_description:rma.field_rma_tag__display_name
@@ -711,6 +740,36 @@ msgstr ""
msgid "Extracted from"
msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__finalization_id
msgid "Finalization Reason"
msgstr ""
#. module: rma
#: model:ir.model.constraint,message:rma.constraint_rma_finalization_name_company_uniq
msgid "Finalization name already exists !"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.rma_view_form
msgid "Finish"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.rma_finalization_wizard_view_form
msgid "Finish RMA"
msgstr ""
#. module: rma
#: model:ir.actions.act_window,name:rma.rma_finalization_wizard_action
msgid "Finish RMA Manualy"
msgstr ""
#. module: rma
#: model:ir.model.fields.selection,name:rma.selection__rma__state__finished
msgid "Finished"
msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__message_follower_ids
#: model:ir.model.fields,field_description:rma.field_rma_team__message_follower_ids
@@ -748,6 +807,8 @@ msgstr ""
#: model:ir.model.fields,field_description:rma.field_res_users__id
#: model:ir.model.fields,field_description:rma.field_rma__id
#: model:ir.model.fields,field_description:rma.field_rma_delivery_wizard__id
#: model:ir.model.fields,field_description:rma.field_rma_finalization__id
#: model:ir.model.fields,field_description:rma.field_rma_finalization_wizard__id
#: model:ir.model.fields,field_description:rma.field_rma_operation__id
#: model:ir.model.fields,field_description:rma.field_rma_split_wizard__id
#: model:ir.model.fields,field_description:rma.field_rma_tag__id
@@ -818,6 +879,16 @@ msgstr ""
msgid "Invoice Address"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.report_rma_document
msgid "Invoicing Address:"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.report_rma_document
msgid "Invoicing and Shipping Address:"
msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__message_is_follower
#: model:ir.model.fields,field_description:rma.field_rma_team__message_is_follower
@@ -843,6 +914,8 @@ msgstr ""
#: model:ir.model.fields,field_description:rma.field_res_users____last_update
#: model:ir.model.fields,field_description:rma.field_rma____last_update
#: model:ir.model.fields,field_description:rma.field_rma_delivery_wizard____last_update
#: model:ir.model.fields,field_description:rma.field_rma_finalization____last_update
#: model:ir.model.fields,field_description:rma.field_rma_finalization_wizard____last_update
#: model:ir.model.fields,field_description:rma.field_rma_operation____last_update
#: model:ir.model.fields,field_description:rma.field_rma_split_wizard____last_update
#: model:ir.model.fields,field_description:rma.field_rma_tag____last_update
@@ -858,6 +931,8 @@ msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__write_uid
#: model:ir.model.fields,field_description:rma.field_rma_delivery_wizard__write_uid
#: model:ir.model.fields,field_description:rma.field_rma_finalization__write_uid
#: model:ir.model.fields,field_description:rma.field_rma_finalization_wizard__write_uid
#: model:ir.model.fields,field_description:rma.field_rma_operation__write_uid
#: model:ir.model.fields,field_description:rma.field_rma_split_wizard__write_uid
#: model:ir.model.fields,field_description:rma.field_rma_tag__write_uid
@@ -868,6 +943,8 @@ msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma__write_date
#: model:ir.model.fields,field_description:rma.field_rma_delivery_wizard__write_date
#: model:ir.model.fields,field_description:rma.field_rma_finalization__write_date
#: model:ir.model.fields,field_description:rma.field_rma_finalization_wizard__write_date
#: model:ir.model.fields,field_description:rma.field_rma_operation__write_date
#: model:ir.model.fields,field_description:rma.field_rma_split_wizard__write_date
#: model:ir.model.fields,field_description:rma.field_rma_tag__write_date
@@ -901,6 +978,13 @@ msgstr ""
msgid "Main Attachment"
msgstr ""
#. module: rma
#: model_terms:ir.actions.act_window,help:rma.action_rma_finalization
msgid ""
"Manage RMA finalization reasons to better classify them for tracking and "
"analysis purposes."
msgstr ""
#. module: rma
#: model_terms:ir.actions.act_window,help:rma.action_rma_tag
msgid ""
@@ -1195,6 +1279,29 @@ msgstr ""
msgid "RMA Delivery Wizard"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.view_rma_finalization_form
msgid "RMA Finalization"
msgstr ""
#. module: rma
#: model:ir.model,name:rma.model_rma_finalization
msgid "RMA Finalization Reason"
msgstr ""
#. module: rma
#: model:ir.actions.act_window,name:rma.action_rma_finalization
#: model:ir.ui.menu,name:rma.rma_configuration_rma_finalization_menu
#: model_terms:ir.ui.view,arch_db:rma.rma_finalization_view_search
#: model_terms:ir.ui.view,arch_db:rma.view_rma_finalization_list
msgid "RMA Finalization Reasons"
msgstr ""
#. module: rma
#: model:ir.model,name:rma.model_rma_finalization_wizard
msgid "RMA Finalization Wizard"
msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_stock_warehouse__rma_in_type_id
msgid "RMA In Type"
@@ -1341,6 +1448,16 @@ msgstr ""
msgid "RMAs yet to be fully processed"
msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma_finalization_wizard__finalization_id
msgid "Reason"
msgstr ""
#. module: rma
#: model:ir.model.fields,field_description:rma.field_rma_finalization__name
msgid "Reason Name"
msgstr ""
#. module: rma
#: model_terms:ir.ui.view,arch_db:rma.rma_view_form
msgid "Receipt"

View File

@@ -2,6 +2,7 @@
from . import account_move
from . import rma
from . import rma_finalization
from . import rma_operation
from . import rma_tag
from . import rma_team

View File

@@ -6,6 +6,11 @@ from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
group_rma_manual_finalization = fields.Boolean(
string="Finish RMA manually choosing a reason",
help="Allow to finish an RMA without returning back a product or refunding",
implied_group="rma.group_rma_manual_finalization",
)
send_rma_confirmation = fields.Boolean(
related="company_id.send_rma_confirmation",
readonly=False,

View File

@@ -67,6 +67,14 @@ class Rma(models.Model):
states={"locked": [("readonly", True)], "cancelled": [("readonly", True)]},
)
tag_ids = fields.Many2many(comodel_name="rma.tag", string="Tags")
finalization_id = fields.Many2one(
string="Finalization Reason",
comodel_name="rma.finalization",
copy=False,
readonly=True,
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
tracking=True,
)
company_id = fields.Many2one(
comodel_name="res.company",
default=lambda self: self.env.company,
@@ -171,6 +179,7 @@ class Rma(models.Model):
("refunded", "Refunded"),
("returned", "Returned"),
("replaced", "Replaced"),
("finished", "Finished"),
("locked", "Locked"),
("cancelled", "Canceled"),
],
@@ -245,6 +254,9 @@ class Rma(models.Model):
can_be_locked = fields.Boolean(
compute="_compute_can_be_locked",
)
can_be_finished = fields.Boolean(
compute="_compute_can_be_finished",
)
remaining_qty = fields.Float(
string="Remaining delivered qty",
digits="Product Unit of Measure",
@@ -388,6 +400,14 @@ class Rma(models.Model):
"replaced",
]
@api.depends("state", "remaining_qty")
def _compute_can_be_finished(self):
for rma in self:
rma.can_be_finished = (
rma.state in {"received", "waiting_replacement", "waiting_return"}
and rma.remaining_qty > 0
)
@api.depends("product_uom_qty", "state", "remaining_qty", "remaining_qty_to_done")
def _compute_can_be_split(self):
"""Compute 'can_be_split'. This field controls the
@@ -718,6 +738,21 @@ class Rma(models.Model):
action["context"].update(active_id=self.id, active_ids=self.ids)
return action
def action_finish(self):
"""Invoked when a user wants to manually finalize the RMA"""
self.ensure_one()
self._ensure_can_be_returned()
# Force active_id to avoid issues when coming from smart buttons
# in other models
action = (
self.env.ref("rma.rma_finalization_wizard_action")
.with_context(active_id=self.id)
.read()[0]
)
action["context"] = dict(self.env.context)
action["context"].update(active_id=self.id, active_ids=self.ids)
return action
def action_cancel(self):
"""Invoked when 'Cancel' button in rma form view is clicked."""
self.mapped("reception_move_id")._action_cancel()
@@ -912,7 +947,14 @@ class Rma(models.Model):
lambda r: r.move_id != self.move_id
).unlink()
return_line = return_wizard.product_return_moves
return_line.quantity = self.product_uom_qty
return_line.update(
{
"quantity": self.product_uom_qty,
# The to_refund field is now True by default, which isn't right in the RMA
# creation context.
"to_refund": False,
}
)
# set_rma_picking_type is to override the copy() method of stock
# picking and change the default picking type to rma picking type.
picking_action = return_wizard.with_context(

View File

@@ -0,0 +1,26 @@
# Copyright 2022 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class RmaFinalization(models.Model):
_description = "RMA Finalization Reason"
_name = "rma.finalization"
_order = "name"
active = fields.Boolean(default=True)
name = fields.Char(
string="Reason Name",
required=True,
translate=True,
copy=False,
)
company_id = fields.Many2one(comodel_name="res.company")
_sql_constraints = [
(
"name_company_uniq",
"unique (name, company_id)",
"Finalization name already exists !",
),
]

View File

@@ -6,3 +6,8 @@ If you want RMAs to be created from incoming emails, you need to:
#. Go to *RMA > Configuration > RMA Team* and select a team or create a new
one.
#. Go to 'Email' tab and set an 'Email Alias'.
If you want to manually finish RMAs, you need to:
#. Go to *Settings > Inventory*.
#. Set *Finish RMAs manually* checkbox on.

View File

@@ -23,6 +23,11 @@ To use this module, you need to:
The RMA will be set automatically to 'Replaced' or 'Returned' state when
the RMA quantity is equal or lower than the quantity in done delivery
orders linked to it.
#. You can also finish the RMA without further ado. To do so click on the *Finish*
button. A wizard will ask you for the reason from a selection of preconfigured ones.
Be sure to configure them in advance on *RMA > Configuration > Finalization Reasons*.
Once the RMA is finished, it will be set to that state and the reason will be
registered.
An RMA can also be created from a return of a delivery order:

View File

@@ -10,3 +10,7 @@ access_rma_tag_user_own,rma.tag.user.own,model_rma_tag,rma_group_user_own,1,0,0,
access_rma_tag_manager,rma.tag.manager,model_rma_tag,rma_group_manager,1,1,1,1
access_rma_delivery_wizard_user_all,rma.delivery.wizard.user.all,model_rma_delivery_wizard,rma_group_user_all,1,1,1,1
access_rma_split_wizard_user_all,rma.split.wizard.user.all,model_rma_split_wizard,rma_group_user_all,1,1,1,1
access_rma_finalization_portal,rma.finalization.portal,model_rma_finalization,base.group_portal,1,0,0,0
access_rma_finalization_user_own,rma.finalization.user.own,model_rma_finalization,rma_group_user_own,1,0,0,0
access_rma_finalization_manager,rma.finalization.manager,model_rma_finalization,rma_group_manager,1,1,1,1
access_rma_finalization_wizard_user_own,rma.finalization.wizard.user.own,model_rma_finalization_wizard,rma_group_user_own,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
10 access_rma_tag_manager rma.tag.manager model_rma_tag rma_group_manager 1 1 1 1
11 access_rma_delivery_wizard_user_all rma.delivery.wizard.user.all model_rma_delivery_wizard rma_group_user_all 1 1 1 1
12 access_rma_split_wizard_user_all rma.split.wizard.user.all model_rma_split_wizard rma_group_user_all 1 1 1 1
13 access_rma_finalization_portal rma.finalization.portal model_rma_finalization base.group_portal 1 0 0 0
14 access_rma_finalization_user_own rma.finalization.user.own model_rma_finalization rma_group_user_own 1 0 0 0
15 access_rma_finalization_manager rma.finalization.manager model_rma_finalization rma_group_manager 1 1 1 1
16 access_rma_finalization_wizard_user_own rma.finalization.wizard.user.own model_rma_finalization_wizard rma_group_user_own 1 0 0 0

View File

@@ -38,6 +38,10 @@
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
/>
</record>
<record id="group_rma_manual_finalization" model="res.groups">
<field name="name">Allow RMA manual finalization</field>
<field name="category_id" ref="base.module_category_hidden" />
</record>
<!-- Record Rules -->
<record id="rma_rule_user_own" model="ir.rule">
<field name="name">Personal RMAs</field>
@@ -79,6 +83,14 @@
name="domain_force"
>['|',('company_id','=',False),('company_id','in',company_ids)]</field>
</record>
<record id="rma_finalization_comp_rule" model="ir.rule">
<field name="name">RMA Finalization Reason multi-company</field>
<field name="model_id" ref="model_rma_finalization" />
<field name="global" eval="True" />
<field
name="domain_force"
> ['|', ('company_id', 'in', company_ids), ('company_id', '=', False)]</field>
</record>
<!-- New users will belong to rma_group_user_own -->
<record id="base.default_user" model="res.users">
<field name="groups_id" eval="[(4, ref('rma_group_user_own'))]" />

View File

@@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
<title>Return Merchandise Authorization Management</title>
<style type="text/css">
@@ -401,6 +401,11 @@ Besides, you have full integration of the RMA documents in the customer portal.<
one.</li>
<li>Go to Email tab and set an Email Alias.</li>
</ol>
<p>If you want to manually finish RMAs, you need to:</p>
<ol class="arabic simple">
<li>Go to <em>Settings &gt; Inventory</em>.</li>
<li>Set <em>Finish RMAs manually</em> checkbox on.</li>
</ol>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id2">Usage</a></h1>
@@ -430,6 +435,11 @@ the RMA quantity is equal or lower than the quantity in done delivery
orders linked to it.</li>
</ul>
</li>
<li>You can also finish the RMA without further ado. To do so click on the <em>Finish</em>
button. A wizard will ask you for the reason from a selection of preconfigured ones.
Be sure to configure them in advance on <em>RMA &gt; Configuration &gt; Finalization Reasons</em>.
Once the RMA is finished, it will be set to that state and the reason will be
registered.</li>
</ol>
<p>An RMA can also be created from a return of a delivery order:</p>
<ol class="arabic simple">

View File

@@ -50,6 +50,13 @@ class TestRma(SavepointCase):
"type": "delivery",
}
)
cls.finalization_reason_1 = cls.env["rma.finalization"].create(
{"name": "[Test] It can't be repaired and customer doesn't want it"}
)
cls.finalization_reason_2 = cls.env["rma.finalization"].create(
{"name": "[Test] It's out of warranty. To be scrapped"}
)
cls.env.ref("rma.group_rma_manual_finalization").users |= cls.env.user
def _create_rma(self, partner=None, product=None, qty=None, location=None):
rma_form = Form(self.env["rma"])
@@ -123,6 +130,8 @@ class TestRma(SavepointCase):
picking.button_validate()
return picking
class TestRmaCase(TestRma):
def test_onchange(self):
rma_form = Form(self.env["rma"])
# If partner changes, the invoice address is set
@@ -500,6 +509,22 @@ class TestRma(SavepointCase):
self.assertFalse(rma.can_be_replaced)
self._test_readonly_fields(rma)
def test_finish_rma(self):
# Create, confirm and receive an RMA
rma = self._create_confirm_receive(self.partner, self.product, 10, self.rma_loc)
rma.action_finish()
finalization_form = Form(
self.env["rma.finalization.wizard"].with_context(
active_ids=rma.ids,
rma_finalization_type="replace",
)
)
finalization_form.finalization_id = self.finalization_reason_2
finalization_wizard = finalization_form.save()
finalization_wizard.action_finish()
self.assertEqual(rma.state, "finished")
self.assertEqual(rma.finalization_id, self.finalization_reason_2)
def test_mass_return_to_customer(self):
# Create, confirm and receive rma_1
rma_1 = self._create_confirm_receive(

View File

@@ -15,14 +15,28 @@
</t>
</t>
<t
t-if="(doc.partner_id or doc.partner_invoice_id) and doc.partner_id != doc.partner_invoice_id"
t-if="doc.partner_shipping_id == doc.partner_invoice_id
and doc.partner_invoice_id != doc.partner_id
or doc.partner_shipping_id != doc.partner_invoice_id"
>
<t t-set="information_block">
<strong>Invoicing address:</strong>
<div
<t t-set="information_block">
<strong
t-if="doc.partner_shipping_id == doc.partner_invoice_id"
>Invoicing and Shipping Address:</strong>
<strong
t-if="doc.partner_shipping_id != doc.partner_invoice_id"
>Invoicing Address:</strong>
<div
t-field="doc.partner_invoice_id"
t-options='{"widget": "contact", "fields": ["address", "name", "phone"], "no_marker": True, "phone_icons": True}'
/>
<t t-if="doc.partner_shipping_id != doc.partner_invoice_id">
<strong>Shipping Address:</strong>
<div
t-field="doc.partner_shipping_id"
t-options='{"widget": "contact", "fields": ["address", "name", "phone"], "no_marker": True, "phone_icons": True}'
/>
</t>
</t>
</t>
<div class="page">

View File

@@ -8,6 +8,21 @@
expr="//div[@data-key='stock']/div[hasclass('o_settings_container')]"
position="inside"
>
<div class="col-12 col-lg-6 o_setting_box" title="Finish RMAs manually">
<div class="o_setting_left_pane">
<field name="group_rma_manual_finalization" />
</div>
<div class="o_setting_right_pane">
<label
for="group_rma_manual_finalization"
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"
title="Send automatic RMA info to customer"

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="rma_finalization_view_search" model="ir.ui.view">
<field name="model">rma.finalization</field>
<field name="arch" type="xml">
<search string="RMA Finalization Reasons">
<field name="name" />
<filter
string="Archived"
name="inactive"
domain="[('active','=',False)]"
/>
<filter
string="Active"
name="active"
domain="[('active','!=',False)]"
/>
</search>
</field>
</record>
<record id="view_rma_finalization_form" model="ir.ui.view">
<field name="name">Rma Finalization Reasons</field>
<field name="model">rma.finalization</field>
<field name="arch" type="xml">
<form string="RMA Finalization">
<sheet>
<widget
name="web_ribbon"
title="Archived"
bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<group>
<field name="name" />
<field name="company_id" groups="base.group_multi_company" />
<field name="active" invisible="1" />
</group>
</sheet>
</form>
</field>
</record>
<record id="view_rma_finalization_list" model="ir.ui.view">
<field name="name">RMA Finalization Reasons</field>
<field name="model">rma.finalization</field>
<field eval="6" name="priority" />
<field name="arch" type="xml">
<tree string="RMA Finalization Reasons">
<field name="name" />
<field name="company_id" groups="base.group_multi_company" />
</tree>
</field>
</record>
<record id="action_rma_finalization" model="ir.actions.act_window">
<field name="name">RMA Finalization Reasons</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">rma.finalization</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new RMA finalization
</p><p>
Manage RMA finalization reasons to better classify them for tracking and analysis purposes.
</p>
</field>
</record>
<menuitem
id="rma_configuration_rma_finalization_menu"
name="RMA Finalization Reasons"
parent="rma_configuration_menu"
action="action_rma_finalization"
groups="rma.group_rma_manual_finalization"
/>
</odoo>

View File

@@ -159,6 +159,7 @@
<t t-set="card_body">
<div id="general_information">
<div class="row mt4">
<!-- Customer -->
<div
t-if="rma.partner_id"
class="col-12 col-md-6 mb-4 mb-md-0"
@@ -189,6 +190,38 @@
</div>
</div>
</div>
<!-- Shipping Address -->
<div
t-if="rma.partner_shipping_id"
class="col-12 col-md-6 mb-4 mb-md-0"
>
<h6>
<strong>Shipping address:</strong>
</h6>
<div class="row">
<div class="col flex-grow-0 pr-3">
<img
t-if="rma.partner_shipping_id.image_1024"
class="rounded-circle mt-1 o_portal_contact_img"
t-att-src="image_data_uri(rma.partner_shipping_id.image_1024)"
alt="Contact"
/>
<img
t-else=""
class="rounded-circle mt-1 o_portal_contact_img"
src="/web/static/src/img/user_menu_avatar.png"
alt="Contact"
/>
</div>
<div class="col pl-sm-0">
<address
t-field="rma.partner_shipping_id"
t-options='{"widget": "contact", "fields": ["name", "email", "phone", "address"]}'
/>
</div>
</div>
</div>
<!-- RMA Info -->
<div t-if="rma.user_id" class="col-12 col-md-6">
<h6>
<strong>Responsible:</strong>

View File

@@ -98,6 +98,7 @@
<field name="product_uom" groups="uom.group_uom" />
<field name="date" />
<field name="deadline" />
<field name="finalization_id" optional="hide" />
<field name="state" />
</tree>
</field>
@@ -281,6 +282,10 @@
/>
<field name="origin" />
<field name="operation_id" />
<field
name="finalization_id"
attrs="{'invisible': [('state', '!=', 'finished')]}"
/>
<field
name="company_id"
options="{'no_create': True}"
@@ -321,6 +326,7 @@
<field name="can_be_replaced" invisible="1" />
<field name="can_be_split" invisible="1" />
<field name="can_be_locked" invisible="1" />
<field name="can_be_finished" invisible="1" />
<field name="commercial_partner_id" invisible="1" />
<field name="remaining_qty" invisible="1" />
</sheet>
@@ -332,6 +338,28 @@
</form>
</field>
</record>
<record id="rma_finalization_form" model="ir.ui.view">
<field name="model">rma</field>
<field name="inherit_id" ref="rma.rma_view_form" />
<field
name="groups_id"
eval="[(4, ref('rma.group_rma_manual_finalization'))]"
/>
<field name="arch" type="xml">
<xpath
expr="//form//header//button[@name='action_cancel']"
position="before"
>
<button
type="object"
string="Finish"
name="action_finish"
class="btn-primary"
attrs="{'invisible': [('can_be_finished', '=', False)]}"
/>
</xpath>
</field>
</record>
<record id="rma_view_pivot" model="ir.ui.view">
<field name="name">rma.pivot</field>
<field name="model">rma</field>

View File

@@ -1,5 +1,6 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import rma_delivery
from . import rma_finalization_wizard
from . import rma_split
from . import stock_picking_return

View File

@@ -0,0 +1,18 @@
# Copyright 2022 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class RmaFinalizationWizard(models.TransientModel):
_name = "rma.finalization.wizard"
_description = "RMA Finalization Wizard"
finalization_id = fields.Many2one(
comodel_name="rma.finalization", string="Reason", required=True
)
def action_finish(self):
self.ensure_one()
rma_ids = self.env.context.get("active_ids")
rma = self.env["rma"].browse(rma_ids)
rma.write({"finalization_id": self.finalization_id, "state": "finished"})

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2022 Tecnativa - David Vidal
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="rma_finalization_wizard_view_form" model="ir.ui.view">
<field name="model">rma.finalization.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<group>
<field name="finalization_id" />
</group>
</group>
<footer>
<button
name="action_finish"
string="Finish RMA"
type="object"
class="btn-primary"
/>
<button string="Cancel" class="btn-secondary" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="rma_finalization_wizard_action" model="ir.actions.act_window">
<field name="name">Finish RMA Manualy</field>
<field name="res_model">rma.finalization.wizard</field>
<field name="view_mode">form</field>
<field name="binding_model_id" ref="rma.model_rma" />
<field name="binding_view_types">list</field>
<field name="target">new</field>
</record>
</odoo>