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.

213 lines
7.7 KiB

  1. from __future__ import division
  2. from datetime import datetime
  3. import openerp.addons.decimal_precision as dp
  4. from openerp import api, fields, models
  5. class DividendYear(models.Model):
  6. _name = "dividend.year"
  7. @api.multi
  8. def _compute_dividend_info(self):
  9. res = {}
  10. for dividend in self:
  11. res[dividend.id] = {
  12. "grand_total_dividend": 0.0,
  13. "grand_total_taxes": 0.0,
  14. }
  15. for line in dividend.dividend_ids:
  16. res[dividend.id][
  17. "grand_total_dividend"
  18. ] += line.dividend_amount
  19. res[dividend.id]["grand_total_taxes"] += line.dividend_taxes
  20. return res
  21. name = fields.Char(string="Code")
  22. date_from = fields.Date(string="Date from")
  23. date_to = fields.Date(string="Date to")
  24. # fiscal_year_id = fields.Many2one('account.fiscalyear',
  25. # string='Fiscal year')
  26. percentage = fields.Float(string="Percentage")
  27. withholding_tax = fields.Float(string="Withholding tax")
  28. detailed_dividend_ids = fields.One2many(
  29. "detailed.dividend.line", "dividend_year_id", string="Dividend lines"
  30. )
  31. dividend_ids = fields.One2many(
  32. "dividend.line", "dividend_year_id", string="Dividend lines"
  33. )
  34. grand_total_dividend = fields.Float(
  35. compute=_compute_dividend_info,
  36. string="Grand total dividend",
  37. digits_compute=dp.get_precision("Account"),
  38. )
  39. grand_total_taxes = fields.Float(
  40. compute=_compute_dividend_info,
  41. string="Grand total taxes",
  42. digits_compute=dp.get_precision("Account"),
  43. )
  44. @api.multi
  45. def compute_dividend(self):
  46. self.ensure_one()
  47. det_div_line_obj = self.env["detailed.dividend.line"]
  48. div_line_obj = self.env["dividend.line"]
  49. res_partner_obj = self.env["res.partner"]
  50. # delete lines if any
  51. detailed_dividend_ids = det_div_line_obj.search(
  52. [("dividend_year_id", "=", self.id)]
  53. )
  54. detailed_dividend_ids.unlink()
  55. dividend_ids = div_line_obj.search(
  56. [("dividend_year_id", "=", self.id)]
  57. )
  58. dividend_ids.unlink()
  59. partner_ids = res_partner_obj.search(
  60. [("cooperator", "=", True), ("member", "=", True)],
  61. order="cooperator_register_number",
  62. )
  63. number_of_days = (
  64. datetime.strptime(self.date_to, "%Y-%m-%d")
  65. - datetime.strptime(self.date_from, "%Y-%m-%d")
  66. ).days + 1
  67. for partner in partner_ids:
  68. total_amount_dividend = 0.0
  69. for line in partner.share_ids:
  70. vals = {}
  71. vals2 = {}
  72. line_id = False
  73. if (
  74. line.effective_date >= self.date_from
  75. and line.effective_date <= self.date_to
  76. ):
  77. date_res = (
  78. datetime.strptime(self.date_to, "%Y-%m-%d")
  79. - datetime.strptime(line.effective_date, "%Y-%m-%d")
  80. ).days
  81. coeff = (date_res / number_of_days) * self.percentage
  82. dividend_amount = line.total_amount_line * coeff
  83. vals["days"] = date_res
  84. vals["dividend_year_id"] = self.id
  85. vals[
  86. "coop_number"
  87. ] = line.partner_id.cooperator_register_number
  88. vals["partner_id"] = partner.id
  89. vals["share_line_id"] = line.id
  90. vals["coeff"] = coeff
  91. vals["dividend_amount"] = dividend_amount
  92. total_amount_dividend += dividend_amount
  93. line_id = det_div_line_obj.create(vals)
  94. elif line.effective_date < self.date_from:
  95. dividend_amount = line.total_amount_line * self.percentage
  96. vals["days"] = number_of_days
  97. vals["dividend_year_id"] = self.id
  98. vals[
  99. "coop_number"
  100. ] = line.partner_id.cooperator_register_number
  101. vals["partner_id"] = partner.id
  102. vals["share_line_id"] = line.id
  103. vals["coeff"] = self.percentage
  104. vals["dividend_amount"] = dividend_amount
  105. total_amount_dividend += dividend_amount
  106. line_id = det_div_line_obj.create(vals)
  107. if line_id:
  108. vals2[
  109. "coop_number"
  110. ] = line.partner_id.cooperator_register_number
  111. vals2["dividend_year_id"] = self.id
  112. vals2["partner_id"] = line.partner_id.id
  113. vals2["dividend_amount_net"] = total_amount_dividend
  114. vals2["dividend_amount"] = total_amount_dividend
  115. # TODO set as a parameter on dividend year object
  116. if total_amount_dividend <= 190.00:
  117. vals2["dividend_taxes"] = 0.0
  118. else:
  119. div_tax = (
  120. total_amount_dividend - 190
  121. ) * self.withholding_tax
  122. vals2["dividend_taxes"] = div_tax
  123. vals2["dividend_amount_net"] = (
  124. total_amount_dividend - div_tax
  125. )
  126. div_line_obj.create(vals2)
  127. return True
  128. class DetailedDividendLine(models.Model):
  129. _name = "detailed.dividend.line"
  130. @api.multi
  131. def _compute_total_line(self):
  132. res = {}
  133. for line in self:
  134. res[line.id] = line.share_unit_price * line.share_number
  135. return res
  136. dividend_year_id = fields.Many2one("dividend.year", string="Dividend year")
  137. coop_number = fields.Integer(string="Cooperator Number")
  138. days = fields.Integer(string="Days")
  139. partner_id = fields.Many2one(
  140. "res.partner", string="Cooperator", readonly=True
  141. )
  142. share_line_id = fields.Many2one(
  143. "share.line", string="Share line", readonly=True
  144. )
  145. share_number = fields.Integer(
  146. related="share_line_id.share_number", string="Number of Share"
  147. )
  148. share_unit_price = fields.Monetary(
  149. string="Share unit price", related="share_line_id.share_unit_price"
  150. )
  151. effective_date = fields.Date(
  152. related="share_line_id.effective_date", string="Effective date"
  153. )
  154. total_amount_line = fields.Monetary(
  155. string="Total value of share",
  156. currency_field="company_currency_id",
  157. compute=_compute_total_line,
  158. readonly=True,
  159. )
  160. coeff = fields.Float(string="Coefficient to apply", digits=(2, 4))
  161. dividend_amount = fields.Float(string="Gross Dividend")
  162. dividend_amount_net = fields.Float(string="Dividend net")
  163. dividend_taxes = fields.Float(string="Taxes")
  164. company_currency_id = fields.Many2one(
  165. related="share_line_id.company_currency_id", readonly=True
  166. )
  167. class DividendLine(models.Model):
  168. _name = "dividend.line"
  169. @api.multi
  170. def _get_account_number(self):
  171. res = {}
  172. for line in self:
  173. bank_accounts = self.env["res.partner.bank"].search(
  174. [("partner_id", "=", line.partner_id.id)]
  175. )
  176. res[line.id] = bank_accounts[0].acc_number
  177. return res
  178. coop_number = fields.Integer(string="Coop Number")
  179. dividend_year_id = fields.Many2one("dividend.year", string="Dividend year")
  180. partner_id = fields.Many2one(
  181. "res.partner", string="Cooperator", readonly=True
  182. )
  183. account_number = fields.Char(
  184. compute=_get_account_number, string="Account Number"
  185. )
  186. dividend_amount = fields.Float(string="Gross Dividend")
  187. dividend_amount_net = fields.Float(string="Dividend net")
  188. dividend_taxes = fields.Float(string="Taxes")