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.

201 lines
6.6 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. import logging
  5. from odoo import _, api, fields, models
  6. _logger = logging.getLogger(__name__)
  7. class LoanIssue(models.Model):
  8. _name = "loan.issue"
  9. _description = "Loan Issue"
  10. @api.multi
  11. def _compute_subscribed_amount(self):
  12. for issue in self:
  13. susbscribed_amount = 0.0
  14. for line in issue.loan_issue_lines.filtered(
  15. lambda record: record.state != "cancelled"
  16. ):
  17. susbscribed_amount += line.amount
  18. issue.subscribed_amount = susbscribed_amount
  19. name = fields.Char(string="Name", translate=True)
  20. default_issue = fields.Boolean(string="Default issue")
  21. subscription_start_date = fields.Date(
  22. string="Start date subscription period"
  23. )
  24. subscription_end_date = fields.Date(string="End date subscription period")
  25. user_id = fields.Many2one("res.users", string="Responsible")
  26. loan_start_date = fields.Date(string="Loan start date")
  27. term_date = fields.Date(string="Term date")
  28. loan_term = fields.Float(string="Duration of the loan in month")
  29. rate = fields.Float(string="Interest rate")
  30. face_value = fields.Monetary(
  31. string="Facial value",
  32. currency_field="company_currency_id",
  33. required=True,
  34. )
  35. minimum_amount = fields.Monetary(
  36. string="Minimum amount of issue", currency_field="company_currency_id"
  37. )
  38. maximum_amount = fields.Monetary(
  39. string="Maximum amount of issue", currency_field="company_currency_id"
  40. )
  41. min_amount_company = fields.Monetary(
  42. string="Minimum amount for a company",
  43. currency_field="company_currency_id",
  44. )
  45. max_amount_company = fields.Monetary(
  46. string="Maximum amount for a company",
  47. currency_field="company_currency_id",
  48. )
  49. min_amount_person = fields.Monetary(
  50. string="Minimum amount for a person",
  51. currency_field="company_currency_id",
  52. )
  53. max_amount_person = fields.Monetary(
  54. string="Maximum amount for a person",
  55. currency_field="company_currency_id",
  56. )
  57. subscribed_amount = fields.Monetary(
  58. string="Subscribed amount",
  59. compute="_compute_subscribed_amount",
  60. currency_field="company_currency_id",
  61. )
  62. capital_payment = fields.Selection(
  63. [
  64. ("end", "End"),
  65. ("yearly", "Yearly")
  66. ],
  67. string="Capital reimbursement"
  68. )
  69. interest_payment = fields.Selection(
  70. [
  71. ("end", "End"),
  72. ("yearly", "Yearly")
  73. ],
  74. string="Interest payment"
  75. )
  76. interest_payment_info = fields.Char(string="Yearly payment on")
  77. loan_issue_lines = fields.One2many(
  78. "loan.issue.line", "loan_issue_id", string="Loan issue lines"
  79. )
  80. state = fields.Selection(
  81. [
  82. ("draft", "Draft"),
  83. ("confirmed", "Confirmed"),
  84. ("cancelled", "Cancelled"),
  85. ("ongoing", "Ongoing"),
  86. ("closed", "Closed"),
  87. ],
  88. string="State",
  89. default="draft",
  90. )
  91. company_currency_id = fields.Many2one(
  92. "res.currency",
  93. related="company_id.currency_id",
  94. string="Company Currency",
  95. readonly=True,
  96. )
  97. company_id = fields.Many2one(
  98. "res.company",
  99. string="Company",
  100. required=True,
  101. readonly=True,
  102. default=lambda self: self.env["res.company"]._company_default_get(),
  103. ) # noqa
  104. by_company = fields.Boolean(string="By company")
  105. by_individual = fields.Boolean(string="By individuals")
  106. display_on_website = fields.Boolean(sting="Display on website")
  107. taxes_rate = fields.Float(string="Taxes on interest", required=True)
  108. @api.multi
  109. def get_max_amount(self, partner):
  110. """
  111. Return the maximum amount that partner can buy.
  112. A negative value means that there is no maximum.
  113. """
  114. self.ensure_one()
  115. lines = self.loan_issue_lines.filtered(
  116. lambda r: r.partner_id == partner and r.state != "cancelled"
  117. )
  118. already_subscribed = sum(line.amount for line in lines)
  119. max_amount = -1 # No max amount
  120. if partner.is_company and self.max_amount_company > 0:
  121. max_amount = max(0, self.max_amount_company - already_subscribed)
  122. if not partner.is_company and self.max_amount_person > 0:
  123. max_amount = max(0, self.max_amount_person - already_subscribed)
  124. return max_amount
  125. @api.multi
  126. def get_min_amount(self, partner):
  127. """
  128. Return the minimum amount that a partner must buy.
  129. A zero value means that there is no minimum amount.
  130. """
  131. self.ensure_one()
  132. lines = self.loan_issue_lines.filtered(
  133. lambda r: r.partner_id == partner and r.state != "cancelled"
  134. )
  135. amount_subscribed = sum(line.amount for line in lines)
  136. if partner.is_company:
  137. min_amount = self.min_amount_company - amount_subscribed
  138. else:
  139. min_amount = self.min_amount_person - amount_subscribed
  140. return max(0, min_amount)
  141. @api.multi
  142. def get_web_issues(self, is_company):
  143. bond_issues = self.search(
  144. [("display_on_website", "=", True), ("state", "=", "ongoing")]
  145. )
  146. if is_company is True:
  147. return bond_issues.filtered("by_company")
  148. else:
  149. return bond_issues.filtered("by_company")
  150. @api.multi
  151. def action_confirm(self):
  152. self.ensure_one()
  153. self.write({"state": "confirmed"})
  154. @api.multi
  155. def action_open(self):
  156. self.ensure_one()
  157. self.write({"state": "ongoing"})
  158. @api.multi
  159. def action_draft(self):
  160. self.ensure_one()
  161. self.write({"state": "draft"})
  162. @api.multi
  163. def action_cancel(self):
  164. self.ensure_one()
  165. self.write({"state": "cancelled"})
  166. @api.multi
  167. def action_close(self):
  168. self.ensure_one()
  169. self.write({"state": "closed"})
  170. @api.multi
  171. def compute_loan_interest(self):
  172. self.ensure_one()
  173. loan_term_year = self.loan_term / 12
  174. if not (loan_term_year).is_integer():
  175. # TODO Handle this case
  176. raise NotImplementedError(
  177. _(
  178. "Calculation on non entire year "
  179. "hasn't been implemented yet"
  180. )
  181. )
  182. lines = self.loan_issue_lines.filtered(lambda record:
  183. record.state == "paid")
  184. lines.action_compute_interest()