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.

255 lines
15 KiB

  1. # -*- coding: utf-8 -*-
  2. import base64
  3. from datetime import datetime
  4. from openerp import api, fields, models, _
  5. TYPE_MAP = {
  6. 'subscription':'subscribed',
  7. 'transfer':'transfered',
  8. 'sell_back':'resold'
  9. }
  10. REPORT_DIC = {'subscription':('easy_my_coop_taxshelter_report.tax_shelter_subscription_report','Tax Shelter Subscription'),
  11. 'shares':('easy_my_coop_taxshelter_report.tax_shelter_shares_report','Tax Shelter Shares')}
  12. class TaxShelterDeclaration(models.Model):
  13. _name = "tax.shelter.declaration"
  14. name = fields.Char(string='Declaration year', required=True)
  15. fiscal_year = fields.Char(String="Fiscal year", required=True)
  16. tax_shelter_certificates = fields.One2many('tax.shelter.certificate','declaration_id', string='Tax shelter certificates', readonly=True)
  17. date_from = fields.Date(string='Date from', required=True)
  18. date_to = fields.Date(string='Date to', required=True)
  19. month_from = fields.Char(String='Month from', required=True)
  20. month_to = fields.Char(String='Month to', required=True)
  21. tax_shelter_percentage = fields.Selection([('30','30%'),
  22. ('45','45%')],
  23. string='Tax Shelter percentage', required=True)
  24. state = fields.Selection([('draft','Draft'),
  25. ('computed','Computed'),
  26. ('validated','Validated')],
  27. string='State',required=True, default="draft")
  28. company_id = fields.Many2one('res.company', string='Company', required=True,
  29. change_default=True, readonly=True,
  30. default=lambda self: self.env['res.company']._company_default_get())
  31. tax_shelter_capital_limit = fields.Float(string="Tax shelter capital limit", required=True)
  32. previously_subscribed_capital = fields.Float(String="Capital previously subscribed", readonly=True)
  33. def _prepare_line(self, certificate, entry, ongoing_capital_sub):
  34. line_vals = {}
  35. line_vals['tax_shelter_certificate'] = certificate.id
  36. line_vals['share_type'] = entry.share_product_id.id
  37. line_vals['share_short_name'] = entry.share_short_name
  38. line_vals['share_unit_price'] = entry.share_unit_price
  39. line_vals['quantity'] = entry.quantity
  40. line_vals['transaction_date'] = entry.date
  41. line_vals['type'] = TYPE_MAP[entry.type]
  42. if entry.type == 'subscription':
  43. capital_after_sub = ongoing_capital_sub + entry.total_amount_line
  44. line_vals['capital_before_sub'] = ongoing_capital_sub
  45. line_vals['capital_after_sub'] = capital_after_sub
  46. line_vals['capital_limit'] = self.tax_shelter_capital_limit
  47. if ongoing_capital_sub <= self.tax_shelter_capital_limit:
  48. line_vals['tax_shelter'] = True
  49. return line_vals
  50. def _compute_certificates(self,entries,partner_certificate):
  51. ongoing_capital_sub = 0.0
  52. for entry in entries:
  53. certificate = partner_certificate.get(entry.partner_id.id, False)
  54. if not certificate:
  55. #create a certificate for this cooperator
  56. cert_vals={}
  57. cert_vals['declaration_id'] = self.id
  58. cert_vals['partner_id'] = entry.partner_id.id
  59. cert_vals['cooperator_number'] = entry.partner_id.cooperator_register_number
  60. certificate = self.env['tax.shelter.certificate'].create(cert_vals)
  61. partner_certificate[entry.partner_id.id] = certificate
  62. line_vals = self._prepare_line(certificate, entry, ongoing_capital_sub)
  63. certificate.write({'lines': [(0, 0, line_vals)]})
  64. #if entry.type == 'subscription' and entry.date >= self.date_from:
  65. ongoing_capital_sub += entry.total_amount_line
  66. return partner_certificate
  67. @api.one
  68. def compute_declaration(self):
  69. entries = self.env['subscription.register'].search([('partner_id.is_company','=',False),
  70. ('date','<=',self.date_to),
  71. ('type','in',['subscription','sell_back','transfer'])])
  72. subscriptions = entries.filtered((lambda r: r.type == 'subscription' and r.date < self.date_from))
  73. cap_prev_sub = 0.0
  74. for subscription in subscriptions:
  75. cap_prev_sub += subscription.total_amount_line
  76. self.previously_subscribed_capital = cap_prev_sub
  77. partner_certificate = {}
  78. partner_certificate = self._compute_certificates(entries, partner_certificate)
  79. self.state = 'computed'
  80. @api.one
  81. def validate_declaration(self):
  82. self.tax_shelter_certificates.write({'state':'validated'})
  83. self.state = 'validated'
  84. @api.one
  85. def reset_declaration(self):
  86. if not self.state == 'validated':
  87. certificate_ids = self.tax_shelter_certificates.ids
  88. self.tax_shelter_certificates.unlink()
  89. self.state = 'draft'
  90. class TaxShelterCertificate(models.Model):
  91. _name = "tax.shelter.certificate"
  92. _order = "cooperator_number asc"
  93. cooperator_number = fields.Integer(string='Cooperator number', required=True, readonly=True)
  94. partner_id = fields.Many2one('res.partner', string='Cooperator', required=True, readonly=True)
  95. state = fields.Selection([('draft','Draft'),
  96. ('validated','Validated'),
  97. ('sent','Sent')],
  98. string='State',required=True, default="draft")
  99. declaration_id = fields.Many2one('tax.shelter.declaration', string='Declaration', required=True, readonly=True)
  100. lines = fields.One2many('certificate.line','tax_shelter_certificate', string='Certificate lines', readonly=True)
  101. previously_subscribed_lines = fields.One2many(compute='_compute_certificate_lines', comodel_name='certificate.line', string='Previously Subscribed lines', readonly=True)
  102. subscribed_lines = fields.One2many(compute='_compute_certificate_lines', comodel_name='certificate.line', string='Shares subscribed', readonly=True)
  103. resold_lines = fields.One2many(compute='_compute_certificate_lines', comodel_name='certificate.line', string='Shares resold', readonly=True)
  104. transfered_lines = fields.One2many(compute='_compute_certificate_lines', comodel_name='certificate.line', string='Shares transfered', readonly=True)
  105. total_amount_previously_subscribed = fields.Float(compute='_compute_amounts', string='Total previously subscribed')
  106. total_amount_subscribed = fields.Float(compute='_compute_amounts', string='Total subscribed')
  107. total_amount_eligible = fields.Float(compute='_compute_amounts', string='Total amount eligible To Tax shelter')
  108. total_amount_resold = fields.Float(compute='_compute_amounts', string='Total resold')
  109. total_amount_transfered = fields.Float(compute='_compute_amounts', string='Total transfered')
  110. total_amount = fields.Float(compute='_compute_amounts', string='Total', readonly=True)
  111. company_id = fields.Many2one(related="declaration_id.company_id", string="Company")
  112. def generate_pdf_report(self,report_type):
  113. report_action, name = REPORT_DIC[report_type]
  114. report = self.env['report'].get_pdf(self, report_action)
  115. report = base64.b64encode(report)
  116. report_name = self.partner_id.name + ' ' + name + ' ' + self.declaration_id.name + '.pdf'
  117. return (report_name, report)
  118. def generate_certificates_report(self):
  119. attachments = []
  120. if self.total_amount_eligible > 0:
  121. #if self.total_amount_resold == 0 and self.total_amount_transfered == 0:
  122. attachments.append(self.generate_pdf_report('subscription'))
  123. if self.partner_id.total_value > 0:
  124. attachments.append(self.generate_pdf_report('shares'))
  125. #if self.total_amount_resold > 0 or self.total_amount_transfered > 0:
  126. # TODO
  127. return attachments
  128. @api.multi
  129. def send_certificates(self):
  130. tax_shelter_mail_template = self.env.ref('easy_my_coop_taxshelter_report.email_template_tax_shelter_certificate', False)
  131. for certificate in self:
  132. attachments = certificate.generate_certificates_report()
  133. if len(attachments) > 0:
  134. tax_shelter_mail_template.send_mail_with_multiple_attachments(certificate.id, attachments,True)
  135. certificate.state = 'sent'
  136. self.env.cr.commit()
  137. @api.multi
  138. def print_subscription_certificate(self):
  139. self.ensure_one()
  140. return self.env['report'].get_action(self, 'easy_my_coop_taxshelter_report.tax_shelter_subscription_report')
  141. @api.multi
  142. def print_shares_certificate(self):
  143. self.ensure_one()
  144. return self.env['report'].get_action(self, 'easy_my_coop_taxshelter_report.tax_shelter_shares_report')
  145. @api.multi
  146. def _compute_amounts(self):
  147. for certificate in self:
  148. total_amount_previously_subscribed = 0
  149. total_amount_subscribed = 0
  150. total_amount_elligible = 0
  151. total_amount_transfered = 0
  152. total_amount_resold = 0
  153. for line in certificate.subscribed_lines:
  154. total_amount_subscribed += line.amount_subscribed
  155. certificate.total_amount_subscribed = total_amount_subscribed
  156. for line in certificate.subscribed_lines:
  157. total_amount_elligible += line.amount_subscribed_eligible
  158. certificate.total_amount_eligible = total_amount_elligible
  159. for line in certificate.previously_subscribed_lines:
  160. total_amount_previously_subscribed += line.amount_subscribed
  161. certificate.total_amount_previously_subscribed = total_amount_previously_subscribed
  162. for line in certificate.transfered_lines:
  163. total_amount_transfered += line.amount_transfered
  164. certificate.total_amount_transfered = total_amount_transfered
  165. for line in certificate.resold_lines:
  166. total_amount_resold += line.amount_resold
  167. certificate.total_amount_resold = total_amount_resold
  168. certificate.total_amount = certificate.total_amount_previously_subscribed + certificate.total_amount_subscribed + certificate.total_amount_resold + certificate.total_amount_transfered
  169. @api.multi
  170. def _compute_certificate_lines(self):
  171. for certificate in self:
  172. certificate.previously_subscribed_lines = certificate.lines.filtered(lambda r: r.type == 'subscribed' and r.transaction_date < certificate.declaration_id.date_from)
  173. certificate.subscribed_lines = certificate.lines.filtered(lambda r: r.type == 'subscribed' and r.transaction_date >= certificate.declaration_id.date_from and r.transaction_date <= certificate.declaration_id.date_to)
  174. certificate.resold_lines = certificate.lines.filtered(lambda r: r.type == 'resold' and r.transaction_date >= certificate.declaration_id.date_from and r.transaction_date <= certificate.declaration_id.date_to)
  175. certificate.transfered_lines = certificate.lines.filtered(lambda r: r.type == 'transfered' and r.transaction_date >= certificate.declaration_id.date_from and r.transaction_date <= certificate.declaration_id.date_to)
  176. @api.model
  177. def batch_send_tax_shelter_certificate(self):
  178. certificates = self.search([('state','=','validated')],limit=80)
  179. certificates.send_certificates()
  180. class TaxShelterCertificateLine(models.Model):
  181. _name= "certificate.line"
  182. declaration_id = fields.Many2one(related='tax_shelter_certificate.declaration_id', string="Declaration")
  183. tax_shelter_certificate = fields.Many2one('tax.shelter.certificate', string="Tax shelter certificate", ondelete='cascade', required=True)
  184. share_type = fields.Many2one('product.product', string='Share type', required=True, readonly=True)
  185. share_unit_price = fields.Float(string='Share price', required=True, readonly=True)
  186. quantity = fields.Integer(string='Number of shares', required=True, readonly=True)
  187. transaction_date = fields.Date(string="Transaction date")
  188. tax_shelter = fields.Boolean(string="Tax shelter eligible", readonly=True)
  189. type = fields.Selection([('subscribed','Subscribed'),
  190. ('resold','Resold'),
  191. ('transfered','Transfered'),
  192. ('kept','Kept')], required=True, readonly=True)
  193. amount_subscribed = fields.Float(compute='_compute_totals', string='Amount subscribed',store=True)
  194. amount_subscribed_eligible = fields.Float(compute='_compute_totals', string='Amount subscribed eligible',store=True)
  195. amount_resold = fields.Float(compute='_compute_totals', string='Amount resold',store=True)
  196. amount_transfered = fields.Float(compute='_compute_totals', string='Amount transfered',store=True)
  197. share_short_name = fields.Char(string='Share type name', readonly=True)
  198. capital_before_sub = fields.Float(string="Capital before subscription", readonly=True)
  199. capital_after_sub = fields.Float(string="Capital after subscription", readonly=True)
  200. capital_limit = fields.Float(string="Capital limit", readonly=True)
  201. @api.multi
  202. @api.depends('quantity','share_unit_price')
  203. def _compute_totals(self):
  204. for line in self:
  205. #limit = line.declaration_id.tax_shelter_capital_limit
  206. if line.type == 'subscribed':
  207. line.amount_subscribed = line.share_unit_price * line.quantity
  208. if line.type == 'subscribed' and line.tax_shelter:
  209. if line.capital_before_sub < line.capital_limit and line.capital_after_sub >= line.capital_limit:
  210. line.amount_subscribed_eligible = line.capital_limit - line.capital_before_sub
  211. elif line.capital_before_sub < line.capital_limit and line.capital_after_sub <= line.capital_limit:
  212. line.amount_subscribed_eligible = line.share_unit_price * line.quantity
  213. elif line.capital_before_sub >= line.capital_limit:
  214. line.amount_subscribed_eligible = 0
  215. if line.type == 'resold':
  216. line.amount_resold = line.share_unit_price * -(line.quantity)
  217. if line.type == 'transfered':
  218. line.amount_transfered = line.share_unit_price * -(line.quantity)