Initial commit: OCA Technical packages (595 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:03 +02:00
commit 2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions

View file

@ -0,0 +1,15 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import account_move
from . import rma
from . import rma_finalization
from . import rma_operation
from . import rma_tag
from . import rma_team
from . import res_company
from . import res_config_settings
from . import res_partner
from . import res_users
from . import stock_move
from . import stock_picking
from . import stock_warehouse

View file

@ -0,0 +1,55 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import float_compare
class AccountMove(models.Model):
_inherit = "account.move"
def _check_rma_invoice_lines_qty(self):
"""We can't refund a different qty than the stated in the RMA.
Extend to change criteria"""
precision = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)
return (
self.sudo()
.mapped("invoice_line_ids")
.filtered(
lambda r: (
r.rma_id
and float_compare(r.quantity, r.rma_id.product_uom_qty, precision)
< 0
)
)
)
def action_post(self):
"""Avoids to validate a refund with less quantity of product than
quantity in the linked RMA.
"""
if self._check_rma_invoice_lines_qty():
raise ValidationError(
_(
"There is at least one invoice lines whose quantity is "
"less than the quantity specified in its linked RMA."
)
)
return super().action_post()
def unlink(self):
rma = self.mapped("invoice_line_ids.rma_id")
rma.write({"state": "received"})
return super().unlink()
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
rma_id = fields.Many2one(
comodel_name="rma",
string="RMA",
)

View file

@ -0,0 +1,89 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# Copyright 2023 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
class ResCompany(models.Model):
_inherit = "res.company"
def _default_rma_mail_confirmation_template(self):
try:
return self.env.ref("rma.mail_template_rma_notification").id
except ValueError:
return False
def _default_rma_mail_receipt_template(self):
try:
return self.env.ref("rma.mail_template_rma_receipt_notification").id
except ValueError:
return False
def _default_rma_mail_draft_template(self):
try:
return self.env.ref("rma.mail_template_rma_draft_notification").id
except ValueError:
return False
rma_return_grouping = fields.Boolean(
string="Group RMA returns by customer address and warehouse",
default=True,
)
send_rma_confirmation = fields.Boolean(
string="Send RMA Confirmation",
help="When the delivery is confirmed, send a confirmation email "
"to the customer.",
)
send_rma_receipt_confirmation = fields.Boolean(
string="Send RMA Receipt Confirmation",
help="When the RMA receipt is confirmed, send a confirmation email "
"to the customer.",
)
send_rma_draft_confirmation = fields.Boolean(
string="Send RMA draft Confirmation",
help="When a customer places an RMA, send a notification with it",
)
rma_mail_confirmation_template_id = fields.Many2one(
comodel_name="mail.template",
string="Email Template confirmation for RMA",
domain="[('model', '=', 'rma')]",
default=_default_rma_mail_confirmation_template,
help="Email sent to the customer once the RMA is confirmed.",
)
rma_mail_receipt_confirmation_template_id = fields.Many2one(
comodel_name="mail.template",
string="Email Template receipt confirmation for RMA",
domain="[('model', '=', 'rma')]",
default=_default_rma_mail_receipt_template,
help="Email sent to the customer once the RMA products are received.",
)
rma_mail_draft_confirmation_template_id = fields.Many2one(
comodel_name="mail.template",
string="Email Template draft notification for RMA",
domain="[('model', '=', 'rma')]",
default=_default_rma_mail_draft_template,
help="Email sent to the customer when they place " "an RMA from the portal",
)
@api.model_create_multi
def create(self, vals_list):
companies = super().create(vals_list)
for company in companies:
company.create_rma_index()
return companies
def create_rma_index(self):
return (
self.env["ir.sequence"]
.sudo()
.create(
{
"name": _("RMA Code"),
"prefix": "RMA",
"code": "rma",
"padding": 4,
"company_id": self.id,
}
)
)

View file

