Kaynağa Gözat

Análisis de cuotas en factura de clientes para crifin

sebas 4 yıl önce
işleme
bc2bbf3790

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+*.pyc

+ 2 - 0
__init__.py

@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+from model import account

+ 20 - 0
__openerp__.py

@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+{
+    'name' : 'Análisis de cuotas.',
+    'version' : '1.0',
+    'description' : """
+    """,
+    'author' : 'Eiru / Adrielso kunert',
+    'category' : 'account',
+    'depends' : [
+        'account',
+        'eiru_account_interest',
+    ],
+    'data' : [
+        'views/template.xml',
+        'views/account_invoice_view.xml',
+    ],
+    'qweb' : ['static/src/xml/*.xml',],
+    'installable' : True,
+    'auto_install' : False,
+}

+ 0 - 0
model/__init__.py


+ 100 - 0
model/account.py

@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+
+from openerp import models, fields, api
+
+class AccountInvoice(models.Model):
+	_inherit = 'account.invoice'
+
+	@api.model
+	def getAccountInvoiceQuoteAnalysis(self,idInvoice):
+		values = []
+		''' Account Invoice '''
+		invoice = self.env['account.invoice'].browse(idInvoice)
+		if (not invoice):
+			return False
+
+		''' Move line'''
+		moveLines = self.env['account.move.line'].search([('invoice','=',invoice.id),('debit','>',0),('date_maturity','!=', False)], order='date_maturity')
+
+		quotaCont = 0
+		for moveLine in moveLines:
+			quotaCont += 1
+
+			state = 'No pagado'
+			if(moveLine.reconcile_ref and moveLine.amount_residual == 0):
+				state = 'Pagado'
+			elif (moveLine.reconcile_ref and moveLine.amount_residual > 0):
+				state = 'Amortizado'
+
+			interestIDS = map(lambda x: x.id, moveLine.interest_line_ids)
+
+			interest = self.env['account.interest.line'].search([('id','in',interestIDS ),('state', '=', 'open')])
+
+			values.append({
+				'dateMaturity' : moveLine.date_maturity,
+				'quotaNumber' : "%s/%s" %(quotaCont, len(moveLines)),
+				'amountQuota' : moveLine.debit,
+				'amountResidual' : moveLine.amount_residual,
+				'expiredDaystot' : interest.expired_daystot if(interest) else 0,
+				'expiredDays' : interest.expired_days if(interest) else 0,
+				'amountInterest' : interest.amount_interest if(interest and interest.state == 'open') else 0,
+				'amountTotal' : (moveLine.amount_residual + interest.amount_interest) if(interest and interest.state == 'open') else moveLine.amount_residual,
+				'state' : state,
+				'value': moveLine.debit - moveLine.amount_residual,
+			})
+
+		return values
+
+	@api.model
+	def getInvoiceAccountStatemnete(self, invoiceId):
+		return [{
+			'id': invoice.id,
+			'number': invoice.number,
+			'partner': {
+				'id' : invoice.partner_id.id,
+				'name' : invoice.partner_id.name,
+				'ruc' : invoice.partner_id.ruc or '',
+			},
+			'amountTotal': invoice.amount_total,
+			'amountResidual': invoice.residual,
+			'currency': {
+	            'thousandsSeparator': invoice.currency_id.thousands_separator,
+	            'decimalPlaces': invoice.currency_id.decimal_places,
+	            'decimalSeparator': invoice.currency_id.decimal_separator,
+	            'name': invoice.currency_id.local_name,
+	            'symbol ':invoice.currency_id.symbol,
+	        },
+			'company':{
+				'id': invoice.company_id.id,
+				'name': invoice.company_id.name,
+				'currencyCompany':{
+					'thousandsSeparator': invoice.company_id.currency_id.thousands_separator,
+ 	            	'decimalPlaces': invoice.company_id.currency_id.decimal_places,
+ 	            	'decimalSeparator': invoice.company_id.currency_id.decimal_separator,
+ 	            	'name': invoice.company_id.currency_id.local_name,
+ 	            	'symbol ':invoice.company_id.currency_id.symbol,
+				},
+				'logo': invoice.company_id.logo,
+			},
+
+
+		} for invoice in self.env['account.invoice'].browse(invoiceId)]
+
+class ResCurrrency(models.Model):
+	_inherit = 'res.currency'
+
+	@api.model
+	def getResCurrencyQuoteAnalysis(self,domain):
+		AccountInvoice = self.env['account.invoice'].search(domain)
+		ResCurrency = self.env['res.currency'].search([('id','=',AccountInvoice.currency_id.id)])
+		values = []
+		for currency in ResCurrency:
+			values.append({
+				'symbol': currency.symbol,
+				'decimal_separator': currency.decimal_separator,
+				'decimal_places': currency.decimal_places,
+				'thousands_separator': currency.thousands_separator,
+				'symbol_position': currency.symbol_position,
+			})
+
+		return values

