account_loan.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. # -*- coding: utf-8 -*-
  2. from openerp import models, fields, tools, api
  3. import openerp.addons.decimal_precision as dp
  4. from datetime import datetime
  5. from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
  6. from pytz import timezone
  7. from datetime import datetime, timedelta
  8. import logging
  9. _logger = logging.getLogger(__name__)
  10. class accountLoan(models.Model):
  11. _name = 'account.loan'
  12. name = fields.Char('name',readonly='readonly')
  13. date = fields.Date('Date', help="Fecha de operación",required=True)
  14. comment = fields.Text('Comment', help="Información adicional")
  15. state = fields.Selection([('rejected','Rechazado'),('draft','Borrador'),('approved','Aprobado'), ('disbursed','Desembolsado'),('paid','Pagado')],'Estado del préstamo', default="draft", help="Estado del préstamo")
  16. amount = fields.Float('Loan amount', digits_compute=dp.get_precision('Account'), required=True, help="Monto del préstamo")
  17. ''' Cliente '''
  18. customer_id = fields.Many2one('res.partner', string="customer", required=True)
  19. ''' Palzo de pagos en cantidad '''
  20. loan_term = fields.Integer('loan term', help="Plazo del préstamo", required=True)
  21. ''' Line '''
  22. lines_ids = fields.One2many('account.loan.line', 'loan_id', string='loan line')
  23. ''' Fecha de vencimiento de la primera cuota '''
  24. date_init = fields.Date('Vencimiento 1° cuota', help="Fecha de vencimiento de la primera cuota")
  25. ''' Sistema de calculo del prestamos (Francés - Alemán)'''
  26. # loan_system = (help="Sistema de calculo del prestamos (Francés - Alemán)")
  27. ''' Tipo de plazo del prestamos (Días, Semana , Mes, Año) '''
  28. # loan_type = fields.Many2one('account.loan.type', string='Tipo de préstamo', ondelete='restrict', index=True, required=True, help="Tipo de plazo del prestamos (Días-Semana-Mes)")
  29. '''
  30. Create
  31. '''
  32. @api.model
  33. def create(self, vals):
  34. loan = super(accountLoan, self).create(vals)
  35. loan.write({'name':("PRESTAMO/%06d" % (int(loan.id)))})
  36. return loan
  37. '''
  38. timezone
  39. '''
  40. def get_timezone(self):
  41. return timezone(self._context.get('tz') or self.env.user.tz)
  42. '''
  43. Datetime
  44. '''
  45. def get_datetime(self):
  46. return datetime.now(self.get_timezone()).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
  47. '''
  48. Date
  49. '''
  50. def get_date(self):
  51. return datetime.now(self.get_timezone()).strftime(DEFAULT_SERVER_DATE_FORMAT)
  52. '''
  53. Convert Str --> Datetime
  54. '''
  55. def _convert_str_to_datetime(self, date):
  56. return datetime.strptime(date,DEFAULT_SERVER_DATE_FORMAT)
  57. '''
  58. Unlink Line
  59. '''
  60. def unlink_loan_line(self,line):
  61. return line.unlink()
  62. '''
  63. Generar los calculos
  64. '''
  65. @api.multi
  66. def calculate_loan(self):
  67. _logger.info('Calculando prestamos')
  68. '''Tipo de prestamos '''
  69. loanType = self.env['account.loan.type'].search([('id', '=', self.loan_type.id),('active', '=', True)])
  70. if (not loanType):
  71. return False
  72. ''' Systema de calculo '''
  73. loanSystem = self.env['account.loan.system'].browse(self.loan_system.id)
  74. if (not loanSystem):
  75. return False
  76. self.unlink_loan_line(self.lines_ids)
  77. amountLoan = float(self.amount)
  78. plazo = self.loan_term
  79. rateDivision = loanType.rate_division
  80. interestYear = loanType.interest_rate_year
  81. interestRate = float(loanType.interest_rate /100)
  82. expirationDays = loanType.expiration_days
  83. days = timedelta(days=expirationDays)
  84. dateServer = self._convert_str_to_datetime(self.get_date())
  85. if (self.date_init):
  86. dateServer = self._convert_str_to_datetime(self.date_init)
  87. if (loanSystem.code =='FRANCES'):
  88. _logger.info('Sistema Frances')
  89. ## Calcular cuota
  90. cuota = ((interestRate * amountLoan) / (1 - (1 / ( 1 + interestRate )) ** plazo))
  91. cont = 0
  92. amortizado = 0
  93. for cc in xrange(plazo):
  94. loanLine =[]
  95. interesCuota = 0.00
  96. amort = 0.0
  97. cont +=1
  98. interesCuota = amountLoan * interestRate
  99. amort = cuota - interesCuota
  100. amortizado += amort
  101. loanLine = {
  102. 'loan_id': self.id,
  103. 'number': cont,
  104. 'date_maturity': dateServer.strftime(DEFAULT_SERVER_DATE_FORMAT),
  105. 'amount': cuota,
  106. 'amount_interest': interesCuota,
  107. 'amount_amortization': amort,
  108. 'amount_residual': amountLoan - amort,
  109. 'amount_amortized': amortizado
  110. }
  111. if (loanLine):
  112. self.env['account.loan.line'].create(loanLine)
  113. amountLoan -= amort
  114. dateServer = dateServer + days
  115. return True
  116. if (loanSystem.code == 'ALEMAN'):
  117. _logger.info('Sistema Aleman')
  118. ## Calcular la amortizacion
  119. amortizacion = amountLoan / plazo
  120. cont = 0
  121. amortizado = 0.00
  122. for cc in xrange(plazo):
  123. loanLine =[]
  124. interesCuota = 0.00
  125. cuota = 0.00
  126. cont +=1
  127. interesCuota = amountLoan * interestRate
  128. cuota = amortizacion + interesCuota
  129. # amort = cuota - interesCuota
  130. amortizado += amortizacion
  131. loanLine = {
  132. 'loan_id': self.id,
  133. 'number': cont,
  134. 'date_maturity': dateServer.strftime(DEFAULT_SERVER_DATE_FORMAT),
  135. 'amount': cuota,
  136. 'amount_interest': interesCuota,
  137. 'amount_amortization': amortizacion,
  138. 'amount_residual': amountLoan - amortizacion,
  139. 'amount_amortized': amortizado
  140. }
  141. if (loanLine):
  142. self.env['account.loan.line'].create(loanLine)
  143. amountLoan -= amortizacion
  144. dateServer = dateServer + days
  145. return True
  146. class accountLoanLine(models.Model):
  147. _name = 'account.loan.line'
  148. ## Interest
  149. loan_id = fields.Many2one('account.loan', string='Account loan', ondelete='cascade', index=True, required=True)
  150. state = fields.Selection([('open','Abierto'),('invoiced','Facturado'),('paid','Pagado')],'Estado de la cuota', default="open")
  151. number = fields.Integer('N°', help="Numero de cuota")
  152. date_maturity = fields.Date('Vencimiento', help="Fecha de vencimiento")
  153. amount = fields.Float('Cuota', digits_compute=dp.get_precision('Account'), help="Monto de la cuota")
  154. amount_interest = fields.Float('interés', digits_compute=dp.get_precision('Account'), help="Monto del Interes")
  155. amount_amortization = fields.Float('Amortización', digits_compute=dp.get_precision('Account'), help="Amortización = (Cuota – interés)")
  156. amount_residual = fields.Float('Capital', digits_compute=dp.get_precision('Account'), help="Monto Restante")
  157. amount_amortized = fields.Float('Amortizado', digits_compute=dp.get_precision('Account'), help="Total pagados")
  158. invoice = fields.Many2one('account.invoice', string='Invoice Reference', ondelete='restrict', index=True)
  159. reference = fields.Char(string='Invoice Reference', help="Invoice Reference")