# -*- coding: utf-8 -*- from openerp import models, fields, tools, api, _ ## date from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT from pytz import timezone from datetime import datetime,timedelta ## logging import logging _logger = logging.getLogger(__name__) class ResPartnerInterest(models.Model): _inherit = 'res.partner' @api.model def eiru_account_interest_verify_partner(self, id): partner = self.env['res.partner'].browse(id) partnerIDS = [] if (partner.is_company): partnerIDS= map(lambda x: x.id, partner.child_ids) partnerIDS.append(partner.id) interest = self. env['account.interest'] interest.get_account_invoice_interest(None,partnerIDS) return { 'state': True, 'message': "Verificación de interés terminado", } class AccountInvoiceInterest(models.Model): _inherit = 'account.invoice' @api.model def eiru_account_interest_verify_invoice(self, id): interest = self. env['account.interest'] interest.get_account_invoice_interest(id,None) return { 'state': True, 'message': "Verificación de interés terminado", } class EiruAccountInterest(models.Model): _inherit = 'account.interest' ''' 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) ''' GET Account Interest ''' @api.model def get_account_interest(self, id): return [{ 'id': interest.id, 'name': interest.name, 'state': interest.state, 'invoiceId': interest.invoice_id.id, 'customer': [{ 'id': partner.id, 'name': partner.name, } for partner in self.env['res.partner'].browse(interest.customer_id.id)], 'currency': [{ 'id': currency.id, 'symbol': currency.symbol, 'rate': currency.rate, 'thousandsSeparator': currency.thousands_separator, 'decimalSeparator': currency.decimal_separator, 'decimalPlaces': currency.decimal_places, 'position': currency.position, } for currency in self.env['res.currency'].browse(interest.currency_id.id)] }for interest in self.env['account.interest'].browse(id)] ''' ____ _ ___ _ _ / ___| ___ _ __ ___ _ __ __ _| |_ ___ |_ _|_ __ | |_ ___ _ __ ___ ___| |_ | | _ / _ \ '_ \ / _ \ '__/ _` | __/ _ \ | || '_ \| __/ _ \ '__/ _ \/ __| __| | |_| | __/ | | | __/ | | (_| | || __/ | || | | | || __/ | | __/\__ \ |_ \____|\___|_| |_|\___|_| \__,_|\__\___| |___|_| |_|\__\___|_| \___||___/\__| ''' @api.model def get_account_invoice_interest(self, invoice=None, partner=None): _logger.info('Verify invoice') domain = [('state', '=', 'open'),('is_interest', '=', False),('type', '=', 'out_invoice')] if (invoice): domain.append(('id', '=', invoice)) if (partner): domain.append(('partner_id.id', 'in', partner)) accountInvoice = self.env['account.invoice'].search(domain) for invoice in accountInvoice: self.get_move_line_in_invoice(invoice.id) return True ''' Get move Line. ''' def get_move_line_in_invoice(self, invoice): _logger.info('Get Move Line') accountInvoice = self.env['account.invoice'].browse(invoice) dateServer = self._convert_str_to_datetime(self.get_date()) domain = [('state','!=','draft'), ('credit','<=', 0),('invoice','=',accountInvoice.id)] for line in self.env['account.move.line'].search(domain): if(not line.date_maturity): return False expiredDays = dateServer - self._convert_str_to_datetime(line.date_maturity) expiredDaystot = dateServer - self._convert_str_to_datetime(line.date_maturity) if (line.date_interest): expiredDays = dateServer - self._convert_str_to_datetime(line.date_interest) if ((line.amount_residual <= 0) or (expiredDays.days <= 0)): continue ''' verify account.interest ''' accountInterest = self.eiru_create_account_interest(accountInvoice.id) if (not accountInterest): return {'state': False} ''' verify account.interest.line ''' interrstLine = self.eiru_create_account_interest_lines(accountInvoice.id, accountInterest.id, line.id, expiredDays.days, expiredDaystot.days) if (not interrstLine): return {'state': False} return True ''' Create Account Interest ''' def eiru_create_account_interest(self, invoiceId): _logger.info('Verify account interest') accountInvoice = self.env['account.invoice'].browse(invoiceId) domain = [('invoice_id', '=', accountInvoice.id)] accountInterest = self.env['account.interest'].search(domain) dateServer = self.get_date() if (not accountInterest): accountInterest = self.env['account.interest'].create({ 'invoice_id': accountInvoice.id, 'customer_id': accountInvoice.commercial_partner_id.id if(accountInvoice.commercial_partner_id) else accountInvoice.partner_id.id, # 'cuota_nro': accountInvoice.cuota_nro, 'date': dateServer, 'currency_id': accountInvoice.currency_id.id, 'reference': accountInvoice.number, }) return accountInterest ''' create / write ''' def eiru_create_account_interest_lines(self, invoiceId, interestID, moveId, expiredDays, expiredDaystot): _logger.info('Verify account interest Line') decimal_precision = self.env['decimal.precision'].precision_get('Account') accountInvoice = self.env['account.invoice'].browse(invoiceId) accountInterest = self.env['account.interest'].browse(interestID) moveLine = self.env['account.move.line'].browse(moveId) interestConfig = self.env['account.interest.config'].search([('active', '=', True)]) domain = [('interest_id.id', '=', accountInterest.id),('move_line_id.id', '=',moveLine.id),('state', '=', 'open')] interestLine = self.env['account.interest.line'].search(domain) decimalPlaces = accountInvoice.currency_id.decimal_places if (not decimalPlaces): decimalPlaces = 0 # cuota_nro = accountInvoice.cuota_nro amount = (moveLine.amount_currency or moveLine.debit or 0.0) amount_residual = (moveLine.amount_residual_currency or moveLine.amount_residual or 0.0) line = { 'move_line_id': moveLine.id, 'amount': round(amount, decimalPlaces), 'date_maturity': moveLine.date_maturity, 'expired_daystot': expiredDaystot, 'expired_days': expiredDays, 'amount_residual': round(amount_residual,decimalPlaces), # 'cuota_nro': accountInvoice.cuota_nro, 'amount_interest': round((expiredDays * (amount_residual * (interestConfig.interest_rate / 100))),decimalPlaces), 'interest_id': accountInterest.id, } if (not interestLine): return interestLine.create(line) return interestLine.write(line) ''' ____ _ ___ _ / ___|_ __ ___ __ _| |_ ___ |_ _|_ ____ _____ (_) ___ ___ | | | '__/ _ \/ _` | __/ _ \ | || '_ \ \ / / _ \| |/ __/ _ \ | |___| | | __/ (_| | || __/ | || | | \ V / (_) | | (_| __/ \____|_| \___|\__,_|\__\___| |___|_| |_|\_/ \___/|_|\___\___| ''' @api.model def create_account_invoice_interest(self, id, interestLine): _logger.info('Create invoice interest') accountInterest = self.env['account.interest'].browse(id) if (not accountInterest): return { 'state': False, 'message': 'Error en obtener el registro de interés' } interestConfig = self.env['account.interest.config'].search([('active', '=', True)]) if (not interestConfig): return { 'state': False, 'message': 'Error en obtener Configuración de interés' } decimal_precision = self.env['decimal.precision'].precision_get('Account') dateServer = self.get_date() invoice_line = [] for line in interestLine: accountInterestLine = self.env['account.interest.line'].browse(line['id']) descrip= "Deuda vencida al %s, días atrasados %d" % (accountInterestLine.date_maturity, accountInterestLine.expired_days) if (line['discount'] > 0): descrip = descrip+" Descuento %d" % (line['discount']) if (accountInterestLine): if (accountInterestLine.amount_interest > line['discount']): invoice_line.append([0,False, { 'name': descrip, 'account_id': interestConfig.line_account_id.id, 'quantity': 1, 'price_unit': round((accountInterestLine.amount_interest - line['discount']),decimal_precision), 'price_subtotal': round((accountInterestLine.amount_interest - line['discount']),decimal_precision), 'partner_id': accountInterest.customer_id.id, 'invoice_line_tax_id': [(6, 0,[x.id for x in interestConfig.line_tax_id])], }]) accountInvoice=[] if (invoice_line): invoice = { 'partner_id': accountInterest.customer_id.id, 'currency_id': accountInterest.currency_id.id, 'date_invoice': dateServer, 'journal_id': interestConfig.invoice_journal_id.id, 'account_id': interestConfig.invoice_account_id.id, 'invoice_line': invoice_line, 'origin': '%s/%s' % (accountInterest.name, accountInterest.reference), 'is_interest': True } ''' Create / open /invoice ''' accountInvoice = self.env['account.invoice'].create(invoice) accountInvoice.signal_workflow('invoice_open') for line in interestLine: accountInterestLine = self.env['account.interest.line'].browse(line['id']) if (accountInterestLine): moveLine = self.env['account.move.line'].browse(accountInterestLine.move_line_id.id) if (moveLine): moveLine.write({'date_interest': dateServer}) accountInterestLine.write({ 'invoice': accountInvoice.id if (accountInvoice and (line['interes'] > line['discount'])) else '', 'reference': accountInvoice.number if(accountInvoice and (line['interes'] > line['discount'])) else '', 'state': 'invoiced' if (line['interes'] > line['discount']) else 'discount', 'amount_dicount': round(line['discount'],decimal_precision) }) ''' Verify State interest ''' state = [] linesState = map(lambda x: x.state, accountInterest.lines_ids) if (('discount'in linesState) or ('paid' in linesState)): state ={ 'state': 'lines_paid'} if (accountInterest.invoice_id.state == 'paid'): state ={ 'state': 'paid'} if (('invoiced' in linesState) or ('invoice_cancel' in linesState) or ('invoice_draft' in linesState) or ('open' in linesState)): state ={'state': 'lines_open'} if (state): accountInterest.write(state) return { 'state': True, 'message': 'Operación exitosa' }