@ -0,0 +1,41 @@
# Copyright 2021 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
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",
)
rma_return_grouping = fields.Boolean(
related="company_id.rma_return_grouping",
readonly=False,
)
send_rma_confirmation = fields.Boolean(
related="company_id.send_rma_confirmation",
readonly=False,
)
rma_mail_confirmation_template_id = fields.Many2one(
related="company_id.rma_mail_confirmation_template_id",
readonly=False,
)
send_rma_receipt_confirmation = fields.Boolean(
related="company_id.send_rma_receipt_confirmation",
readonly=False,
)
rma_mail_receipt_confirmation_template_id = fields.Many2one(
related="company_id.rma_mail_receipt_confirmation_template_id",
readonly=False,
)
send_rma_draft_confirmation = fields.Boolean(
related="company_id.send_rma_draft_confirmation",
readonly=False,
)
rma_mail_draft_confirmation_template_id = fields.Many2one(
related="company_id.rma_mail_draft_confirmation_template_id",
readonly=False,
)

View file

@ -0,0 +1,41 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ResPartner(models.Model):
_inherit = "res.partner"
rma_ids = fields.One2many(
comodel_name="rma",
inverse_name="partner_id",
string="RMAs",
)
rma_count = fields.Integer(
string="RMA count",
compute="_compute_rma_count",
)
def _compute_rma_count(self):
rma_data = self.env["rma"].read_group(
[("partner_id", "in", self.ids)], ["partner_id"], ["partner_id"]
)
mapped_data = {r["partner_id"][0]: r["partner_id_count"] for r in rma_data}
for record in self:
record.rma_count = mapped_data.get(record.id, 0)
def action_view_rma(self):
self.ensure_one()
action = self.sudo().env.ref("rma.rma_action").read()[0]
rma = self.rma_ids
if len(rma) == 1:
action.update(
res_id=rma.id,
view_mode="form",
view_id=False,
views=False,
)
else:
action["domain"] = [("partner_id", "in", self.ids)]
return action

View file

@ -0,0 +1,14 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ResUsers(models.Model):
_inherit = "res.users"
rma_team_id = fields.Many2one(
comodel_name="rma.team",
string="RMA Team",
help="RMA Team the user is member of.",
)

File diff suppressed because it is too large Load diff

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

