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.

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