You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
417 lines
14 KiB
417 lines
14 KiB
# -*- coding: utf-8 -*-
|
|
from dateutil.relativedelta import relativedelta
|
|
from odoo import models, fields, api
|
|
from odoo.osv.expression import OR
|
|
|
|
SCALES = [
|
|
("1", "National"),
|
|
("2", "Regional"),
|
|
("3", "Departmental"),
|
|
("4", "Local"),
|
|
("5", "Licensee"),
|
|
]
|
|
|
|
|
|
class ResPartner(models.Model):
|
|
_inherit = "res.partner"
|
|
_rec_names_search = ["display_name", "ref", "partner_code", "email"]
|
|
|
|
# Partner fields
|
|
ffck_network = fields.Boolean(string="FFCK network")
|
|
first_membership_date = fields.Date("1st membership")
|
|
last_membership_date = fields.Date("Last membership")
|
|
last_membership_validity = fields.Date(
|
|
string="Validity",
|
|
compute="_get_membership_validity",
|
|
store=True,
|
|
)
|
|
# Structure typing
|
|
partner_scale = fields.Selection(
|
|
selection=SCALES,
|
|
string="Scale",
|
|
compute="_get_partner_scale",
|
|
store=True,
|
|
)
|
|
ffck_structure_type_id = fields.Many2one(
|
|
comodel_name="ffck.structure.type",
|
|
string="Structure type",
|
|
)
|
|
age_range = fields.Selection(
|
|
related="age_range_id.age_range",
|
|
store=True,
|
|
)
|
|
ffck_membership_type_id = fields.Many2one(
|
|
comodel_name="ffck.membership.type",
|
|
string="License type",
|
|
)
|
|
partner_code = fields.Char(
|
|
string="FFCK code",
|
|
size=6,
|
|
index=True,
|
|
)
|
|
partner_code_editable = fields.Boolean(
|
|
string="FFCK code editable",
|
|
default=True,
|
|
)
|
|
# FFCK
|
|
ffck_partner_id = fields.Many2one(
|
|
comodel_name="res.partner",
|
|
string="FFCK partner",
|
|
ondelete="restrict",
|
|
compute="_get_ffck_partner",
|
|
store=True,
|
|
)
|
|
ffck_partner_code = fields.Char(
|
|
string="FFCK",
|
|
default="0",
|
|
readonly=True,
|
|
)
|
|
# CRCK
|
|
crck_partner_id = fields.Many2one(
|
|
comodel_name="res.partner",
|
|
string="CRCK partner",
|
|
index=True,
|
|
compute="_get_crck_partner",
|
|
store=True,
|
|
)
|
|
crck_partner_code = fields.Char(
|
|
related="crck_partner_id.partner_code",
|
|
store=True,
|
|
)
|
|
# CDCK
|
|
cdck_partner_id = fields.Many2one(
|
|
comodel_name="res.partner",
|
|
string="CDCK partner",
|
|
index=True,
|
|
compute="_get_cdck_partner",
|
|
store=True,
|
|
)
|
|
cdck_partner_code = fields.Char(
|
|
related="cdck_partner_id.partner_code",
|
|
store=True,
|
|
)
|
|
local_partner_id = fields.Many2one(
|
|
comodel_name="res.partner",
|
|
string="Local partner",
|
|
index=True,
|
|
domain=[("ffck_network", "=", True), ("partner_scale", "=", 4)],
|
|
)
|
|
local_partner_code = fields.Char(
|
|
related="local_partner_id.partner_code",
|
|
store=True,
|
|
)
|
|
crck_partner_ids = fields.One2many(
|
|
comodel_name="res.partner",
|
|
inverse_name="ffck_partner_id",
|
|
domain=[("partner_scale", "=", "2")],
|
|
string="Regional Comittees",
|
|
)
|
|
cdck_partner_ids = fields.One2many(
|
|
comodel_name="res.partner",
|
|
inverse_name="crck_partner_id",
|
|
domain=[("partner_scale", "=", "3")],
|
|
string="Departmental Comittees",
|
|
)
|
|
local_partner_ids = fields.One2many(
|
|
comodel_name="res.partner",
|
|
inverse_name="cdck_partner_id",
|
|
domain=[("partner_scale", "=", "4")],
|
|
string="Local structures",
|
|
)
|
|
# Compute hierarchy for searchpanel TODO : move to standalone module
|
|
hierarchy_id = fields.Many2one(
|
|
comodel_name="res.partner.hierarchy",
|
|
string="Hierarchy element",
|
|
compute="_compute_partner_hierarchy",
|
|
store=True,
|
|
)
|
|
|
|
@api.depends(
|
|
"ffck_network",
|
|
"partner_scale",
|
|
"partner_code",
|
|
"local_partner_id",
|
|
"cdck_partner_id",
|
|
"crck_partner_id",
|
|
"ffck_partner_id",
|
|
)
|
|
def _compute_partner_hierarchy(self):
|
|
for partner in self:
|
|
partner.hierarchy_id = (
|
|
partner.id
|
|
if partner.ffck_network
|
|
and int(partner.partner_scale) in range(1, 4)
|
|
and partner.partner_code
|
|
else partner.local_partner_id.id
|
|
or partner.cdck_partner_id.id
|
|
or partner.crck_partner_id.id
|
|
or partner.ffck_partner_id.id
|
|
)
|
|
|
|
# COMPUTES
|
|
|
|
@api.depends("last_membership_date", "ffck_membership_type_id")
|
|
def _get_membership_validity(self):
|
|
to_process = self.filtered("ffck_membership_type_id").filtered(
|
|
"last_membership_date"
|
|
)
|
|
for partner in to_process:
|
|
date = partner.last_membership_date
|
|
year_end = date.replace(day=31, month=12)
|
|
membership = partner.ffck_membership_type_id
|
|
dur = membership.duration
|
|
unit = membership.unit
|
|
if unit == "day":
|
|
partner.last_membership_validity = date + relativedelta(days=dur - 1)
|
|
elif unit == "month":
|
|
partner.last_membership_validity = min(
|
|
date + relativedelta(days=-1, months=dur),
|
|
year_end,
|
|
)
|
|
elif unit == "year":
|
|
partner.last_membership_validity = year_end
|
|
for partner in self - to_process:
|
|
partner.last_membership_validity = False
|
|
|
|
@api.depends(
|
|
"is_company",
|
|
"ffck_network",
|
|
"ffck_structure_type_id",
|
|
"ffck_structure_type_id.scale",
|
|
)
|
|
def _get_partner_scale(self):
|
|
ffck_partners = self.filtered("ffck_network")
|
|
for partner in ffck_partners:
|
|
if not partner.is_company:
|
|
partner.partner_scale = "5"
|
|
else:
|
|
partner.partner_scale = (
|
|
partner.ffck_structure_type_id.scale
|
|
if partner.ffck_structure_type_id
|
|
else False
|
|
)
|
|
for partner in self - ffck_partners:
|
|
partner.partner_scale = False
|
|
|
|
def lock_partner_code(self):
|
|
self.write({"partner_code_editable": False})
|
|
|
|
@api.depends("ffck_network")
|
|
def _get_ffck_partner(self):
|
|
ffck = self.env.ref("ffck_commons.res_partner_ffck", raise_if_not_found=False)
|
|
main = self.env.ref("base.main_partner")
|
|
for partner in self:
|
|
if main.ref == "FFCK":
|
|
if ffck and ffck.active:
|
|
ffck.write({"active": False})
|
|
partner.ffck_partner_id = main
|
|
else:
|
|
partner.ffck_partner_id = ffck
|
|
|
|
@api.depends(
|
|
"state_id",
|
|
"ffck_network",
|
|
"partner_scale",
|
|
"cdck_partner_id",
|
|
)
|
|
def _get_crck_partner(self):
|
|
cdck_ok = self.filtered("cdck_partner_id.crck_partner_id")
|
|
for partner in cdck_ok:
|
|
partner.crck_partner_id = partner.cdck_partner_id.crck_partner_id
|
|
todo = self - cdck_ok
|
|
if todo:
|
|
states = todo.mapped("state_id")
|
|
crck_ok = self.with_context(active_test=False).search(
|
|
[
|
|
("ffck_network", "=", True),
|
|
("partner_scale", "=", "2"),
|
|
("state_id", "in", states.ids),
|
|
]
|
|
)
|
|
states_ok = states & crck_ok.mapped("state_id")
|
|
crck_by_state = {crck.state_id: crck for crck in crck_ok}
|
|
concerned = todo.filtered(
|
|
lambda rp: rp.ffck_network
|
|
and int(rp.partner_scale) >= 3
|
|
and rp.state_id in states_ok
|
|
)
|
|
for partner in concerned:
|
|
state = partner.state_id
|
|
partner.crck_partner_id = crck_by_state[state]
|
|
# treat unconcerned
|
|
for partner in todo - concerned:
|
|
partner.crck_partner_id = False
|
|
|
|
@api.depends(
|
|
"is_company",
|
|
"ffck_network",
|
|
"partner_code",
|
|
"partner_scale",
|
|
"local_partner_id",
|
|
"local_partner_id",
|
|
"local_partner_id.partner_code",
|
|
"country_department_id",
|
|
"country_department_id.code",
|
|
)
|
|
def _get_cdck_partner(self):
|
|
local_ok = self.filtered("local_partner_id.cdck_partner_id")
|
|
for partner in local_ok:
|
|
partner.cdck_partner_id = partner.local_partner_id.cdck_partner_id
|
|
todo = self - local_ok
|
|
if todo:
|
|
structures = todo.filtered(
|
|
lambda rp: rp.is_company
|
|
and rp.ffck_network
|
|
and rp.partner_code
|
|
and len(rp.partner_code) >= 2
|
|
and int(rp.partner_scale) == 4
|
|
)
|
|
licensees = todo.filtered(
|
|
lambda rp: not rp.is_company
|
|
and rp.ffck_network
|
|
and int(rp.partner_scale) == 5
|
|
and rp.country_department_id
|
|
)
|
|
dept_codes = todo.mapped(
|
|
lambda rp: rp.ffck_network
|
|
and (
|
|
rp.is_company
|
|
and rp.partner_code
|
|
and len(rp.partner_code) >= 2
|
|
and int(rp.partner_scale) in (3, 4)
|
|
and rp.partner_code[:2]
|
|
or not rp.is_company
|
|
and rp.country_department_id
|
|
and rp.country_department_id.code
|
|
)
|
|
)
|
|
cdck_ok = self.with_context(active_test=False).search(
|
|
[
|
|
("is_company", "=", True),
|
|
("ffck_network", "=", True),
|
|
("partner_scale", "=", "3"),
|
|
(
|
|
"partner_code",
|
|
"in",
|
|
["{}00".format(code) for code in dept_codes],
|
|
),
|
|
]
|
|
)
|
|
cdck_by_code = {cdck.partner_code[:2]: cdck for cdck in cdck_ok}
|
|
# Treat structures
|
|
for partner in structures:
|
|
partner.cdck_partner_id = cdck_by_code[partner.partner_code[:2]]
|
|
# Treat licensees
|
|
for partner in licensees:
|
|
dept = partner.country_department_id
|
|
local = partner.local_partner_id
|
|
local_cd = local.cdck_partner_id
|
|
partner.cdck_partner_id = (
|
|
local_cd if local and local_cd else cdck_by_code[dept.code]
|
|
)
|
|
# treat others
|
|
for partner in todo - (structures | licensees):
|
|
partner.cdck_partner_id = False
|
|
|
|
@api.depends(
|
|
"ffck_network",
|
|
"partner_scale",
|
|
"ffck_partner_id",
|
|
"crck_partner_id",
|
|
"cdck_partner_id",
|
|
"local_partner_id",
|
|
)
|
|
def _get_ffck_parent(self):
|
|
field_by_scale = {
|
|
"2": "ffck_partner_id",
|
|
"3": "crck_partner_id",
|
|
"4": "cdck_partner_id",
|
|
"5": "local_partner_id",
|
|
}
|
|
for partner in self:
|
|
if partner.ffck_network and int(partner.partner_scale) in range(2, 6):
|
|
partner.ffck_parent_id = getattr(
|
|
partner, field_by_scale[partner.partner_scale]
|
|
)
|
|
else:
|
|
partner.ffck_parent_id = False
|
|
|
|
# INHERITANCE
|
|
|
|
# @api.model
|
|
# def name_search(self, name="", args=None, operator="ilike", limit=100):
|
|
# """Allow searching by sequence code by default."""
|
|
# # Do not add any domain when user just clicked on search widget
|
|
# if not (name == "" and operator == "ilike"):
|
|
# # The dangling | is needed to combine with the domain added by super()
|
|
# args = OR(
|
|
# [
|
|
# [
|
|
# "&",
|
|
# ("ffck_network", "=", True),
|
|
# ("partner_code", "=like", name + "%"),
|
|
# ],
|
|
# args or [],
|
|
# ]
|
|
# )
|
|
# return super().name_search(name, args, operator, limit)
|
|
|
|
@api.depends(
|
|
"is_company",
|
|
"name",
|
|
"parent_id.display_name",
|
|
"type",
|
|
"company_name",
|
|
"commercial_company_name",
|
|
"ref",
|
|
"partner_code",
|
|
)
|
|
def _compute_display_name(self):
|
|
return super()._compute_display_name()
|
|
|
|
def name_get(self):
|
|
res = []
|
|
ffck_partners = self.filtered("ffck_network")
|
|
others = self - ffck_partners
|
|
for record in ffck_partners:
|
|
code = record.partner_code
|
|
ref = record.ref
|
|
res.append(
|
|
(
|
|
record.id,
|
|
"{}{}{}".format(
|
|
code and code + " - " or "",
|
|
ref and record.is_company and ref + " - " or "",
|
|
super(ResPartner, record).name_get()[0][1],
|
|
),
|
|
)
|
|
)
|
|
res += super(ResPartner, others).name_get()
|
|
return res
|
|
|
|
# ONCHANGES
|
|
|
|
@api.onchange("partner_code", "company_type", "ffck_network")
|
|
def onchange_partner_code(self):
|
|
if self.ffck_network and not self.is_company:
|
|
code = self.partner_code or "000000"
|
|
if len(code) < 6:
|
|
self.update({"partner_code": code.zfill(6)})
|
|
elif len(code) > 6:
|
|
self.update({"partner_code": code[:-6]})
|
|
|
|
# CRUD
|
|
|
|
# @api.model_create_multi
|
|
# def create(self, vals_list):
|
|
# for vals in vals_list:
|
|
# vals.update({"partner_code_editable": False})
|
|
# return super().create(vals_list)
|
|
|
|
def write(self, vals):
|
|
is_company = vals.get("is_company", None)
|
|
if is_company is True:
|
|
vals.update({"ffck_membership_type_id": False})
|
|
if is_company is False:
|
|
vals.update({"ffck_structure_type_id": False})
|
|
return super().write(vals)
|