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.

283 lines
9.8 KiB

4 months ago
4 months ago
  1. # -*- coding: utf-8 -*-
  2. from odoo import models, fields, api
  3. from odoo.osv.expression import OR
  4. from .ffck_structure_type import SCALES
  5. class ResPartner(models.Model):
  6. _inherit = "res.partner"
  7. # Partner fields
  8. ffck_network = fields.Boolean(string="FFCK network")
  9. first_membership_date = fields.Date("Structure 1st membership")
  10. # Structure typing
  11. partner_scale = fields.Selection(
  12. selection=SCALES,
  13. string="Scale",
  14. compute="_get_partner_scale",
  15. store=True,
  16. )
  17. ffck_structure_type_id = fields.Many2one(
  18. comodel_name="ffck.structure.type",
  19. string="Structure type",
  20. )
  21. partner_code = fields.Char(string="FFCK code", size=6, index=True)
  22. partner_code_editable = fields.Boolean(string="FFCK code editable", default=True)
  23. # FFCK
  24. ffck_partner_id = fields.Many2one(
  25. comodel_name="res.partner",
  26. string="FFCK partner",
  27. ondelete="restrict",
  28. compute="_get_ffck_partner",
  29. store=True,
  30. )
  31. ffck_partner_code = fields.Char(string="FFCK", default="0", readonly=True)
  32. # CRCK
  33. crck_partner_id = fields.Many2one(
  34. comodel_name="res.partner",
  35. string="CRCK partner",
  36. index=True,
  37. ondelete="restrict",
  38. compute="_get_crck_partner",
  39. store=True,
  40. )
  41. crck_partner_code = fields.Char(related="crck_partner_id.partner_code", store=True)
  42. # CDCK
  43. cdck_partner_id = fields.Many2one(
  44. comodel_name="res.partner",
  45. string="CDCK partner",
  46. index=True,
  47. ondelete="restrict",
  48. compute="_get_cdck_partner",
  49. store=True,
  50. )
  51. cdck_partner_code = fields.Char(related="cdck_partner_id.partner_code", store=True)
  52. local_partner_id = fields.Many2one(
  53. comodel_name="res.partner",
  54. string="Local partner",
  55. index=True,
  56. ondelete="restrict",
  57. domain=[("ffck_network", "=", True), ("partner_scale", "=", 4)],
  58. )
  59. local_partner_code = fields.Char(
  60. related="local_partner_id.partner_code", store=True
  61. )
  62. crck_partner_ids = fields.One2many(
  63. comodel_name="res.partner",
  64. inverse_name="ffck_partner_id",
  65. domain=[("partner_scale", "=", "2")],
  66. string="Regional Comittees",
  67. )
  68. cdck_partner_ids = fields.One2many(
  69. comodel_name="res.partner",
  70. inverse_name="crck_partner_id",
  71. domain=[("partner_scale", "=", "3")],
  72. string="Departmental Comittees",
  73. )
  74. local_partner_ids = fields.One2many(
  75. comodel_name="res.partner",
  76. inverse_name="cdck_partner_id",
  77. domain=[("partner_scale", "=", "4")],
  78. string="Local structures",
  79. )
  80. # Compute hierarchy for searchpanel
  81. hierarchy_id = fields.Many2one(
  82. comodel_name="res.partner.hierarchy",
  83. string="Hierarchy element",
  84. compute="_compute_partner_hierarchy",
  85. store=True,
  86. )
  87. @api.depends("ffck_network", "partner_scale", "partner_code")
  88. def _compute_partner_hierarchy(self):
  89. for partner in self:
  90. partner.hierarchy_id = (
  91. partner.id
  92. if partner.ffck_network
  93. and int(partner.partner_scale) in range(1, 5)
  94. and partner.partner_code
  95. else False
  96. )
  97. @api.model
  98. def name_search(self, name="", args=None, operator="ilike", limit=100):
  99. """Allow searching by sequence code by default."""
  100. # Do not add any domain when user just clicked on search widget
  101. if not (name == "" and operator == "ilike"):
  102. # The dangling | is needed to combine with the domain added by super()
  103. args = OR(
  104. [
  105. [
  106. "&",
  107. ("ffck_network", "=", True),
  108. ("partner_code", "=like", name + "%"),
  109. ],
  110. args or [],
  111. ]
  112. )
  113. return super().name_search(name, args, operator, limit)
  114. @api.depends("name", "ref", "partner_code")
  115. def name_get(self):
  116. result = []
  117. ffck_partners = self.filtered("ffck_network")
  118. others = self - ffck_partners
  119. for record in ffck_partners:
  120. code = record.partner_code
  121. ref = record.ref
  122. result.append(
  123. (
  124. record.id,
  125. "{}{}{}".format(
  126. code and code + " - " or "",
  127. ref and record.is_company and ref + " - " or "",
  128. super(ResPartner, record).name_get()[0][1],
  129. ),
  130. )
  131. )
  132. result += super(ResPartner, others).name_get()
  133. return result
  134. # COMPUTES
  135. @api.depends("company_type", "ffck_structure_type_id")
  136. def _get_partner_scale(self):
  137. for partner in self:
  138. if partner.company_type == "individual":
  139. partner.partner_scale = "5"
  140. else:
  141. partner.partner_scale = partner.ffck_structure_type_id.scale
  142. def _get_ffck_partner(self):
  143. ffck = self.env.ref("ffck_commons.res_partner_ffck", raise_if_not_found=False)
  144. main = self.env.ref("base.main_partner")
  145. for partner in self:
  146. if main.ref == "FFCK":
  147. if ffck and ffck.active:
  148. ffck.write({"active": False})
  149. partner.ffck_partner_id = main
  150. else:
  151. partner.ffck_partner_id = ffck
  152. @api.depends("state_id", "ffck_network", "partner_scale")
  153. def _get_crck_partner(self):
  154. states = self.mapped("state_id")
  155. crck_ok = self.with_context(active_test=False).search(
  156. [
  157. ("ffck_network", "=", True),
  158. ("partner_scale", "=", "2"),
  159. ("state_id", "in", states.ids),
  160. ]
  161. )
  162. crck_by_state = {crck.state_id: crck for crck in crck_ok}
  163. states_ok = states & crck_ok.mapped("state_id")
  164. concerned = self.filtered(
  165. lambda rp: rp.ffck_network
  166. and int(rp.partner_scale) >= 2
  167. and rp.state_id in states_ok
  168. )
  169. for partner in concerned:
  170. state = partner.state_id
  171. partner.crck_partner_id = crck_by_state[state]
  172. # treat unconcerned
  173. for partner in self - concerned:
  174. partner.crck_partner_id = False
  175. @api.depends(
  176. "is_company",
  177. "ffck_network",
  178. "partner_code",
  179. "partner_scale",
  180. "local_partner_id",
  181. "local_partner_id.partner_code",
  182. "country_department_id",
  183. "country_department_id.code",
  184. )
  185. def _get_cdck_partner(self):
  186. structures = self.filtered(
  187. lambda rp: rp.is_company
  188. and rp.ffck_network
  189. and rp.partner_code
  190. and len(rp.partner_code) >= 2
  191. and int(rp.partner_scale) in (3, 4)
  192. )
  193. licensees = self.filtered(
  194. lambda rp: not rp.is_company
  195. and rp.ffck_network
  196. and int(rp.partner_scale) == 5
  197. and (
  198. rp.local_partner_id
  199. and rp.local_partner_id.cdck_partner_id
  200. or rp.country_department_id
  201. )
  202. )
  203. dept_codes = self.mapped(
  204. lambda rp: rp.partner_code
  205. and len(rp.partner_code) >= 2
  206. and int(rp.partner_scale) in (3, 4)
  207. and rp.partner_code[:2]
  208. )
  209. cdck_ok = self.with_context(active_test=False).search(
  210. [
  211. ("ffck_network", "=", True),
  212. ("partner_scale", "=", "3"),
  213. ("partner_code", "in", ["{}00".format(code) for code in dept_codes]),
  214. ]
  215. )
  216. cdck_by_code = {cdck.partner_code[:2]: cdck for cdck in cdck_ok}
  217. # Treat structures
  218. for partner in structures:
  219. partner.cdck_partner_id = cdck_by_code[partner.partner_code[:2]]
  220. # Treat licensees
  221. for partner in licensees:
  222. dept = partner.country_department_id
  223. local = partner.local_partner_id
  224. local_cd = local.cdck_partner_id
  225. partner.cdck_partner_id = (
  226. local_cd if local and local_cd else cdck_by_code[dept.code]
  227. )
  228. # treat others
  229. for partner in self - (structures | licensees):
  230. partner.cdck_partner_id = False
  231. @api.depends(
  232. "ffck_network",
  233. "partner_scale",
  234. "ffck_partner_id",
  235. "crck_partner_id",
  236. "cdck_partner_id",
  237. "local_partner_id",
  238. )
  239. def _get_ffck_parent(self):
  240. field_by_scale = {
  241. "2": "ffck_partner_id",
  242. "3": "crck_partner_id",
  243. "4": "cdck_partner_id",
  244. "5": "local_partner_id",
  245. }
  246. for partner in self:
  247. if partner.ffck_network and int(partner.partner_scale) in range(2, 6):
  248. partner.ffck_parent_id = getattr(
  249. partner, field_by_scale[partner.partner_scale]
  250. )
  251. else:
  252. partner.ffck_parent_id = False
  253. # ONCHANGES
  254. @api.onchange("partner_code", "company_type", "ffck_network")
  255. def onchange_partner_code(self):
  256. if self.ffck_network and self.is_company == False:
  257. code = self.partner_code or "000000"
  258. if len(code) < 6:
  259. self.update({"partner_code": code.zfill(6)})
  260. elif len(code) > 6:
  261. self.update({"partner_code": code[:-6]})
  262. # CRUD
  263. @api.model_create_multi
  264. def create(self, vals_list):
  265. for vals in vals_list:
  266. vals.update({"partner_code_editable": False})
  267. return super().create(vals_list)