From 1a74483e9f058b70f2f9bc6b87793eeb4fbbaf34 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Sat, 25 Sep 2021 06:24:58 +0200 Subject: [PATCH 01/11] [repair_purchase_return][new] --- repair_purchase_return/README.rst | 92 ++++ repair_purchase_return/__init__.py | 2 + repair_purchase_return/__manifest__.py | 21 + repair_purchase_return/models/__init__.py | 4 + .../models/purchase_return_order_line.py | 11 + repair_purchase_return/models/repair_fee.py | 44 ++ repair_purchase_return/models/repair_line.py | 44 ++ repair_purchase_return/models/repair_order.py | 103 ++++ .../readme/CONTRIBUTORS.rst | 2 + repair_purchase_return/readme/DESCRIPTION.rst | 9 + repair_purchase_return/readme/USAGE.rst | 1 + .../security/ir.model.access.csv | 2 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 438 ++++++++++++++++++ .../views/repair_order_views.xml | 36 ++ repair_purchase_return/wizards/__init__.py | 1 + .../wizards/repair_purchase_return_wiz.py | 41 ++ .../repair_purchase_return_wiz_views.xml | 50 ++ 18 files changed, 901 insertions(+) create mode 100644 repair_purchase_return/README.rst create mode 100644 repair_purchase_return/__init__.py create mode 100644 repair_purchase_return/__manifest__.py create mode 100644 repair_purchase_return/models/__init__.py create mode 100644 repair_purchase_return/models/purchase_return_order_line.py create mode 100644 repair_purchase_return/models/repair_fee.py create mode 100644 repair_purchase_return/models/repair_line.py create mode 100644 repair_purchase_return/models/repair_order.py create mode 100644 repair_purchase_return/readme/CONTRIBUTORS.rst create mode 100644 repair_purchase_return/readme/DESCRIPTION.rst create mode 100644 repair_purchase_return/readme/USAGE.rst create mode 100644 repair_purchase_return/security/ir.model.access.csv create mode 100644 repair_purchase_return/static/description/icon.png create mode 100644 repair_purchase_return/static/description/index.html create mode 100644 repair_purchase_return/views/repair_order_views.xml create mode 100644 repair_purchase_return/wizards/__init__.py create mode 100644 repair_purchase_return/wizards/repair_purchase_return_wiz.py create mode 100644 repair_purchase_return/wizards/repair_purchase_return_wiz_views.xml diff --git a/repair_purchase_return/README.rst b/repair_purchase_return/README.rst new file mode 100644 index 00000000..cc49782f --- /dev/null +++ b/repair_purchase_return/README.rst @@ -0,0 +1,92 @@ +================= +Repair Stock Move +================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github + :target: https://github.com/OCA/manufacture/tree/14.0/repair_stock_move + :alt: OCA/manufacture +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/manufacture-14-0/manufacture-14-0-repair_stock_move + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/129/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +The purpose of this module is to modify the behaviour of the repair standard module. Achieving more flexibility in a repair process. + +The first change that it applies is the modification of the creation of stock moves in the repair flow: + +* Confirm Repair: creates draft stock moves on confirmation of the repair order. +* Start Repair: confirms the stock moves. +* End Repair: completes the stock moves and ends the repair order. + +Another feature which this module includes is that it allows to add components during all the different stages of the repair process, which adjusts better to the needs of some businesses. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Follow the Odoo standard repair module flow. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* ForgeFlow + +Contributors +~~~~~~~~~~~~ + +* Mateu Griful +* Lois Rilo + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/manufacture `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/repair_purchase_return/__init__.py b/repair_purchase_return/__init__.py new file mode 100644 index 00000000..aee8895e --- /dev/null +++ b/repair_purchase_return/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards diff --git a/repair_purchase_return/__manifest__.py b/repair_purchase_return/__manifest__.py new file mode 100644 index 00000000..9f4ed231 --- /dev/null +++ b/repair_purchase_return/__manifest__.py @@ -0,0 +1,21 @@ +# Copyright (C) 2021 ForgeFlow S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +{ + "name": "Repair Purchase Return", + "version": "14.0.1.0.0", + "development_status": "Alpha", + "license": "LGPL-3", + "category": "Repair", + "summary": "Create a Purchase Return from a Repair", + "author": "ForgeFlow, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/manufacture", + "depends": ["repair", "purchase_return"], + "data": [ + "security/ir.model.access.csv", + "wizards/repair_purchase_return_wiz_views.xml", + "views/repair_order_views.xml", + ], + "installable": True, + "application": False, +} diff --git a/repair_purchase_return/models/__init__.py b/repair_purchase_return/models/__init__.py new file mode 100644 index 00000000..8c6863bb --- /dev/null +++ b/repair_purchase_return/models/__init__.py @@ -0,0 +1,4 @@ +from . import repair_order +from . import repair_line +from . import repair_fee +from . import purchase_return_order_line diff --git a/repair_purchase_return/models/purchase_return_order_line.py b/repair_purchase_return/models/purchase_return_order_line.py new file mode 100644 index 00000000..5ec94a98 --- /dev/null +++ b/repair_purchase_return/models/purchase_return_order_line.py @@ -0,0 +1,11 @@ +# Copyright (C) 2021 ForgeFlow S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from odoo import fields, models + + +class PurchaseReturnOrderLine(models.Model): + _inherit = "purchase.return.order.line" + + repair_line_ids = fields.Many2many(comodel_name="repair.line") + repair_fee_ids = fields.Many2many(comodel_name="repair.fee") diff --git a/repair_purchase_return/models/repair_fee.py b/repair_purchase_return/models/repair_fee.py new file mode 100644 index 00000000..3c047e85 --- /dev/null +++ b/repair_purchase_return/models/repair_fee.py @@ -0,0 +1,44 @@ +# Copyright (C) 2021 ForgeFlow S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from odoo import api, fields, models + + +class RepairFee(models.Model): + _inherit = "repair.fee" + + purchase_return_line_ids = fields.Many2many( + comodel_name="purchase.return.order.line" + ) + + @api.model + def _get_purchase_return_line_onchange_product_fields(self): + return ["price_unit", "taxes_id", "refund_only"] + + @api.model + def _execute_purchase_return_line_onchange(self, vals): + cls = self.env["purchase.return.order.line"] + onchanges_dict = { + "onchange_product_id": self._get_purchase_return_line_onchange_product_fields() + } + for onchange_method, changed_fields in onchanges_dict.items(): + if any(f not in vals for f in changed_fields): + obj = cls.new(vals) + getattr(obj, onchange_method)() + for field in changed_fields: + vals[field] = obj._fields[field].convert_to_write(obj[field], obj) + + @api.model + def _prepare_purchase_order_line_vals(self, pro): + vals = { + "name": self.name, + "order_id": pro.id, + "product_id": self.product_id.id, + "product_uom": self.product_uom.id, + "price_unit": 0.0, + "product_qty": self.product_uom_qty, + "repair_fee_ids": [(4, self.id)], + "date_planned": fields.Datetime.now(), + } + self._execute_purchase_return_line_onchange(vals) + return vals diff --git a/repair_purchase_return/models/repair_line.py b/repair_purchase_return/models/repair_line.py new file mode 100644 index 00000000..f3a4b59e --- /dev/null +++ b/repair_purchase_return/models/repair_line.py @@ -0,0 +1,44 @@ +# Copyright (C) 2021 ForgeFlow S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from odoo import api, fields, models + + +class RepairLine(models.Model): + _inherit = "repair.line" + + purchase_return_line_ids = fields.Many2many( + comodel_name="purchase.return.order.line" + ) + + @api.model + def _get_purchase_return_line_onchange_product_fields(self): + return ["price_unit", "taxes_id", "refund_only"] + + @api.model + def _execute_purchase_return_line_onchange(self, vals): + cls = self.env["purchase.return.order.line"] + onchanges_dict = { + "onchange_product_id": self._get_purchase_return_line_onchange_product_fields() + } + for onchange_method, changed_fields in onchanges_dict.items(): + if any(f not in vals for f in changed_fields): + obj = cls.new(vals) + getattr(obj, onchange_method)() + for field in changed_fields: + vals[field] = obj._fields[field].convert_to_write(obj[field], obj) + + @api.model + def _prepare_purchase_order_line_vals(self, pro): + vals = { + "name": self.name, + "order_id": pro.id, + "product_id": self.product_id.id, + "product_uom": self.product_uom.id, + "price_unit": 0.0, + "product_qty": self.product_uom_qty, + "repair_line_ids": [(4, self.id)], + "date_planned": fields.Datetime.now(), + } + self._execute_purchase_return_line_onchange(vals) + return vals diff --git a/repair_purchase_return/models/repair_order.py b/repair_purchase_return/models/repair_order.py new file mode 100644 index 00000000..a00709b3 --- /dev/null +++ b/repair_purchase_return/models/repair_order.py @@ -0,0 +1,103 @@ +# Copyright (C) 2021 ForgeFlow S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from odoo import api, fields, models + + +class RepairOrder(models.Model): + _inherit = "repair.order" + + purchase_return_ids = fields.Many2many( + comodel_name="purchase.return.order", + compute="_compute_purchase_returns", + copy=False, + store=True, + ) + purchase_return_count = fields.Integer( + compute="_compute_purchase_returns", + string="Purchase Return Count", + copy=False, + default=0, + store=True, + ) + + @api.depends( + "operations.purchase_return_line_ids.order_id", + "fees_lines.purchase_return_line_ids.order_id", + ) + def _compute_purchase_returns(self): + for order in self: + pros = order.mapped("operations.purchase_return_line_ids.order_id") + pros |= order.mapped("fees_lines.purchase_return_line_ids.order_id") + order.purchase_return_ids = pros + order.purchase_return_count = len(pros) + + def _prepare_purchase_return_values(self, vendor): + invoice_vals = { + "origin": self.name, + "partner_id": vendor.id, + "fiscal_position_id": vendor.property_account_position_id + and vendor.property_account_position_id.id + or False, + "company_id": self.company_id.id, + } + return invoice_vals + + @api.model + def _select_operations_to_return(self, operations): + return operations.filtered(lambda o: o.type == "add") + + @api.model + def _select_fees_to_return(self, fees): + return fees + + def _create_purchase_return(self, vendor): + pro_line_obj = self.env["purchase.return.order.line"] + pr_vals = self._prepare_purchase_return_values(vendor) + pro = ( + self.env["purchase.return.order"] + .sudo() + .create(pr_vals) + .with_user(self.env.uid) + ) + for operation in self._select_operations_to_return(self.operations): + pr_line_vals = operation._prepare_purchase_order_line_vals(pro) + pro_line_obj.create(pr_line_vals) + for fee in self._select_fees_to_return(self.fees_lines): + pr_line_vals = fee._prepare_purchase_order_line_vals(pro) + pro_line_obj.create(pr_line_vals) + return pro + + def action_view_purchase_returns(self): + purchase_returns = self.mapped("purchase_return_ids") + action = self.env["ir.actions.actions"]._for_xml_id( + "purchase_return.purchase_return_form_action" + ) + if len(purchase_returns) > 1: + action["domain"] = [("id", "in", purchase_returns.ids)] + elif len(purchase_returns) == 1: + form_view = [ + (self.env.ref("purchase_return.purchase_return_order_form").id, "form") + ] + if "views" in action: + action["views"] = form_view + [ + (state, view) for state, view in action["views"] if view != "form" + ] + else: + action["views"] = form_view + action["res_id"] = purchase_returns.id + else: + action = {"type": "ir.actions.act_window_close"} + + context = { + "default_move_type": "out_invoice", + } + if len(self) == 1: + context.update( + { + "default_partner_id": self.partner_id.id, + "default_user_id": self.user_id.id, + } + ) + action["context"] = context + return action diff --git a/repair_purchase_return/readme/CONTRIBUTORS.rst b/repair_purchase_return/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..087dd292 --- /dev/null +++ b/repair_purchase_return/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Mateu Griful +* Lois Rilo diff --git a/repair_purchase_return/readme/DESCRIPTION.rst b/repair_purchase_return/readme/DESCRIPTION.rst new file mode 100644 index 00000000..f46cb240 --- /dev/null +++ b/repair_purchase_return/readme/DESCRIPTION.rst @@ -0,0 +1,9 @@ +The purpose of this module is to modify the behaviour of the repair standard module. Achieving more flexibility in a repair process. + +The first change that it applies is the modification of the creation of stock moves in the repair flow: + +* Confirm Repair: creates draft stock moves on confirmation of the repair order. +* Start Repair: confirms the stock moves. +* End Repair: completes the stock moves and ends the repair order. + +Another feature which this module includes is that it allows to add components during all the different stages of the repair process, which adjusts better to the needs of some businesses. diff --git a/repair_purchase_return/readme/USAGE.rst b/repair_purchase_return/readme/USAGE.rst new file mode 100644 index 00000000..3009b22a --- /dev/null +++ b/repair_purchase_return/readme/USAGE.rst @@ -0,0 +1 @@ +Follow the Odoo standard repair module flow. diff --git a/repair_purchase_return/security/ir.model.access.csv b/repair_purchase_return/security/ir.model.access.csv new file mode 100644 index 00000000..1bcd7179 --- /dev/null +++ b/repair_purchase_return/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_repair_purchase_return_wiz,repair.purchase.return.wiz,model_repair_purchase_return_wiz,purchase.group_purchase_user,1,1,1,1 diff --git a/repair_purchase_return/static/description/icon.png b/repair_purchase_return/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/repair_purchase_return/static/description/index.html b/repair_purchase_return/static/description/index.html new file mode 100644 index 00000000..93c5dc60 --- /dev/null +++ b/repair_purchase_return/static/description/index.html @@ -0,0 +1,438 @@ + + + + + + +Repair Stock Move + + + +
+