@ -0,0 +1,163 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from ast import literal_eval
from collections import defaultdict
from odoo import _, api, fields, models
from odoo.osv.expression import AND
PROCESSED_STATES = ["received", "refunded", "replaced", "finished"]
AWAITING_ACTION_STATES = ["waiting_return", "waiting_replacement", "confirmed"]
class RmaOperation(models.Model):
_name = "rma.operation"
_description = "RMA requested operation"
active = fields.Boolean(default=True)
name = fields.Char(required=True, translate=True)
color = fields.Integer()
count_rma_draft = fields.Integer(compute="_compute_count_rma")
count_rma_awaiting_action = fields.Integer(compute="_compute_count_rma")
count_rma_processed = fields.Integer(compute="_compute_count_rma")
action_create_receipt = fields.Selection(
[
("manual_on_confirm", "Manually on Confirm"),
("automatic_on_confirm", "Automatically on Confirm"),
],
string="Create Receipt",
default="automatic_on_confirm",
help="Define how the receipt action should be handled.",
)
different_return_product = fields.Boolean(
help="If checked, allows the return of a product different from the one "
"originally ordered. Used if the delivery is created automatically",
)
auto_confirm_reception = fields.Boolean(
help="Enable this option to automatically confirm the reception when the RMA is"
" confirmed."
)
action_create_delivery = fields.Selection(
[
("manual_on_confirm", "Manually on Confirm"),
("automatic_on_confirm", "Automatically on Confirm"),
("manual_after_receipt", "Manually After Receipt"),
("automatic_after_receipt", "Automatically After Receipt"),
],
string="Delivery Action",
help="Define how the delivery action should be handled.",
default="manual_after_receipt",
)
action_create_refund = fields.Selection(
[
("manual_on_confirm", "Manually on Confirm"),
("automatic_on_confirm", "Automatically on Confirm"),
("manual_after_receipt", "Manually After Receipt"),
("automatic_after_receipt", "Automatically After Receipt"),
("update_quantity", "Update Quantities"),
],
string="Refund Action",
default="manual_after_receipt",
help="Define how the refund action should be handled.",
)
_sql_constraints = [
("name_uniq", "unique (name)", "That operation name already exists !"),
]
@api.model
def _get_rma_draft_domain(self):
return [("state", "=", "draft")]
@api.model
def _get_rma_awaiting_action_domain(self):
return [("state", "in", AWAITING_ACTION_STATES)]
@api.model
def _get_rma_processed_domain(self):
return [("state", "in", PROCESSED_STATES)]
def _compute_count_rma(self):
self.update(
{
"count_rma_draft": 0,
"count_rma_processed": 0,
"count_rma_awaiting_action": 0,
}
)
state_by_op = defaultdict(int)
for group in self.env["rma"].read_group(
AND([[("operation_id", "!=", False)]]),
groupby=["operation_id", "state"],
fields=["id"],
lazy=False,
):
operation_id = group.get("operation_id")[0]
state = group.get("state")
count = group.get("__count")
if state == "draft":
state_by_op[(operation_id, "count_rma_draft")] += count
if state in PROCESSED_STATES:
state_by_op[(operation_id, "count_rma_processed")] += count
if state in AWAITING_ACTION_STATES:
state_by_op[(operation_id, "count_rma_awaiting_action")] += count
for (operation_id, field), count in state_by_op.items():
self.browse(operation_id).update({field: count})
def _get_action(self, name, domain):
action = self.env["ir.actions.actions"]._for_xml_id("rma.rma_action")
action["display_name"] = name
context = {
"search_default_operation_id": [self.id],
"default_operation_id": self.id,
}
action_context = literal_eval(action["context"])
context = {**action_context, **context}
action["context"] = context
action["domain"] = domain
return action
def get_action_rma_tree_draft(self):
self.ensure_one()
name = self.display_name + ": " + _("Draft")
return self._get_action(
name,
domain=AND(
[
[("operation_id", "=", self.id)],
self._get_rma_draft_domain(),
]
),
)
def get_action_rma_tree_awaiting_action(self):
self.ensure_one()
name = self.display_name + ": " + _("Awaiting Action")
return self._get_action(
name,
domain=AND(
[
[("operation_id", "=", self.id)],
self._get_rma_awaiting_action_domain(),
]
),
)
def get_action_rma_tree_processed(self):
self.ensure_one()
name = self.display_name + ": " + _("Processed")
return self._get_action(
name,
domain=AND(
[
[("operation_id", "=", self.id)],
self._get_rma_processed_domain(),
]
),
)
def get_action_all_rma(self):
self.ensure_one()
name = self.display_name
return self._get_action(name, domain=[("operation_id", "=", self.id)])

View file

@ -0,0 +1,30 @@
# Copyright 2021 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class RmaTag(models.Model):
_description = "RMA Tags"
_name = "rma.tag"
_order = "name"
active = fields.Boolean(
default=True,
help="The active field allows you to hide the category without " "removing it.",
)
name = fields.Char(
string="Tag Name",
required=True,
translate=True,
copy=False,
)
is_public = fields.Boolean(
string="Public Tag",
help="The tag is visible in the portal view",
)
color = fields.Integer(string="Color Index")
rma_ids = fields.Many2many(comodel_name="rma")
_sql_constraints = [
("name_uniq", "unique (name)", "Tag name already exists !"),
]

View file

