diff --git a/sale_partner_primeship/README.rst b/sale_partner_primeship/README.rst index 5bf905efc3d..d48ee82e05e 100644 --- a/sale_partner_primeship/README.rst +++ b/sale_partner_primeship/README.rst @@ -2,32 +2,39 @@ Sale Partner Primeship ====================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:4a8b2bd09f624001cb742f00bfe88a35f7c7ba7dceca566dae0bb4ed0d49e56e + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |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 +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github :target: https://github.com/OCA/sale-workflow/tree/14.0/sale_partner_primeship :alt: OCA/sale-workflow .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/sale-workflow-14-0/sale-workflow-14-0-sale_partner_primeship :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/167/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/sale-workflow&target_branch=14.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| This module adds a concept of primeship for partners. +A primeship is basically a simple membership very easy to use. This primeship is activated on the confirmation of a sale containing -a primeship activation product for a customizable duration. +a primeship activation product for a customizable duration expressed in months. +It is automatically deactivated when the duration expires. +You can then check if the primeship is active for a particular customer +and take actions based on it. **Table of contents** @@ -44,7 +51,7 @@ go to the product form Sales tab and tick the Activates primeship checkbox: You can then set a primeship duration. -You can see current primeship availability for a customer: +You can see current primeship availability for a customer: .. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/14.0/sale_partner_primeship/static/description/partner-with-primeship.png @@ -57,7 +64,7 @@ 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 +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. @@ -76,6 +83,7 @@ Contributors * `Akretion `_: * Florian Mounier + * Kevin Roche * Olivier Nibart Maintainers diff --git a/sale_partner_primeship/__manifest__.py b/sale_partner_primeship/__manifest__.py index 3dc51212594..d7154c07825 100644 --- a/sale_partner_primeship/__manifest__.py +++ b/sale_partner_primeship/__manifest__.py @@ -1,4 +1,5 @@ # Copyright 2021 Akretion - Florian Mounier +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { "name": "Sale Partner Primeship", "summary": """Allow you to manage time limited prime memberships @@ -16,5 +17,5 @@ "security/sale_partner_primeship.xml", "data/ir_cron.xml", ], - "license": "LGPL-3", + "license": "AGPL-3", } diff --git a/sale_partner_primeship/models/product_template.py b/sale_partner_primeship/models/product_template.py index 36976e23c12..181e6e56714 100644 --- a/sale_partner_primeship/models/product_template.py +++ b/sale_partner_primeship/models/product_template.py @@ -1,3 +1,6 @@ +# Copyright 2021 Akretion France (http://www.akretion.com/) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from odoo import fields, models diff --git a/sale_partner_primeship/models/res_partner.py b/sale_partner_primeship/models/res_partner.py index ac6cf59b5d1..e203a4c1cbb 100644 --- a/sale_partner_primeship/models/res_partner.py +++ b/sale_partner_primeship/models/res_partner.py @@ -1,3 +1,7 @@ +# Copyright 2021 Akretion France (http://www.akretion.com/) +# Copyright 2023 Akretion France (http://www.akretion.com/) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from odoo import api, fields, models @@ -10,8 +14,13 @@ class ResPartner(models.Model): required=True, ) + # store True allow to filter on active_primeship. + # There is a cron job to set it to False when the customer has no active + # primeship anymore. active_primeship = fields.Boolean( - string="Active Primeship", compute="_compute_active_primeship", store=True + string="Active Primeship", + compute="_compute_active_primeship", + store=True, ) primeship_count = fields.Integer( string="Primeships Count", compute="_compute_primeship_count" diff --git a/sale_partner_primeship/models/sale_order.py b/sale_partner_primeship/models/sale_order.py index 1ea4500d252..54b4ca54551 100644 --- a/sale_partner_primeship/models/sale_order.py +++ b/sale_partner_primeship/models/sale_order.py @@ -1,3 +1,7 @@ +# Copyright 2021 Akretion France (http://www.akretion.com/) +# Copyright 2024 Akretion France (http://www.akretion.com/) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from dateutil.relativedelta import relativedelta from odoo import api, fields, models @@ -6,8 +10,9 @@ class SaleOrder(models.Model): _inherit = "sale.order" - def action_confirm(self): - rv = super().action_confirm() + def _action_confirm(self): + super()._action_confirm() + sale_primeship = self.env["sale.primeship"] for record in self: partner = record.partner_id.commercial_partner_id @@ -28,22 +33,35 @@ def action_confirm(self): start = primeship.end_date end = start + relativedelta(months=duration) - self.env["sale.primeship"].create( - { - "start_date": start, - "end_date": end, - "partner_id": partner.id, - "order_line_id": line.id, - } - ) - return rv + vals = { + "start_date": start, + "end_date": end, + "partner_id": partner.id, + "order_line_id": line.id, + # this is to reactivate a maybe deactivated existing primeship + "active": True, + } + if line.primeship_id: + # Hm... something seems to have gone wrong here, + # but we handle it nonetheless. + line.primeship_id.write(vals) + else: + # We may have a deactivated primeship because of an order + # cancellation. + primeship = sale_primeship.with_context( + active_test=False, + ).search([("order_line_id", "=", line.id)]) + if primeship: + primeship.write(vals) + else: + sale_primeship.create(vals) + + return True def action_cancel(self): rv = super().action_cancel() - for record in self: record.order_line.mapped("primeship_id").active = False - return rv @@ -65,8 +83,7 @@ class SaleOrderLine(models.Model): @api.depends("primeship_ids") def _compute_primeship_id(self): for record in self: - if record.primeship_ids: - record.primeship_id = record.primeship_ids[0] + record.primeship_id = record.primeship_ids[:1] def _inverse_primeship_id(self): for record in self: @@ -78,10 +95,10 @@ def _inverse_primeship_id(self): record.primeship_id.order_line_id = record - # Update invoice start/end dates def _prepare_invoice_line(self, **optional_values): - # Set invoice start/end dates to primeship start/end dates - # In case of multi quantity, this assumes continuous date ranges + """Update invoice start/end dates. + Set invoice start/end dates to primeship start/end dates + In case of multi quantity, this assumes continuous date ranges.""" self.ensure_one() res = super()._prepare_invoice_line(**optional_values) if self.primeship_id: diff --git a/sale_partner_primeship/models/sale_primeship.py b/sale_partner_primeship/models/sale_primeship.py index 0e98a66af75..d70ed45ae90 100644 --- a/sale_partner_primeship/models/sale_primeship.py +++ b/sale_partner_primeship/models/sale_primeship.py @@ -1,3 +1,7 @@ +# Copyright 2021 Akretion France (http://www.akretion.com/) +# Copyright 2024 Akretion France (http://www.akretion.com/) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from odoo import _, api, fields, models from odoo.exceptions import ValidationError @@ -19,16 +23,23 @@ class SalePrimeship(models.Model): ondelete="cascade", index=True, ) - order_line_id = fields.Many2one( comodel_name="sale.order.line", string="Sale Order Line", ) - order_id = fields.Many2one(string="Sale Order", related="order_line_id.order_id") current = fields.Boolean(string="Currently Active", compute="_compute_current") + _sql_constraints = [ + # Constraint for One2one impl of "sale.order.line".primeship_id + ( + "unique_order_line", + "UNIQUE(order_line_id)", + "A sale order line can only have one primeship!", + ) + ] + @api.depends("start_date", "end_date") def _compute_name(self): for record in self: diff --git a/sale_partner_primeship/readme/CONTRIBUTORS.rst b/sale_partner_primeship/readme/CONTRIBUTORS.rst index a4d0ad92299..eac4144055f 100644 --- a/sale_partner_primeship/readme/CONTRIBUTORS.rst +++ b/sale_partner_primeship/readme/CONTRIBUTORS.rst @@ -1,3 +1,5 @@ * `Akretion `_: * Florian Mounier + * Kevin Roche + * Olivier Nibart diff --git a/sale_partner_primeship/readme/DESCRIPTION.rst b/sale_partner_primeship/readme/DESCRIPTION.rst index e2e920f2f9f..4f4bd4b2b3c 100644 --- a/sale_partner_primeship/readme/DESCRIPTION.rst +++ b/sale_partner_primeship/readme/DESCRIPTION.rst @@ -1,3 +1,7 @@ This module adds a concept of primeship for partners. +A primeship is basically a simple membership very easy to use. This primeship is activated on the confirmation of a sale containing -a primeship activation product for a customizable duration. +a primeship activation product for a customizable duration expressed in months. +It is automatically deactivated when the duration expires. +You can then check if the primeship is active for a particular customer +and take actions based on it. \ No newline at end of file diff --git a/sale_partner_primeship/static/description/index.html b/sale_partner_primeship/static/description/index.html index f44010436bb..192692416d3 100644 --- a/sale_partner_primeship/static/description/index.html +++ b/sale_partner_primeship/static/description/index.html @@ -1,20 +1,20 @@ - + - + Sale Partner Primeship