BIN
static/description/icon.png


+ 373 - 0
static/src/js/main.js

@@ -0,0 +1,373 @@
+openerp.eiru_quota_analysis2 = function (instance, local) {
+    local.widgetInstance = null;
+    local.parentInstance = null;
+    var model = openerp;
+    var instanceWeb = openerp.web;
+
+    local.EiruQuotaAnalysis2Widget = instance.Widget.extend({
+        template : "eiru_quota_analysis2.EiruQuotaAnalysis2",
+        id: undefined,
+        AccountInvoice: [],
+        ResCurrency: [],
+        invoiceState : [],
+
+        init: function(parent) {
+            this._super(parent);
+            this.buttons = parent.$buttons;
+        },
+
+        start: function () {
+            var self = this;
+            var table = $('#quota_table');
+            table.bootstrapTable({data : self.rowsData});
+
+            /* Click Imprimir */
+            bottomPrint = this.$el.find('.button-quota-print2');
+            bottomPrint.click(function(){
+                    self.initialPrint();
+            });
+            self.buttons.click(function(e) {
+                // E (Editar)
+                if (e.target.accessKey === 'E')
+                    self.$el.css('display','none');
+                // S (Guarrdar)
+                if (e.target.accessKey === 'S')
+                    self.$el.css('display','flex');
+                // D (Cancelar)
+                if (e.target.accessKey === 'D')
+                    self.$el.css('display','flex');
+                // CREAR
+                if (e.target.accessKey === 'C')
+                    self.$el.css('display','none');
+            });
+        },
+
+       /* */
+        updateId : function(id){
+            var self = this;
+            self.id = id;
+            self.Initial();
+        },
+
+        Initial: function(){
+            var self = this;
+            self.fetchAccountInvoice().then(function (AccountInvoice){
+                return AccountInvoice;
+            }).then(function(AccountInvoice){
+                self.AccountInvoice = AccountInvoice;
+                console.log(self.AccountInvoice);
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+                return self.build();
+            });
+            return;
+        },
+
+        /* GET Quota invoice */
+        fetchAccountInvoice: function (){
+            var self = this;
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoiceQuoteAnalysis',[self.id], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /* CURRENCY */
+        fetchResCurrency: function (){
+            var self = this;
+            var domain = [
+                ['id','=',self.id],
+            ];
+            var ResCurrency = new model.web.Model('res.currency');
+            return ResCurrency.call('getResCurrencyQuoteAnalysis',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /* Generar Table */
+        build: function(){
+            var self = this;
+            var data = [];
+            var state = '';
+            var date = '';
+            var CurrencyBase = self.ResCurrency[0];
+            _.each(self.AccountInvoice, function(item){
+
+                if(item.state == 'Amortizado'){
+                    state = item.state + ' ( ' + accounting.formatMoney(item.value, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' )';
+                }else{
+                    state = item.state;
+                }
+
+                date = moment(item.dateMaturity).format('DD/MM/YYYY');
+                if(item.state != 'Pagado'){
+                    if(item.dateMaturity < moment().format('YYYY-MM-DD')){
+                        date = moment(item.dateMaturity,'YYYY-MM-DD').format('DD/MM/YYYY') + ' (vencido) ';
+                    }
+                }
+                data.push({
+                    'dateMaturity': date,
+                    'quotaNumber': item.quotaNumber,
+                    'amountQuota': accounting.formatMoney(item.amountQuota, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    'amountResidual': accounting.formatMoney(item.amountResidual, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    'expiredDaystot': item.expiredDaystot,
+                    'expiredDays': item.expiredDays,
+                    'amountInterest': accounting.formatMoney(item.amountInterest, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    'amountTotal': accounting.formatMoney(item.amountTotal, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    'state': state
+                });
+            });
+            self.loadTable(data);
+        },
+
+        /* Load Table */
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = $('#quota_table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+
+        /*---------------------------
+        |        IMPRIMIR           |
+        --------------------------*/
+        /*INIT PRINT*/
+        initialPrint: function() {
+            var self = this;
+
+            self.fetchInvoiceState().then(function(invoiceState){
+                return invoiceState
+            }).then(function(invoiceState){
+                self.invoiceState = invoiceState
+                return self.printCustomerAccountStatement();
+            });
+        },
+        /* GET Quota invoice */
+        fetchInvoiceState: function (){
+            var self = this;
+            var invoice = new model.web.Model('account.invoice');
+            return invoice.call('getInvoiceAccountStatemnete',[self.id], {
+                context: new model.web.CompoundContext()
+            });
+        },
+        /* Get interets total */
+        getInterestLines: function() {
+            var self = this;
+            var total = 0;
+            _.each(self.AccountInvoice, function(item){
+                total += item.amountInterest;
+            });
+            return  total;
+        },
+        filterLineQuota: function(currency) {
+            self = this;
+            var data = [];
+
+            _.each(self.AccountInvoice, function(item){
+                //
+                var state = item.state;
+                if(item.state == 'Amortizado'){
+                    state = item.state + ' ('+instanceWeb.formatCurrency(item.value, currency)+' )';
+                }
+
+                date = moment(item.dateMaturity).format('DD/MM/YYYY');
+
+                if(item.state != 'Pagado') {
+                    if(item.dateMaturity < moment().format('YYYY-MM-DD')) {
+                        date = moment(item.dateMaturity,'YYYY-MM-DD').format('DD/MM/YYYY') +' (vencido)';
+                    }
+                }
+
+                data.push({
+                    'dateMaturity': date,
+                    'quotaNumber': item.quotaNumber,
+                    'amountQuota': instanceWeb.formatCurrency(item.amountQuota, currency),
+                    'amountResidual': instanceWeb.formatCurrency(item.amountResidual, currency),
+                    'expiredDaystot': item.expiredDaystot,
+                    'expiredDays': item.expiredDays,
+                    'amountInterest': instanceWeb.formatCurrency(item.amountInterest, currency),
+                    'amountTotal': instanceWeb.formatCurrency(item.amountTotal, currency),
+                    'state': state
+                });
+            });
+            return data
+        },
+        /*PRINT*/
+        printCustomerAccountStatement: function() {
+            var self = this;
+            var pdfDoc = new jsPDF();
+            var y = 15;
+            var space = 7;
+            var invoice = self.invoiceState.shift();
+            var currency = invoice.currency;
+            var company = invoice.company;
+            var interest = self.getInterestLines();
+            var lineQuota  =self.filterLineQuota(currency);
+            var base64Img = 'data:image/png;base64,' + company.logo;
+
+            /********************
+            |       LOGO        |
+            ********************/
+            pdfDoc.addImage(base64Img, 'png', 7, 2, 0, 15);
+            /********************
+            |       FECHA       |
+            ********************/
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor(40)
+            pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 35, 8, moment().format('DD/MM/YYYY'));
+            /********************
+            |       TITLE       |
+            ********************/
+            pdfDoc.setFontSize('18');
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.text(105,y, pdfDoc.splitTextToSize('Estado de cuenta' , 180) , null, null, 'center');
+            pdfDoc.setFontSize('12');
+            /************************
+            |       Clientes        |
+            ************************/
+            y += 10;
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.text(10,y,'Cliente :');
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.text(28,y, invoice.partner.name);
+            /********************************
+            |           RUC                 |
+            ********************************/
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.text(110,y, 'RUC:');
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.text(125, y,invoice.partner.ruc);
+            /************************
+            |       Factura         |
+            ************************/
+            y += space;
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.text(10,y, 'Factura :');
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.text(30,y, invoice.number);
+            /********************
+            |       MONEDA      |
+            ********************/
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.text(110,y, 'Moneda:');
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.text(130,y, currency.name);
+            /*****************************
+            |       Amount TOTAL         |
+            ****************************/
+            y += space;
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.text(10,y, 'Total Factura:');
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.text(40, y, instanceWeb.formatCurrency(invoice.amountTotal, currency));
+            /********************************
+            |       Amount Residual         |
+            ********************************/
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.text(110,y, 'Residual:');
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(231, 76, 60);
+            pdfDoc.text(132, y, instanceWeb.formatCurrency(invoice.amountResidual, currency));
+
+            /******************************
+            |       Amount Interes        |
+            ******************************/
+            y += space;
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor(0, 0, 0);
+            pdfDoc.text(10,y, 'Interés Calculado:');
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.text(50, y, instanceWeb.formatCurrency(interest, currency));
+            /*****************************************
+            |       Amount Residual +Interes         |
+            *****************************************/
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.text(110,y, 'Residual + Interés:');
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(231, 76, 60);
+            pdfDoc.text(150, y, instanceWeb.formatCurrency((invoice.amountResidual+interest), currency));
+
+            /*********************
+            |        Table       |
+            **********************/
+            var getColumns = [
+                {'title' : 'Vencimiento', 'dataKey' : 'dateMaturity'},
+                {'title' : 'Nº Cuota', 'dataKey' : 'quotaNumber'},
+                {'title' : 'Cuota', 'dataKey' : 'amountQuota'},
+                {'title' : 'Pendiente', 'dataKey' : 'amountResidual'},
+                {'title' : 'Días Total', 'dataKey' : 'expiredDaystot'},
+                {'title' : 'Días atrasado', 'dataKey' : 'expiredDays'},
+                {'title' : 'Interés', 'dataKey' : 'amountInterest'},
+                {'title' : 'Total', 'dataKey' : 'amountTotal'},
+                {'title' : 'Estado', 'dataKey' : 'state'},
+            ]
+            rowsPdf = lineQuota;
+
+            pdfDoc.autoTable(getColumns,rowsPdf, {
+                body: rowsPdf,
+                theme: 'grid',
+                startY: 50,
+                styles: {
+                    overflow: 'linebreak',
+                    columnWidth: 'auto',
+                    fontSize: 8,
+                },
+                columnStyles: {
+                    dateMaturity : {columnWidth: 25, halign:'center'},
+                    quotaNumber: {columnWidth: 20, halign:'center'},
+                    amountQuota: {halign:'right'},
+                    amountResidual : {halign:'right'},
+                    expiredDaystot : {columnWidth: 20, halign:'center'},
+                    expiredDays : {columnWidth: 25, halign:'center'},
+                    amountInterest : {halign:'right'},
+                    amountTotal : {halign:'right'},
+                    state : {columnWidth: 20, halign:'center'},
+                },
+                headerStyles: {
+                    fillColor: [76, 133, 248],
+                    fontSize: 9
+                },
+                margin: {
+                    top: 20,
+                    horizontal: 7,
+                    bottom: 40
+                },
+            });
+
+            pdfDoc.save('Estado_financiero.pdf');
+        },
+    });
+
+    if (instance.web && instance.web.FormView) {
+        instance.web.FormView.include({
+            load_record: function (record) {
+                this._super.apply(this, arguments);
+
+                if (this.model !== 'account.invoice')
+                    return;
+
+                local.parentInstance = this;
+
+                if (local.widgetInstance) {
+                    local.widgetInstance.updateId(record.id);
+                    if (this.$el.find('.eiru-quota-table2').length !== 0){
+                        return
+                    }
+                }
+
+                if (this.$el.find('.eiru-quota-table2').length !== 0){
+                    return
+                }
+
+                local.widgetInstance = new local.EiruQuotaAnalysis2Widget(this);
+                var elemento = this.$el.find('.oe_form_sheet.oe_form_sheet_width');
+                elemento =  elemento.find('.quota_box');
+                local.widgetInstance.appendTo(elemento);
+                local.widgetInstance.updateId(record.id);
+            }
+        });
+    }
+};

+ 29 - 0
static/src/xml/view.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="eiru_quota_analysis2.EiruQuotaAnalysis2">
+        <!-- <br/> -->
+        <div class="eiru-quota-table2">
+            <!-- Button -->
+            <button class="button-quota-print2 oe_stat_button btn btn_default">
+                <div class="stat_button_icon fa fa-tasks"></div>
+                <div class="add-button-task">Imprimir</div>
+            </button>
+            <!-- Table -->
+            <table id="quota_table" data-toggle="table" data-classes="table table-condensed" data-undefined-text=" ">
+                <thead style="background:none;">
+                    <tr>
+                        <th data-field="dateMaturity" data-align="left">Vencimiento</th>
+                        <th data-field="quotaNumber" data-align="left">Nº Cuota</th>
+                        <th data-field="amountQuota" data-align="right">Cuota</th>
+                        <th data-field="amountResidual" data-align="right">Pendiente</th>
+                        <th data-field="expiredDaystot" data-align="center">Días Total</th>
+                        <th data-field="expiredDays" data-align="center">Días atrasados</th>
+                        <th data-field="amountInterest" data-align="right">Interés</th>
+                        <th data-field="amountTotal" data-align="right">Total</th>
+                        <th data-field="state" data-align="left">Estado</th>
+                    </tr>
+                </thead>
+            </table>
+        </div>
+    </t>
+</template>

+ 17 - 0
views/account_invoice_view.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+	<data>
+        <record id="account_invoice_quota_view" model="ir.ui.view">
+            <field name="name">account.invoice.quota.view</field>
+            <field name="model">account.invoice</field>
+            <field name="inherit_id" ref="account.invoice_form"/>
+            <field name="arch" type="xml">
+				<xpath expr="//notebook/page[@string='Payments']" position="after">
+                    <page string="Cuotas" groups="base.group_user" attrs="{'invisible': [('state','not in',('open'))]}">
+						<div class="quota_box"></div>
+                    </page>
+				</xpath>
+            </field>
+        </record>
+	</data>
+</openerp>

+ 9 - 0
views/template.xml

@@ -0,0 +1,9 @@
+<openerp>
+    <data>
+        <template id="eiru_quota_analysis2.assets_backend" name="eiru_quota_analysis_assets" inherit_id="eiru_assets.assets">
+            <xpath expr="." position="inside">
+                <script type="text/javascript" src="/eiru_quota_analysis2/static/src/js/main.js"/>
+            </xpath>
+        </template>
+    </data>
+</openerp>