|
|
# -*- 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 list(range(1, 5)) 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: 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) >= 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} cdck_codes = cdck_by_code.keys() 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 and rp.partner_code[:2] in cdck_codes ) licensees = todo.filtered( lambda rp: not rp.is_company and rp.ffck_network and int(rp.partner_scale) == 5 and rp.country_department_id.code in cdck_codes ) # 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.code if dept in cdck_codes: partner.cdck_partner_id = cdck_by_code[dept] # 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): if self.env.context.get("website_id", False): return super().name_get() 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)
|