@ -0,0 +1,64 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import ast
from odoo import _, fields, models
class RmaTeam(models.Model):
_name = "rma.team"
_inherit = ["mail.alias.mixin", "mail.thread"]
_description = "RMA Team"
_order = "sequence, name"
sequence = fields.Integer()
name = fields.Char(
required=True,
translate=True,
)
active = fields.Boolean(
default=True,
help="If the active field is set to false, it will allow you "
"to hide the RMA Team without removing it.",
)
company_id = fields.Many2one(
comodel_name="res.company",
string="Company",
default=lambda self: self.env.company,
)
user_id = fields.Many2one(
comodel_name="res.users",
string="Team Leader",
domain=[("share", "=", False)],
default=lambda self: self.env.user,
)
member_ids = fields.One2many(
comodel_name="res.users",
inverse_name="rma_team_id",
string="Team Members",
)
def copy(self, default=None):
self.ensure_one()
if default is None:
default = {}
if not default.get("name"):
default["name"] = _("%s (copy)") % self.name
team = super().copy(default)
for follower in self.message_follower_ids:
team.message_subscribe(
partner_ids=follower.partner_id.ids,
subtype_ids=follower.subtype_ids.ids,
)
return team
def _alias_get_creation_values(self):
values = super()._alias_get_creation_values()
values["alias_model_id"] = self.env.ref("rma.model_rma").id
if self.id:
values["alias_defaults"] = defaults = ast.literal_eval(
self.alias_defaults or "{}"
)
defaults["team_id"] = self.id
return values

View file

@ -0,0 +1,138 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import float_compare
class StockMove(models.Model):
_inherit = "stock.move"
# RMAs that were created from the delivery move
rma_ids = fields.One2many(
comodel_name="rma",
inverse_name="move_id",
string="RMAs",
copy=False,
)
# RMAs linked to the incoming movement from client
rma_receiver_ids = fields.One2many(
comodel_name="rma",
inverse_name="reception_move_id",
string="RMA receivers",
copy=False,
)
# RMA that creates the out move
rma_id = fields.Many2one(
comodel_name="rma", string="RMA return", copy=False, index=True
)
def unlink(self):
# A stock user could have no RMA permissions, so the ids wouldn't
# be accessible due to record rules.
rma_receiver = self.sudo().rma_receiver_ids
rma = self.sudo().rma_id
res = super().unlink()
rma_receiver.filtered(lambda x: x.state != "cancelled").write(
{"state": "draft"}
)
rma.update_received_state()
rma.update_replaced_state()
return res
def _action_cancel(self):
res = super()._action_cancel()
# A stock user could have no RMA permissions, so the ids wouldn't
# be accessible due to record rules.
cancelled_moves = self.filtered(lambda r: r.state == "cancel").sudo()
cancelled_moves.mapped("rma_receiver_ids").write({"state": "draft"})
cancelled_moves.mapped("rma_id").update_received_state()
cancelled_moves.mapped("rma_id").update_replaced_state()
return res
def _action_done(self, cancel_backorder=False):
"""Avoids to validate stock.move with less quantity than the
quantity in the linked receiver RMA. It also set the appropriated
linked RMA to 'received' or 'delivered'.
"""
for move in self.filtered(lambda r: r.state not in ("done", "cancel")):
rma_receiver = move.sudo().rma_receiver_ids
qty_prec = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)
if (
rma_receiver
and float_compare(
move.quantity_done,
rma_receiver.product_uom_qty,
precision_digits=qty_prec,
)
!= 0
):
raise ValidationError(
_(
"The quantity done for the product '%(id)s' must "
"be equal to its initial demand because the "
"stock move is linked to an RMA (%(name)s)."
)
% (
{
"id": move.product_id.name,
"name": move.rma_receiver_ids.name,
}
)
)
res = super()._action_done(cancel_backorder=cancel_backorder)
move_done = self.filtered(lambda r: r.state == "done").sudo()
# Set RMAs as received. We sudo so we can grant the operation even
# if the stock user has no RMA permissions.
to_be_received = (
move_done.sudo()
.mapped("rma_receiver_ids")
.filtered(lambda r: r.state == "confirmed")
)
to_be_received.update_received_state_on_reception()
# Set RMAs as delivered
move_done.mapped("rma_id").update_replaced_state()
move_done.mapped("rma_id").update_returned_state()
return res
@api.model
def _prepare_merge_moves_distinct_fields(self):
"""The main use is that launched delivery RMAs doesn't merge
two moves if they are linked to a different RMAs.
"""
return super()._prepare_merge_moves_distinct_fields() + [
"rma_id",
"rma_receiver_ids",
]
def _prepare_move_split_vals(self, qty):
"""Intended to the backport of picking linked to RMAs propagates the
RMA link id.
"""
res = super()._prepare_move_split_vals(qty)
res["rma_id"] = self.sudo().rma_id.id
return res
def _prepare_procurement_values(self):
res = super()._prepare_procurement_values()
if self.rma_id:
res["rma_id"] = self.rma_id.id
return res
class StockRule(models.Model):
_inherit = "stock.rule"
def _get_custom_move_fields(self):
move_fields = super()._get_custom_move_fields()
move_fields += [
"rma_id",
"origin_returned_move_id",
"move_orig_ids",
"rma_receiver_ids",
]
return move_fields

