-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5ff7049
commit e70035e
Showing
19 changed files
with
882 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
====================== | ||
Sale Partner Primeship | ||
====================== | ||
|
||
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! This file is generated by oca-gen-addon-readme !! | ||
!! changes will be overwritten. !! | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
.. |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 | ||
.. |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 | ||
|
||
|badge1| |badge2| |badge3| |badge4| |badge5| | ||
|
||
This module adds a concept of primeship for partners. | ||
This primeship is activated on the confirmation of a sale containing | ||
a primeship activation product for a customizable duration. | ||
|
||
**Table of contents** | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Usage | ||
===== | ||
|
||
To make a product that activates primeship on sale order, you have to edit it, set its type to service and | ||
go to the product form Sales tab and tick the Activates primeship checkbox: | ||
|
||
.. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/14.0/sale_partner_primeship/static/description/primeship-product.png | ||
|
||
You can then set a primeship duration. | ||
|
||
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 | ||
|
||
And a click on the widget will get you to the primeship list view for this customer: | ||
|
||
.. figure:: https://raw.githubusercontent.com/OCA/sale-workflow/14.0/sale_partner_primeship/static/description/primeship-partner-view.png | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/sale-workflow/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 <https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_partner_primeship%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. | ||
|
||
Do not contact contributors directly about support or help with technical issues. | ||
|
||
Credits | ||
======= | ||
|
||
Authors | ||
~~~~~~~ | ||
|
||
* Akretion | ||
|
||
Contributors | ||
~~~~~~~~~~~~ | ||
|
||
* `Akretion <https://www.akretion.com>`_: | ||
|
||
* Florian Mounier | ||
|
||
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/sale-workflow <https://github.com/OCA/sale-workflow/tree/14.0/sale_partner_primeship>`_ project on GitHub. | ||
|
||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Copyright 2021 Akretion - Florian Mounier | ||
{ | ||
"name": "Sale Partner Primeship", | ||
"summary": "Allow you to manage time limited prime memberships and prime membership activation products.", | ||
"version": "14.0.1.0.0", | ||
"author": "Akretion, Odoo Community Association (OCA)", | ||
"website": "https://github.com/OCA/sale-workflow", | ||
"category": "Sales", | ||
"depends": ["sale", "account_invoice_start_end_dates"], | ||
"data": [ | ||
"views/product_template_views.xml", | ||
"views/sale_primeship_views.xml", | ||
"views/res_partner_views.xml", | ||
"security/ir.model.access.csv", | ||
], | ||
"license": "LGPL-3", | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import product_template, res_partner, sale_primeship, sale_order |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from odoo import fields, models | ||
|
||
|
||
class ProductTemplate(models.Model): | ||
_inherit = "product.template" | ||
|
||
primeship_activation = fields.Boolean(string="Activates primeship", default=False) | ||
primeship_duration = fields.Integer( | ||
string="Primeship duration (in months)", default=12 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from odoo import api, fields, models | ||
|
||
|
||
class ResPartner(models.Model): | ||
_inherit = "res.partner" | ||
|
||
primeship_ids = fields.One2many( | ||
comodel_name="sale.primeship", | ||
inverse_name="partner_id", | ||
required=True, | ||
) | ||
|
||
active_primeship = fields.Boolean( | ||
string="Active Primeship", compute="_compute_active_primeship", store=True | ||
) | ||
primeship_count = fields.Integer( | ||
string="Primeships Count", compute="_compute_primeship_count" | ||
) | ||
|
||
@api.depends( | ||
"commercial_partner_id.primeship_ids", | ||
"commercial_partner_id.primeship_ids.current", | ||
) | ||
def _compute_active_primeship(self): | ||
for record in self: | ||
record.active_primeship = ( | ||
record.commercial_partner_id.primeship_ids.filtered("current") | ||
) | ||
|
||
@api.depends("commercial_partner_id.primeship_ids") | ||
def _compute_primeship_count(self): | ||
for record in self: | ||
record.primeship_count = len(record.commercial_partner_id.primeship_ids) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
from odoo import api, fields, models | ||
from dateutil.relativedelta import relativedelta | ||
|
||
|
||
class SaleOrder(models.Model): | ||
_inherit = "sale.order" | ||
|
||
def action_confirm(self): | ||
rv = super().action_confirm() | ||
for record in self: | ||
partner = record.partner_id.commercial_partner_id | ||
|
||
for line in record.order_line: | ||
product_template = line.product_template_id | ||
|
||
if product_template.primeship_activation: | ||
# We do not take in account product_qty for now: | ||
duration = product_template.primeship_duration | ||
start = fields.Date.context_today(record) | ||
end = start + relativedelta(months=duration) | ||
|
||
# If we have already some primeships, we need to check for overlaps | ||
if partner.primeship_ids: | ||
# We assume no overlaps between partner primeships | ||
for primeship in partner.primeship_ids.sorted("start_date"): | ||
if primeship.overlaps(start, end): | ||
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 | ||
|
||
def action_cancel(self): | ||
rv = super().action_cancel() | ||
|
||
for record in self: | ||
record.order_line.mapped("primeship_id").active = False | ||
|
||
return rv | ||
|
||
|
||
class SaleOrderLine(models.Model): | ||
_inherit = "sale.order.line" | ||
|
||
primeship_id = fields.Many2one( | ||
string="Primeships", | ||
comodel_name="sale.primeship", | ||
compute="_compute_primeship_id", | ||
inverse="_compute_inverse_primeship_id", | ||
) | ||
|
||
# One2one impl | ||
primeship_ids = fields.One2many( | ||
comodel_name="sale.primeship", inverse_name="order_line_id" | ||
) | ||
|
||
@api.depends("primeship_ids") | ||
def _compute_primeship_id(self): | ||
for record in self: | ||
if record.primeship_ids: | ||
record.primeship_id = record.primeship_ids[0] | ||
|
||
def _compute_inverse_primeship_id(self): | ||
for record in self: | ||
if record.primeship_ids: | ||
primeship = record.env["sale.primeship"].browse( | ||
record.primeship_ids[0].id | ||
) | ||
primeship.order_line_id = record | ||
|
||
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 | ||
self.ensure_one() | ||
res = super()._prepare_invoice_line(**optional_values) | ||
if self.primeship_id: | ||
res.update( | ||
{ | ||
"start_date": self.primeship_id.start_date, | ||
"end_date": self.primeship_id.end_date, | ||
} | ||
) | ||
return res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
from odoo import api, fields, models | ||
from odoo.exceptions import ValidationError | ||
|
||
|
||
class SalePrimeship(models.Model): | ||
_name = "sale.primeship" | ||
_description = "Sale Prime Memberships" | ||
|
||
active = fields.Boolean(default=True) | ||
name = fields.Char(compute="_compute_name") | ||
|
||
start_date = fields.Date(string="Start Date", required=True) | ||
# End date day is not included in primeship date range | ||
end_date = fields.Date(string="End Date", required=True) | ||
|
||
partner_id = fields.Many2one( | ||
comodel_name="res.partner", | ||
required=True, | ||
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") | ||
|
||
@api.depends("start_date", "end_date") | ||
def _compute_name(self): | ||
for record in self: | ||
record.name = ( | ||
f"{record.start_date} - {record.end_date} Primeship" | ||
if record | ||
else "New Primeship" | ||
) | ||
|
||
@api.depends("active", "start_date", "end_date") | ||
def _compute_current(self): | ||
for record in self: | ||
record.current = ( | ||
record.active | ||
and record.start_date | ||
<= fields.Date.context_today(record) | ||
< record.end_date | ||
) | ||
|
||
@api.constrains("end_date") | ||
def _check_end_date(self): | ||
for record in self: | ||
if record.end_date < record.start_date: | ||
raise ValidationError("The end date cannot be before start date") | ||
|
||
if any( | ||
( | ||
primeship.overlaps(record.start_date, record.end_date) | ||
for primeship in record.partner_id.primeship_ids | ||
if primeship.id != record.id | ||
) | ||
): | ||
raise ValidationError("Primeships cannot overlaps") | ||
|
||
def overlaps(self, start, end): | ||
self.ensure_one() | ||
return self.start_date < end and self.end_date > start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* `Akretion <https://www.akretion.com>`_: | ||
|
||
* Florian Mounier |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
This module adds a concept of primeship for partners. | ||
This primeship is activated on the confirmation of a sale containing | ||
a primeship activation product for a customizable duration. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
To make a product that activates primeship on sale order, you have to edit it, set its type to service and | ||
go to the product form Sales tab and tick the Activates primeship checkbox: | ||
|
||
.. figure:: ../static/description/primeship-product.png | ||
|
||
You can then set a primeship duration. | ||
|
||
You can see current primeship availability for a customer: | ||
|
||
.. figure:: ../static/description/partner-with-primeship.png | ||
|
||
And a click on the widget will get you to the primeship list view for this customer: | ||
|
||
.. figure:: ../static/description/primeship-partner-view.png |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink | ||
access_sale_primeship_form,sale.primeship,model_sale_primeship,sales_team.group_sale_manager,1,1,1,1 | ||
access_sale_primeship_form_manager,sale.primeship,model_sale_primeship,account.group_account_readonly,1,0,0,0 |
Oops, something went wrong.