Repair Stock Move

+ + +

Alpha License: LGPL-3 OCA/manufacture Translate me on Weblate Try me on Runbot

+

The purpose of this module is to modify the behaviour of the repair standard module. Achieving more flexibility in a repair process.

+

The first change that it applies is the modification of the creation of stock moves in the repair flow:

+
    +
  • Confirm Repair: creates draft stock moves on confirmation of the repair order.
  • +
  • Start Repair: confirms the stock moves.
  • +
  • End Repair: completes the stock moves and ends the repair order.
  • +
+

Another feature which this module includes is that it allows to add components during all the different stages of the repair process, which adjusts better to the needs of some businesses.

+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+
+

Table of contents

+ +
+

Usage

+

Follow the Odoo standard repair module flow.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ForgeFlow
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/manufacture project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/repair_purchase_return/views/repair_order_views.xml b/repair_purchase_return/views/repair_order_views.xml new file mode 100644 index 00000000..0c2fbcdb --- /dev/null +++ b/repair_purchase_return/views/repair_order_views.xml @@ -0,0 +1,36 @@ + + + + + repair.order.form - repair_stock_move + repair.order + + +
+
+
+ +
+
+
+ +
diff --git a/repair_purchase_return/wizards/__init__.py b/repair_purchase_return/wizards/__init__.py new file mode 100644 index 00000000..73706688 --- /dev/null +++ b/repair_purchase_return/wizards/__init__.py @@ -0,0 +1 @@ +from . import repair_purchase_return_wiz diff --git a/repair_purchase_return/wizards/repair_purchase_return_wiz.py b/repair_purchase_return/wizards/repair_purchase_return_wiz.py new file mode 100644 index 00000000..1517c0fa --- /dev/null +++ b/repair_purchase_return/wizards/repair_purchase_return_wiz.py @@ -0,0 +1,41 @@ +# Copyright (C) 2021 ForgeFlow S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from odoo import api, fields, models + + +class RepairPurchaseReturnWiz(models.TransientModel): + _name = "repair.purchase.return.wiz" + _description = "RepairPurchaseReturnWizard" + + vendor_id = fields.Many2one("res.partner", required=True) + + @api.model + def default_get(self, fields): + vals = super(RepairPurchaseReturnWiz, self).default_get(fields) + repair_ids = self.env.context["active_ids"] or [] + active_model = self.env.context["active_model"] + + if not repair_ids: + return vals + assert active_model == "repair.order", "Bad context propagation" + + repairs = self.env["repair.order"].browse(repair_ids) + vendors = self.env["res.partner"] + for repair in repairs: + vendors |= ( + repair.product_id.mapped("seller_ids") + .filtered(lambda s: s.company_id == repair.company_id) + .name + ) + if len(vendors) == 1: + vals["vendor_id"] = vendors[0].id + return vals + + def create_purchase_returns(self): + repairs = self.env["repair.order"].browse(self._context.get("active_ids", [])) + for repair in repairs: + repair._create_purchase_return(self.vendor_id) + if self._context.get("open_purchase_returns", False): + return repairs.action_view_purchase_returns() + return {"type": "ir.actions.act_window_close"} diff --git a/repair_purchase_return/wizards/repair_purchase_return_wiz_views.xml b/repair_purchase_return/wizards/repair_purchase_return_wiz_views.xml new file mode 100644 index 00000000..f0108913 --- /dev/null +++ b/repair_purchase_return/wizards/repair_purchase_return_wiz_views.xml @@ -0,0 +1,50 @@ + + + + Create Purchase Returns + repair.purchase.return.wiz + +
+