View file

@ -0,0 +1,44 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class StockPicking(models.Model):
_inherit = "stock.picking"
rma_count = fields.Integer(
string="RMA count",
compute="_compute_rma_count",
)
def _compute_rma_count(self):
for rec in self:
rec.rma_count = len(rec.move_ids.mapped("rma_ids"))
def copy(self, default=None):
self.ensure_one()
if self.env.context.get("set_rma_picking_type"):
location_dest_id = default.get("location_dest_id")
if location_dest_id:
warehouse = self.env["stock.warehouse"].search(
[("rma_loc_id", "parent_of", location_dest_id)], limit=1
)
if warehouse:
default["picking_type_id"] = warehouse.rma_in_type_id.id
return super().copy(default)
def action_view_rma(self):
self.ensure_one()
action = self.env["ir.actions.act_window"]._for_xml_id("rma.rma_action")
rma = self.move_ids.rma_ids
if len(rma) == 1:
action.update(
res_id=rma.id,
view_mode="form",
view_id=False,
views=False,
)
else:
action["domain"] = [("id", "in", rma.ids)]
return action

View file

@ -0,0 +1,216 @@
# Copyright 2020 Tecnativa - Ernesto Tejeda
# Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, fields, models
class StockWarehouse(models.Model):
_inherit = "stock.warehouse"
# This is a strategic field used to create an rma location
# and rma operation types in existing warehouses when
# installing this module.
rma = fields.Boolean(
"RMA",
default=True,
help="RMA related products can be stored in this warehouse.",
)
rma_in_type_id = fields.Many2one(
comodel_name="stock.picking.type",
string="RMA In Type",
)
rma_out_type_id = fields.Many2one(
comodel_name="stock.picking.type",
string="RMA Out Type",
)
rma_loc_id = fields.Many2one(
comodel_name="stock.location",
string="RMA Location",
)
rma_in_route_id = fields.Many2one("stock.route", "RMA in Route")
rma_out_route_id = fields.Many2one("stock.route", "RMA out Route")
rma_out_replace_route_id = fields.Many2one("stock.route", "RMA out Replace Route")
def _get_rma_location_values(self, vals, code=False):
"""this method is intended to be used by 'create' method
to create a new RMA location to be linked to a new warehouse.
"""
company_id = vals.get(
"company_id", self.default_get(["company_id"])["company_id"]
)
code = vals.get("code") or code or ""
code = code.replace(" ", "").upper()
view_location_id = vals.get("view_location_id")
view_location = (
view_location_id
and self.view_location_id.browse(view_location_id)
or self.view_location_id
)
return {
"name": view_location.name,
"active": True,
"return_location": True,
"usage": "internal",
"company_id": company_id,
"location_id": self.env.ref("rma.stock_location_rma").id,
"barcode": self._valid_barcode(code + "-RMA", company_id),
}
def _get_locations_values(self, vals, code=False):
res = super()._get_locations_values(vals, code)
res["rma_loc_id"] = self._get_rma_location_values(vals, code)
return res
def _get_sequence_values(self, name=False, code=False):
values = super()._get_sequence_values(name=name, code=code)
values.update(
{
"rma_in_type_id": {
"name": self.name + " " + _("Sequence RMA in"),
"prefix": self.code + "/RMA/IN/",
"padding": 5,
"company_id": self.company_id.id,
},
"rma_out_type_id": {
"name": self.name + " " + _("Sequence RMA out"),
"prefix": self.code + "/RMA/OUT/",
"padding": 5,
"company_id": self.company_id.id,
},
}
)
return values
def _update_name_and_code(self, new_name=False, new_code=False):
res = super()._update_name_and_code(new_name, new_code)
for warehouse in self:
sequence_data = warehouse._get_sequence_values()
warehouse.rma_in_type_id.sequence_id.write(sequence_data["rma_in_type_id"])
warehouse.rma_out_type_id.sequence_id.write(
sequence_data["rma_out_type_id"]
)
return res
def _get_picking_type_create_values(self, max_sequence):
data, next_sequence = super()._get_picking_type_create_values(max_sequence)
data.update(
{
"rma_in_type_id": {
"name": _("RMA Receipts"),
"code": "incoming",
"use_create_lots": False,
"use_existing_lots": True,
"default_location_src_id": False,
"default_location_dest_id": self.rma_loc_id.id,
"sequence": max_sequence + 1,
"sequence_code": "RMA/IN",
"company_id": self.company_id.id,
},
"rma_out_type_id": {
"name": _("RMA Delivery Orders"),
"code": "outgoing",
"use_create_lots": False,
"use_existing_lots": True,
"default_location_src_id": self.rma_loc_id.id,
"default_location_dest_id": False,
"sequence": max_sequence + 2,
"sequence_code": "RMA/OUT",
"company_id": self.company_id.id,
},
}
)
return data, max_sequence + 3
def _get_picking_type_update_values(self):
data = super()._get_picking_type_update_values()
picking_types = {
"rma_in_type_id": {"default_location_dest_id": self.rma_loc_id.id},
"rma_out_type_id": {"default_location_src_id": self.rma_loc_id.id},
}
if self.env.context.get("rma_post_init_hook"):
return picking_types
data.update(picking_types)
return data
def _create_or_update_sequences_and_picking_types(self):
data = super()._create_or_update_sequences_and_picking_types()
stock_picking_type = self.env["stock.picking.type"]
if "out_type_id" in data:
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)}
)
if "rma_in_type_id" in data:
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)}
)
return data
def _get_routes_values(self):
res = super()._get_routes_values()
rma_routes = {
"rma_in_route_id": {
"routing_key": "rma_in",
"depends": ["active"],
"route_update_values": {
"name": self._format_routename("RMA In"),
"active": self.active,
},
"route_create_values": {
"warehouse_selectable": True,
"company_id": self.company_id.id,
"sequence": 100,
},
"rules_values": {
"active": True,
},
},
"rma_out_route_id": {
"routing_key": "rma_out",
"depends": ["active"],
"route_update_values": {
"name": self._format_routename("RMA Out"),
"active": self.active,
},
"route_create_values": {
"warehouse_selectable": True,
"company_id": self.company_id.id,
"sequence": 110,
},
"rules_values": {
"active": True,
},
},
}
if self.env.context.get("rma_post_init_hook"):
return rma_routes
res.update(rma_routes)
return res
def get_rules_dict(self):
res = super().get_rules_dict()
customer_loc, supplier_loc = self._get_partner_locations()
for warehouse in self:
res[warehouse.id].update(
{
"rma_in": [
self.Routing(
customer_loc,
warehouse.rma_loc_id,
warehouse.rma_in_type_id,
"pull",
)
],
"rma_out": [
self.Routing(
warehouse.rma_loc_id,
customer_loc,
warehouse.rma_out_type_id,
"pull",
)
],
}
)
return res