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.

937 lines
29 KiB

  1. # Copyright 2019 Coop IT Easy SCRL fs
  2. # Houssine Bakkali <houssine@coopiteasy.be>
  3. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  4. from datetime import datetime
  5. from addons.base_iban.models.res_partner_bank import validate_iban
  6. from odoo import _, api, fields, models
  7. from odoo.exceptions import UserError, ValidationError
  8. _REQUIRED = [
  9. "email",
  10. "firstname",
  11. "lastname",
  12. "birthdate",
  13. "address",
  14. "share_product_id",
  15. "ordered_parts",
  16. "zip_code",
  17. "city",
  18. "iban",
  19. "gender",
  20. ]
  21. @api.model
  22. def _lang_get(self):
  23. languages = self.env["res.lang"].search([])
  24. return [(language.code, language.name) for language in languages]
  25. # todo move to subscription_request.py
  26. class SubscriptionRequest(models.Model):
  27. _name = "subscription.request"
  28. _description = "Subscription Request"
  29. def get_required_field(self):
  30. required_fields = _REQUIRED
  31. company = self.env["res.company"]._company_default_get()
  32. if company.data_policy_approval_required:
  33. required_fields.append("data_policy_approved")
  34. if company.internal_rules_approval_required:
  35. required_fields.append("internal_rules_approved")
  36. return required_fields
  37. def get_mail_template_notif(self, is_company=False):
  38. if is_company:
  39. mail_template = "easy_my_coop.email_template_confirmation_company"
  40. else:
  41. mail_template = "easy_my_coop.email_template_confirmation"
  42. return self.env.ref(mail_template, False)
  43. def is_member(self, vals, cooperator):
  44. if cooperator.member:
  45. vals["type"] = "increase"
  46. vals["already_cooperator"] = True
  47. return vals
  48. @api.model
  49. def create(self, vals):
  50. partner_obj = self.env["res.partner"]
  51. if not vals.get("partner_id"):
  52. cooperator = False
  53. if vals.get("email"):
  54. cooperator = partner_obj.get_cooperator_from_email(
  55. vals.get("email")
  56. )
  57. if cooperator:
  58. # TODO remove the following line once it has
  59. # been found a way to avoid double encoding
  60. cooperator = cooperator[0]
  61. vals["type"] = "subscription"
  62. vals = self.is_member(vals, cooperator)
  63. vals["partner_id"] = cooperator.id
  64. else:
  65. cooperator_id = vals.get("partner_id")
  66. cooperator = partner_obj.browse(cooperator_id)
  67. vals = self.is_member(vals, cooperator)
  68. if not cooperator.cooperator:
  69. cooperator.write({"cooperator": True})
  70. subscr_request = super(SubscriptionRequest, self).create(vals)
  71. mail_template_notif = subscr_request.get_mail_template_notif(False)
  72. mail_template_notif.send_mail(subscr_request.id)
  73. return subscr_request
  74. @api.model
  75. def create_comp_sub_req(self, vals):
  76. vals["name"] = vals["company_name"]
  77. if not vals.get("partner_id"):
  78. cooperator = self.env["res.partner"].get_cooperator_from_crn(
  79. vals.get("company_register_number")
  80. )
  81. if cooperator:
  82. vals["partner_id"] = cooperator.id
  83. vals["type"] = "increase"
  84. vals["already_cooperator"] = True
  85. subscr_request = super(SubscriptionRequest, self).create(vals)
  86. confirmation_mail_template = subscr_request.get_mail_template_notif(
  87. True
  88. )
  89. confirmation_mail_template.send_mail(subscr_request.id)
  90. return subscr_request
  91. def check_empty_string(self, value):
  92. if value is None or value is False or value == "":
  93. return False
  94. return True
  95. def check_iban(self, iban):
  96. try:
  97. if iban:
  98. validate_iban(iban)
  99. return True
  100. else:
  101. return False
  102. except ValidationError:
  103. return False
  104. @api.multi
  105. @api.depends("iban", "skip_control_ng")
  106. def _compute_validated_lines(self):
  107. for sub_request in self:
  108. validated = sub_request.skip_control_ng or self.check_iban(
  109. sub_request.iban
  110. )
  111. sub_request.validated = validated
  112. @api.multi
  113. @api.depends(
  114. "share_product_id", "share_product_id.list_price", "ordered_parts"
  115. )
  116. def _compute_subscription_amount(self):
  117. for sub_request in self:
  118. sub_request.subscription_amount = (
  119. sub_request.share_product_id.list_price
  120. * sub_request.ordered_parts
  121. )
  122. already_cooperator = fields.Boolean(
  123. string="I'm already cooperator",
  124. readonly=True,
  125. states={"draft": [("readonly", False)]},
  126. )
  127. name = fields.Char(
  128. string="Name",
  129. required=True,
  130. readonly=True,
  131. states={"draft": [("readonly", False)]},
  132. )
  133. firstname = fields.Char(
  134. string="Firstname",
  135. readonly=True,
  136. states={"draft": [("readonly", False)]},
  137. )
  138. lastname = fields.Char(
  139. string="Lastname",
  140. readonly=True,
  141. states={"draft": [("readonly", False)]},
  142. )
  143. birthdate = fields.Date(
  144. string="Birthdate",
  145. readonly=True,
  146. states={"draft": [("readonly", False)]},
  147. )
  148. gender = fields.Selection(
  149. [("male", _("Male")), ("female", _("Female")), ("other", _("Other"))],
  150. string="Gender",
  151. readonly=True,
  152. states={"draft": [("readonly", False)]},
  153. )
  154. type = fields.Selection(
  155. [
  156. ("new", "New Cooperator"),
  157. ("subscription", "Subscription"),
  158. ("increase", "Increase number of share"),
  159. ],
  160. string="Type",
  161. default="new",
  162. readonly=True,
  163. states={"draft": [("readonly", False)]},
  164. )
  165. state = fields.Selection(
  166. [
  167. ("draft", "Draft"),
  168. ("block", "Blocked"),
  169. ("done", "Done"),
  170. ("waiting", "Waiting"),
  171. ("transfer", "Transfer"),
  172. ("cancelled", "Cancelled"),
  173. ("paid", "paid"),
  174. ],
  175. string="State",
  176. required=True,
  177. default="draft",
  178. )
  179. email = fields.Char(
  180. string="Email",
  181. required=True,
  182. readonly=True,
  183. states={"draft": [("readonly", False)]},
  184. )
  185. iban = fields.Char(
  186. string="Account Number",
  187. readonly=True,
  188. states={"draft": [("readonly", False)]},
  189. )
  190. partner_id = fields.Many2one(
  191. "res.partner",
  192. string="Cooperator",
  193. readonly=True,
  194. states={"draft": [("readonly", False)]},
  195. )
  196. share_product_id = fields.Many2one(
  197. "product.product",
  198. string="Share type",
  199. domain=[("is_share", "=", True)],
  200. required=True,
  201. readonly=True,
  202. states={"draft": [("readonly", False)]},
  203. )
  204. share_short_name = fields.Char(
  205. related="share_product_id.short_name",
  206. string="Share type name",
  207. readonly=True,
  208. states={"draft": [("readonly", False)]},
  209. )
  210. share_unit_price = fields.Float(
  211. related="share_product_id.list_price",
  212. string="Share price",
  213. readonly=True,
  214. states={"draft": [("readonly", False)]},
  215. )
  216. subscription_amount = fields.Monetary(
  217. compute="_compute_subscription_amount",
  218. string="Subscription amount",
  219. currency_field="company_currency_id",
  220. readonly=True,
  221. states={"draft": [("readonly", False)]},
  222. )
  223. ordered_parts = fields.Integer(
  224. string="Number of Share",
  225. required=True,
  226. readonly=True,
  227. default=1,
  228. states={"draft": [("readonly", False)]},
  229. )
  230. address = fields.Char(
  231. string="Address",
  232. required=True,
  233. readonly=True,
  234. states={"draft": [("readonly", False)]},
  235. )
  236. city = fields.Char(
  237. string="City",
  238. required=True,
  239. readonly=True,
  240. states={"draft": [("readonly", False)]},
  241. )
  242. zip_code = fields.Char(
  243. string="Zip Code",
  244. required=True,
  245. readonly=True,
  246. states={"draft": [("readonly", False)]},
  247. )
  248. country_id = fields.Many2one(
  249. "res.country",
  250. string="Country",
  251. ondelete="restrict",
  252. required=True,
  253. readonly=True,
  254. states={"draft": [("readonly", False)]},
  255. )
  256. phone = fields.Char(
  257. string="Phone", readonly=True, states={"draft": [("readonly", False)]}
  258. )
  259. user_id = fields.Many2one("res.users", string="Responsible", readonly=True)
  260. # todo rename to valid_subscription_request
  261. validated = fields.Boolean(
  262. compute="_compute_validated_lines",
  263. string="Valid Subscription request?",
  264. readonly=True,
  265. )
  266. skip_control_ng = fields.Boolean(
  267. string="Skip control",
  268. help="if this field is checked then no"
  269. " control will be done on the national"
  270. " register number and on the iban bank"
  271. " account. To be done in case of the id"
  272. " card is from abroad or in case of"
  273. " a passport",
  274. )
  275. lang = fields.Selection(
  276. _lang_get,
  277. string="Language",
  278. required=True,
  279. readonly=True,
  280. states={"draft": [("readonly", False)]},
  281. default=lambda self: self.env["res.company"]
  282. ._company_default_get()
  283. .default_lang_id.code,
  284. )
  285. date = fields.Date(
  286. string="Subscription date request",
  287. required=True,
  288. readonly=True,
  289. states={"draft": [("readonly", False)]},
  290. default=lambda self: datetime.strftime(datetime.now(), "%Y-%m-%d"),
  291. )
  292. company_id = fields.Many2one(
  293. "res.company",
  294. string="Company",
  295. required=True,
  296. change_default=True,
  297. readonly=True,
  298. default=lambda self: self.env["res.company"]._company_default_get(),
  299. )
  300. company_currency_id = fields.Many2one(
  301. "res.currency",
  302. related="company_id.currency_id",
  303. string="Company Currency",
  304. readonly=True,
  305. )
  306. is_company = fields.Boolean(
  307. string="Is a company",
  308. readonly=True,
  309. states={"draft": [("readonly", False)]},
  310. )
  311. is_operation = fields.Boolean(
  312. string="Is an operation",
  313. readonly=True,
  314. states={"draft": [("readonly", False)]},
  315. )
  316. company_name = fields.Char(
  317. string="Company name",
  318. readonly=True,
  319. states={"draft": [("readonly", False)]},
  320. )
  321. company_email = fields.Char(
  322. string="Company email",
  323. readonly=True,
  324. states={"draft": [("readonly", False)]},
  325. )
  326. company_register_number = fields.Char(
  327. string="Company register number",
  328. readonly=True,
  329. states={"draft": [("readonly", False)]},
  330. )
  331. company_type = fields.Selection(
  332. [("", "")],
  333. string="Company type",
  334. readonly=True,
  335. states={"draft": [("readonly", False)]},
  336. )
  337. same_address = fields.Boolean(
  338. string="Same address",
  339. readonly=True,
  340. states={"draft": [("readonly", False)]},
  341. )
  342. activities_address = fields.Char(
  343. string="Activities address",
  344. readonly=True,
  345. states={"draft": [("readonly", False)]},
  346. )
  347. activities_city = fields.Char(
  348. string="Activities city",
  349. readonly=True,
  350. states={"draft": [("readonly", False)]},
  351. )
  352. activities_zip_code = fields.Char(
  353. string="Activities zip Code",
  354. readonly=True,
  355. states={"draft": [("readonly", False)]},
  356. )
  357. activities_country_id = fields.Many2one(
  358. "res.country",
  359. string="Activities country",
  360. ondelete="restrict",
  361. readonly=True,
  362. states={"draft": [("readonly", False)]},
  363. )
  364. contact_person_function = fields.Char(
  365. string="Function",
  366. readonly=True,
  367. states={"draft": [("readonly", False)]},
  368. )
  369. operation_request_id = fields.Many2one(
  370. "operation.request",
  371. string="Operation Request",
  372. readonly=True,
  373. states={"draft": [("readonly", False)]},
  374. )
  375. capital_release_request = fields.One2many(
  376. "account.invoice",
  377. "subscription_request",
  378. string="Capital release request",
  379. readonly=True,
  380. states={"draft": [("readonly", False)]},
  381. )
  382. capital_release_request_date = fields.Date(
  383. string="Force the capital " "release request date",
  384. help="Keep empty to use the " "current date",
  385. copy=False,
  386. readonly=True,
  387. states={"draft": [("readonly", False)]},
  388. )
  389. source = fields.Selection(
  390. [
  391. ("website", "Website"),
  392. ("crm", "CRM"),
  393. ("manual", "Manual"),
  394. ("operation", "Operation"),
  395. ],
  396. string="Source",
  397. default="website",
  398. readonly=True,
  399. states={"draft": [("readonly", False)]},
  400. )
  401. data_policy_approved = fields.Boolean(
  402. string="Data Policy Approved", default=False
  403. )
  404. internal_rules_approved = fields.Boolean(
  405. string="Approved Internal Rules", default=False
  406. )
  407. _order = "id desc"
  408. def get_person_info(self, partner):
  409. self.firstname = partner.firstname
  410. self.name = partner.name
  411. self.lastname = partner.lastname
  412. self.email = partner.email
  413. self.birthdate = partner.birthdate_date
  414. self.gender = partner.gender
  415. self.address = partner.street
  416. self.city = partner.city
  417. self.zip_code = partner.zip
  418. self.country_id = partner.country_id
  419. self.phone = partner.phone
  420. self.lang = partner.lang
  421. @api.onchange("partner_id")
  422. def onchange_partner(self):
  423. partner = self.partner_id
  424. if partner:
  425. self.is_company = partner.is_company
  426. self.already_cooperator = partner.member
  427. if partner.bank_ids:
  428. self.iban = partner.bank_ids[0].acc_number
  429. if partner.member:
  430. self.type = "increase"
  431. if partner.is_company:
  432. self.company_name = partner.name
  433. self.company_email = partner.email
  434. self.company_register_number = partner.company_register_number
  435. representative = partner.get_representative()
  436. self.get_person_info(representative)
  437. self.contact_person_function = representative.function
  438. else:
  439. self.get_person_info(partner)
  440. # declare this function in order to be overriden
  441. def get_eater_vals(self, partner, share_product_id): # noqa
  442. return {}
  443. def _prepare_invoice_line(self, product, partner, qty):
  444. self.ensure_one()
  445. account = (
  446. product.property_account_income_id
  447. or product.categ_id.property_account_income_categ_id
  448. )
  449. if not account:
  450. raise UserError(
  451. _(
  452. "Please define income account for this product:"
  453. ' "%s" (id:%d) - or for its category: "%s".'
  454. )
  455. % (product.name, product.id, product.categ_id.name)
  456. )
  457. fpos = partner.property_account_position_id
  458. if fpos:
  459. account = fpos.map_account(account)
  460. res = {
  461. "name": product.name,
  462. "account_id": account.id,
  463. "price_unit": product.lst_price,
  464. "quantity": qty,
  465. "uom_id": product.uom_id.id,
  466. "product_id": product.id or False,
  467. }
  468. return res
  469. def get_capital_release_mail_template(self):
  470. template = "easy_my_coop.email_template_release_capital"
  471. return self.env.ref(template, False)
  472. def send_capital_release_request(self, invoice):
  473. email_template = self.get_capital_release_mail_template()
  474. # we send the email with the capital release request in attachment
  475. # TODO remove sudo() and give necessary access right
  476. email_template.sudo().send_mail(invoice.id, True)
  477. invoice.sent = True
  478. def get_journal(self):
  479. return self.env["account.journal"].search([("code", "=", "SUBJ")])[0]
  480. def get_accounting_account(self):
  481. account_obj = self.env["account.account"]
  482. if self.company_id.property_cooperator_account:
  483. account = self.company_id.property_cooperator_account
  484. else:
  485. accounts = account_obj.search([("code", "=", "416000")])
  486. if accounts:
  487. account = accounts[0]
  488. else:
  489. raise UserError(
  490. _("You must set a cooperator account on you company.")
  491. )
  492. return account
  493. def get_invoice_vals(self, partner):
  494. return {
  495. "partner_id": partner.id,
  496. "journal_id": self.get_journal().id,
  497. "account_id": self.get_accounting_account().id,
  498. "type": "out_invoice",
  499. "release_capital_request": True,
  500. "subscription_request": self.id,
  501. }
  502. def create_invoice(self, partner):
  503. # creating invoice and invoice lines
  504. invoice_vals = self.get_invoice_vals(partner)
  505. if self.capital_release_request_date:
  506. invoice_vals["date_invoice"] = self.capital_release_request_date
  507. invoice = self.env["account.invoice"].create(invoice_vals)
  508. vals = self._prepare_invoice_line(
  509. self.share_product_id, partner, self.ordered_parts
  510. )
  511. vals["invoice_id"] = invoice.id
  512. self.env["account.invoice.line"].create(vals)
  513. # validate the capital release request
  514. invoice.action_invoice_open()
  515. self.send_capital_release_request(invoice)
  516. return invoice
  517. def get_partner_company_vals(self):
  518. partner_vals = {
  519. "name": self.company_name,
  520. "last_name": self.company_name,
  521. "is_company": self.is_company,
  522. "company_register_number": self.company_register_number, # noqa
  523. "cooperator": True,
  524. "street": self.address,
  525. "zip": self.zip_code,
  526. "city": self.city,
  527. "email": self.company_email,
  528. "out_inv_comm_type": "bba",
  529. "customer": self.share_product_id.customer,
  530. "country_id": self.country_id.id,
  531. "lang": self.lang,
  532. "data_policy_approved": self.data_policy_approved,
  533. "internal_rules_approved": self.internal_rules_approved,
  534. }
  535. return partner_vals
  536. def get_partner_vals(self):
  537. partner_vals = {
  538. "name": self.name,
  539. "firstname": self.firstname,
  540. "lastname": self.lastname,
  541. "street": self.address,
  542. "zip": self.zip_code,
  543. "email": self.email,
  544. "gender": self.gender,
  545. "cooperator": True,
  546. "city": self.city,
  547. "phone": self.phone,
  548. "country_id": self.country_id.id,
  549. "lang": self.lang,
  550. "birthdate_date": self.birthdate,
  551. "customer": self.share_product_id.customer,
  552. "data_policy_approved": self.data_policy_approved,
  553. "internal_rules_approved": self.internal_rules_approved,
  554. }
  555. return partner_vals
  556. def get_representative_vals(self):
  557. contact_vals = {
  558. "name": self.name,
  559. "firstname": self.firstname,
  560. "lastname": self.lastname,
  561. "customer": False,
  562. "is_company": False,
  563. "cooperator": True,
  564. "street": self.address,
  565. "gender": self.gender,
  566. "zip": self.zip_code,
  567. "city": self.city,
  568. "phone": self.phone,
  569. "email": self.email,
  570. "country_id": self.country_id.id,
  571. "out_inv_comm_type": "bba",
  572. "out_inv_comm_algorithm": "random",
  573. "lang": self.lang,
  574. "birthdate_date": self.birthdate,
  575. "parent_id": self.partner_id.id,
  576. "representative": True,
  577. "function": self.contact_person_function,
  578. "type": "representative",
  579. "data_policy_approved": self.data_policy_approved,
  580. "internal_rules_approved": self.internal_rules_approved,
  581. }
  582. return contact_vals
  583. def create_coop_partner(self):
  584. partner_obj = self.env["res.partner"]
  585. if self.is_company:
  586. partner_vals = self.get_partner_company_vals()
  587. else:
  588. partner_vals = self.get_partner_vals()
  589. partner = partner_obj.create(partner_vals)
  590. if self.iban:
  591. self.env["res.partner.bank"].create(
  592. {"partner_id": partner.id, "acc_number": self.iban}
  593. )
  594. return partner
  595. def set_membership(self):
  596. # To be overridden
  597. return True
  598. @api.multi
  599. def validate_subscription_request(self):
  600. self.ensure_one()
  601. # todo rename to validate (careful with iwp dependencies)
  602. partner_obj = self.env["res.partner"]
  603. if self.ordered_parts <= 0:
  604. raise UserError(_("Number of share must be greater than 0."))
  605. if self.partner_id:
  606. partner = self.partner_id
  607. else:
  608. partner = None
  609. domain = []
  610. if self.already_cooperator:
  611. raise UserError(
  612. _(
  613. "The checkbox already cooperator is"
  614. " checked please select a cooperator."
  615. )
  616. )
  617. elif self.is_company and self.company_register_number:
  618. domain = [
  619. (
  620. "company_register_number",
  621. "=",
  622. self.company_register_number,
  623. )
  624. ] # noqa
  625. elif not self.is_company and self.email:
  626. domain = [("email", "=", self.email)]
  627. if domain:
  628. partner = partner_obj.search(domain)
  629. if not partner:
  630. partner = self.create_coop_partner()
  631. self.partner_id = partner
  632. else:
  633. partner = partner[0]
  634. partner.cooperator = True
  635. if self.is_company and not partner.has_representative():
  636. contact = False
  637. if self.email:
  638. domain = [("email", "=", self.email)]
  639. contact = partner_obj.search(domain)
  640. if contact:
  641. contact.type = "representative"
  642. if not contact:
  643. contact_vals = self.get_representative_vals()
  644. partner_obj.create(contact_vals)
  645. else:
  646. if len(contact) > 1:
  647. raise UserError(
  648. _(
  649. "There is two different persons with the"
  650. " same national register number. Please"
  651. " proceed to a merge before to continue"
  652. )
  653. )
  654. if contact.parent_id and contact.parent_id.id != partner.id:
  655. raise UserError(
  656. _(
  657. "This contact person is already defined"
  658. " for another company. Please select"
  659. " another contact"
  660. )
  661. )
  662. else:
  663. contact.write(
  664. {"parent_id": partner.id, "representative": True}
  665. )
  666. invoice = self.create_invoice(partner)
  667. self.write({"state": "done"})
  668. self.set_membership()
  669. return invoice
  670. @api.multi
  671. def block_subscription_request(self):
  672. self.ensure_one()
  673. self.write({"state": "block"})
  674. @api.multi
  675. def unblock_subscription_request(self):
  676. self.ensure_one()
  677. self.write({"state": "draft"})
  678. @api.multi
  679. def cancel_subscription_request(self):
  680. self.ensure_one()
  681. self.write({"state": "cancelled"})
  682. @api.multi
  683. def put_on_waiting_list(self):
  684. self.ensure_one()
  685. waiting_list_mail_template = self.env.ref(
  686. "easy_my_coop.email_template_waiting_list", False
  687. )
  688. waiting_list_mail_template.send_mail(self.id, True)
  689. self.write({"state": "waiting"})
  690. # todo move to share_line.py
  691. class ShareLine(models.Model):
  692. _name = "share.line"
  693. _description = "Share line"
  694. @api.multi
  695. def _compute_total_line(self):
  696. res = {}
  697. for line in self:
  698. line.total_amount_line = line.share_unit_price * line.share_number
  699. return res
  700. share_product_id = fields.Many2one(
  701. "product.product", string="Share type", required=True, readonly=True
  702. )
  703. share_number = fields.Integer(
  704. string="Number of Share", required=True, readonly=True
  705. )
  706. share_short_name = fields.Char(
  707. related="share_product_id.short_name",
  708. string="Share type name",
  709. readonly=True,
  710. )
  711. share_unit_price = fields.Monetary(
  712. string="Share price",
  713. currency_field="company_currency_id",
  714. readonly=True,
  715. )
  716. effective_date = fields.Date(string="Effective Date", readonly=True)
  717. partner_id = fields.Many2one(
  718. "res.partner",
  719. string="Cooperator",
  720. required=True,
  721. ondelete="cascade",
  722. readonly=True,
  723. )
  724. total_amount_line = fields.Monetary(
  725. string="Total amount line",
  726. currency_field="company_currency_id",
  727. compute="_compute_total_line",
  728. )
  729. company_id = fields.Many2one(
  730. "res.company",
  731. string="Company",
  732. required=True,
  733. change_default=True,
  734. readonly=True,
  735. default=lambda self: self.env["res.company"]._company_default_get(),
  736. )
  737. company_currency_id = fields.Many2one(
  738. "res.currency",
  739. string="Company Currency",
  740. related="company_id.currency_id",
  741. readonly=True,
  742. )
  743. # todo move to subscription_register.py
  744. class SubscriptionRegister(models.Model):
  745. _name = "subscription.register"
  746. _description = "Subscription register"
  747. @api.multi
  748. def _compute_total_line(self):
  749. for line in self:
  750. line.total_amount_line = line.share_unit_price * line.quantity
  751. name = fields.Char(string="Number Operation", required=True, readonly=True)
  752. register_number_operation = fields.Integer(
  753. string="Register Number Operation", required=True, readonly=True
  754. )
  755. partner_id = fields.Many2one(
  756. "res.partner", string="Cooperator", required=True, readonly=True
  757. )
  758. partner_id_to = fields.Many2one(
  759. "res.partner", string="Transfered to", readonly=True
  760. )
  761. date = fields.Date(
  762. string="Subscription Date", required=True, readonly=True
  763. )
  764. quantity = fields.Integer(string="Number of share", readonly=True)
  765. share_unit_price = fields.Monetary(
  766. string="Share price",
  767. currency_field="company_currency_id",
  768. readonly=True,
  769. )
  770. total_amount_line = fields.Monetary(
  771. string="Total amount line",
  772. currency_field="company_currency_id",
  773. compute="_compute_total_line",
  774. )
  775. share_product_id = fields.Many2one(
  776. "product.product",
  777. string="Share type",
  778. required=True,
  779. readonly=True,
  780. domain=[("is_share", "=", True)],
  781. )
  782. share_short_name = fields.Char(
  783. related="share_product_id.short_name",
  784. string="Share type name",
  785. readonly=True,
  786. )
  787. share_to_product_id = fields.Many2one(
  788. "product.product",
  789. string="Share to type",
  790. readonly=True,
  791. domain=[("is_share", "=", True)],
  792. )
  793. share_to_short_name = fields.Char(
  794. related="share_to_product_id.short_name",
  795. string="Share to type name",
  796. readonly=True,
  797. )
  798. quantity_to = fields.Integer(string="Number of share to", readonly=True)
  799. share_to_unit_price = fields.Monetary(
  800. string="Share to price",
  801. currency_field="company_currency_id",
  802. readonly=True,
  803. )
  804. type = fields.Selection(
  805. [
  806. ("subscription", "Subscription"),
  807. ("transfer", "Transfer"),
  808. ("sell_back", "Sell Back"),
  809. ("convert", "Conversion"),
  810. ],
  811. string="Operation Type",
  812. readonly=True,
  813. )
  814. company_id = fields.Many2one(
  815. "res.company",
  816. string="Company",
  817. required=True,
  818. change_default=True,
  819. readonly=True,
  820. default=lambda self: self.env["res.company"]._company_default_get(),
  821. )
  822. company_currency_id = fields.Many2one(
  823. "res.currency",
  824. related="company_id.currency_id",
  825. string="Company Currency",
  826. readonly=True,
  827. )
  828. user_id = fields.Many2one(
  829. "res.users",
  830. string="Responsible",
  831. readonly=True,
  832. default=lambda self: self.env.user,
  833. )
  834. _order = "register_number_operation asc"
  835. @api.model
  836. def read_group(
  837. self,
  838. domain,
  839. fields,
  840. groupby,
  841. offset=0,
  842. limit=None,
  843. orderby=False,
  844. lazy=True,
  845. ):
  846. if "share_unit_price" in fields:
  847. fields.remove("share_unit_price")
  848. if "register_number_operation" in fields:
  849. fields.remove("register_number_operation")
  850. res = super(SubscriptionRegister, self).read_group(
  851. domain,
  852. fields,
  853. groupby,
  854. offset=offset,
  855. limit=limit,
  856. orderby=orderby,
  857. lazy=lazy,
  858. )
  859. if "total_amount_line" in fields:
  860. for line in res:
  861. if "__domain" in line:
  862. lines = self.search(line["__domain"])
  863. inv_value = 0.0
  864. for line2 in lines:
  865. inv_value += line2.total_amount_line
  866. line["total_amount_line"] = inv_value
  867. return res