# -*- coding: utf-8 -*- from openerp import models, fields, tools, api import openerp.addons.decimal_precision as dp from datetime import datetime from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT from pytz import timezone from datetime import datetime, timedelta import logging _logger = logging.getLogger(__name__) class accountLoan(models.Model): _name = 'account.loan' name = fields.Char('name',readonly='readonly') date = fields.Date('Date', help="Fecha de operación",required=True) comment = fields.Text('Comment', help="Información adicional") state = fields.Selection([('rejected','Rechazado'),('draft','Borrador'),('approved','Aprobado'), ('disbursed','Desembolsado'),('paid','Pagado')],'Estado del préstamo', default="draft", help="Estado del préstamo") amount = fields.Float('Loan amount', digits_compute=dp.get_precision('Account'), required=True, help="Monto del préstamo") ''' Cliente ''' customer_id = fields.Many2one('res.partner', string="customer", required=True) ''' Palzo de pagos en cantidad ''' loan_term = fields.Integer('loan term', help="Plazo del préstamo", required=True) ''' Line ''' lines_ids = fields.One2many('account.loan.line', 'loan_id', string='loan line') ''' Fecha de vencimiento de la primera cuota ''' date_init = fields.Date('Vencimiento 1° cuota', help="Fecha de vencimiento de la primera cuota") ''' Sistema de calculo del prestamos (Francés - Alemán)''' # loan_system = (help="Sistema de calculo del prestamos (Francés - Alemán)") ''' Tipo de plazo del prestamos (Días, Semana , Mes, Año) ''' # 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)") ''' Create ''' @api.model def create(self, vals): loan = super(accountLoan, self).create(vals) loan.write({'name':("PRESTAMO/%06d" % (int(loan.id)))}) return loan ''' timezone ''' def get_timezone(self): return timezone(self._context.get('tz') or self.env.user.tz) ''' Datetime ''' def get_datetime(self): return datetime.now(self.get_timezone()).strftime(DEFAULT_SERVER_DATETIME_FORMAT) ''' Date ''' def get_date(self): return datetime.now(self.get_timezone()).strftime(DEFAULT_SERVER_DATE_FORMAT) ''' Convert Str --> Datetime ''' def _convert_str_to_datetime(self, date): return datetime.strptime(date,DEFAULT_SERVER_DATE_FORMAT) ''' Unlink Line ''' def unlink_loan_line(self,line): return line.unlink() ''' Generar los calculos ''' @api.multi def calculate_loan(self): _logger.info('Calculando prestamos') '''Tipo de prestamos ''' loanType = self.env['account.loan.type'].search([('id', '=', self.loan_type.id),('active', '=', True)]) if (not loanType): return False ''' Systema de calculo ''' loanSystem = self.env['account.loan.system'].browse(self.loan_system.id) if (not loanSystem): return False self.unlink_loan_line(self.lines_ids) amountLoan = float(self.amount) plazo = self.loan_term rateDivision = loanType.rate_division interestYear = loanType.interest_rate_year interestRate = float(loanType.interest_rate /100) expirationDays = loanType.expiration_days days = timedelta(days=expirationDays) dateServer = self._convert_str_to_datetime(self.get_date()) if (self.date_init): dateServer = self._convert_str_to_datetime(self.date_init) if (loanSystem.code =='FRANCES'): _logger.info('Sistema Frances') ## Calcular cuota cuota = ((interestRate * amountLoan) / (1 - (1 / ( 1 + interestRate )) ** plazo)) cont = 0 amortizado = 0 for cc in xrange(plazo): loanLine =[] interesCuota = 0.00 amort = 0.0 cont +=1 interesCuota = amountLoan * interestRate amort = cuota - interesCuota amortizado += amort loanLine = { 'loan_id': self.id, 'number': cont, 'date_maturity': dateServer.strftime(DEFAULT_SERVER_DATE_FORMAT), 'amount': cuota, 'amount_interest': interesCuota, 'amount_amortization': amort, 'amount_residual': amountLoan - amort, 'amount_amortized': amortizado } if (loanLine): self.env['account.loan.line'].create(loanLine) amountLoan -= amort dateServer = dateServer + days return True if (loanSystem.code == 'ALEMAN'): _logger.info('Sistema Aleman') ## Calcular la amortizacion amortizacion = amountLoan / plazo cont = 0 amortizado = 0.00 for cc in xrange(plazo): loanLine =[] interesCuota = 0.00 cuota = 0.00 cont +=1 interesCuota = amountLoan * interestRate cuota = amortizacion + interesCuota # amort = cuota - interesCuota amortizado += amortizacion loanLine = { 'loan_id': self.id, 'number': cont, 'date_maturity': dateServer.strftime(DEFAULT_SERVER_DATE_FORMAT), 'amount': cuota, 'amount_interest': interesCuota, 'amount_amortization': amortizacion, 'amount_residual': amountLoan - amortizacion, 'amount_amortized': amortizado } if (loanLine): self.env['account.loan.line'].create(loanLine) amountLoan -= amortizacion dateServer = dateServer + days return True class accountLoanLine(models.Model): _name = 'account.loan.line' ## Interest loan_id = fields.Many2one('account.loan', string='Account loan', ondelete='cascade', index=True, required=True) state = fields.Selection([('open','Abierto'),('invoiced','Facturado'),('paid','Pagado')],'Estado de la cuota', default="open") number = fields.Integer('N°', help="Numero de cuota") date_maturity = fields.Date('Vencimiento', help="Fecha de vencimiento") amount = fields.Float('Cuota', digits_compute=dp.get_precision('Account'), help="Monto de la cuota") amount_interest = fields.Float('interés', digits_compute=dp.get_precision('Account'), help="Monto del Interes") amount_amortization = fields.Float('Amortización', digits_compute=dp.get_precision('Account'), help="Amortización = (Cuota – interés)") amount_residual = fields.Float('Capital', digits_compute=dp.get_precision('Account'), help="Monto Restante") amount_amortized = fields.Float('Amortizado', digits_compute=dp.get_precision('Account'), help="Total pagados") invoice = fields.Many2one('account.invoice', string='Invoice Reference', ondelete='restrict', index=True) reference = fields.Char(string='Invoice Reference', help="Invoice Reference")