+ Purchase Returns will be created in draft so that you + can review them before validation. +

+ + + +
+
+
+
+
+ + + Create Purchase Return Orders + ir.actions.act_window + repair.purchase.return.wiz + form + new + + list + + +
From 33feef353b649e02874b9f6c79205c56cb0e857c Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Wed, 27 Oct 2021 13:52:20 +0200 Subject: [PATCH 02/11] create purchase return lines using refund_only=True by default --- repair_purchase_return/__manifest__.py | 1 + repair_purchase_return/models/__init__.py | 1 + .../models/purchase_return_order.py | 48 +++++++++++++++++++ .../models/purchase_return_order_line.py | 4 +- repair_purchase_return/models/repair_fee.py | 3 +- repair_purchase_return/models/repair_line.py | 3 +- repair_purchase_return/models/repair_order.py | 2 + .../views/purchase_return_order_views.xml | 28 +++++++++++ 8 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 repair_purchase_return/models/purchase_return_order.py create mode 100644 repair_purchase_return/views/purchase_return_order_views.xml diff --git a/repair_purchase_return/__manifest__.py b/repair_purchase_return/__manifest__.py index 9f4ed231..afd66a71 100644 --- a/repair_purchase_return/__manifest__.py +++ b/repair_purchase_return/__manifest__.py @@ -15,6 +15,7 @@ "security/ir.model.access.csv", "wizards/repair_purchase_return_wiz_views.xml", "views/repair_order_views.xml", + "views/purchase_return_order_views.xml", ], "installable": True, "application": False, diff --git a/repair_purchase_return/models/__init__.py b/repair_purchase_return/models/__init__.py index 8c6863bb..03a614c8 100644 --- a/repair_purchase_return/models/__init__.py +++ b/repair_purchase_return/models/__init__.py @@ -2,3 +2,4 @@ from . import repair_line from . import repair_fee from . import purchase_return_order_line +from . import purchase_return_order diff --git a/repair_purchase_return/models/purchase_return_order.py b/repair_purchase_return/models/purchase_return_order.py new file mode 100644 index 00000000..1601fd68 --- /dev/null +++ b/repair_purchase_return/models/purchase_return_order.py @@ -0,0 +1,48 @@ +# Copyright (C) 2021 ForgeFlow S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) + +from odoo import fields, models + + +class PurchaseReturnOrder(models.Model): + _inherit = "purchase.return.order" + + repair_order_count = fields.Integer( + compute="_compute_repair_orders", + string="Repair Order Count", + copy=False, + default=0, + ) + repair_order_ids = fields.Many2many( + comodel_name="repair.order", + compute="_compute_repair_orders", + copy=False, + store=True, + ) + + def _compute_repair_orders(self): + for rec in self: + repair_orders = rec.order_line.mapped("repair_line_ids.repair_id") + repair_orders |= rec.order_line.mapped("repair_fee_ids.repair_id") + rec.repair_order_ids = repair_orders + rec.repair_order_count = len(repair_orders) + + def action_view_repair_orders(self): + repair_orders = self.mapped("repair_order_ids") + action = self.env["ir.actions.actions"]._for_xml_id( + "repair.action_repair_order_tree" + ) + if len(repair_orders) > 1: + action["domain"] = [("id", "in", repair_orders.ids)] + elif len(repair_orders) == 1: + form_view = [(self.env.ref("repair.view_repair_order_form").id, "form")] + if "views" in action: + action["views"] = form_view + [ + (state, view) for state, view in action["views"] if view != "form" + ] + else: + action["views"] = form_view + action["res_id"] = repair_orders.id + else: + action = {"type": "ir.actions.act_window_close"} + return action diff --git a/repair_purchase_return/models/purchase_return_order_line.py b/repair_purchase_return/models/purchase_return_order_line.py index 5ec94a98..04a16fc1 100644 --- a/repair_purchase_return/models/purchase_return_order_line.py +++ b/repair_purchase_return/models/purchase_return_order_line.py @@ -7,5 +7,5 @@ class PurchaseReturnOrderLine(models.Model): _inherit = "purchase.return.order.line" - repair_line_ids = fields.Many2many(comodel_name="repair.line") - repair_fee_ids = fields.Many2many(comodel_name="repair.fee") + repair_line_ids = fields.Many2many(comodel_name="repair.line", copy=False) + repair_fee_ids = fields.Many2many(comodel_name="repair.fee", copy=False) diff --git a/repair_purchase_return/models/repair_fee.py b/repair_purchase_return/models/repair_fee.py index 3c047e85..b18e19e8 100644 --- a/repair_purchase_return/models/repair_fee.py +++ b/repair_purchase_return/models/repair_fee.py @@ -8,7 +8,7 @@ class RepairFee(models.Model): _inherit = "repair.fee" purchase_return_line_ids = fields.Many2many( - comodel_name="purchase.return.order.line" + comodel_name="purchase.return.order.line", copy=False ) @api.model @@ -39,6 +39,7 @@ def _prepare_purchase_order_line_vals(self, pro): "product_qty": self.product_uom_qty, "repair_fee_ids": [(4, self.id)], "date_planned": fields.Datetime.now(), + "refund_only": True, } self._execute_purchase_return_line_onchange(vals) return vals diff --git a/repair_purchase_return/models/repair_line.py b/repair_purchase_return/models/repair_line.py index f3a4b59e..3acc0e71 100644 --- a/repair_purchase_return/models/repair_line.py +++ b/repair_purchase_return/models/repair_line.py @@ -8,7 +8,7 @@ class RepairLine(models.Model): _inherit = "repair.line" purchase_return_line_ids = fields.Many2many( - comodel_name="purchase.return.order.line" + comodel_name="purchase.return.order.line", copy=False ) @api.model @@ -39,6 +39,7 @@ def _prepare_purchase_order_line_vals(self, pro): "product_qty": self.product_uom_qty, "repair_line_ids": [(4, self.id)], "date_planned": fields.Datetime.now(), + "refund_only": True, } self._execute_purchase_return_line_onchange(vals) return vals diff --git a/repair_purchase_return/models/repair_order.py b/repair_purchase_return/models/repair_order.py index a00709b3..f4ee7797 100644 --- a/repair_purchase_return/models/repair_order.py +++ b/repair_purchase_return/models/repair_order.py @@ -22,7 +22,9 @@ class RepairOrder(models.Model): ) @api.depends( + "operations.purchase_return_line_ids", "operations.purchase_return_line_ids.order_id", + "fees_lines.purchase_return_line_ids", "fees_lines.purchase_return_line_ids.order_id", ) def _compute_purchase_returns(self): diff --git a/repair_purchase_return/views/purchase_return_order_views.xml b/repair_purchase_return/views/purchase_return_order_views.xml new file mode 100644 index 00000000..20bfcebc --- /dev/null +++ b/repair_purchase_return/views/purchase_return_order_views.xml @@ -0,0 +1,28 @@ + + + + + purchase.return.order.form + purchase.return.order + + +
+ +
+
+
+ +
From d96e44a337315724bded5de96d9acae8f14ce1c2 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Tue, 23 Nov 2021 18:27:32 +0100 Subject: [PATCH 03/11] [imp] repair_purchase_return: purchase_return_notes --- repair_purchase_return/models/repair_order.py | 6 ++++-- repair_purchase_return/views/repair_order_views.xml | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/repair_purchase_return/models/repair_order.py b/repair_purchase_return/models/repair_order.py index f4ee7797..e643f61f 100644 --- a/repair_purchase_return/models/repair_order.py +++ b/repair_purchase_return/models/repair_order.py @@ -20,6 +20,7 @@ class RepairOrder(models.Model): default=0, store=True, ) + purchase_return_notes = fields.Text("Purchase Return Notes") @api.depends( "operations.purchase_return_line_ids", @@ -35,15 +36,16 @@ def _compute_purchase_returns(self): order.purchase_return_count = len(pros) def _prepare_purchase_return_values(self, vendor): - invoice_vals = { + vals = { "origin": self.name, "partner_id": vendor.id, "fiscal_position_id": vendor.property_account_position_id and vendor.property_account_position_id.id or False, "company_id": self.company_id.id, + "notes": self.purchase_return_notes, } - return invoice_vals + return vals @api.model def _select_operations_to_return(self, operations): diff --git a/repair_purchase_return/views/repair_order_views.xml b/repair_purchase_return/views/repair_order_views.xml index 0c2fbcdb..85df9e49 100644 --- a/repair_purchase_return/views/repair_order_views.xml +++ b/repair_purchase_return/views/repair_order_views.xml @@ -30,6 +30,12 @@ + + + From 7767c923aa44b1c4f998d6e9d69ffd5b512fa255 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Sun, 2 Jan 2022 19:51:41 +0100 Subject: [PATCH 04/11] [fix][repair_purchase_return] use the supplier's currency --- repair_purchase_return/models/repair_order.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/repair_purchase_return/models/repair_order.py b/repair_purchase_return/models/repair_order.py index e643f61f..2324c5b5 100644 --- a/repair_purchase_return/models/repair_order.py +++ b/repair_purchase_return/models/repair_order.py @@ -36,15 +36,17 @@ def _compute_purchase_returns(self): order.purchase_return_count = len(pros) def _prepare_purchase_return_values(self, vendor): + fp = vendor.with_company(self.company_id).property_account_position_id + currency = vendor.with_company(self.company_id).property_purchase_currency_id vals = { "origin": self.name, "partner_id": vendor.id, - "fiscal_position_id": vendor.property_account_position_id - and vendor.property_account_position_id.id - or False, + "fiscal_position_id": fp and fp.id or False, "company_id": self.company_id.id, "notes": self.purchase_return_notes, } + if currency: + vals["currency_id"] = currency.id return vals @api.model From eb353382a692b71763108b6b2d33eef87ce923e1 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Date: Mon, 3 Jan 2022 07:52:43 +0100 Subject: [PATCH 05/11] add maintainer --- repair_purchase_return/__manifest__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/repair_purchase_return/__manifest__.py b/repair_purchase_return/__manifest__.py index afd66a71..f04ebc7f 100644 --- a/repair_purchase_return/__manifest__.py +++ b/repair_purchase_return/__manifest__.py @@ -17,6 +17,7 @@ "views/repair_order_views.xml", "views/purchase_return_order_views.xml", ], + "maintainers": ["JordiBForgeFlow"], "installable": True, "application": False, } From 31dd450feb5e603c6b095fcbab5323a73209eed6 Mon Sep 17 00:00:00 2001 From: Christopher Ormaza Date: Thu, 6 Jan 2022 08:14:53 -0500 Subject: [PATCH 06/11] FIX: Should select almost one of suppliers --- repair_purchase_return/wizards/repair_purchase_return_wiz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repair_purchase_return/wizards/repair_purchase_return_wiz.py b/repair_purchase_return/wizards/repair_purchase_return_wiz.py index 1517c0fa..d9225cff 100644 --- a/repair_purchase_return/wizards/repair_purchase_return_wiz.py +++ b/repair_purchase_return/wizards/repair_purchase_return_wiz.py @@ -28,7 +28,7 @@ def default_get(self, fields): .filtered(lambda s: s.company_id == repair.company_id) .name ) - if len(vendors) == 1: + if len(vendors) >= 1: vals["vendor_id"] = vendors[0].id return vals From 03e57a4382287e1924b0a561e77b9ecc83078eb4 Mon Sep 17 00:00:00 2001 From: Christopher Ormaza Date: Tue, 19 Jul 2022 11:57:17 -0500 Subject: [PATCH 07/11] [FIX] field definition --- repair_purchase_return/models/purchase_return_order.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/repair_purchase_return/models/purchase_return_order.py b/repair_purchase_return/models/purchase_return_order.py index 1601fd68..a6d7631c 100644 --- a/repair_purchase_return/models/purchase_return_order.py +++ b/repair_purchase_return/models/purchase_return_order.py @@ -1,7 +1,7 @@ # Copyright (C) 2021 ForgeFlow S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html) -from odoo import fields, models +from odoo import api, fields, models class PurchaseReturnOrder(models.Model): @@ -10,16 +10,16 @@ class PurchaseReturnOrder(models.Model): repair_order_count = fields.Integer( compute="_compute_repair_orders", string="Repair Order Count", - copy=False, - default=0, ) repair_order_ids = fields.Many2many( comodel_name="repair.order", compute="_compute_repair_orders", - copy=False, - store=True, ) + @api.depends( + "order_line.repair_line_ids.repair_id", + "order_line.repair_fee_ids.repair_id", + ) def _compute_repair_orders(self): for rec in self: repair_orders = rec.order_line.mapped("repair_line_ids.repair_id") From 27a91e36d4d177af2b49848fbad55ce412f9c531 Mon Sep 17 00:00:00 2001 From: PauBForgeFlow Date: Thu, 17 Aug 2023 11:51:34 +0200 Subject: [PATCH 08/11] [MIG] repair_purchase_return: Migration to 16.0 --- repair_purchase_return/__manifest__.py | 2 +- repair_purchase_return/models/purchase_return_order.py | 2 +- repair_purchase_return/models/repair_fee.py | 1 + repair_purchase_return/models/repair_line.py | 1 + repair_purchase_return/models/repair_order.py | 4 ++-- repair_purchase_return/wizards/repair_purchase_return_wiz.py | 2 +- 6 files changed, 7 insertions(+), 5 deletions(-) diff --git a/repair_purchase_return/__manifest__.py b/repair_purchase_return/__manifest__.py index f04ebc7f..d9ee762d 100644 --- a/repair_purchase_return/__manifest__.py +++ b/repair_purchase_return/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Repair Purchase Return", - "version": "14.0.1.0.0", + "version": "16.0.1.0.0", "development_status": "Alpha", "license": "LGPL-3", "category": "Repair", diff --git a/repair_purchase_return/models/purchase_return_order.py b/repair_purchase_return/models/purchase_return_order.py index a6d7631c..019bd7ef 100644 --- a/repair_purchase_return/models/purchase_return_order.py +++ b/repair_purchase_return/models/purchase_return_order.py @@ -9,7 +9,7 @@ class PurchaseReturnOrder(models.Model): repair_order_count = fields.Integer( compute="_compute_repair_orders", - string="Repair Order Count", + string="Repair Orders Count", ) repair_order_ids = fields.Many2many( comodel_name="repair.order", diff --git a/repair_purchase_return/models/repair_fee.py b/repair_purchase_return/models/repair_fee.py index b18e19e8..de8751eb 100644 --- a/repair_purchase_return/models/repair_fee.py +++ b/repair_purchase_return/models/repair_fee.py @@ -40,6 +40,7 @@ def _prepare_purchase_order_line_vals(self, pro): "repair_fee_ids": [(4, self.id)], "date_planned": fields.Datetime.now(), "refund_only": True, + "display_type": "product", } self._execute_purchase_return_line_onchange(vals) return vals diff --git a/repair_purchase_return/models/repair_line.py b/repair_purchase_return/models/repair_line.py index 3acc0e71..7a79ef32 100644 --- a/repair_purchase_return/models/repair_line.py +++ b/repair_purchase_return/models/repair_line.py @@ -40,6 +40,7 @@ def _prepare_purchase_order_line_vals(self, pro): "repair_line_ids": [(4, self.id)], "date_planned": fields.Datetime.now(), "refund_only": True, + "display_type": "product", } self._execute_purchase_return_line_onchange(vals) return vals diff --git a/repair_purchase_return/models/repair_order.py b/repair_purchase_return/models/repair_order.py index 2324c5b5..fda9ab73 100644 --- a/repair_purchase_return/models/repair_order.py +++ b/repair_purchase_return/models/repair_order.py @@ -15,12 +15,12 @@ class RepairOrder(models.Model): ) purchase_return_count = fields.Integer( compute="_compute_purchase_returns", - string="Purchase Return Count", + string="Return Purchase Count", copy=False, default=0, store=True, ) - purchase_return_notes = fields.Text("Purchase Return Notes") + purchase_return_notes = fields.Text("Return Purchase Notes") @api.depends( "operations.purchase_return_line_ids", diff --git a/repair_purchase_return/wizards/repair_purchase_return_wiz.py b/repair_purchase_return/wizards/repair_purchase_return_wiz.py index d9225cff..8cbc8222 100644 --- a/repair_purchase_return/wizards/repair_purchase_return_wiz.py +++ b/repair_purchase_return/wizards/repair_purchase_return_wiz.py @@ -26,7 +26,7 @@ def default_get(self, fields): vendors |= ( repair.product_id.mapped("seller_ids") .filtered(lambda s: s.company_id == repair.company_id) - .name + .partner_id ) if len(vendors) >= 1: vals["vendor_id"] = vendors[0].id From d335692079f2a7f751fd3e9db8c9942d0b2c709b Mon Sep 17 00:00:00 2001 From: PauBForgeFlow Date: Thu, 17 Aug 2023 13:35:21 +0200 Subject: [PATCH 09/11] [ADD] base test --- repair_purchase_return/README.rst | 51 +++++++------- repair_purchase_return/__manifest__.py | 2 +- .../static/description/index.html | 67 +++++++++--------- repair_purchase_return/tests/__init__.py | 1 + .../test_repair_purchase_return_order.py | 70 +++++++++++++++++++ .../odoo/addons/repair_purchase_return | 1 + setup/repair_purchase_return/setup.py | 6 ++ test-requirements.txt | 0 8 files changed, 140 insertions(+), 58 deletions(-) create mode 100644 repair_purchase_return/tests/__init__.py create mode 100644 repair_purchase_return/tests/test_repair_purchase_return_order.py create mode 120000 setup/repair_purchase_return/odoo/addons/repair_purchase_return create mode 100644 setup/repair_purchase_return/setup.py create mode 100644 test-requirements.txt diff --git a/repair_purchase_return/README.rst b/repair_purchase_return/README.rst index cc49782f..8160340a 100644 --- a/repair_purchase_return/README.rst +++ b/repair_purchase_return/README.rst @@ -1,11 +1,14 @@ -================= -Repair Stock Move -================= +====================== +Repair Purchase Return +====================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:98b3537e74e31e79bd228a2bcd31227949424adb0cec58b0f5e4168559e53de3 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png :target: https://odoo-community.org/page/development-status @@ -13,27 +16,19 @@ Repair Stock Move .. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 -.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github - :target: https://github.com/OCA/manufacture/tree/14.0/repair_stock_move - :alt: OCA/manufacture +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Frepair-lightgray.png?logo=github + :target: https://github.com/OCA/repair/tree/16.0/repair_purchase_return + :alt: OCA/repair .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/manufacture-14-0/manufacture-14-0-repair_stock_move + :target: https://translation.odoo-community.org/projects/repair-16-0/repair-16-0-repair_purchase_return :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/129/14.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/repair&target_branch=16.0 + :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| -The purpose of this module is to modify the behaviour of the repair standard module. Achieving more flexibility in a repair process. - -The first change that it applies is the modification of the creation of stock moves in the repair flow: - -* Confirm Repair: creates draft stock moves on confirmation of the repair order. -* Start Repair: confirms the stock moves. -* End Repair: completes the stock moves and ends the repair order. - -Another feature which this module includes is that it allows to add components during all the different stages of the repair process, which adjusts better to the needs of some businesses. +The purpose of this module is to add the possibility of create a purchase return order for some repair components products and operations directly from repair order. .. IMPORTANT:: This is an alpha version, the data model and design can change at any time without warning. @@ -53,10 +48,10 @@ Follow the Odoo standard repair module flow. Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. +Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -87,6 +82,14 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/manufacture `_ project on GitHub. +.. |maintainer-JordiBForgeFlow| image:: https://github.com/JordiBForgeFlow.png?size=40px + :target: https://github.com/JordiBForgeFlow + :alt: JordiBForgeFlow + +Current `maintainer `__: + +|maintainer-JordiBForgeFlow| + +This module is part of the `OCA/repair `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/repair_purchase_return/__manifest__.py b/repair_purchase_return/__manifest__.py index d9ee762d..416650e6 100644 --- a/repair_purchase_return/__manifest__.py +++ b/repair_purchase_return/__manifest__.py @@ -9,7 +9,7 @@ "category": "Repair", "summary": "Create a Purchase Return from a Repair", "author": "ForgeFlow, Odoo Community Association (OCA)", - "website": "https://github.com/OCA/manufacture", + "website": "https://github.com/OCA/repair", "depends": ["repair", "purchase_return"], "data": [ "security/ir.model.access.csv", diff --git a/repair_purchase_return/static/description/index.html b/repair_purchase_return/static/description/index.html index 93c5dc60..a458550b 100644 --- a/repair_purchase_return/static/description/index.html +++ b/repair_purchase_return/static/description/index.html @@ -1,20 +1,19 @@ - - -Repair Stock Move + +Repair Purchase Return -
-

Repair Stock Move

+
+

Repair Purchase Return

-

Alpha License: LGPL-3 OCA/manufacture Translate me on Weblate Try me on Runbot

-

The purpose of this module is to modify the behaviour of the repair standard module. Achieving more flexibility in a repair process.

-

The first change that it applies is the modification of the creation of stock moves in the repair flow:

-
    -
  • Confirm Repair: creates draft stock moves on confirmation of the repair order.
  • -
  • Start Repair: confirms the stock moves.
  • -
  • End Repair: completes the stock moves and ends the repair order.
  • -
-

Another feature which this module includes is that it allows to add components during all the different stages of the repair process, which adjusts better to the needs of some businesses.

+

Alpha License: LGPL-3 OCA/repair Translate me on Weblate Try me on Runboat

+

The purpose of this module is to add the possibility of create a purchase return order for some repair components products and operations directly from repair order.

Important

This is an alpha version, the data model and design can change at any time without warning. @@ -385,51 +379,58 @@

Repair Stock Move

Table of contents

-

Usage

-

Follow the Odoo standard repair module flow.

+

Usage

+
    +
  1. Go to Repair > Repair Orders > New and create a new repair order. Add at least one line in Parts (with type Add and positive Quantity) and Operations (with positive Quantity).
  2. +
  3. Click Create Purchase Return button.
  4. +
  5. On the wizard, choose a valid vendor and click Create And View Purchase Return button.
  6. +
+

In the Purchase Return Order, Unit Price of each product line would be the cost price of the product.

-

Bug Tracker

-

Bugs are tracked on GitHub Issues. +

Bug Tracker

+

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

+If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • ForgeFlow
-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

-

This module is part of the OCA/manufacture project on GitHub.

+

Current maintainer:

+

JordiBForgeFlow

+

This module is part of the OCA/repair project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/repair_purchase_return/tests/__init__.py b/repair_purchase_return/tests/__init__.py new file mode 100644 index 00000000..4170f994 --- /dev/null +++ b/repair_purchase_return/tests/__init__.py @@ -0,0 +1 @@ +from . import test_repair_purchase_return_order diff --git a/repair_purchase_return/tests/test_repair_purchase_return_order.py b/repair_purchase_return/tests/test_repair_purchase_return_order.py new file mode 100644 index 00000000..37c241f4 --- /dev/null +++ b/repair_purchase_return/tests/test_repair_purchase_return_order.py @@ -0,0 +1,70 @@ +from odoo.tests import tagged + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon + + +@tagged("-at_install", "post_install") +class TestRepairPurchaseReturnOrder(AccountTestInvoicingCommon): + @classmethod + def setUpClass(cls): + super(TestRepairPurchaseReturnOrder, cls).setUpClass() + cls.product = cls.env["product.product"].create( + { + "name": "Test product", + "standard_price": 10, + "list_price": 20, + } + ) + cls.partner = cls.env.ref("base.res_partner_address_1") + cls.location = cls.env["stock.location"].create( + { + "name": "Test location", + } + ) + cls.repair = cls.env["repair.order"].create( + { + "product_id": cls.product.id, + "partner_id": cls.partner.id, + "partner_invoice_id": cls.partner.id, + "product_uom": cls.product.uom_id.id, + "location_id": cls.location.id, + "invoice_method": "after_repair", + } + ) + domain_location = [("usage", "=", "production")] + stock_location_id = cls.env["stock.location"].search(domain_location, limit=1) + cls.repair_line = cls.env["repair.line"].create( + { + "repair_id": cls.repair.id, + "type": "add", + "product_id": cls.product.id, + "product_uom": cls.product.uom_id.id, + "name": "Test line", + "location_id": cls.repair.location_id.id, + "location_dest_id": stock_location_id.id, + "product_uom_qty": 1, + "price_unit": 20, + } + ) + + cls.repair["operations"] = cls.repair_line + + cls.journal = cls.env["account.journal"].create( + { + "name": "Test Journal", + "code": "test", + "type": "sale", + "invoice_reference_type": "invoice", + "invoice_reference_model": "odoo", + } + ) + + cls.vendor = cls.env["res.partner"].create( + { + "name": "Vendor1", + } + ) + + def test_purchase_return_base(self): + self.pro = self.repair._create_purchase_return(self.vendor) + self.pro.action_view_repair_orders() diff --git a/setup/repair_purchase_return/odoo/addons/repair_purchase_return b/setup/repair_purchase_return/odoo/addons/repair_purchase_return new file mode 120000 index 00000000..6983fec7 --- /dev/null +++ b/setup/repair_purchase_return/odoo/addons/repair_purchase_return @@ -0,0 +1 @@ +../../../../repair_purchase_return \ No newline at end of file diff --git a/setup/repair_purchase_return/setup.py b/setup/repair_purchase_return/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/repair_purchase_return/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000..e69de29b From 94f8336dcb77e441e6f80d4c12ca153e6da7dc1f Mon Sep 17 00:00:00 2001 From: PauBForgeFlow Date: Thu, 21 Sep 2023 17:03:18 +0200 Subject: [PATCH 10/11] [IMP] repair_purchase_return: Description and usage files updated --- repair_purchase_return/README.rst | 15 +++++++++++++-- repair_purchase_return/readme/DESCRIPTION.rst | 10 +--------- repair_purchase_return/readme/USAGE.rst | 8 +++++++- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/repair_purchase_return/README.rst b/repair_purchase_return/README.rst index 8160340a..6d683cc0 100644 --- a/repair_purchase_return/README.rst +++ b/repair_purchase_return/README.rst @@ -26,7 +26,7 @@ Repair Purchase Return :target: https://runboat.odoo-community.org/builds?repo=OCA/repair&target_branch=16.0 :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| The purpose of this module is to add the possibility of create a purchase return order for some repair components products and operations directly from repair order. @@ -40,10 +40,21 @@ The purpose of this module is to add the possibility of create a purchase return .. contents:: :local: +Description +=========== + +The purpose of this module is to add the possibility of create a purchase return order for some repair components products and operations directly from repair order. + Usage ===== -Follow the Odoo standard repair module flow. +#. Go to *Repair > Repair Orders > New* and create a new repair order. Add at least one line in *Parts* (with type *Add* and positive *Quantity*) and *Operations* (with positive *Quantity*). + +#. Click *Create Purchase Return* button. + +#. On the wizard, choose a valid vendor and click *Create And View Purchase Return* button. + +In the *Purchase Return Order*, *Unit Price* of each product line would be the cost price of the product. Bug Tracker =========== diff --git a/repair_purchase_return/readme/DESCRIPTION.rst b/repair_purchase_return/readme/DESCRIPTION.rst index f46cb240..a88f5f9c 100644 --- a/repair_purchase_return/readme/DESCRIPTION.rst +++ b/repair_purchase_return/readme/DESCRIPTION.rst @@ -1,9 +1 @@ -The purpose of this module is to modify the behaviour of the repair standard module. Achieving more flexibility in a repair process. - -The first change that it applies is the modification of the creation of stock moves in the repair flow: - -* Confirm Repair: creates draft stock moves on confirmation of the repair order. -* Start Repair: confirms the stock moves. -* End Repair: completes the stock moves and ends the repair order. - -Another feature which this module includes is that it allows to add components during all the different stages of the repair process, which adjusts better to the needs of some businesses. +The purpose of this module is to add the possibility of create a purchase return order for some repair components products and operations directly from repair order. diff --git a/repair_purchase_return/readme/USAGE.rst b/repair_purchase_return/readme/USAGE.rst index 3009b22a..4f8de837 100644 --- a/repair_purchase_return/readme/USAGE.rst +++ b/repair_purchase_return/readme/USAGE.rst @@ -1 +1,7 @@ -Follow the Odoo standard repair module flow. +#. Go to *Repair > Repair Orders > New* and create a new repair order. Add at least one line in *Parts* (with type *Add* and positive *Quantity*) and *Operations* (with positive *Quantity*). + +#. Click *Create Purchase Return* button. + +#. On the wizard, choose a valid vendor and click *Create And View Purchase Return* button. + +In the *Purchase Return Order*, *Unit Price* of each product line would be the cost price of the product. From 23f760215af660c875fc53e50f737799b50830bd Mon Sep 17 00:00:00 2001 From: PauBForgeFlow Date: Thu, 21 Sep 2023 17:32:10 +0200 Subject: [PATCH 11/11] [IMP] repair_purchase_return: Some test improvement --- .../test_repair_purchase_return_order.py | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/repair_purchase_return/tests/test_repair_purchase_return_order.py b/repair_purchase_return/tests/test_repair_purchase_return_order.py index 37c241f4..557f711e 100644 --- a/repair_purchase_return/tests/test_repair_purchase_return_order.py +++ b/repair_purchase_return/tests/test_repair_purchase_return_order.py @@ -15,6 +15,15 @@ def setUpClass(cls): "list_price": 20, } ) + + cls.service = cls.env["product.product"].create( + { + "name": "Test Fee", + "standard_price": 30, + "list_price": 50, + } + ) + cls.partner = cls.env.ref("base.res_partner_address_1") cls.location = cls.env["stock.location"].create( { @@ -28,7 +37,7 @@ def setUpClass(cls): "partner_invoice_id": cls.partner.id, "product_uom": cls.product.uom_id.id, "location_id": cls.location.id, - "invoice_method": "after_repair", + "invoice_method": "none", } ) domain_location = [("usage", "=", "production")] @@ -43,11 +52,23 @@ def setUpClass(cls): "location_id": cls.repair.location_id.id, "location_dest_id": stock_location_id.id, "product_uom_qty": 1, - "price_unit": 20, + "price_unit": cls.product.list_price, + } + ) + + cls.fees_lines = cls.env["repair.fee"].create( + { + "repair_id": cls.repair.id, + "product_id": cls.service.id, + "product_uom": cls.service.uom_id.id, + "name": "Test Fee", + "product_uom_qty": 1, + "price_unit": cls.service.list_price, } ) cls.repair["operations"] = cls.repair_line + cls.repair["fees_lines"] = cls.fees_lines cls.journal = cls.env["account.journal"].create( { @@ -65,6 +86,11 @@ def setUpClass(cls): } ) - def test_purchase_return_base(self): - self.pro = self.repair._create_purchase_return(self.vendor) - self.pro.action_view_repair_orders() + def test_repair_purchase_return(self): + pro = self.repair._create_purchase_return(self.vendor) + pro.action_view_repair_orders() + + # Check that purchase return order is caching the two lines and using the product cost + self.assertEqual(pro.order_line[0].price_unit, 10) + + self.assertEqual(pro.order_line[1].price_unit, 30)