ソースを参照

Eiru report general

SEBAS 1 年間 前
コミット
a0367d9576
100 ファイル変更42251 行追加0 行削除
  1. 1 0
      .gitignore
  2. 3 0
      __init__.py
  3. 30 0
      __openerp__.py
  4. 1 0
      controller/__init__.py
  5. 48 0
      controller/helpers/__init__.py
  6. 76 0
      controller/helpers/account_bank_statement_line.py
  7. 516 0
      controller/helpers/account_invoice.py
  8. 1005 0
      controller/helpers/account_invoice_line.py
  9. 15 0
      controller/helpers/account_journal.py
  10. 42 0
      controller/helpers/account_move_line.py
  11. 26 0
      controller/helpers/account_period.py
  12. 297 0
      controller/helpers/account_voucher.py
  13. 15 0
      controller/helpers/company_logo.py
  14. 79 0
      controller/helpers/pos_order.py
  15. 242 0
      controller/helpers/pos_order_line.py
  16. 17 0
      controller/helpers/product_attribute.py
  17. 23 0
      controller/helpers/product_attribute_value.py
  18. 33 0
      controller/helpers/product_brand.py
  19. 25 0
      controller/helpers/product_category.py
  20. 106 0
      controller/helpers/product_product.py
  21. 26 0
      controller/helpers/report_category.py
  22. 28 0
      controller/helpers/report_report.py
  23. 62 0
      controller/helpers/res_company.py
  24. 21 0
      controller/helpers/res_partner.py
  25. 13 0
      controller/helpers/res_store.py
  26. 27 0
      controller/helpers/res_users.py
  27. 182 0
      controller/main.py
  28. 822 0
      models.py
  29. BIN
      static/description/icon.png
  30. 148 0
      static/src/css/custom.css
  31. 922 0
      static/src/js/chart.js
  32. 102 0
      static/src/js/configuration_reporting.js
  33. 40 0
      static/src/js/datepicker.js
  34. 305 0
      static/src/js/main.js
  35. 1575 0
      static/src/js/pdf.js
  36. 22 0
      static/src/js/reporting_base.js
  37. 1040 0
      static/src/js/reports/report_account_payable.js
  38. 1038 0
      static/src/js/reports/report_account_payable_expenses.js
  39. 1029 0
      static/src/js/reports/report_account_receivable.js
  40. 362 0
      static/src/js/reports/report_customer.js
  41. 698 0
      static/src/js/reports/report_customer_payment.js
  42. 710 0
      static/src/js/reports/report_customer_paymentespecial.js
  43. 760 0
      static/src/js/reports/report_customer_ranking.js
  44. 966 0
      static/src/js/reports/report_customer_ratings.js
  45. 1027 0
      static/src/js/reports/report_customer_refund.js
  46. 885 0
      static/src/js/reports/report_daily_sale.js
  47. 957 0
      static/src/js/reports/report_dues_analysis.js
  48. 947 0
      static/src/js/reports/report_duessupplier_analysis.js
  49. 512 0
      static/src/js/reports/report_expense.js
  50. 638 0
      static/src/js/reports/report_expense_analytic.js
  51. 881 0
      static/src/js/reports/report_income_summary.js
  52. 727 0
      static/src/js/reports/report_outcome_summary.js
  53. 1060 0
      static/src/js/reports/report_product_list.js
  54. 560 0
      static/src/js/reports/report_profit_and_loss.js
  55. 504 0
      static/src/js/reports/report_purchase.js
  56. 639 0
      static/src/js/reports/report_purchase_analytic.js
  57. 718 0
      static/src/js/reports/report_purchase_journal.js
  58. 846 0
      static/src/js/reports/report_purchase_journal_detallado.js
  59. 825 0
      static/src/js/reports/report_sale.js
  60. 922 0
      static/src/js/reports/report_sale_analytic.js
  61. 931 0
      static/src/js/reports/report_sale_gross.js
  62. 917 0
      static/src/js/reports/report_sale_journal.js
  63. 847 0
      static/src/js/reports/report_sale_journal_detallado.js
  64. 923 0
      static/src/js/reports/report_sale_ranking_product.js
  65. 565 0
      static/src/js/reports/report_sale_summary.js
  66. 991 0
      static/src/js/reports/report_sale_utility_analytic.js
  67. 580 0
      static/src/js/reports/report_stock_history.js
  68. 750 0
      static/src/js/reports/report_stock_movement.js
  69. 761 0
      static/src/js/reports/report_stock_valuation.js
  70. 358 0
      static/src/js/reports/report_supplier.js
  71. 524 0
      static/src/js/reports/report_supplier_payment.js
  72. 1097 0
      static/src/js/reports/report_supplier_ranking.js
  73. 1027 0
      static/src/js/reports/report_supplier_refund.js
  74. 219 0
      static/src/reports/report_account_payable.xml
  75. 218 0
      static/src/reports/report_account_payable_expenses.xml
  76. 216 0
      static/src/reports/report_account_receivable.xml
  77. 112 0
      static/src/reports/report_customer.xml
  78. 181 0
      static/src/reports/report_customer_payment.xml
  79. 178 0
      static/src/reports/report_customer_paymentespecial.xml
  80. 178 0
      static/src/reports/report_customer_ranking.xml
  81. 163 0
      static/src/reports/report_customer_ratings.xml
  82. 249 0
      static/src/reports/report_customer_refund.xml
  83. 176 0
      static/src/reports/report_daily_sale.xml
  84. 181 0
      static/src/reports/report_dues_analysis.xml
  85. 179 0
      static/src/reports/report_duessupplier_analysis.xml
  86. 230 0
      static/src/reports/report_expense.xml
  87. 259 0
      static/src/reports/report_expense_analytic.xml
  88. 143 0
      static/src/reports/report_income_summary.xml
  89. 144 0
      static/src/reports/report_outcome_summary.xml
  90. 191 0
      static/src/reports/report_product_list.xml
  91. 150 0
      static/src/reports/report_profit_and_loss.xml
  92. 234 0
      static/src/reports/report_purchase.xml
  93. 260 0
      static/src/reports/report_purchase_analytic.xml
  94. 257 0
      static/src/reports/report_purchase_journal.xml
  95. 327 0
      static/src/reports/report_purchase_journal_detallado.xml
  96. 261 0
      static/src/reports/report_sale.xml
  97. 300 0
      static/src/reports/report_sale_analytic.xml
  98. 237 0
      static/src/reports/report_sale_gross.xml
  99. 265 0
      static/src/reports/report_sale_journal.xml
  100. 326 0
      static/src/reports/report_sale_journal_detallado.xml

+ 1 - 0
.gitignore

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

+ 3 - 0
__init__.py

@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+import controller
+import models

+ 30 - 0
__openerp__.py

@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+#
+{
+    'name': "Eiru Reports",
+    'author': "Eiru",
+    'category': 'report',
+    'version': '1.1',
+    'depends': [
+        'base',
+        'product',
+        'account',
+        'stock',
+        'eiru_assets',
+        'account_journal_active',
+        'category_expense',
+        'multi_store',
+        'multi_store_stock',
+        'expense_menu',
+        'product_factory_referente',
+    ],
+    'qweb': [
+        'static/src/xml/*.xml',
+        'static/src/reports/*.xml'
+    ],
+    'data': [
+        'templates.xml',
+        'views/actions.xml',
+        'views/menus.xml',
+    ],
+}

+ 1 - 0
controller/__init__.py

@@ -0,0 +1 @@
+import main

+ 48 - 0
controller/helpers/__init__.py

@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+# REPORT CONFIG
+from report_report import get_report_report
+from report_category import get_report_category
+# RES USERS
+from res_users import get_res_users
+from res_partner import get_res_partner
+
+# ACCOUNT VOUCHER
+from account_voucher import get_account_voucher_all
+from account_voucher import get_account_voucher_customer
+from account_voucher import get_account_voucher_supplier
+from account_voucher import get_account_voucher_payment
+from account_move_line import get_account_move_line
+
+# ACCOUNT BANK STATEMENT lINE
+from account_bank_statement_line import get_account_bank_statement_line
+
+from res_company import get_res_company
+from res_company import get_company_logo
+from res_store import get_res_store
+from account_journal import get_account_journal
+
+from pos_order import get_pos_order
+from pos_order_line import get_pos_order_line
+from account_period import get_account_period
+
+# PRODUCT
+from product_category import get_product_category_all
+from product_category import get_product_category_expense
+from product_brand import get_product_brand
+from product_attribute import get_product_attribute
+from product_attribute_value import get_product_attribute_value
+from product_product import get_product_product
+
+# ACCOUNT INVOICE
+from account_invoice import get_account_invoice_all_type
+from account_invoice import get_account_invoice_sale_type
+from account_invoice import get_account_invoice_sale_and_refund_type
+from account_invoice import get_account_invoice_purchase_type
+from account_invoice import get_account_invoice_expense_type
+
+# ACCOUNT INVOICE LINE
+from account_invoice_line import get_account_invoice_line_all_type
+from account_invoice_line import get_account_invoice_line_out_invoice
+from account_invoice_line import get_account_invoice_line_out_invoice_and_out_refund
+from account_invoice_line import get_account_invoice_line_in_invoice_purchase
+from account_invoice_line import get_account_invoice_line_in_invoice_expense

+ 76 - 0
controller/helpers/account_bank_statement_line.py

@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_bank_statement_line():
+    user_store = r.env.user.store_id.id
+
+    validate = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='pos_order')
+    '''
+
+    query = '''
+        SELECT
+        	line.id,
+        	line.name,
+        	statement.journal_id,
+        	line.amount,
+        	CASE
+        		WHEN journal.currency IS NULL
+        		THEN line.amount
+        		ELSE line.amount * (%s / (array_agg(rate.rate ORDER BY rate.name DESC))[1])
+        		END AS amount_currency,
+        	journal_rel.store_id,
+        	line.company_id,
+        	journal.name,
+        	partner.name,
+            line.date,
+            line.ref
+            FROM account_bank_statement_line as line
+            LEFT JOIN account_bank_statement as statement
+            ON statement.id = line.statement_id
+            LEFT JOIN res_store_journal_rel AS journal_rel
+            ON statement.journal_id = journal_rel.journal_id
+            LEFT JOIN account_journal AS journal
+            ON journal.id = statement.journal_id
+            LEFT JOIN res_partner AS partner
+            ON partner.id = line.partner_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = journal.currency
+            WHERE line.pos_statement_id IS NOT NULL
+            GROUP BY
+        		line.id,
+        		statement.journal_id,
+        		journal.currency,
+        		journal_rel.store_id,
+        		journal.name,
+        		partner.name
+    '''
+
+    r.cr.execute(validate)
+    for j in r.cr.fetchall():
+        band = j[0]
+
+    if band == True:
+        company_currency_rate = r.env.user.company_id.currency_id.rate
+        r.cr.execute(query,[company_currency_rate])
+        return [
+            {
+                'id': j[0],
+                'name': j[1],
+                'journal_id': j[2],
+                'amount': j[3],
+                'amount_currency': j[4],
+                'store_id': j[5],
+                'company_id': j[6],
+                'journal_name': j[7],
+                'partner_name': j[8],
+                'date': j[9],
+                'origin': j[10],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        return []

+ 516 - 0
controller/helpers/account_invoice.py

@@ -0,0 +1,516 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_invoice_all_type():
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+        SELECT
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.partner_id,
+        	invoice.user_id,
+        	invoice.amount_total * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as invoice_rate,
+            invoice.number,
+            partner.name,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            customer.ruc,
+            invoice.supplier_invoice_number
+        FROM account_invoice AS invoice
+        LEFT JOIN res_store_journal_rel AS journal
+        ON journal.journal_id = invoice.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = invoice.currency_id
+        LEFT JOIN res_company AS company
+        ON company.id = invoice.company_id
+        LEFT JOIN res_users AS users
+        ON users.id = invoice.user_id
+        LEFT JOIN res_partner AS partner
+        ON partner.id = users.partner_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = invoice.partner_id
+        WHERE invoice.state NOT IN ('draft', 'cancel')
+        GROUP BY
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.amount_total,
+        	invoice.partner_id,
+        	invoice.user_id,
+            invoice.amount_total,
+            partner.name,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            customer.ruc,
+            invoice.supplier_invoice_number
+    '''
+
+    r.cr.execute(query,(tuple([company_currency_rate])))
+
+    return [
+        {
+            'invoice_id': j[0],
+            'currency_id': j[1],
+            'date': j[2],
+            'type': j[3],
+            'origin': j[4],
+            'customer_id':j[5],
+            'user_id':j[6],
+            'amount':j[7],
+            'number':j[8],
+            'user_name':j[9],
+            'customer_name':j[10],
+            'amount_tax':j[11],
+            'state':j[12],
+            'store_id':j[13],
+            'journal_id':j[14],
+            'state':j[15],
+            'customer_ruc':j[16],
+            'supplier_invoice_number':j[17],
+        } for j in r.cr.fetchall()
+    ]
+
+def get_account_invoice_sale_type(): #historico de venta
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    validate_columns = '''
+        SELECT EXISTS (SELECT 1 FROM information_schema.columns
+        WHERE table_name='account_invoice' AND column_name in ('contado','credito'))'''
+
+    query1 = '''
+        SELECT
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.partner_id,
+        	invoice.user_id,
+        	invoice.amount_total * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]),
+            invoice.number,
+            partner.name,
+            customer.name,
+            invoice.amount_tax * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]),
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            customer.ruc,
+            invoice.supplier_invoice_number
+        FROM account_invoice AS invoice
+        LEFT JOIN res_store_journal_rel AS journal
+        ON journal.journal_id = invoice.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = invoice.currency_id
+        LEFT JOIN res_company AS company
+        ON company.id = invoice.company_id
+        LEFT JOIN res_users AS users
+        ON users.id = invoice.user_id
+        LEFT JOIN res_partner AS partner
+        ON partner.id = users.partner_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = invoice.partner_id
+        WHERE invoice.state NOT IN ('draft', 'cancel')
+        AND invoice.type IN ('out_invoice')
+        GROUP BY
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.amount_total,
+        	invoice.partner_id,
+        	invoice.user_id,
+            invoice.amount_total,
+            partner.name,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            customer.ruc,
+            invoice.supplier_invoice_number
+    '''
+
+    query2 = '''
+        SELECT
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.partner_id,
+        	invoice.user_id,
+        	invoice.amount_total * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]),
+            invoice.number,
+            partner.name,
+            customer.name,
+            invoice.amount_tax * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]),
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            customer.ruc,
+            invoice.supplier_invoice_number,
+            invoice.contado,
+            invoice.credito
+        FROM account_invoice AS invoice
+        LEFT JOIN res_store_journal_rel AS journal
+        ON journal.journal_id = invoice.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = invoice.currency_id
+        LEFT JOIN res_company AS company
+        ON company.id = invoice.company_id
+        LEFT JOIN res_users AS users
+        ON users.id = invoice.user_id
+        LEFT JOIN res_partner AS partner
+        ON partner.id = users.partner_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = invoice.partner_id
+        WHERE invoice.state NOT IN ('draft', 'cancel')
+        AND invoice.type IN ('out_invoice')
+        GROUP BY
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.amount_total,
+        	invoice.partner_id,
+        	invoice.user_id,
+            invoice.amount_total,
+            partner.name,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            customer.ruc,
+            invoice.supplier_invoice_number
+    '''
+
+    r.cr.execute(validate_columns)
+
+    for j in r.cr.fetchall():
+        column = j[0]
+
+    if column == True:
+        r.cr.execute(query2,(tuple([company_currency_rate,company_currency_rate])))
+        return [{
+            'invoice_id': j[0],
+            'currency_id': j[1],
+            'date': j[2],
+            'type': j[3],
+            'origin': j[4],
+            'customer_id':j[5],
+            'user_id':j[6],
+            'amount':j[7],
+            'number':j[8],
+            'user_name':j[9],
+            'customer_name':j[10],
+            'amount_tax':j[11],
+            'state':j[12],
+            'store_id':j[13],
+            'journal_id':j[14],
+            'state':j[15],
+            'company_id':j[16],
+            'customer_ruc':j[17],
+            'supplier_invoice_number':j[18],
+            'contado':j[19],
+            'credito':j[20],
+        } for j in r.cr.fetchall()]
+    else:
+        r.cr.execute(query1,(tuple([company_currency_rate,company_currency_rate])))
+        return [{
+            'invoice_id': j[0],
+            'currency_id': j[1],
+            'date': j[2],
+            'type': j[3],
+            'origin': j[4],
+            'customer_id':j[5],
+            'user_id':j[6],
+            'amount':j[7],
+            'number':j[8],
+            'user_name':j[9],
+            'customer_name':j[10],
+            'amount_tax':j[11],
+            'state':j[12],
+            'store_id':j[13],
+            'journal_id':j[14],
+            'state':j[15],
+            'company_id':j[16],
+            'customer_ruc':j[17],
+            'supplier_invoice_number':j[18],
+        } for j in r.cr.fetchall()]
+
+def get_account_invoice_sale_and_refund_type():
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+        SELECT
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.partner_id,
+        	invoice.user_id,
+        	invoice.amount_total * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as invoice_rate,
+            invoice.number,
+            partner.name,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id
+        FROM account_invoice AS invoice
+        LEFT JOIN res_store_journal_rel AS journal
+        ON journal.journal_id = invoice.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = invoice.currency_id
+        LEFT JOIN res_company AS company
+        ON company.id = invoice.company_id
+        LEFT JOIN res_users AS users
+        ON users.id = invoice.user_id
+        LEFT JOIN res_partner AS partner
+        ON partner.id = users.partner_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = invoice.partner_id
+        WHERE invoice.state NOT IN ('draft', 'cancel')
+        AND invoice.type IN ('out_invoice','out_refund')
+        GROUP BY
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.amount_total,
+        	invoice.partner_id,
+        	invoice.user_id,
+            invoice.amount_total,
+            partner.name,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id
+    '''
+
+    r.cr.execute(query,(tuple([company_currency_rate])))
+
+    return [
+        {
+            'invoice_id': j[0],
+            'currency_id': j[1],
+            'date': j[2],
+            'type': j[3],
+            'origin': j[4],
+            'customer_id':j[5],
+            'user_id':j[6],
+            'amount':j[7],
+            'number':j[8],
+            'user_name':j[9],
+            'customer_name':j[10],
+            'amount_tax':j[11],
+            'state':j[12],
+            'store_id':j[13],
+            'journal_id':j[14],
+            'state':j[15],
+            'company_id':j[16]
+        } for j in r.cr.fetchall()
+    ]
+
+def get_account_invoice_expense_type():
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    origin = '%PO%'
+    query = '''
+        SELECT
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.partner_id,
+        	invoice.user_id,
+        	invoice.amount_total * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as invoice_rate,
+            invoice.number,
+            partner.name,
+            customer.ruc,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            invoice.supplier_invoice_number
+        FROM account_invoice AS invoice
+        LEFT JOIN res_store_journal_rel AS journal
+        ON journal.journal_id = invoice.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = invoice.currency_id
+        LEFT JOIN res_company AS company
+        ON company.id = invoice.company_id
+        LEFT JOIN res_users AS users
+        ON users.id = invoice.user_id
+        LEFT JOIN res_partner AS partner
+        ON partner.id = users.partner_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = invoice.partner_id
+        WHERE invoice.state NOT IN ('draft', 'cancel')
+        AND invoice.type IN ('in_invoice')
+        AND (invoice.origin NOT LIKE %s OR invoice.origin IS NULL)
+        GROUP BY
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.amount_total,
+        	invoice.partner_id,
+        	invoice.user_id,
+            invoice.amount_total,
+            partner.name,
+            customer.ruc,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            invoice.supplier_invoice_number
+    '''
+    r.cr.execute(query,([company_currency_rate,origin]))
+
+    return [
+        {
+            'invoice_id':j[0],
+            'currency_id':j[1],
+            'date':j[2],
+            'type':j[3],
+            'origin':j[4],
+            'customer_id':j[5],
+            'user_id':j[6],
+            'amount':j[7],
+            'number':j[8],
+            'user_name':j[9],
+            'supplier_ruc':j[10],
+            'supplier_name':j[11],
+            'amount_tax':j[12],
+            'state':j[13],
+            'store_id':j[14],
+            'journal_id':j[15],
+            'state':j[16],
+            'company_id':j[17],
+            'supplier_invoice_number':j[18],
+        } for j in r.cr.fetchall()
+    ]
+
+def get_account_invoice_purchase_type():
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    origin = '%PO%'
+    query = '''
+        SELECT
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.partner_id,
+        	invoice.user_id,
+        	invoice.amount_total * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as invoice_rate,
+            invoice.number,
+            partner.name,
+            customer.ruc,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            invoice.supplier_invoice_number
+        FROM account_invoice AS invoice
+        LEFT JOIN res_store_journal_rel AS journal
+        ON journal.journal_id = invoice.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = invoice.currency_id
+        LEFT JOIN res_company AS company
+        ON company.id = invoice.company_id
+        LEFT JOIN res_users AS users
+        ON users.id = invoice.user_id
+        LEFT JOIN res_partner AS partner
+        ON partner.id = users.partner_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = invoice.partner_id
+        WHERE invoice.state NOT IN ('draft', 'cancel')
+        AND invoice.type IN ('in_invoice')
+        AND (invoice.origin LIKE %s OR invoice.origin <> NULL)
+        GROUP BY
+        	invoice.id,
+        	rate.currency_id,
+        	invoice.date_invoice,
+        	invoice.type,
+        	invoice.origin,
+        	invoice.amount_total,
+        	invoice.partner_id,
+        	invoice.user_id,
+            invoice.amount_total,
+            partner.name,
+            customer.ruc,
+            customer.name,
+            invoice.amount_tax,
+            invoice.state,
+            journal.store_id,
+            invoice.journal_id,
+            invoice.state,
+            invoice.company_id,
+            invoice.supplier_invoice_number
+    '''
+    r.cr.execute(query,([company_currency_rate,origin]))
+
+    return [
+        {
+            'invoice_id':j[0],
+            'currency_id':j[1],
+            'date':j[2],
+            'type':j[3],
+            'origin':j[4],
+            'customer_id':j[5],
+            'user_id':j[6],
+            'amount':j[7],
+            'number':j[8],
+            'user_name':j[9],
+            'supplier_ruc':j[10],
+            'supplier_name':j[11],
+            'amount_tax':j[12],
+            'state':j[13],
+            'store_id':j[14],
+            'journal_id':j[15],
+            'state':j[16],
+            'company_id':j[17],
+            'supplier_invoice_number':j[18],
+        } for j in r.cr.fetchall()
+    ]

+ 1005 - 0
controller/helpers/account_invoice_line.py

@@ -0,0 +1,1005 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_invoice_line_all_type():
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	invoice.type,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            --line.name,
+            journal.store_id,
+            template.categ_id
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal,
+            journal.store_id,
+            template.categ_id
+    '''
+
+    r.cr.execute(query,(tuple([company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate])))
+
+    return [
+        {
+            'invoice_id': j[0],
+            'invoice_line_id': j[1],
+            'number': j[2],
+            'origin': j[3],
+            'date': j[4],
+            'type': j[5],
+            'product_name':j[6],
+            'price_unit':j[7],
+            'quantity':j[8],
+            'subtotal':j[9],
+            'tax': j[10],
+            'cost': j[11],
+            'store_id': j[12],
+            'categ_id': j[13],
+        } for j in r.cr.fetchall()
+    ]
+
+def get_account_invoice_line_out_invoice(): #analisis de venta
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+
+    validate_brand = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='product_brand')
+    '''
+
+    query_with_brand = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	invoice.type,
+            CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (((line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) * line.discount)/100))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            journal.store_id,
+            template.categ_id,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            template.product_brand_id,
+            brand.name,
+            line.discount,
+            line.name
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            --Product
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        	ON attr_rel.prod_id = product.id
+        	LEFT JOIN product_attribute_value AS attr_value
+        	ON attr_value.id = attr_rel.att_id
+        	LEFT JOIN product_attribute AS attr
+        	ON attr.id = attr_value.attribute_id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            LEFT JOIN res_partner AS partner
+            ON partner.id = invoice.partner_id
+            LEFT JOIN product_brand AS brand
+            ON brand.id = template.product_brand_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+            AND invoice.type = 'out_invoice'
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal,
+            journal.store_id,
+            template.categ_id,
+            product.default_code,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            template.product_brand_id,
+            brand.name,
+            line.name
+    '''
+
+    query_without_brand = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	invoice.type,
+            CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (((line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) * line.discount)/100))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            journal.store_id,
+            template.categ_id,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            line.discount,
+            line.name
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            --Product
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        	ON attr_rel.prod_id = product.id
+        	LEFT JOIN product_attribute_value AS attr_value
+        	ON attr_value.id = attr_rel.att_id
+        	LEFT JOIN product_attribute AS attr
+        	ON attr.id = attr_value.attribute_id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            LEFT JOIN res_partner AS partner
+            ON partner.id = invoice.partner_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+            AND invoice.type = 'out_invoice'
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal,
+            journal.store_id,
+            template.categ_id,
+            product.default_code,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            line.name
+    '''
+
+    r.cr.execute(validate_brand)
+    for j in r.cr.fetchall():
+        brand = j[0]
+
+    if brand == True:
+        r.cr.execute(query_with_brand,[company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate])
+        return [
+            {
+                'invoice_id': j[0],
+                'invoice_line_id': j[1],
+                'number': j[2],
+                'origin': j[3],
+                'date': j[4],
+                'type': j[5],
+                'product_name':j[6],
+                'price_unit':j[7],
+                'quantity':j[8],
+                'subtotal':j[9],
+                'tax': j[10],
+                'cost': j[11],
+                'store_id': j[12],
+                'categ_id': j[13],
+                'partner_name': j[14],
+                'partner_ruc': j[15],
+                'product_id': j[16],
+                'company_id': j[17],
+                'journal_id': j[18],
+                'attribute_value_ids': j[19],
+                'attribute_values': j[20],
+                'attribute_ids': j[21],
+                'product_brand_id': j[22],
+                'brand_name': j[23],
+                'discount': j[24],
+                'name': j[25],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        r.cr.execute(query_without_brand,[company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate])
+        return [
+            {
+                'invoice_id': j[0],
+                'invoice_line_id': j[1],
+                'number': j[2],
+                'origin': j[3],
+                'date': j[4],
+                'type': j[5],
+                'product_name':j[6],
+                'price_unit':j[7],
+                'quantity':j[8],
+                'subtotal':j[9],
+                'tax': j[10],
+                'cost': j[11],
+                'store_id': j[12],
+                'categ_id': j[13],
+                'partner_ruc': j[14],
+                'partner_name': j[15],
+                'product_id': j[16],
+                'company_id': j[17],
+                'journal_id': j[18],
+                'attribute_value_ids': j[19],
+                'attribute_values': j[20],
+                'attribute_ids': j[21],
+                'discount': j[22],
+                'name': j[23],
+            } for j in r.cr.fetchall()
+        ]
+
+def get_account_invoice_line_out_invoice_and_out_refund():
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+
+    validate_brand = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='product_brand')
+    '''
+
+    query_with_brand = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	invoice.type,
+            CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            journal.store_id,
+            template.categ_id,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            template.product_brand_id,
+            brand.name,
+            partner.id
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            --Product
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        	ON attr_rel.prod_id = product.id
+        	LEFT JOIN product_attribute_value AS attr_value
+        	ON attr_value.id = attr_rel.att_id
+        	LEFT JOIN product_attribute AS attr
+        	ON attr.id = attr_value.attribute_id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            LEFT JOIN res_partner AS partner
+            ON partner.id = invoice.partner_id
+            LEFT JOIN product_brand AS brand
+            ON brand.id = template.product_brand_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+            AND invoice.type in ('out_invoice','out_refund')
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal,
+            journal.store_id,
+            template.categ_id,
+            product.default_code,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            template.product_brand_id,
+            brand.name,
+            partner.id
+    '''
+
+    query_without_brand = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	invoice.type,
+            CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            --line.name
+            journal.store_id,
+            template.categ_id,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            partner.id
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            --Product
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        	ON attr_rel.prod_id = product.id
+        	LEFT JOIN product_attribute_value AS attr_value
+        	ON attr_value.id = attr_rel.att_id
+        	LEFT JOIN product_attribute AS attr
+        	ON attr.id = attr_value.attribute_id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            LEFT JOIN res_partner AS partner
+            ON partner.id = invoice.partner_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+            AND invoice.type = 'out_invoice'
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal,
+            journal.store_id,
+            template.categ_id,
+            product.default_code,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            partner.id
+    '''
+
+    r.cr.execute(validate_brand)
+    for j in r.cr.fetchall():
+        brand = j[0]
+
+    if brand == True:
+        r.cr.execute(query_with_brand,(tuple([company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate])))
+        return [
+            {
+                'invoice_id': j[0],
+                'invoice_line_id': j[1],
+                'number': j[2],
+                'origin': j[3],
+                'date': j[4],
+                'type': j[5],
+                'product_name':j[6],
+                'price_unit':j[7],
+                'quantity':j[8],
+                'subtotal':j[9],
+                'tax': j[10],
+                'cost': j[11],
+                'store_id': j[12],
+                'categ_id': j[13],
+                'partner_name': j[14],
+                'product_id': j[15],
+                'company_id': j[16],
+                'journal_id': j[17],
+                'attribute_value_ids': j[18],
+                'attribute_values': j[19],
+                'attribute_ids': j[20],
+                'product_brand_id': j[21],
+                'brand_name': j[22],
+                'partner_id': j[23],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        r.cr.execute(query_without_brand,(tuple([company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate])))
+        return [
+            {
+                'invoice_id': j[0],
+                'invoice_line_id': j[1],
+                'number': j[2],
+                'origin': j[3],
+                'date': j[4],
+                'type': j[5],
+                'product_name':j[6],
+                'price_unit':j[7],
+                'quantity':j[8],
+                'subtotal':j[9],
+                'tax': j[10],
+                'cost': j[11],
+                'store_id': j[12],
+                'categ_id': j[13],
+                'partner_name': j[14],
+                'product_id': j[15],
+                'company_id': j[16],
+                'journal_id': j[17],
+                'attribute_value_ids': j[18],
+                'attribute_values': j[19],
+                'attribute_ids': j[20],
+                'partner_id': j[21],
+            } for j in r.cr.fetchall()
+        ]
+
+def get_account_invoice_line_in_invoice_purchase():
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    origin = '%PO%'
+
+    validate_brand = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='product_brand')
+    '''
+
+    query_with_brand = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+            invoice.supplier_invoice_number,
+        	invoice.date_invoice,
+        	invoice.type,
+            CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            journal.store_id,
+            template.categ_id,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            template.product_brand_id,
+            brand.name,
+            line.name
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            --Product
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        	ON attr_rel.prod_id = product.id
+        	LEFT JOIN product_attribute_value AS attr_value
+        	ON attr_value.id = attr_rel.att_id
+        	LEFT JOIN product_attribute AS attr
+        	ON attr.id = attr_value.attribute_id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            LEFT JOIN res_partner AS partner
+            ON partner.id = invoice.partner_id
+            LEFT JOIN product_brand AS brand
+            ON brand.id = template.product_brand_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+            AND invoice.type = 'in_invoice'
+            AND invoice.origin LIKE %s
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+            invoice.supplier_invoice_number,
+        	invoice.date_invoice,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal,
+            journal.store_id,
+            template.categ_id,
+            product.default_code,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            template.product_brand_id,
+            brand.name,
+            line.name
+    '''
+
+    query_without_brand = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+            invoice.supplier_invoice_number,
+        	invoice.date_invoice,
+        	invoice.type,
+            CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            journal.store_id,
+            template.categ_id,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            line.name
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            --Product
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        	ON attr_rel.prod_id = product.id
+        	LEFT JOIN product_attribute_value AS attr_value
+        	ON attr_value.id = attr_rel.att_id
+        	LEFT JOIN product_attribute AS attr
+        	ON attr.id = attr_value.attribute_id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            LEFT JOIN res_partner AS partner
+            ON partner.id = invoice.partner_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+            AND invoice.type = 'in_invoice'
+            AND invoice.origin LIKE %s
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+            invoice.supplier_invoice_number,
+        	invoice.date_invoice,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal,
+            journal.store_id,
+            template.categ_id,
+            product.default_code,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            line.name
+    '''
+
+    r.cr.execute(validate_brand)
+    for j in r.cr.fetchall():
+        brand = j[0]
+
+    if brand == True:
+        r.cr.execute(query_with_brand,([company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate,origin]))
+        return [
+            {
+                'invoice_id': j[0],
+                'invoice_line_id': j[1],
+                'number': j[2],
+                'origin': j[3],
+                'supplier_invoice_number': j[4],
+                'date': j[5],
+                'type': j[6],
+                'product_name':j[7],
+                'price_unit':j[8],
+                'quantity':j[9],
+                'subtotal':j[10],
+                'tax': j[11],
+                'cost': j[12],
+                'store_id': j[13],
+                'categ_id': j[14],
+                'partner_ruc': j[15],
+                'partner_name': j[16],
+                'product_id': j[17],
+                'company_id': j[18],
+                'journal_id': j[19],
+                'attribute_value_ids': j[20],
+                'attribute_values': j[21],
+                'attribute_ids': j[22],
+                'product_brand_id': j[23],
+                'brand_name': j[24],
+                'name': j[25],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        r.cr.execute(query_without_brand,([company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate,origin]))
+        return [
+            {
+                'invoice_id': j[0],
+                'invoice_line_id': j[1],
+                'number': j[2],
+                'origin': j[3],
+                'supplier_invoice_number': j[4],
+                'date': j[5],
+                'type': j[6],
+                'product_name':j[7],
+                'price_unit':j[8],
+                'quantity':j[9],
+                'subtotal':j[10],
+                'tax': j[11],
+                'cost': j[12],
+                'store_id': j[13],
+                'categ_id': j[14],
+                'partner_ruc': j[15],
+                'partner_name': j[16],
+                'product_id': j[17],
+                'company_id': j[18],
+                'journal_id': j[19],
+                'attribute_value_ids': j[20],
+                'attribute_values': j[21],
+                'attribute_ids': j[22],
+                'name': j[23],
+            } for j in r.cr.fetchall()
+        ]
+
+def get_account_invoice_line_in_invoice_expense():
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    origin = '%PO%'
+
+    validate_brand = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='product_brand')
+    '''
+
+    query_with_brand = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	invoice.type,
+            CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            journal.store_id,
+            template.categ_id,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            template.product_brand_id,
+            brand.name,
+            line.name
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            --Product
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        	ON attr_rel.prod_id = product.id
+        	LEFT JOIN product_attribute_value AS attr_value
+        	ON attr_value.id = attr_rel.att_id
+        	LEFT JOIN product_attribute AS attr
+        	ON attr.id = attr_value.attribute_id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            LEFT JOIN res_partner AS partner
+            ON partner.id = invoice.partner_id
+            LEFT JOIN product_brand AS brand
+            ON brand.id = template.product_brand_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+            AND invoice.type = 'in_invoice'
+            AND (invoice.origin NOT LIKE %s OR invoice.origin IS NULL)
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal,
+            journal.store_id,
+            template.categ_id,
+            product.default_code,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            template.product_brand_id,
+            brand.name,
+            line.name
+    '''
+
+    query_without_brand = '''
+        SELECT
+        	invoice.id AS invoice_id,
+        	line.id AS invoice_line_id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	invoice.type,
+            CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) as price_unit,
+        	line.quantity AS cant,
+        	line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]) AS subtotal,
+        	(line.quantity * (line.price_unit * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1]))) - (line.price_subtotal * (%s / (array_agg(rate.rate ORDER BY rate.id DESC))[1])) AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            journal.store_id,
+            template.categ_id,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            line.name
+            FROM account_invoice AS invoice
+            LEFT JOIN account_invoice_line AS line
+            ON line.invoice_id = invoice.id
+            --Product
+            LEFT JOIN product_product AS product
+            ON line.product_id = product.id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        	ON attr_rel.prod_id = product.id
+        	LEFT JOIN product_attribute_value AS attr_value
+        	ON attr_value.id = attr_rel.att_id
+        	LEFT JOIN product_attribute AS attr
+        	ON attr.id = attr_value.attribute_id
+            LEFT JOIN res_store_journal_rel AS journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            LEFT JOIN res_currency_rate AS rate
+            ON rate.currency_id = invoice.currency_id
+            LEFT JOIN res_partner AS partner
+            ON partner.id = invoice.partner_id
+            WHERE invoice.state NOT IN ('draft', 'cancel')
+            AND invoice.type = 'in_invoice'
+            AND (invoice.origin NOT LIKE %s OR invoice.origin IS NULL)
+        GROUP BY
+        	invoice.id,
+        	line.id,
+        	invoice.number,
+        	invoice.origin,
+        	invoice.date_invoice,
+        	product.name_template,
+        	line.price_unit,
+        	line.quantity,
+        	line.price_subtotal,
+            journal.store_id,
+            template.categ_id,
+            product.default_code,
+            partner.ruc,
+            partner.name,
+            product.id,
+            invoice.company_id,
+            invoice.journal_id,
+            line.name
+    '''
+
+    r.cr.execute(validate_brand)
+    for j in r.cr.fetchall():
+        brand = j[0]
+
+    if brand == True:
+        r.cr.execute(query_with_brand,([company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate,origin]))
+        return [
+            {
+                'invoice_id': j[0],
+                'invoice_line_id': j[1],
+                'number': j[2],
+                'origin': j[3],
+                'date': j[4],
+                'type': j[5],
+                'product_name':j[6],
+                'price_unit':j[7],
+                'quantity':j[8],
+                'subtotal':j[9],
+                'tax': j[10],
+                'cost': j[11],
+                'store_id': j[12],
+                'categ_id': j[13],
+                'partner_ruc': j[14],
+                'partner_name': j[15],
+                'product_id': j[16],
+                'company_id': j[17],
+                'journal_id': j[18],
+                'attribute_value_ids': j[19],
+                'attribute_values': j[20],
+                'attribute_ids': j[21],
+                'product_brand_id': j[22],
+                'brand_name': j[23],
+                'name': j[24],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        r.cr.execute(query_without_brand,([company_currency_rate,company_currency_rate,company_currency_rate,company_currency_rate,origin]))
+        return [
+            {
+                'invoice_id': j[0],
+                'invoice_line_id': j[1],
+                'number': j[2],
+                'origin': j[3],
+                'date': j[4],
+                'type': j[5],
+                'product_name':j[6],
+                'price_unit':j[7],
+                'quantity':j[8],
+                'subtotal':j[9],
+                'tax': j[10],
+                'cost': j[11],
+                'store_id': j[12],
+                'categ_id': j[13],
+                'partner_ruc': j[14],
+                'partner_name': j[15],
+                'product_id': j[16],
+                'company_id': j[17],
+                'journal_id': j[18],
+                'attribute_value_ids': j[19],
+                'attribute_values': j[20],
+                'attribute_ids': j[21],
+                'name': j[22],
+            } for j in r.cr.fetchall()
+        ]

+ 15 - 0
controller/helpers/account_journal.py

@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+_MODEL = 'account.journal'
+
+def get_account_journal():
+    return [
+        {
+            'id': journal.id,
+            'name': journal.name,
+            'code': journal.code,
+            'type': journal.type,
+            'store_id': journal.store_ids.id
+        } for journal in r.env[_MODEL].search([])
+    ]

+ 42 - 0
controller/helpers/account_move_line.py

@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_move_line():
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+        SELECT
+        	move.id,
+        	move_line.id,
+        	account.id,
+            move.name,
+        	move_line.debit,
+        	move_line.credit,
+        	move_line.date_maturity,
+        	move_line.reconcile_ref,
+            account.type,
+            move_line.reconcile_partial_id
+        FROM account_move AS move
+        LEFT JOIN account_move_line AS move_line
+        ON move_line.move_id = move.id
+        LEFT JOIN account_account AS account
+        ON account.id = move_line.account_id
+        ORDER BY move_line.date_maturity
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'move_id': j[0],
+            'move_line_id': j[1],
+            'account_id': j[2],
+            'name': j[3],
+            'debit': j[4],
+            'credit': j[5],
+            'date_maturity': j[6],
+            'reconcile_ref':j[7],
+            'type':j[8],
+            'reconcile_partial_id':j[9],
+        } for j in r.cr.fetchall()
+    ]

+ 26 - 0
controller/helpers/account_period.py

@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_period():
+    query = '''
+        SELECT
+            id,
+            name,
+            company_id,
+            date_start,
+            date_stop
+        FROM account_period
+        WHERE special = False
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+            'company_id': j[2],
+            'date_start': j[3],
+            'date_stop': j[4],
+        } for j in r.cr.fetchall()
+    ]

+ 297 - 0
controller/helpers/account_voucher.py

@@ -0,0 +1,297 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_account_voucher_all():
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+    SELECT  voucher.id,
+        	voucher.number,
+        	voucher.type,
+        	voucher.date,
+        	journal.currency,
+            voucher.amount,
+        	CASE
+        		WHEN journal.currency IS NULL
+        		THEN voucher.amount
+        		ELSE voucher.amount * (%s / (array_agg(rate.rate ORDER BY rate.name DESC))[1])
+        		END AS amount_currency,
+            voucher.journal_id,
+            voucher.reference
+        FROM account_voucher AS voucher
+        LEFT JOIN res_store_journal_rel AS journal_rel
+        ON voucher.journal_id = journal_rel.journal_id
+        LEFT JOIN account_journal AS journal
+        ON journal.id = voucher.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = journal.currency
+        WHERE voucher.state = 'posted'
+        GROUP BY
+        	voucher.id,
+        	voucher.number,
+        	voucher.type,
+        	voucher.date,
+        	voucher.amount,
+        	journal.name,
+        	journal.currency
+    '''
+
+    r.cr.execute(query,(tuple([company_currency_rate])))
+
+    return [
+        {
+            'id': j[0],
+            'number': j[1],
+            'type': j[2],
+            'date': j[3],
+            'currency_id': j[4],
+            'amount': j[5],
+            'amount_currency': j[6],
+            'journal_id': j[7],
+            'reference': j[8],
+        } for j in r.cr.fetchall()
+    ]
+
+def get_account_voucher_customer():
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+    SELECT  voucher.id,
+        	voucher.number,
+        	voucher.type,
+        	voucher.date,
+        	journal.currency,
+            voucher.amount,
+        	CASE
+        		WHEN journal.currency IS NULL
+        		THEN voucher.amount
+        		ELSE voucher.amount * (%s / (array_agg(rate.rate ORDER BY rate.name DESC))[1])
+        		END AS amount_currency,
+            voucher.journal_id,
+            voucher.reference,
+            journal_rel.store_id,
+            journal.name,
+            invoice.origin,
+            partner.name,
+            voucher.name,
+            voucher.company_id,
+            move.id
+            --,
+        	--move_line.reconcile_ref
+        FROM account_voucher AS voucher
+        LEFT JOIN res_store_journal_rel AS journal_rel
+        ON voucher.journal_id = journal_rel.journal_id
+        LEFT JOIN account_journal AS journal
+        ON journal.id = voucher.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = journal.currency
+        LEFT JOIN account_invoice AS invoice
+        ON invoice.number = voucher.reference
+        LEFT JOIN res_partner AS partner
+        ON partner.id = voucher.partner_id
+        LEFT JOIN account_move AS move
+        ON move.name = voucher.number
+        --LEFT JOIN account_move_line AS move_line
+        --on move_line.move_id = move.id
+        WHERE voucher.state = 'posted'
+        AND voucher.type = 'receipt'
+        --AND move_line.reconcile_ref IS NOT NULL
+        GROUP BY
+        	voucher.id,
+        	voucher.number,
+        	voucher.type,
+        	voucher.date,
+        	voucher.amount,
+        	journal.name,
+        	journal.currency,
+            journal_rel.store_id,
+            invoice.origin,
+            partner.name,
+            move.id
+            --,
+            --move_line.reconcile_ref
+    '''
+
+    r.cr.execute(query,(tuple([company_currency_rate])))
+
+    return [
+        {
+            'id': j[0],
+            'number': j[1],
+            'type': j[2],
+            'date': j[3],
+            'currency_id': j[4],
+            'amount': j[5],
+            'amount_currency': j[6],
+            'journal_id': j[7],
+            'reference': j[8],
+            'store_id': j[9],
+            'journal_name': j[10],
+            'origin': j[11],
+            'partner_name': j[12],
+            'name': j[13],
+            'company_id': j[14],
+            'move_id': j[15],
+            # 'reconcile_ref': j[16],
+        } for j in r.cr.fetchall()
+    ]
+
+def get_account_voucher_supplier():
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+    SELECT  voucher.id,
+        	voucher.number,
+        	voucher.type,
+        	voucher.date,
+        	journal.currency,
+            voucher.amount,
+        	CASE
+        		WHEN journal.currency IS NULL
+        		THEN voucher.amount
+        		ELSE voucher.amount * (%s / (array_agg(rate.rate ORDER BY rate.name DESC))[1])
+        		END AS amount_currency,
+            voucher.journal_id,
+            voucher.reference,
+            journal_rel.store_id,
+            journal.name,
+            invoice.origin,
+            partner.name,
+            voucher.name,
+            voucher.company_id
+        FROM account_voucher AS voucher
+        LEFT JOIN res_store_journal_rel AS journal_rel
+        ON voucher.journal_id = journal_rel.journal_id
+        LEFT JOIN account_journal AS journal
+        ON journal.id = voucher.journal_id
+        LEFT JOIN res_currency_rate AS rate
+        ON rate.currency_id = journal.currency
+        LEFT JOIN account_invoice AS invoice
+        ON invoice.number = voucher.reference
+        LEFT JOIN res_partner AS partner
+        ON partner.id = voucher.partner_id
+        WHERE voucher.state = 'posted'
+        AND voucher.type = 'payment'
+        GROUP BY
+        	voucher.id,
+        	voucher.number,
+        	voucher.type,
+        	voucher.date,
+        	voucher.amount,
+        	journal.name,
+        	journal.currency,
+            journal_rel.store_id,
+            invoice.origin,
+            partner.name
+    '''
+
+    r.cr.execute(query,(tuple([company_currency_rate])))
+
+    return [
+        {
+            'id': j[0],
+            'number': j[1],
+            'type': j[2],
+            'date': j[3],
+            'currency_id': j[4],
+            'amount': j[5],
+            'amount_currency': j[6],
+            'journal_id': j[7],
+            'reference': j[8],
+            'store_id': j[9],
+            'journal_name': j[10],
+            'origin': j[11],
+            'partner_name': j[12],
+            'name': j[13],
+            'company_id': j[14],
+        } for j in r.cr.fetchall()
+    ]
+
+
+def get_account_voucher_payment():
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+    query = '''
+    SELECT
+        voucher.id,
+        voucher.number,
+        voucher.type,
+        voucher.date,
+        journal.currency,
+        voucher_line.amount_original,
+        voucher_line.amount,
+        CASE
+            WHEN journal.currency IS NULL
+        	THEN voucher_line.amount
+        	ELSE voucher_line.amount * (%s / (array_agg(rate.rate ORDER BY rate.name DESC))[1])
+        	END AS amount_currency,
+        voucher.journal_id,
+        voucher.reference,
+        journal_rel.store_id,
+        journal.name,
+        partner.name,
+        invoice.number,
+        invoice.residual,
+        voucher.company_id,
+	    move_line.date_maturity,
+        voucher.name,
+        move_line.reconcile_ref
+    FROM account_voucher AS voucher
+    LEFT JOIN res_store_journal_rel AS journal_rel
+    ON voucher.journal_id = journal_rel.journal_id
+    LEFT JOIN account_journal AS journal
+    ON journal.id = voucher.journal_id
+    LEFT JOIN res_currency_rate AS rate
+    ON rate.currency_id = journal.currency
+    LEFT JOIN account_invoice AS invoice
+    ON invoice.number = voucher.reference
+    LEFT JOIN res_partner AS partner
+    ON partner.id = voucher.partner_id
+	LEFT JOIN account_voucher_line AS voucher_line
+	ON voucher_line.voucher_id = voucher.id
+    LEFT JOIN account_move_line AS move_line
+    ON move_line.id = voucher_line.move_line_id
+    WHERE voucher.state = 'posted'
+    AND voucher.type = 'receipt'
+    AND move_line.reconcile_ref IS NOT NULL
+    GROUP BY
+        voucher.id,
+        voucher.number,
+        voucher.type,
+        voucher.date,
+        voucher_line.amount_original,
+        voucher_line.amount,
+        journal.name,
+        journal.currency,
+		journal_rel.store_id,
+		invoice.origin,
+		invoice.number,
+        invoice.residual,
+        partner.name,
+	    move_line.date_maturity,
+        voucher.name,
+        move_line.reconcile_ref
+
+    '''
+    r.cr.execute(query,(tuple([company_currency_rate])))
+
+    return [
+        {
+            'id': j[0],
+            'number': j[1],
+            'type': j[2],
+            'date': j[3],
+            'currency_id': j[4],
+            'amount_original': j[5],
+            'amount': j[6],
+            'amount_currency': j[7],
+            'journal_id': j[8],
+            'reference': j[9],
+            'store_id': j[10],
+            'journal_name': j[11],
+            'partner_name': j[12],
+            'invoice_number': j[13],
+            'residual': j[14],
+            'company_id': j[15],
+            'date_maturity': j[16],
+            'name': j[17],
+            'reconcile_ref': j[18],
+
+        } for j in r.cr.fetchall()
+    ]

+ 15 - 0
controller/helpers/company_logo.py

@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+_MODEL = 'res.company'
+
+def get_company_logo():
+    # domain = [
+    #     ('expense','=', True)
+    # ]
+    return [
+        {
+            'id': company.id,
+            'logo': company.image_medium,
+        } for company in r.env[_MODEL].search()
+    ]

+ 79 - 0
controller/helpers/pos_order.py

@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_pos_order():
+    user_store = r.env.user.store_id.id
+
+    validate = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='pos_order')
+    '''
+
+    query = '''
+        SELECT
+            pos.create_date,
+            pos.name,
+            pos.partner_id,
+            pos.user_id,
+            SUM(line.price_subtotal_incl) as amount,
+            partner.name,
+            pos.id,
+            salesperson.name,
+            SUM(line.price_subtotal) as untaxed,
+            pos.sale_journal,
+            journal.store_id,
+            pos.company_id,
+            partner.ruc
+        FROM pos_order as pos
+        LEFT JOIN res_store_journal_rel as journal
+        ON journal.journal_id = pos.sale_journal
+        LEFT JOIN pos_order_line AS line
+        ON line.order_id = pos.id
+        LEFT JOIN res_partner AS partner
+        ON partner.id = pos.partner_id
+        LEFT JOIN res_users AS users
+        ON users.id = pos.user_id
+        LEFT JOIN res_partner AS salesperson
+        ON salesperson.id = users.partner_id
+        GROUP BY
+            pos.create_date,
+            pos.partner_id,
+            pos.user_id,
+            pos.name,
+            partner.name,
+            pos.id,
+            salesperson.name,
+            pos.sale_journal,
+            journal.store_id,
+            pos.company_id,
+            partner.ruc
+    '''
+
+    r.cr.execute(validate)
+    for j in r.cr.fetchall():
+        band = j[0]
+
+    if band == True:
+        r.cr.execute(query)
+        return [
+            {
+                'date': j[0],
+                'name': j[1],
+                'customer_id': j[2],
+                'user_id': j[3],
+                'amount': j[4],
+                'customer_name': j[5],
+                'order_id': j[6],
+                'user_name': j[7],
+                'amount_untaxed': j[8],
+                'journal_id': j[9],
+                'store_id': j[10],
+                'company_id': j[11],
+                'customer_ruc': j[12],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        return []

+ 242 - 0
controller/helpers/pos_order_line.py

@@ -0,0 +1,242 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_pos_order_line():
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+
+    validate = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='pos_order')
+    '''
+
+    validate_brand = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='product_brand')
+    '''
+
+    query_with_brand = '''
+        SELECT
+        	pos.id,
+        	line.id,
+        	pos.name,
+        	CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit,
+        	line.qty,
+        	line.price_subtotal,
+        	line.price_subtotal_incl - line.price_subtotal AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            history.product_template_id,
+            journal.store_id,
+            pos.date_order,
+            pos.company_id,
+            pos.sale_journal,
+            template.categ_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            template.product_brand_id,
+            brand.name,
+            product.id,
+            customer.ruc,
+            customer.name,
+            customer.id,
+            line.discount
+        FROM pos_order AS pos
+        LEFT JOIN pos_order_line AS line
+        ON pos.id = line.order_id
+        LEFT JOIN res_store_journal_rel as journal
+        ON journal.journal_id = pos.sale_journal
+        LEFT JOIN product_product as product
+        ON product.id = line.product_id
+        LEFT JOIN product_template as template
+        ON template.id = product.product_tmpl_id
+        LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        ON attr_rel.prod_id = product.id
+        LEFT JOIN product_attribute_value AS attr_value
+        ON attr_value.id = attr_rel.att_id
+        LEFT JOIN product_attribute AS attr
+        ON attr.id = attr_value.attribute_id
+        LEFT JOIN product_price_history AS history
+        ON history.product_template_id = product.product_tmpl_id
+        LEFT JOIN product_brand AS brand
+        ON brand.id = template.product_brand_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = pos.partner_id
+        WHERE pos.state NOT IN ('draft')
+        GROUP BY
+        	pos.id,
+        	line.id,
+        	pos.name,
+        	product.name_template,
+        	line.price_unit,
+        	line.qty,
+        	line.price_subtotal,
+            history.product_template_id,
+            journal.store_id,
+            pos.date_order,
+            pos.company_id,
+            pos.sale_journal,
+            template.categ_id,
+            product.default_code,
+            template.product_brand_id,
+            brand.name,
+            product.id,
+            customer.ruc,
+            customer.name,
+            customer.id
+    '''
+
+    query_without_brand = '''
+        SELECT
+        	pos.id,
+        	line.id,
+        	pos.name,
+        	CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	line.price_unit,
+        	line.qty,
+        	line.price_subtotal,
+        	line.price_subtotal_incl - line.price_subtotal AS impuestos,
+        	(array_agg(history.cost ORDER BY history.id DESC))[1] AS cost,
+            history.product_template_id,
+            journal.store_id,
+            pos.date_order,
+            pos.company_id,
+            pos.sale_journal,
+            template.categ_id,
+            (array_agg(attr_rel.att_id)) AS attr_rel,
+            (array_agg(attr_value.name)) AS attr_value,
+            (array_agg(attr.id)) AS attr,
+            product.id,
+            customer.ruc,
+            customer.name,
+            customer.id,
+            line.discount
+        FROM pos_order AS pos
+        LEFT JOIN pos_order_line AS line
+        ON pos.id = line.order_id
+        LEFT JOIN res_store_journal_rel as journal
+        ON journal.journal_id = pos.sale_journal
+        LEFT JOIN product_product as product
+        ON product.id = line.product_id
+        LEFT JOIN product_template as template
+        ON template.id = product.product_tmpl_id
+        LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        ON attr_rel.prod_id = product.id
+        LEFT JOIN product_attribute_value AS attr_value
+        ON attr_value.id = attr_rel.att_id
+        LEFT JOIN product_attribute AS attr
+        ON attr.id = attr_value.attribute_id
+        LEFT JOIN product_price_history AS history
+        ON history.product_template_id = product.product_tmpl_id
+        LEFT JOIN res_partner AS customer
+        ON customer.id = pos.partner_id
+        WHERE pos.state NOT IN ('draft')
+        GROUP BY
+        	pos.id,
+        	line.id,
+        	pos.name,
+        	product.name_template,
+        	line.price_unit,
+        	line.qty,
+        	line.price_subtotal,
+            history.product_template_id,
+            journal.store_id,
+            pos.date_order,
+            pos.company_id,
+            pos.sale_journal,
+            template.categ_id,
+            product.default_code,
+            product.id,
+            customer.ruc,
+            customer.name,
+            customer.id
+    '''
+
+    r.cr.execute(validate)
+
+    for j in r.cr.fetchall():
+        band = j[0]
+
+    if band == True:
+        r.cr.execute(validate_brand)
+
+        for j in r.cr.fetchall():
+            brand = j[0]
+
+        if brand == True:
+            r.cr.execute(query_with_brand,(tuple([company_currency_rate,company_currency_rate])))
+            return [
+                {
+                    'order_id': j[0],
+                    'order_line_id': j[1],
+                    'name': j[2],
+                    'product_name':j[3],
+                    'price_unit':j[4],
+                    'quantity':j[5],
+                    'subtotal':j[6],
+                    'tax': j[7],
+                    'cost': j[8],
+                    'template_id': j[9],
+                    'store_id': j[10],
+                    'date': j[11],
+                    'company_id': j[12],
+                    'journal_id': j[13],
+                    'categ_id': j[14],
+                    'attribute_value_ids': j[15],
+                    'attribute_values': j[16],
+                    'attribute_ids': j[17],
+                    'product_brand_id': j[18],
+                    'brand_name': j[19],
+                    'product_id': j[20],
+                    'customer_ruc': j[21],
+                    'customer_name': j[22],
+                    'customer_id': j[23],
+                    'discount': j[24],
+                } for j in r.cr.fetchall()
+            ]
+        else:
+            r.cr.execute(query_without_brand,(tuple([company_currency_rate,company_currency_rate])))
+            return [
+                {
+                    'order_id': j[0],
+                    'order_line_id': j[1],
+                    'name': j[2],
+                    'product_name':j[3],
+                    'price_unit':j[4],
+                    'quantity':j[5],
+                    'subtotal':j[6],
+                    'tax': j[7],
+                    'cost': j[8],
+                    'template_id': j[9],
+                    'store_id': j[10],
+                    'date': j[11],
+                    'company_id': j[12],
+                    'journal_id': j[13],
+                    'categ_id': j[14],
+                    'attribute_value_ids': j[15],
+                    'attribute_values': j[16],
+                    'attribute_ids': j[17],
+                    'product_id': j[18],
+                    'customer_ruc': j[19],
+                    'customer_name': j[20],
+                    'customer_id': j[21],
+                    'discount': j[22],
+                } for j in r.cr.fetchall()
+            ]
+    else:
+        return []

+ 17 - 0
controller/helpers/product_attribute.py

@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_product_attribute():
+    query = '''
+        SELECT
+            id,
+            name
+        FROM product_attribute
+    '''
+    r.cr.execute(query)
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+        } for j in r.cr.fetchall()
+    ]

+ 23 - 0
controller/helpers/product_attribute_value.py

@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_product_attribute_value():
+    query = '''
+        SELECT
+            attribute_value.id,
+            attribute_value.name,
+            attribute_value.attribute_id,
+            attribute.name
+        FROM product_attribute_value AS attribute_value
+        LEFT JOIN product_attribute AS attribute
+        ON attribute.id = attribute_value.attribute_id
+    '''
+    r.cr.execute(query)
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+            'attribute_id': j[2],
+            'attribute_name': j[3],
+        } for j in r.cr.fetchall()
+    ]

+ 33 - 0
controller/helpers/product_brand.py

@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_product_brand():
+    validate = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='product_brand')
+    '''
+
+    query = '''
+        SELECT
+            id,
+            name
+        FROM product_brand
+    '''
+
+    r.cr.execute(validate)
+    for j in r.cr.fetchall():
+        band = j[0]
+
+    if band == True:
+        r.cr.execute(query)
+        return [
+            {
+                'id': j[0],
+                'name': j[1],
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        return []

+ 25 - 0
controller/helpers/product_category.py

@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+_MODEL = 'product.category'
+
+def get_product_category_all():
+    return [
+        {
+            'id': category.id,
+            'name': category.display_name,
+            'parent_id': category.parent_id.id,
+        } for category in r.env[_MODEL].search([])
+    ]
+
+def get_product_category_expense():
+    domain = [
+        ('expense','=', True)
+    ]
+    return [
+        {
+            'id': category.id,
+            'name': category.display_name,
+            'parent_id': category.parent_id.id,
+        } for category in r.env[_MODEL].search(domain)
+    ]

+ 106 - 0
controller/helpers/product_product.py

@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_product_product():
+    user_store = r.env.user.store_id.id
+    company_currency_rate = r.env.user.company_id.currency_id.rate
+
+    validate_brand = '''
+        SELECT EXISTS(
+            SELECT table_name
+            FROM information_schema.columns
+            WHERE table_schema='public'
+                AND table_name='product_brand')
+    '''
+
+    query_with_brand = '''
+        SELECT
+        	product.id,
+        	template.categ_id,
+        	CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	(array_agg(attr_rel.att_id)) AS attr_rel,
+        	(array_agg(attr_value.name)) AS attr_value,
+        	(array_agg(attr.id)) AS attr,
+        	template.product_brand_id,
+        	brand.name
+        FROM product_product AS product
+        LEFT JOIN product_template AS template
+        ON template.id = product.product_tmpl_id
+        LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        ON attr_rel.prod_id = product.id
+        LEFT JOIN product_attribute_value AS attr_value
+        ON attr_value.id = attr_rel.att_id
+        LEFT JOIN product_attribute AS attr
+        ON attr.id = attr_value.attribute_id
+        LEFT JOIN product_brand AS brand
+        ON brand.id = template.product_brand_id
+        GROUP BY
+        	product.id,
+        	template.categ_id,
+        	product.default_code,
+        	template.product_brand_id,
+        	brand.name
+    '''
+
+    query_without_brand = '''
+        SELECT
+        	product.id,
+        	template.categ_id,
+        	CASE
+        		WHEN product.default_code IS NOT NULL
+        		THEN ('[' || product.default_code || '] ' || product.name_template)
+        		ELSE product.name_template
+        		END AS display_name,
+        	(array_agg(attr_rel.att_id)) AS attr_rel,
+        	(array_agg(attr_value.name)) AS attr_value,
+        	(array_agg(attr.id)) AS attr
+        FROM product_product AS product
+        LEFT JOIN product_template AS template
+        ON template.id = product.product_tmpl_id
+        LEFT JOIN product_attribute_value_product_product_rel AS attr_rel
+        ON attr_rel.prod_id = product.id
+        LEFT JOIN product_attribute_value AS attr_value
+        ON attr_value.id = attr_rel.att_id
+        LEFT JOIN product_attribute AS attr
+        ON attr.id = attr_value.attribute_id
+        GROUP BY
+        	product.id,
+        	template.categ_id,
+        	product.default_code
+    '''
+
+    r.cr.execute(validate_brand)
+
+    for j in r.cr.fetchall():
+        brand = j[0]
+
+    if brand == True:
+        r.cr.execute(query_with_brand,([company_currency_rate]))
+        return [
+            {
+                'product_id': j[0],
+                'categ_id': j[1],
+                'product_name': j[2],
+                'attribute_value_ids':j[3],
+                'attribute_values':j[4],
+                'attribute':j[5],
+                'product_brand_id':j[6],
+                'brand_name': j[7]
+            } for j in r.cr.fetchall()
+        ]
+    else:
+        r.cr.execute(query_without_brand,([company_currency_rate]))
+        return [
+            {
+                'product_id': j[0],
+                'categ_id': j[1],
+                'product_name': j[2],
+                'attribute_value_ids':j[3],
+                'attribute_values':j[4],
+                'attribute':j[5],
+            } for j in r.cr.fetchall()
+        ]

+ 26 - 0
controller/helpers/report_category.py

@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_report_category():
+    query = '''
+        SELECT
+            category.id,
+            category.name,
+            category.name_template,
+            category.description,
+            category.icon_code
+        FROM report_category AS category
+        ORDER BY category.sequence
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+            'name_template': j[2],
+            'description': j[3],
+            'icon_code': j[4],
+        } for j in r.cr.fetchall()
+    ]

+ 28 - 0
controller/helpers/report_report.py

@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_report_report():
+    query = '''
+        SELECT
+            report.id,
+            report.name,
+            report.name_template,
+            report.description,
+            report.icon_code,
+            report.category_id
+        FROM report_report AS report
+        ORDER BY report.sequence
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+            'name_template': j[2],
+            'description': j[3],
+            'icon_code': j[4],
+            'category_id': j[5],
+        } for j in r.cr.fetchall()
+    ]

+ 62 - 0
controller/helpers/res_company.py

@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+_MODEL = 'res.company'
+
+def get_company_logo():
+    domain = [
+        # ('expense','=', True)
+    ]
+    return [
+        {
+            'id': company.id,
+            'logo': company.logo,
+        } for company in r.env[_MODEL].search(domain)
+    ]
+
+def get_res_company():
+    user_company = r.env.user.company_id.id
+    user_store = r.env.user.store_id.id
+    query = '''
+        SELECT
+            company.id,
+            company.name,
+            currency.id,
+            currency.name,
+            currency.symbol,
+            currency.decimal_places,
+            currency.decimal_separator,
+            currency.thousands_separator,
+            currency.symbol_position,
+            store.name AS store,
+            partner.ruc AS company_ruc
+        FROM res_company AS company
+        LEFT JOIN res_currency AS currency
+        ON company.currency_id = currency.id
+        LEFT JOIN res_store AS store
+        ON store.id = ''' + str(user_store) + '''
+        LEFT JOIN res_partner AS partner
+        ON partner.id = company.partner_id
+        WHERE currency.active = true
+        ORDER BY company.id ASC
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+            'currency_id':{
+                'id':  j[2],
+                'name':  j[3],
+                'symbol':  j[4],
+                'decimal_places':  j[5],
+                'decimal_separator':  j[6],
+                'thousands_separator':  j[7],
+                'symbol_position':  j[8],
+            },
+            'store': j[9],
+            'ruc': j[10],
+        } for j in r.cr.fetchall()
+    ]

+ 21 - 0
controller/helpers/res_partner.py

@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_res_partner():
+    query = '''
+        SELECT
+            partner.id,
+            partner.name,
+            partner.ruc
+        FROM res_partner AS partner
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'name': j[1],
+            'ruc': j[2],
+        } for j in r.cr.fetchall()
+    ]

+ 13 - 0
controller/helpers/res_store.py

@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+_MODEL = 'res.store'
+
+def get_res_store():
+    return [
+        {
+            'id': store.id,
+            'name': store.name,
+            'company_id': store.company_id.id,
+        } for store in r.env[_MODEL].search([])
+    ]

+ 27 - 0
controller/helpers/res_users.py

@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+def get_res_users():
+    query = '''
+        SELECT
+            users.id,
+            users.company_id,
+            users.store_id,
+            partner.name
+        FROM res_users AS users
+        LEFT JOIN res_partner AS partner
+        ON partner.id = users.partner_id
+        WHERE users.active = true
+    '''
+
+    r.cr.execute(query)
+
+    return [
+        {
+            'id': j[0],
+            'company_id': j[1],
+            'store_id': j[2],
+            'name': j[3],
+
+        } for j in r.cr.fetchall()
+    ]

+ 182 - 0
controller/main.py

@@ -0,0 +1,182 @@
+# -*- coding: utf-8 -*-
+from openerp import http
+from werkzeug.wrappers import Response
+from werkzeug.datastructures import Headers
+from gzip import GzipFile
+from StringIO import StringIO as IO
+import simplejson as json
+import helpers as hp
+import logging
+
+LOGGER = logging.getLogger(__name__)
+GZIP_COMPRESSION_LEVEL = 9
+
+def make_gzip_response(data=None, status=200):
+    gzip_buffer = IO()
+
+    with GzipFile(mode='wb', compresslevel=GZIP_COMPRESSION_LEVEL, fileobj=gzip_buffer) as gzip_file:
+        gzip_file.write(json.dumps(data))
+
+    value = gzip_buffer.getvalue()
+    gzip_buffer.close()
+
+    headers = Headers()
+    headers.add('Content-Encoding', 'gzip')
+    headers.add('Vary', 'Accept-Encoding')
+    headers.add('Content-Length', len(value))
+
+    return Response(value, status=status, headers=headers, content_type='application/json')
+
+class ReportController(http.Controller):
+
+    # CONSULTA INICIAL
+    @http.route('/report-filter-data', auth='user', methods=['GET', 'POST'])
+    def getFilterData(self, **kw):
+        return make_gzip_response({
+            'companies': hp.get_res_company(),
+            'logo': hp.get_company_logo(),
+            'stores': hp.get_res_store(),
+            'journals': hp.get_account_journal(),
+            'users': hp.get_res_users(),
+            'categories': hp.get_product_category_all(),
+            'brands': hp.get_product_brand(),
+            'attributes': hp.get_product_attribute(),
+            'attribute_values': hp.get_product_attribute_value(),
+        })
+
+    # HISTORICO DE VENTAS
+    @http.route('/report-sale-history', auth='user', methods=['GET', 'POST'])
+    def getSaleHistory(self, **kw):
+        return make_gzip_response({
+            'invoices': hp.get_account_invoice_sale_type(),
+            'orders': hp.get_pos_order(),
+            'vouchers': hp.get_account_voucher_customer(),
+        })
+
+    # ANALISIS DE VENTAS
+    @http.route('/report-sale-analytic', auth='user', methods=['GET', 'POST'])
+    def getSaleAnalytic(self, **kw):
+        return make_gzip_response({
+            'invoice_lines': hp.get_account_invoice_line_out_invoice(),
+            'order_lines': hp.get_pos_order_line(),
+        })
+
+    # HISTORICO DE COMPRAS
+    @http.route('/report-purchase-history', auth='user', methods=['GET', 'POST'])
+    def getPurchaseHistory(self, **kw):
+        return make_gzip_response({
+            'invoices': hp.get_account_invoice_purchase_type(),
+            'vouchers': hp.get_account_voucher_supplier(),
+        })
+
+    # ANALISIS DE COMPRAS
+    @http.route('/report-purchase-analytic', auth='user', methods=['GET', 'POST'])
+    def getPurchaseAnalytic(self, **kw):
+        return make_gzip_response({
+            'invoice_lines': hp.get_account_invoice_line_in_invoice_purchase(),
+            'invoices': hp.get_account_invoice_purchase_type(),
+        })
+
+    # HISTORICO DE GASTOS
+    @http.route('/report-expense-history', auth='user', methods=['GET', 'POST'])
+    def getExpenseHistory(self, **kw):
+        return make_gzip_response({
+            'invoices': hp.get_account_invoice_expense_type(),
+            'vouchers': hp.get_account_voucher_supplier(),
+        })
+
+    # ANALISIS DE GASTOS
+    @http.route('/report-expense-analytic', auth='user', methods=['GET', 'POST'])
+    def getExpenseAnalytic(self, **kw):
+        return make_gzip_response({
+            'invoice_lines': hp.get_account_invoice_line_in_invoice_expense(),
+            'invoices': hp.get_account_invoice_expense_type(),
+        })
+
+    # RANKING DE PRODUCTOS
+    @http.route('/report-sale-product-ranking', auth='user', methods=['GET', 'POST'])
+    def getSaleProductRanking(self, **kw):
+        return make_gzip_response({
+            'invoice_lines': hp.get_account_invoice_line_out_invoice_and_out_refund(),
+            'order_lines': hp.get_pos_order_line(),
+            'products': hp.get_product_product(),
+        })
+
+    # RANKING DE CLIENTES
+    @http.route('/report-sale-customer-ranking', auth='user', methods=['GET', 'POST'])
+    def getSaleCustomerRanking(self, **kw):
+        return make_gzip_response({
+            'invoice_lines': hp.get_account_invoice_line_out_invoice_and_out_refund(),
+            'order_lines': hp.get_pos_order_line(),
+            'partners': hp.get_res_partner(),
+        })
+
+    # RESUMEN DE VENTAS
+    @http.route('/report-sale-summary', auth='user', methods=['GET', 'POST'])
+    def getSaleSummary(self, **kw):
+        return make_gzip_response({
+            'invoices': hp.get_account_invoice_sale_and_refund_type(),
+            'orders': hp.get_pos_order(),
+        })
+
+    # PERDIDAS Y GANANCIAS
+    @http.route('/report-profit-loss', auth='user', methods=['GET', 'POST'])
+    def getProfitLoss(self, **kw):
+        return make_gzip_response({
+            'invoice_lines': hp.get_account_invoice_line_all_type(),
+            'order_lines': hp.get_pos_order_line(),
+            'product_categories': hp.get_product_category_expense(),
+        })
+
+    # ANALISIS DE UTILIDAD DE VENTAS
+    @http.route('/report-sale-utility-analytic', auth='user', methods=['GET', 'POST'])
+    def getSaleUtilityAnalytic(self, **kw):
+        return make_gzip_response({
+            'invoice_lines': hp.get_account_invoice_line_out_invoice_and_out_refund(),
+            'order_lines': hp.get_pos_order_line(),
+        })
+
+    # PAGOS DE CLIENTES
+    @http.route('/report-account-voucher-customer-payment', auth='user', methods=['GET', 'POST'])
+    def getCustomerAccountVoucher(self, **kw):
+        return make_gzip_response({
+            'vouchers': hp.get_account_voucher_payment(),
+            'statement_lines': hp.get_account_bank_statement_line(),
+            'move_lines': hp.get_account_move_line(),
+            'invoices': hp.get_account_invoice_sale_type(),
+        })
+
+    # PAGOS A PROVEEDORES
+    @http.route('/report-supplier-account-voucher', auth='user', methods=['GET', 'POST'])
+    def getSupplierAccountVoucher(self, **kw):
+        return make_gzip_response({
+            'vouchers': hp.get_account_voucher_supplier(),
+            'invoices': hp.get_account_invoice_purchase_type(),
+        })
+
+
+    # PAGOS DE CLIENTES
+    @http.route('/report-account-voucherrefund-customer-payment', auth='user', methods=['GET', 'POST'])
+    def getCustomerAccountRefundVoucher(self, **kw):
+        return make_gzip_response({
+            'vouchers': hp.get_account_voucher_payment(),
+            'statement_lines': hp.get_account_bank_statement_line(),
+            'move_lines': hp.get_account_move_line(),
+            'invoices': hp.get_account_invoice_sale_and_refund_type(),
+        })
+
+    # LIBRO DE VENTAS
+    @http.route('/report-sale-journal', auth='user', methods=['GET', 'POST'])
+    def getSaleJournal(self, **kw):
+        return make_gzip_response({
+            'invoices': hp.get_account_invoice_sale_type(),
+            'orders': hp.get_pos_order(),
+        })
+
+    # LIBRO DE COMPRAS
+    @http.route('/report-purchase-journal', auth='user', methods=['GET', 'POST'])
+    def getPurchaseJournal(self, **kw):
+        return make_gzip_response({
+            'invoice_lines': hp.get_account_invoice_line_in_invoice_expense(),
+            'orders': hp.get_account_invoice_expense_type(),
+        })

+ 822 - 0
models.py

@@ -0,0 +1,822 @@
+# -*- coding: utf-8 -*-
+
+from openerp import models, fields, api
+
+class AccountInvoice(models.Model):
+	_inherit = 'account.invoice'
+
+	############################################################
+	#	ACCOUNT INVOICE
+	############################################################
+
+	@api.model
+	def getAccountInvoice(self,domain):
+		AccountInvoice = self.env['account.invoice'].search(domain)
+		decimal_precision = self.env['decimal.precision'].precision_get('Account')
+		values = []
+		for invoice in AccountInvoice:
+			values.append({
+				'id': invoice.id,
+				'type': invoice.type,
+				'state': invoice.state,
+				'number': invoice.number,
+				'journal_id': [
+					invoice.journal_id.id,
+					invoice.journal_id.name
+				],
+				'journal_type': invoice.journal_id.type,
+				'invoice_currency': [
+					invoice.currency_id.id,
+					invoice.currency_id.name,
+					invoice.currency_id.rate
+				],
+				'company_currency': [
+					invoice.company_id.currency_id.id,
+					invoice.company_id.currency_id.name,
+					invoice.company_id.currency_id.rate
+				],
+				'date_invoice': invoice.date_invoice,
+				'partner_id': [
+					invoice.partner_id.id,
+					invoice.partner_id.name,
+					invoice.partner_id.ruc
+				],
+				'partner_info': {
+					'mobile': invoice.partner_id.mobile,
+					'phone': invoice.partner_id.phone,
+				},
+				'supplier_invoice_number': invoice.supplier_invoice_number,
+				'user_id': [
+					invoice.user_id.id,
+					invoice.user_id.name
+				],
+                'period_id': [
+                	invoice.period_id.id,
+                	invoice.period_id.name
+                ],
+                'amount_untaxed': invoice.amount_untaxed,
+                'origin': invoice.origin,
+                'residual': invoice.residual,
+                'amount_tax': invoice.amount_tax,
+				'amount_total': invoice.amount_total,
+				'amount_untaxed_currency': invoice.amount_untaxed * (invoice.company_id.currency_id.rate / invoice.currency_id.rate),
+				'residual_currency': invoice.residual * (invoice.company_id.currency_id.rate / invoice.currency_id.rate),
+				'amount_tax_currency': invoice.amount_tax * (invoice.company_id.currency_id.rate / invoice.currency_id.rate),
+				'amount_total_currency': invoice.amount_total * (invoice.company_id.currency_id.rate / invoice.currency_id.rate),
+			})
+
+		return values
+
+	############################################################
+	#	POS ORDER
+	############################################################
+
+	@api.model
+	def getPosOrder(self,domain):
+		PosOrder = self.env['pos.order'].search(domain)
+		decimal_precision = self.env['decimal.precision'].precision_get('Account')
+		values = []
+		for order in PosOrder:
+			values.append({
+				'id': order.id,
+				'name': order.name,
+				'date_order': order.date_order,
+				'pricelist_id':[
+					order.pricelist_id.id,
+					order.pricelist_id.name,
+				],
+				'sale_journal':[
+					order.sale_journal.id,
+					order.sale_journal.name,
+				],
+				'partner_id': [
+					order.partner_id.id,
+					order.partner_id.name,
+					order.partner_id.ruc,
+				],
+				'user_id': [
+					order.user_id.id,
+					order.user_id.name
+				],
+				'session_id': [
+					order.session_id.id,
+					order.session_id.name
+				],
+				'order_currency': [
+					order.pricelist_id.currency_id.id,
+					order.pricelist_id.currency_id.name,
+					order.pricelist_id.currency_id.rate
+				],
+				'company_currency': [
+					order.company_id.currency_id.id,
+					order.company_id.currency_id.name,
+					order.company_id.currency_id.rate
+				],
+                'amount_tax': order.amount_tax,
+                'amount_total': order.amount_total,
+				'amount_tax_currency': order.amount_tax * (order.company_id.currency_id.rate / order.pricelist_id.currency_id.rate),
+				'amount_total_currency': order.amount_total * (order.company_id.currency_id.rate / order.pricelist_id.currency_id.rate),
+			})
+
+		return values
+
+class AccountInvoiceLine(models.Model):
+	_inherit = 'account.invoice.line'
+
+	############################################################
+	#	ACCOUNT INVOICE LINE
+	############################################################
+
+	@api.model
+	def getAccountInvoiceLine(self,domain):
+		AccountInvoiceLine = self.env['account.invoice.line'].search(domain)
+		decimal_precision = self.env['decimal.precision'].precision_get('Account')
+		values = []
+		# factory_reference = ''
+		for line in AccountInvoiceLine:
+
+			values.append({
+				'id': line.id,
+				'invoice_id':line.invoice_id.id,
+				'number':line.invoice_id.number,
+				'supplier_invoice_number':line.invoice_id.supplier_invoice_number,
+				'date_invoice': line.invoice_id.date_invoice,
+				'user_id': [
+					line.invoice_id.user_id.id,
+					line.invoice_id.user_id.name,
+				],
+				'partner_id': [
+					line.invoice_id.partner_id.id,
+					line.invoice_id.partner_id.name,
+					line.invoice_id.partner_id.ruc,
+				],
+				'store_id': [
+					line.invoice_id.journal_id.store_ids.id,
+					line.invoice_id.journal_id.store_ids.name,
+				],
+				'period_id': [
+					line.invoice_id.period_id.id,
+					line.invoice_id.period_id.name,
+				],
+				'journal_id': [
+					line.invoice_id.journal_id.id,
+					line.invoice_id.journal_id.name,
+				],
+				'invoice_state': line.invoice_id.state,
+				'journal_type': line.invoice_id.journal_id.type,
+				'invoice_type': line.invoice_id.type,
+				'product_id': [
+					line.product_id.id,
+					line.product_id.display_name,
+					line.product_id.categ_id.complete_name,
+					line.product_id.standard_price,
+					line.product_id.factory_reference,
+				],
+				'product_category_id': line.product_id.categ_id.id,
+				'price_unit': line.price_unit,
+				'price_subtotal': line.price_subtotal,
+				'quantity': line.quantity,
+				'name': line.name,
+				'company_currency':[
+					line.invoice_id.company_id.currency_id.id,
+					line.invoice_id.company_id.currency_id.name,
+					line.invoice_id.company_id.currency_id.rate,
+				],
+				'invoice_currency':[
+					line.invoice_id.currency_id.id,
+					line.invoice_id.currency_id.name,
+					line.invoice_id.currency_id.rate,
+				],
+				'price_unit_currency': round(line.price_unit * (line.invoice_id.company_id.currency_id.rate / line.invoice_id.currency_id.rate),decimal_precision),
+				'price_subtotal_currency': round(line.price_subtotal * (line.invoice_id.company_id.currency_id.rate / line.invoice_id.currency_id.rate),decimal_precision),
+				'tax_currency': round((line.price_unit * (line.invoice_id.company_id.currency_id.rate / line.invoice_id.currency_id.rate) * line.quantity) - line.price_subtotal * (line.invoice_id.company_id.currency_id.rate / line.invoice_id.currency_id.rate),decimal_precision),
+				'amount_currency': round((line.quantity * line.price_unit) * (line.invoice_id.company_id.currency_id.rate / line.invoice_id.currency_id.rate),decimal_precision),
+			})
+
+		return values
+
+	############################################################
+	#	POS ORDER LINE
+	############################################################
+
+	@api.model
+	def getPosOrderLine(self,domain):
+		PosOrderLine = self.env['pos.order.line'].search(domain)
+		decimal_precision = self.env['decimal.precision'].precision_get('Account')
+		values = []
+		for line in PosOrderLine:
+			values.append({
+				'id': line.id,
+				'order_id': [
+					line.order_id.id,
+					line.order_id.name
+				],
+				'product_id': [
+					line.product_id.id,
+					line.product_id.display_name,
+					line.product_id.standard_price,
+				],
+				'store_id': [
+					line.order_id.sale_journal.store_ids.id,
+					line.order_id.sale_journal.store_ids.name,
+				],
+				'sale_journal': [
+					line.order_id.sale_journal.id,
+					line.order_id.sale_journal.name,
+				],
+				'qty': line.qty,
+				'create_date': line.create_date,
+				'user_id': [
+					line.order_id.user_id.id,
+					line.order_id.user_id.name
+				],
+				'partner_id': [
+					line.order_id.partner_id.id,
+					line.order_id.partner_id.name,
+				],
+				'company_currency':[
+					line.order_id.company_id.currency_id.id,
+					line.order_id.company_id.currency_id.name,
+					line.order_id.company_id.currency_id.rate,
+				],
+				'order_currency':[
+					line.order_id.pricelist_id.currency_id.id,
+					line.order_id.pricelist_id.currency_id.name,
+					line.order_id.pricelist_id.currency_id.rate,
+				],
+				'price_unit': line.price_unit,
+				'price_subtotal': line.price_subtotal,
+				'price_subtotal_incl': line.price_subtotal_incl,
+				'price_unit_currency': round(line.price_unit * (line.order_id.company_id.currency_id.rate / line.order_id.pricelist_id.currency_id.rate),decimal_precision),
+				'price_subtotal_currency': round(line.price_subtotal * (line.order_id.company_id.currency_id.rate / line.order_id.pricelist_id.currency_id.rate),decimal_precision),
+				'price_subtotal_incl_currency': round(line.price_subtotal_incl * (line.order_id.company_id.currency_id.rate / line.order_id.pricelist_id.currency_id.rate),decimal_precision),
+				# 'amount_currency': round(line.price_subtotal_incl * (line.order_id.company_id.currency_id.rate / line.order_id.pricelist_id.currency_id.rate),decimal_precision)
+			})
+
+		return values
+
+class AccountJournal(models.Model):
+	_inherit = 'account.journal'
+
+	@api.model
+	def getAccountJournal(self,domain):
+		AccountJournal = self.env['account.journal'].search(domain)
+		values = []
+		for journal in AccountJournal:
+			if(journal.currency):
+				complete_name = journal.name + ' (' + journal.currency.local_name + ')'
+			else:
+				complete_name = journal.name + ' (' + journal.company_id.currency_id.local_name + ')'
+			values.append({
+				'id': journal.id,
+				'name': journal.name,
+				'complete_name': complete_name,
+				'type': journal.type,
+				'store_ids': [
+					journal.store_ids.id,
+					journal.store_ids.name,
+				],
+				'company_id': [
+					journal.company_id.id,
+					journal.company_id.name
+				],
+				'currency': [
+					journal.currency.id,
+					journal.currency.name
+				],
+			})
+
+		return values
+
+class AccountBankStatementLine(models.Model):
+	_inherit = 'account.bank.statement.line'
+
+	@api.model
+	def getAccountBankStatementLine(self,domain):
+		AccountBankStatementLine = self.env['account.bank.statement.line'].search(domain)
+		decimal_precision = self.env['decimal.precision'].precision_get('Account')
+		values = []
+		for line in AccountBankStatementLine:
+			try:
+				pos_statement_id = line.pos_statement_id.id
+				partner_id = [line.partner_id.id,line.partner_id.name]
+			except:
+				pos_statement_id = ''
+				partner_id = ''
+
+			if(line.journal_id.currency):
+				amount_currency = round(line.amount * (line.company_id.currency_id.rate / line.journal_id.currency.rate),decimal_precision),
+			else:
+				amount_currency = line.amount
+
+			values.append({
+				'id': line.id,
+				'name': line.name,
+				'date': line.date,
+				'partner_id': partner_id,
+				'ref': line.ref,
+				'currency_id': [
+					line.currency_id.id,
+					line.currency_id.name,
+				],
+				'journal_id': [
+					line.journal_id.id,
+					line.journal_id.name,
+				],
+				'pos_statement_id': pos_statement_id,
+				'amount': line.amount,
+				'amount': line.amount_currency,
+				'amount_currency': amount_currency
+			})
+
+		return values
+
+class AccountMoveLine(models.Model):
+	_inherit = 'account.move.line'
+
+	@api.model
+	def getAccountMoveLine(self,domain):
+		AccountMoveLine = self.env['account.move.line'].search(domain)
+		decimal_precision = self.env['decimal.precision'].precision_get('Account')
+		values = []
+		for line in AccountMoveLine:
+
+			values.append({
+				'id': line.id,
+				'name': line.name,
+				'date': line.date,
+				'date_maturity': line.date_maturity,
+				'reconcile_ref': line.reconcile_ref,
+				'amount_residual': line.amount_residual,
+				'partner_id': [
+					line.partner_id.id,
+					line.partner_id.name,
+				],
+				'move_id': [
+					line.move_id.id,
+					line.move_id.name,
+				],
+				'account_id': [
+					line.account_id.id,
+					line.account_id.name,
+				],
+				'journal_id': [
+					line.journal_id.id,
+					line.journal_id.name,
+				],
+				'debit': line.debit,
+				'credit': line.credit,
+			})
+
+		return values
+
+class AccountAccount(models.Model):
+	_inherit = 'account.account'
+
+	@api.model
+	def getAccountAccount(self,domain):
+		AccountAccount = self.env['account.account'].search(domain)
+		values = []
+		for account in AccountAccount:
+			values.append({
+				'id': account.id,
+				'name': account.name,
+			})
+
+		return values
+
+class ResCompany(models.Model):
+	_inherit = 'res.company'
+
+	@api.model
+	def getResCompany(self,domain):
+		ResCompany = self.env['res.company'].search(domain)
+		values = []
+		for company in ResCompany:
+			values.append({
+				'id': company.id,
+				'name': company.name,
+				'currency_id': [
+					company.currency_id.id,
+					company.currency_id.name,
+				],
+				'company_ruc': company.partner_id.ruc,
+				'phone': company.phone,
+				'logo': company.logo,
+			})
+
+		return values
+
+class AccountVoucher(models.Model):
+	_inherit = 'account.voucher'
+
+	@api.model
+	def getAccountVoucher(self,domain):
+		AccountVoucher = self.env['account.voucher'].search(domain)
+		values = []
+		for voucher in AccountVoucher:
+			values.append({
+				'id': voucher.id,
+				'number': voucher.number,
+				'name': voucher.name,
+				'create_uid': voucher.create_uid.name,
+				'partner_id': [
+					voucher.partner_id.id,
+					voucher.partner_id.name,
+				],
+				'journal_id': [
+					voucher.journal_id.id,
+					voucher.journal_id.name,
+				],
+				'period_id': [
+					voucher.period_id.id,
+					voucher.period_id.name,
+				],
+				'currency_id': [
+					voucher.currency_id.id,
+					voucher.currency_id.name,
+				],
+				'reference': voucher.reference,
+				'date': voucher.date,
+				'amount': voucher.amount,
+				'amount_currency': voucher.amount * (voucher.company_id.currency_id.rate / voucher.currency_id.rate),
+			})
+
+		return values
+
+class ResCurrency(models.Model):
+	_inherit = 'res.currency'
+
+	@api.model
+	def getResCurrency(self,domain):
+		ResCurrency = self.env['res.currency'].search(domain)
+		values = []
+		for currency in ResCurrency:
+			values.append({
+				'id': currency.id,
+				'name': currency.name,
+				'symbol': currency.symbol,
+				'rate_silent': currency.rate_silent,
+				'base': currency.base,
+				'decimal_separator': currency.decimal_separator,
+				'decimal_places': currency.decimal_places,
+				'thousands_separator': currency.thousands_separator,
+				'symbol_position': currency.symbol_position,
+			})
+
+		return values
+
+class ResPartner(models.Model):
+	_inherit = 'res.partner'
+
+	@api.model
+	def getResPartner(self,domain):
+		ResPartner = self.env['res.partner'].search(domain)
+		values = []
+		for partner in ResPartner:
+			values.append({
+				'id': partner.id,
+				'name': partner.name,
+				'ruc': partner.ruc,
+				'street': partner.street,
+				'city': partner.city,
+				'phone': partner.phone,
+				'mobile': partner.mobile,
+				'email': partner.email,
+				'property_product_pricelist': partner.property_product_pricelist.name,
+				'property_product_pricelist_purchase': partner.property_product_pricelist_purchase.name,
+				'credit': partner.credit,
+				'debit': partner.debit,
+				'supplier': partner.supplier,
+			})
+
+		return values
+
+class ProductProduct(models.Model):
+	_inherit = 'product.product'
+
+	############################################################
+	#	PRODUCT PRODUCT
+	############################################################
+
+	@api.model
+	def getProductProduct(self,domain):
+		ProductProduct = self.env['product.product'].search(domain)
+		values = []
+		for product in ProductProduct:
+
+			# try:    'factory_reference':factory_reference,
+			#  	factory_reference = product.factory_reference
+			# except:
+			#  	factory_reference = ''
+
+			attributeValuesLines = map(lambda x: x.id, product.attribute_value_ids)
+			attributeIDS = []
+			for arttIds in self.env['product.attribute.value'].search([('id', 'in', attributeValuesLines)]):
+				attributeIDS.append(arttIds.attribute_id.id)
+
+			try:
+				# sale list price
+				sale_price = map(lambda x: x.id, product.pricelists)
+				saleIDS = []
+				for item in self.env['product.pricelist'].search([('id', 'in', sale_price)]):
+					saleIDS.append(item.id)
+
+				# purchase list price
+				buy_price = map(lambda x: x.id, product.purchase_pricelists)
+				buyIDS = []
+				for item in self.env['product.pricelist'].search([('id', 'in', buy_price)]):
+					buyIDS.append(item.id)
+			except:
+				buyIDS = []
+				saleIDS = []
+
+			try:
+				brand = product.product_brand_id.id
+			except:
+				brand = ''
+
+			values.append({
+				'id': product.id,
+				'name': product.name,
+				'display_name': product.display_name,
+				'standard_price': product.standard_price,
+				'lst_price': product.lst_price,
+				'categ_id': {
+					'id': product.categ_id.id,
+					'name': product.categ_id.name,
+					'complete_name': product.categ_id.complete_name,
+				},
+				'product_brand_id':brand,
+				'atribute_value_ids': attributeValuesLines,
+				'attribute_ids': attributeIDS,
+				'qty_available': product.qty_available,
+				'default_code': product.default_code,
+				'image_medium': product.image_medium,
+				'pricelists': saleIDS,
+				'purchase_pricelists':buyIDS,
+				'product_tmpl_id': product.product_tmpl_id.id,
+				'image': product.image,
+				'ean13': product.ean13,
+				'factory_reference': product_id.factory_reference,
+			})
+
+		return values
+
+	############################################################
+	#	PRODUCT PRODUCT - STOCK 'minimo_quantity': product.minimo_quantity,
+	############################################################
+
+	@api.model
+	def getProductProductStock(self,domain):
+		ProductProduct = self.env['product.product'].search(domain)
+		values = []
+		for product in ProductProduct:
+			attributeValuesLines = map(lambda x: x.id, product.attribute_value_ids)
+			attributeIDS = []
+			for arttIds in self.env['product.attribute.value'].search([('id', 'in', attributeValuesLines)]):
+				attributeIDS.append(arttIds.attribute_id.id)
+
+			values.append({
+				'id': product.id,
+				'display_name': product.display_name,
+				'standard_price': product.standard_price,
+				'lst_price': product.lst_price,
+				'categ_id': {
+					'id': product.categ_id.id,
+					'name': product.categ_id.name,
+					'complete_name': product.categ_id.complete_name,
+				},
+				'atribute_value_ids': attributeValuesLines,
+				'attribute_ids': attributeIDS,
+				'default_code': product.default_code,
+				'factory_reference': product.factory_reference,
+				'ean13': product.ean13,
+			})
+
+		return values
+
+
+	############################################################
+	#	PRODUCT BRAND
+	############################################################
+
+	@api.model
+	def getProductBrand(self,domain):
+		ProductBrand = self.env['product.brand'].search(domain)
+		values = []
+		for brand in ProductBrand:
+			values.append({
+				'id': brand.id,
+				'name': brand.name,
+			})
+
+		return values
+
+class ProductCategory(models.Model):
+	_inherit = 'product.category'
+
+	@api.model
+	def getProductCategory(self,domain):
+		ProductCategory = self.env['product.category'].search(domain)
+		values = []
+		for category in ProductCategory:
+			values.append({
+				'id': category.id,
+				'name': category.name,
+				'display_name': category.display_name,
+				'parent_id': [
+					category.parent_id.id,
+					category.parent_id.name,
+				],
+			})
+
+		return values
+
+class ProductAttribute(models.Model):
+	_inherit = 'product.attribute'
+
+	@api.model
+	def getProductAttribute(self,domain):
+		ProductAttribute = self.env['product.attribute'].search(domain)
+		values = []
+		for attribute in ProductAttribute:
+			values.append({
+				'id': attribute.id,
+				'name': attribute.name,
+			})
+
+		return values
+
+class ProductAttributeValue(models.Model):
+	_inherit = 'product.attribute.value'
+
+	@api.model
+	def getProductAttributeValue(self,domain):
+		ProductAttributeValue = self.env['product.attribute.value'].search(domain)
+		values = []
+		for value in ProductAttributeValue:
+			values.append({
+				'id': value.id,
+				'name': value.name,
+				'attribute_id': [
+					value.attribute_id.id,
+					value.attribute_id.name,
+				],
+			})
+
+		return values
+
+class StockLocation(models.Model):
+	_inherit = 'stock.location'
+
+	@api.model
+	def getStockLocation(self,domain):
+		StockLocation = self.env['stock.location'].search(domain)
+		values = []
+		for location in StockLocation:
+			values.append({
+				'id': location.id,
+				'name': location.name,
+				'display_name': location.display_name,
+				'parent_name': location.location_id.name,
+				'company_id': [
+					location.company_id.id,
+					location.company_id.name,
+				],
+				'store_id': [
+					location.store_id.id,
+					location.store_id.name,
+				],
+				'usage': location.usage,
+			})
+
+		return values
+
+class StockQuant(models.Model):
+	_inherit = 'stock.quant'
+
+	@api.model
+	def getStockQuant(self,domain):
+		StockQuant = self.env['stock.quant'].search(domain)
+		values = []
+		for quant in StockQuant:
+			values.append({
+				'id': quant.id,
+				'name': quant.name,
+				'display_name': quant.display_name,
+				'location_id': [
+					quant.location_id.id,
+					quant.location_id.name,
+				],
+				'product_id': [
+					quant.product_id.id,
+					quant.product_id.name,
+				],
+				'qty': quant.qty,
+			})
+
+		return values
+
+class StockMove(models.Model):
+	_inherit = 'stock.move'
+
+	@api.model
+	def getStockMove(self,domain):
+		StockMove = self.env['stock.move'].search(domain)
+		values = []
+		for move in StockMove:
+		    values.append({
+		        'id': move.id,
+		        'create_date' : move.create_date,
+		        'name': move.name,
+		        'state' : move.state,
+		        'location_id': {
+		            'id' : move.location_id.id,
+		            'complete_name' : move.location_id.complete_name,
+		            'store_id' : move.location_id.store_id.id,
+		        },
+		        'location_dest_id': {
+		            'id' : move.location_dest_id.id,
+		            'complete_name' : move.location_dest_id.complete_name,
+		            'store_id' : move.location_dest_id.store_id.id,
+		        },
+		        'origin' : move.origin,
+		        'picking_id' : {
+		            'id' : move.picking_id.id,
+		            'name' : move.picking_id.name,
+		            },
+		        'partner_id' : {
+		            'id' : move.partner_id.id,
+		            'name' : move.partner_id.name,
+		        },
+		        'product_id': {
+		            'id' : move.product_id.id,
+		            'display_name' : move.product_id.display_name,
+
+		        },
+		        'product_uom_qty': move.product_uom_qty,
+		    })
+
+		return values
+
+class StockPicking(models.Model):
+	_inherit = 'stock.picking'
+
+	@api.model
+	def getStockPicking(self,domain):
+		StockPicking = self.env['stock.picking'].search(domain)
+		values = []
+		for picking in StockPicking:
+		    values.append({
+		        'id' : picking.id,
+		        'date' : picking.create_date,
+		        'name' : picking.name,
+		        'state' : picking.state,
+		        'partner_id' : {
+		            'id' : picking.partner_id.id,
+		            'name' : picking.partner_id.name,
+		        },
+		        'move_type' : picking.move_type,
+		        'picking_type_id' : {
+		            'id' : picking.picking_type_id.id,
+		            'name' : picking.picking_type_id.name,
+		        },
+		        'date_done' : picking.date_done,
+		        'priority' : picking.priority,
+
+		    })
+
+		return values
+
+class ProductPriceList(models.Model):
+	_inherit = 'product.pricelist'
+
+	@api.model
+	def getProductPriceList(self,domain):
+		ProductPriceList = self.env['product.pricelist'].search(domain)
+		values = []
+
+		for pricelist in ProductPriceList:
+			version_ids = map(lambda x: x.id, pricelist.version_id)
+			versionIDS = []
+			for item in self.env['product.pricelist'].search([('id', 'in', version_ids)]):
+				versionIDS.append(item.id)
+
+			values.append({
+		        'id' : pricelist.id,
+		        'name' : pricelist.name,
+		        'type' : pricelist.type,
+		        'version_id' : versionIDS,
+		        'store_id' : {
+		            'id' : pricelist.store_id.id,
+		            'name' : pricelist.store_id.name,
+		        },
+		        'currency_id' : {
+		            'id' : pricelist.currency_id.id,
+		            'name' : pricelist.currency_id.name,
+					'rate_silent': pricelist.currency_id.rate_silent,
+		        },
+		    })
+
+		return values

BIN
static/description/icon.png


+ 148 - 0
static/src/css/custom.css

@@ -0,0 +1,148 @@
+.reporting_page_header {
+    padding-bottom: 9px;
+    margin: 25px 0 35px;
+    border-bottom: 1px solid #eee;
+}
+.range-style {
+    padding-bottom: 9px;
+    border-bottom: 1px solid #eee;
+}
+
+.hover:hover{
+  cursor: grab;
+  cursor: -webkit-grab;
+}
+
+/*
+=============================================
+    FIRST STYLE
+=============================================
+*/
+.panel-first-style {
+    border: 1px solid #bbdefb !important;
+}
+
+.panel-header-first-style {
+    background: #bbdefb !important;
+    text-align: center;
+    font-weight: normal;
+}
+
+/*
+=============================================
+    SECOND STYLE
+=============================================
+*/
+
+.panel-second-style {
+    border: 1px solid #c8e6c9 !important;
+}
+
+.panel-header-second-style {
+    background-color: #c8e6c9 !important;
+    text-align: center;
+    font-weight: bold;
+}
+
+/*
+=============================================
+    THIRD STYLE
+=============================================
+*/
+
+.panel-third-style {
+    border: 1px solid #ffccbc !important;
+}
+
+.panel-header-third-style {
+    background-color: #ffccbc !important;
+    text-align: center;
+    font-weight: bold;
+}
+
+/*
+=============================================
+    BUTTON STYLE
+=============================================
+*/
+
+.myButton{
+    background: #d9534f !important;
+    /* background: #d9534f !important; */
+    /* color: #37474f !important; */
+    color: #fff !important;
+    height: 34px !important;
+    /* border: 1px solid #bdbdbd !important; */
+    /* border: 1px solid #428bca !important; */
+    border: none !important;
+}
+
+.dropdown-menu > li > a {
+    color: #37474f !important;
+}
+
+.dropdown-menu > .active > a {
+    color:#fff !important;
+    background-color: #d9534f !important;
+}
+
+.detail-icon {
+    color: #e57373 !important;
+}
+
+.pagination > .active > a{
+    color:#fff !important;
+    background-color: #d9534f !important;
+    border-color: #d9534f !important;
+}
+
+.filter-style {
+    padding-top: 10px;
+}
+
+.sale-button {
+    color: #fff !important;
+    background: #81c784;
+    border-color: #81c784;
+}
+.sale-button:hover{
+    color: #fff !important;
+    background: #81c784;
+    border-color: #81c784;
+}
+
+.purchase-button {
+    color: #fff !important;
+    background: #ffb74d;
+    border-color: #ffb74d;
+}
+.purchase-button:hover{
+    color: #fff !important;
+    background: #ffb74d;
+    border-color: #ffb74d;
+}
+
+.expense-button {
+    color: #fff !important;
+    background: #e57373;
+    border-color: #e57373;
+}
+.expense-button:hover{
+    color: #fff !important;
+    background: #e57373;
+    border-color: #e57373;
+}
+
+.balance-button {
+    color: #fff !important;
+    background: #0288d1;
+    border-color: #0288d1;
+}
+.balance-button:hover{
+    color: #fff !important;
+    background: #0288d1;
+    border-color: #0288d1;
+}
+.chart-container{
+    width: 100%;
+}

+ 922 - 0
static/src/js/chart.js

@@ -0,0 +1,922 @@
+function chart(reporting) {
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportChartWidget = reporting.Base.extend({
+
+        BuildDemoChart: function (label,data,CurrencyBase) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+                ticks: {
+                    callback: function(tick) {
+                        return tick.toLocaleString('de-DE');
+                    }
+                }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+
+            var chartData = {
+    			labels: label,
+    			datasets: [{
+    				type: 'line',
+    				label: 'Balance',
+    				borderColor: '#0288d1',
+                    fill:false,
+    				data: [
+                        '10500',
+                        '5000',
+                        '3000',
+                        '19000',
+                        '4000',
+                        '70000',
+                        '8000',
+                        '43000',
+                        '25000',
+                        '39000',
+                        '36000',
+                        '47000',
+    				],
+    				borderWidth: 2
+    			}, {
+    				type: 'bar',
+    				label: 'Ventas',
+                    backgroundColor: '#81c784',
+    				borderWidth: 1,
+    				data: [
+                        '10000',
+                        '5000',
+                        '3000',
+                        '15000',
+                        '45000',
+                        '70000',
+                        '90000',
+                        '40000',
+                        '25000',
+                        '70000',
+                        '30000',
+                        '50000',
+    				]
+    			}, {
+    				type: 'bar',
+    				label: 'Compras',
+    				backgroundColor: '#ffb74d',
+    				data: [
+                        '10000',
+                        '5000',
+                        '3000',
+                        '15000',
+                        '4000',
+                        '70000',
+                        '8000',
+                        '40000',
+                        '25000',
+                        '35000',
+                        '30000',
+                        '40000',
+    				],
+    				borderWidth: 1
+    			}, {
+    				type: 'bar',
+    				label: 'Gastos',
+    				backgroundColor: '#e57373',
+    				data: [
+                        '10500',
+                        '5000',
+                        '3000',
+                        '19000',
+                        '4000',
+                        '70000',
+                        '8000',
+                        '43000',
+                        '25000',
+                        '39000',
+                        '36000',
+                        '47000',
+    				],
+    				borderWidth: 1
+    			}]
+    		};
+            var chart = new Chart($(".reporting-chart"), {
+                type: 'bar',
+                data: chartData,
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    title: {
+                        display: false,
+                    },
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                       display: false,
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    // events: ['click'],
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(tooltipItem.yLabel, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                                return label;
+                            }
+                        }
+                    }
+                }
+            });
+        },
+
+        BuildLineChart: function (label,data,CurrencyBase) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+                ticks: {
+                    callback: function(tick) {
+                        return tick.toLocaleString('de-DE');
+                    }
+                }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+            var chart = new Chart($(".reporting-chart"), {
+                type: 'line',
+                data: {
+                    labels: label,
+                    datasets: [
+                        {
+                            label: false,
+                            data: data,
+                            backgroundColor: '#bbdefb',
+                            borderColor: '#0288d1',
+                            borderWidth: 1,
+                            fill: true,
+                        }
+                    ]
+                },
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    title: {
+                        display: false,
+                    },
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                       display: false,
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    events: ['click'],
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(tooltipItem.yLabel, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                                return label;
+                            }
+                        }
+                    }
+                }
+            });
+        },
+
+        BuildBarChart: function (data,CurrencyBase,label,body) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+              ticks: {
+                callback: function(tick) {
+                    return tick.toLocaleString('de-DE');
+                }
+              }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+
+            var color = [];
+            color.push('#BCCEF4');
+            color.push('#A9E5E3');
+            color.push('#A0D995');
+            color.push('#C5D084');
+            color.push('#FAE187');
+            color.push('#FFBD82');
+            color.push('#FFA8B8');
+            color.push('#E5BEDD');
+            color.push('#C4ABFE');
+            color.push('#D8D8D8');
+
+            var chart = new Chart($(".reporting-chart"), {
+                type: 'horizontalBar',
+                data: {
+                    labels: label,
+                    datasets: [
+                        {
+                            label: false,
+                            data: body,
+                            backgroundColor: color,
+                            fill: true,
+                        }
+                    ]
+                },
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    title: {
+                        display: false,
+                    },
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                       display: false,
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(tooltipItem.xLabel, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                                return label;
+                            }
+                        }
+                    },
+                    events: ['click'],
+                }
+            });
+        },
+
+        BuildPieChart: function (data,CurrencyBase,label,body) {
+            var self = this;
+
+            var color = [];
+            color.push('#BCCEF4');
+            color.push('#A9E5E3');
+            color.push('#A0D995');
+            color.push('#C5D084');
+            color.push('#FAE187');
+            color.push('#FFBD82');
+            color.push('#FFA8B8');
+            color.push('#E5BEDD');
+            color.push('#C4ABFE');
+            color.push('#D8D8D8');
+            color.push('#f3e5f5');
+
+            var chart = new Chart($(".reporting-pie-chart"), {
+                type: 'pie',
+                data: {
+                    labels: label,
+                    datasets: [
+                        {
+                            label: false,
+                            data: body,
+                            backgroundColor: color,
+                            fill: true,
+                        }
+                    ]
+                },
+
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                        position: 'right',
+                        // position: 'none',
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.labels[tooltipItem.index] || '';
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(data.datasets[0].data[tooltipItem.index],{
+                                    symbol: "%",
+                                    format: "%v%s",
+                                    precision: 2,
+                                    thousand: ".",
+                                    decimal: ","
+                                });
+                                return label;
+                            }
+                        }
+                    },
+                    events: ['click'],
+                }
+            });
+        },
+
+        BuildDoughnutChart: function (data,CurrencyBase,label,body) {
+            var self = this;
+
+            var color = [];
+            color.push('#BCCEF4');
+            color.push('#A9E5E3');
+            color.push('#A0D995');
+            color.push('#C5D084');
+            color.push('#FAE187');
+            color.push('#FFBD82');
+            color.push('#FFA8B8');
+            color.push('#E5BEDD');
+            color.push('#C4ABFE');
+            color.push('#D8D8D8');
+
+            var chart = new Chart($(".reporting-doughnut-chart"), {
+                type: 'doughnut',
+                data: {
+                    labels: label,
+                    datasets: [
+                        {
+                            label: false,
+                            data: body,
+                            backgroundColor: color,
+                            fill: true,
+                        }
+                    ]
+                },
+
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                        position: 'left',
+                        // position: 'none',
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.labels[tooltipItem.index] || '';
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(data.datasets[0].data[tooltipItem.index],{
+                                    symbol: "%",
+                                    format: "%v%s",
+                                    precision: 2,
+                                    thousand: ".",
+                                    decimal: ","
+                                });
+                                return label;
+                            }
+                        }
+                    },
+                    events: ['click'],
+                }
+            });
+        },
+
+        BuildMultipleChart: function (CurrencyBase,label,body_subtotal,body_tax,body_cost,body_total,body_profit) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+                ticks: {
+                    callback: function(tick) {
+                        return tick.toLocaleString('de-DE');
+                    }
+                }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+
+            var chartData = {
+    			labels: label,
+    			datasets: [
+                    /*
+                    ================
+                        BENEFICIO
+                    ================
+                    */
+                    {
+    				type: 'line',
+    				label: 'Beneficio',
+                    borderColor: '#03a9f4',
+                    fill: false,
+                    borderWidth: 2,
+    				data: body_profit,
+
+                    },
+                    /*
+                    ================
+                        TOTAL
+                    ================
+                    */
+                    {
+    				type: 'bar',
+    				label: 'Total',
+                    borderColor: '#BCCEF4',
+    				backgroundColor: '#BCCEF4',
+                    borderWidth: 1,
+    				data: body_total,
+                    },
+                    /*
+                    ================
+                        SUB TOTAL
+                    ================
+                    */
+                    {
+    				type: 'bar',
+    				label: 'Sub-Total',
+    				borderColor: '#A9E5E3',
+                    backgroundColor: '#A9E5E3',
+    				borderWidth: 1,
+    				data: body_subtotal,
+    			    },
+                    /*
+                    ================
+                        IMPUESTOS
+                    ================
+                    */
+                    {
+    				type: 'bar',
+    				label: 'Impuestos',
+                    borderColor: '#A0D995',
+    				backgroundColor: '#A0D995',
+                    borderWidth: 1,
+    				data:body_tax,
+    			    },
+                    /*
+                    ================
+                        COSTE
+                    ================
+                    */
+                    {
+    				type: 'bar',
+    				label: 'Coste',
+                    borderColor: '#C5D084',
+    				backgroundColor: '#C5D084',
+                    borderWidth: 1,
+    				data: body_cost,
+                    },
+                ]
+    		};
+            var chart = new Chart($(".reporting-chart"), {
+                type: 'bar',
+                data: chartData,
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:20,
+                    maintainAspectRatio:false,
+                    title: {
+                        display: false,
+                    },
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                       display: false,
+                    },
+                    layout: {
+                        padding: {
+                            top: 15,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    events: ['click'],
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(tooltipItem.yLabel, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                                return label;
+                            }
+                        }
+                    }
+                }
+            });
+        },
+
+        BuildMultipleBarChart: function (
+            data,
+            CurrencyBase,
+            first_label,
+            first_body,
+            second_label,
+            second_body,
+            third_label,
+            third_body,
+            fourth_label,
+            fourth_body,
+            label
+            ) {
+            var self = this;
+            Chart.scaleService.updateScaleDefaults('linear', {
+                ticks: {
+                    callback: function(tick) {
+                        return tick.toLocaleString('de-DE');
+                    }
+                }
+            });
+            Chart.defaults.global.tooltips.callbacks.label = function(tooltipItem, data) {
+                var dataset = data.datasets[tooltipItem.datasetIndex];
+                var datasetLabel = dataset.label || '';
+                return datasetLabel +  dataset.data[tooltipItem.index].toLocaleString('de-DE');
+            };
+
+            var chartData = {
+    			labels: label,
+    			datasets: [
+
+                    {
+    				type: 'bar',
+    				label: first_label,
+                    borderColor: '#BCCEF4',
+    				backgroundColor: '#BCCEF4',
+                    borderWidth: 1,
+    				data: first_body,
+                    },
+
+                    {
+    				type: 'bar',
+    				label: second_label,
+    				borderColor: '#A9E5E3',
+                    backgroundColor: '#A9E5E3',
+    				borderWidth: 1,
+    				data: second_body,
+    			    },
+
+                    {
+    				type: 'bar',
+    				label: third_label,
+                    borderColor: '#A0D995',
+    				backgroundColor: '#A0D995',
+                    borderWidth: 1,
+    				data: third_body,
+    			    },
+
+                    {
+    				type: 'bar',
+    				label: fourth_label,
+                    borderColor: '#0288d1',
+    				backgroundColor: '#0288d1',
+                    borderWidth: 1,
+    				data: fourth_body,
+    			    },
+                ]
+    		};
+
+            var chart = new Chart($(".reporting-chart"), {
+                type: 'bar',
+                data: chartData,
+                options: {
+                    responsive: true,
+                    responsiveAnimationDuration:10,
+                    maintainAspectRatio:false,
+                    title: {
+                        display: false,
+                    },
+                    hover: {
+                        mode: 'nearest',
+                        intersect: true
+                    },
+                    legend: {
+                       display: false,
+                    },
+                    layout: {
+                        padding: {
+                            top: 0,
+                            bottom: 0,
+                            left : 0,
+                            rigth: 0,
+                        }
+                    },
+                    tooltips: {
+                        callbacks: {
+                            label: function(tooltipItem, data) {
+                                var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+                                if (label) {
+                                    label += ': ';
+                                }
+                                label += accounting.formatMoney(tooltipItem.yLabel, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                                return label;
+                            }
+                        }
+                    },
+                    events: ['click'],
+                }
+            });
+        },
+        drawPdf4: function(row,ResCompany,pdf_title,pdf_type,pdf_name,pdf_columnStyles,filter){
+         var self = this;
+         var base64Img = 'data:image/png;base64,' + ResCompany.logo;
+         var hoy = moment().format('DD/MM/YYYY');
+         var totalPagesExp = "{total_pages_count_string}";
+         var pdfDoc = new jsPDF(pdf_type);
+         var title = [];
+         var currentpage = 0;
+         var i = 0;
+         var position = 27;
+         var y_position2 = 27;
+
+         title.push({
+           title : 'Factura',
+           dataKey: 'invoice',
+         });
+         title.push({
+           title : 'Cuota',
+           dataKey: 'name',
+         });
+         title.push({
+           title : 'Fecha de Vencimiento',
+           dataKey: 'date',
+         });
+         title.push({
+           title : 'Estado',
+           dataKey: 'state',
+         });
+         title.push({
+           title : 'Días Atrasados',
+           dataKey: 'days_of_delays',
+         });
+         title.push({
+           title : 'Total',
+           dataKey: 'amount',
+         });
+         title.push({
+           title : 'Saldo',
+           dataKey: 'residual',
+         });
+         title.push({
+           title : 'Saldo Factura',
+           dataKey: 'invoice_residual',
+         });
+
+         //LOGO
+         pdfDoc.addImage(base64Img, 'png', 7, 2, 0, 15);
+
+         //FECHA
+         pdfDoc.setFontSize(13);
+         pdfDoc.setFontStyle('normal');
+         pdfDoc.setTextColor(40)
+         pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 35, 12,hoy);
+
+         //TITULO
+         pdfDoc.setFontSize(15);
+         pdfDoc.setFontStyle('bold');
+         pdfDoc.setTextColor('#0288d1');
+         pdfDoc.autoTableText(pdf_title, pdfDoc.internal.pageSize.getWidth() - 12, 18, {
+           halign: 'right',
+           valign: 'middle'
+         });
+         pdfDoc.setLineWidth(0.5);
+         pdfDoc.setDrawColor('#424242');
+         pdfDoc.line(10, 22, pdfDoc.internal.pageSize.getWidth() - 10 , 22);
+
+         var ii=0;
+         if(pdf_type == 'l'){
+           var col1_title = 15;
+           var col1_value = 55;
+           var col2_title = 150;
+           var col2_value = 190;
+         }
+         else{
+           var col1_title = 10;
+           var col1_value = 50;
+           var col2_title = 110;
+           var col2_value = 150;
+         }
+         if(filter.length >0){
+           _.each(filter,function(item){
+             if(ii<4){
+               self.addFilter(pdfDoc,item.title,item.value,col1_title,col1_value,position);
+               position = position + 5;
+             }else{
+               self.addFilter(pdfDoc,item.title,item.value,col2_title,col2_value,y_position2);
+               y_position2 = y_position2 + 5;
+             }
+               ii++;
+           });
+           pdfDoc.setLineWidth(0.5);
+           pdfDoc.setDrawColor('#424242');
+
+           if(position >= y_position2){
+             position = position;
+             pdfDoc.line(10, position, pdfDoc.internal.pageSize.getWidth() - 10 , position);
+           }else{
+             position = y_position2;
+             pdfDoc.line(10, y_position2, pdfDoc.internal.pageSize.getWidth() - 10 , y_position2);
+           }
+         }
+
+         _.each(row, function(item){
+           if(i > 0){
+             let first = pdfDoc.autoTable.previous;
+             position = first.finalY + 5;
+           };
+
+           var docItem = [];
+           if(item.info != 'undefined'){
+             _.each(item.info, function(index){
+               docItem.push({
+                 invoice: index.invoice,
+                 name: index.name,
+                 date: index.date,
+                 state: index.state,
+                 days_of_delays: index.days_of_delays,
+                 amount: index.amount,
+                 residual: index.residual,
+                 invoice_residual: index.invoice_residual,
+               })
+             });
+           }
+
+           pdfDoc.setDrawColor(0);
+           pdfDoc.setFillColor(76, 133, 248);
+           pdfDoc.rect(7, position+5, 196, 8, 'F');
+
+           pdfDoc.setFontSize(9);
+           pdfDoc.setTextColor(255,255,255)
+           pdfDoc.setFontStyle('bold');
+
+           pdfDoc.autoTableText('Cliente: ', 10, position+9, {
+             halign: 'left',
+             valign: 'middle'
+           });
+
+           pdfDoc.autoTableText(item.partner_name, 22, position+9, {
+             halign: 'left',
+             valign: 'middle'
+           });
+
+           pdfDoc.autoTableText('Cuotas Vencidas: ', 80, position+9, {
+             halign: 'left',
+             valign: 'middle'
+           });
+
+           pdfDoc.autoTableText(item.due_qty.toString(), 108, position+9, {
+             halign: 'left',
+             valign: 'middle'
+           });
+
+           pdfDoc.autoTableText('Días Atrasados: ', 115, position+9, {
+             halign: 'left',
+             valign: 'middle'
+           });
+
+           pdfDoc.autoTableText(item.max_days_of_delay.toString(), 140, position+9, {
+             halign: 'left',
+             valign: 'middle'
+           });
+
+           pdfDoc.autoTableText('Monto Atrasado: ', 148, position+9, {
+             halign: 'left',
+             valign: 'middle'
+           });
+
+           pdfDoc.autoTableText(item.amount, 175, position+9, {
+             halign: 'left',
+             valign: 'middle'
+           });
+
+           pdfDoc.autoTable(title, docItem, {
+             //  showHeader: false,
+             startY: position+15,
+             theme: 'grid',
+             styles: {
+               overflow: 'linebreak',
+               fontSize: 8,
+               margin: 50,
+               lineWidth: 0.3,
+               lineColor: [132,132,132]
+             },
+
+             headerStyles: {
+               fillColor: [255,255,255],
+               fontSize: 9,
+               textColor: [0,0,0],
+               lineWidth: 0.3,
+               lineColor: [132,132,132],
+               halign: 'center',
+             },
+             columnStyles: pdf_columnStyles,
+             margin: 'auto',
+             tableWidth: 'auto',
+
+             addPageContent: function (data) {
+               // FOOTER
+               if (currentpage < pdfDoc.internal.getNumberOfPages()) {
+                 var str = "Página " + pdfDoc.internal.getNumberOfPages();
+                 str = str + " de " + totalPagesExp;
+                 pdfDoc.setFontSize(9);
+                 pdfDoc.setFontStyle('bold');
+                 pdfDoc.setTextColor(40);
+                 var pageHeight = pdfDoc.internal.pageSize.height || pdfDoc.internal.pageSize.getHeight();
+                 pdfDoc.text(str, pdfDoc.internal.pageSize.getWidth() - 55, pageHeight - 5);
+                 currentpage = pdfDoc.internal.getNumberOfPages();
+               }
+             }
+           });
+           i++;
+         });
+         if(typeof pdfDoc.putTotalPages === 'function'){
+           pdfDoc.putTotalPages(totalPagesExp);
+         }
+         row.pop();
+         if(model.printer_bridge){
+           var data = pdfDoc.output('datauristring');
+           model.printer_bridge.print(data);
+           return;
+         }
+         pdfDoc.save(pdf_name + hoy + '.pdf');
+       },
+
+       addFilter: function(pdfDoc,title,value,x_position_title,x_position_value,y_position){
+            pdfDoc.setFontSize(10);
+            pdfDoc.setTextColor('#424242');
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.autoTableText(title+':', x_position_title, y_position, {
+              halign: 'left',
+              valign: 'middle'
+            });
+            pdfDoc.setFontSize(10);
+            pdfDoc.setTextColor('#424242');
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.autoTableText(value, x_position_value, y_position, {
+              halign: 'left',
+              valign: 'middle'
+            });
+      },
+    });
+}

+ 102 - 0
static/src/js/configuration_reporting.js

@@ -0,0 +1,102 @@
+function configuration_reporting (reporting, instance, widget) {
+    "use strict";
+    var widgets = widget;
+
+    widget.ReportingWidget = instance.Widget.extend({
+        template: 'EiruReport',
+        events: {},
+
+        start: function () {
+            var self = this;
+            self.fetchInitial();
+            self.BuildChart();
+        },
+
+        fetchInitial:function() {
+            var self = this;
+            self.fetchResUser().then(function (ResUser) {
+                return ResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCurrency();
+            }).then(function (ResCurrency) {
+                self.ResCurrency = ResCurrency;
+                self.BuildChart();
+                return self.InsertUser();
+            });
+        },
+
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new instance.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [
+                ['base','=',true],
+            ];
+            var ResCurrency = new instance.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        BuildChart: function(){
+            var self = this;
+            var label = [
+                'Enero',
+                'Febrero',
+                'Marzo',
+                'Abril',
+                'Mayo',
+                'Junio',
+                'Julio',
+                'Agosto',
+                'Septiembre',
+                'Octubre',
+                'Noviembre',
+                'Diciembre',
+            ];
+            var body = [
+                '20000',
+                '30000',
+                '80000',
+                '50000',
+                '60000',
+                '70000',
+                '90000',
+                '40000',
+                '100000',
+                '70000',
+                '30000',
+                '50000',
+            ];
+            var CurrencyBase = self.ResCurrency;
+            if(CurrencyBase){
+                var chart = new reporting.ReportChartWidget(self);
+                chart.BuildDemoChart(label,body,CurrencyBase[0]);
+            }
+        },
+
+        InsertUser: function(id) {
+            var self = this;
+            var user = self.ResUser[0].name;
+            self.$el.find('.user-content').find('p').text("Hola " + user + " ...!");
+        },
+
+    });
+}

+ 40 - 0
static/src/js/datepicker.js

@@ -0,0 +1,40 @@
+function datepicker(reporting) {
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportDatePickerWidget = reporting.Base.extend({
+        fecthFecha: function() {
+            var to;
+            var dateFormat1 = "mm/dd/yy",
+            from = $( "#from" )
+            .datepicker({
+                dateFormat: "dd/mm/yy",
+                changeMonth: true,
+                numberOfMonths: 1,
+            })
+            .on( "change", function() {
+                to.datepicker( "option", "minDate", getDate(this), "dd/mm/yyyy");
+            });
+            to = $( "#to" ).datepicker({
+                dateFormat: "dd/mm/yy",
+                defaultDate: "+7d",
+                changeMonth: true,
+                numberOfMonths: 1,
+            })
+            .on( "change", function() {
+                from.datepicker( "option", "maxDate", getDate(this));
+            });
+            function getDate( element ) {
+                var fechaSel =element.value.split('/');
+                var date;
+                try {
+                    date = $.datepicker.parseDate( dateFormat1, (fechaSel[1]+"/"+fechaSel[0]+"/"+fechaSel[2]));
+                } catch( error ) {
+                    date = null;
+                }
+                return date;
+            }
+        },
+    });
+}

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

@@ -0,0 +1,305 @@
+openerp.eiru_reports = function (instance) {
+    "use strict";
+
+    var reporting = instance.eiru_reports;
+
+    reporting_base(instance,reporting);
+    configuration_reporting(reporting,instance,reporting);
+
+    try {
+        /*
+        ================================
+            BASE
+        ================================
+        */
+        pdf(reporting);
+        chart(reporting);
+        datepicker(reporting);
+        /*
+        ================================
+            COMPRAS
+        ================================
+        */
+        report_purchase(reporting);
+        report_purchase_analytic(reporting);
+        report_supplier(reporting);
+        report_supplier_ranking(reporting);
+        /*
+        ================================
+            VENTAS
+        ================================
+        */
+        report_sale(reporting);
+        report_sale_analytic(reporting);
+        report_customer(reporting);
+        report_customer_ranking(reporting);
+        report_sale_ranking_product(reporting);
+        report_product_list(reporting);
+        /*
+        ================================
+            GASTOS
+        ================================
+        */
+        report_expense(reporting);
+        report_expense_analytic(reporting);
+        /*
+        ================================
+            STOCK
+        ================================
+        */
+        report_stock_valuation(reporting);
+        report_stock_history(reporting);
+        report_stock_movement(reporting);
+        /*
+        ================================
+            FINANZAS
+        ================================
+        */
+        report_profit_and_loss(reporting);
+        report_sale_gross(reporting);
+        report_sale_utility_analytic(reporting);
+        report_daily_sale(reporting);
+        report_income_summary(reporting);
+        report_outcome_summary(reporting);
+        report_sale_summary(reporting);
+        report_account_receivable(reporting);
+        report_account_payable(reporting);
+        report_account_payable_expenses(reporting);
+        report_dues_analysis(reporting);
+        report_duessupplier_analysis(reporting);
+        report_customer_payment(reporting);
+        report_supplier_payment(reporting);
+        report_customer_paymentespecial(reporting);
+        report_customer_refund(reporting);
+        report_supplier_refund(reporting);
+        report_customer_ratings(reporting)
+        /*
+        ================================
+            CONTABILIDAD
+        ================================
+        */
+        // report_sale_journal(reporting);
+        // report_purchase_journal(reporting);
+        report_purchase_journal_detallado(reporting);
+        report_sale_journal_detallado(reporting);
+
+    } catch (e) {
+        // ignorar error
+    }
+
+    /*
+    ================================================================================
+        PANTALLA DE BIENVENIDA
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.welcome_action', 'instance.eiru_reports.ReportingWidget');
+
+    /*
+    ================================================================================
+        HISTORICO DE COMPRAS
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.purchase_action', 'instance.eiru_reports.ReportPurchaseWidget');
+
+    /*
+    ================================================================================
+        ANALISIS DE COMPRAS
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.purchase_analytic_action', 'instance.eiru_reports.ReportPurchaseAnalyticWidget');
+
+    /*
+    ================================================================================
+        PROVEEDORES
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.supplier_action', 'instance.eiru_reports.ReportSupplierWidget');
+
+    /*
+    ================================================================================
+        RANKING DE PROVEEDORES
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.supplier_ranking_action', 'instance.eiru_reports.ReportSupplierRankingWidget');
+
+    /*
+    ================================================================================
+        HISTORICO DE VENTAS
+    ================================================================================
+    */
+    instance.web.client_actions.add('eiru_reports.sale_action', 'instance.eiru_reports.ReportSaleWidget');
+
+    /*
+    ================================================================================
+        ANALISIS DE VENTAS
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.sale_analytic_action', 'instance.eiru_reports.ReportSaleAnalyticWidget');
+
+    /*
+    ================================================================================
+        CLIENTES
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.customer_action', 'instance.eiru_reports.ReportCustomerWidget');
+
+    /*
+    ================================================================================
+        RANKING DE CLIENTES
+    ================================================================================
+    */
+    instance.web.client_actions.add('eiru_reports.customer_ranking_action', 'instance.eiru_reports.ReportCustomerRankingWidget');
+
+    /*
+    ================================================================================
+        RANKING DE PRODUCTOS MAS VENDIDOS
+    ================================================================================
+    */
+    instance.web.client_actions.add('eiru_reports.sale_ranking_product_action', 'instance.eiru_reports.ReportSaleRankingProductWidget');
+
+    /*
+    ================================================================================
+        HISTORICO GASTOS
+    ================================================================================
+    */
+    instance.web.client_actions.add('eiru_reports.expense_action', 'instance.eiru_reports.ReportExpenseWidget');
+
+    /*
+    ================================================================================
+        ANALISIS DE GASTOS
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.expense_analytic_action', 'instance.eiru_reports.ReportExpenseAnalyticWidget');
+
+    /*
+    ================================================================================
+        VALORACION DE INVENTARIO
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.stock_valuation_action', 'instance.eiru_reports.ReportStockValuationWidget');
+
+    /*
+    ================================================================================
+        MOVIMIENTO DE INVENTARIO
+    ================================================================================
+    */
+    instance.web.client_actions.add('eiru_reports.stock_movement_action', 'instance.eiru_reports.ReportStockMovementWidget');
+
+    //  HISTORIAL DE INVENTARIO
+    instance.web.client_actions.add('eiru_reports.stock_history_action', 'instance.eiru_reports.ReportStockHistoryWidget');
+
+    /*
+    ================================================================================
+        UTILIDAD DE VENTAS
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.profit_and_loss_action', 'instance.eiru_reports.ReportProfitAndLossWidget');
+
+    /*
+    ================================================================================
+        UTILIDAD DE VENTAS
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.sale_gross_action', 'instance.eiru_reports.ReportSaleGrossWidget');
+
+    /*
+    ================================================================================
+        ANALISIS DE UTILIDAD VENTAS
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.sale_utility_analytic_action', 'instance.eiru_reports.ReportSaleUtilityAnalyticWidget');
+
+    //  RESUMEN DE VENTAS DIARIAS
+    instance.web.client_actions.add('eiru_reports.daily_sale_action', 'instance.eiru_reports.ReportDailySaleWidget');
+
+    /*
+    ================================================================================
+        RESUMEN DE INGRESOS
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.income_summary_action', 'instance.eiru_reports.ReportIncomeSummaryWidget');
+
+    //  RESUMEN DE EGRESOS
+    instance.web.client_actions.add('eiru_reports.outcome_summary_action', 'instance.eiru_reports.ReportOutcomeSummaryWidget');
+
+    /*
+    ================================================================================
+        RESUMEN DE VENTAS
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.sale_summary_action', 'instance.eiru_reports.ReportSaleSummaryWidget');
+
+    /*
+    ================================================================================
+        CUENTAS A COBRAR
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.account_receivable_action', 'instance.eiru_reports.ReportAccountReceivableWidget');
+
+    //  CUENTAS A PAGAR COMPRA
+    instance.web.client_actions.add('eiru_reports.account_payable_action', 'instance.eiru_reports.ReportAccountPayableWidget');
+    //  CUENTAS A PAGAR GASTOS
+    instance.web.client_actions.add('eiru_reports.account_payable_expenses_action', 'instance.eiru_reports.ReportAccountPayableExpensesWidget');
+
+    //  ANALISIS DE CUOTAS
+    instance.web.client_actions.add('eiru_reports.dues_analysis_action', 'instance.eiru_reports.ReportDuesAnalysisWidget');
+
+    //  ANALISIS DE CUOTAS A PAGAR
+    instance.web.client_actions.add('eiru_reports.duessupplier_analysis_action', 'instance.eiru_reports.ReportDuesSupplierAnalysisWidget');
+
+    /*
+    ================================================================================
+        PAGOS DE CLIENTES
+    ================================================================================
+    */
+    instance.web.client_actions.add('eiru_reports.customer_payment_action', 'instance.eiru_reports.ReportCustomerPaymentWidget');
+
+    //  PAGOS A PROVEEDORES
+    instance.web.client_actions.add('eiru_reports.supplier_payment_action', 'instance.eiru_reports.ReportSupplierPaymentWidget');
+
+    //  PAGOS DE CLIENTES Y NOTA DE CREDITO
+    instance.web.client_actions.add('eiru_reports.customer_paymentespecial_action', 'instance.eiru_reports.ReportCustomerPaymentEspecialWidget');
+
+    //    NOTAS DE CREDITO
+    instance.web.client_actions.add('eiru_reports.customer_refund_action', 'instance.eiru_reports.ReportCustomerRefundWidget');
+
+    //    NOTAS DE DEBITO
+    instance.web.client_actions.add('eiru_reports.supplier_refund_action', 'instance.eiru_reports.ReportSupplierRefundWidget');
+
+    //LISTA DE PRODUCTOS
+    instance.web.client_actions.add('eiru_reports.product_list_action', 'instance.eiru_reports.ReportProductListWidget');
+
+    //LISTA DE MOROSOS
+    instance.web.client_actions.add('eiru_reports.customer_ratings_action', 'instance.eiru_reports.ReportCustomerRatingsWidget');
+
+
+
+    /*
+    ================================================================================
+        LIBRO DE VENTAS
+    ================================================================================
+     */
+    // instance.web.client_actions.add('eiru_reports.sale_journal_action', 'instance.eiru_reports.ReportSaleJournalWidget');
+
+    /*
+    ================================================================================
+        LIBRO DE COMPRAS
+    ================================================================================
+     */
+    // instance.web.client_actions.add('eiru_reports.purchase_journal_action', 'instance.eiru_reports.ReportPurchaseJournalWidget');
+
+    /*
+    ================================================================================
+        LIBRO DE COMPRAS DETALLADO
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.purchase_journal_detallado_action', 'instance.eiru_reports.ReportPurchaseJournalDetalladoWidget');
+
+    /*
+    ================================================================================
+        LIBRO DE VENTAS DETALLADO
+    ================================================================================
+     */
+    instance.web.client_actions.add('eiru_reports.sale_journal_detallado_action', 'instance.eiru_reports.ReportSaleJournalDetalladoWidget');
+
+}

+ 1575 - 0
static/src/js/pdf.js

@@ -0,0 +1,1575 @@
+function pdf(reporting) {
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportPdfWidget = reporting.Base.extend({
+      drawPDF: function (getColumns,row,ResCompany,pdf_title,pdf_type,pdf_name,pdf_columnStyles,filter) {
+        var self = this;
+        var base64Img = 'data:image/png;base64,' + ResCompany.logo;
+        var hoy = moment().format('DD/MM/YYYY');
+        var totalPagesExp = "{total_pages_count_string}";
+        var pdfDoc = new jsPDF(pdf_type);
+        var y_position = 10;
+        var y_position2 = 10;
+
+        //LOGO
+        pdfDoc.addImage(base64Img, 'png', 7, 2, 0, 15);
+
+        //FECHA
+        pdfDoc.setFontSize(13);
+        pdfDoc.setFontStyle('normal');
+        pdfDoc.setTextColor(40)
+        pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 35, 12,hoy);
+
+        //TITULO
+        pdfDoc.setFontSize(15);
+        pdfDoc.setFontStyle('bold');
+        pdfDoc.setTextColor('#0288d1');
+        pdfDoc.autoTableText(pdf_title, pdfDoc.internal.pageSize.getWidth() - 12, 18, {
+          halign: 'right',
+          valign: 'middle'
+        });
+        pdfDoc.setLineWidth(0.5);
+        pdfDoc.setDrawColor('#424242');
+        pdfDoc.line(10, 22, pdfDoc.internal.pageSize.getWidth() - 10 , 22);
+
+        var i=0;
+        if(pdf_type == 'l'){
+          var col1_title = 15;
+          var col1_value = 55;
+          var col2_title = 150;
+          var col2_value = 190;
+        }
+        else{
+          var col1_title = 10;
+          var col1_value = 50;
+          var col2_title = 110;
+          var col2_value = 150;
+        }
+        if(filter.length >0){
+          _.each(filter,function(item){
+            if(i<4){
+              self.addFilter(pdfDoc,item.title,item.value,col1_title,col1_value,y_position);
+              y_position = y_position + 5;
+            }else{
+              self.addFilter(pdfDoc,item.title,item.value,col2_title,col2_value,y_position2);
+              y_position2 = y_position2 + 5;
+            }
+              i++;
+          });
+          pdfDoc.setLineWidth(0.5);
+          pdfDoc.setDrawColor('#424242');
+
+          if(y_position >= y_position2){
+            y_position = y_position;
+            pdfDoc.line(10, y_position, pdfDoc.internal.pageSize.getWidth() - 10 , y_position);
+          }else{
+            y_position = y_position2;
+            pdfDoc.line(10, y_position2, pdfDoc.internal.pageSize.getWidth() - 10 , y_position2);
+          }
+        }
+
+
+        pdfDoc.autoTable(getColumns, row, {
+            // showHeader: 'firstPage',
+            startY: y_position + 5,
+            theme: 'grid',
+            styles: {
+                overflow: 'linebreak',
+                columnWidth: 'auto',
+                fontSize: 7,
+            },
+            headerStyles: {
+                fillColor: [76, 133, 248],
+                fontSize: 9
+            },
+            columnStyles: pdf_columnStyles,
+            margin: { horizontal: 7},
+
+            drawCell: function(cell, opts) {
+                var rows = opts.table.rows;
+                if (opts.row.index == rows.length - 1) {
+                  pdfDoc.setFontStyle('bold');
+                }
+            },
+
+            addPageContent: function (data) {
+
+            //FOOTER
+                var str = "Página " + data.pageCount;
+                if (typeof pdfDoc.putTotalPages === 'function') {
+                    str = str + " de " + totalPagesExp;
+                }
+                pdfDoc.setFontSize(9);
+                pdfDoc.setFontStyle('bold');
+                pdfDoc.setTextColor(40);
+                var pageHeight = pdfDoc.internal.pageSize.height || pdfDoc.internal.pageSize.getHeight();
+                pdfDoc.autoTableText(str, pdfDoc.internal.pageSize.getWidth() - 35, pageHeight - 5, {
+                  halign: 'rigth',
+                  valign: 'middle'
+                });
+            }
+        });
+        if (typeof pdfDoc.putTotalPages === 'function') {
+            pdfDoc.putTotalPages(totalPagesExp);
+        }
+        row.pop();
+        if(model.printer_bridge){
+            var data = pdfDoc.output('datauristring');
+            model.printer_bridge.print(data);
+            return;
+        }
+        pdfDoc.save(pdf_name + hoy + '.pdf');
+      },
+
+      addFilter: function(pdfDoc,title,value,x_position_title,x_position_value,y_position){
+        pdfDoc.setFontSize(10);
+        pdfDoc.setTextColor('#424242');
+        pdfDoc.setFontStyle('bold');
+        pdfDoc.autoTableText(title+':', x_position_title, y_position, {
+          halign: 'left',
+          valign: 'middle'
+        });
+        pdfDoc.setFontSize(10);
+        pdfDoc.setTextColor('#424242');
+        pdfDoc.setFontStyle('normal');
+        pdfDoc.autoTableText(value, x_position_value, y_position, {
+          halign: 'left',
+          valign: 'middle'
+        });
+      },
+
+        drawStockPDF: function (
+            index,
+            getColumns,
+            row,
+            ResCompany,
+            pdf_title,
+            pdf_type,
+            pdf_name,
+            pdf_columnStyles,
+            current_location) {
+            var self = this;
+            var base64Img = 'data:image/png;base64,' + ResCompany.logo;
+            var hoy = moment().format('DD/MM/YYYY');
+            var totalPagesExp = "{total_pages_count_string}";
+            var pdfDoc = new jsPDF(pdf_type);
+            getColumns.shift();
+            pdfDoc.autoTable(getColumns, row, {
+                theme: 'grid',
+                styles: {
+                    overflow: 'linebreak',
+                    columnWidth: 'auto',
+                    fontSize: 7,
+                },
+                headerStyles: {
+                    fillColor: [76, 133, 248],
+                    fontSize: 8
+                },
+                columnStyles: pdf_columnStyles,
+                margin: { top: 20, horizontal: 7, bottom: 40,},
+
+                drawCell: function(cell, data) {
+                    var rows = data.table.rows;
+                    if (data.row.index == rows.length - 1) {
+                        pdfDoc.setFontStyle('bold');
+                    };
+                },
+
+                addPageContent: function (data) {
+                    pdfDoc.addImage(base64Img, 'png', 7, 2, 0, 15);
+                    if(pdf_type == 'l'){
+                        pdfDoc.setFontSize(12);
+                        pdfDoc.setFontStyle('bold');
+                        pdfDoc.setTextColor(40);
+                        pdfDoc.text(pdf_title,130,10);
+                    }else{
+                        pdfDoc.setFontSize(12);
+                        pdfDoc.setFontStyle('bold');
+                        pdfDoc.setTextColor(40);
+                        pdfDoc.text(pdf_title,80,10);
+                    }
+                    if(current_location.length > 0){
+                        pdfDoc.setFontSize(9);
+                        pdfDoc.setFontStyle('normal');
+                        pdfDoc.setTextColor(40)
+                        pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 54, 18,"Ubicación: " + current_location[0].parent_name);
+                    }
+                    pdfDoc.setFontSize(9);
+                    pdfDoc.setFontStyle('normal');
+                    pdfDoc.setTextColor(40)
+                    pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 55, 14," Fecha de Expedición: " + hoy);
+
+                    /*===========
+                        FOOTER
+                    ===========*/
+                    var str = "Página " + data.pageCount;
+                    if (typeof pdfDoc.putTotalPages === 'function') {
+                        str = str + " de " + totalPagesExp;
+                    }
+                    pdfDoc.setFontSize(9);
+                    pdfDoc.setFontStyle('bold');
+                    pdfDoc.setTextColor(40);
+                    var pageHeight = pdfDoc.internal.pageSize.height || pdfDoc.internal.pageSize.getHeight();
+                    pdfDoc.text(str, pdfDoc.internal.pageSize.getWidth() - 55, pageHeight - 5);
+                }
+            });
+            if (typeof pdfDoc.putTotalPages === 'function') {
+                pdfDoc.putTotalPages(totalPagesExp);
+            }
+            row.pop();
+            if(model.printer_bridge){
+                var data = pdfDoc.output('datauristring');
+                model.printer_bridge.print(data);
+                return;
+            }
+            pdfDoc.save(pdf_name + hoy + '.pdf');
+        },
+
+        drawSaleJournalPDF: function (getColumns,row,ResCompany,pdf_title,pdf_type,pdf_name,pdf_columnStyles,desde,hasta) {
+            var self = this;
+            var base64Img = 'data:image/png;base64,' + ResCompany.logo;
+            var hoy = moment().format('DD/MM/YYYY');
+            var totalPagesExp = "{total_pages_count_string}";
+            var pdfDoc = new jsPDF(pdf_type);
+
+            /*
+            ==============================================
+                PRIMERA COLUMNA
+            ==============================================
+            */
+
+            // Title
+            pdfDoc.setFontSize(15);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text(pdf_title,7,10);
+
+            // DEL
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('DEL: ' + desde,7,20);
+
+            // AL
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('AL: ' + hasta ,7,24);
+
+            /*
+            ==============================================
+                SEGUNDA COLUMNA
+            ==============================================
+            */
+
+            // CODIGO DESDE
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('Código Desde: ' + 1 ,50,20);
+
+            // CODIGO HASTA
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('Código Hasta: ' + (row.length - 1),50,24);
+
+            /*
+            ==============================================
+                QUINTA COLUMNA
+            ==============================================
+            */
+
+            // Empresa
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('Empresa: ' + ResCompany.name ,100,20);
+
+            // RUC
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('R.U.C: ' + ResCompany.ruc ,100,24);
+
+            /*
+            ==============================================
+                    CREACION DEL PDF
+            ==============================================
+            */
+
+            pdfDoc.autoTable(getColumns, row, {
+                showHeader: 'false',
+                theme: 'grid',
+
+                drawRow: function (row, data) {
+                    if(pdf_type == "l"){
+                        if (row.index === 0) {
+                             pdfDoc.setTextColor(40);
+                             pdfDoc.setFontSize(8);
+                             pdfDoc.setFontStyle('bold');
+                             // Documento
+                             pdfDoc.rect(data.settings.margin.left, row.y, 75, 8, 'S');
+                             // Clientes
+                             pdfDoc.rect(82, row.y, 70, 8, 'S');
+                             // Total de Ventas
+                             pdfDoc.rect(152, row.y, 140, 8, 'S');
+
+                             pdfDoc.autoTableText("DOCUMENTO", 33, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             pdfDoc.autoTableText("CLIENTES", 115, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             pdfDoc.autoTableText("TOTAL DE VENTAS", 210, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // NUM
+                             pdfDoc.rect(data.settings.margin.left, row.y + 8, 27, 8, 'S');
+                             pdfDoc.autoTableText("NUM", 22, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // Factura
+                             pdfDoc.rect(34, row.y + 8, 21, 8, 'S');
+                             pdfDoc.autoTableText("N° Factura", 44, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // FECHA
+                             pdfDoc.rect(55, row.y + 8, 27, 8, 'S');
+                             pdfDoc.autoTableText("FECHA", 65, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // RAZON SOCIAL
+                             pdfDoc.rect(82, row.y + 8, 50, 8, 'S');
+                             pdfDoc.autoTableText("RAZON SOCIAL", 105, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // RUC
+                             pdfDoc.rect(132, row.y + 8, 19.87, 8, 'S');
+                             pdfDoc.autoTableText("RUC", 143, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // TASA 5%
+                             pdfDoc.rect(151.9, row.y + 8, 24.32, 8, 'S');
+                             pdfDoc.autoTableText("TASA 5%", 163, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // GRAVADAS 5%
+                             pdfDoc.rect(151.9, row.y + 8, 24.32, 8, 'S');
+                             pdfDoc.autoTableText("5%", 163, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // TASA 10%
+                             pdfDoc.rect(151.9, row.y + 8, 24.32, 8, 'S');
+                             pdfDoc.autoTableText("TASA 10%", 163, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                              // GRAVADAS 10%
+                             pdfDoc.rect(151.9, row.y + 8, 24.32, 8, 'S');
+                             pdfDoc.autoTableText("10%", 163, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // %
+                             pdfDoc.rect(176.45, row.y + 8, 8.6, 8, 'S');
+                             pdfDoc.autoTableText("%", 179.5, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             //IMPUESTOS
+                             pdfDoc.rect(184.85, row.y + 8, 24, 8, 'S');
+                             pdfDoc.autoTableText("IMPUESTOS", 197, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // EXENTAS
+                             pdfDoc.rect(209, row.y + 8, 21, 8, 'S');
+                             pdfDoc.autoTableText("EXENTAS", 220, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // Ret IVA
+                             pdfDoc.rect(230, row.y + 8, 18, 8, 'S');
+                             pdfDoc.autoTableText("Ret IVA", 238, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // Ret Renta
+                             pdfDoc.rect(248, row.y + 8, 20, 8, 'S');
+                             pdfDoc.autoTableText("Ret RENTA", 258, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // TOTAL
+                             pdfDoc.rect(268, row.y + 8, 24, 8, 'S');
+                             pdfDoc.autoTableText("TOTAL", 279, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             data.cursor.y += 16;
+                         };
+                     }else{
+                         if (row.index === 0) {
+                             pdfDoc.setTextColor(40);
+                             pdfDoc.setFontSize(8);
+                             pdfDoc.setFontStyle('bold');
+                             // Documento
+                             pdfDoc.rect(data.settings.margin.left, row.y, 65, 8, 'S');
+                             // Clientes
+                             pdfDoc.rect(71.9, row.y, 49.1, 8, 'S');
+                             // Total de Ventas
+                             pdfDoc.rect(121.1, row.y, 86.6, 8, 'S');
+                             pdfDoc.autoTableText("DOCUMENTO", 29, row.y + row.height / 2, {
+                                 halign: 'center',
+                             });
+                             pdfDoc.autoTableText(" CLIENTES", 85, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             pdfDoc.autoTableText("TOTAL DE VENTAS",167, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // NUM
+                             pdfDoc.setFontSize(6);
+                             pdfDoc.rect(data.settings.margin.left, row.y + 8, 25, 8, 'S');
+                             pdfDoc.autoTableText("NUM", 21, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // factura
+                             pdfDoc.rect(32.15, row.y + 8, 23.7, 8, 'S');
+                             pdfDoc.autoTableText("N° Fact.", 42, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // FECHA
+                             pdfDoc.rect(55.7, row.y + 8, 16.2, 8, 'S');
+                             pdfDoc.autoTableText("FECHA", 65, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                            });
+                             // RAZON SOCIAL
+                             pdfDoc.rect(72, row.y + 8, 32, 8, 'S');
+                             pdfDoc.autoTableText("RAZON SOCIAL", 85, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // RUC
+                             pdfDoc.rect(104.2, row.y + 8, 16.8, 8, 'S');
+                             pdfDoc.autoTableText("RUC", 111, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // TASA 5%
+                             pdfDoc.rect(121.1, row.y + 8, 15.1, 8, 'S');
+                             pdfDoc.autoTableText("TASA 5%", 128, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // GRAVADAS 5%
+                             pdfDoc.rect(136.1, row.y + 8, 13.05, 8, 'S');
+                             pdfDoc.autoTableText("IVA 5%", 142, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // TASA 10%
+                             pdfDoc.rect(148.7, row.y + 8, 14.55, 8, 'S');
+                             pdfDoc.autoTableText("TASA 10%", 156, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // GRAVADAS 10%
+                             pdfDoc.rect(163.52, row.y + 8, 12.7, 8, 'S');
+                             pdfDoc.autoTableText("IVA 10%", 170, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // EXENTAS
+                             pdfDoc.rect(176.5, row.y + 8, 14.7, 8, 'S');
+                             pdfDoc.autoTableText("EXENTAS", 183.5, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // %
+/*                             pdfDoc.rect(165.5, row.y + 8, 4.6, 8, 'S');
+                             pdfDoc.autoTableText("%", 171, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });*/
+                             // IMPUESTOS
+                         /*    pdfDoc.rect(177, row.y + 8, 15, 7.9, 'S');
+                             pdfDoc.autoTableText("IMPUESTOS", 185, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });*/
+
+                             // Ret IVA
+/*                             pdfDoc.rect(177.1, row.y + 8, 6.7, 8, 'S');
+                             pdfDoc.autoTableText("Ret", 179.3, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });*/
+                           /*  pdfDoc.autoTableText("IVA", 179.3, row.y + row.height / 2 + 10, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });*/
+                             // Ret Renta
+ /*                            pdfDoc.rect(184, row.y + 8, 7.9, 8, 'S');
+                             pdfDoc.autoTableText("Ret", 187.5, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             pdfDoc.autoTableText("Renta", 187.5, row.y + row.height / 2 + 10, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             }); */
+                             // TOTAL
+                             pdfDoc.rect(190.9, row.y + 8, 17, 8, 'S');
+                             pdfDoc.autoTableText("TOTAL", 199, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             data.cursor.y += 16;
+                        };
+                    }
+                },
+
+                drawCell: function(cell, data) {
+                    var rows = data.table.rows;
+                    if (data.row.index == rows.length - 1) {
+                        pdfDoc.setFillColor(200, 200, 255);
+                    }
+                },
+
+                styles: {
+                    overflow: 'linebreak',
+                    columnWidth: 'auto',
+                    fontSize: 7,
+                },
+                headerStyles: {
+                    fillColor: [76, 133, 248],
+                    fontSize: 9
+                },
+
+                columnStyles: pdf_columnStyles,
+                margin: { top: 28, horizontal: 7},
+
+                addPageContent: function (data) {
+                    /*===========
+                        FOOTER
+                    ===========*/
+                    var str = "Página " + data.pageCount;
+                    if (typeof pdfDoc.putTotalPages === 'function') {
+                        str = str + " de " + totalPagesExp;
+                    }
+                    pdfDoc.setFontSize(9);
+                    pdfDoc.setFontStyle('bold');
+                    pdfDoc.setTextColor(40);
+                    var pageHeight = pdfDoc.internal.pageSize.height || pdfDoc.internal.pageSize.getHeight();
+                    pdfDoc.text(str, pdfDoc.internal.pageSize.getWidth() - 55, pageHeight - 5);
+                }
+            });
+
+            pdfDoc.setFontSize(9);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('Listado concluido', 7, pdfDoc.autoTable.previous.finalY + 5);
+
+            if (typeof pdfDoc.putTotalPages === 'function') {
+                pdfDoc.putTotalPages(totalPagesExp);
+            }
+            row.pop();
+            if(model.printer_bridge){
+                var data = pdfDoc.output('datauristring');
+                model.printer_bridge.print(data);
+                return;
+            }
+            pdfDoc.save(pdf_name + hoy + '.pdf');
+        },
+
+
+        // ----------------------- purchase libro
+
+        drawPurchaseJournalPDF: function (getColumns,row,ResCompany,pdf_title,pdf_type,pdf_name,pdf_columnStyles,desde,hasta) {
+            var self = this;
+            var base64Img = 'data:image/png;base64,' + ResCompany.logo;
+            var hoy = moment().format('DD/MM/YYYY');
+            var totalPagesExp = "{total_pages_count_string}";
+            var pdfDoc = new jsPDF(pdf_type);
+
+            /*
+            ==============================================
+                PRIMERA COLUMNA
+            ==============================================
+            */
+
+            // Title
+            pdfDoc.setFontSize(15);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text(pdf_title,7,10);
+
+            // DEL
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('DEL: ' + desde,7,20);
+
+            // AL
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('AL: ' + hasta ,7,24);
+
+            /*
+            ==============================================
+                SEGUNDA COLUMNA
+            ==============================================
+            */
+
+            // CODIGO DESDE
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('Código Desde: ' + 1 ,50,20);
+
+            // CODIGO HASTA
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('Código Hasta: ' + (row.length - 1),50,24);
+
+            /*
+            ==============================================
+                QUINTA COLUMNA
+            ==============================================
+            */
+
+            // Empresa
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('Empresa: ' + ResCompany.name ,100,20);
+
+            // RUC
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('R.U.C: ' + ResCompany.ruc ,100,24);
+
+            /*
+            ==============================================
+                    CREACION DEL PDF
+            ==============================================
+            */
+
+            pdfDoc.autoTable(getColumns, row, {
+                showHeader: 'false',
+                theme: 'grid',
+
+                drawRow: function (row, data) {
+                    if(pdf_type == "l"){
+                        if (row.index === 0) {
+                             pdfDoc.setTextColor(40);
+                             pdfDoc.setFontSize(8);
+                             pdfDoc.setFontStyle('bold');
+                             // Documento
+                             pdfDoc.rect(data.settings.margin.left, row.y, 75, 8, 'S');
+                             // Clientes
+                             pdfDoc.rect(82, row.y, 70, 8, 'S');
+                             // Total de Ventas
+                             pdfDoc.rect(152, row.y, 140, 8, 'S');
+
+                             pdfDoc.autoTableText("DOCUMENTO", 33, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             pdfDoc.autoTableText("PROVEEDORES", 115, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             pdfDoc.autoTableText("TOTAL DE COMPRAS", 210, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // NUM
+                             pdfDoc.rect(data.settings.margin.left, row.y + 8, 27, 8, 'S');
+                             pdfDoc.autoTableText("NUM", 22, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // Factura
+                             pdfDoc.rect(34, row.y + 8, 21, 8, 'S');
+                             pdfDoc.autoTableText("N° Factura", 44, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // FECHA
+                             pdfDoc.rect(55, row.y + 8, 27, 8, 'S');
+                             pdfDoc.autoTableText("FECHA", 65, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // RAZON SOCIAL
+                             pdfDoc.rect(82, row.y + 8, 50, 8, 'S');
+                             pdfDoc.autoTableText("RAZON SOCIAL", 105, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // RUC
+                             pdfDoc.rect(132, row.y + 8, 19.87, 8, 'S');
+                             pdfDoc.autoTableText("RUC", 143, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // TASA 5%
+                             pdfDoc.rect(151.1, row.y + 8, 15.1, 8, 'S');
+                             pdfDoc.autoTableText("TASA 5%", 158, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // GRAVADAS 5%
+                             pdfDoc.rect(166.1, row.y + 8, 13.05, 8, 'S');
+                             pdfDoc.autoTableText("IVA 5%", 172, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // TASA 10%
+                             pdfDoc.rect(178.7, row.y + 8, 14.55, 8, 'S');
+                             pdfDoc.autoTableText("TASA 10%", 186, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // GRAVADAS 10%
+                             pdfDoc.rect(193.52, row.y + 8, 12.7, 8, 'S');
+                             pdfDoc.autoTableText("IVA 10%", 200, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // EXENTAS
+                             pdfDoc.rect(206.5, row.y + 8, 14.7, 8, 'S');
+                             pdfDoc.autoTableText("EXENTAS", 213.5, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // Ret IVA
+                             pdfDoc.rect(230, row.y + 8, 18, 8, 'S');
+                             pdfDoc.autoTableText("Ret IVA", 238, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // Ret Renta
+                             pdfDoc.rect(248, row.y + 8, 20, 8, 'S');
+                             pdfDoc.autoTableText("Ret RENTA", 258, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // TOTAL
+                             pdfDoc.rect(268, row.y + 8, 24, 8, 'S');
+                             pdfDoc.autoTableText("TOTAL", 279, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             data.cursor.y += 16;
+                         };
+                     }else{
+                         if (row.index === 0) {
+                             pdfDoc.setTextColor(40);
+                             pdfDoc.setFontSize(8);
+                             pdfDoc.setFontStyle('bold');
+                             // Documento
+                             pdfDoc.rect(data.settings.margin.left, row.y, 65, 8, 'S');
+                             // Clientes
+                             pdfDoc.rect(71.9, row.y, 49.1, 8, 'S');
+                             // Total de Ventas
+                             pdfDoc.rect(121.1, row.y, 86.6, 8, 'S');
+                             pdfDoc.autoTableText("DOCUMENTO", 29, row.y + row.height / 2, {
+                                 halign: 'center',
+                             });
+                             pdfDoc.autoTableText("PROVEEDORES", 85, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             pdfDoc.autoTableText("TOTAL DE COMPRAS",167, row.y + row.height / 2, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // NUM
+                             pdfDoc.setFontSize(6);
+                             pdfDoc.rect(data.settings.margin.left, row.y + 8, 25, 8, 'S');
+                             pdfDoc.autoTableText("NUM", 21, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // factura
+                             pdfDoc.rect(32.15, row.y + 8, 23.7, 8, 'S');
+                             pdfDoc.autoTableText("N° Fact.", 42, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // FECHA
+                             pdfDoc.rect(55.7, row.y + 8, 16.2, 8, 'S');
+                             pdfDoc.autoTableText("FECHA", 65, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                            });
+                             // RAZON SOCIAL
+                             pdfDoc.rect(72, row.y + 8, 32, 8, 'S');
+                             pdfDoc.autoTableText("RAZON SOCIAL", 85, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // RUC
+                             pdfDoc.rect(104.2, row.y + 8, 16.8, 8, 'S');
+                             pdfDoc.autoTableText("RUC", 111, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // TASA 5%
+                             pdfDoc.rect(121.1, row.y + 8, 15.1, 8, 'S');
+                             pdfDoc.autoTableText("TASA 5%", 128, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // GRAVADAS 5%
+                             pdfDoc.rect(136.1, row.y + 8, 13.05, 8, 'S');
+                             pdfDoc.autoTableText("IVA 5%", 142, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // TASA 10%
+                             pdfDoc.rect(148.7, row.y + 8, 14.55, 8, 'S');
+                             pdfDoc.autoTableText("TASA 10%", 156, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // GRAVADAS 10%
+                             pdfDoc.rect(163.52, row.y + 8, 12.7, 8, 'S');
+                             pdfDoc.autoTableText("IVA 10%", 170, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                            // EXENTAS
+                             pdfDoc.rect(176.5, row.y + 8, 14.7, 8, 'S');
+                             pdfDoc.autoTableText("EXENTAS", 183.5, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             // %
+/*                             pdfDoc.rect(165.5, row.y + 8, 4.6, 8, 'S');
+                             pdfDoc.autoTableText("%", 171, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });*/
+                             // IMPUESTOS
+                         /*    pdfDoc.rect(177, row.y + 8, 15, 7.9, 'S');
+                             pdfDoc.autoTableText("IMPUESTOS", 185, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });*/
+
+                             // Ret IVA
+/*                             pdfDoc.rect(177.1, row.y + 8, 6.7, 8, 'S');
+                             pdfDoc.autoTableText("Ret", 179.3, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });*/
+                           /*  pdfDoc.autoTableText("IVA", 179.3, row.y + row.height / 2 + 10, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });*/
+                             // Ret Renta
+ /*                            pdfDoc.rect(184, row.y + 8, 7.9, 8, 'S');
+                             pdfDoc.autoTableText("Ret", 187.5, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             pdfDoc.autoTableText("Renta", 187.5, row.y + row.height / 2 + 10, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             }); */
+                             // TOTAL
+                            pdfDoc.rect(190.9, row.y + 8, 17, 8, 'S');
+                             pdfDoc.autoTableText("TOTAL", 199, row.y + row.height / 2 + 8, {
+                                 halign: 'center',
+                                 valign: 'middle'
+                             });
+                             data.cursor.y += 16;
+                        };
+                    }
+                },
+
+                drawCell: function(cell, data) {
+                    var rows = data.table.rows;
+                    if (data.row.index == rows.length - 1) {
+                        pdfDoc.setFillColor(200, 200, 255);
+                    }
+                },
+
+                styles: {
+                    overflow: 'linebreak',
+                    columnWidth: 'auto',
+                    fontSize: 7,
+                },
+                headerStyles: {
+                    fillColor: [76, 133, 248],
+                    fontSize: 9
+                },
+
+                columnStyles: pdf_columnStyles,
+                margin: { top: 28, horizontal: 7},
+
+                addPageContent: function (data) {
+                    /*===========
+                        FOOTER
+                    ===========*/
+                    var str = "Página " + data.pageCount;
+                    if (typeof pdfDoc.putTotalPages === 'function') {
+                        str = str + " de " + totalPagesExp;
+                    }
+                    pdfDoc.setFontSize(9);
+                    pdfDoc.setFontStyle('bold');
+                    pdfDoc.setTextColor(40);
+                    var pageHeight = pdfDoc.internal.pageSize.height || pdfDoc.internal.pageSize.getHeight();
+                    pdfDoc.text(str, pdfDoc.internal.pageSize.getWidth() - 55, pageHeight - 5);
+                }
+            });
+
+            pdfDoc.setFontSize(9);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text('Listado concluido', 7, pdfDoc.autoTable.previous.finalY + 5);
+
+            if (typeof pdfDoc.putTotalPages === 'function') {
+                pdfDoc.putTotalPages(totalPagesExp);
+            }
+            row.pop();
+            if(model.printer_bridge){
+                var data = pdfDoc.output('datauristring');
+                model.printer_bridge.print(data);
+                return;
+            }
+            pdfDoc.save(pdf_name + hoy + '.pdf');
+        },
+
+
+        // ---------------------- fin purchase libro
+
+        drawWithDetails: function (getColumns,row,ResCompany,pdf_title,pdf_type,pdf_name,pdf_columnStyles,amount) {
+            var self = this;
+            var base64Img = 'data:image/png;base64,' + ResCompany.logo;
+            var hoy = moment().format('DD/MM/YYYY');
+            var totalPagesExp = "{total_pages_count_string}";
+            var pdfDoc = new jsPDF(pdf_type);
+            var title = [];
+            title.push({
+                title : 'Metodo de Pago',
+                dataKey: 'name',
+                align: 'left',
+            });
+            title.push({
+                title : 'Monto',
+                dataKey: 'amount',
+                align: 'right',
+            });
+            var i = 0;
+            var position = 25;
+            _.each(row, function(item){
+                var docItem = [];
+                if(item.info != 'undefined'){
+                    _.each(item.info, function(index){
+                        docItem.push({
+                            name: index.journal,
+                            amount: index.amount_total
+                        });
+                    });
+                };
+                docItem.push({
+                    name: 'Total',
+                    amount: item.amount_total
+                });
+
+                if(row.length <= 2 & row.length == i+1){
+                    return false;
+                };
+
+                if(i > 0){
+                    let first = pdfDoc.autoTable.previous;
+                    position = first.finalY + 7;
+                    pdfDoc.rect(7, position - 7, 196, 10, 'S');
+                };
+                pdfDoc.setFontSize(10);
+                pdfDoc.autoTableText(item.store, 102, position - 3, {
+                    halign: 'center',
+                    valign: 'middle'
+                });
+                pdfDoc.autoTable(title, docItem, {
+                    showHeader: false,
+                    startY: position,
+                    theme: 'grid',
+                    styles: {
+                        overflow: 'linebreak',
+                        columnWidth: 'auto',
+                        fontSize: 7,
+                    },
+                    headerStyles: {
+                        fillColor: [76, 133, 248],
+                        fontSize: 9
+                    },
+                    columnStyles: {
+                        name:{halign:'left'},
+                        amount:{columnWidth: 50, halign:'right'},
+                    },
+                    margin: { horizontal: 7},
+                    drawCell: function(cell, data) {
+                        var rows = data.table.rows;
+                        if (data.row.index == rows.length - 1) {
+                            pdfDoc.setFontStyle('bold');
+                        }
+                    },
+                    addPageContent: function (data) {
+                        if(i == 0){
+                            pdfDoc.addImage(base64Img, 'png', 7, 2, 0, 15);
+                            if(pdf_type == 'l'){
+                                pdfDoc.setFontSize(12);
+                                pdfDoc.setFontStyle('bold');
+                                pdfDoc.setTextColor(40);
+                                pdfDoc.text(pdf_title,130,10);
+                            }else{
+                                pdfDoc.setFontSize(12);
+                                pdfDoc.setFontStyle('bold');
+                                pdfDoc.setTextColor(40);
+                                pdfDoc.text(pdf_title,80,10);
+                            }
+                            pdfDoc.setFontSize(9);
+                            pdfDoc.setFontStyle('normal');
+                            pdfDoc.setTextColor(40)
+                            pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 55, 14," Fecha de Expedición: " + hoy);
+
+                            /*===========
+                                FOOTER
+                            ===========*/
+                            var str = "Página " + data.pageCount;
+                            if (typeof pdfDoc.putTotalPages === 'function') {
+                                str = str + " de " + totalPagesExp;
+                            }
+                            pdfDoc.setFontSize(9);
+                            pdfDoc.setFontStyle('bold');
+                            pdfDoc.setTextColor(40);
+                            var pageHeight = pdfDoc.internal.pageSize.height || pdfDoc.internal.pageSize.getHeight();
+                            pdfDoc.text(str, pdfDoc.internal.pageSize.getWidth() - 55, pageHeight - 5);
+                        }
+                    }
+                });
+                i++;
+            });
+
+            if (typeof pdfDoc.putTotalPages === 'function') {
+                pdfDoc.putTotalPages(totalPagesExp);
+            }
+            // row.pop();
+            if(model.printer_bridge){
+                var data = pdfDoc.output('datauristring');
+                model.printer_bridge.print(data);
+                return;
+            }
+            pdfDoc.save(pdf_name + hoy + '.pdf');
+        },
+
+        drawProfitAndLossPDF: function (
+            getColumns,
+            row,
+            ResCompany,
+            pdf_title,
+            pdf_type,
+            pdf_name,
+            amount
+            ) {
+            var self = this;
+            var sale = [];
+            var expense = [];
+            var column = [];
+            var base64Img = 'data:image/png;base64,' + ResCompany.logo;
+            var hoy = moment().format('DD/MM/YYYY');
+            var totalPagesExp = "{total_pages_count_string}";
+            var pdfDoc = new jsPDF(pdf_type);
+
+            /*
+            ============================
+                VENTAS
+            ============================
+            */
+            var coste = 0;
+            var profit = 0;
+            _.each(row, function(item){
+                if(item.type == 'sale'){
+                    sale.push({
+                        name : item.store,
+                        total : item.amount_total,
+                    });
+                };
+                if(item.expense == true){
+                    coste = item.amount_total;
+                };
+                if(item.profit == true){
+                    profit = item.amount_total;
+                };
+                if(item.expense_detail == true){
+                    expense.push({
+                        name : item.store,
+                        total : item.amount_total,
+                    });
+                };
+            });
+            column.push({
+                title : 'Name',
+                dataKey: 'name',
+                align: 'left',
+            });
+            column.push({
+                title : 'total',
+                dataKey: 'total',
+                align: 'right',
+            });
+
+            /*
+            ==============================
+                LOGO
+            ==============================
+            */
+            pdfDoc.addImage(base64Img, 'png', 10, 10, 0, 20);
+            /*
+            ==============================
+                FECHA
+            ==============================
+            */
+            pdfDoc.setFontSize(13);
+            pdfDoc.setFontStyle('normal');
+            pdfDoc.setTextColor(40)
+            pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 32, 12,hoy);
+            /*
+            ==============================
+                TITULO
+            ==============================
+            */
+            pdfDoc.setFontSize(15);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor('#0288d1');
+            pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 75, 18, pdf_title);
+            /*
+            ==============================
+                DESCRIPCION
+            ==============================
+            */
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor('#424242');
+            pdfDoc.text(10, 38, 'Descripción');
+            /*
+            ==============================
+                LINEA
+            ==============================
+            */
+            pdfDoc.setLineWidth(0.5);
+            pdfDoc.setDrawColor('#424242');
+            pdfDoc.line(10, 40, pdfDoc.internal.pageSize.getWidth() - 10 , 40);
+            /*
+            ==============================
+                VENTAS
+            ==============================
+            */
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor('#424242');
+            pdfDoc.text(10, 45, 'VENTAS');
+
+            /*
+            ==============================
+                PRIMERA TABLA
+            ==============================
+            */
+            pdfDoc.autoTable(column, sale, {
+                showHeader: false,
+                theme: 'plain',
+                styles: {
+                    overflow: 'linebreak',
+                    columnWidth: 'auto',
+                    fontSize: 9,
+                },
+                columnStyles: {
+                    amount:{halign:'left'},
+                    total:{columnWidth: 50, halign:'right'},
+                },
+                margin: { top: 48, horizontal: 20},
+                drawCell: function(cell, data) {
+                    var rows = data.table.rows;
+                    if (data.row.index == rows.length - 1) {
+                        pdfDoc.setTextColor('#0288d1');
+                        pdfDoc.setFontStyle('bold');
+                    };
+                },
+            });
+            /*
+            ==============================
+                LINEA
+            ==============================
+            */
+            pdfDoc.setLineWidth(0.5);
+            pdfDoc.setDrawColor('#424242');
+            pdfDoc.line(10, pdfDoc.autoTable.previous.finalY + 1, pdfDoc.internal.pageSize.getWidth() - 10 , pdfDoc.autoTable.previous.finalY + 1);
+            /*
+            ==============================
+                COSTE DE VENTAS
+            ==============================
+            */
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor('#424242');
+            pdfDoc.text(10, pdfDoc.autoTable.previous.finalY + 7, 'Coste de ventas');
+            /*
+            ==============================
+                COSTE DE VENTAS - valor
+            ==============================
+            */
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor('#424242');
+            pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 35, pdfDoc.autoTable.previous.finalY + 7, coste);
+            /*
+            ==============================
+                LINEA
+            ==============================
+            */
+            pdfDoc.setLineWidth(0.5);
+            pdfDoc.setDrawColor('#424242');
+            pdfDoc.line(10, pdfDoc.autoTable.previous.finalY + 10, pdfDoc.internal.pageSize.getWidth() - 10 , pdfDoc.autoTable.previous.finalY + 10);
+            /*
+            ==============================
+                BENEFICIO
+            ==============================
+            */
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text(10, pdfDoc.autoTable.previous.finalY + 15, 'BENEFICIO BRUTO');
+            /*
+            ==============================
+                BENEFICIO - valor
+            ==============================
+            */
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor('#0288d1');
+            pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 35, pdfDoc.autoTable.previous.finalY + 15, profit);
+            /*
+            ==============================
+                SEGUNDA TABLA
+            ==============================
+            */
+            var dynamic_top = pdfDoc.autoTable.previous.finalY + 25;
+            pdfDoc.autoTable(column, expense, {
+                showHeader: false,
+                theme: 'plain',
+                styles: {
+                    overflow: 'linebreak',
+                    columnWidth: 'auto',
+                    fontSize: 9,
+                },
+                columnStyles: {
+                    amount:{halign:'left'},
+                    total:{columnWidth: 50, halign:'right'},
+                },
+                startY: pdfDoc.autoTable.previous.finalY + 25,
+                margin: {
+                    horizontal: 20
+                },
+                drawCell: function(cell, data) {
+                    var rows = data.table.rows;
+                    if (data.row.index == rows.length - 1) {
+                        pdfDoc.setTextColor('#0288d1');
+                        pdfDoc.setFontStyle('bold');
+                    };
+                },
+                addPageContent: function (data) {
+                    /*===========
+                        FOOTER
+                    ===========*/
+                    var str = "Página " + data.pageCount;
+                    if (typeof pdfDoc.putTotalPages === 'function') {
+                        str = str + " de " + totalPagesExp;
+                    }
+                    pdfDoc.setFontSize(9);
+                    pdfDoc.setFontStyle('bold');
+                    pdfDoc.setTextColor(40);
+                    var pageHeight = pdfDoc.internal.pageSize.height || pdfDoc.internal.pageSize.getHeight();
+                    pdfDoc.text(str, pdfDoc.internal.pageSize.getWidth() - 55, pageHeight - 5);
+                },
+            });
+
+            /*
+            ==============================
+                LINEA
+            ==============================
+            */
+            pdfDoc.setLineWidth(0.5);
+            pdfDoc.setDrawColor('#424242');
+            pdfDoc.line(10, pdfDoc.autoTable.previous.finalY + 10, pdfDoc.internal.pageSize.getWidth() - 10 , pdfDoc.autoTable.previous.finalY + 10);
+            /*
+            ==============================
+                RESULTADO
+            ==============================
+            */
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor(40);
+            pdfDoc.text(10, pdfDoc.autoTable.previous.finalY + 15, 'RESULTADO');
+            /*
+            ==============================
+                VALOR FINAL
+            ==============================
+            */
+            pdfDoc.setFontSize(10);
+            pdfDoc.setFontStyle('bold');
+            pdfDoc.setTextColor('#0288d1');
+            pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 35, pdfDoc.autoTable.previous.finalY + 15, amount);
+
+            if (typeof pdfDoc.putTotalPages === 'function') {
+                pdfDoc.putTotalPages(totalPagesExp);
+            }
+
+            if(model.printer_bridge){
+                var data = pdfDoc.output('datauristring');
+                model.printer_bridge.print(data);
+                return;
+            };
+            pdfDoc.save(pdf_name + hoy + '.pdf');
+        },
+
+        getPDFFileButton: function  () {
+            var canvas = $(".reporting-chart").get(0);
+            var dataURL = canvas.toDataURL();
+            var pdf = new jsPDF();
+            pdf.addImage(dataURL, 'JPEG', 10, 10, 190, 70);
+            pdf.save("chart.pdf");
+        },
+
+        // pdf resumen de ventas diarias cod:3
+        drawPdf3: function (row,ResCompany,pdf_title,pdf_type,pdf_name,pdf_columnStyles,filter) {
+          var self = this;
+          var base64Img = 'data:image/png;base64,' + ResCompany.logo;
+          var hoy = moment().format('DD/MM/YYYY');
+          var totalPagesExp = "{total_pages_count_string}";
+          var pdfDoc = new jsPDF(pdf_type);
+          var title = [];
+          var currentpage = 0;
+          var i = 0;
+          var position = 27;
+          var y_position2 = 27;
+
+          title.push({
+            title : 'Fecha',
+            dataKey: 'date',
+            align: 'center',
+          });
+          title.push({
+            title : 'Sucursal',
+            dataKey: 'store',
+            align: 'center',
+          });
+          title.push({
+            title : 'Cantidad',
+            dataKey: 'qty',
+            align: 'center',
+          });
+          title.push({
+            title : 'Monto de Venta',
+            dataKey: 'price',
+            align: 'right',
+          });
+          title.push({
+            title : 'Promedio de Venta Total',
+            dataKey: 'average',
+            align: 'right',
+          });
+
+          //LOGO
+          pdfDoc.addImage(base64Img, 'png', 7, 2, 0, 15);
+
+          //FECHA
+          pdfDoc.setFontSize(13);
+          pdfDoc.setFontStyle('normal');
+          pdfDoc.setTextColor(40)
+          pdfDoc.text(pdfDoc.internal.pageSize.getWidth() - 35, 12,hoy);
+
+          //TITULO
+          pdfDoc.setFontSize(15);
+          pdfDoc.setFontStyle('bold');
+          pdfDoc.setTextColor('#0288d1');
+          pdfDoc.autoTableText(pdf_title, pdfDoc.internal.pageSize.getWidth() - 12, 18, {
+            halign: 'right',
+            valign: 'middle'
+          });
+          pdfDoc.setLineWidth(0.5);
+          pdfDoc.setDrawColor('#424242');
+          pdfDoc.line(10, 22, pdfDoc.internal.pageSize.getWidth() - 10 , 22);
+
+          var ii=0;
+          if(pdf_type == 'l'){
+            var col1_title = 15;
+            var col1_value = 55;
+            var col2_title = 150;
+            var col2_value = 190;
+          }
+          else{
+            var col1_title = 10;
+            var col1_value = 50;
+            var col2_title = 110;
+            var col2_value = 150;
+          }
+          if(filter.length >0){
+            _.each(filter,function(item){
+              if(ii<4){
+                self.addFilter(pdfDoc,item.title,item.value,col1_title,col1_value,position);
+                position = position + 5;
+              }else{
+                self.addFilter(pdfDoc,item.title,item.value,col2_title,col2_value,y_position2);
+                y_position2 = y_position2 + 5;
+              }
+                ii++;
+            });
+            pdfDoc.setLineWidth(0.5);
+            pdfDoc.setDrawColor('#424242');
+
+            if(position >= y_position2){
+              position = position;
+              pdfDoc.line(10, position, pdfDoc.internal.pageSize.getWidth() - 10 , position);
+            }else{
+              position = y_position2;
+              pdfDoc.line(10, y_position2, pdfDoc.internal.pageSize.getWidth() - 10 , y_position2);
+            }
+          }
+
+          _.each(row, function(item){
+            if(i > 0){
+              let first = pdfDoc.autoTable.previous;
+              position = first.finalY + 5;
+            };
+
+            var docItem = [];
+            if(item.info != 'undefined'){
+              _.each(item.info, function(index){
+                docItem.push({
+                  date: index.date,
+                  store: index.store,
+                  qty: index.qty,
+                  price: index.price,
+                  average: index.average,
+                })
+              });
+            }
+
+            pdfDoc.setDrawColor(0);
+            pdfDoc.setFillColor(76, 133, 248);
+            pdfDoc.rect(7, position+5, 196, 8, 'F');
+
+            pdfDoc.setFontSize(9);
+            pdfDoc.setTextColor(255,255,255)
+            pdfDoc.setFontStyle('bold');
+
+            pdfDoc.autoTableText('Vendedor: ', 15, position+9, {
+              halign: 'left',
+              valign: 'middle'
+            });
+
+            pdfDoc.autoTableText(item.user, 33, position+9, {
+              halign: 'left',
+              valign: 'middle'
+            });
+
+            pdfDoc.autoTableText('Cantidad: ', 110, position+9, {
+              halign: 'left',
+              valign: 'middle'
+            });
+
+            pdfDoc.autoTableText(item.qty, 126, position+9, {
+              halign: 'left',
+              valign: 'middle'
+            });
+
+            pdfDoc.autoTableText('Monto Total: ', 145, position+9, {
+              halign: 'left',
+              valign: 'middle'
+            });
+
+            pdfDoc.autoTableText(item.price, 165, position+9, {
+              halign: 'left',
+              valign: 'middle'
+            });
+
+            pdfDoc.autoTable(title, docItem, {
+              //  showHeader: false,
+              startY: position+15,
+              theme: 'grid',
+              styles: {
+                overflow: 'linebreak',
+                fontSize: 8,
+                margin: 50,
+                lineWidth: 0.3,
+                lineColor: [132,132,132]
+              },
+              headerStyles: {
+                fillColor: [255,255,255],
+                fontSize: 9,
+                textColor: [0,0,0],
+                lineWidth: 0.3,
+                lineColor: [132,132,132]
+              },
+              columnStyles: pdf_columnStyles,
+              margin: 'auto',
+              tableWidth: 'auto',
+
+              addPageContent: function (data) {
+                // FOOTER
+                if (currentpage < pdfDoc.internal.getNumberOfPages()) {
+                  var str = "Página " + pdfDoc.internal.getNumberOfPages();
+                  str = str + " de " + totalPagesExp;
+                  pdfDoc.setFontSize(9);
+                  pdfDoc.setFontStyle('bold');
+                  pdfDoc.setTextColor(40);
+                  var pageHeight = pdfDoc.internal.pageSize.height || pdfDoc.internal.pageSize.getHeight();
+                  pdfDoc.text(str, pdfDoc.internal.pageSize.getWidth() - 55, pageHeight - 5);
+                  currentpage = pdfDoc.internal.getNumberOfPages();
+                }
+              }
+            });
+            i++;
+          });
+          if (typeof pdfDoc.putTotalPages === 'function') {
+            pdfDoc.putTotalPages(totalPagesExp);
+          }
+          row.pop();
+          if(model.printer_bridge){
+            var data = pdfDoc.output('datauristring');
+            model.printer_bridge.print(data);
+            return;
+          }
+          pdfDoc.save(pdf_name + hoy + '.pdf');
+        },
+        //end cod:3
+
+    });
+}

+ 22 - 0
static/src/js/reporting_base.js

@@ -0,0 +1,22 @@
+function reporting_base (instance, widget) {
+    "use strict";
+
+    widget.Base = instance.Widget.extend({
+
+        position: 0,
+
+        init: function (parent, position) {
+            this._super(parent);
+            this.position = position || this.position;
+        },
+        start: function () {
+            
+        },
+        getPosition: function () {
+            return this.position;
+        },
+        setPosition: function (position) {
+            this.position = position;
+        }
+    });
+}

+ 1040 - 0
static/src/js/reports/report_account_payable.js

@@ -0,0 +1,1040 @@
+function report_account_payable(reporting){
+  "use strict";
+  var model = openerp;
+
+  reporting.ReportAccountPayableWidget = reporting.Base.extend({
+    template: 'ReportAccountPayable',
+    rowsData :[],
+    content :[],
+
+    events:{
+      'click #toolbar > button' : 'clickOnAction',
+      'click #generate' : 'fetchGenerate',
+      'click-row.bs.table #table' : 'clickAnalysisDetail',
+      'change #current-company' : 'updateSelections',
+      'change #current-store' : 'updateJournalSelections',
+      'change #current-period' : 'updatePeriodSelections',
+      'change #current-date' : 'ShowDateRange',
+    },
+
+    init : function(parent){
+      this._super(parent);
+    },
+
+    start: function () {
+      var table = this.$el.find('#table');
+      table.bootstrapTable({data : self.rowsData});
+      var date = new reporting.ReportDatePickerWidget(self);
+      date.fecthFecha();
+      this.fetchInitial();
+    },
+
+    valorNull:function(dato){
+      var valor = "";
+      if (dato){
+        valor = dato;
+      }
+      return valor;
+    },
+
+    ShowDateRange : function(){
+      var self = this;
+      var date = self.$el.find('#current-date').val();
+      if(date == 'range'){
+        self.$el.find('.datepicker').css('display','block');
+      }
+      if(date != 'range'){
+        self.$el.find('.datepicker').css('display','none');
+      }
+    },
+
+    clickAnalysisDetail : function(e, row, $element, field){
+        if(field == 'number'){
+            this.do_action({
+                name : 'Factura',
+                type : 'ir.actions.act_window',
+                res_model : 'account.invoice',
+                views : [[false,'form']],
+                target  : 'new',
+                domain : [['id','=',row.id]],
+                context : {},
+                flags : {'form' : {'action_buttons' : false, 'options' : {'mode' : 'view'}}},
+                res_id : row.id,
+            });
+        }
+        e.stopImmediatePropagation();
+    },
+
+
+    fetchInitial: function () {
+      var self = this;
+      self.fecthIrModuleModule().then(function (IrModuleModule) {
+        return IrModuleModule;
+      }).then(function(IrModuleModule) {
+        self.IrModuleModule = IrModuleModule;
+        return self.fetchResUser;
+      }).then(function (ResUser) {
+        self.ResUser = ResUser;
+        return self.fetchResCompany();
+      }).then(function(ResCompany){
+        self.ResCompany = ResCompany;
+        if(ResCompany.length > 1){
+          self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+          _.each(ResCompany,function(item){
+            self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+        }else{
+          self.$el.find('.company').css('display','none');
+        }
+        return self.fetchResStore();
+      }).then(function(ResStore){
+        self.ResStore = ResStore;
+        if(ResStore.length > 1){
+          self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+          _.each(ResStore,function(item){
+            self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+        }else{
+          self.$el.find('.store').css('display','none');
+        }
+        return self.fetchAccountJournal();
+      }).then(function(AccountJournal){
+        self.AccountJournal = AccountJournal;
+        if(AccountJournal.length > 1){
+          self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+          _.each(AccountJournal,function(item){
+            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+        }else{
+          self.$el.find('.journal').css('display','none');
+        }
+        return self.fetchAccountPeriod();
+      }).then(function(AccountPeriod){
+        self.AccountPeriod = AccountPeriod;
+        self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+        _.each(AccountPeriod,function(item){
+          self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+        });
+        return self.fetchResCurrency();
+      }).then(function(ResCurrency){
+        self.ResCurrency = ResCurrency;
+      });
+        self.$el.find('#generate').css('display','inline');
+        return;
+      },
+
+      fetchGenerate: function () {
+        var self = this;
+        self.$el.find('.search-form').block({
+          message: null,
+          overlayCSS: {
+            backgroundColor: '#FAFAFA'
+          }
+        });
+        self.$el.find('.report-form').block({
+          message: null,
+          overlayCSS: {
+            backgroundColor: '#FAFAFA'
+          }
+        });
+        this.fetchAccountInvoice().then(function(AccountInvoice) {
+          return AccountInvoice;
+        }).then(function (AccountInvoice) {
+          self.AccountInvoice = AccountInvoice;
+          return self.fetchAccountMoveLine();
+        }).then(function (AccountMoveLine){
+          self.AccountMoveLine = AccountMoveLine;
+          return self.fetchAccountVoucher();
+        }).then(function (AccountVoucher){
+          self.AccountVoucher = AccountVoucher;
+          return self.BuildTable();
+        });
+      },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+      fecthIrModuleModule: function(){
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['name','id'];
+        var domain=[['state','=','installed']];
+        var IrModuleModule = new model.web.Model('ir.module.module');
+        IrModuleModule.query(fields).filter(domain).all().then(function(results){
+          defer.resolve(results);
+        })
+        return defer;
+      },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','purchase']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open']],
+                ['type', '=', 'in_invoice'],
+                ['journal_id','in',journal_ids],
+                ['origin', '!=', false]
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================*/
+        fetchAccountMoveLine: function (){
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['move_id','in',invoice_numbers],
+                ['credit','>',0],
+            ];
+
+            var AccountMoveLine = new model.web.Model('account.move.line');
+            return AccountMoveLine.call('getAccountMoveLine',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*=====================================================================
+            ACCOUNT VOUCHER
+        =====================================================================*/
+        fetchAccountVoucher: function () {
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['state','=','posted'],
+                ['reference','in',invoice_numbers]
+            ];
+
+            var AccountVoucher = new model.web.Model('account.voucher');
+            return AccountVoucher.call('getAccountVoucher',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT MOVE LINE
+        ====================================================================*/
+        getAccountMoveLine: function (number) {
+            var self = this;
+            return _.filter(self.AccountMoveLine,function (item) {
+                return item.move_id[1] == number;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT VOUCHER
+        ====================================================================*/
+        getAccountVoucher: function (number) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.reference == number;
+            })
+        },
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*============================
+            ACCOUNT DATA BY DAY
+        ============================*/
+        getContentByDay:function(date) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM-DD') === date;
+            }));
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var info = [];
+            var payments = [];
+            var type = $('#current-type').val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var AccountInvoice = self.AccountInvoice;
+            _.each(AccountInvoice, function(item){
+                info = [];
+                payments = [];
+                var AccountMoveLine = self.getAccountMoveLine(item.number);
+                var AccountVoucher = self.getAccountVoucher(item.number);
+                var Currency = self.getResCurrency(item.invoice_currency[0]).shift();
+                var i = AccountMoveLine.length;
+                var x = AccountMoveLine.length;
+                _.each(AccountMoveLine, function(index){
+                    var amount = 0;
+                    var date;
+                    if(Currency.id != CurrencyBase.id){
+                        amount = accounting.formatMoney(index.debit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.price_subtotal, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) +')';
+                    }else{
+                        amount = accounting.formatMoney(index.debit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                    };
+                    var state = 'No Pagado';
+                    if(index.reconcile_ref){
+                        if(index.amount_residual == 0){
+                            state = 'Pagado'
+                        };
+                        if(index.amount_residual > 0){
+                            var value = accounting.formatMoney(index.debit - index.amount_residual, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                            state = 'Amortizado ' + ' ( ' + value + ' )';
+                        };
+                    };
+                    date = moment(index.date_maturity).format('DD/MM/YYYY');
+                    if(state != 'Pagado'){
+                        if(index.date_maturity < moment().format('YYYY-MM-DD')){
+                            date = moment(index.date_maturity).format('DD/MM/YYYY') + ' (vencido) ';
+                        };
+                    };
+                    info.push({
+                        date : date,
+                        name : 'Cuota ' + i +' / ' + x,
+                        state : state,
+                        amount: amount,
+                    });
+                    i--;
+                });
+                if(AccountVoucher.length > 0){
+                    _.each(AccountVoucher, function(index){
+                        var CurrencyVoucher = self.getResCurrency(index.currency_id[0]).shift();
+                        var amount = 0;
+                        if(CurrencyVoucher.id != CurrencyBase.id){
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.amount, '', CurrencyVoucher.decimal_places, CurrencyVoucher.thousands_separator, CurrencyVoucher.decimal_separator) +')';
+                        }else{
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        }
+                        payments.push({
+                            date : moment(index.date).format('DD/MM/YYYY'),
+                            user : index.create_uid,
+                            journal_name : index.journal_id[1],
+                            amount : amount,
+                        });
+                    });
+                }
+
+                var residual_total = 0;
+                var amount_untaxed_total = 0;
+                var amount_tax_total = 0;
+                var amount_total = 0;
+
+                if(Currency.id != CurrencyBase.id){
+                    residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.residual, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                    amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.amount_total, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                }else{
+                    residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                    amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                }
+
+                data.push({
+                    /*=======================
+                        IDS
+                    =======================*/
+                    id : item.id,
+                    /*=======================
+                        INFO
+                    =======================*/
+                    number : item.number,
+                    supplier_invoice_number: self.valorNull(item.supplier_invoice_number),
+                    date_invoice : moment(item.date_invoice).format('DD/MM/YYYY'),
+                    date : moment(item.date_invoice).format('YYYY-MM-DD'),
+                    user_id : item.user_id[1],
+                    partner_id : self.valorNull(item.partner_id[1]),
+                    residual_total : residual_total,
+                    amortized_total: accounting.formatMoney(item.amount_total_currency - item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    amount_total : amount_total,
+                    /*=======================
+                        VALORES SIN FORMATEAR
+                    =======================*/
+                    residual : item.residual_currency,
+                    amortized: item.amount_total_currency - item.residual_currency,
+                    amount : item.amount_total_currency,
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                    /*==============================
+                        DATA
+                    ==============================*/
+                    info : info,
+                    payments : payments,
+                });
+            });
+
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return -1;
+                }
+                if (a.date < b.date) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.BuildChartByPeriod();
+        },
+
+        /*====================================================================
+            BUILD CHART BY PERIOD
+        ====================================================================*/
+        BuildChartByPeriod: function(){
+            var self = this;
+            var data = [];
+            var label = [];
+            var body = [];
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var AccountPeriod = self.AccountPeriod;
+            var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL PERIODO
+            =============================================================================
+            */
+            if(period != 9999999){
+                var range = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                var date = range[0].date_start;
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > range[0].date_stop){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL RANGO DE FECHAS
+            =============================================================================
+            */
+            if(date == 'range'){
+
+                // DESDE
+                var desde = self.$el.find('#from').val();
+                desde = desde.split('/');
+                desde = (desde[2] + "-" + desde[1] + "-" + desde[0]);
+
+                // HASTA
+                var hasta = self.$el.find('#to').val();
+                if(hasta){
+                    hasta = hasta.split('/');
+                    hasta = (hasta[2] + "-" + hasta[1] + "-" + hasta[0]);
+                }else{
+                    hasta = moment().format('YYYY-MM-DD');
+                }
+                // DETERMINAR RANGO DE FECHAS
+                const diff = moment(hasta).diff(moment(desde),'days');
+
+                if(diff > 0 & diff < 32){
+                    self.$el.find('.chart-container').css('display','block');
+                    var date = desde;
+                    for (var i = 0; i < 32; i++) {
+                        if(i > 0){
+                            date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                        }
+                        if(date > hasta){
+                            break;
+                        }
+                        var data = self.getContentByDay(date);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(moment(date).format('DD/MM/YYYY'));
+                            body.push(total);
+                        }
+                    }
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff > 31){
+                    self.$el.find('.chart-container').css('display','block');
+                    _.each(AccountPeriod, function(item){
+                        var data = self.getContent(item.date_start);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(item.name);
+                            body.push(total);
+                        }
+                    });
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff == 0){
+                    self.$el.find('.chart-container').css('display','none');
+                }
+            }
+            /*
+            =============================================================================
+                OCULTAR GRAFICO EN EL CASO DE QUE EL FILTRO SEA AYER U HOY
+            =============================================================================
+            */
+            if(date == 'today' || date == 'yesterday'){
+                self.$el.find('.chart-container').css('display','none');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES ACTUAL
+            =============================================================================
+            */
+            if(date == 'currentMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES PASADO
+            =============================================================================
+            */
+            if(date == 'lastMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().add(-1,'month').startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().add(-1,'month').endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR SIN FILTRO
+            =============================================================================
+            */
+            if(date == 9999999 & period == 9999999){
+                _.each(AccountPeriod, function(item){
+                    var data = self.getContent(item.date_start);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(item.name);
+                        body.push(total);
+                    }
+                });
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            var chart = new reporting.ReportChartWidget(self);
+            chart.BuildLineChart(label,body,CurrencyBase);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var total = totalFormatter(row);
+            var amortized = totalAmortizedFormatter(row);
+            var residual = totalResidualFormatter(row);
+
+            row.push({
+                number : 'Totales',
+                amount_total : total,
+                amortized_total : amortized,
+                residual_total : residual,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Compras a Pagar.';
+                // var pdf_title = 'Cuentas a Pagar.';
+                var pdf_type = '';
+                var pdf_name = 'compras_a_pagar_';
+                var pdf_columnStyles = {
+                    number :{columnWidth: 28, halign:'center'},
+                    date_invoice :{columnWidth: 18, halign:'center'},
+                    user_id :{columnWidth: 23, halign:'left'},
+                    partner_id : {halign:'left'},
+                    amount_total : {columnWidth: 25, halign:'right'},
+                    amortized_total : {columnWidth: 25, halign:'right'},
+                    residual_total : {columnWidth: 25, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter =self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var period = self.$el.find('#current-period').val();
+          var journal = self.$el.find('#current-journal').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+          }
+
+          if(period && period != 9999999){
+
+            var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+                return item.id == period;
+            });
+            filter.push({
+                 title: 'Periodo',
+                 value:  AccountPeriod[0].name,
+               });
+          }
+
+          if(journal && journal != 9999999){
+            var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                return item.id == journal;
+            });
+            filter.push({
+                 title: 'Factura',
+                 value: AccountJournal[0].name,
+               });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        },
+    });
+}

+ 1038 - 0
static/src/js/reports/report_account_payable_expenses.js

@@ -0,0 +1,1038 @@
+function report_account_payable_expenses(reporting){
+  "use strict";
+  var model = openerp;
+
+  reporting.ReportAccountPayableExpensesWidget = reporting.Base.extend({
+    template: 'ReportAccountPayableExpenses',
+    rowsData :[],
+    content :[],
+
+    events:{
+      'click #toolbar > button' : 'clickOnAction',
+      'click #generate' : 'fetchGenerate',
+      'click-row.bs.table #table' : 'clickAnalysisDetail',
+      'change #current-company' : 'updateSelections',
+      'change #current-store' : 'updateJournalSelections',
+      'change #current-period' : 'updatePeriodSelections',
+      'change #current-date' : 'ShowDateRange',
+    },
+
+    init : function(parent){
+      this._super(parent);
+    },
+
+    start: function () {
+      var table = this.$el.find('#table');
+      table.bootstrapTable({data : self.rowsData});
+      var date = new reporting.ReportDatePickerWidget(self);
+      date.fecthFecha();
+      this.fetchInitial();
+    },
+
+    valorNull:function(dato){
+      var valor = "";
+      if (dato){
+        valor = dato;
+      }
+      return valor;
+    },
+
+    ShowDateRange : function(){
+      var self = this;
+      var date = self.$el.find('#current-date').val();
+      if(date == 'range'){
+        self.$el.find('.datepicker').css('display','block');
+      }
+      if(date != 'range'){
+        self.$el.find('.datepicker').css('display','none');
+      }
+    },
+
+    clickAnalysisDetail : function(e, row, $element, field){
+        if(field == 'number'){
+            this.do_action({
+                name : 'Factura',
+                type : 'ir.actions.act_window',
+                res_model : 'account.invoice',
+                views : [[false,'form']],
+                target  : 'new',
+                domain : [['id','=',row.id]],
+                context : {},
+                flags : {'form' : {'action_buttons' : false, 'options' : {'mode' : 'view'}}},
+                res_id : row.id,
+            });
+        }
+        e.stopImmediatePropagation();
+    },
+
+    fetchInitial: function () {
+      var self = this;
+      self.fecthIrModuleModule().then(function (IrModuleModule) {
+        return IrModuleModule;
+      }).then(function(IrModuleModule) {
+        self.IrModuleModule = IrModuleModule;
+        return self.fetchResUser;
+      }).then(function (ResUser) {
+        self.ResUser = ResUser;
+        return self.fetchResCompany();
+      }).then(function(ResCompany){
+        self.ResCompany = ResCompany;
+        if(ResCompany.length > 1){
+          self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+          _.each(ResCompany,function(item){
+            self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+        }else{
+          self.$el.find('.company').css('display','none');
+        }
+        return self.fetchResStore();
+      }).then(function(ResStore){
+        self.ResStore = ResStore;
+        if(ResStore.length > 1){
+          self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+          _.each(ResStore,function(item){
+            self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+        }else{
+          self.$el.find('.store').css('display','none');
+        }
+        return self.fetchAccountJournal();
+      }).then(function(AccountJournal){
+        self.AccountJournal = AccountJournal;
+        if(AccountJournal.length > 1){
+          self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+          _.each(AccountJournal,function(item){
+            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+        }else{
+          self.$el.find('.journal').css('display','none');
+        }
+        return self.fetchAccountPeriod();
+      }).then(function(AccountPeriod){
+        self.AccountPeriod = AccountPeriod;
+        self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+        _.each(AccountPeriod,function(item){
+          self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+        });
+        return self.fetchResCurrency();
+      }).then(function(ResCurrency){
+        self.ResCurrency = ResCurrency;
+      });
+        self.$el.find('#generate').css('display','inline');
+        return;
+      },
+
+      fetchGenerate: function () {
+        var self = this;
+        self.$el.find('.search-form').block({
+          message: null,
+          overlayCSS: {
+            backgroundColor: '#FAFAFA'
+          }
+        });
+        self.$el.find('.report-form').block({
+          message: null,
+          overlayCSS: {
+            backgroundColor: '#FAFAFA'
+          }
+        });
+        this.fetchAccountInvoice().then(function(AccountInvoice) {
+          return AccountInvoice;
+        }).then(function (AccountInvoice) {
+          self.AccountInvoice = AccountInvoice;
+          return self.fetchAccountMoveLine();
+        }).then(function (AccountMoveLine){
+          self.AccountMoveLine = AccountMoveLine;
+          return self.fetchAccountVoucher();
+        }).then(function (AccountVoucher){
+          self.AccountVoucher = AccountVoucher;
+          return self.BuildTable();
+        });
+      },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+      fecthIrModuleModule: function(){
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['name','id'];
+        var domain=[['state','=','installed']];
+        var IrModuleModule = new model.web.Model('ir.module.module');
+        IrModuleModule.query(fields).filter(domain).all().then(function(results){
+          defer.resolve(results);
+        })
+        return defer;
+      },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','purchase']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open']],
+                ['type', '=', 'in_invoice'],
+                ['journal_id','in',journal_ids],
+                ['origin', '=', false]
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================*/
+        fetchAccountMoveLine: function (){
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['move_id','in',invoice_numbers],
+                ['credit','>',0],
+            ];
+
+            var AccountMoveLine = new model.web.Model('account.move.line');
+            return AccountMoveLine.call('getAccountMoveLine',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*=====================================================================
+            ACCOUNT VOUCHER
+        =====================================================================*/
+        fetchAccountVoucher: function () {
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['state','=','posted'],
+                ['reference','in',invoice_numbers]
+            ];
+
+            var AccountVoucher = new model.web.Model('account.voucher');
+            return AccountVoucher.call('getAccountVoucher',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT MOVE LINE
+        ====================================================================*/
+        getAccountMoveLine: function (number) {
+            var self = this;
+            return _.filter(self.AccountMoveLine,function (item) {
+                return item.move_id[1] == number;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT VOUCHER
+        ====================================================================*/
+        getAccountVoucher: function (number) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.reference == number;
+            })
+        },
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*============================
+            ACCOUNT DATA BY DAY
+        ============================*/
+        getContentByDay:function(date) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM-DD') === date;
+            }));
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var info = [];
+            var payments = [];
+            var type = $('#current-type').val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var AccountInvoice = self.AccountInvoice;
+            _.each(AccountInvoice, function(item){
+                info = [];
+                payments = [];
+                var AccountMoveLine = self.getAccountMoveLine(item.number);
+                var AccountVoucher = self.getAccountVoucher(item.number);
+                var Currency = self.getResCurrency(item.invoice_currency[0]).shift();
+                var i = AccountMoveLine.length;
+                var x = AccountMoveLine.length;
+                _.each(AccountMoveLine, function(index){
+                    var amount = 0;
+                    var date;
+                    if(Currency.id != CurrencyBase.id){
+                        amount = accounting.formatMoney(index.debit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.price_subtotal, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) +')';
+                    }else{
+                        amount = accounting.formatMoney(index.debit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                    };
+                    var state = 'No Pagado';
+                    if(index.reconcile_ref){
+                        if(index.amount_residual == 0){
+                            state = 'Pagado'
+                        };
+                        if(index.amount_residual > 0){
+                            var value = accounting.formatMoney(index.debit - index.amount_residual, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                            state = 'Amortizado ' + ' ( ' + value + ' )';
+                        };
+                    };
+                    date = moment(index.date_maturity).format('DD/MM/YYYY');
+                    if(state != 'Pagado'){
+                        if(index.date_maturity < moment().format('YYYY-MM-DD')){
+                            date = moment(index.date_maturity).format('DD/MM/YYYY') + ' (vencido) ';
+                        };
+                    };
+                    info.push({
+                        date : date,
+                        name : 'Cuota ' + i +' / ' + x,
+                        state : state,
+                        amount: amount,
+                    });
+                    i--;
+                });
+                if(AccountVoucher.length > 0){
+                    _.each(AccountVoucher, function(index){
+                        var CurrencyVoucher = self.getResCurrency(index.currency_id[0]).shift();
+                        var amount = 0;
+                        if(CurrencyVoucher.id != CurrencyBase.id){
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.amount, '', CurrencyVoucher.decimal_places, CurrencyVoucher.thousands_separator, CurrencyVoucher.decimal_separator) +')';
+                        }else{
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        }
+                        payments.push({
+                            date : moment(index.date).format('DD/MM/YYYY'),
+                            user : index.create_uid,
+                            journal_name : index.journal_id[1],
+                            amount : amount,
+                        });
+                    });
+                }
+
+                var residual_total = 0;
+                var amount_untaxed_total = 0;
+                var amount_tax_total = 0;
+                var amount_total = 0;
+
+                if(Currency.id != CurrencyBase.id){
+                    residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.residual, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                    amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.amount_total, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                }else{
+                    residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                    amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                }
+
+                data.push({
+                    /*=======================
+                        IDS
+                    =======================*/
+                    id : item.id,
+                    /*=======================
+                        INFO
+                    =======================*/
+                    number : item.number,
+                    date_invoice : moment(item.date_invoice).format('DD/MM/YYYY'),
+                    date : moment(item.date_invoice).format('YYYY-MM-DD'),
+                    user_id : item.user_id[1],
+                    partner_id : self.valorNull(item.partner_id[1]),
+                    residual_total : residual_total,
+                    amortized_total: accounting.formatMoney(item.amount_total_currency - item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    amount_total : amount_total,
+                    /*=======================
+                        VALORES SIN FORMATEAR
+                    =======================*/
+                    residual : item.residual_currency,
+                    amortized: item.amount_total_currency - item.residual_currency,
+                    amount : item.amount_total_currency,
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                    /*==============================
+                        DATA
+                    ==============================*/
+                    info : info,
+                    payments : payments,
+                });
+            });
+
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return -1;
+                }
+                if (a.date < b.date) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.BuildChartByPeriod();
+        },
+
+        /*====================================================================
+            BUILD CHART BY PERIOD
+        ====================================================================*/
+        BuildChartByPeriod: function(){
+            var self = this;
+            var data = [];
+            var label = [];
+            var body = [];
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var AccountPeriod = self.AccountPeriod;
+            var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL PERIODO
+            =============================================================================
+            */
+            if(period != 9999999){
+                var range = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                var date = range[0].date_start;
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > range[0].date_stop){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL RANGO DE FECHAS
+            =============================================================================
+            */
+            if(date == 'range'){
+
+                // DESDE
+                var desde = self.$el.find('#from').val();
+                desde = desde.split('/');
+                desde = (desde[2] + "-" + desde[1] + "-" + desde[0]);
+
+                // HASTA
+                var hasta = self.$el.find('#to').val();
+                if(hasta){
+                    hasta = hasta.split('/');
+                    hasta = (hasta[2] + "-" + hasta[1] + "-" + hasta[0]);
+                }else{
+                    hasta = moment().format('YYYY-MM-DD');
+                }
+                // DETERMINAR RANGO DE FECHAS
+                const diff = moment(hasta).diff(moment(desde),'days');
+
+                if(diff > 0 & diff < 32){
+                    self.$el.find('.chart-container').css('display','block');
+                    var date = desde;
+                    for (var i = 0; i < 32; i++) {
+                        if(i > 0){
+                            date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                        }
+                        if(date > hasta){
+                            break;
+                        }
+                        var data = self.getContentByDay(date);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(moment(date).format('DD/MM/YYYY'));
+                            body.push(total);
+                        }
+                    }
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff > 31){
+                    self.$el.find('.chart-container').css('display','block');
+                    _.each(AccountPeriod, function(item){
+                        var data = self.getContent(item.date_start);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(item.name);
+                            body.push(total);
+                        }
+                    });
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff == 0){
+                    self.$el.find('.chart-container').css('display','none');
+                }
+            }
+            /*
+            =============================================================================
+                OCULTAR GRAFICO EN EL CASO DE QUE EL FILTRO SEA AYER U HOY
+            =============================================================================
+            */
+            if(date == 'today' || date == 'yesterday'){
+                self.$el.find('.chart-container').css('display','none');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES ACTUAL
+            =============================================================================
+            */
+            if(date == 'currentMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES PASADO
+            =============================================================================
+            */
+            if(date == 'lastMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().add(-1,'month').startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().add(-1,'month').endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR SIN FILTRO
+            =============================================================================
+            */
+            if(date == 9999999 & period == 9999999){
+                _.each(AccountPeriod, function(item){
+                    var data = self.getContent(item.date_start);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(item.name);
+                        body.push(total);
+                    }
+                });
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            var chart = new reporting.ReportChartWidget(self);
+            chart.BuildLineChart(label,body,CurrencyBase);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var total = totalFormatter(row);
+            var amortized = totalAmortizedFormatter(row);
+            var residual = totalResidualFormatter(row);
+
+            row.push({
+                number : 'Totales',
+                amount_total : total,
+                amortized_total : amortized,
+                residual_total : residual,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Gastos a Pagar.';
+                // var pdf_title = 'Cuentas a Pagar.';
+                var pdf_type = '';
+                var pdf_name = 'gastos_a_pagar_';
+                var pdf_columnStyles = {
+                    number :{columnWidth: 28, halign:'center'},
+                    date_invoice :{columnWidth: 18, halign:'center'},
+                    user_id :{columnWidth: 23, halign:'left'},
+                    partner_id : {halign:'left'},
+                    amount_total : {columnWidth: 25, halign:'right'},
+                    amortized_total : {columnWidth: 25, halign:'right'},
+                    residual_total : {columnWidth: 25, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter =self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var period = self.$el.find('#current-period').val();
+          var journal = self.$el.find('#current-journal').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+          }
+
+          if(period && period != 9999999){
+
+            var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+                return item.id == period;
+            });
+            filter.push({
+                 title: 'Periodo',
+                 value:  AccountPeriod[0].name,
+               });
+          }
+
+          if(journal && journal != 9999999){
+            var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                return item.id == journal;
+            });
+            filter.push({
+                 title: 'Factura',
+                 value: AccountJournal[0].name,
+               });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        },
+    });
+}

+ 1029 - 0
static/src/js/reports/report_account_receivable.js

@@ -0,0 +1,1029 @@
+function report_account_receivable(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportAccountReceivableWidget = reporting.Base.extend({
+        template: 'ReportAccountReceivable',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                // self.fecthCheckType();
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.fetchAccountMoveLine();
+            }).then(function (AccountMoveLine){
+                self.AccountMoveLine = AccountMoveLine;
+                return self.fetchAccountVoucher();
+            }).then(function (AccountVoucher){
+                self.AccountVoucher = AccountVoucher;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','sale']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open']],
+                ['type', '=', 'out_invoice'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================*/
+        fetchAccountMoveLine: function (){
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['move_id','in',invoice_numbers],
+                ['debit','>',0],
+            ];
+            var AccountMoveLine = new model.web.Model('account.move.line');
+            return AccountMoveLine.call('getAccountMoveLine',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*=====================================================================
+            ACCOUNT VOUCHER
+        =====================================================================*/
+        fetchAccountVoucher: function () {
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['state','=','posted'],
+                ['reference','in',invoice_numbers]
+            ];
+            var AccountVoucher = new model.web.Model('account.voucher');
+            return AccountVoucher.call('getAccountVoucher',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT MOVE LINE
+        ====================================================================*/
+        getAccountMoveLine: function (number) {
+            var self = this;
+            return _.filter(self.AccountMoveLine,function (item) {
+                return item.move_id[1] == number;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT VOUCHER
+        ====================================================================*/
+        getAccountVoucher: function (number) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.reference == number;
+            })
+        },
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*============================
+            ACCOUNT DATA BY DAY
+        ============================*/
+        getContentByDay:function(date) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM-DD') === date;
+            }));
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var info = [];
+            var payments = [];
+            var type = $('#current-type').val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            /*
+            ==========================================
+                ACCOUNT INVOICE
+            ==========================================
+            */
+
+            var AccountInvoice = self.AccountInvoice;
+            _.each(AccountInvoice, function(item){
+                info = [];
+                payments = [];
+                var AccountMoveLine = self.getAccountMoveLine(item.number);
+                var AccountVoucher = self.getAccountVoucher(item.number);
+                var Currency = self.getResCurrency(item.invoice_currency[0]).shift();
+                var i = AccountMoveLine.length;
+                var x = AccountMoveLine.length;
+                _.each(AccountMoveLine, function(index){
+                    var amount = 0;
+                    var date;
+                    if(Currency.id != CurrencyBase.id){
+                        amount = accounting.formatMoney(index.credit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.price_subtotal, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) +')';
+                    }else{
+                        amount = accounting.formatMoney(index.credit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                    };
+                    var state = 'No Pagado';
+                    if(index.reconcile_ref){
+                        if(index.amount_residual == 0){
+                            state = 'Pagado'
+                        };
+                        if(index.amount_residual > 0){
+                            var value = accounting.formatMoney(index.credit - index.amount_residual, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                            state = 'Amortizado ' + ' ( ' + value + ' )';
+                        };
+                    };
+                    date = moment(index.date_maturity).format('DD/MM/YYYY');
+                    if(state != 'Pagado'){
+                        if(index.date_maturity < moment().format('YYYY-MM-DD')){
+                            date = moment(index.date_maturity).format('DD/MM/YYYY') + ' (vencido) ';
+                        };
+                    };
+                    info.push({
+                        date : date,
+                        name : 'Cuota ' + i +' / ' + x,
+                        state : state,
+                        amount: amount,
+                    });
+                    i--;
+                });
+                if(AccountVoucher.length > 0){
+                    _.each(AccountVoucher, function(index){
+                        var CurrencyVoucher = self.getResCurrency(index.currency_id[0]).shift();
+                        var amount = 0;
+                        if(CurrencyVoucher.id != CurrencyBase.id){
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.amount, '', CurrencyVoucher.decimal_places, CurrencyVoucher.thousands_separator, CurrencyVoucher.decimal_separator) +')';
+                        }else{
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        }
+                        payments.push({
+                            date : moment(index.date).format('DD/MM/YYYY'),
+                            user : index.create_uid,
+                            journal_name : index.journal_id[1],
+                            amount : amount,
+                        });
+                    });
+                }
+
+                var residual_total = 0;
+                var amount_untaxed_total = 0;
+                var amount_tax_total = 0;
+                var amount_total = 0;
+
+                if(Currency.id != CurrencyBase.id){
+                    residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.residual, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                    amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.amount_total, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                }else{
+                    residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                    amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                }
+
+                data.push({
+                    /*=======================
+                        IDS
+                    =======================*/
+                    id : item.id,
+                    /*=======================
+                        INFO
+                    =======================*/
+                    number : item.number,
+                    supplier_invoice_number: self.valorNull(item.supplier_invoice_number),
+                    date_invoice : moment(item.date_invoice).format('DD/MM/YYYY'),
+                    date : moment(item.date_invoice).format('YYYY-MM-DD'),
+                    user_id : item.user_id[1],
+                    partner_id : self.valorNull(item.partner_id[1]),
+                    residual_total : residual_total,
+                    amortized_total: accounting.formatMoney(item.amount_total_currency - item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    amount_total : amount_total,
+                    /*=======================
+                        VALORES SIN FORMATEAR
+                    =======================*/
+                    residual : item.residual_currency,
+                    amortized: item.amount_total_currency - item.residual_currency,
+                    amount : item.amount_total_currency,
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                    /*==============================
+                        DATA
+                    ==============================*/
+                    info : info,
+                    payments : payments,
+                });
+            });
+
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return -1;
+                }
+                if (a.date < b.date) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.BuildChartByPeriod();
+        },
+
+        /*====================================================================
+            BUILD CHART BY PERIOD
+        ====================================================================*/
+        BuildChartByPeriod: function(){
+            var self = this;
+            var data = [];
+            var label = [];
+            var body = [];
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var AccountPeriod = self.AccountPeriod;
+            var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL PERIODO
+            =============================================================================
+            */
+            if(period != 9999999){
+                var range = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                var date = range[0].date_start;
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > range[0].date_stop){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL RANGO DE FECHAS
+            =============================================================================
+            */
+            if(date == 'range'){
+
+                // DESDE
+                var desde = self.$el.find('#from').val();
+                desde = desde.split('/');
+                desde = (desde[2] + "-" + desde[1] + "-" + desde[0]);
+
+                // HASTA
+                var hasta = self.$el.find('#to').val();
+                if(hasta){
+                    hasta = hasta.split('/');
+                    hasta = (hasta[2] + "-" + hasta[1] + "-" + hasta[0]);
+                }else{
+                    hasta = moment().format('YYYY-MM-DD');
+                }
+                // DETERMINAR RANGO DE FECHAS
+                const diff = moment(hasta).diff(moment(desde),'days');
+
+                if(diff > 0 & diff < 32){
+                    self.$el.find('.chart-container').css('display','block');
+                    var date = desde;
+                    for (var i = 0; i < 32; i++) {
+                        if(i > 0){
+                            date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                        }
+                        if(date > hasta){
+                            break;
+                        }
+                        var data = self.getContentByDay(date);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(moment(date).format('DD/MM/YYYY'));
+                            body.push(total);
+                        }
+                    }
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff > 31){
+                    self.$el.find('.chart-container').css('display','block');
+                    _.each(AccountPeriod, function(item){
+                        var data = self.getContent(item.date_start);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(item.name);
+                            body.push(total);
+                        }
+                    });
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff == 0){
+                    self.$el.find('.chart-container').css('display','none');
+                }
+            }
+            /*
+            =============================================================================
+                OCULTAR GRAFICO EN EL CASO DE QUE EL FILTRO SEA AYER U HOY
+            =============================================================================
+            */
+            if(date == 'today' || date == 'yesterday'){
+                self.$el.find('.chart-container').css('display','none');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES ACTUAL
+            =============================================================================
+            */
+            if(date == 'currentMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES PASADO
+            =============================================================================
+            */
+            if(date == 'lastMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().add(-1,'month').startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().add(-1,'month').endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR SIN FILTRO
+            =============================================================================
+            */
+            if(date == 9999999 & period == 9999999){
+                _.each(AccountPeriod, function(item){
+                    var data = self.getContent(item.date_start);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(item.name);
+                        body.push(total);
+                    }
+                });
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            var chart = new reporting.ReportChartWidget(self);
+            chart.BuildLineChart(label,body,CurrencyBase);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var total = totalFormatter(row);
+            var amortized = totalAmortizedFormatter(row);
+            var residual = totalResidualFormatter(row);
+
+            row.push({
+                number : 'Totales',
+                amount_total : total,
+                amortized_total : amortized,
+                residual_total : residual,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Cuentas a Cobrar.';
+                var pdf_type = '';
+                var pdf_name = 'cuentas_a_cobrar_';
+                var pdf_columnStyles = {
+                    number :{columnWidth: 25, halign:'center'},
+                    date_invoice :{columnWidth: 18, halign:'center'},
+                    user_id :{columnWidth: 23, halign:'left'},
+                    partner_id : {halign:'left'},
+                    amount_total : {columnWidth: 23, halign:'right'},
+                    amortized_total : {columnWidth: 23, halign:'right'},
+                    residual_total : {columnWidth: 23, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var period = self.$el.find('#current-period').val();
+          var journal = self.$el.find('#current-journal').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                 title: 'Sucursal',
+                 value:  ResStore[0].name,
+               });
+
+          }
+
+          if(period && period != 9999999){
+
+            var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+                return item.id == period;
+            });
+            filter.push({
+                 title: 'Periodo',
+                 value:  AccountPeriod[0].name,
+               });
+          }
+
+          if(journal && journal != 9999999){
+            var AccountJournal = _.filter(self.AccountJournal, function(item){
+              return item.id == journal;
+            })
+            filter.push({
+              title:'Factura',
+              value: AccountJournal[0].name,
+            })
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+
+          return filter;
+        }
+    });
+}

+ 362 - 0
static/src/js/reports/report_customer.js

@@ -0,0 +1,362 @@
+function report_customer(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportCustomerWidget = reporting.Base.extend({
+        template: 'ReportCustomer',
+        rowsData :[],
+        content :[],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        clickAnalysisDetail: function(e, row, $element,field){
+            if (field == 'name'){
+                this.do_action({
+                    name:"Cliente",
+                    type: 'ir.actions.act_window',
+                    res_model: "res.partner",
+                    views: [[false,'form']],
+                    target: 'new',
+                    domain: [['id','=', row.id]],
+                    context: {},
+                    flags: {'form': {'action_buttons': false, 'options': {'mode': 'view'}}},
+                    res_id: row.id,
+                });
+            }
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            this.fetchResUser().then(function(ResUser) {
+                return ResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchResPartner().then(function(ResPartner) {
+                return ResPartner;
+            }).then(function (ResPartner) {
+                self.ResPartner = ResPartner;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES PARTNER
+        ====================================================================*/
+        fetchResPartner: function() {
+            var self = this;
+        //    var state = self.$el.find('#current-state').val();
+            var company = self.$el.find('#current-company').val();
+            var type = self.$el.find('#current-type').val();
+            var domain = [
+                ['active', '=', true],
+                ['customer', '=', true],
+            ];
+            // if(state == 'with'){
+            //     domain.push(['credit','>',0]);
+            // }
+            // if(state == 'without'){
+            //     domain.push(['credit','=',0]);
+            // }
+
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseInt(company)]);
+            }
+            if(type == 'company'){
+                domain.push(['is_company','=',true]);
+            }
+            if(type == 'people'){
+                domain.push(['is_company','!=',true]);
+            }
+            var ResPartner = new model.web.Model('res.partner');
+            return ResPartner.call('getResPartner',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var ResPartner = self.ResPartner;
+            _.each(ResPartner, function(item){
+                data.push({
+                    id : item.id,
+                    ruc : self.valorNull(item.ruc),
+                    name : item.name,
+                    street : self.valorNull(item.street),
+                    city : self.valorNull(item.city),
+                    phone : self.valorNull(item.phone),
+                    mobile : self.valorNull(item.mobile),
+                    email : self.valorNull(item.email),
+                    property_product_pricelist : self.valorNull(item.property_product_pricelist),
+                    credit : accounting.formatMoney(item.credit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    amount : item.credit,
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                });
+            });
+
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            // var prueba = table.bootstrapTable();
+
+            var amount = totalFormatter(row);
+
+            row.push({
+                ruc: 'Total',
+                credit: amount,
+            })
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Clientes.';
+                var pdf_type = 'l';
+                var pdf_name = 'clientes_';
+                var pdf_columnStyles = {
+                    ruc :{columnWidth: 20, halign:'left'},
+                    name :{halign:'left'},
+                    street :{halign:'left'},
+                    city:{halign:'left'},
+                    phone : {columnWidth: 30, halign:'left'},
+                    mobile :{columnWidth: 30, halign:'left'},
+                    email:{columnWidth: 30, halign:'left'},
+                    property_product_pricelist:{columnWidth: 30, halign:'center'},
+                    credit:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+      //    var state = self.$el.find('#current-state').val();
+          var type = self.$el.find('#current-type').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          // if(state && state != 9999999){
+          //   filter.push({
+          //     title: 'Estado',
+          //     value: $("#current-state option:selected").text(),
+          //   })
+          // }
+
+          if(type && type != 9999999){
+            filter.push({
+              title: 'Tipo de Cliente',
+              value: $('#current-type option:selected').text(),
+            })
+          }
+          return filter;
+        },
+    });
+}

+ 698 - 0
static/src/js/reports/report_customer_payment.js

@@ -0,0 +1,698 @@
+function report_customer_payment(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportCustomerPaymentWidget = reporting.Base.extend({
+        template: 'ReportCustomerPayment',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-date' : 'ShowDateRange',
+            'click .print-report':'clickOnAction',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                var journal = _.flatten(_.filter(self.AccountJournal,function (item) {
+                    return item.type == 'cash' || item.type == 'bank';
+                }));
+                if(journal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todos los métodos de pago</option>');
+                    _.each(journal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fethIrModuleModule();
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fethCheckType();
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountVoucher = DataSQL.vouchers;
+                self.AccountBankStatementLine = DataSQL.statement_lines;
+                self.AccountMoveLine = DataSQL.move_lines;
+                self.AccountInvoice = DataSQL.invoices;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-account-voucher-customer-payment');
+            return data;
+        },
+
+        fethIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fethCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('point_of_sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var journal;
+            var AccountJournal = _.flatten(_.filter(self.AccountJournal,function (item) {
+                return item.type == 'cash' || item.type == 'bank';
+            }));
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todos los métodos de pago</option>');
+                _.each(AccountJournal,function(item){
+                    if(item.store_id == store){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todos los métodos de pago</option>');
+                _.each(AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getAccountBankStatementLine:function() {
+            var self = this;
+            var content = self.AccountBankStatementLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var journal = self.$el.find('#current-journal').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getAccountVoucher:function(number) {
+            var self = this;
+            var content = self.AccountVoucher;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var journal = self.$el.find('#current-journal').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            content = _.filter(content,function (item) {
+                return item.reference == number;
+            })
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getQuota:function(reference, reconcile_ref) {
+
+            var self = this;
+            var content = [];
+            var AccountMoveLine = self.AccountMoveLine;
+
+            content = _.flatten(_.filter(AccountMoveLine,function (item) {
+                return item.name == reference && item.type == 'receivable';
+            }));
+            var c = 1;
+            var x = content.length;
+            _.each(content, function(item){
+                item.quota = 'Cuota ' + c + ' / ' + x;
+                c++;
+            });
+            content = _.flatten(_.filter(content,function (item) {
+                return item.reconcile_ref == reconcile_ref;
+            }));
+
+
+          if (content.length > 0){
+            if(content[0].reconcile_partial_id != null){
+                AccountMoveLine = _.flatten(_.filter(AccountMoveLine,function (item) {
+                    return item.reconcile_partial_id == content[0].reconcile_partial_id && item.credit > 0;
+                }));
+                var total =  _.reduce(_.map(AccountMoveLine,function(item){
+                    return item.credit;
+                }), function(memo, num){
+                    return memo + num;
+                },0);
+                content[0].residual = content[0].debit - total;
+
+            }
+          }
+
+            return content;
+        },
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var residual = 0;
+            var monto = 0;
+            var CurrencyBase = self.ResCompany[0].currency_id;
+
+            var AccountInvoice = self.AccountInvoice;
+            _.each(AccountInvoice, function(each){
+              var AccountVoucher = self.getAccountVoucher(each.number);
+              _.each(AccountVoucher, function(item){
+                var quota = self.getQuota(self.valorNull(item.reference), item.reconcile_ref);
+
+                data.push({
+                    id:item.id,
+                    number:item.number,
+                    name: self.valorNull(item.name),
+                    partner_name:item.partner_name,
+                    invoice_number: self.valorNull(item.invoice_number),
+                    origin: self.valorNull(each.origin),
+                    user_name: self.valorNull(each.user_name),
+                    description: quota.length > 0 ? quota[0].quota : 'Cuota 1 / 1',
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    date_maturity:moment(item.date_maturity).format('DD/MM/YYYY'),
+                    journal_name:item.journal_name,
+                    amount_original:accounting.formatMoney(item.amount_original,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    residual:accounting.formatMoney(item.residual,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+
+                    /*
+                    =======================
+                        NO FORMAT
+                    =======================
+                    */
+                    amount_original_no_format: item.amount_original,
+                    total_no_format:item.amount,
+                    residual_no_format:item.residual,
+                    /*
+                    =======================
+                        FOOTER
+                    =======================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+              })
+            });
+            /*
+            ==========================================
+                ACCOUNT BANK STATEMENT LINE
+            ==========================================
+            */
+            var AccountBankStatementLine = self.getAccountBankStatementLine();
+            _.each(AccountBankStatementLine, function(item){
+                var amount = item.amount_currency;
+                if(item.currency_id != null){
+                    amount = amount + '('  + item.amount + ')';
+                }
+                data.push({
+                    id:item.id,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    invoice_number:item.origin,
+                    number:item.number,
+                    name:item.name,
+                    partner_name:self.valorNull(item.partner_name),
+                    journal_name:item.journal_name,
+                    reference:item.name,
+                    description: 'Cuota 1 / 1',
+                    residual: accounting.formatMoney(0,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    amount_original:accounting.formatMoney(amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    /*
+                    =======================
+                        NO FORMAT
+                    =======================
+                    */
+                    date_no_format: moment(item.date).format('YYYY-MM-DD'),
+                    amount_original_no_format: item.amount_currency,
+                    total_no_format:item.amount_currency,
+                    /*
+                    =======================
+                        FOOTER
+                    =======================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.ResCompany,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = CompanyLogo[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var amount_original = amountOriginalFormatter(row);
+            var total = totalFormatter(row);
+            row.push({
+                number:'Totales',
+                amount_original: amount_original,
+                total:total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Pagos de clientes.';
+                var pdf_type = '';
+                var pdf_name = 'pagos_de_clientes';
+                var pdf_columnStyles = {
+                    number:{columnWidth: 25, halign:'left'},
+                    partner_name:{columnWidth: 'auto', halign:'left'},
+                    invoice_number:{columnWidth: 25, halign:'left'},
+                    origin:{columnWidth: 18, halign:'left'},
+                    name:{columnWidth: 17, halign:'left'},
+                    description:{columnWidth: 18, halign:'left'},
+                    date:{columnWidth: 17,  halign:'center'},
+                    date_maturity:{columnWidth: 18,  halign:'center'},
+                    journal_name:{columnWidth: 18, halign:'left'},
+                    user_name:{columnWidth: 18, halign:'left'},
+                    amount_original:{columnWidth: 20, halign:'right'},
+                    total:{columnWidth: 20, halign:'right'},
+
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var journal = self.$el.find('#current-journal').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                        return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(journal && journal != 9999999){
+                var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                    return item.id == journal;
+                });
+                filter.push({
+                   title: 'Método de pago',
+                   value: AccountJournal[0].name,
+                });
+            }
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 710 - 0
static/src/js/reports/report_customer_paymentespecial.js

@@ -0,0 +1,710 @@
+function report_customer_paymentespecial(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportCustomerPaymentEspecialWidget = reporting.Base.extend({
+        template: 'ReportCustomerPaymentEspecial',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-date' : 'ShowDateRange',
+            'click .print-report':'clickOnAction',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                var journal = _.flatten(_.filter(self.AccountJournal,function (item) {
+                    return item.type == 'cash' || item.type == 'bank';
+                }));
+                if(journal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todos los métodos de pago</option>');
+                    _.each(journal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fethIrModuleModule();
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fethCheckType();
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountVoucher = DataSQL.vouchers;
+                self.AccountBankStatementLine = DataSQL.statement_lines;
+                self.AccountMoveLine = DataSQL.move_lines;
+                self.AccountInvoice = DataSQL.invoices;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-account-voucherrefund-customer-payment');
+            return data;
+        },
+
+        fethIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fethCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('point_of_sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var journal;
+            var AccountJournal = _.flatten(_.filter(self.AccountJournal,function (item) {
+                return item.type == 'cash' || item.type == 'bank';
+            }));
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todos los métodos de pago</option>');
+                _.each(AccountJournal,function(item){
+                    if(item.store_id == store){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todos los métodos de pago</option>');
+                _.each(AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getAccountBankStatementLine:function() {
+            var self = this;
+            var content = self.AccountBankStatementLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var journal = self.$el.find('#current-journal').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getAccountVoucher:function(number) {
+            var self = this;
+            var content = self.AccountVoucher;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var journal = self.$el.find('#current-journal').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            content = _.filter(content,function (item) {
+                return item.reference == number;
+            })
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getQuota:function(reference, reconcile_ref) {
+
+            var self = this;
+            var content = [];
+            var AccountMoveLine = self.AccountMoveLine;
+            content = _.flatten(_.filter(AccountMoveLine,function (item) {
+                return item.name == reference && item.type == 'receivable';
+            }));
+            var c = 1;
+            var x = content.length;
+            _.each(content, function(item){
+                item.quota = 'Cuota ' + c + ' / ' + x;
+                c++;
+            });
+            content = _.flatten(_.filter(content,function (item) {
+                return item.reconcile_ref == reconcile_ref;
+            }));
+
+
+          if (content.length > 0){
+            if(content[0].reconcile_partial_id != null){
+                AccountMoveLine = _.flatten(_.filter(AccountMoveLine,function (item) {
+                    return item.reconcile_partial_id == content[0].reconcile_partial_id && item.credit > 0;
+                }));
+                var total =  _.reduce(_.map(AccountMoveLine,function(item){
+                    return item.credit;
+                }), function(memo, num){
+                    return memo + num;
+                },0);
+                content[0].residual = content[0].debit - total;
+
+            }
+          }
+
+            return content;
+        },
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var residual = 0;
+            var CurrencyBase = self.ResCompany[0].currency_id;
+
+            var AccountInvoice = self.AccountInvoice;
+
+            _.each(AccountInvoice, function(each){
+              var AccountVoucher = self.getAccountVoucher(each.number);
+              _.each(AccountVoucher, function(item){
+                var pagado = 0;
+                var totalpagado = 0;
+                var tresidual = 0;
+              if(each.type == 'out_refund'){
+                    pagado = -(item.amount_original);
+                    totalpagado = -(item.amount);
+                    tresidual = -(item.residual);
+                }else{
+                  pagado = (item.amount_original);
+                  totalpagado = (item.amount);
+                  tresidual = (item.residual);
+                }
+
+                var quota = self.getQuota(self.valorNull(item.reference), item.reconcile_ref);
+
+
+                data.push({
+                    id:item.id,
+                    number:item.number,
+                    partner_name:item.partner_name,
+                    invoice_number: self.valorNull(item.invoice_number),
+                    origin: self.valorNull(each.origin),
+                    user_name: self.valorNull(each.user_name),
+                    description: quota.length > 0 ? quota[0].quota : 'Cuota 1 / 1',
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    date_maturity:moment(item.date_maturity).format('DD/MM/YYYY'),
+                    journal_name:item.journal_name,
+                    user_name: self.valorNull(each.user_name),
+                    amount_original:accounting.formatMoney(pagado,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(totalpagado,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    residual:accounting.formatMoney(tresidual,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+
+                    /*
+                    =======================
+                        NO FORMAT
+                    =======================
+                    */
+                    amount_original_no_format: pagado,
+                    total_no_format:totalpagado,
+                    residual_no_format:tresidual,
+                    /*
+                    =======================
+                        FOOTER
+                    =======================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+              })
+            });
+            /*
+            ==========================================
+                ACCOUNT BANK STATEMENT LINE
+            ==========================================
+            */
+            var AccountBankStatementLine = self.getAccountBankStatementLine();
+            _.each(AccountBankStatementLine, function(item){
+                var amount = item.amount_currency;
+                if(item.currency_id != null){
+                    amount = amount + '('  + item.amount + ')';
+                }
+                data.push({
+                    id:item.id,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    invoice_number:item.origin,
+                    // name:item.name,
+                    number:item.name,
+                    partner_name:self.valorNull(item.partner_name),
+                    journal_name:item.journal_name,
+                    reference:item.name,
+                    description: 'Cuota 1 / 1',
+                    residual: accounting.formatMoney(0,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    amount_original:accounting.formatMoney(amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    /*
+                    =======================
+                        NO FORMAT
+                    =======================
+                    */
+                    date_no_format: moment(item.date).format('YYYY-MM-DD'),
+                    amount_original_no_format: item.amount_currency,
+                    total_no_format:item.amount_currency,
+                    /*
+                    =======================
+                        FOOTER
+                    =======================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.ResCompany,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = CompanyLogo[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var amount_original = amountOriginalFormatter(row);
+            var total = totalFormatter(row);
+            row.push({
+                number:'Totales',
+                amount_original: amount_original,
+                total:total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Pagos y devoluciones de clientes.';
+                var pdf_type = '';
+                var pdf_name = 'pagos_devoluciones_clientes';
+                var pdf_columnStyles = {
+                    number:{columnWidth: 25, halign:'left'},
+                    partner_name:{columnWidth: 'auto', halign:'left'},
+                    invoice_number:{columnWidth: 25, halign:'left'},
+                    origin:{columnWidth: 16, halign:'left'},
+                    description:{columnWidth: 18, halign:'left'},
+                    date:{columnWidth: 18,  halign:'center'},
+                    date_maturity:{columnWidth: 18,  halign:'center'},
+                    journal_name:{columnWidth: 18, halign:'left'},
+                    user_name:{columnWidth: 18, halign:'left'},
+                    amount_original:{columnWidth: 20, halign:'right'},
+                    total:{columnWidth: 20, halign:'right'},
+
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var journal = self.$el.find('#current-journal').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                        return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(journal && journal != 9999999){
+                var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                    return item.id == journal;
+                });
+                filter.push({
+                   title: 'Método de pago',
+                   value: AccountJournal[0].name,
+                });
+            }
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 760 - 0
static/src/js/reports/report_customer_ranking.js

@@ -0,0 +1,760 @@
+function report_customer_ranking(reporting){
+  "use strict";
+
+  var model = openerp;
+
+    reporting.ReportCustomerRankingWidget = reporting.Base.extend({
+        template : 'ReportCustomerRanking',
+        rowsData : [],
+        content : [],
+        modules : ['product_brand','point_of_sale'],
+
+        events : {
+            'click #generate' : 'fetchGenerate',
+            'change #current-date' : 'ShowDateRange',
+            'change #current-company': 'updateSelections',
+            'change #current-attribute': 'updateAttributeSelections',
+            'click .print-report':'clickOnAction',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start : function(){
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull : function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        checkModule: function(module) {
+            var self = this;
+            return _.filter(self.session.module_list, function(item) {
+                return item == module;
+            });
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                if(self.AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(self.AccountJournal,function(item){
+                        if(item.type == 'sale'){
+                            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                        }
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                /*
+                =================================
+                    PRODUCT CATEGORY
+                =================================
+                */
+                self.ProductCategory = IntialSQL.categories;
+                if(self.ProductCategory.length > 1){
+                    self.$el.find('#current-category').append('<option value="9999999">Todos las Categorias</option>');
+                    _.each(self.ProductCategory,function(item){
+                        self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }
+                self.ProductBrand = IntialSQL.brands;
+                if(self.ProductBrand.length > 1){
+                    self.$el.find('#current-brand').append('<option value="9999999">Todas las Marcas</option>');
+                    _.each(self.ProductBrand,function(item){
+                        self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.brand').css('display','none');
+                }
+                self.ProductAttribute = IntialSQL.attributes;
+                if(self.ProductAttribute.length > 1){
+                    self.$el.find('#current-attribute').append('<option value="9999999">Todas los atributos</option>');
+                    _.each(self.ProductAttribute,function(item){
+                        self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute').css('display','none');
+                }
+                self.ProductAttributeValue = IntialSQL.attribute_values;
+                if(self.ProductAttributeValue.length > 1){
+                    self.$el.find('#current-attribute-value').append('<option value="9999999">Todas los valores de atributos</option>');
+                    _.each(self.ProductAttributeValue,function(item){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute-value').css('display','none');
+                }
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchCheckType();
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.chart-container').css('display', 'none');
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoiceLine = DataSQL.invoice_lines;
+                self.PosOrderLine = DataSQL.order_lines;
+                self.ResPartner = DataSQL.partners;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-sale-customer-ranking');
+            return data;
+        },
+
+        fetchCheckType: function() {
+            var self = this;
+            var modules = self.checkModule('point_of_sale');
+            if (modules.length == 0) {
+                self.$el.find('.type').css('display', 'none');
+            }
+        },
+
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateAttributeSelections: function () {
+            var self = this;
+            var attribute_value;
+            var attribute = self.$el.find('#current-attribute').val();
+            if(attribute != 9999999){
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    if(parseFloat(attribute) == item.attribute_id){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getPosOrderLine:function() {
+            var self = this;
+            var content = self.PosOrderLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var type = self.$el.find('#current-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'sale'){
+                    content = [];
+                }
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        getAccountInvoiceLine:function() {
+            var self = this;
+            var content = self.AccountInvoiceLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var type = self.$el.find('#current-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'tpv'){
+                    content = [];
+                }
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        getAccountInvoiceLineByCustomer:function(partner_id,type) {
+            var self = this;
+            return  _.filter(self.AccountInvoiceLine,function (item) {
+                return item.partner_id == partner_id && item.type == type;
+            });
+        },
+
+        getPosOrderLineByCustomer:function(partner_id) {
+            var self = this;
+            return  _.filter(self.PosOrderLine,function (item) {
+                return item.customer_id == partner_id;
+            });
+        },
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            self.AccountInvoiceLine = self.getAccountInvoiceLine();
+            self.PosOrderLine = self.getPosOrderLine();
+            var ResPartner = self.ResPartner;
+            _.each(ResPartner, function(item){
+
+                /*
+                    INVOICE
+                */
+                var AccountInvoiceLine = self.getAccountInvoiceLineByCustomer(item.id,'out_invoice');
+                var InvoiceLineAmount = _.reduce(_.map(AccountInvoiceLine, function(map) {
+                    return map.subtotal + map.tax;
+                }), function(meno, num) {
+                    return meno + num;
+                }, 0);
+                /*
+                    INVOICE REFUND
+                */
+                var AccountInvoiceLineRefund = self.getAccountInvoiceLineByCustomer(item.id,'out_refund');
+                var InvoiceLineRefundAmount = _.reduce(_.map(AccountInvoiceLineRefund, function(map) {
+                    return map.subtotal + map.tax;
+                }), function(meno, num) {
+                    return meno + num;
+                }, 0);
+                /*
+                    POS ORDER
+                */
+                var PosOrderLine = self.getPosOrderLineByCustomer(item.id);
+                var PosOrderAmount = _.reduce(_.map(PosOrderLine, function(map) {
+                    return map.subtotal + map.tax;
+                }), function(meno, num) {
+                    return meno + num;
+                }, 0);
+
+                var amount = InvoiceLineAmount + PosOrderAmount - InvoiceLineRefundAmount;
+
+                if(amount > 0){
+                    data.push({
+                        ruc:item.ruc,
+                        name:item.name,
+                        total:accounting.formatMoney(amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                        /*
+                        =======================
+                            NO FORMAT
+                        =======================
+                        */
+                        total_no_format:amount,
+                        /*
+                        =======================
+                            FOOTER
+                        =======================
+                        */
+                        decimal_places: CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+                    });
+                }
+            });
+            data.sort(function(a, b) {
+                return b.total_no_format - a.total_no_format;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.CompanyLogo,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = ResCompany[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var total = TotalFooter(row);
+
+            row.push({
+                name: 'Totales',
+                total:total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Ranking de Clientes (+Compras)';
+                var pdf_type = '';
+                var pdf_name = 'ranking_clientes_';
+                var pdf_columnStyles = {
+                    ruc:{hcolumnWidth:45, align:'left'},
+                    name:{columnWidth:70,halign:'left'},
+                    total:{halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var user = self.$el.find('#current-user').val();
+            var type = self.$el.find('#current-type').val();
+            var product = self.$el.find('#current-product').val();
+            var brand = self.$el.find('#current-brand').val();
+            var category = self.$el.find('#current-category').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                    return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+
+            if(user && user != 9999999){
+                var ResUser =  _.filter(self.ResUser,function (item) {
+                    return item.id == user;
+                });
+                filter.push({
+                    title: 'Vendedor',
+                    value:  ResUser[0].name,
+                });
+            }
+
+            if(type && type != 9999999){
+                filter.push({
+                    title: 'Tipo de Venta',
+                    value:  $("#current-type option:selected").text(),
+                });
+            }
+
+            if(brand && brand != 9999999){
+                brand =  _.filter(self.ProductBrand,function (item) {
+                    return item.id == brand;
+                });
+                filter.push({
+                    title: 'Marca',
+                    value: brand[0].name,
+                });
+            }
+
+            if(category && category != 9999999){
+                var categ =  _.filter(self.ProductCategory,function (item) {
+                    return item.id == category;
+                });
+                filter.push({
+                    title: 'Categoría',
+                    value: categ[0].name,
+                });
+            }
+
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+ hasta,
+                    });
+                }else{
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        }
+    });
+}

+ 966 - 0
static/src/js/reports/report_customer_ratings.js

@@ -0,0 +1,966 @@
+function report_customer_ratings(reporting){
+  "use strict";
+  var model = openerp;
+
+  reporting.ReportCustomerRatingsWidget = reporting.Base.extend({
+       template: 'ReportCustomerRatings',
+       rowsData :[],
+       content :[],
+
+       events:{
+           'click #toolbar > button' : 'clickOnAction',
+           'click #generate' : 'fetchGenerate',
+           'change #current-company' : 'updateSelections',
+           'change #current-period' : 'updatePeriodSelections',
+           'change #current-date' : 'ShowDateRange',
+       },
+
+       init: function(parent){
+           this._super(parent);
+       },
+
+       start: function(){
+         var self = this;
+         var date = new reporting.ReportDatePickerWidget(self);
+         date.fecthFecha();
+         this.fetchInitial();
+       },
+
+       valorNull:function(dato){
+           var valor = "";
+           if (dato){
+               valor = dato;
+           }
+           return valor;
+       },
+
+       ShowDateRange : function(){
+           var self = this;
+           var date = self.$el.find('#current-date').val();
+           if(date == 'range'){
+               self.$el.find('.datepicker').css('display','block');
+           }
+           if(date != 'range'){
+               self.$el.find('.datepicker').css('display','none');
+           }
+       },
+
+       fetchInitial: function(){
+           var self = this;
+           self.fecthIrModuleModule().then(function(IrModuleModule){
+               return IrModuleModule;
+           }).then(function(IrModuleModule){
+               self.IrModuleModule = IrModuleModule;
+               return self.fetchResUser;
+           }).then(function (ResUser){
+               self.ResUser = ResUser;
+               return self.fetchResCompany();
+           }).then(function(ResCompany){
+               self.ResCompany = ResCompany;
+               if(ResCompany.length > 1){
+                   self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                   _.each(ResCompany,function(item){
+                       self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                   });
+               }else{
+                   self.$el.find('.company').css('display','none');
+               }
+               return self.fetchResStore();
+           }).then(function(ResStore){
+               self.ResStore = ResStore;
+               if(ResStore.length > 1){
+                   self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                   _.each(ResStore,function(item){
+                       self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                   });
+               }else{
+                   self.$el.find('.store').css('display','none');
+               }
+               return self.fetchAccountPeriod();
+           }).then(function(AccountPeriod){
+               self.AccountPeriod = AccountPeriod;
+               self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+               _.each(AccountPeriod,function(item){
+                   self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+               });
+               return self.fetchResPartner();
+           }).then(function(ResPartner){
+               self.ResPartner = ResPartner;
+               self.$el.find('#current-partner').append('<option value="9999999">Todos los clientes</option>');
+               _.each(ResPartner,function(item){
+                   self.$el.find('#current-partner').append('<option value="' + item.id + '">' + item.name + '</option>');
+               });
+               return self.fetchAccountJournal();
+           }).then(function(AccountJournal){
+               self.AccountJournal = AccountJournal;
+           });
+           self.$el.find('#generate').css('display','inline');
+           return;
+       },
+
+       fetchGenerate: function(){
+           var self = this;
+           self.$el.find('.search-form').block({
+               message: null,
+               overlayCSS: {
+                   backgroundColor: '#FAFAFA'
+               }
+           });
+           self.$el.find('.report-form').block({
+               message: null,
+               overlayCSS: {
+                   backgroundColor: '#FAFAFA'
+               }
+           });
+
+           this.fetchAccountInvoice().then(function(AccountInvoice) {
+               return AccountInvoice;
+           }).then(function (AccountInvoice) {
+               self.AccountInvoice = AccountInvoice;
+               return self.fetchAccountMoveLine();
+           }).then(function (AccountMoveLine){
+               self.AccountMoveLine = AccountMoveLine;
+               return self.fetchResCurrency();
+           }).then(function(ResCurrency){
+               self.ResCurrency = ResCurrency;
+               return self.BuildTable();
+           });
+       },
+
+       /*=====================================================================
+           IR MODULE
+       =====================================================================*/
+       fecthIrModuleModule: function(){
+           var self = this;
+           var defer = $.Deferred();
+           var fields = ['name','id'];
+           var domain=[['state','=','installed']];
+           var IrModuleModule = new model.web.Model('ir.module.module');
+           IrModuleModule.query(fields).filter(domain).all().then(function(results){
+             defer.resolve(results);
+           })
+           return defer;
+       },
+
+       /*
+       =====================================================================
+           USER
+       =====================================================================
+       */
+       fetchResUser: function(){
+           var self = this;
+           var defer = $.Deferred();
+           var fields = ['id','name','store_id'];
+           var domain = [['id','=',self.session.uid]];
+           var ResUser = new model.web.Model('res.users');
+           ResUser.query(fields).filter(domain).all().then(function(results){
+               defer.resolve(results);
+           });
+           return defer;
+       },
+
+       /*
+       =====================================================================
+           PARTNER
+       =====================================================================
+       */
+       fetchResPartner: function(){
+           var self = this;
+           var defer = $.Deferred();
+           var fields = ['id','name'];
+           var domain = [
+             ['active','=', true],
+             ['customer','=', true]];
+           var ResPartner = new model.web.Model('res.partner');
+           ResPartner.query(fields).filter(domain).all().then(function(results){
+               defer.resolve(results);
+           });
+           return defer;
+       },
+       /*
+       =====================================================================
+           ACCOUNT PERIOD
+       =====================================================================
+       */
+       fetchAccountPeriod: function(){
+           var self = this;
+           var defer = $.Deferred();
+           var domain = [['special','=',false]];
+           var field =['id', 'name', 'date_start','date_stop','company_id'];
+           var AccountPeriod = new model.web.Model('account.period');
+           AccountPeriod.query(field).filter(domain).all().then(function(results){
+               defer.resolve(results);
+           });
+           return defer;
+       },
+       /*
+       ====================================================================
+           RES STORE
+       ====================================================================
+       */
+       fetchResStore: function(){
+           var self = this;
+           var defer = $.Deferred();
+           var field = ['id','name','company_id'];
+           var ResStore = new model.web.Model('res.store');
+           ResStore.query(field).all().then(function(results){
+               defer.resolve(results);
+           });
+           return defer;
+       },
+       /*
+       ====================================================================
+           ACCOUNT JOURNAL
+       ====================================================================
+       */
+       fetchAccountJournal: function(){
+           var self = this;
+           var defer = $.Deferred();
+           var company = $('#current-company').val();
+           var store = $('#current-store').val();
+           var domain = [['active','=',true],['type','=','sale']];
+           if(company && company != 9999999){
+               domain.push(['company_id','=',parseFloat(company)]);
+           }
+           if(store && store != 9999999){
+               domain.push(['store_ids','=',parseFloat(store)]);
+           }
+           var field = ['id', 'name','store_ids'];
+           var AccountJournal = new model.web.Model('account.journal');
+           AccountJournal.query(field).filter(domain).all().then(function(results){
+               defer.resolve(results);
+           });
+           return defer;
+       },
+       /*
+       ====================================================================
+           ACCOUNT INVOICE
+       ====================================================================
+       */
+       fetchAccountInvoice: function(){
+           var self = this;
+           var store = self.$el.find('#current-store').val();
+           var journal = self.$el.find('#current-journal').val();
+           var partner = self.$el.find('#current-partner').val();
+
+           if(store && store != 9999999){
+               var journal_ids = _.map(_.filter(self.AccountJournal,function(item){
+                   return item.store_ids == store;
+               }), function(map){
+                   return map.id;
+               });
+           }else{
+               var journal_ids = _.flatten(_.map(self.AccountJournal, function(item){
+                   return item.id;
+               }));
+           }
+           var domain = [
+               ['state', 'in',['open']],
+               ['type', '=', 'out_invoice'],
+               ['journal_id','in',journal_ids],
+           ];
+           if(journal && journal != 9999999){
+               domain.push(['journal_id','=',parseInt(journal)]);
+           }
+
+           if(partner && partner != 9999999){
+               domain.push(['partner_id','=',parseInt(partner)]);
+           }
+
+           var AccountInvoice = new model.web.Model('account.invoice');
+           return AccountInvoice.call('getAccountInvoice',[domain], {
+               context: new model.web.CompoundContext()
+           });
+       },
+       /*
+       ====================================================================
+           ACCOUNT INVOICE LINE
+       ====================================================================
+       */
+       fetchAccountMoveLine: function(){
+           var self = this;
+           var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function(item){
+               return item.number;
+           }));
+           var domain = [
+               ['move_id','in',invoice_numbers],
+               ['debit','>',0],
+               ['date_maturity','!=', false]
+           ];
+
+           var AccountMoveLine = new model.web.Model('account.move.line');
+           return AccountMoveLine.call('getAccountMoveLine',[domain], {
+               context: new model.web.CompoundContext()
+           });
+       },
+       /*
+       ====================================================================
+           RES COMPANY
+       ====================================================================
+       */
+       fetchResCompany: function(){
+           var self = this;
+           var defer = $.Deferred();
+           var currency = new model.web.Model('res.company');
+           var field=['id','name','currency_id','logo'];
+           currency.query(field).filter().all().then(function(results){
+               defer.resolve(results);
+           });
+           return defer;
+       },
+       /*
+       ====================================================================
+           RES CURRENCY
+       ====================================================================
+       */
+       fetchResCurrency : function(){
+           var self = this;
+           var defer = $.Deferred();
+           var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+           var domain = [['active', '=', true]];
+           var ResCurrency = new model.web.Model('res.currency');
+           ResCurrency.query(fields).filter(domain).all().then(function(results){
+               defer.resolve(results);
+           });
+           return defer;
+       },
+
+       /*
+       ====================================================================
+           UPDATE SELECTIONS
+       ====================================================================
+       */
+       updateSelections: function(){
+           var self = this;
+           var company = self.$el.find('#current-company').val();
+           if(company != 9999999){
+               /*===================
+                   STORE SELECTION
+               ===================*/
+               var store = self.$el.find('#current-store').empty();
+               self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+               _.each(self.ResStore,function(item){
+                   if(parseFloat(company) == item.company_id[0]){
+                       self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                   }
+               });
+               /*====================
+                   PERIOD SELECTION
+               ====================*/
+               var period = self.$el.find('#current-period').empty();
+               self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+               _.each(self.AccountPeriod,function(item){
+                   if(parseFloat(company) == item.company_id[0]){
+                       self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                   }
+               });
+           }else{
+               /*===================
+                   STORE SELECTION
+               ===================*/
+               var store = self.$el.find('#current-store').empty();
+               self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+               _.each(self.ResStore,function(item){
+                   self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+               });
+               /*====================
+                   PERIOD SELECTION
+               ====================*/
+               var period = self.$el.find('#current-period').empty();
+               self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+               _.each(self.AccountPeriod,function(item){
+                   self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+               });
+           }
+       },
+
+       updatePeriodSelections: function(){
+           var self = this;
+           var period = self.$el.find('#current-period').val();
+           if(period != 9999999){
+               self.$el.find('#current-date').val(9999999);
+               self.$el.find('#current-date').prop('disabled','disabled');
+               self.$el.find('.datepicker').css('display','none');
+           }else{
+               self.$el.find('#current-date').prop('disabled',false);
+           }
+       },
+
+       /*====================================================================
+           GET RES COMPANY
+       ====================================================================*/
+       getResCompany: function(id){
+           var self = this;
+           return _.filter(self.ResCompany,function(item){
+               return item.id == id;
+           });
+       },
+
+       /*====================================================================
+           GET RES CURRENCY BASE
+       ====================================================================*/
+       getResCurrency: function(id){
+           var self = this;
+           return _.filter(self.ResCurrency,function(item){
+               return item.id === id;
+           });
+       },
+
+       /*====================================================================
+           GET ACCOUNT MOVE LINE
+       ====================================================================*/
+       getAccountMoveLine: function(number){
+           var self = this;
+           var period = self.$el.find('#current-period').val();
+           var date = self.$el.find('#current-date').val();
+           var desde = self.$el.find('#from').val();
+           var hasta = self.$el.find('#to').val();
+           var AccountMoveLine = _.filter(self.AccountMoveLine,function(item){
+                return item.move_id[1] == number;
+            });
+            var x = AccountMoveLine.length;
+            var i = AccountMoveLine.length;
+
+           var content =_.map(AccountMoveLine, function(item2){
+               if(item2.date_maturity != false){
+                   item2.dues_name= 'Cuota ' + i +' / ' + x;
+                   i--;
+                   return item2;
+               };
+           });
+
+           if(date && date != 9999999){
+               if(date == 'range'){
+                   if(desde){
+                       var date = desde.split('/')
+                       date = (date[2]+"-"+date[1]+"-"+date[0]);
+                       content = _.flatten(_.filter(content,function(item){
+                         return item.date_maturity >= date;
+                       }));
+                   }
+                   if(hasta){
+                       var date = hasta.split('/')
+                       date = (date[2]+"-"+date[1]+"-"+date[0]);
+                       content = _.flatten(_.filter(content,function(item){
+                         return item.date_maturity <= date;
+                       }));
+                   }
+               }
+               if(date == 'today'){
+                   var today = moment().format('YYYY-MM-DD');
+                   content = _.flatten(_.filter(content,function(item){
+                     return item.date_maturity == today;
+                   }));
+               }
+
+               if(date == 'yesterday'){
+                   var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                   content = _.flatten(_.filter(content,function(item){
+                     return item.date_maturity == yesterday;
+                   }));
+               }
+               if(date == 'currentMonth'){
+                   var currentMonth = moment().format('YYYY-MM');
+                   content = _.flatten(_.filter(content,function(item){
+                     return moment(item.date_maturity,'YYYY-MM-DD').format('YYYY-MM') == currentMonth;
+                   }));
+               }
+               if(date == 'lastMonth'){
+                   var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                   content = _.flatten(_.filter(content,function(item){
+                     return moment(item.date_maturity,'YYYY-MM-DD').format('YYYY-MM') == lastMonth;
+                   }));
+               }
+           }
+
+           if(period && period != 9999999){
+               var periodo = _.flatten(_.filter(self.AccountPeriod,function (item) {
+                   return item.id == period;
+               }));
+
+               content = _.flatten(_.filter(content,function (item) {
+                   return moment(item.date_maturity,'YYYY-MM-DD').format('MM/YYYY') == periodo[0].name;
+               }));
+           }
+           content = _.filter(content,function(item){
+             return item != undefined;
+           })
+           return content;
+       },
+
+
+       /*============================
+           GET INVOICE
+       ============================*/
+       getAccountInvoice:function(partner_id){
+         var self = this;
+         return _.filter(self.AccountInvoice,function(item){
+             return item.partner_id[0] === partner_id;
+         })
+       },
+
+       /*====================================================================
+           BUILD
+       ====================================================================*/
+       BuildTable: function(){
+           var self = this;
+           var data = [];
+           var company = $('#current-company').val();
+           var state = $('#current-state').val();
+
+           if(company && company != 9999999){
+               var ResCompany = self.getResCompany(company).shift();
+               var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+           }else{
+               var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+           }
+
+           var ResPartner = self.ResPartner;
+
+           _.each(ResPartner, function(item){
+             var info = [];
+             var due_qty=0;
+             var amount=0;
+             var aux_ruc;
+
+
+               var AccountInvoice = self.getAccountInvoice(item.id);
+
+               _.each(AccountInvoice, function(item){
+                   aux_ruc = item.partner_id[2];
+
+                   var AccountMoveLine = self.getAccountMoveLine(item.number);
+                   var Currency = self.getResCurrency(item.invoice_currency[0]).shift();
+
+                   _.each(AccountMoveLine, function(index){
+                       var date;
+
+                       var state = 'Vencido';
+                       if(index.reconcile_ref){
+                           if(index.amount_residual == 0){
+                               state = 'Pagado';
+                           }
+                           if(index.amount_residual > 0){
+                               var value = accounting.formatMoney(index.debit - index.amount_residual, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                               state = 'Amortizado ' + ' (' + value + ')';
+                           }
+                       }
+
+                       date = moment(index.date_maturity,'YYYY-MM-DD').format('DD/MM/YYYY');
+                       if(state != 'Pagado'){
+
+                           if(index.date_maturity < moment().format('YYYY-MM-DD')){
+
+                               due_qty++;
+
+                               var days_of_delays =  moment().diff(moment(index.date_maturity), 'days');
+
+                               amount = amount + index.amount_residual;
+
+                               info.push({
+                                   invoice_id : item.id,
+                                   invoice : item.number,
+                                   partner_ruc : self.valorNull(aux_ruc),
+                                   partner_name : item.partner_id[1],
+                                   date : date,
+                                   name : index.dues_name,
+                                   state : state,
+                                   days_of_delays: days_of_delays,
+                                   amount : accounting.formatMoney(index.debit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                                   residual : accounting.formatMoney(index.amount_residual, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                                   invoice_residual : accounting.formatMoney(item.residual, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+
+                                   invoice_residual_no_format : item.residual,
+                                   amount_no_format : index.debit,
+                                   residual_no_format : index.amount_residual,
+
+                                   decimal_places : CurrencyBase.decimal_places,
+                                   thousands_separator : CurrencyBase.thousands_separator,
+                                   decimal_separator : CurrencyBase.decimal_separator,
+                               });
+
+                           };
+                       };
+
+                   });
+                 });
+
+                 if(info.length > 0){
+
+                     var max_days_of_delay= info.reduce((max, p) => p.days_of_delays > max ? p.days_of_delays : max, info[0].days_of_delays);
+
+                     info.sort(function(a, b){
+                       if(state == 'day_of_delay'){
+                         var x = a.days_of_delays;
+                         var y = b.days_of_delays;
+                       };
+
+                       if(state == 'amount_delay'){
+                         var x = a.residual_no_format;
+                         var y = b.residual_no_format;
+                       };
+
+                         if (x > y) {
+                             return -1;
+                         }
+                         if (x < y) {
+                             return 1;
+                         }
+                         return 0;
+                     });
+
+                     data.push({
+                         partner_ruc : self.valorNull(aux_ruc),
+                         partner_name : item.name,
+                         due_qty:due_qty,
+                         max_days_of_delay: max_days_of_delay,
+                         amount: accounting.formatMoney(amount, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+
+                         amount_no_format: amount,
+
+                         info: info,
+
+                         decimal_places : CurrencyBase.decimal_places,
+                         thousands_separator : CurrencyBase.thousands_separator,
+                         decimal_separator : CurrencyBase.decimal_separator,
+                       });
+                 }
+           });
+
+           data.sort(function(a, b){
+
+             if(state == 'day_of_delay'){
+               var x = a.max_days_of_delay;
+               var y = b.max_days_of_delay;
+             };
+             if(state == 'due_qty'){
+               var x = a.due_qty;
+               var y = b.due_qty;
+             }
+             if(state == 'amount_delay'){
+               var x = a.amount_no_format;
+               var y = b.amount_no_format;
+             };
+
+               if (x > y) {
+                   return -1;
+               }
+               if (x < y) {
+                   return 1;
+               }
+               return 0;
+           });
+
+           self.content = data;
+
+           self.CallCharts(data, CurrencyBase);
+           self.loadTable(data);
+       },
+
+       CallCharts: function(data,CurrencyBase){
+           var self = this;
+           var state = $('#current-state').val();
+           /*
+           ================================================
+           GRAFICO DE BARRAS
+           ================================================
+           */
+           var BarChart = new model.eiru_reports.ReportChartWidget(self);
+           var rank = 10;
+           var item;
+           var label = [];
+           var body = [];
+           for (var i = 0; i < rank; i++) {
+               if (data[i]){
+                   item = data[i];
+               }else{
+                   item = {};
+                   item.partner_name = "N/A";
+                   item.max_days_of_delay=0;
+                   item.due_qty=0;
+                   item.amount_no_format=0;
+               }
+
+               label.push(item.partner_name.trim());
+               if(state == 'day_of_delay'){
+                 body.push(item.max_days_of_delay);
+                 CurrencyBase.symbol = "Días atrasados: ";
+               };
+               if(state == 'due_qty'){
+                 body.push(item.due_qty);
+                 CurrencyBase.symbol = "Cuotas vencidas: ";
+               }
+               if(state == 'amount_delay'){
+                 body.push(item.amount_no_format);
+               };
+
+           }
+           $('.chart-container').empty();
+           $('.chart-container').html('<canvas class="reporting-chart"></canvas>');
+           BarChart.BuildBarChart(data,CurrencyBase,label,body);
+
+           self.$el.find('.report-form').css('display','block');
+           self.$el.find('.search-form').unblock();
+           self.$el.find('.report-form').unblock();
+       },
+
+       /*====================================================================
+           LOAD BOOTSTRAP TABLE
+       ====================================================================*/
+       loadTable:function(rowsTable){
+         var self = this;
+         var data = [];
+         self.rowsData = rowsTable;
+         var table = this.$el.find('#table');
+
+         table.bootstrapTable({
+           data:rowsTable,
+           detailView: true,
+           onExpandRow: function(index, row, $detail){
+             $detail.html('<div class="panel panel-first-style"><div class="panel-heading panel-header-first-style">Cuotas vencidas</div><table id="table2"></table></div>').find('table').bootstrapTable({
+               columns: [
+                     {
+                         field: 'invoice',
+                         title: 'Factura',
+                         align: 'center',
+                     },
+                     {
+                         field: 'partner_ruc',
+                         title: 'Nº Doc.',
+                         align: 'center',
+                     },
+                     {
+                         field: 'name',
+                         title: 'Cuota',
+                         align: 'center',
+                     },
+                     {
+                         field: 'date',
+                         title: 'Fecha Vencimiento',
+                         align: 'center',
+                     },
+                     {
+                         field: 'state',
+                         title: 'Estado',
+                         align: 'center',
+                     },
+                     {
+                         field: 'days_of_delays',
+                         title: 'Días atrasados',
+                         align: 'center',
+                     },
+                     {
+                         field: 'amount',
+                         title: 'Total',
+                         align: 'right',
+                     },
+                     {
+                         field: 'residual',
+                         title: 'Saldo',
+                         align: 'right',
+                     },
+                     {
+                         field: 'invoice_residual',
+                         title: 'Saldo Factura',
+                         align: 'right',
+                     }
+                   ],
+
+             data:row.info,
+             })
+               $('#table2').removeClass('table-hover').addClass('table-no-bordered');
+               $('thead').css('background','none');
+           }
+         });
+
+         table.bootstrapTable('load', rowsTable);
+       },
+
+       /*====================================================================
+           PRINT PDF
+       ====================================================================*/
+       clickOnAction: function(e){
+           var self = this;
+           var ResCompany;
+           var action = this.$el.find(e.target).val();
+           var company = $('#current-company').val();
+
+           if(company && company != 9999999){
+               ResCompany = self.getResCompany(company).shift();
+           }else{
+               ResCompany = self.ResCompany[0];
+           }
+
+
+           var table = this.$el.find("#table");
+           var row = table.bootstrapTable('getData');
+
+
+           if (action === 'pdf') {
+
+               var pdf_title = 'Calificación de Cliente.';
+               var pdf_type = '';
+               var pdf_name = 'calificacion_de_clientes_';
+               var pdf_columnStyles = {
+                 invoice: {
+                   columnWidth: 20,
+                   halign: 'center'
+                 },
+                 partner_ruc: {
+                   columnWidth: 18,
+                   halign: 'center'
+                 },
+                 name: {
+                   columnWidth: 18,
+                   halign: 'center'
+                 },
+
+                 date: {
+                   columnWidth: 20,
+                   halign: 'center'
+                 },
+
+                 state: {
+                   columnWidth: 20,
+                   halign: 'center'
+                 },
+
+                 days_of_delays: {
+                   columnWidth: 20,
+                   halign: 'center'
+                 },
+
+                 amount: {
+                   columnWidth: 25,
+                   halign: 'right'
+                 },
+
+                 residual: {
+                   columnWidth: 25,
+                   halign: 'right'
+                 },
+
+                 invoice_residual: {
+                   columnWidth: 25,
+                   halign: 'right'
+                 },
+               };
+               /*
+               ============================================================
+                   LLAMAR FUNCION DE IMPRESION
+               ============================================================
+               */
+               var filter =self.getFilter();
+               var pdf = new reporting.ReportPdfWidget(self);
+               pdf.drawPdf4(
+                   row,
+                   ResCompany,
+                   pdf_title,
+                   pdf_type,
+                   pdf_name,
+                   pdf_columnStyles,
+                   filter
+               );
+             }
+       },
+
+       getFilter: function(){
+         var self = this;
+         var company = self.$el.find('#current-company').val();
+         var store = self.$el.find('#current-store').val();
+         var partner = self.$el.find('#current-partner').val();
+         var state = self.$el.find('#current-state').val();
+         var period = self.$el.find('#current-period').val();
+         var date = self.$el.find('#current-date').val();
+         var desde = self.$el.find('#from').val();
+         var hasta = self.$el.find('#to').val();
+
+         var filter = [];
+
+         if(company && company != 9999999){
+           var ResCompany = _.filter(self.ResCompany, function(item){
+             return item.id == company;
+           });
+           filter.push({
+             title:'Empresa',
+             value: ResCompany[0].name,
+           });
+         }
+
+         if(store && store != 9999999){
+           var ResStore =  _.filter(self.ResStore,function(item){
+               return item.id == store;
+           });
+
+           filter.push({
+               title: 'Sucursal',
+               value:  ResStore[0].name,
+           });
+         }
+
+         if(partner && partner != 9999999){
+           var ResPartner =  _.filter(self.ResPartner,function(item){
+               return item.id == partner;
+           });
+
+           filter.push({
+               title: 'Cliente',
+               value:  ResPartner[0].name,
+           });
+         }
+
+         if(state && state != 9999999){
+           filter.push({
+               title: 'Ordenado por',
+               value:  $("#current-state option:selected").text(),
+           });
+         }
+
+         if(period && period != 9999999){
+
+           var AccountPeriod =  _.filter(self.AccountPeriod,function(item){
+               return item.id == period;
+           });
+           filter.push({
+                title: 'Periodo',
+                value:  AccountPeriod[0].name,
+              });
+         }
+
+         if(date && date != 9999999){
+           moment.locale('es', {
+             months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+           });
+
+           if(date == 'range'){
+             filter.push({
+                 title: 'Fecha',
+                 value:  desde +' al '+hasta,
+             });
+
+           }
+           else {
+             if(date == 'today'){
+                 var fecha = moment().format('DD/MM/YYYY');
+             }
+
+             if(date == 'yesterday'){
+                 var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+             }
+             if(date == 'currentMonth'){
+                 var fecha = moment().format('MMMM/YYYY');
+             }
+             if(date == 'lastMonth'){
+                 var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+             }
+
+             filter.push({
+                 title: 'Fecha',
+                 value:  fecha,
+             });
+           }
+         }
+         return filter;
+       },
+   });
+}

+ 1027 - 0
static/src/js/reports/report_customer_refund.js

@@ -0,0 +1,1027 @@
+function report_customer_refund(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportCustomerRefundWidget = reporting.Base.extend({
+        template: 'ReportCustomerRefund',
+        rowsData :[],
+        content :[],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.fetchAccountInvoiceLine();
+            }).then(function (AccountInvoiceLine){
+                self.AccountInvoiceLine = AccountInvoiceLine;
+                return self.fetchAccountVoucher();
+            }).then(function (AccountVoucher){
+                self.AccountVoucher = AccountVoucher;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed']];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','sale_refund']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open','paid']],
+                ['type', '=', 'out_refund'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+            if(state != 9999999){
+                domain.push(['state','=',state]);
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================*/
+        fetchAccountInvoiceLine: function (){
+            var self = this;
+            var invoice_ids = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.id;
+            }));
+            var domain = [
+                ['invoice_id','in',invoice_ids],
+            ];
+            var AccountInvoiceLine = new model.web.Model('account.invoice.line');
+            return AccountInvoiceLine.call('getAccountInvoiceLine',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+
+        /*=====================================================================
+            ACCOUNT VOUCHER
+        =====================================================================*/
+        fetchAccountVoucher: function () {
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['type','=','receipt'],
+                ['state','=','posted'],
+                ['reference','in',invoice_numbers]
+            ];
+            var AccountVoucher = new model.web.Model('account.voucher');
+            return AccountVoucher.call('getAccountVoucher',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT INVOICE LINE
+        ====================================================================*/
+        getAccountInvoiceLine: function (id) {
+            var self = this;
+            return _.filter(self.AccountInvoiceLine,function (item) {
+                return item.invoice_id === id;
+            })
+        },
+
+
+        /*====================================================================
+            GET ACCOUNT VOUCHER
+        ====================================================================*/
+        getAccountVoucher: function (number) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.reference == number;
+            })
+        },
+
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*============================
+            ACCOUNT DATA BY DAY
+        ============================*/
+        getContentByDay:function(date) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM-DD') === date;
+            }));
+        },
+
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var info = [];
+            var payments = [];
+
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+                var AccountInvoice = self.AccountInvoice;
+                _.each(AccountInvoice, function(item){
+                    info = [];
+                    payments = [];
+                    var AccountInvoiceLine = self.getAccountInvoiceLine(item.id);
+                    var AccountVoucher = self.getAccountVoucher(item.number);
+                    var Currency = self.getResCurrency(item.invoice_currency[0]).shift();
+                    _.each(AccountInvoiceLine, function(index){
+                        var price_unit = 0;
+                        var amount = 0;
+                        if(Currency.id != CurrencyBase.id){
+                            price_unit = accounting.formatMoney(index.price_unit_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.price_unit, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) +')';
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.price_subtotal, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) +')';
+                        }else{
+                            price_unit = accounting.formatMoney(index.price_unit_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        }
+                        info.push({
+                            product_name : index.product_id[1],
+                            price_unit : price_unit,
+                            quantity : index.quantity,
+                            amount: amount,
+                        });
+                    });
+                    if(AccountVoucher.length > 0){
+                        _.each(AccountVoucher, function(index){
+                            var CurrencyVoucher = self.getResCurrency(index.currency_id[0]).shift();
+                            var amount = 0;
+                            if(CurrencyVoucher.id != CurrencyBase.id){
+                                amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.amount, '', CurrencyVoucher.decimal_places, CurrencyVoucher.thousands_separator, CurrencyVoucher.decimal_separator) +')';
+                            }else{
+                                amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                            }
+                            payments.push({
+                                date : moment(index.date).format('DD/MM/YYYY'),
+                                journal_name : index.journal_id[1],
+                                amount : amount,
+                            });
+                        });
+                    }
+
+                    var residual_total = 0;
+                    var amount_untaxed_total = 0;
+                    var amount_tax_total = 0;
+                    var amount_total = 0;
+
+                    if(Currency.id != CurrencyBase.id){
+                        residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.residual, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                        amount_untaxed_total = accounting.formatMoney(item.amount_untaxed_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.amount_untaxed, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                        amount_tax_total = accounting.formatMoney(item.amount_tax_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.amount_tax, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                        amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.amount_total, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                    }else{
+                        residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        amount_untaxed_total = accounting.formatMoney(item.amount_untaxed_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        amount_tax_total = accounting.formatMoney(item.amount_tax_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                    }
+
+                    data.push({
+                        /*=======================
+                            IDS
+                        =======================*/
+                        id : item.id,
+                        /*=======================
+                            INFO
+                        =======================*/
+                        number : item.number,
+                        date_invoice : moment(item.date_invoice).format('DD/MM/YYYY'),
+                        date : moment(item.date_invoice).format('YYYY-MM-DD'),
+                        origin : self.valorNull(item.origin),
+                        user_id : item.user_id[1],
+                        partner_id : self.valorNull(item.partner_id[1]),
+                        residual_total : residual_total,
+                        amount_untaxed_total : amount_untaxed_total,
+                        amount_tax_total : amount_tax_total,
+                        amount_total : amount_total,
+                        /*=======================
+                            VALORES SIN FORMATEAR
+                        =======================*/
+                        residual : item.residual_currency,
+                        amount_untaxed : item.amount_untaxed_currency,
+                        amount_tax : item.amount_tax_currency,
+                        amount : item.amount_total_currency,
+                        /*==============================
+                            TOTAL FOOTER CONFIGURATION
+                        ==============================*/
+                        decimal_places : CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+                        /*==============================
+                            DATA
+                        ==============================*/
+                        info : info,
+                        payments : payments,
+                    });
+                });
+
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return -1;
+                }
+                if (a.date < b.date) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.BuildChartByPeriod();
+        },
+
+        /*====================================================================
+            BUILD CHART BY PERIOD
+        ====================================================================*/
+        BuildChartByPeriod: function(){
+            var self = this;
+            var data = [];
+            var label = [];
+            var body = [];
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var AccountPeriod = self.AccountPeriod;
+            var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL PERIODO
+            =============================================================================
+            */
+            if(period != 9999999){
+                var range = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                var date = range[0].date_start;
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > range[0].date_stop){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL RANGO DE FECHAS
+            =============================================================================
+            */
+            if(date == 'range'){
+
+                // DESDE
+                var desde = self.$el.find('#from').val();
+                desde = desde.split('/');
+                desde = (desde[2] + "-" + desde[1] + "-" + desde[0]);
+
+                // HASTA
+                var hasta = self.$el.find('#to').val();
+                if(hasta){
+                    hasta = hasta.split('/');
+                    hasta = (hasta[2] + "-" + hasta[1] + "-" + hasta[0]);
+                }else{
+                    hasta = moment().format('YYYY-MM-DD');
+                }
+                // DETERMINAR RANGO DE FECHAS
+                const diff = moment(hasta).diff(moment(desde),'days');
+
+                if(diff > 0 & diff < 32){
+                    self.$el.find('.chart-container').css('display','block');
+                    var date = desde;
+                    for (var i = 0; i < 32; i++) {
+                        if(i > 0){
+                            date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                        }
+                        if(date > hasta){
+                            break;
+                        }
+                        var data = self.getContentByDay(date);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(moment(date).format('DD/MM/YYYY'));
+                            body.push(total);
+                        }
+                    }
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff > 31){
+                    self.$el.find('.chart-container').css('display','block');
+                    _.each(AccountPeriod, function(item){
+                        var data = self.getContent(item.date_start);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(item.name);
+                            body.push(total);
+                        }
+                    });
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff == 0){
+                    self.$el.find('.chart-container').css('display','none');
+                }
+            }
+            /*
+            =============================================================================
+                OCULTAR GRAFICO EN EL CASO DE QUE EL FILTRO SEA AYER U HOY
+            =============================================================================
+            */
+            if(date == 'today' || date == 'yesterday'){
+                self.$el.find('.chart-container').css('display','none');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES ACTUAL
+            =============================================================================
+            */
+            if(date == 'currentMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES PASADO
+            =============================================================================
+            */
+            if(date == 'lastMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().add(-1,'month').startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().add(-1,'month').endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR SIN FILTRO
+            =============================================================================
+            */
+            if(date == 9999999 & period == 9999999){
+                _.each(AccountPeriod, function(item){
+                    var data = self.getContent(item.date_start);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(item.name);
+                        body.push(total);
+                    }
+                });
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            var chart = new reporting.ReportChartWidget(self);
+            chart.BuildLineChart(label,body,CurrencyBase);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var residual = totalResidualFormatter(row);
+            var untaxed = totalUntaxedFormatter(row);
+            var tax = totalTaxFormatter(row);
+            var total = totalFormatter(row);
+
+            row.push({
+                number : 'Totales',
+                residual_total : residual,
+                amount_untaxed_total : untaxed,
+                amount_tax_total : tax,
+                amount_total : total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Notas de Crédito.';
+                var pdf_type = '';
+                var pdf_name = 'notas_de_credito_';
+                var pdf_columnStyles = {
+                    number :{columnWidth: 25, halign:'center'},
+                    date_invoice :{columnWidth: 18, halign:'center'},
+                    user_id :{columnWidth: 20, halign:'left'},
+                    origin :{columnWidth: 23, halign:'left'},
+                    partner_id : {halign:'left'},
+                    residual_total : {columnWidth: 20, halign:'right'},
+                    amount_untaxed_total : {columnWidth: 20, halign:'right'},
+                    amount_tax_total : {columnWidth: 19, halign:'right'},
+                    amount_total : {columnWidth: 19, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var state = self.$el.find('#current-state').val();
+          var period = self.$el.find('#current-period').val();
+          var journal = self.$el.find('#current-journal').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+
+          }
+          if(state && state != 9999999){
+            filter.push({
+                title: 'Estado',
+                value:  $("#current-state option:selected").text(),
+            });
+          }
+
+          if(period && period != 9999999){
+
+            var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+                return item.id == period;
+            });
+            filter.push({
+                 title: 'Periodo',
+                 value:  AccountPeriod[0].name,
+               });
+          }
+
+          if(journal && journal != 9999999){
+            var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                return item.id == journal;
+            });
+            filter.push({
+                 title: 'Factura',
+                 value: AccountJournal[0].name,
+               });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        },
+    });
+}

+ 885 - 0
static/src/js/reports/report_daily_sale.js

@@ -0,0 +1,885 @@
+function report_daily_sale(reporting){
+  "use strict";
+
+  var model = openerp;
+
+  reporting.ReportDailySaleWidget = reporting.Base.extend({
+    template: 'ReportDailySale',
+    rowsData :[],
+    content :[],
+    modules: ['point_of_sale'],
+
+    events:{
+      'click #toolbar > button' : 'clickOnAction',
+      'click #generate' : 'fetchGenerate',
+      'change #current-company' : 'updateSelections',
+      'change #current-date' : 'ShowDateRange',
+      'change #current-period' : 'updatePeriodSelections',
+    },
+
+    init : function(parent){
+      this._super(parent);
+    },
+
+    start: function () {
+      var table = this.$el.find('#table');
+      table.bootstrapTable({data : self.rowsData});
+      var date = new reporting.ReportDatePickerWidget(self);
+      date.fecthFecha();
+      this.fetchInitial();
+    },
+
+    checkModel : function(model){
+      var self = this;
+      return _.filter(self.IrModuleModule,function(item){
+        return item.name === model
+      });
+    },
+
+    valorNull:function(dato){
+      var valor = "";
+      if (dato){
+        valor = dato;
+      }
+      return valor;
+    },
+
+    ShowDateRange : function(){
+      var self = this;
+      var date = self.$el.find('#current-date').val();
+      if(date == 'range'){
+        self.$el.find('.datepicker').css('display','block');
+      }
+      if(date != 'range'){
+        self.$el.find('.datepicker').css('display','none');
+      }
+    },
+
+      fetchInitial: function () {
+        var self = this;
+        self.fecthIrModuleModule().then(function (IrModuleModule) {
+          return IrModuleModule;
+        }).then(function(IrModuleModule) {
+          self.IrModuleModule = IrModuleModule;
+          return self.fetchResUser();
+        }).then(function (ResUser) {
+          self.ResUser = ResUser;
+          if(ResUser.length > 1){
+            self.$el.find('#current-user').append('<option value="9999999">Todos los vendedores</option>');
+            _.each(ResUser,function(item){
+              self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+            });
+          }else{
+            self.$el.find('.user').css('display','none');
+          }
+          self.fecthCheckType();
+          return self.fetchResCompany();
+        }).then(function(ResCompany){
+          self.ResCompany = ResCompany;
+          if(ResCompany.length > 1){
+            self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+            _.each(ResCompany,function(item){
+              self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+            });
+          }else{
+            self.$el.find('.company').css('display','none');
+          }
+          return self.fetchResStore();
+        }).then(function(ResStore){
+          self.ResStore = ResStore;
+          if(ResStore.length > 1){
+            self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+            _.each(ResStore,function(item){
+              self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+            });
+          }else{
+            self.$el.find('.store').css('display','none');
+          }
+          return self.fetchAccountPeriod();
+        }).then(function(AccountPeriod){
+          self.AccountPeriod = AccountPeriod;
+          self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+          _.each(AccountPeriod,function(item){
+            self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+          return self.fetchResCurrency();
+        }).then(function(ResCurrency){
+          self.ResCurrency = ResCurrency;
+        });
+        self.$el.find('#generate').css('display','inline');
+        return;
+      },
+
+      fetchGenerate: function () {
+        var self = this;
+        self.$el.find('.search-form').block({
+          message: null,
+          overlayCSS: {
+            backgroundColor: '#FAFAFA'
+          }
+        });
+        self.$el.find('.report-form').block({
+          message: null,
+          overlayCSS: {
+            backgroundColor: '#FAFAFA'
+          }
+        });
+
+        this.fetchAccountInvoice().then(function(AccountInvoice) {
+          return AccountInvoice;
+        }).then(function (AccountInvoice) {
+          self.AccountInvoice = AccountInvoice;
+          return self.fetchPosOrder();
+        }).then(function (PosOrder){
+          self.PosOrder = PosOrder;
+          return self.fetchPosOrderLine();
+        }).then(function (PosOrderLine){
+          self.PosOrderLine = PosOrderLine;
+          return self.fetchAccountInvoiceLine();
+        }).then(function(AccountInvoiceLine){
+          self.AccountInvoiceLine = AccountInvoiceLine;
+          return self.fetchResUser();
+        }).then(function(ResUser){
+          self.ResUser = ResUser;
+          return self.BuildTable();
+        });
+      },
+
+/*=====================================================================
+            IR MODULE
+=====================================================================*/
+      fecthIrModuleModule: function(){
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['name','id'];
+        var domain=[['state','=','installed'],['name','in',self.modules]];
+        var IrModuleModule = new model.web.Model('ir.module.module');
+        IrModuleModule.query(fields).filter(domain).all().then(function(results){
+          defer.resolve(results);
+        })
+        return defer;
+      },
+
+/*=====================================================================
+            Check type
+=====================================================================*/
+      fecthCheckType: function(){
+        var self = this;
+        var modules = self.checkModel('point_of_sale');
+        if(modules.length == 0){
+          self.$el.find('.type').css('display','none');
+        }
+      },
+
+/*=====================================================================
+            USER
+=====================================================================*/
+      fetchResUser: function() {
+        var self = this;
+        var domain = [];
+        var defer = $.Deferred();
+        var fields = ['id','name','store_id','company_id'];
+        var user = self.$el.find('#current-user').val();
+        var store = self.$el.find('#current-store').val();
+        var company = self.$el.find('#current-company').val();
+
+        if(company && company != 9999999){
+          domain.push(['company_id','=',parseInt(company)]);
+        }
+
+        if(user && user != 9999999){
+          domain.push(['id','=', parseInt(user)]);
+        }
+        if(store && store != 9999999){
+          domain.push(['store_id','=',parseInt(store)]);
+        }
+
+        var ResUser = new model.web.Model('res.users');
+        ResUser.query(fields).filter(domain).all().then(function (results) {
+          defer.resolve(results);
+        });
+        return defer;
+      },
+
+/*=====================================================================
+            ACCOUNT PERIOD
+=====================================================================*/
+      fetchAccountPeriod: function () {
+        var self = this;
+        var defer = $.Deferred();
+        var domain = [['special','=',false]];
+        var field =['id', 'name', 'date_start','date_stop','company_id'];
+        var AccountPeriod = new model.web.Model('account.period');
+        AccountPeriod.query(field).filter(domain).all().then(function (results) {
+          defer.resolve(results);
+        });
+        return defer;
+      },
+
+/*====================================================================
+            RES STORE
+====================================================================*/
+      fetchResStore: function(){
+        var self = this;
+        var defer = $.Deferred();
+        var field = ['id','name','company_id'];
+        var ResStore = new model.web.Model('res.store');
+        ResStore.query(field).all().then(function(results){
+          defer.resolve(results);
+        });
+        return defer;
+      },
+
+/*====================================================================
+            ACCOUNT INVOICE
+====================================================================*/
+      fetchAccountInvoice: function () {
+        var self = this;
+        var period = self.$el.find('#current-period').val();
+        var date = self.$el.find('#current-date').val();
+        var desde = self.$el.find('#from').val();
+        var hasta = self.$el.find('#to').val();
+
+        var domain = [
+          ['state', 'in',['open','paid']],
+          ['type', '=', 'out_invoice'],
+        ];
+
+        if(period != 9999999){
+          domain.push(['period_id','=',parseInt(period)]);
+        }
+
+        if(date && date != 9999999){
+          if(desde){
+            var date = desde.split('/')
+            date = (date[2]+"-"+date[1]+"-"+date[0]);
+            domain.push(['date_invoice','>=',date]);
+          }
+
+          if(hasta){
+            var date = hasta.split('/')
+            date = (date[2]+"-"+date[1]+"-"+date[0]);
+            domain.push(['date_invoice','<=',date]);
+          }
+
+          if(date == 'today'){
+            var today = moment().format('YYYY-MM-DD');
+            domain.push(['date_invoice','=',today]);
+          }
+
+          if(date == 'yesterday'){
+            var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+            domain.push(['date_invoice','=',yesterday]);
+          }
+
+          if(date == 'currentMonth'){
+            var currentMonth = moment().format('YYYY-MM');
+            domain.push(['date_invoice','like',currentMonth]);
+          }
+
+          if(date == 'lastMonth'){
+            var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+            domain.push(['date_invoice','like',lastMonth]);
+          }
+        }
+
+        var AccountInvoice = new model.web.Model('account.invoice');
+        return AccountInvoice.call('getAccountInvoice',[domain], {
+          context: new model.web.CompoundContext()
+        });
+      },
+
+
+      fetchAccountInvoiceLine: function () {
+        var self = this;
+        var invoice_ids = _.flatten(_.map(self.AccountInvoice, function (item) {
+            return item.id;
+        }));
+        var domain = [
+            ['invoice_id','in',invoice_ids],
+        ];
+
+        var AccountInvoiceLine = new model.web.Model('account.invoice.line');
+        return AccountInvoiceLine.call('getAccountInvoiceLine',[domain], {
+          context: new model.web.CompoundContext()
+        });
+      },
+
+
+/*====================================================================
+            POS ORDER
+====================================================================*/
+      fetchPosOrder: function () {
+        var self = this;
+        var type = $('#current-type').val();
+        var modules = self.checkModel('point_of_sale');
+        if (type && modules.length > 0){
+          if(type != 'sale'){
+
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+
+            var domain = [
+              ['state', 'not in',['draft','cancel']],
+            ];
+
+            if(date && date != 9999999){
+              if(desde){
+                var date = desde.split('/')
+                date = (date[2]+"-"+date[1]+"-"+date[0]);
+                domain.push(['date_order','>=',date]);
+              }
+            }
+
+            var PosOrder = new model.web.Model('account.invoice');
+            return PosOrder.call('getPosOrder',[domain], {
+              context: new model.web.CompoundContext()
+            });
+          }
+        }else{
+          var PosOrder = [];
+          return PosOrder;
+        }
+      },
+
+      fetchPosOrderLine: function () {
+        var self = this;
+        var domain = [];
+        var order_ids = _.flatten(_.map(self.PosOrder, function (item) {
+            return item.id;
+        }));
+        var domain = [
+            ['order_id','in',order_ids],
+        ];
+
+        var modules = self.checkModel('point_of_sale');
+        if (modules.length > 0){
+          var PosOrderLine = new model.web.Model('account.invoice.line');
+          return PosOrderLine.call('getPosOrderLine',[domain], {
+              context: new model.web.CompoundContext()
+          });
+        }else{
+            var PosOrderLine = [];
+            return PosOrderLine;
+        }
+      },
+
+/*====================================================================
+            RES COMPANY
+====================================================================*/
+      fetchResCompany: function(){
+        var self = this;
+        var defer = $.Deferred();
+        var currency = new model.web.Model('res.company');
+        var field=['id','name','currency_id','logo'];
+        currency.query(field).filter().all().then(function(results){
+          defer.resolve(results);
+        });
+        return defer;
+      },
+
+/*====================================================================
+            RES CURRENCY
+====================================================================*/
+      fetchResCurrency : function(){
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+        var domain = [['active', '=', true]];
+        var ResCurrency = new model.web.Model('res.currency');
+        ResCurrency.query(fields).filter(domain).all().then(function(results) {
+          defer.resolve(results);
+        });
+        return defer;
+      },
+
+/*====================================================================
+            UPDATE SELECTIONS
+====================================================================*/
+      updateSelections: function () {
+        var self = this;
+        var company = self.$el.find('#current-company').val();
+        if(company != 9999999){
+          /*===================
+              STORE SELECTION
+          ==================*/
+          var store = self.$el.find('#current-store').empty();
+          self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+          _.each(self.ResStore,function(item){
+            if(parseFloat(company) == item.company_id[0]){
+              self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+            }
+          });
+          /*====================
+                PERIOD SELECTION
+          ====================*/
+          var period = self.$el.find('#current-period').empty();
+          self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+          _.each(self.AccountPeriod,function(item){
+            if(parseFloat(company) == item.company_id[0]){
+              self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+            }
+          });
+        }else{
+          /*===================
+              STORE SELECTION
+          ===================*/
+          var store = self.$el.find('#current-store').empty();
+          self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+          _.each(self.ResStore,function(item){
+            self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+          /*====================
+              PERIOD SELECTION
+            ====================*/
+          var period = self.$el.find('#current-period').empty();
+          self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+          _.each(self.AccountPeriod,function(item){
+            self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+        }
+      },
+
+      updatePeriodSelections: function () {
+          var self = this;
+          var period = self.$el.find('#current-period').val();
+          if(period != 9999999){
+              self.$el.find('#current-date').val(9999999);
+              self.$el.find('#current-date').prop('disabled','disabled');
+              self.$el.find('.datepicker').css('display','none');
+          }else{
+              self.$el.find('#current-date').prop('disabled',false);
+          }
+      },
+
+/*====================================================================
+          GET RES COMPANY
+====================================================================*/
+      getResCompany: function (id) {
+        var self = this;
+        return _.filter(self.ResCompany,function (item) {
+          return item.id == id;
+        })
+      },
+
+/*====================================================================
+            GET RES CURRENCY BASE
+====================================================================*/
+      getResCurrency: function (id) {
+        var self = this;
+        return _.filter(self.ResCurrency,function (item) {
+          return item.id === id;
+        })
+      },
+
+/*============================
+            ACCOUNT DATA BY MONTH
+============================*/
+      getContent:function(mes) {
+        var self = this;
+        return _.flatten(_.filter(self.content,function (inv) {
+          return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+        }));
+      },
+/*============================
+            GET POS ORDER
+============================*/
+      getPosOrder:function(id) {
+        var self = this;
+        var date = self.$el.find('#current-date').val();
+        var period = self.$el.find('#current-period').val();
+        var desde = self.$el.find('#from').val();
+        var hasta = self.$el.find('#to').val();
+        var content = _.filter(self.PosOrder,function (inv) {
+          return inv.user_id[0] == id;
+        });
+          if(date && date != 9999999){
+            if(desde){
+              var date = desde.split('/')
+              date = (date[2]+"-"+date[1]+"-"+date[0]);
+              content = _.flatten(_.filter(content,function (inv) {
+                var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                utc = moment(utc._d).format('YYYY-MM-DD');
+                return moment(utc).format('YYYY-MM-DD') >= desde;
+              }));
+            }
+            if(hasta){
+              var date = desde.split('/')
+              date = (date[2]+"-"+date[1]+"-"+date[0]);
+              content = _.flatten(_.filter(content,function (inv) {
+                var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                utc = moment(utc._d).format('YYYY-MM-DD');
+                return moment(utc).format('YYYY-MM-DD') <= hasta;
+              }));
+            }
+            if(date == 'today'){
+              var today = moment().format('YYYY-MM-DD');
+              content = _.flatten(_.filter(content,function (inv) {
+                var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                utc = moment(utc._d).format('YYYY-MM-DD');
+                return moment(utc).format('YYYY-MM-DD') === today;
+              }));
+            }
+            if(date == 'yesterday'){
+              var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+              content = _.flatten(_.filter(content,function (inv) {
+                var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                utc = moment(utc._d).format('YYYY-MM-DD');
+                return moment(utc).format('YYYY-MM-DD') === yesterday;
+              }));
+            }
+            if(date == 'currentMonth'){
+              var currentMonth = moment().format('YYYY-MM');
+              content = _.flatten(_.filter(content,function (inv) {
+                var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                utc = moment(utc._d).format('YYYY-MM-DD');
+                return moment(utc).format('YYYY-MM') === currentMonth;
+              }));
+            }
+            if(date == 'lastMonth'){
+              var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+              content = _.flatten(_.filter(content,function (inv) {
+                var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                utc = moment(utc._d).format('YYYY-MM-DD');
+                return moment(utc).format('YYYY-MM') === lastMonth;
+              }));
+            }
+          }
+          if(period && period != 9999999){
+            var data = _.filter(self.AccountPeriod,function (inv) {
+              return inv.id == parseInt(period);
+            });
+            content = _.flatten(_.filter(content,function (inv) {
+              var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+              utc = moment(utc._d).format('YYYY-MM-DD');
+              return moment(utc).format('MM/YYYY') === data[0].name;
+            }));
+          }
+
+          return content;
+      },
+
+      getPosOrderLine: function (id) {
+        var self = this;
+        return _.filter(self.PosOrderLine,function (item) {
+            return item.order_id[0] == id;
+        });
+      },
+
+      getAccountInvoice: function (id) {
+        var self = this;
+        return _.filter(self.AccountInvoice,function (item) {
+          return item.user_id[0] === id;
+        })
+      },
+
+      getAccountInvoiceLine: function (id) {
+        var self = this;
+        return _.filter(self.AccountInvoiceLine,function (item) {
+          return item.invoice_id === id;
+        })
+      },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+      BuildTable: function(){
+        var self = this;
+        var data = [];
+        var all_data = [];
+        var AccountInvoice = [];
+        var PosOrder = [];
+
+        var type = $('#current-type').val();
+        var company = $('#current-company').val();
+        if(company && company != 9999999){
+          var ResCompany = self.getResCompany(company).shift();
+          var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+        }else{
+          var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+        }
+
+        var ResUser = self.ResUser;
+        _.each(ResUser, function(user){
+          var info=[];
+          var header_qty = 0;
+          var header_price = 0;
+
+          if(type == 'sale' || type == 9999999){
+            AccountInvoice =_.map(self.getAccountInvoice(user.id), function(item){
+              item.group_type= 'sale';
+              return item;
+            });
+          }
+          if(type == 'tpv' || type == 9999999){
+            PosOrder =_.map(self.getPosOrder(user.id), function(item){
+              item.group_type= 'tpv';
+              return item;
+            });
+          }
+
+          var concatBothSaleType = AccountInvoice.concat(PosOrder);
+          var grouped_data = self.groupBy(concatBothSaleType);
+
+          grouped_data.forEach((item,key) => {
+
+            var sum_qty=0;
+            var sum_price=0;
+            var sum_qty_pos=0;
+            var sum_price_pos=0;
+            var total_qty =0;
+            var total_price=0;
+            var total_average =0;
+
+            _.each(item, function(item2){//1
+              if(item2.group_type == 'sale'){
+                var AccountInvoiceLine = self.getAccountInvoiceLine(item2.id);
+                _.each(AccountInvoiceLine, function(item3){
+                  sum_qty = sum_qty + item3.quantity;
+                  sum_price = sum_price + (item3.price_unit * item3.quantity);
+                });
+              }
+              if(item2.group_type == 'tpv'){
+                var PosOrderLine = self.getPosOrderLine(item2.id);
+                _.each(PosOrderLine, function(item3){
+                  sum_qty_pos = sum_qty_pos + item3.qty;
+                  sum_price_pos = sum_price_pos + (item3.price_unit * item3.qty);
+                });
+              }
+            });//1
+
+            //suma venta normal + pos
+
+            total_qty = sum_qty + sum_qty_pos;
+            total_price = sum_price + sum_price_pos;
+            total_average = total_price / total_qty;
+            header_qty = header_qty + total_qty;
+            header_price = header_price + total_price;
+
+            info.push({
+              date: moment(key).format('DD/MM/YYYY'),
+              store: user.store_id[1],
+              user: user.name,
+              qty: accounting.formatNumber(total_qty, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+              price: accounting.formatMoney(total_price, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+              average: accounting.formatMoney(total_average, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+            });
+
+            info.sort(function(a, b) {
+              a = new Date(moment(a.date).format('DD/MM/YYYY'));
+              b = new Date(moment(b.date).format('DD/MM/YYYY'));
+              return a>b ? -1 : a<b ? 1 : 0;
+            });
+          });
+
+          if( header_price > 0){
+            data.push({
+              user: user.name,
+              qty: accounting.formatNumber(header_qty, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+              price: accounting.formatMoney(header_price, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+
+              qty_no_format : header_qty,
+              price_no_format: header_price,
+
+              decimal_places : CurrencyBase.decimal_places,
+              thousands_separator: CurrencyBase.thousands_separator,
+              decimal_separator: CurrencyBase.decimal_separator,
+
+              info:info,
+            });
+          }
+        });
+
+        self.content = data;
+        self.loadTable(data);
+        self.$el.find('.report-form').css('display','block');
+        self.$el.find('.search-form').unblock();
+        self.$el.find('.report-form').unblock();
+      },
+
+      groupBy: function(list) {
+        const map = new Map();
+        list.forEach((item) => {
+          const key = item.date_invoice || moment(item.date_order).format('YYYY-MM-DD');
+          const collection = map.get(key);
+          if (!collection) {
+            map.set(key, [item]);
+          } else {
+            collection.push(item);
+          }
+        });
+        return map;
+      },
+
+
+/*====================================================================
+            LOAD BOOTSTRAP TABLE
+====================================================================*/
+      loadTable:function(rowsTable){
+        var self = this;
+        self.rowsData = rowsTable;
+        var table = this.$el.find('#table');
+        table.bootstrapTable('load', rowsTable);
+      },
+
+/*====================================================================
+            PRINT PDF
+====================================================================*/
+      clickOnAction: function (e) {
+        var self = this;
+        var ResCompany;
+        var action = this.$el.find(e.target).val();
+        var company = $('#current-company').val();
+        if(company && company != 9999999){
+          ResCompany = self.getResCompany(company).shift();
+          var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+        }else{
+          ResCompany = self.ResCompany[0];
+          var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+        }
+        var getColumns=[];
+        var rows=[];
+        var table = this.$el.find("#table");
+        var column = table.bootstrapTable('getVisibleColumns');
+        var row = table.bootstrapTable('getData');
+
+        if (action === 'pdf') {
+          var data = _.map(column, function (val){ return val.field});
+          _.each(_.map(column,function(val){
+            return val}), function(item){
+              getColumns.push([{
+                title: item.title,
+                dataKey: item.field
+              }]);
+            });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+          var pdf_title = 'Resumen de Ventas Diarias.';
+          var pdf_type = '';
+          var pdf_name = 'resumen_ventas_diarias_';
+          var pdf_columnStyles = {
+            date :{halign:'center'},
+            store :{halign:'left'},
+            user : {halign:'left'},
+            qty : {columnWidth: '20%', halign:'right'},
+            price : {columnWidth: '20%', halign:'right'},
+            average : {columnWidth: '20%', halign:'right'},
+          };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+          var filter = self.getFilter();
+          var pdf = new reporting.ReportPdfWidget(self);
+          pdf.drawPdf3(
+            row,
+            ResCompany,
+            pdf_title,
+            pdf_type,
+            pdf_name,
+            pdf_columnStyles,
+            filter,
+          );
+        }
+      },
+      getFilter: function(){
+        var self = this;
+        var company = self.$el.find('#current-company').val();
+        var user = self.$el.find('#current-user').val();
+        var store = self.$el.find('#current-store').val();
+        var period = self.$el.find('#current-period').val();
+        var type = self.$el.find('#current-type').val();
+        var date = self.$el.find('#current-date').val();
+        var desde = self.$el.find('#from').val();
+        var hasta = self.$el.find('#to').val();
+
+        var filter = [];
+        if(company && company != 9999999){
+          var ResCompany = _.filter(self.ResCompany, function(item){
+            return item.id == company;
+          });
+          filter.push({
+            title:'Empresa',
+            value: ResCompany[0].name,
+          });
+        }
+
+        if(user && user != 9999999){
+          var ResUser = _.filter(self.ResUser, function(item){
+            return item.id == user;
+          })
+
+          filter.push({
+            title: 'Vendedor',
+            value: ResUser[0].name,
+          })
+        }
+        if(store && store != 9999999){
+          var ResStore =  _.filter(self.ResStore,function (item) {
+              return item.id == store;
+          });
+
+          filter.push({
+              title: 'Sucursal',
+              value:  ResStore[0].name,
+          });
+        }
+
+        if(period && period != 9999999){
+          var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+              return item.id == period;
+          });
+          filter.push({
+               title: 'Periodo',
+               value:  AccountPeriod[0].name,
+             });
+        }
+
+      if(type && type != 9999999){
+        filter.push({
+          title: 'Tipo de Venta',
+          value: $("#current-type option:selected").text(),
+        })
+      }
+
+        if(date && date != 9999999){
+          moment.locale('es', {
+            months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+          });
+
+          if(date == 'range'){
+            filter.push({
+                title: 'Fecha',
+                value:  desde +' al '+hasta,
+            });
+
+          }
+          else {
+            if(date == 'today'){
+                var fecha = moment().format('DD/MM/YYYY');
+            }
+
+            if(date == 'yesterday'){
+                var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+            }
+            if(date == 'currentMonth'){
+                var fecha = moment().format('MMMM/YYYY');
+            }
+            if(date == 'lastMonth'){
+                var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+            }
+
+            filter.push({
+                title: 'Fecha',
+                value:  fecha,
+            });
+          }
+        }
+        return filter;
+      },
+    });
+}

+ 957 - 0
static/src/js/reports/report_dues_analysis.js

@@ -0,0 +1,957 @@
+function report_dues_analysis(reporting){
+  "use strict";
+  var model = openerp;
+
+    reporting.ReportDuesAnalysisWidget = reporting.Base.extend({
+        template: 'ReportDuesAnalysis',
+        rowsData :[],
+        content :[],
+        modules: ['eiru_account_interest'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+          var self = this;
+          return _.filter(self.IrModuleModule,function(item){
+            return item.name === model
+          });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        clickAnalysisDetail : function(e, row, $element, field){
+            if(field == 'invoice'){
+                this.do_action({
+                    name : 'Factura',
+                    type : 'ir.actions.act_window',
+                    res_model : 'account.invoice',
+                    views : [[false,'form']],
+                    target  : 'new',
+                    domain : [['id','=',row.invoice_id]],
+                    context : {},
+                    flags : {'form' : {'action_buttons' : false, 'options' : {'mode' : 'view'}}},
+                    res_id : row.invoice_id,
+                });
+            }
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.fetchAccountMoveLine();
+            }).then(function (AccountMoveLine){
+                self.AccountMoveLine = AccountMoveLine;
+                return self.fetchAccountInterest();
+            }).then(function(AccountInterest){
+                self.AccountInterest = AccountInterest;
+                return self.fetchAccountInterestLine();
+            }).then(function(AccountInterestLine){
+                self.AccountInterestLine = AccountInterestLine;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+              defer.resolve(results);
+            })
+            return defer;
+        },
+
+        fetchAccountInterest:function(){
+          var self = this;
+          var defer = $.Deferred();
+          var field =['id', 'invoice_id','lines_ids','state'];
+          var domain=[['state','=','lines_open']];
+          var modules = self.checkModel('eiru_account_interest');
+          if (modules.length > 0){
+            var AccountInterest = new model.web.Model('account.interest');
+            AccountInterest.query(field).filter(domain).all().then(function (results) {
+              defer.resolve(results);
+            });
+            return defer;
+          }else{
+              var AccountInterest = [];
+              return AccountInterest;
+          }
+        },
+
+        fetchAccountInterestLine:function(){
+          var self = this;
+          var defer = $.Deferred();
+          var field =['id', 'move_line_id','amount_interest','state'];
+          var domain=[['state','=','open']];
+          var modules = self.checkModel('eiru_account_interest');
+          if (modules.length > 0){
+            var AccountInterestLine = new model.web.Model('account.interest.line');
+            AccountInterestLine.query(field).filter(domain).all().then(function (results) {
+              defer.resolve(results);
+            });
+            return defer;
+          }else{
+              var AccountInterestLine = [];
+              return AccountInterestLine;
+          }
+        },
+
+        /*
+        =====================================================================
+            USER
+        =====================================================================
+        */
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        =====================================================================
+            ACCOUNT PERIOD
+        =====================================================================
+        */
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        ====================================================================
+            RES STORE
+        ====================================================================
+        */
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        ====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================
+        */
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','sale']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        ====================================================================
+            ACCOUNT INVOICE
+        ====================================================================
+        */
+        fetchAccountInvoice: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open']],
+                ['type', '=', 'out_invoice'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+        /*
+        ====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================
+        */
+        fetchAccountMoveLine: function (){
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['move_id','in',invoice_numbers],
+                ['debit','>',0],
+                ['date_maturity','!=', false]
+            ];
+
+            var AccountMoveLine = new model.web.Model('account.move.line');
+            return AccountMoveLine.call('getAccountMoveLine',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+        /*
+        ====================================================================
+            RES COMPANY
+        ====================================================================
+        */
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        ====================================================================
+            RES CURRENCY
+        ====================================================================
+        */
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*
+        ====================================================================
+            UPDATE SELECTIONS
+        ====================================================================
+        */
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        // get due interest
+
+        getDueInterest: function (id) {
+            var self = this;
+            var AccountInterestLine = self.AccountInterestLine;
+            if(AccountInterestLine.length > 0){
+              var interes = _.map(_.filter(AccountInterestLine,function (item) {
+                  return item.move_line_id[0] === id;
+              }), function(map){
+                  return map.amount_interest;
+              });
+              if(interes.length > 0){
+                return interes[0]
+              }
+              else{
+                return 0;
+              }
+
+            }
+            else{
+              return 0;
+            }
+        },
+
+        // get invoice interest
+        getInvoiceInterest: function (id) {
+            var self = this;
+
+            var AccountInterest = self.AccountInterest;
+            if(AccountInterest.length > 0){
+              var interes = _.filter(AccountInterest,function (item) {
+                  return item.invoice_id[0] === id;
+              });
+              if(interes.length > 0){
+                var suma;
+                _.each(interes,function(each){
+                  suma=0;
+                  _.each(each.lines_ids, function(i){
+                    var x = _.filter(self.AccountInterestLine,function (item) {
+                      return item.id === i;
+                    });
+                    if(x.length > 0){
+                      suma = suma + x[0].amount_interest;
+                    }
+                  })
+                });
+                return suma;
+              }
+              else{
+                return 0;
+              }
+            }
+            else{
+              return 0;
+            }
+        },
+
+        /*====================================================================
+            GET ACCOUNT MOVE LINE
+        ====================================================================*/
+        getAccountMoveLine: function (number) {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var AccountMoveLine = _.filter(self.AccountMoveLine,function (item) {
+                 return item.move_id[1] == number;
+             });
+             var x = AccountMoveLine.length;
+             var i = AccountMoveLine.length;
+
+            var content =_.map(AccountMoveLine, function(item2){
+                if(item2.date_maturity != false){
+                    item2.dues_name= 'Cuota ' + i +' / ' + x;
+                    i--;
+                    return item2;
+                };
+            });
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (item) {
+                          return item.date_maturity >= date;
+                        }));
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (item) {
+                          return item.date_maturity <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (item) {
+                      return item.date_maturity == today;
+                    }));
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (item) {
+                      return item.date_maturity == yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (item) {
+                      return moment(item.date_maturity,'YYYY-MM-DD').format('YYYY-MM') == currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (item) {
+                      return moment(item.date_maturity,'YYYY-MM-DD').format('YYYY-MM') == lastMonth;
+                    }));
+                }
+            }
+
+            if(state && state != 9999999){
+
+              var today = moment().format('YYYY-MM-DD');
+                if(state == 'expired'){
+                    content = _.flatten(_.filter(content,function (item) {
+                        return item.date_maturity <= today && item.amount_residual > 0;
+                    }));
+                }
+                if(state == 'to_receive'){
+                    content = _.flatten(_.filter(content,function (item) {
+                      return item.amount_residual > 0;
+                    }));
+                };
+
+                if(state == 'paid'){
+                    content = _.flatten(_.filter(content,function (item) {
+                      return item.amount_residual == 0;
+                    }));
+                };
+            };
+
+            if(period && period != 9999999){
+                var periodo = _.flatten(_.filter(self.AccountPeriod,function (item) {
+                    return item.id == period;
+                }));
+
+                content = _.flatten(_.filter(content,function (item) {
+                    return moment(item.date_maturity,'YYYY-MM-DD').format('MM/YYYY') == periodo[0].name;
+                }));
+            }
+            content = _.filter(content,function(item){
+              return item != undefined
+            })
+            return content;
+        },
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date,'YYYY-MM-DD').format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*============================
+            ACCOUNT DATA BY DAY
+        ============================*/
+        getContentByDay:function(date) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date,'YYYY-MM-DD').format('YYYY-MM-DD') === date;
+            }));
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var type = $('#current-type').val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var AccountInvoice = self.AccountInvoice;
+            _.each(AccountInvoice, function(item){
+
+                var invoice_interest = self.getInvoiceInterest(item.id)
+
+                var AccountMoveLine = self.getAccountMoveLine(item.number);
+                var Currency = self.getResCurrency(item.invoice_currency[0]).shift();
+
+                _.each(AccountMoveLine, function(index){
+
+                    var amount = 0;
+                    var date;
+                    var date_pay;
+
+                    var due_interest = self.getDueInterest(index.id);
+
+                    var state = 'No Pagado';
+                    if(index.reconcile_ref){
+                        if(index.amount_residual == 0){
+                            state = 'Pagado';
+                            date_pay = moment(index.date).format('DD/MM/YYYY');
+                            console.log(date_pay);
+                        }
+                        if(index.amount_residual > 0){
+                            var value = accounting.formatMoney(index.debit - index.amount_residual, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                            state = 'Amortizado ' + ' (' + value + ')';
+                        }
+                    }
+
+                    date = moment(index.date_maturity,'YYYY-MM-DD').format('DD/MM/YYYY');
+                    if(state != 'Pagado'){
+                        if(index.date_maturity < moment().format('YYYY-MM-DD')){
+                            date = moment(index.date_maturity,'YYYY-MM-DD').format('DD/MM/YYYY') + ' (vencido) ';
+
+                        };
+                    };
+                    if(index.date_maturity != false || date_pay != false){
+                        var days_of_delays =  moment().diff(moment(index.date_maturity), 'days');
+                        data.push({
+                            invoice_id : item.id,
+                            invoice : item.number,
+                            supplier_invoice_number : self.valorNull(item.supplier_invoice_number),
+                            origin : self.valorNull(item.origin),
+                            date_invoice:moment(item.date_invoice).format('DD/MM/YYYY'),
+                            partner_ruc : self.valorNull(item.partner_id[2]),
+                            partner_name : item.partner_id[1],
+                            partner_mobile : self.valorNull(item.partner_info.mobile),
+                            partner_phone : self.valorNull(item.partner_info.phone),
+                            date : date,
+                            date_pay: date_pay,
+                            name : index.dues_name,
+                            state : state,
+                            days_of_delays: days_of_delays > 0 ? days_of_delays : '-',
+                            amount : accounting.formatMoney(index.debit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            due_interest : accounting.formatMoney(due_interest, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            residual : accounting.formatMoney(index.amount_residual + due_interest, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            invoice_residual : accounting.formatMoney(item.residual + invoice_interest, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            invoice_total : accounting.formatMoney(item.amount_total + invoice_interest, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+
+                            invoice_residual_no_format : item.residual,
+                            amount_no_format : index.debit,
+                            residual_no_format : index.amount_residual,
+
+                            decimal_places : CurrencyBase.decimal_places,
+                            thousands_separator : CurrencyBase.thousands_separator,
+                            decimal_separator : CurrencyBase.decimal_separator,
+                        });
+                    };
+                });
+              });
+
+            data.sort(function (a, b) {
+              var x = moment(a.date,'DD/MM/YYYY').format('YYYY-MM-DD');
+              var y = moment(b.date,'DD/MM/YYYY').format('YYYY-MM-DD');
+                if (x > y) {
+                    return -1;
+                }
+                if (x < y) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var total = totalAmountFormatter(row);
+            var residual = totalResidualFormatter(row);
+
+            row.push({
+                partner_ruc : 'Totales',
+                amount : total,
+                residual : residual,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Análisis de Cuotas.';
+                var pdf_type = 'l';
+                var pdf_name = 'analisis_de_cuotas_';
+                var pdf_columnStyles = {
+                    partner_ruc :{columnWidth: 17, halign:'center'},
+                    partner_name :{columnWidth: 30, halign:'left'},
+                    invoice :{columnWidth: 24, halign:'center'},
+                    supplier_invoice_number:{columnWidth: 24, halign:'center'},
+                    origin :{columnWidth: 12, halign:'center'},
+                    date_invoice : {columnWidth: 21, halign:'center'},
+                    name :{columnWidth: 17, halign:'center'},
+                    date : {columnWidth: 17, halign:'center'},
+                    date_pay : {columnWidth: 17, halign:'center'},
+                    state : {columnWidth: 16, halign:'center'},
+                    days_of_delays : {columnWidth:13,halign:'center'},
+                    amount : {columnWidth: 22, halign:'right'},
+                    due_interest:{columnWidth:14,halign:'right'},
+                    residual : {columnWidth: 20, halign:'right'},
+                    invoice_total : {columnWidth: 21, halign:'right'},
+                    invoice_residual : {columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter =self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var state = self.$el.find('#current-state').val();
+          var period = self.$el.find('#current-period').val();
+          var journal = self.$el.find('#current-journal').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+
+          }
+          if(state && state != 9999999){
+            filter.push({
+                title: 'Estado',
+                value:  $("#current-state option:selected").text(),
+            });
+          }
+
+          if(period && period != 9999999){
+
+            var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+                return item.id == period;
+            });
+            filter.push({
+                 title: 'Periodo',
+                 value:  AccountPeriod[0].name,
+               });
+          }
+
+          if(journal && journal != 9999999){
+            var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                return item.id == journal;
+            });
+            filter.push({
+                 title: 'Factura',
+                 value: AccountJournal[0].name,
+               });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        },
+    });
+}

+ 947 - 0
static/src/js/reports/report_duessupplier_analysis.js

@@ -0,0 +1,947 @@
+function report_duessupplier_analysis(reporting){
+  "use strict";
+  var model = openerp;
+
+    reporting.ReportDuesSupplierAnalysisWidget = reporting.Base.extend({
+        template: 'ReportDuesSupplierAnalysis',
+        rowsData :[],
+        content :[],
+        modules: ['eiru_account_interest'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+          var self = this;
+          return _.filter(self.IrModuleModule,function(item){
+            return item.name === model
+          });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        clickAnalysisDetail : function(e, row, $element, field){
+            if(field == 'invoice'){
+                this.do_action({
+                    name : 'Factura',
+                    type : 'ir.actions.act_window',
+                    res_model : 'account.invoice',
+                    views : [[false,'form']],
+                    target  : 'new',
+                    domain : [['id','=',row.invoice_id]],
+                    context : {},
+                    flags : {'form' : {'action_buttons' : false, 'options' : {'mode' : 'view'}}},
+                    res_id : row.invoice_id,
+                });
+            }
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.fetchAccountMoveLine();
+            }).then(function (AccountMoveLine){
+                self.AccountMoveLine = AccountMoveLine;
+                return self.fetchAccountInterest();
+            }).then(function(AccountInterest){
+                self.AccountInterest = AccountInterest;
+                return self.fetchAccountInterestLine();
+            }).then(function(AccountInterestLine){
+                self.AccountInterestLine = AccountInterestLine;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+              defer.resolve(results);
+            })
+            return defer;
+        },
+
+        fetchAccountInterest:function(){
+          var self = this;
+          var defer = $.Deferred();
+          var field =['id', 'invoice_id','lines_ids','state'];
+          var domain=[['state','=','lines_open']];
+          var modules = self.checkModel('eiru_account_interest');
+          if (modules.length > 0){
+            var AccountInterest = new model.web.Model('account.interest');
+            AccountInterest.query(field).filter(domain).all().then(function (results) {
+              defer.resolve(results);
+            });
+            return defer;
+          }else{
+              var AccountInterest = [];
+              return AccountInterest;
+          }
+        },
+
+        fetchAccountInterestLine:function(){
+          var self = this;
+          var defer = $.Deferred();
+          var field =['id', 'move_line_id','amount_interest','state'];
+          var domain=[['state','=','open']];
+          var modules = self.checkModel('eiru_account_interest');
+          if (modules.length > 0){
+            var AccountInterestLine = new model.web.Model('account.interest.line');
+            AccountInterestLine.query(field).filter(domain).all().then(function (results) {
+              defer.resolve(results);
+            });
+            return defer;
+          }else{
+              var AccountInterestLine = [];
+              return AccountInterestLine;
+          }
+        },
+
+        /*
+        =====================================================================
+            USER
+        =====================================================================
+        */
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        =====================================================================
+            ACCOUNT PERIOD
+        =====================================================================
+        */
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        ====================================================================
+            RES STORE
+        ====================================================================
+        */
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        ====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================
+        */
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','purchase']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        ====================================================================
+            ACCOUNT INVOICE
+        ====================================================================
+        */
+        fetchAccountInvoice: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open']],
+                ['type', '=', 'in_invoice'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+        /*
+        ====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================
+        */
+        fetchAccountMoveLine: function (){
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['move_id','in',invoice_numbers],
+                ['credit','>',0],
+                ['date_maturity','!=', false]
+            ];
+
+            var AccountMoveLine = new model.web.Model('account.move.line');
+            return AccountMoveLine.call('getAccountMoveLine',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+        /*
+        ====================================================================
+            RES COMPANY
+        ====================================================================
+        */
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*
+        ====================================================================
+            RES CURRENCY
+        ====================================================================
+        */
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*
+        ====================================================================
+            UPDATE SELECTIONS
+        ====================================================================
+        */
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        // get due interest
+
+        getDueInterest: function (id) {
+            var self = this;
+            var AccountInterestLine = self.AccountInterestLine;
+            if(AccountInterestLine.length > 0){
+              var interes = _.map(_.filter(AccountInterestLine,function (item) {
+                  return item.move_line_id[0] === id;
+              }), function(map){
+                  return map.amount_interest;
+              });
+              if(interes.length > 0){
+                return interes[0]
+              }
+              else{
+                return 0;
+              }
+
+            }
+            else{
+              return 0;
+            }
+        },
+
+        // get invoice interest
+        getInvoiceInterest: function (id) {
+            var self = this;
+
+            var AccountInterest = self.AccountInterest;
+            if(AccountInterest.length > 0){
+              var interes = _.filter(AccountInterest,function (item) {
+                  return item.invoice_id[0] === id;
+              });
+              if(interes.length > 0){
+                var suma;
+                _.each(interes,function(each){
+                  suma=0;
+                  _.each(each.lines_ids, function(i){
+                    var x = _.filter(self.AccountInterestLine,function (item) {
+                      return item.id === i;
+                    });
+                    if(x.length > 0){
+                      suma = suma + x[0].amount_interest;
+                    }
+                  })
+                });
+                return suma;
+              }
+              else{
+                return 0;
+              }
+            }
+            else{
+              return 0;
+            }
+        },
+
+        /*====================================================================
+            GET ACCOUNT MOVE LINE
+        ====================================================================*/
+        getAccountMoveLine: function (number) {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var AccountMoveLine = _.filter(self.AccountMoveLine,function (item) {
+                 return item.move_id[1] == number;
+             });
+             var x = AccountMoveLine.length;
+             var i = AccountMoveLine.length;
+
+            var content =_.map(AccountMoveLine, function(item2){
+                if(item2.date_maturity != false){
+                    item2.dues_name= 'Cuota ' + i +' / ' + x;
+                    i--;
+                    return item2;
+                };
+            });
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (item) {
+                          return item.date_maturity >= date;
+                        }));
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (item) {
+                          return item.date_maturity <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (item) {
+                      return item.date_maturity == today;
+                    }));
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (item) {
+                      return item.date_maturity == yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (item) {
+                      return moment(item.date_maturity,'YYYY-MM-DD').format('YYYY-MM') == currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (item) {
+                      return moment(item.date_maturity,'YYYY-MM-DD').format('YYYY-MM') == lastMonth;
+                    }));
+                }
+            }
+
+            if(state && state != 9999999){
+
+              var today = moment().format('YYYY-MM-DD');
+                if(state == 'expired'){
+                    content = _.flatten(_.filter(content,function (item) {
+                        return item.date_maturity <= today && item.amount_residual > 0;
+                    }));
+                }
+                if(state == 'to_receive'){
+                    content = _.flatten(_.filter(content,function (item) {
+                      return item.amount_residual > 0;
+                    }));
+                };
+
+                if(state == 'paid'){
+                    content = _.flatten(_.filter(content,function (item) {
+                      return item.amount_residual == 0;
+                    }));
+                };
+            };
+
+            if(period && period != 9999999){
+                var periodo = _.flatten(_.filter(self.AccountPeriod,function (item) {
+                    return item.id == period;
+                }));
+
+                content = _.flatten(_.filter(content,function (item) {
+                    return moment(item.date_maturity,'YYYY-MM-DD').format('MM/YYYY') == periodo[0].name;
+                }));
+            }
+            content = _.filter(content,function(item){
+              return item != undefined
+            })
+            return content;
+        },
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date,'YYYY-MM-DD').format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*============================
+            ACCOUNT DATA BY DAY
+        ============================*/
+        getContentByDay:function(date) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date,'YYYY-MM-DD').format('YYYY-MM-DD') === date;
+            }));
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var type = $('#current-type').val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var AccountInvoice = self.AccountInvoice;
+            _.each(AccountInvoice, function(item){
+                var invoice_interest = self.getInvoiceInterest(item.id)
+
+                var AccountMoveLine = self.getAccountMoveLine(item.number);
+                var Currency = self.getResCurrency(item.invoice_currency[0]).shift();
+
+                _.each(AccountMoveLine, function(index){
+                    var amount = 0;
+                    var date;
+
+                    var due_interest = self.getDueInterest(index.id);
+
+                    var state = 'No Pagado';
+                    if(index.reconcile_ref){
+                        if(index.amount_residual == 0){
+                            state = 'Pagado'
+                        }
+                        if(index.amount_residual > 0){
+                            var value = accounting.formatMoney(index.debit - index.amount_residual, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                            state = 'Amortizado ' + ' (' + value + ')';
+                        }
+                    }
+
+                    date = moment(index.date_maturity,'YYYY-MM-DD').format('DD/MM/YYYY');
+                    if(state != 'Pagado'){
+                        if(index.date_maturity < moment().format('YYYY-MM-DD')){
+                            date = moment(index.date_maturity,'YYYY-MM-DD').format('DD/MM/YYYY') + ' (vencido) ';
+                        };
+                    };
+                    if(index.date_maturity != false){
+                        var days_of_delays =  moment().diff(moment(index.date_maturity), 'days');
+                        data.push({
+                            invoice_id : item.id,
+                            invoice : item.number,
+                            supplier_invoice_number : self.valorNull(item.supplier_invoice_number),
+                            date_invoice:moment(item.date_invoice).format('DD/MM/YYYY'),
+                            partner_ruc : self.valorNull(item.partner_id[2]),
+                            partner_name : item.partner_id[1],
+                            partner_mobile : self.valorNull(item.partner_info.mobile),
+                            partner_phone : self.valorNull(item.partner_info.phone),
+                            date : date,
+                            name : index.dues_name,
+                            state : state,
+                            days_of_delays: days_of_delays > 0 ? days_of_delays : '-',
+                            amount : accounting.formatMoney(index.debit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            due_interest : accounting.formatMoney(due_interest, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            residual : accounting.formatMoney(index.amount_residual + due_interest, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            invoice_residual : accounting.formatMoney(item.residual + invoice_interest, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            invoice_total : accounting.formatMoney(item.amount_total + invoice_interest, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+
+                            invoice_residual_no_format : item.residual,
+                            amount_no_format : index.debit,
+                            residual_no_format : index.amount_residual,
+
+                            decimal_places : CurrencyBase.decimal_places,
+                            thousands_separator : CurrencyBase.thousands_separator,
+                            decimal_separator : CurrencyBase.decimal_separator,
+                        });
+                    };
+                });
+              });
+
+            data.sort(function (a, b) {
+              var x = moment(a.date,'DD/MM/YYYY').format('YYYY-MM-DD');
+              var y = moment(b.date,'DD/MM/YYYY').format('YYYY-MM-DD');
+                if (x > y) {
+                    return -1;
+                }
+                if (x < y) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var total = totalAmountFormatter(row);
+            var residual = totalResidualFormatter(row);
+
+            row.push({
+                partner_ruc : 'Totales',
+                amount : total,
+                residual : residual,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Análisis de Cuotas de Proveedor';
+                var pdf_type = 'l';
+                var pdf_name = 'analisis_de_cuotas_proveedor_';
+                var pdf_columnStyles = {
+                    partner_ruc :{columnWidth: 17, halign:'center'},
+                    partner_name :{columnWidth: 17,halign:'left'},
+                    invoice :{columnWidth: 24, halign:'center'},
+                    supplier_invoice_number:{columnWidth: 24, halign:'center'},
+                    date_invoice : {columnWidth: 22, halign:'center'},
+                    name :{columnWidth: 20, halign:'center'},
+                    date : {columnWidth: 22, halign:'center'},
+                    state : {columnWidth: 18, halign:'center'},
+                    days_of_delays : {columnWidth:16,halign:'center'},
+                    amount : {columnWidth: 22, halign:'right'},
+                    due_interest:{columnWidth:22,halign:'right'},
+                    residual : {columnWidth: 22, halign:'right'},
+                    invoice_total : {columnWidth: 21, halign:'right'},
+                    invoice_residual : {columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter =self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var state = self.$el.find('#current-state').val();
+          var period = self.$el.find('#current-period').val();
+          var journal = self.$el.find('#current-journal').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+
+          }
+          if(state && state != 9999999){
+            filter.push({
+                title: 'Estado',
+                value:  $("#current-state option:selected").text(),
+            });
+          }
+
+          if(period && period != 9999999){
+
+            var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+                return item.id == period;
+            });
+            filter.push({
+                 title: 'Periodo',
+                 value:  AccountPeriod[0].name,
+               });
+          }
+
+          if(journal && journal != 9999999){
+            var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                return item.id == journal;
+            });
+            filter.push({
+                 title: 'Factura',
+                 value: AccountJournal[0].name,
+               });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        },
+    });
+}

+ 512 - 0
static/src/js/reports/report_expense.js

@@ -0,0 +1,512 @@
+function report_expense(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportExpenseWidget = reporting.Base.extend({
+        template: 'ReportExpense',
+        rowsData :[],
+        content :[],
+
+        events:{
+            'click #generate':'fetchGenerate',
+            'change #current-company':'updateSelections',
+            'change #current-date':'ShowDateRange',
+            'click .print-report':'clickOnAction',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                if(self.AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(self.AccountJournal,function(item){
+                        if(item.type == 'sale'){
+                            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                        }
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                /*
+                =================================
+                    RES USERS
+                =================================
+                */
+                self.ResUsers = IntialSQL.users;
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var ResUsers = _.flatten(_.filter(self.ResUsers,function (item) {
+                    return _.contains(store_ids, item.store_id);
+                }));
+                if(ResUsers.length > 1){
+                    self.$el.find('#current-user').append('<option value="9999999">Todos los Responsables</option>');
+                    _.each(ResUsers,function(item){
+                        self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoice = DataSQL.invoices;
+                self.PosOrder = DataSQL.orders;
+                self.AccountVoucher = DataSQL.vouchers;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-expense-history');
+            return data;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getAccountInvoice:function() {
+            var self = this;
+            var content = self.AccountInvoice;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var user = self.$el.find('#current-user').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                return item.id;
+            }));
+
+            var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                return item.id;
+            }));
+
+            content = _.flatten(_.filter(content,function (item) {
+                return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+            }));
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(state && state != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.state == state;
+                }));
+            }
+            if(user && user != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.user_id == user;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getAccountVoucher: function (number) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.reference == number;
+            });
+        },
+
+        BuildTable: function(){
+            var self = this;
+
+            var data = [];
+            var residual = 0;
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            var AccountInvoice = self.getAccountInvoice();
+            _.each(AccountInvoice, function(item){
+                residual = 0;
+                if(item.state == 'open'){
+                    residual = self.getAccountVoucher(item.number);
+                    residual =  _.reduce(_.map(residual,function(item){
+                        return item.amount_currency;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    residual = item.amount - residual;
+                }
+                data.push({
+                    /*
+                    =======================
+                        IDS
+                    =======================
+                    */
+                    id:item.id,
+                    /*
+                    =======================
+                        INFO
+                    =======================
+                    */
+                    origin:item.origin,
+                    supplier_invoice_number:item.supplier_invoice_number,
+                    number:item.number,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    user_name:item.user_name,
+                    user_id:item.user_id,
+                    customer_ruc:self.valorNull(item.supplier_ruc),
+                    supplier_name:self.valorNull(item.supplier_name),
+                    residual:accounting.formatMoney(residual,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    untaxed:accounting.formatMoney(item.amount - item.amount_tax,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.amount_tax,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    /*
+                    =======================
+                        NO FORMAT
+                    =======================
+                    */
+                    date_no_format: moment(item.date).format('YYYY-MM-DD'),
+                    residual_no_format:residual,
+                    untaxed_no_format:item.amount - item.amount_tax,
+                    tax_no_format:item.amount_tax,
+                    total_no_format:item.amount,
+                    /*
+                    =======================
+                        FOOTER
+                    =======================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.CompanyLogo,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = ResCompany[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var residual = ResidualFooter(row);
+            var untaxed = UntaxedFooter(row);
+            var tax = TaxFooter(row);
+            var total = TotalFooter(row);
+
+            row.push({
+                number:'Totales',
+                residual:residual,
+                untaxed:untaxed,
+                tax:tax,
+                total:total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Facturas de Gastos.';
+                var pdf_type = '';
+                var pdf_name = 'facturas_de_gastos_';
+                var pdf_columnStyles = {
+                    number:{columnWidth: 29,halign:'left'},
+                    date:{halign:'center'},
+                    user_name:{ halign:'left'},
+                    customer_ruc:{columnWidth:12, halign:'left'},
+                    supplier_name:{columnWidth: 30, halign:'left'},
+                    residual:{columnWidth: 20, halign:'right'},
+                    untaxed:{columnWidth: 20, halign:'right'},
+                    tax:{columnWidth: 20, halign:'right'},
+                    total:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                        return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(state && state != 9999999){
+                filter.push({
+                    title: 'Estado',
+                    value: $('#current-state option:selected').text(),
+                });
+            }
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 638 - 0
static/src/js/reports/report_expense_analytic.js

@@ -0,0 +1,638 @@
+function report_expense_analytic(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportExpenseAnalyticWidget = reporting.Base.extend({
+        template: 'ReportExpenseAnalytic',
+        rowsData :[],
+        content :[],
+        modules: ['product_brand'],
+
+        events:{
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-attribute' : 'updateAttributeSelections',
+            'change #current-date' : 'ShowDateRange',
+            'click .print-report':'clickOnAction',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModule : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    PRODUCT CATEGORY
+                =================================
+                */
+                self.ProductCategory = IntialSQL.categories;
+                if(self.ProductCategory.length > 1){
+                    self.$el.find('#current-category').append('<option value="9999999">Todas las Categorias</option>');
+                    _.each(self.ProductCategory,function(item){
+                        self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }
+                self.ProductBrand = IntialSQL.brands;
+                if(self.ProductBrand.length > 1){
+                    self.$el.find('#current-brand').append('<option value="9999999">Todas las Marcas</option>');
+                    _.each(self.ProductBrand,function(item){
+                        self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.brand').css('display','none');
+                }
+                self.ProductAttribute = IntialSQL.attributes;
+                if(self.ProductAttribute.length > 1){
+                    self.$el.find('#current-attribute').append('<option value="9999999">Todos los atributos</option>');
+                    _.each(self.ProductAttribute,function(item){
+                        self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute').css('display','none');
+                }
+                self.ProductAttributeValue = IntialSQL.attribute_values;
+                if(self.ProductAttributeValue.length > 1){
+                    self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                    _.each(self.ProductAttributeValue,function(item){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute-value').css('display','none');
+                }
+                return self.fetchIrModuleModule();
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoiceLine = DataSQL.invoice_lines;
+                self.AccountInvoice = DataSQL.invoices;
+                return self.BuildTable();
+            });
+       },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-expense-analytic');
+            return data;
+        },
+
+        fetchIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*
+        ====================================================================
+            UPDATE SELECTIONS
+        ====================================================================
+        */
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateAttributeSelections: function () {
+            var self = this;
+            var attribute_value;
+            var attribute = self.$el.find('#current-attribute').val();
+            if(attribute != 9999999){
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    if(parseFloat(attribute) == item.attribute_id){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getProductCategory: function (id) {
+            var self = this;
+            var category;
+            category =  _.filter(self.ProductCategory,function (item) {
+                return item.id == id;
+            });
+            if(category.length > 0)
+                return category[0].name;
+        },
+
+        getPhysicInvoice: function (id) {
+            var self = this;
+            var invoice;
+            invoice =  _.filter(self.AccountInvoice,function (item) {
+                return item.invoice_id == id;
+            });
+            if(invoice.length > 0)
+                return invoice[0].supplier_invoice_number;
+        },
+
+        getAccountInvoiceLine:function() {
+            var self = this;
+            var content = self.AccountInvoiceLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                return item.id;
+            }));
+
+            var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                return item.id;
+            }));
+
+            content = _.flatten(_.filter(content,function (item) {
+                return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+            }));
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            var display_name;
+            var modules = self.checkModule('product_brand');
+            var AccountInvoiceLine = self.getAccountInvoiceLine();
+
+            _.each(AccountInvoiceLine,function(item) {
+                var category = self.getProductCategory(item.categ_id);
+                var physic_invoice = self.getPhysicInvoice(item.invoice_id);
+                if(item.attribute_values[0] == null){
+                    display_name = item.product_name;
+                }else{
+                    display_name = item.product_name + ' (' + _.uniq(item.attribute_values) + ')';
+                }
+                if(modules.length > 0){
+                    if(item.product_brand_id != null){
+                        display_name = display_name + ' ( ' + item.brand_name + ')';
+                    }
+                }
+                data.push({
+                    id : item.invoice_line_id,
+                    supplier_invoice_number:physic_invoice,
+                    number:item.number,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    ruc : self.valorNull(item.partner_ruc),
+                    supplier_name:item.partner_name,
+                    product_name:item.name,
+                    product_category:category,
+                    price_unit:accounting.formatMoney(item.price_unit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    quantity:accounting.formatNumber(item.quantity,2,'.',','),
+                    untaxed:accounting.formatMoney(item.subtotal, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.subtotal + item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*
+                    =============================
+                        VALORES SIN FORMATEAR
+                    =============================
+                    */
+                    date_no_format:item.date,
+                    price_unit_no_fortmat:item.price_unit,
+                    quantity_no_format:item.quantity,
+                    untaxed_no_format:item.subtotal,
+                    tax_no_format:item.tax,
+                    total_no_format:item.subtotal + item.tax,
+                    /*
+                    ==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.CompanyLogo,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = ResCompany[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns = [];
+            var rows = [];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var price_unit = PriceUnitFooter(row);
+            var quantity = QuantityFooter(row);
+            var tax = TaxFooter(row);
+            var untaxed = UntaxedFooter(row);
+            var total = TotalFooter(row);
+
+            row.push({
+                number:'Totales',
+                price_unit:price_unit,
+                quantity:quantity,
+                tax:tax,
+                untaxed:untaxed,
+                total:total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Analisis de Gastos.';
+                var pdf_type = 'l';
+                var pdf_name = 'analisis_de_gastos_';
+                var pdf_columnStyles = {
+                    number:{columnWidth: 30, halign:'center'},
+                    supplier_invoice_number:{columnWidth: 20, halign:'center'},
+                    date:{columnWidth: 19, halign:'center'},
+                    ruc:{columnWidth: 20, halign:'center'},
+                    supplier_name:{halign:'center'},
+                    product_name:{columnWidth: 'auto', halign:'left'},
+                    product_category:{columnWidth: 40, halign:'left'},
+                    price_unit:{columnWidth: 20, halign:'right'},
+                    quantity:{columnWidth: 20, halign:'right'},
+                    untaxed:{columnWidth: 20, halign:'right'},
+                    tax:{columnWidth: 20, halign:'right'},
+                    total:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+               );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                    return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(category && category != 9999999){
+                var categ =  _.filter(self.ProductCategory,function (item) {
+                    return item.id == category;
+                });
+                filter.push({
+                    title: 'Categoría',
+                    value: categ[0].name,
+               });
+            }
+            if(brand && brand != 9999999){
+                var ProductBrand =  _.filter(self.ProductBrand,function (item) {
+                    return item.id == brand;
+                });
+                filter.push({
+                    title: 'Marca',
+                    value: ProductBrand[0].name,
+                });
+            }
+            if(attribute && attribute != 9999999){
+                var attr =  _.filter(self.ProductAttribute,function (item) {
+                    return item.id == attribute;
+                });
+                filter.push({
+                    title: 'Atributo',
+                    value: attr[0].name,
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                var attr_value =  _.filter(self.ProductAttributeValue,function (item) {
+                    return item.id == attribute_value;
+                });
+                filter.push({
+                    title: 'Valor de Atributo',
+                    value: attr_value[0].name,
+                });
+            }
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 881 - 0
static/src/js/reports/report_income_summary.js

@@ -0,0 +1,881 @@
+function report_income_summary(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportIncomeSummaryWidget = reporting.Base.extend({
+        template: 'ReportIncomeSummary',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model
+            });
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser();
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                // self.fecthCheckType();
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' +  item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+
+            this.fetchAccountVoucher().then(function(AccountVoucher) {
+                return AccountVoucher;
+            }).then(function (AccountVoucher) {
+                self.AccountVoucher = AccountVoucher;
+                return self.fetchAccountBankStatementLine();
+            }).then(function (AccountBankStatementLine) {
+                self.AccountBankStatementLine = AccountBankStatementLine;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                return item.id;
+            }));
+            var domain = [
+                ['active','=',true],
+                ['type','in',['bank','cash']],
+                ['store_ids','in',store_ids],
+            ];
+            if(company && company != 9999999){
+               domain.push(['company_id','=',parseInt(company)]);
+            }
+            if(store && store != 9999999){
+               domain.push(['store_ids','=',parseInt(store)]);
+            }
+            var AccountJournal = new model.web.Model('account.journal');
+            return AccountJournal.call('getAccountJournal',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT VOUCHER
+        =====================================================================*/
+        fetchAccountVoucher: function () {
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var domain = [['state','=','posted'],['type','=','receipt']];
+            var period = self.$el.find('#current-period').val();
+
+            if(period && period != 9999999){
+               domain.push(['period_id','=',parseInt(period)]);
+            }
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date','>=',date]);
+                    }
+
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD 00:00:00');
+                    domain.push(['date','>=',today]);
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD 00:00:00');
+                    domain.push(['date','>=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date','like',lastMonth]);
+                }
+            }
+            var AccountVoucher = new model.web.Model('account.voucher');
+            return AccountVoucher.call('getAccountVoucher',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*=====================================================================
+            ACCOUNT BANK STATEMENT LINE
+        =====================================================================*/
+        fetchAccountBankStatementLine: function () {
+            var self = this;
+            var modules = self.checkModel('point_of_sale');
+            if (modules.length > 0){
+                var store = self.$el.find('#current-store').val();
+                var date = self.$el.find('#current-date').val();
+                var desde = self.$el.find('#from').val();
+                var hasta = self.$el.find('#to').val();
+                var period = self.$el.find('#current-period').val();
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item;
+                }), function(map){
+                    return map.id;
+                });
+                var domain = [
+                    ['pos_statement_id','!=',false],
+                    ['journal_id','in',journal_ids],
+                ];
+                if(store && store != 9999999){
+                    var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                        return item.store_ids == store;
+                    }), function(map){
+                        return map.id;
+                    });
+                }else{
+                    var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                        return item.id;
+                    }));
+                }
+
+                if(period && period != 9999999){
+                    var data = _.filter(self.AccountPeriod,function (inv) {
+                        return inv.id == parseInt(period);
+                    });
+                    domain.push(['date','>=',data[0].date_start]);
+                    domain.push(['date','<=',data[0].date_stop]);
+                }
+
+                if(date && date != 9999999){
+                    if(date == 'range'){
+                        if(desde){
+                            var date = desde.split('/')
+                            date = (date[2]+"-"+date[1]+"-"+date[0]);
+                            domain.push(['date','>=',date]);
+                        }
+
+                        if(hasta){
+                            var date = hasta.split('/')
+                            date = (date[2]+"-"+date[1]+"-"+date[0]);
+                            domain.push(['date','<=',date]);
+                        }
+                    }
+
+                    if(date == 'today'){
+                        var today = moment().format('YYYY-MM-DD 00:00:00');
+                        domain.push(['date','>=',today]);
+                    }
+
+                    if(date == 'yesterday'){
+                        var yesterday = moment().add(-1,'days').format('YYYY-MM-DD 00:00:00');
+                        domain.push(['date','>=',yesterday]);
+                    }
+
+                    if(date == 'currentMonth'){
+                        var currentMonth = moment().format('YYYY-MM');
+                        domain.push(['date','like',currentMonth]);
+                    }
+
+                    if(date == 'lastMonth'){
+                        var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                        domain.push(['date','like',lastMonth]);
+                    }
+                }
+                var AccountBankStatementLine = new model.web.Model('account.bank.statement.line');
+                return AccountBankStatementLine.call('getAccountBankStatementLine',[domain], {
+                    context: new model.web.CompoundContext()
+                });
+            }else{
+                var AccountBankStatementLine = [];
+                return AccountBankStatementLine;
+            }
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            return ResCurrency.call('getResCurrency',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT JOURNAL
+        ====================================================================*/
+        getAccountJournal: function (id) {
+            var self = this;
+            return _.filter(self.AccountJournal,function (item) {
+                return item.store_ids[0] === id;
+            })
+        },
+        /*====================================================================
+            GET ACCOUNT VOUCHER
+        ====================================================================*/
+        getAccountVoucher: function (id) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.journal_id[0] === id;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT BANK STATEMENT LINE
+        ====================================================================*/
+        getAccountAccountBankStatementLine: function (id) {
+            var self = this;
+            return _.filter(self.AccountBankStatementLine,function (item) {
+                return item.journal_id[0] === id;
+            })
+        },
+
+        /*====================================================================
+            GET RES STORE
+        ====================================================================*/
+        getResStore: function () {
+            var self = this;
+            var content = self.ResStore;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.company_id[0] === parseInt(company);
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.id === parseInt(store);
+                }));
+            }
+            return content;
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var info = [];
+            var ResStore = self.getResStore();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            };
+            _.each(ResStore,function(item) {
+                var AccountJournal = self.getAccountJournal(item.id);
+                info = [];
+                _.each(AccountJournal,function(index) {
+                    var AccountVoucher = self.getAccountVoucher(index.id);
+                    var AccountBankStatementLine = self.getAccountAccountBankStatementLine(index.id);
+                    /*
+                    ====================================================
+                        AMOUNT IN CURRENCY BASE
+                    ====================================================
+                    */
+                    var voucher_amount_currency = _.reduce(_.map(AccountVoucher, function (map) {
+                        return map.amount_currency
+                    }), function (meno,num) {
+                        return meno + num
+                    }, 0);
+                    var account_bank_statement_line_amount_currency = _.reduce(_.map(AccountBankStatementLine, function (map) {
+                        return map.amount_currency
+                    }), function (meno,num) {
+                        return meno + num
+                    }, 0);
+                    /*
+                    ====================================================
+                        AMOUNT IN CURRENCY
+                    ====================================================
+                    */
+                    if(index.currency[0]){
+                        var voucher_amount = _.reduce(_.map(AccountVoucher, function (map) {
+                            return map.amount
+                        }), function (meno,num) {
+                            return meno + num
+                        }, 0);
+                        var account_bank_statement_line_amount = _.reduce(_.map(AccountBankStatementLine, function (map) {
+                            return map.amount
+                        }), function (meno,num) {
+                            return meno + num
+                        }, 0);
+                    }
+                    /*
+                    ====================================================
+                        TOTAL IN CURRENCY BASE
+                    ====================================================
+                    */
+                    var amount_currency = voucher_amount_currency + account_bank_statement_line_amount_currency;
+                    /*
+                    ====================================================
+                        TOTAL IN CURRENCY
+                    ====================================================
+                    */
+                    var amount = voucher_amount + account_bank_statement_line_amount;
+                    if(AccountVoucher.length > 0 || AccountBankStatementLine.length > 0){
+                        var currency = self.getResCurrency(index.currency[0]).shift();
+                        var total = 0;
+                        if(index.currency[0]){
+                            total = accounting.formatMoney(amount_currency,'',CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '    (' + accounting.formatMoney(amount,'',currency.decimal_places, currency.thousands_separator, currency.decimal_separator) + ')';
+                        }else{
+                            total = accounting.formatMoney(amount_currency,'',CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        }
+                        info.push({
+                            journal : index.complete_name,
+                            amount_total : total,
+                            amount : amount_currency,
+
+                            decimal_places : CurrencyBase.decimal_places,
+                            thousands_separator: CurrencyBase.thousands_separator,
+                            decimal_separator: CurrencyBase.decimal_separator,
+                        });
+                        info.sort(function(a, b) {
+                            return b.amount - a.amount
+                        });
+                    }
+                });
+                var total_amount = _.reduce(_.map(info, function (map) {
+                    return map.amount
+                }), function (meno,num) {
+                    return meno + num
+                }, 0);
+                if(total_amount > 0){
+                    data.push({
+                        store: item.name,
+                        amount_total: accounting.formatMoney(total_amount, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        amount: total_amount,
+                        /*==============================
+                            TOTAL FOOTER CONFIGURATION
+                        ==============================*/
+                        decimal_places : CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+                        /*
+                        ================================
+                            DATA
+                        ================================
+                        */
+                        info: info,
+                    });
+                }
+            });
+            data.sort(function(a, b) {
+                return b.amount - a.amount
+            });
+            self.content = data;
+            if(ResStore.length > 1){
+                self.loadTable(data,ResStore.length);
+            }
+            else{
+                self.loadTable(info,ResStore.length);
+            }
+
+            self.CallCharts(data,CurrencyBase);
+        },
+
+        /*
+        ======================================================================
+            LLAMAR LOS GRAFICOS
+        ======================================================================
+        */
+        CallCharts: function(data,CurrencyBase){
+            var self = this;
+            /*
+            ================================================
+            GRAFICO DE BARRAS
+            ================================================
+            */
+            var BarChart = new reporting.ReportChartWidget(self);
+            var item;
+            var label = [];
+            var body = [];
+            for (var i = 0; i < data.length; i++) {
+                if (data[i]){
+                    item = data[i];
+                }else{
+                    item = {};
+                    item.store = "N/A";
+                    item.amount = 0;
+                }
+                label.push(item.store.trim());
+                body.push(item.amount);
+            }
+            BarChart.BuildBarChart(data,CurrencyBase,label,body);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable, ResStore){
+            var self = this;
+            var table = self.$el.find('#table');
+            table.bootstrapTable('destroy');
+
+            if(ResStore > 1){
+              table.bootstrapTable({
+                  data: rowsTable,
+                  columns: [{
+                      field: 'store',
+                      title: 'Sucursal',
+                      footerFormatter: 'Totales',
+                  },
+                  {
+                      field: 'amount_total',
+                      title: 'Total',
+                      footerFormatter: totalFormatter,
+                  }],
+
+                  detailView: true,
+                  detailFormatter:detailFormatter,
+              });
+              self.$el.find('.chart-container').css('display','block');
+            }
+            else{
+              table.bootstrapTable({
+                  data: rowsTable,
+                  columns: [{
+                      field: 'journal',
+                      title: 'Método de pago',
+                      footerFormatter: 'Totales',
+                  },
+                  {
+                      field: 'amount_total',
+                      title: 'Total',
+                      footerFormatter: totalFormatter,
+                  }],
+              });
+              self.$el.find('.chart-container').css('display','none');
+            }
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var amount = totalFormatter(row);
+
+            row.push({
+                store: 'Totales',
+                journal: 'Totales',
+                amount_total: amount,
+            })
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Resumen de Ingresos';
+                var pdf_type = '';
+                var pdf_name = 'resumen_ingresos_';
+                var pdf_columnStyles =  {
+                    store:{halign:'left'},
+                    amount_total:{columnWidth: 50, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+
+                var ResStore = self.getResStore();
+                if(ResStore.length > 1){
+                    pdf.drawWithDetails(
+                        _.flatten(getColumns),
+                        row,
+                        ResCompany,
+                        pdf_title,
+                        pdf_type,
+                        pdf_name,
+                        pdf_columnStyles,
+                        amount,
+                    );
+                }
+                else{
+                  pdf.drawPDF(
+                      _.flatten(getColumns),
+                      row,
+                      ResCompany,
+                      pdf_title,
+                      pdf_type,
+                      pdf_name,
+                      pdf_columnStyles,
+                      filter,
+                  );
+                }
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var period = self.$el.find('#current-period').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+
+          }
+
+          if(period && period != 9999999){
+
+            var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+                return item.id == period;
+            });
+            filter.push({
+                 title: 'Periodo',
+                 value:  AccountPeriod[0].name,
+               });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        },
+    });
+}

+ 727 - 0
static/src/js/reports/report_outcome_summary.js

@@ -0,0 +1,727 @@
+function report_outcome_summary(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportOutcomeSummaryWidget = reporting.Base.extend({
+        template: 'ReportOutcomeSummary',
+        content :[],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser();
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' +  item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+
+            this.fetchAccountVoucher().then(function(AccountVoucher) {
+                return AccountVoucher;
+            }).then(function (AccountVoucher) {
+                self.AccountVoucher = AccountVoucher;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed']];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                return item.id;
+            }));
+            var domain = [
+                ['active','=',true],
+                ['type','in',['bank','cash']],
+                ['store_ids','in',store_ids],
+            ];
+            if(company && company != 9999999){
+               domain.push(['company_id','=',parseInt(company)]);
+            }
+            if(store && store != 9999999){
+               domain.push(['store_ids','=',parseInt(store)]);
+            }
+            var AccountJournal = new model.web.Model('account.journal');
+            return AccountJournal.call('getAccountJournal',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT VOUCHER
+        =====================================================================*/
+        fetchAccountVoucher: function () {
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var domain = [['state','=','posted'],['type','=','payment']];
+            var period = self.$el.find('#current-period').val();
+
+            if(period && period != 9999999){
+               domain.push(['period_id','=',parseInt(period)]);
+            }
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date','>=',date]);
+                    }
+
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD 00:00:00');
+                    domain.push(['date','>=',today]);
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD 00:00:00');
+                    domain.push(['date','>=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date','like',lastMonth]);
+                }
+            }
+            var AccountVoucher = new model.web.Model('account.voucher');
+            return AccountVoucher.call('getAccountVoucher',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            return ResCurrency.call('getResCurrency',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT JOURNAL
+        ====================================================================*/
+        getAccountJournal: function (id) {
+            var self = this;
+            return _.filter(self.AccountJournal,function (item) {
+                return item.store_ids[0] === id;
+            })
+        },
+        /*====================================================================
+            GET ACCOUNT VOUCHER
+        ====================================================================*/
+        getAccountVoucher: function (id) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.journal_id[0] === id;
+            })
+        },
+
+        /*====================================================================
+            GET RES STORE
+        ====================================================================*/
+        getResStore: function () {
+            var self = this;
+            var content = self.ResStore;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.company_id[0] === parseInt(company);
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.id === parseInt(store);
+                }));
+            }
+            return content;
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var info = [];
+            var ResStore = self.getResStore();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            };
+            _.each(ResStore,function(item) {
+                var AccountJournal = self.getAccountJournal(item.id);
+                  var amount_store = 0;
+                  info = [];
+                _.each(AccountJournal,function(index) {
+
+                    var amount_voucher = 0;
+                      var AccountVoucher = self.getAccountVoucher(index.id);
+                    _.each(AccountVoucher, function(each){
+                      amount_voucher = amount_voucher + each.amount;
+                    });
+                    if(amount_voucher > 0){
+                    info.push({
+                        journal : index.complete_name,
+                        amount_total : accounting.formatMoney(amount_voucher, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+
+                        amount_no_format : amount_voucher,
+
+                        decimal_places : CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+
+                    });
+                  }
+
+                    amount_store = amount_store + amount_voucher;
+                });
+                info.sort(function(a, b) {
+                    return b.amount_voucher_not_format - a.amount_voucher_not_format
+                });
+
+                if(amount_store > 0){
+                    data.push({
+                        store: item.name,
+                        amount_total: accounting.formatMoney(amount_store, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+
+                        amount_no_format : amount_store,
+
+                        decimal_places : CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+
+                        info: info,
+                    });
+                }
+            });
+            data.sort(function(a, b) {
+                return b.amount_store_no_format - a.amount_store_no_format
+            });
+
+            self.content = data;
+            if(ResStore.length > 1){
+                self.loadTable(data,ResStore.length);
+            }
+            else{
+                self.loadTable(info,ResStore.length);
+            }
+
+            self.CallCharts(data,CurrencyBase);
+
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable, ResStore){
+            var self = this;
+            var table = self.$el.find('#table');
+            table.bootstrapTable('destroy');
+
+            if(ResStore > 1){
+              table.bootstrapTable({
+                  data: rowsTable,
+                  columns: [{
+                      field: 'store',
+                      title: 'Sucursal',
+                      footerFormatter: 'Totales',
+                  },
+                  {
+                      field: 'amount_total',
+                      title: 'Total',
+                      footerFormatter: totalFormatter,
+                  }],
+
+                  detailView: true,
+                  detailFormatter:detailFormatter,
+              });
+              self.$el.find('.chart-container').css('display','block');
+            }
+            else{
+              table.bootstrapTable({
+                  data: rowsTable,
+                  columns: [{
+                      field: 'journal',
+                      title: 'Método de pago',
+                      footerFormatter: 'Totales',
+                  },
+                  {
+                      field: 'amount_total',
+                      title: 'Total',
+                      footerFormatter: totalFormatter,
+                  }],
+              });
+              self.$el.find('.chart-container').css('display','none');
+            }
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*
+        ======================================================================
+            LLAMAR LOS GRAFICOS
+        ======================================================================
+        */
+        CallCharts: function(data,CurrencyBase){
+            var self = this;
+            /*
+            ================================================
+            GRAFICO DE BARRAS
+            ================================================
+            */
+            var BarChart = new reporting.ReportChartWidget(self);
+            var item;
+            var label = [];
+            var body = [];
+            for (var i = 0; i < data.length; i++) {
+                if (data[i]){
+                    item = data[i];
+                }else{
+                    item = {};
+                    item.store = "N/A";
+                    item.amount_no_format = 0;
+                }
+                label.push(item.store.trim());
+                body.push(item.amount_no_format);
+            }
+            BarChart.BuildBarChart(data,CurrencyBase,label,body);
+             self.$el.find('.report-form').css('display','block');
+             self.$el.find('.search-form').unblock();
+             self.$el.find('.report-form').unblock();
+
+        },
+
+
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find('#table');
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var amount = totalFormatter(row);
+
+            row.push({
+                store: 'Totales',
+                journal: 'Totales',
+                amount_total: amount,
+            })
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Resumen de Egresos';
+                var pdf_type = '';
+                var pdf_name = 'resumen_egresos_';
+                var pdf_columnStyles =  {
+                    store:{halign:'left'},
+                    amount_total:{columnWidth: 50, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+
+                var ResStore = self.getResStore();
+                if(ResStore.length > 1){
+                  pdf.drawWithDetails(
+                      _.flatten(getColumns),
+                      row,
+                      ResCompany,
+                      pdf_title,
+                      pdf_type,
+                      pdf_name,
+                      pdf_columnStyles,
+                      amount,
+                  );
+                }
+                else{
+                  pdf.drawPDF(
+                      _.flatten(getColumns),
+                      row,
+                      ResCompany,
+                      pdf_title,
+                      pdf_type,
+                      pdf_name,
+                      pdf_columnStyles,
+                      filter,
+                  );
+                }
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var period = self.$el.find('#current-period').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+
+          }
+
+          if(period && period != 9999999){
+
+            var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+                return item.id == period;
+            });
+            filter.push({
+                 title: 'Periodo',
+                 value:  AccountPeriod[0].name,
+               });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        },
+    });
+}

+ 1060 - 0
static/src/js/reports/report_product_list.js

@@ -0,0 +1,1060 @@
+function report_product_list(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportProductListWidget = reporting.Base.extend({
+        template: 'ReportProductList',
+        rowsData :[],
+        content :[],
+        modules: ['product_brand'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+            'change #current-company' : 'updateSelections',
+            'change #current-attribute' : 'updateAttributeSelections',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model
+            });
+        },
+
+        clickAnalysisDetail: function(e, row, $element,field){
+            if (field == 'name'){
+                this.do_action({
+                    name:"Producto",
+                    type: 'ir.actions.act_window',
+                    res_model: "product.product",
+                    views: [[false,'form']],
+                    target: 'new',
+                    domain: [['id','=', row.id]],
+                    context: {},
+                    flags: {'form': {'action_buttons': false, 'options': {'mode': 'view'}}},
+                    res_id: row.id,
+                });
+            }
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser();
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchProductCategory();
+            }).then(function(ProductCategory){
+                self.ProductCategory = ProductCategory;
+                self.$el.find('#current-category').append('<option value="9999999">Todas las categorias</option>');
+                _.each(ProductCategory,function(item){
+                    self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.complete_name + '</option>');
+                });
+                return self.fetchProductBrand();
+            }).then(function(ProductBrand){
+                self.ProductBrand = ProductBrand;
+                if(ProductBrand.length > 0){
+                    self.$el.find('#current-brand').append('<option value="9999999">Todas las marcas</option>');
+                    _.each(ProductBrand,function(item){
+                        self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.brand').css('display','none');
+                }
+                return self.fetchProductAttribute();
+            }).then(function(ProductAttribute){
+                self.ProductAttribute = ProductAttribute;
+                if(ProductAttribute.length > 0){
+                    self.$el.find('#current-attribute').append('<option value="9999999">Todos los atributos</option>');
+                    _.each(ProductAttribute,function(item){
+                        self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute').css('display','none');
+                }
+                return self.fetchProductAttributeValue();
+            }).then(function(ProductAttributeValue){
+                self.ProductAttributeValue = ProductAttributeValue;
+                if(ProductAttributeValue.length > 0){
+                    self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                    _.each(ProductAttributeValue,function(item){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute-value').css('display','none');
+                }
+                return self.fetchProductPriceList();
+            }).then(function(ProductPriceList){
+                self.ProductPriceList = ProductPriceList;
+                if(ProductPriceList.length > 0){
+                  var sale = _.filter(ProductPriceList,function (item) {
+                      return item.type == 'sale';
+                  });
+                  var purchase = _.filter(ProductPriceList,function (item) {
+                      return item.type == 'purchase';
+                  });
+                  self.$el.find('#current-sale-price').append('<option value="9999999">Precio Base</option>');
+                  _.each(sale,function(item){
+                      self.$el.find('#current-sale-price').append('<option value="' + item.id + '">' + item.name + '</option>');
+                  });
+
+                  self.$el.find('#current-purchase-price').append('<option value="9999999">Precio Base</option>');
+                  _.each(purchase,function(item){
+                      self.$el.find('#current-purchase-price').append('<option value="' + item.id + '">' + item.name + '</option>');
+                  });
+               }else{
+                  self.$el.find('.salePrice').css('display','none');
+                  self.$el.find('.buyPrice').css('display','none');
+              }
+                return self.fetchPricelistVersion();
+            }).then(function(PricelistVersion){
+                self.PricelistVersion = PricelistVersion;
+                return self.fetchPricelistVersionItem();
+            }).then(function(PricelistVersionItem){
+                self.PricelistVersionItem = PricelistVersionItem;
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+                return self.fetchProductTemplate();
+            }).then(function(ProductTemplate){
+                self.ProductTemplate = ProductTemplate;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchProductProduct().then(function(ProductProduct) {
+                return ProductProduct;
+            }).then(function (ProductProduct) {
+                self.ProductProduct = ProductProduct;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            PRICE LIST
+        =====================================================================*/
+        fetchProductPriceList: function() {
+            var self = this;
+            var domain = [];
+            var ProductProduct = new model.web.Model('product.pricelist');
+            return ProductProduct.call('getProductPriceList',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*=====================================================================
+            PRICE LIST VERSION
+        =====================================================================*/
+        fetchPricelistVersion: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','listprice_id','items_id','date_start','date_end'];
+            var domain = [['active','=',true]];
+            var ResUser = new model.web.Model('product.pricelist.version');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            PRICE LIST VERSION ITEMS
+        =====================================================================*/
+        fetchPricelistVersionItem: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','product_id','categ_id','min_quantity','product_tmpl_id','sequence','base','price_discount','price_surcharge','price_round','price_min_margin','price_max_margin'];
+            var ResUser = new model.web.Model('product.pricelist.item');
+            ResUser.query(fields).filter().all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*====================================================================
+            PRODUCT TEMPLATE
+        ====================================================================*/
+        fetchProductTemplate: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','product_variant_ids','store_id'];
+            var domain =[
+              ['active','=', true],
+              ['sale_ok','=',true]];
+
+            var ProductTemplate = new model.web.Model('product.template');
+            ProductTemplate.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            PRODUCT CATEGORY
+        ====================================================================*/
+        fetchProductCategory : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','parent_id','complete_name'];
+            var ProductCategory = new model.web.Model('product.category');
+            ProductCategory.query(fields).filter().all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*====================================================================
+            PRODUCT BRAND
+        ====================================================================*/
+        fetchProductBrand : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var modules = self.checkModel('product_brand');
+            if (modules.length > 0){
+                var fields = ['id','name'];
+                var ProductBrand = new model.web.Model('product.brand');
+                ProductBrand.query(fields).filter().all().then(function(results) {
+                    defer.resolve(results);
+                });
+                return defer;
+            }else{
+                var ProductBrand = [];
+                return ProductBrand;
+            }
+        },
+
+        /*====================================================================
+            PRODUCT ATTRIBUTE
+        ====================================================================*/
+        fetchProductAttribute : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name'];
+            var ProductAttribute = new model.web.Model('product.attribute');
+            ProductAttribute.query(fields).filter().all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            PRODUCT ATTRIBUTE VALUE
+        ====================================================================*/
+        fetchProductAttributeValue : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','attribute_id'];
+            var ProductAttributeValue = new model.web.Model('product.attribute.value');
+            ProductAttributeValue.query(fields).filter().all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES PARTNER
+        ====================================================================*/
+        fetchProductProduct: function() {
+            var self = this;
+            var categ_ids = [];
+            var templates_ids =[];
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var state1 = self.$el.find('#current-state1').val();
+            var type = self.$el.find('#current-type').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var domain = [
+                ['active', '=', true],
+                ['sale_ok','=',true],
+            ];
+
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseInt(company)]);
+            }
+
+            if(store && store != 9999999){
+                _.map(_.filter(self.ProductTemplate, function (item) {
+                  return item.store_id[0] == store;
+                }), function(map){
+
+                    if(map.product_variant_ids.length > 1){
+                        _.each(map.product_variant_ids, function(each){
+                            templates_ids.push(each);
+                        });
+                    }else{
+                        templates_ids.push(map.product_variant_ids[0]);
+                    }
+                });
+                domain.push(['id','in', templates_ids]);
+            }
+
+            if(state && state != 9999999){
+              if(state == 'available'){
+                domain.push(['qty_available','>',0]);
+              }
+              if(state == 'unavailable'){
+                domain.push(['qty_available','<=',0]);
+              }
+            }
+
+            if(type && type != 9999999){
+              domain.push(['type','=',type]);
+            }
+
+            if(category){
+              // Nivel 0, nivel 1
+              var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                  return item.id == category || item.parent_id[0] == category;
+              }), function(map){
+                  return map.id;
+              });
+
+              // Nivel 0, nivel 1, nivel 2
+              var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                  return _.contains(category_ids, item.parent_id[0]) || item.id == category;
+              }), function(map){
+                  return map.id;
+              });
+
+              // Nivel 0, nivel 1, nivel 2, nivel 3
+              var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                  return _.contains(category_children_ids, item.parent_id[0]) || item.id == category;
+              }), function(map){
+                  return map.id;
+              }) ;
+
+              // Nivel 0, nivel 1, nivel 2, nivel 3, nivel 4
+              categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                  return _.contains(category_grandchildren_ids, item.parent_id[0]) || item.id == category;
+              }), function(map){
+                  return map.id;
+              });
+            }
+
+            if(category && category != 9999999){
+              domain.push(['categ_id','in',categ_ids]);
+            }
+
+            if(brand && brand != 9999999){
+              domain.push(['product_brand_id','=',parseInt(brand)]);
+            }
+
+            var attribute_ids = _.map(_.filter(self.ProductAttribute,function (item) {
+              return item.id == attribute;
+            }), function(map){
+              return map.id;
+           });
+
+           var attribute_value_ids = _.map(_.filter(self.ProductAttributeValue,function (item) {
+              return item.id == attribute_value;
+            }), function(map){
+              return map.id;
+           });
+
+           if(attribute && attribute != 9999999){
+             domain.push(['attribute_line_ids.attribute_id', 'in', attribute_ids]);
+           }
+
+           if(attribute_value && attribute_value != 9999999){
+             domain.push(['attribute_value_ids', 'in', attribute_value_ids]);
+           }
+
+           var ProductProduct = new model.web.Model('product.product');
+           return ProductProduct.call('getProductProduct',[domain], {
+                context: new model.web.CompoundContext()
+           });
+        },
+
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateAttributeSelections: function () {
+            var self = this;
+            var attribute = self.$el.find('#current-attribute').val();
+            if(attribute != 9999999){
+                /*=============================
+                    ATTRIBUTE VALUE SELECTION
+                =============================*/
+                var attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    if(parseFloat(attribute) == item.attribute_id[0]){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ATTRIBUTE VALUE SELECTION
+                =============================*/
+                var attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+
+
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        getPricelistVersion: function(id){
+          var self = this;
+          return _.filter(self.PricelistVersion,function (item) {
+              return item.id === id;
+          })
+        },
+
+        getPricelistVersionItem: function(id){
+          var self = this;
+          var item= _.filter(self.PricelistVersionItem,function (item) {
+              return item.id === id;
+
+          })
+            return item[0];
+        },
+
+        getProductSalePrice: function(product){
+          var self = this;
+          var r;
+          var CurrencyBase;
+          var today = moment().format('YYYY-MM-DD');
+          var salePrice = self.$el.find('#current-sale-price').val();
+          var company = self.$el.find('#current-company').val();
+
+          if(company && company != 9999999){
+              var ResCompany = self.getResCompany(company).shift();
+              CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+          }else{
+              CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+          }
+
+          if(salePrice && salePrice != 9999999){
+            var priceList= _.filter(self.ProductPriceList,function (item) {
+              return item.id == salePrice;
+            });
+
+            var x = _.map(priceList, function(map){
+              if(map.version_id.length > 0){
+                _.each(map.version_id, function(v){
+                  var version = self.getPricelistVersion(v);
+                  var date_start = version.date_start;
+                  var date_end = version.date_end;
+                  r= _.filter(version, function(a){
+                    return ((a.date_start == false) || (a.date_start <= today)) && ((a.date_end == false) || (a.date_end >= today));
+                  });
+                });
+
+                var item=  _.map(r[0].items_id,function(i){
+                  return self.getPricelistVersionItem(i);
+                });
+
+                var items =[];
+                var items2 = [];
+                _.each(item, function(index){
+                  if(index.product_tmpl_id && index.product_tmpl_id[0] == product.product_tmpl_id){
+                    items.push(index);
+                  }
+                  if(index.sequence > 1) {
+                    items2.push(index);
+                  }
+                });
+
+                if(items.length > 0){
+                  return items[0];
+                }
+                else{
+                  if(items2.length > 0){
+                    items2.sort(function(a, b) {
+                      return a.sequence - b.sequence
+                    });
+                    return items2[0];
+                  }
+                }
+              }
+            });
+            if(CurrencyBase.id == priceList[0].currency_id.id){
+              return product.lst_price*(1+x[0].price_discount)+x[0].price_surcharge;
+            }
+            else {
+              return (product.lst_price*priceList[0].currency_id.rate_silent)*(1+x[0].price_discount)+x[0].price_surcharge;
+            }
+          }
+          else{
+            return product.lst_price;
+          }
+        },
+
+        getProductBuyPrice: function(product){
+          var self = this;
+          var r;
+          var CurrencyBase;
+          var today = moment().format('YYYY-MM-DD');
+          var company = self.$el.find('#current-company').val();
+          var purchasePrice = self.$el.find('#current-purchase-price').val();
+
+          if(company && company != 9999999){
+              var ResCompany = self.getResCompany(company).shift();
+              CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+          }else{
+              CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+          }
+
+          if(purchasePrice && purchasePrice != 9999999){
+            var priceList = _.filter(self.ProductPriceList,function (item) {
+              return item.id == purchasePrice;
+            });
+
+            var x = _.map(priceList, function(map){
+              if(map.version_id.length > 0){
+                _.each(map.version_id, function(v){
+                  var version = self.getPricelistVersion(v);
+                  var date_start = version.date_start;
+                  var date_end = version.date_end;
+                  r= _.filter(version, function(a){
+                    return ((a.date_start == false) || (a.date_start <= today)) && ((a.date_end == false) || (a.date_end >= today));
+                  });
+                });
+
+                var item=  _.map(r[0].items_id,function(i){
+                  return self.getPricelistVersionItem(i);
+                });
+                var items =[];
+                var items2 = [];
+                _.each(item, function(index){
+                  if(index.product_tmpl_id && index.product_tmpl_id[0] == product.product_tmpl_id){
+                    items.push(index);
+                  }
+                  if(index.sequence > 1) {
+                    items2.push(index);
+                  }
+                });
+
+                if(items.length > 0){
+                  return items[0];
+                }
+                else{
+                  if(items2.length > 0){
+                    items2.sort(function(a, b) {
+                      return a.sequence - b.sequence
+                    });
+                    return items2[0];
+                  }
+                }
+              }
+            });
+
+            if(CurrencyBase.id == priceList[0].currency_id.id){
+              return product.standard_price*(1+x[0].price_discount)+x[0].price_surcharge;
+            }
+            else {
+              return (product.standard_price*priceList[0].currency_id.rate_silent)*(1+x[0].price_discount)+x[0].price_surcharge;
+            }
+          }
+          else{
+            return product.standard_price;
+          }
+        },
+
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var company = $('#current-company').val();
+            var purchasePrice = self.$el.find('#current-purchase-price').val();
+            var salePrice = self.$el.find('#current-sale-price').val();
+
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            if(purchasePrice && purchasePrice != 9999999){
+                var priceList =  _.filter(self.ProductPriceList,function (item) {
+                    return item.id == purchasePrice;
+                });
+                var CurrencyBasePurchase = self.getResCurrency(priceList[0].currency_id.id).shift();
+            }else{
+                var CurrencyBasePurchase = CurrencyBase;
+            }
+            if(salePrice && salePrice != 9999999){
+                var priceList = _.filter(self.ProductPriceList,function (item) {
+                  return item.id == salePrice;
+                });
+                var CurrencyBaseSale = self.getResCurrency(priceList[0].currency_id.id).shift();
+            }else{
+                var CurrencyBaseSale = CurrencyBase;
+            }
+
+            var ProductProduct = self.ProductProduct;
+
+            _.each(ProductProduct, function(item){
+              var salePrice = self.getProductSalePrice(item);
+              var purchasePrice = self.getProductBuyPrice(item);
+              // var auxminimo = 0;
+              //
+              //   if(item.qty_available>item.minimo_quantity){
+              //       auxminimo = 1;
+              //   }
+              //   else{
+              //       auxminimo = 0;
+              //   }
+
+                if(item.image_medium){
+                  var src='data:image/png;base64,'+ item.image_medium;
+                }
+                else{
+                  var src="/web/static/src/img/placeholder.png";
+                }
+
+              var brand = _.map(_.filter(self.ProductBrand,function (a) {
+                  return a.id == item.product_brand_id;
+              }), function(map){
+                  return map.name;
+              });
+
+                data.push({
+                    id : item.id,
+                    image_medium : src,
+                    name : item.display_name,
+                    brand: brand,
+                    default_code : self.valorNull(item.default_code),
+                    categ_id : item.categ_id.complete_name,
+                    standard_price : accounting.formatMoney(purchasePrice, '', CurrencyBasePurchase.decimal_places, CurrencyBasePurchase.thousands_separator, CurrencyBasePurchase.decimal_separator),
+                    lst_price : accounting.formatMoney(salePrice, '', CurrencyBaseSale.decimal_places, CurrencyBaseSale.thousands_separator, CurrencyBaseSale.decimal_separator),
+                    qty_available : accounting.formatNumber(item.qty_available,'',CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    // minimo_quantity : accounting.formatNumber(item.minimo_quantity,'',CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    standard_price_no_format: purchasePrice,
+                    lst_price_no_formart: salePrice,
+                    qty_no_formart: item.qty_available,
+                    // minimo_quantity_no_formart: item.minimo_qty,
+                    // minimo_quantity_aux: auxminimo,
+
+
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+
+                    decimal_places_sale : CurrencyBaseSale.decimal_places,
+                    thousands_separator_sale: CurrencyBaseSale.thousands_separator,
+                    decimal_separator_sale: CurrencyBaseSale.decimal_separator,
+                    symbol_sale: CurrencyBaseSale.symbol,
+
+                    decimal_places_purchase : CurrencyBasePurchase.decimal_places,
+                    thousands_separator_purchase: CurrencyBasePurchase.thousands_separator,
+                    decimal_separator_purchase: CurrencyBasePurchase.decimal_separator,
+                    symbol_purchase: CurrencyBasePurchase.symbol,
+                });
+            });
+
+            self.content = data;
+
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            if (action === 'pdf') {
+              var data = _.map(column, function (val){ return val.field});
+              _.each(_.map(column,function(val){
+                  return val
+              }), function(item){
+                  if(item.field != 'image_medium'){
+                      getColumns.push([{
+                          title: item.title,
+                          dataKey: item.field
+                      }]);
+                  }
+              });
+
+              var standard_price = purchaseTotalFormatter(row);
+              var lst_price = saleTotalFormatter(row);
+              var qty_available = qtyTotalFormatter(row);
+
+              row.push({
+                  default_code : 'Totales',
+                  standard_price : standard_price,
+                  lst_price: lst_price,
+                  qty_available: qty_available,
+              });
+
+                var pdf_title = 'Lista de Productos.';
+                var pdf_type = 'l';
+                var pdf_name = 'lista_de_productos_';
+
+                var pdf_columnStyles = {
+                  name :{halign:'left'},
+                  brand :{columnWidth: 25, halign:'center'},
+                  default_code :{columnWidth: 25,halign:'left'},
+                  categ_id :{halign:'left'},
+                  standard_price :{columnWidth: 25, halign:'right'},
+                  lst_price :{columnWidth: 25, halign:'right'},
+                  qty_available :{columnWidth: 20, halign:'center'},
+                  // minimo_quantity :{columnWidth: 20, halign:'center'},
+                }
+
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var state = self.$el.find('#current-state').val();
+          // var state1 = self.$el.find('#current-state1').val();
+          var type = self.$el.find('#current-type').val();
+          var salePrice = self.$el.find('#current-sale-price').val();
+          var purchasePrice = self.$el.find('#current-purchase-price').val();
+          var brand = self.$el.find('#current-brand').val();
+          var category = self.$el.find('#current-category').val();
+          var attribute = self.$el.find('#current-attribute').val();
+          var attribute_value = self.$el.find('#current-attribute-value').val();
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                 title: 'Sucursal',
+                 value:  ResStore[0].name,
+               });
+
+          }
+          if(state && state != 9999999){
+            filter.push({
+                 title: 'Estado',
+                 value:  $("#current-state option:selected").text(),
+               });
+          }
+
+          // if(state1 && state1 != 9999999){
+          //   filter.push({
+          //        title: 'Stock Minimo',
+          //        value:  $("#current-state1 option:selected").text(),
+          //      });
+          // }
+
+          if(type && type != 9999999){
+            filter.push({
+                 title: 'Tipo',
+                 value:  $("#current-type option:selected").text(),
+               });
+          }
+
+          if(salePrice && salePrice != 9999999){
+            var sale =  _.filter(self.ProductPriceList,function (item) {
+                return item.id == salePrice;
+            });
+            filter.push({
+                 title: 'Precio de Venta',
+                 value: sale[0].name,
+               });
+          }
+
+          if(purchasePrice && purchasePrice != 9999999){
+            var purchase =  _.filter(self.ProductPriceList,function (item) {
+                return item.id == purchasePrice;
+            });
+            filter.push({
+                 title: 'Precio de Compra',
+                 value: purchase[0].name,
+               });
+          }
+
+          if(brand && brand != 9999999){
+            var brand =  _.filter(self.ProductBrand,function (item) {
+                return item.id == brand;
+            });
+            filter.push({
+                 title: 'Marca',
+                 value: brand[0].name,
+               });
+          }
+
+          if(category && category != 9999999){
+            var categ =  _.filter(self.ProductCategory,function (item) {
+                return item.id == category;
+            });
+            filter.push({
+                 title: 'Categoría',
+                 value: categ[0].name,
+               });
+          }
+
+          if(attribute && attribute != 9999999){
+            var attr =  _.filter(self.ProductAttribute,function (item) {
+                return item.id == attribute;
+            });
+            filter.push({
+                 title: 'Atributo',
+                 value: attr[0].name,
+               });
+          }
+
+          if(attribute_value && attribute_value != 9999999){
+            var attr_value =  _.filter(self.ProductAttributeValue,function (item) {
+                return item.id == attribute_value;
+            });
+            filter.push({
+                 title: 'Valor de Atributo',
+                 value: attr_value[0].name,
+               });
+          }
+          return filter;
+        }
+    });
+}

+ 560 - 0
static/src/js/reports/report_profit_and_loss.js

@@ -0,0 +1,560 @@
+function report_profit_and_loss(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportProfitAndLossWidget = reporting.Base.extend({
+        template: 'ReportProfitAndLoss',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                self.ResCompany = IntialSQL.companies;
+                if(self.ResCompany .length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany ,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                self.CompanyLogo = IntialSQL.logo;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoice = DataSQL.invoices;
+                self.AccountInvoiceLine = DataSQL.invoice_lines;
+                self.PosOrder = DataSQL.invoice_lines;
+                self.PosOrderLine = DataSQL.order_lines;
+                self.ProductCategory = DataSQL.product_categories;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-profit-loss');
+            return data;
+        },
+
+        getAccountInvoiceLine: function (id,types) {
+            var self = this;
+            var content = self.AccountInvoiceLine;
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            content = _.flatten(_.filter(content,function (inv) {
+                return _.contains(types, inv.type) && inv.store_id == id;
+            }));
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return inv.date >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return inv.date<= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return inv.date === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return inv.date === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') == currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') == lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getAccountInvoiceExpenseLine: function (id,type) {
+            var self = this;
+            var content = self.AccountInvoiceLine;
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            content = _.flatten(_.filter(content,function (inv) {
+                return inv.type == type && inv.categ_id == id;
+            }));
+
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.store_id == store;
+                }));
+            }
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return inv.date >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return inv.date<= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return inv.date === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return inv.date === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') == currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') == lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getPosOrderLine: function (id) {
+            var self = this;
+            var content = self.PosOrderLine;
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            content = _.flatten(_.filter(content,function (inv) {
+                return inv.store_id == id;
+            }));
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') == currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') == lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getResStore:function () {
+            var self = this;
+            var content = self.ResStore;
+            var store = self.$el.find('#current-store').val();
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.id == store;
+                }));
+            }
+            return content;
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var ResStore = self.getResStore();
+            var ProductCategory = self.ProductCategory;
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            data.push({
+                description: 'Ventas',
+                decimal_places: CurrencyBase.decimal_places,
+                thousands_separator: CurrencyBase.thousands_separator,
+                decimal_separator: CurrencyBase.decimal_separator,
+            });
+            _.each(ResStore,function(item) {
+                /*
+                #################################
+                    ACCOUNT INVOICE LINE
+                #################################
+                */
+                var monto = 0;
+                var credit_amount = 0;
+                var AccountInvoiceLine = self.getAccountInvoiceLine(item.id,['out_invoice','out_refund']);
+                var invoice_amount = _.reduce(_.map(AccountInvoiceLine, function (map) {
+                    if(map.type == 'out_refund'){
+                        credit_amount += map.price_unit * map.quantity;
+                        monto = 0;
+                    }else{
+                        monto = map.price_unit * map.quantity;
+                    }
+                    return monto;
+                }), function (meno,num) {
+                    return meno + num;
+                }, 0);
+
+                var coste = 0;
+                var credit_cost = 0;
+                var invoice_cost = _.reduce(_.map(AccountInvoiceLine, function (map) {
+                    if(map.type == 'out_refund'){
+                        credit_cost += map.cost;
+                        coste = 0;
+                    }else{
+                        coste = map.cost;
+                    }
+                    return coste;
+                }), function (meno,num) {
+                    return meno + num;
+                }, 0);
+                /*
+                #################################
+                    POS ORDER LINE
+                #################################
+                */
+                var PosOrderLine = self.getPosOrderLine(item.id);
+                var pos_amount = _.reduce(_.map(PosOrderLine, function (map) {
+                    return map.price_unit * map.quantity;
+                }), function (meno,num) {
+                    return meno + num;
+                }, 0);
+                var pos_cost = _.reduce(_.map(PosOrderLine, function (map) {
+                    return map.cost;
+                }), function (meno,num) {
+                    return meno + num;
+                }, 0);
+                /*
+                #################################
+                    TOTAL
+                #################################
+                */
+                var amount = (invoice_amount + pos_amount) - credit_amount;
+                var cost = (invoice_cost + pos_cost) - credit_cost;
+                data.push({
+                    store: item.name,
+                    amount_total: accounting.formatMoney(amount, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    amount: amount,
+                    cost: cost,
+                    type: 'sale',
+                });
+            });
+
+            var valor = _.reduce(_.map(data, function (map) {
+                if(map.amount != undefined){
+                    return map.amount;
+                }else{
+                    return 0;
+                }
+            }), function (meno,num) {
+                return meno + num;
+            }, 0);
+
+            var cost = _.reduce(_.map(data, function (map) {
+                if(map.amount != undefined){
+                    return map.cost;
+                }else{
+                    return 0;
+                }
+            }), function (meno,num) {
+                return meno + num;
+            }, 0);
+
+            data.push({
+                store: 'Total de Ventas',
+                amount_total: accounting.formatMoney(valor, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                amount: valor,
+                type: 'sale',
+                check: true,
+            });
+
+            data.push({
+                description: 'Coste de ventas',
+                amount_total: accounting.formatMoney(cost * -1, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                amount: cost * -1,
+                expense: true,
+            });
+
+            data.push({
+                description: 'BENEFICIO BRUTO',
+                amount_total: accounting.formatMoney(valor - cost, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                footer_amount: valor - cost,
+                amount: valor - cost,
+                profit: true,
+            });
+
+            data.push({
+                description: 'GASTOS',
+            });
+            var expense = 0;
+            _.each(ProductCategory,function(item) {
+                var AccountInvoiceExpenseLine = self.getAccountInvoiceExpenseLine(item.id,'in_invoice');
+                var amount = _.reduce(_.map(AccountInvoiceExpenseLine, function (map) {
+                    if(map.origin == null){
+                        return  map.quantity * map.price_unit;
+                    }else{
+                        var origin = 0;
+                        if(map.origin != null){
+                            if(map.origin.match(/PO/) == null){
+
+                                origin =  map.quantity * map.price_unit;
+                            }
+                        }
+                        return origin;
+                    }
+                }), function (meno,num) {
+                    return meno + num;
+                }, 0);
+                amount = amount * -1;
+                expense += amount;
+                data.push({
+                    store: item.name,
+                    amount_total: accounting.formatMoney(amount, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    expense_detail: true,
+                });
+            });
+            data.push({
+                store: 'Total de Gastos',
+                amount_total: accounting.formatMoney(expense, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                footer_amount: expense,
+                check: true,
+                expense_detail: true,
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var action = this.$el.find(e.target).val();
+            var ResCompany = self.CompanyLogo[0];
+            var CurrencyBase = self.ResCompany[0].currency_id;
+
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var amount = _.reduce(_.map(row, function (map) {
+                if(map.footer_amount != undefined){
+                    return map.footer_amount;
+                }else{
+                    return 0;
+                }
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            amount = accounting.formatMoney(amount, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+
+            if (action === 'pdf') {
+
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+
+                var pdf_title = 'PERDIDAS Y GANANCIAS';
+                var pdf_type = '';
+                var pdf_name = 'perdidas_y_ganancias_';
+
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawProfitAndLossPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    amount
+                );
+            }
+        },
+    });
+}

+ 504 - 0
static/src/js/reports/report_purchase.js

@@ -0,0 +1,504 @@
+function report_purchase(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportPurchaseWidget = reporting.Base.extend({
+        template: 'ReportPurchase',
+        rowsData :[],
+        content :[],
+
+        events:{
+            'click #generate':'fetchGenerate',
+            'click .print-report':'clickOnAction',
+            'change #current-company':'updateSelections',
+            'change #current-date':'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                if(self.AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(self.AccountJournal,function(item){
+                        if(item.type == 'sale'){
+                            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                        }
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                self.ResUsers = IntialSQL.users;
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var ResUsers = _.flatten(_.filter(self.ResUsers,function (item) {
+                    return _.contains(store_ids, item.store_id);
+                }));
+                if(ResUsers.length > 1){
+                    self.$el.find('#current-user').append('<option value="9999999">Todos los responsables</option>');
+                    _.each(ResUsers,function(item){
+                        self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoice = DataSQL.invoices;
+                self.AccountVoucher = DataSQL.vouchers;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-purchase-history');
+            return data;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getAccountInvoice:function() {
+            var self = this;
+            var content = self.AccountInvoice;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var user = self.$el.find('#current-user').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                return item.id;
+            }));
+
+            var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                return item.id;
+            }));
+
+            content = _.flatten(_.filter(content,function (item) {
+                return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+            }));
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(state && state != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.state == state;
+                }));
+            }
+            if(user && user != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.user_id == user;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getAccountVoucher: function (number) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.reference == number;
+            });
+        },
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var residual = 0;
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            /*
+            ==========================================
+                ACCOUNT INVOICE
+            ==========================================
+            */
+            var AccountInvoice = self.getAccountInvoice();
+            console.log(AccountInvoice);
+            _.each(AccountInvoice, function(item){
+                residual = 0;
+                if(item.state == 'open'){
+                    residual = self.getAccountVoucher(item.number);
+                    residual =  _.reduce(_.map(residual,function(item){
+                        return item.amount_currency;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    residual = item.amount - residual;
+                }
+                data.push({
+                    /*=======================
+                        IDS
+                    =======================*/
+                    id:item.invoice_id,
+                    origin:item.origin,
+                    /*=======================
+                        INFO
+                    =======================*/
+                    supplier_invoice_number:self.valorNull(item.supplier_invoice_number),
+                    number:item.number,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    user_name:item.user_name,
+                    user_id:item.user_id,
+                    customer_ruc:self.valorNull(item.supplier_ruc),
+                    partner_name:self.valorNull(item.supplier_name),
+                    residual:accounting.formatMoney(residual,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    untaxed:accounting.formatMoney(item.amount - item.amount_tax,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.amount_tax,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    /*=======================
+                        VALORES SIN FORMATEAR
+                    =======================*/
+                    date_no_format: moment(item.date).format('YYYY-MM-DD'),
+                    residual_no_format:residual,
+                    untaxed_no_format:item.amount - item.amount_tax,
+                    tax_no_format:item.amount_tax,
+                    total_no_format:item.amount,
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.CompanyLogo,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = ResCompany[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var residual = ResidualFooter(row);
+            var untaxed = UntaxedFooter(row);
+            var tax = TaxFooter(row);
+            var total = TotalFooter(row);
+            row.push({
+                number:'Totales',
+                residual:residual,
+                untaxed:untaxed,
+                tax:tax,
+                total:total,
+            });
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Facturas de Compra.';
+                var pdf_type = '';
+                var pdf_name = 'facturas_de_compra_';
+                var pdf_columnStyles = {
+                    supplier_invoice_number:{columnWidth: 15,halign:'left'},
+                    number:{columnWidth: 30,halign:'left'},
+                    origin:{columnWidth: 15, halign:'center'},
+                    date_invoice:{halign:'center'},
+                    user_name:{ halign:'left'},
+                    customer_ruc:{columnWidth:12, halign:'left'},
+                    partner_name:{columnWidth: 30, halign:'left'},
+                    residual:{columnWidth: 20, halign:'right'},
+                    untaxed:{columnWidth: 20, halign:'right'},
+                    tax:{columnWidth: 20, halign:'right'},
+                    total:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                        return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(state && state != 9999999){
+                filter.push({
+                    title: 'Estado',
+                    value: $('#current-state option:selected').text(),
+                });
+            }
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 639 - 0
static/src/js/reports/report_purchase_analytic.js

@@ -0,0 +1,639 @@
+function report_purchase_analytic(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportPurchaseAnalyticWidget = reporting.Base.extend({
+        template: 'ReportPurchaseAnalytic',
+        rowsData :[],
+        content :[],
+        modules: ['product_brand'],
+
+        events:{
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-attribute' : 'updateAttributeSelections',
+            'change #current-date' : 'ShowDateRange',
+            'click .print-report':'clickOnAction',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModule : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    PRODUCT CATEGORY
+                =================================
+                */
+                self.ProductCategory = IntialSQL.categories;
+                if(self.ProductCategory.length > 1){
+                    self.$el.find('#current-category').append('<option value="9999999">Todas las Categorias</option>');
+                    _.each(self.ProductCategory,function(item){
+                        self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }
+                self.ProductBrand = IntialSQL.brands;
+                if(self.ProductBrand.length > 1){
+                    self.$el.find('#current-brand').append('<option value="9999999">Todas las Marcas</option>');
+                    _.each(self.ProductBrand,function(item){
+                        self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.brand').css('display','none');
+                }
+                self.ProductAttribute = IntialSQL.attributes;
+                if(self.ProductAttribute.length > 1){
+                    self.$el.find('#current-attribute').append('<option value="9999999">Todos los atributos</option>');
+                    _.each(self.ProductAttribute,function(item){
+                        self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute').css('display','none');
+                }
+                self.ProductAttributeValue = IntialSQL.attribute_values;
+                if(self.ProductAttributeValue.length > 1){
+                    self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                    _.each(self.ProductAttributeValue,function(item){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute-value').css('display','none');
+                }
+                return self.fetchIrModuleModule();
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoiceLine = DataSQL.invoice_lines;
+                self.AccountInvoice = DataSQL.invoices;
+                return self.BuildTable();
+            });
+       },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-purchase-analytic');
+            return data;
+        },
+
+        fetchIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*
+        ====================================================================
+            UPDATE SELECTIONS
+        ====================================================================
+        */
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateAttributeSelections: function () {
+            var self = this;
+            var attribute_value;
+            var attribute = self.$el.find('#current-attribute').val();
+            if(attribute != 9999999){
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    if(parseFloat(attribute) == item.attribute_id){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getProductCategory: function (id) {
+            var self = this;
+            var category;
+            category =  _.filter(self.ProductCategory,function (item) {
+                return item.id == id;
+            });
+            if(category.length > 0)
+                return category[0].name;
+        },
+
+        getPhysicInvoice: function (id) {
+            var self = this;
+            var invoice;
+            invoice =  _.filter(self.AccountInvoice,function (item) {
+                return item.invoice_id == id;
+            });
+            if(invoice.length > 0)
+                return invoice[0].supplier_invoice_number;
+        },
+
+        getAccountInvoiceLine:function() {
+            var self = this;
+            var content = self.AccountInvoiceLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                return item.id;
+            }));
+
+            var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                return item.id;
+            }));
+
+            content = _.flatten(_.filter(content,function (item) {
+                return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+            }));
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            var display_name;
+            var modules = self.checkModule('product_brand');
+            var AccountInvoiceLine = self.getAccountInvoiceLine();
+            _.each(AccountInvoiceLine,function(item) {
+                var category = self.getProductCategory(item.categ_id);
+                var physic_invoice = self.getPhysicInvoice(item.invoice_id);
+                if(item.attribute_values[0] == null){
+                    display_name = item.product_name;
+                }else{
+                    display_name = item.product_name + ' (' + _.uniq(item.attribute_values) + ')';
+                }
+                if(modules.length > 0){
+                    if(item.product_brand_id != null){
+                        display_name = display_name + ' ( ' + item.brand_name + ')';
+                    }
+                }
+                data.push({
+                    id : item.invoice_line_id,
+                    supplier_invoice_number: self.valorNull(physic_invoice),
+                    number:item.number,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    ruc : self.valorNull(item.partner_ruc),
+                    supplier_name:self.valorNull(item.partner_name),
+                    product_name:item.name,
+                    product_category:category,
+                    price_unit:accounting.formatMoney(item.price_unit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    quantity:accounting.formatNumber(item.quantity,2,'.',','),
+                    untaxed:accounting.formatMoney(item.subtotal, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.subtotal + item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*
+                    =============================
+                        VALORES SIN FORMATEAR
+                    =============================
+                    */
+                    date_no_format:item.date,
+                    price_unit_no_fortmat:item.price_unit,
+                    quantity_no_format:item.quantity,
+                    untaxed_no_format:item.subtotal,
+                    tax_no_format:item.tax,
+                    total_no_format:item.subtotal + item.tax,
+                    /*
+                    ==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.CompanyLogo,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = ResCompany[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns = [];
+            var rows = [];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var price_unit = PriceUnitFooter(row);
+            var quantity = QuantityFooter(row);
+            var tax = TaxFooter(row);
+            var untaxed = UntaxedFooter(row);
+            var total = TotalFooter(row);
+
+            row.push({
+                number:'Totales',
+                price_unit:price_unit,
+                quantity:quantity,
+                tax:tax,
+                untaxed:untaxed,
+                total:total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Analisis de Compras.';
+                var pdf_type = 'l';
+                var pdf_name = 'analisis_de_compras_';
+                var pdf_columnStyles = {
+                    number:{columnWidth: 36, halign:'center'},
+                    supplier_invoice_number:{columnWidth: 22, halign:'center'},
+                    date:{columnWidth: 19, halign:'center'},
+                    ruc:{columnWidth: 20, halign:'center'},
+                    supplier_name:{halign:'center'},
+                    product_name:{columnWidth: 'auto', halign:'left'},
+                    product_category:{columnWidth: 40, halign:'left'},
+                    price_unit:{columnWidth: 20, halign:'right'},
+                    quantity:{columnWidth: 20, halign:'right'},
+                    untaxed:{columnWidth: 20, halign:'right'},
+                    tax:{columnWidth: 20, halign:'right'},
+                    total:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+               );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                    return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(category && category != 9999999){
+                var categ =  _.filter(self.ProductCategory,function (item) {
+                    return item.id == category;
+                });
+                filter.push({
+                    title: 'Categoría',
+                    value: categ[0].name,
+               });
+            }
+            if(brand && brand != 9999999){
+                var ProductBrand =  _.filter(self.ProductBrand,function (item) {
+                    return item.id == brand;
+                });
+                filter.push({
+                    title: 'Marca',
+                    value: ProductBrand[0].name,
+                });
+            }
+            if(attribute && attribute != 9999999){
+                var attr =  _.filter(self.ProductAttribute,function (item) {
+                    return item.id == attribute;
+                });
+                filter.push({
+                    title: 'Atributo',
+                    value: attr[0].name,
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                var attr_value =  _.filter(self.ProductAttributeValue,function (item) {
+                    return item.id == attribute_value;
+                });
+                filter.push({
+                    title: 'Valor de Atributo',
+                    value: attr_value[0].name,
+                });
+            }
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 718 - 0
static/src/js/reports/report_purchase_journal.js

@@ -0,0 +1,718 @@
+function report_purchase_journal(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportPurchaseJournalWidget = reporting.Base.extend({
+        template: 'ReportPurchaseJournal',
+        rowsData :[],
+        content :[],
+        modules: ['purchase'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        clickAnalysisDetail: function(e, row, $element,field){
+
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            // console.log(self);
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                self.fecthCheckType();
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fecthCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('purchase');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            // var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','purchase']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this
+            // console.log(self);
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open','paid']],
+                ['type', '=', 'in_invoice'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+
+            if(state != 9999999){
+                domain.push(['state','=',state]);
+            }
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var domain = [[1,'=',1]];
+            var ResCompany = new model.web.Model('res.company');
+            return ResCompany.call('getResCompany',[domain],{
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var company = $('#current-company').val();
+
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            /*
+            ==========================================
+                ACCOUNT INVOICE
+            ==========================================
+            */
+            // if(type == 'purchase'){
+                var AccountInvoice = self.AccountInvoice;
+                _.each(AccountInvoice, function(item){
+                    // console.log(item);
+                    var gravada = 0;
+                    var impuesto = 0;
+                    var exenta = 0;
+                    if(item.amount_tax_currency == 0){
+                        exenta = item.amount_total_currency;
+                    }else{
+                        gravada = item.amount_total_currency - item.amount_tax_currency;
+                    }
+                    data.push({
+                        /*=======================
+                            IDS
+                        =======================*/
+                        id : item.id,
+                        /*=======================
+                            INFO
+                        =======================*/
+                        number : item.number,
+                        supplier_invoice_number: self.valorNull(item.supplier_invoice_number),
+                        date_invoice : moment(item.date_invoice).format('DD/MM/YYYY'),
+                        date : item.date_invoice,
+                        partner_id : self.valorNull(item.partner_id[1]),
+                        partner_ruc : self.valorNull(item.partner_id[2]),
+                        gravada_total : accounting.formatMoney(gravada, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        percetage_total : '',
+                        tax_total : accounting.formatMoney(item.amount_tax_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        exenta_total : accounting.formatMoney(exenta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        ret_iva_total : 0,
+                        ret_renta_total : 0,
+                        amount_total : accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        /*=======================
+                            VALORES SIN FORMATEAR
+                        =======================*/
+                        gravada : gravada,
+                        tax : item.amount_tax_currency,
+                        exenta : exenta,
+                        ret_iva : 0,
+                        ret_renta : 0,
+                        amount : item.amount_total_currency,
+                        /*==============================
+                            TOTAL FOOTER CONFIGURATION
+                        ==============================*/
+                        decimal_places : CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+                    });
+                });
+            // }
+            // data.sort(function(a,b){
+            //     // return new Date(a.date) - new Date(b.date);
+            //     return new Date(b.date) - new Date(a.date);
+            // });
+
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return 1;
+                }
+                if (a.date < b.date) {
+                    return -1;
+                }
+                return 0;
+            });
+
+            self.content = data;
+            self.loadTable(data);
+
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            var date = $('#current-company').val();
+            var period = $('#current-period').val();
+            var pdf_type = $('#current-pdf-type').val();
+            var desde = $('#from').val();
+            var hasta = $('#to').val();
+            if(period && period != 9999999){
+                var data = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                desde = moment(data[0].date_start).format('DD/MM/YYYY');
+                hasta = moment(data[0].date_stop).format('DD/MM/YYYY');
+            }
+
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var gravada = _.reduce(_.map(row, function (map) {
+                return map.gravada;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var tax = _.reduce(_.map(row, function (map) {
+                return map.tax;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var exenta = _.reduce(_.map(row, function (map) {
+                return map.exenta;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var ret_iva = _.reduce(_.map(row, function (map) {
+                return map.ret_iva;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var ret_renta = _.reduce(_.map(row, function (map) {
+                return map.ret_renta;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var total = _.reduce(_.map(row, function (map) {
+                return map.amount;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            row.push({
+                number : 'Items: ',
+                supplier_invoice_number: row.length,
+                date_invoice : ' ',
+                partner_id : 'TOTALES: ',
+                partner_ruc : ' ',
+                gravada_total : accounting.formatMoney(gravada, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                tax_total : accounting.formatMoney(tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                exenta_total : accounting.formatMoney(exenta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                ret_iva_total : accounting.formatMoney(ret_iva, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                ret_renta_total : accounting.formatMoney(ret_renta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                amount_total : accounting.formatMoney(total, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Libro de Compras.';
+                var pdf_name = 'libro_de_compras_';
+                if(pdf_type == 1){
+                    pdf_type = 'l';
+                    var pdf_columnStyles = {
+                        number :{columnWidth: 27, halign:'center'},
+                        supplier_invoice_number: {columnWidth: 24, halign:'center'},
+                        date_invoice :{columnWidth: 24, halign:'center'},
+                        partner_id :{columnWidth: 52, halign:'left'},
+                        partner_ruc : {columnWidth: 18, halign:'left'},
+                        gravada_total : {columnWidth: 24.2, halign:'right'},
+                        percetage_total : {columnWidth: 8.9, halign:'right'},
+                        tax_total : {columnWidth: 24, halign:'right'},
+                        exenta_total : {columnWidth: 21, halign:'right'},
+                        ret_iva_total : {columnWidth: 18, halign:'right'},
+                        ret_renta_total : {columnWidth: 20, halign:'right'},
+                        amount_total : {columnWidth: 24, halign:'right'},
+                    };
+                }else{
+                    pdf_type = '';
+                    var pdf_columnStyles = {
+                        number :{columnWidth: 25, halign:'center'},
+                        supplier_invoice_number: {columnWidth: 24, halign:'center'},
+                        date_invoice :{columnWidth: 16, halign:'center'},
+                        partner_id :{columnWidth: 35, halign:'left'},
+                        partner_ruc : {columnWidth: 16.8, halign:'left'},
+                        gravada_total : {columnWidth: 18, halign:'right'},
+                        percetage_total : {columnWidth: 4, halign:'right'},
+                        tax_total : {columnWidth: 15, halign:'right'},
+                        exenta_total : {columnWidth: 16, halign:'right'},
+                        ret_iva_total : {columnWidth: 7, halign:'right'},
+                        ret_renta_total : {columnWidth: 7, halign:'right'},
+                        amount_total : {columnWidth: 18, halign:'right'},
+                    };
+                }
+
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPurchaseJournalPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    desde,
+                    hasta,
+                );
+            }
+        },
+    });
+}

+ 846 - 0
static/src/js/reports/report_purchase_journal_detallado.js

@@ -0,0 +1,846 @@
+function report_purchase_journal_detallado(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportPurchaseJournalDetalladoWidget = reporting.Base.extend({
+        template: 'ReportPurchaseJournalDetallado',
+        rowsData :[],
+        content :[],
+        modules: ['purchase'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        clickAnalysisDetail: function(e, row, $element,field){
+
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            // console.log(self);
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                self.fecthCheckType();
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.fetchAccountInvoiceLine(AccountInvoice);
+            }).then(function (AccountInvoiceLine) {
+              self.AccountInvoiceLine = AccountInvoiceLine;
+              return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fecthCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('purchase');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            // var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','purchase']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this
+            // console.log(self);
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open','paid']],
+                ['type', '=', 'in_invoice'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+
+            if(state != 9999999){
+                domain.push(['state','=',state]);
+            }
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var domain = [[1,'=',1]];
+            var ResCompany = new model.web.Model('res.company');
+            return ResCompany.call('getResCompany',[domain],{
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+
+        /*====================================================================
+            GET ACCOUNT INVOICE LINE
+        ====================================================================*/
+        getAccountInvoiceLine: function (id) {
+            var self = this;
+            return _.flatten(_.filter(self.AccountInvoiceLine,function (item) {
+                return item.invoice_id == id;
+            }));
+        },
+
+
+        // Invoice line (Linea de Factura)
+        /*====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================*/
+        fetchAccountInvoiceLine: function () {
+          var self = this;
+          var domain = [];
+          var invoice_ids = _.flatten(_.map(self.AccountInvoice, function (item) {
+              return item.id;
+          }));
+          var domain = [
+              ['invoice_id','in',invoice_ids],
+          ];
+
+          var AccountInvoiceLine = new model.web.Model('account.invoice.line');
+          return AccountInvoiceLine.call('getAccountInvoiceLine',[domain], {
+              context: new model.web.CompoundContext()
+          });
+        },
+
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var company = $('#current-company').val();
+
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            /*
+            ==========================================
+                ACCOUNT INVOICE
+            ==========================================
+            */
+            // if(type == 'purchase'){
+                var AccountInvoice = self.AccountInvoice;
+                _.each(AccountInvoice, function(item){
+                    // console.log(item);
+                    var gravada = 0;
+                    var impuesto = 0;
+                    var exenta = 0;
+                    var tasa_10 = 0;
+                    var tasa_5 = 0;
+                    var iva_5 = 0;
+                    var iva_10 = 0;
+                    var IVA = 0;
+                    var TAX = 0;
+
+                    var untaxed = 0;
+
+                    var AccountInvoiceLine = self.getAccountInvoiceLine(item.id);
+
+                    if(item.amount_tax_currency == 0){
+                        exenta = item.amount_total_currency;
+                    }else{
+                        gravada = item.amount_total_currency - item.amount_tax_currency;
+                    }
+                        _.each(AccountInvoiceLine,function(index2) {
+                            // if(item.id == index2.invoice_id){
+                                var IVA = 0;
+                                var TAX = 0;
+                                // Manejo de impuestos
+                                IVA = accounting.formatNumber(((index2.price_unit*index2.quantity) / 11),"","");
+                                TAX = accounting.formatNumber(((index2.price_unit*index2.quantity)-index2.price_subtotal),"","");
+
+                                // Determinar si fue aplicado algun impuesto a la factura.
+                                if(index2.price_subtotal == (index2.price_unit*index2.quantity)){
+                                    untaxed = untaxed + index2.price_subtotal;
+                                    //  untaxed = accounting.formatNumber(item.price_subtotal,"","");
+                                }else{
+                                    // Si fue aplicado impuesto, determina si fue de 10% o 5%.
+                                    if(IVA == TAX){
+                                        iva_10 = iva_10 + ((index2.price_unit*index2.quantity)-index2.price_subtotal);
+                                        tasa_10 = tasa_10 + (index2.price_unit*index2.quantity);
+
+                                        // iva_10 = accounting.formatNumber(((item.price_unit*item.quantity)-item.price_subtotal),"","");;
+                                        // tasa_10 = accounting.formatNumber((item.price_unit*item.quantity) ,"","");
+                                    }else{
+
+                                        iva_5 = iva_5 + ((index2.price_unit*index2.quantity)-index2.price_subtotal);
+                                        tasa_5 = tasa_5 + (index2.price_unit*index2.quantity);
+
+                                        //  iva_5 = accounting.formatNumber(((item.price_unit*item.quantity)-item.price_subtotal),"","");;
+                                        // tasa_5 = accounting.formatNumber((item.price_unit*item.quantity) ,"","");
+                                    }
+
+                                }
+                        });
+
+
+                    data.push({
+                        /*=======================
+                            IDS
+                        =======================*/
+                        id : item.id,
+                        /*=======================
+                            INFO
+                        =======================*/
+                        number : item.number,
+                        supplier_invoice_number: self.valorNull(item.supplier_invoice_number),
+                        date_invoice : moment(item.date_invoice).format('DD/MM/YYYY'),
+                        date : item.date_invoice,
+                        partner_id : self.valorNull(item.partner_id[1]),
+                        partner_ruc : self.valorNull(item.partner_id[2]),
+                        tasa_5 : accounting.formatMoney(tasa_5, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        iva_5 : accounting.formatMoney(iva_5, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        tasa_10 : accounting.formatMoney(tasa_10, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        iva_10 : accounting.formatMoney(iva_10, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        amount_untaxed: accounting.formatMoney(untaxed, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        gravada_total : accounting.formatMoney(gravada, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        percetage_total : '',
+                        tax_total : accounting.formatMoney((iva_10+iva_5), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        exenta_total : accounting.formatMoney(exenta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        ret_iva_total : 0,
+                        ret_renta_total : 0,
+                        amount_total : accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        /*=======================
+                            VALORES SIN FORMATEAR
+                        =======================*/
+                        gravada : gravada,
+                        tax : (iva_10+iva_5),
+                        exenta : exenta,
+                        sftasa_10 : tasa_10,
+                        sfiva_10 : iva_10,
+                        sftasa_5 : tasa_5,
+                        sfiva_5 : iva_5,
+                        sfamount_untaxed: untaxed,
+                        ret_iva : 0,
+                        ret_renta : 0,
+                        amount : item.amount_total_currency,
+                        /*==============================
+                            TOTAL FOOTER CONFIGURATION
+                        ==============================*/
+                        decimal_places : CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+                    });
+                });
+
+            // data.sort(function(a,b){
+            //     // return new Date(a.date) - new Date(b.date);
+            //     return new Date(b.date) - new Date(a.date);
+            // });
+
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return 1;
+                }
+                if (a.date < b.date) {
+                    return -1;
+                }
+                return 0;
+            });
+
+            self.content = data;
+            self.loadTable(data);
+
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            var date = $('#current-company').val();
+            var period = $('#current-period').val();
+            var pdf_type = $('#current-pdf-type').val();
+            var desde = $('#from').val();
+            var hasta = $('#to').val();
+            if(period && period != 9999999){
+                var data = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                desde = moment(data[0].date_start).format('DD/MM/YYYY');
+                hasta = moment(data[0].date_stop).format('DD/MM/YYYY');
+            }
+
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            console.log(row);
+
+            var sftasa_5 = _.reduce(_.map(row, function (map) {
+                return map.sftasa_5;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var sfiva_5 = _.reduce(_.map(row, function (map) {
+                return map.sfiva_5;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var sftasa_10 = _.reduce(_.map(row, function (map) {
+                return map.sftasa_10;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var sfiva_10 = _.reduce(_.map(row, function (map) {
+                return map.sfiva_10;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var gravada = _.reduce(_.map(row, function (map) {
+                return map.gravada;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var tax = _.reduce(_.map(row, function (map) {
+                return map.tax;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var exenta = _.reduce(_.map(row, function (map) {
+                return map.exenta;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var ret_iva = _.reduce(_.map(row, function (map) {
+                return map.ret_iva;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var ret_renta = _.reduce(_.map(row, function (map) {
+                return map.ret_renta;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var total = _.reduce(_.map(row, function (map) {
+                return map.amount;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            row.push({
+                number : 'Items: ',
+                supplier_invoice_number: row.length,
+                date_invoice : ' ',
+                partner_id : 'TOTALES: ',
+                partner_ruc : ' ',
+                tasa_5 : accounting.formatMoney(sftasa_5, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                iva_5 : accounting.formatMoney(sfiva_5, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                tasa_10 : accounting.formatMoney(sftasa_10, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                iva_10 : accounting.formatMoney(sfiva_10, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                gravada_total : accounting.formatMoney(gravada, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                tax_total : accounting.formatMoney(tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                exenta_total : accounting.formatMoney(exenta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+               ret_iva_total : accounting.formatMoney(ret_iva, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                ret_renta_total : accounting.formatMoney(ret_renta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                amount_total : accounting.formatMoney(total, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Libro de Compras.';
+                var pdf_name = 'libro_de_compras_';
+                if(pdf_type == 1){
+                    pdf_type = 'l';
+                    var pdf_columnStyles = {
+                        number :{columnWidth: 27, halign:'center'},
+                        supplier_invoice_number: {columnWidth: 24, halign:'center'},
+                        date_invoice :{columnWidth: 24, halign:'center'},
+                        partner_id :{columnWidth: 50, halign:'left'},
+                        partner_ruc : {columnWidth: 20, halign:'left'},
+                        tasa_5 : {columnWidth: 17.2, halign:'right'},
+                        iva_5 : {columnWidth: 17.3, halign:'right'},
+                        tasa_10 : {columnWidth: 19.3, halign:'right'},
+                        iva_10 : {columnWidth: 18.5, halign:'right'},
+                        gravada_total : {columnWidth: 20.2, halign:'right'},
+                    //    percetage_total : {columnWidth: 8.9, halign:'right'},
+                       tax_total : {columnWidth: 20, halign:'right'},
+                      //  exenta_total : {columnWidth: 22, halign:'right'},
+                    //    ret_iva_total : {columnWidth: 18, halign:'right'},
+                    //    ret_renta_total : {columnWidth: 20, halign:'right'},
+                      //  amount_total : {columnWidth: 25.5, halign:'right'},
+                    };
+                }else{
+                    pdf_type = '';
+                    var pdf_columnStyles = {
+                        number :{columnWidth: 25, halign:'center'},
+                        supplier_invoice_number: {columnWidth: 24, halign:'center'},
+                        date_invoice :{columnWidth: 16, halign:'center'},
+                        partner_id :{columnWidth: 32, halign:'left'},
+                        partner_ruc : {columnWidth: 16.8, halign:'left'},
+                        tasa_5 : {columnWidth: 15.5, halign:'right'},
+                        iva_5 : {columnWidth: 13.2, halign:'right'},
+                        tasa_10 : {columnWidth: 15.1, halign:'right'},
+                        iva_10 : {columnWidth: 12.2, halign:'right'},
+                        gravada_total  : {columnWidth: 17.5, halign:'right'},
+                      //  gravada_total : {columnWidth: 14, halign:'right'},
+                      //  percetage_total : {columnWidth: 2, halign:'right'},
+                        tax_total : {columnWidth: 19, halign:'right'},
+                      //  exenta_total : {columnWidth: 16, halign:'right'},
+                      //  ret_iva_total : {columnWidth: 7, halign:'right'},
+                      //  ret_renta_total : {columnWidth: 7, halign:'right'},
+                      //  amount_total : {columnWidth: 18, halign:'right'},
+                    };
+                }
+
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPurchaseJournalPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    desde,
+                    hasta,
+                );
+            }
+        },
+    });
+}

+ 825 - 0
static/src/js/reports/report_sale.js

@@ -0,0 +1,825 @@
+function report_sale(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSaleWidget = reporting.Base.extend({
+        template: 'ReportSale',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-date' : 'ShowDateRange',
+            'click .print-report':'clickOnAction',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                var journal = _.flatten(_.filter(self.AccountJournal,function (item) {
+                    return item.type == 'sale';
+                }));
+                if(journal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(self.AccountJournal,function(item){
+                        if(item.type == 'sale'){
+                            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                        }
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                /*
+                =================================
+                    RES USERS
+                =================================
+                */
+                self.ResUsers = IntialSQL.users;
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var ResUsers = _.flatten(_.filter(self.ResUsers,function (item) {
+                    return _.contains(store_ids, item.store_id);
+                }));
+                if(ResUsers.length > 0){
+                    self.$el.find('#current-user').append('<option value="9999999">Todos los Vendedores</option>');
+                    _.each(ResUsers,function(item){
+                        self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.users').css('display','none');
+                }
+                return self.fethIrModuleModule();
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fethCheckType();
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoice = DataSQL.invoices;
+                self.PosOrder = DataSQL.orders;
+                self.AccountVoucher = DataSQL.vouchers;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-sale-history');
+            return data;
+        },
+
+        fethIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fethCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('point_of_sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var journal;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_id && item.type == 'sale'){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                self.$el.find('#current-user').empty();
+                self.$el.find('#current-user').append('<option value="9999999">Todos los Vendedores</option>');
+                _.each(self.ResUsers,function(item){
+                    if(parseFloat(store) == item.store_id){
+                        self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(item.type == 'sale'){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                _.each(self.ResUsers,function(item){
+                        self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getPosOrder:function() {
+            var self = this;
+            var content = self.PosOrder;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var type = self.$el.find('#current-type').val();
+            var invoice_type = self.$el.find('#current-invoice-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var user = self.$el.find('#current-user').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(state && state != 9999999){
+                if(state == 'open'){
+                    content = [];
+                }
+            }
+            if(type && type != 9999999){
+                if(type == 'sale'){
+                    content = [];
+                }
+            }
+            if(invoice_type && invoice_type != 9999999){
+                if(invoice_type == 'credit'){
+                    content = [];
+                }
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(user && user != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.user_id == user;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getAccountInvoice:function() {
+            var self = this;
+            var content = self.AccountInvoice;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var type = self.$el.find('#current-type').val();
+            var invoice_type = self.$el.find('#current-invoice-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var user = self.$el.find('#current-user').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(state && state != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.state == state;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'tpv'){
+                    content = [];
+                }
+            }
+            if(invoice_type && invoice_type != 9999999){
+              if (invoice_type == 'credit'){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.credito == true;
+                }));
+
+              }
+
+              if(invoice_type == 'cash'){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.contado == true;
+                }));
+              }
+            }
+
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(user && user != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.user_id == user;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getAccountVoucher: function (number) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.reference == number;
+            });
+        },
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var residual = 0;
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            /*
+            ==========================================
+                POS ORDER
+            ==========================================
+            */
+            var discount_amount;
+            var PosOrder = self.getPosOrder();
+            _.each(PosOrder, function(item){
+                var utc = moment.utc(item.date,'YYYY-MM-DD h:mm:ss A');
+                var forma = 'Contado';
+                data.push({
+                    id:item.id,
+                    origin:'',
+                    number:item.name,
+                    date:moment(utc._d).format('DD/MM/YYYY HH:mm'),
+                    forma: forma,
+                    user_name:item.user_name,
+                    user_id:item.user_id,
+                    customer_ruc:self.valorNull(item.customer_ruc),
+                    customer_name:self.valorNull(item.customer_name),
+                    residual:0,
+                    untaxed:accounting.formatMoney(item.amount_untaxed,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.amount - item.amount_untaxed,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    /*
+                    ===========================
+                        NO FORMAT
+                    ===========================
+                    */
+                    date_no_format:moment(utc._d).format('YYYY-MM-DD HH:mm'),
+                    residual_no_format: 0,
+                    untaxed_no_format:item.amount_untaxed,
+                    tax_no_format:item.amount - item.amount_untaxed,
+                    total_no_format:item.amount,
+                    /*
+                    ===========================
+                        FOOTER
+                    ===========================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            /*
+            ==========================================
+                ACCOUNT INVOICE
+            ==========================================
+            */
+            var AccountInvoice = self.getAccountInvoice();
+            _.each(AccountInvoice, function(item){
+                residual = 0;
+                // var pagado = 0;
+                var totalamount = 0;
+              if(item.type == 'out_refund'){
+                    // pagado = -(item.amount_original);
+                    totalamount = -(item.amount);
+                }else{
+                  // pagado = (item.amount_original);
+                  totalamount = (item.amount);
+                }
+
+                var forma = 'Contado';
+                if (item.contado == true){
+                   forma = 'Contado'
+                };
+                if (item.credito == true){
+                   forma = 'Credito'
+                };
+                if(item.state == 'open'){
+                   if(item.type == 'out_refund'){
+                      residual = self.getAccountVoucher(item.number);
+                      residual =  _.reduce(_.map(residual,function(item){
+                          return item.amount_currency;
+                      }), function(memo, num){
+                          return memo + num;
+                      },0);
+                      residual = item.amount - residual;
+                  }else{
+                      residual = self.getAccountVoucher(item.number);
+                      residual =  _.reduce(_.map(residual,function(item){
+                          return item.amount_currency;
+                      }), function(memo, num){
+                          return memo + num;
+                      },0);
+                      residual = -(item.amount - residual);
+                  }
+                }
+                data.push({
+                    id:item.id,
+                    supplier_invoice_number:item.supplier_invoice_number,
+                    origin:item.origin,
+                    number:item.number,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    forma: forma,
+                    user_name:item.user_name,
+                    user_id:item.user_id,
+                    customer_ruc:self.valorNull(item.customer_ruc),
+                    customer_name:self.valorNull(item.customer_name),
+                    residual:accounting.formatMoney(residual,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    untaxed:accounting.formatMoney(item.amount - item.amount_tax,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.amount_tax,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(totalamount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    /*
+                    =======================
+                        NO FORMAT
+                    =======================
+                    */
+                    date_no_format: moment(item.date).format('YYYY-MM-DD'),
+                    residual_no_format:residual,
+                    untaxed_no_format:item.amount - item.amount_tax,
+                    tax_no_format:item.amount_tax,
+                    total_no_format: totalamount,
+                    /*
+                    =======================
+                        FOOTER
+                    =======================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.ResCompany,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = CompanyLogo[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var residual = ResidualFooter(row);
+            var untaxed = UntaxedFooter(row);
+            var tax = TaxFooter(row);
+            var total = TotalFooter(row);
+            row.push({
+                number:'Totales',
+                residual:residual,
+                untaxed:untaxed,
+                tax:tax,
+                total:total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Facturas de Venta.';
+                var pdf_type = '';
+                var pdf_name = 'facturas_de_venta_';
+                var pdf_columnStyles = {
+                    number:{columnWidth: 25,halign:'left'},
+                    origin:{columnWidth: 15, halign:'center'},
+                    date:{halign:'center'},
+                    forma:{ halign:'left'},
+                    user_name:{ halign:'left'},
+                    customer_ruc:{columnWidth: 13, halign:'left'},
+                    customer_name:{columnWidth: 30, halign:'left'},
+                    residual:{columnWidth: 20, halign:'right'},
+                    untaxed:{columnWidth: 20, halign:'right'},
+                    tax:{columnWidth: 20, halign:'right'},
+                    total:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var journal = self.$el.find('#current-journal').val();
+            var type = self.$el.find('#current-type').val();
+            var invoice_type = self.$el.find('#current-invoice-type').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                        return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(state && state != 9999999){
+                filter.push({
+                    title: 'Estado',
+                    value: $('#current-state option:selected').text(),
+                });
+            }
+            if(journal && journal != 9999999){
+                var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                    return item.id == journal;
+                });
+                filter.push({
+                   title: 'Factura',
+                   value: AccountJournal[0].name,
+                });
+            }
+            if(type && type != 9999999){
+                filter.push({
+                    title: 'Tipo de Venta',
+                    value: $('#current-type option:selected').text(),
+                });
+            }
+            if(invoice_type && invoice_type != 9999999){
+                filter.push({
+                    title: 'Tipo de Factura',
+                    value: $('#current-invoice-type option:selected').text(),
+                });
+            }
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 922 - 0
static/src/js/reports/report_sale_analytic.js

@@ -0,0 +1,922 @@
+function report_sale_analytic(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSaleAnalyticWidget = reporting.Base.extend({
+        template: 'ReportSaleAnalytic',
+        rowsData :[],
+        content :[],
+        modules: ['product_brand','point_of_sale'],
+
+        events:{
+            'click .print-report' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-attribute' : 'updateAttributeSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModule : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                var journal = _.flatten(_.filter(self.AccountJournal,function (item) {
+                    return item.type == 'sale';
+                }));
+                if(journal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(self.AccountJournal,function(item){
+                        if(item.type == 'sale'){
+                            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                        }
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                /*
+                =================================
+                    PRODUCT CATEGORY
+                =================================
+                */
+                self.ProductCategory = IntialSQL.categories;
+                if(self.ProductCategory.length > 1){
+                    self.$el.find('#current-category').append('<option value="9999999">Todas las Categorias</option>');
+                    _.each(self.ProductCategory,function(item){
+                        self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }
+                /*
+                =================================
+                    PRODUCT BRAND
+                =================================
+                */
+                self.ProductBrand = IntialSQL.brands;
+                if(self.ProductBrand.length > 1){
+                    self.$el.find('#current-brand').append('<option value="9999999">Todas las Marcas</option>');
+                    _.each(self.ProductBrand,function(item){
+                        self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.brand').css('display','none');
+                }
+                self.ProductAttribute = IntialSQL.attributes;
+                if(self.ProductAttribute.length > 1){
+                    self.$el.find('#current-attribute').append('<option value="9999999">Todos los atributos</option>');
+                    _.each(self.ProductAttribute,function(item){
+                        self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute').css('display','none');
+                }
+                self.ProductAttributeValue = IntialSQL.attribute_values;
+                if(self.ProductAttributeValue.length > 1){
+                    self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                    _.each(self.ProductAttributeValue,function(item){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute-value').css('display','none');
+                }
+                return self.fetchIrModuleModule();
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchCheckType();
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoiceLine = DataSQL.invoice_lines;
+                self.PosOrderLine = DataSQL.order_lines;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-sale-analytic');
+            return data;
+        },
+
+        fetchIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        fetchCheckType: function(){
+            var self = this;
+            var modules = self.checkModule('point_of_sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateAttributeSelections: function () {
+            var self = this;
+            var attribute_value;
+            var attribute = self.$el.find('#current-attribute').val();
+            if(attribute != 9999999){
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    if(parseFloat(attribute) == item.attribute_id){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var journal;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_id){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getProductCategory: function (id) {
+            var self = this;
+            var category;
+            category =  _.filter(self.ProductCategory,function (item) {
+                return item.id == id;
+            });
+            if(category.length > 0)
+                return category[0].name;
+        },
+
+        getPosOrderLine:function() {
+            var self = this;
+            var content = self.PosOrderLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var type = self.$el.find('#current-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'sale'){
+                    content = [];
+                }
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        getAccountInvoiceLine:function() {
+            var self = this;
+            var content = self.AccountInvoiceLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var type = self.$el.find('#current-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'tpv'){
+                    content = [];
+                }
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            var PosOrderLine = self.getPosOrderLine();
+            var display_name;
+            var discount_amount;
+            var modules = self.checkModule('product_brand');
+            _.each(PosOrderLine,function(item) {
+
+                var category = self.getProductCategory(item.categ_id);
+                if(item.attribute_values[0] == null){
+                    display_name = item.product_name;
+                }else{
+                    display_name = item.product_name + ' (' + _.uniq(item.attribute_values) + ')';
+                }
+                if(modules.length > 0){
+                    if(item.product_brand_id != null){
+                        display_name = display_name + ' ( ' + item.brand_name + ')';
+                    }
+                }
+                discount_amount = 0;
+                if(item.discount > 0){
+                    discount_amount = ((item.quantity * item.price_unit) * item.discount)/100;
+                }
+
+                data.push({
+                    id : item.order_line_id,
+                    number:item.name,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    ruc : self.valorNull(item.partner_ruc),
+                    customer_name:self.valorNull(item.customer_name),
+                    product_name:display_name,
+                    product_category:category,
+                    discount:accounting.formatNumber(item.discount,2,'.',',') + '%',
+                    discount_amount:accounting.formatMoney(discount_amount, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    price_unit:accounting.formatMoney(item.price_unit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    quantity:accounting.formatNumber(item.quantity,2,'.',','),
+                    untaxed:accounting.formatMoney(item.subtotal, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.subtotal + item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*
+                    =============================
+                        NO FORMAT
+                    =============================
+                    */
+                    date_no_format:item.date,
+                    price_unit_no_format:item.price_unit,
+                    quantity_no_format:item.quantity,
+                    discount_amount_no_format:discount_amount,
+                    untaxed_no_format:item.subtotal,
+                    tax_no_format:item.tax,
+                    total_no_format:item.subtotal + item.tax,
+                    /*
+                    ==============================
+                        FOOTER
+                    ==============================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            var AccountInvoiceLine = self.getAccountInvoiceLine();
+            _.each(AccountInvoiceLine,function(item) {
+                var category = self.getProductCategory(item.categ_id);
+                if(item.attribute_values[0] == null){
+                    display_name = item.product_name;
+                }else{
+                    display_name = item.product_name + ' (' + _.uniq(item.attribute_values) + ')';
+                }
+                if(modules.length > 0){
+                    if(item.product_brand_id != null){
+                        display_name = display_name + ' ( ' + item.brand_name + ')';
+                    }
+                }
+                discount_amount = 0;
+                if(item.discount > 0){
+                    discount_amount = ((item.quantity * item.price_unit) * item.discount)/100;
+                }
+                data.push({
+                    id : item.invoice_line_id,
+                    number:item.number,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    ruc : self.valorNull(item.partner_ruc),
+                    customer_name:self.valorNull(item.partner_name),
+                    //product_name: display_name,
+                    product_name: !!display_name ?display_name : item.name,
+                    product_category:category,
+                    discount:accounting.formatNumber(item.discount,2,'.',',') + '%',
+                    discount_amount:accounting.formatMoney(discount_amount, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    price_unit:accounting.formatMoney(item.price_unit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    quantity:accounting.formatNumber(item.quantity,2,'.',','),
+                    untaxed:accounting.formatMoney(item.subtotal, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.subtotal + item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*
+                    =============================
+                        NO FORMAT
+                    =============================
+                    */
+                    date_no_format:item.date,
+                    price_unit_no_format:item.price_unit,
+                    quantity_no_format:item.quantity,
+                    discount_amount_no_format: discount_amount,
+                    untaxed_no_format:item.subtotal,
+                    tax_no_format:item.tax,
+                    total_no_format:item.subtotal + item.tax,
+                    /*
+                    ==============================
+                        FOOTER
+                    ==============================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.CompanyLogo,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = CompanyLogo[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns = [];
+            var rows = [];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var price_unit = PriceUnitFooter(row);
+            var quantity = QuantityFooter(row);
+            var tax = TaxFooter(row);
+            var untaxed = UntaxedFooter(row);
+            var total = TotalFooter(row);
+
+            row.push({
+                number : 'Totales',
+                price_unit : price_unit,
+                quantity : quantity,
+                tax : tax,
+                untaxed : untaxed,
+                total : total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Analisis de Venta.';
+                var pdf_type = 'l';
+                var pdf_name = 'analisis_de_venta_';
+                var pdf_columnStyles = {
+                    number:{columnWidth: 25, halign:'center'},
+                    date:{columnWidth: 20, halign:'center'},
+                    ruc:{columnWidth: 20, halign:'center'},
+                    customer_name:{halign:'center'},
+                    product_name:{columnWidth: 'auto', halign:'left'},
+                    product_category:{columnWidth: 40, halign:'left'},
+                    price_unit:{columnWidth: 20, halign:'right'},
+                    quantity:{columnWidth: 20, halign:'right'},
+                    untaxed:{columnWidth: 20, halign:'right'},
+                    tax:{columnWidth: 20, halign:'right'},
+                    total:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+               );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var journal = self.$el.find('#current-journal').val();
+            var type = self.$el.find('#current-type').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                    return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(journal && journal != 9999999){
+                var AccountJournal = _.filter(self.AccountJournal, function(item){
+                  return item.id == journal;
+                });
+                filter.push({
+                  title: 'Factura',
+                  value: AccountJournal[0].name,
+                });
+            }
+            if(type && type != 9999999){
+                filter.push({
+                    title: 'Tipo de Venta',
+                    value: $('#current-type option:selected').text(),
+                });
+            }
+            if(category && category != 9999999){
+                var categ =  _.filter(self.ProductCategory,function (item) {
+                    return item.id == category;
+                });
+                filter.push({
+                    title: 'Categoría',
+                    value: categ[0].name,
+               });
+            }
+            if(brand && brand != 9999999){
+                var ProductBrand =  _.filter(self.ProductBrand,function (item) {
+                    return item.id == brand;
+                });
+                filter.push({
+                    title: 'Marca',
+                    value: ProductBrand[0].name,
+                });
+            }
+            if(attribute && attribute != 9999999){
+                var attr =  _.filter(self.ProductAttribute,function (item) {
+                    return item.id == attribute;
+                });
+                filter.push({
+                    title: 'Atributo',
+                    value: attr[0].name,
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                var attr_value =  _.filter(self.ProductAttributeValue,function (item) {
+                    return item.id == attribute_value;
+                });
+                filter.push({
+                    title: 'Valor de Atributo',
+                    value: attr_value[0].name,
+                });
+            }
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 931 - 0
static/src/js/reports/report_sale_gross.js

@@ -0,0 +1,931 @@
+function report_sale_gross(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSaleGrossWidget = reporting.Base.extend({
+        template: 'ReportSaleGross',
+        rowsData: [],
+        content: [],
+        details: [],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                self.fecthCheckType();
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.fetchAccountInvoiceLine();
+            }).then(function (AccountInvoiceLine){
+                self.AccountInvoiceLine = AccountInvoiceLine;
+                return self.fetchPosOrder();
+            }).then(function (PosOrder){
+                self.PosOrder = PosOrder;
+                return self.fetchPosOrderLine();
+            }).then(function (PosOrderLine){
+                self.PosOrderLine = PosOrderLine;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fecthCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('point_of_sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','sale']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open','paid']],
+                ['type', '=', 'out_invoice'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================*/
+        fetchAccountInvoiceLine: function (){
+            var self = this;
+            var invoice_ids = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.id;
+            }));
+            var domain = [
+                ['invoice_id','in',invoice_ids],
+            ];
+            var AccountInvoiceLine = new model.web.Model('account.invoice.line');
+            return AccountInvoiceLine.call('getAccountInvoiceLine',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            POS ORDER
+        ====================================================================*/
+        fetchPosOrder: function () {
+            var self = this;
+            var type = $('#current-type').val();
+            var modules = self.checkModel('point_of_sale');
+            if (type && modules.length > 0){
+                if(type != 'sale'){
+                    var store = self.$el.find('#current-store').val();
+                    var company = self.$el.find('#current-company').val();
+                    var journal = self.$el.find('#current-journal').val();
+                    var date = self.$el.find('#current-date').val();
+                    var desde = self.$el.find('#from').val();
+
+                    if(store && store != 9999999){
+                        var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                            return item.store_ids == store;
+                        }), function(map){
+                            return map.id;
+                        });
+                    }else{
+                        var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                            return item.id;
+                        }));
+                    }
+
+                    var domain = [
+                        ['state', 'not in',['draft','cancel']],
+                        ['sale_journal','in',journal_ids],
+                    ];
+
+                    if(company && company != 9999999){
+                        domain.push(['company_id','=',parseInt(company)]);
+                    }
+
+                    if(journal && journal != 9999999){
+                        domain.push(['sale_journal','=',parseInt(journal)]);
+                    }
+
+                    if(date && date != 9999999){
+                        if(date == 'range'){
+                            if(desde){
+                                var date = desde.split('/')
+                                date = (date[2]+"-"+date[1]+"-"+date[0]);
+                                domain.push(['date_order','>=',date]);
+                            }
+                        }
+                    }
+
+                    var PosOrder = new model.web.Model('account.invoice');
+                    return PosOrder.call('getPosOrder',[domain], {
+                        context: new model.web.CompoundContext()
+                    });
+                }
+            }else{
+                var PosOrder = [];
+                return PosOrder;
+            }
+        },
+        /*====================================================================
+            POS ORDER LINE
+        ====================================================================*/
+        fetchPosOrderLine: function () {
+            var self = this;
+            var modules = self.checkModel('point_of_sale');
+            if (modules.length > 0){
+                var order_ids = _.flatten(_.map(self.PosOrder, function (item) {
+                    return item.id;
+                }));
+                var domain = [
+                    ['order_id','in',order_ids],
+                ];
+                var PosOrderLine = new model.web.Model('account.invoice.line');
+                return PosOrderLine.call('getPosOrderLine',[domain], {
+                    context: new model.web.CompoundContext()
+                });
+            }else{
+                var PosOrderLine = [];
+                return PosOrderLine;
+            }
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT INVOICE LINE
+        ====================================================================*/
+        getAccountInvoiceLine: function (id, store_id) {
+            var self = this;
+            return _.filter(self.AccountInvoiceLine,function (item) {
+                return item.period_id[0] === id & item.store_id[0] === store_id;
+            })
+        },
+
+        /*====================================================================
+            GET POS ORDER LINE
+        ====================================================================*/
+        getPosOrderLine: function (date_start,date_stop,store_id) {
+            var self = this;
+            return _.filter(self.PosOrderLine,function (item) {
+                var utc = moment.utc(item.create_date,'YYYY-MM-DD h:mm:ss A');
+                utc = moment(utc._d).format('YYYY-MM-DD');
+                return utc >= date_start & utc <= date_stop & item.store_id[0] === store_id;
+            });
+        },
+
+        /*====================================================================
+            GET RES STORE
+        ====================================================================*/
+        getResStore: function () {
+            var self = this;
+            var content = self.ResStore;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.company_id[0] === parseInt(company);
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.id === parseInt(store);
+                }));
+            }
+            return content;
+        },
+
+        /*====================================================================
+            GET ACCOUNT PERIOD
+        ====================================================================*/
+        getAccountPeriod: function () {
+            var self = this;
+            var content = self.AccountPeriod;
+            var company = self.$el.find('#current-company').val();
+            var period = self.$el.find('#current-period').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.company_id[0] === parseInt(company);
+                }));
+            }
+            if(period && period != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.id === parseInt(period);
+                }));
+            }
+            return content;
+        },
+
+        /*====================================================================
+            GET CONTENT BY MONTH
+        ====================================================================*/
+        getContent:function(id) {
+            var self = this;
+            return _.flatten(_.filter(self.details,function (inv) {
+                return inv.period_id === id;
+            }));
+        },
+
+        /*============================
+            BUILD TABLE
+        ============================*/
+        BuildTable: function() {
+            var self = this;
+            var data = [];
+
+            var info = [];
+            var details = [];
+            var ResStore = self.getResStore();
+            var AccountPeriod = self.getAccountPeriod();
+            var total_amount_untaxed;
+            var total_amount_tax;
+            var total_amount_total;
+            var total_cost_total;
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            _.each(ResStore, function (item) {
+                total_amount_untaxed = 0;
+                total_amount_tax = 0;
+                total_amount_total = 0;
+                total_cost_total = 0;
+                info = [];
+                _.each(AccountPeriod, function (index) {
+                    /*
+                    ======================================================================================
+                        ACCOUNT INVOICE
+                    ======================================================================================
+                    */
+                    var AccountInvoiceLine = self.getAccountInvoiceLine(index.id, item.id);
+                    var invoice_amount_untaxed = 0;
+                    var invoice_amount_tax = 0;
+                    var invoice_amount_cost = 0;
+                    var invoice_amount_total = 0;
+                    if(AccountInvoiceLine.length > 0){
+                        /*
+                        ================
+                            SUB-TOTAL
+                        ================
+                        */
+                        invoice_amount_untaxed = _.reduce(_.map(AccountInvoiceLine,function(item) {
+                            return item.price_subtotal_currency;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        /*
+                        ================
+                            IMPUESTOS
+                        ================
+                        */
+                        invoice_amount_tax = _.reduce(_.map(AccountInvoiceLine,function(item) {
+                            return item.tax_currency;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        /*
+                        ================
+                            COSTE
+                        ================
+                        */
+                        invoice_amount_cost = _.reduce(_.map(AccountInvoiceLine,function(item) {
+                            return item.product_id[3] * item.quantity;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        /*
+                        ================
+                            TOTAL
+                        ================
+                        */
+                        invoice_amount_total = _.reduce(_.map(AccountInvoiceLine,function(item) {
+                            return item.amount_currency;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                    };
+                    /*
+                    ======================================================================================
+                        POS ORDER LINE
+                    ======================================================================================
+                    */
+                    var PosOrderLine = self.getPosOrderLine(index.date_start, index.date_stop, item.id);
+                    var pos_amount_untaxed = 0;
+                    var pos_amount_tax = 0;
+                    var pos_amount_cost = 0;
+                    var pos_amount_total = 0;
+                    if(PosOrderLine.length > 0){
+                        /*
+                        ================
+                            SUB-TOTAL
+                        ================
+                        */
+                        pos_amount_untaxed = _.reduce(_.map(PosOrderLine,function(item) {
+                            return item.price_subtotal_currency;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        /*
+                        ================
+                            IMPUESTOS
+                        ================
+                        */
+                        pos_amount_tax = _.reduce(_.map(PosOrderLine,function(item) {
+                            return item.price_subtotal_incl_currency - item.price_subtotal_currency;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        /*
+                        ================
+                            COSTE
+                        ================
+                        */
+                        pos_amount_cost = _.reduce(_.map(PosOrderLine,function(item) {
+                            return item.product_id[2];
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        /*
+                        ================
+                            TOTAL
+                        ================
+                        */
+                        pos_amount_total = _.reduce(_.map(PosOrderLine,function(item) {
+                            return item.price_subtotal_incl_currency;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                    };
+                    if(AccountInvoiceLine.length > 0 || PosOrderLine.length > 0){
+                        var margin = ((invoice_amount_cost + pos_amount_cost) * 100)/(invoice_amount_untaxed + pos_amount_untaxed);
+                        margin = 100 - margin;
+                        info.push({
+                            period : index.name,
+                            subtotal : accounting.formatMoney((invoice_amount_untaxed + pos_amount_untaxed), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            tax : accounting.formatMoney((invoice_amount_tax + pos_amount_tax), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            cost : accounting.formatMoney((invoice_amount_cost + pos_amount_cost), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            margin : accounting.formatNumber(margin,2,".",",") + '%',
+                            total : accounting.formatMoney((invoice_amount_total + pos_amount_total), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            profit : accounting.formatMoney(((invoice_amount_untaxed + pos_amount_untaxed) - (invoice_amount_cost + pos_amount_cost)), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            /*=======================
+                                VALORES SIN FORMATEAR
+                            =======================*/
+                            subtotal_amount : invoice_amount_untaxed + pos_amount_untaxed,
+                            tax_amount : invoice_amount_tax + pos_amount_tax,
+                            cost_amount : invoice_amount_cost + pos_amount_cost,
+                            total_amount : invoice_amount_total + pos_amount_total,
+                            profit_amount : (invoice_amount_untaxed + pos_amount_untaxed) - (invoice_amount_cost + pos_amount_cost),
+                        });
+                        details.push({
+                            period : index.name,
+                            period_id : index.id,
+                            subtotal_amount : invoice_amount_untaxed + pos_amount_untaxed,
+                            tax_amount : invoice_amount_tax + pos_amount_tax,
+                            cost_amount : invoice_amount_cost + pos_amount_cost,
+                            total_amount : invoice_amount_total + pos_amount_total,
+                            profit_amount : (invoice_amount_untaxed + pos_amount_untaxed) - (invoice_amount_cost + pos_amount_cost),
+                        });
+                    };
+                    /*
+                    ======================================================================================
+                        TOTALES
+                    ======================================================================================
+                    */
+                    total_amount_untaxed = total_amount_untaxed + invoice_amount_untaxed + pos_amount_untaxed;
+                    total_amount_tax = total_amount_tax + invoice_amount_tax + pos_amount_tax;
+                    total_cost_total = total_cost_total + invoice_amount_cost + pos_amount_cost;
+                    total_amount_total = total_amount_total + invoice_amount_total + pos_amount_total;
+
+                });
+
+                var margin = ((total_amount_untaxed - total_cost_total) / total_amount_untaxed) * 100;
+                // margin = 100 - margin;
+
+                data.push({
+                    id : item.id,
+                    name : item.name,
+                    subtotal_amount : accounting.formatMoney(total_amount_untaxed, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    tax_amount : accounting.formatMoney(total_amount_tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    cost_amount : accounting.formatMoney(total_cost_total, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    margin : accounting.formatNumber(margin,2,".",",") + '%',
+                    total_amount : accounting.formatMoney(total_amount_total, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    profit_amount : accounting.formatMoney((total_amount_untaxed - total_cost_total), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*=======================
+                        VALORES SIN FORMATEAR
+                    =======================*/
+                    subtotal : total_amount_untaxed,
+                    tax : total_amount_tax,
+                    cost : total_cost_total,
+                    total : total_amount_total,
+                    profit : total_amount_untaxed - total_cost_total,
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                    /*==============================
+                        DATA
+                    ==============================*/
+                    info : info,
+                });
+            });
+            self.details = details;
+            self.content = data;
+            self.loadTable(data);
+            self.CallCharts(data,CurrencyBase);
+        },
+
+        /*
+        ======================================================================
+            LLAMAR LOS GRAFICOS
+        ======================================================================
+        */
+        CallCharts: function(data,CurrencyBase){
+            var self = this;
+            /*
+            ================================================
+            MULTIPLES GRAFICOS
+            ================================================
+            */
+            var MultipleChart = new reporting.ReportChartWidget(self);
+            var item;
+            var label = [];
+            var AccountPeriod = self.AccountPeriod
+            var body_subtotal = [];
+            var body_tax = [];
+            var body_cost = [];
+            var body_total = [];
+            var body_profit = [];
+            _.each(AccountPeriod, function (item) {
+                var content = self.getContent(item.id);
+                if(content.length > 0){
+                    /*
+                    =============================
+                        SUBTOTAL
+                    =============================
+                    */
+                    var subtotal = _.reduce(_.map(content,function(item) {
+                        return item.subtotal_amount;
+                    }),function(memo, num) {
+                        return memo + num;
+                    },0);
+                    /*
+                    =============================
+                        IMPUESTOS
+                    =============================
+                    */
+                    var tax = _.reduce(_.map(content,function(item) {
+                        return item.tax_amount;
+                    }),function(memo, num) {
+                        return memo + num;
+                    },0);
+                    /*
+                    =============================
+                        COSTE
+                    =============================
+                    */
+                    var cost = _.reduce(_.map(content,function(item) {
+                        return item.cost_amount;
+                    }),function(memo, num) {
+                        return memo + num;
+                    },0);
+                    /*
+                    =============================
+                        COSTE
+                    =============================
+                    */
+                    var total = _.reduce(_.map(content,function(item) {
+                        return item.total_amount;
+                    }),function(memo, num) {
+                        return memo + num;
+                    },0);
+                    /*
+                    =============================
+                        BENEFICIO
+                    =============================
+                    */
+                    var profit = _.reduce(_.map(content,function(item) {
+                        return item.profit_amount;
+                    }),function(memo, num) {
+                        return memo + num;
+                    },0);
+
+                    body_subtotal.push(subtotal);
+                    body_tax.push(tax);
+                    body_cost.push(cost);
+                    body_total.push(total);
+                    body_profit.push(profit);
+                    label.push(item.name);
+
+                }
+            });
+            MultipleChart.BuildMultipleChart(CurrencyBase,label,body_subtotal,body_tax,body_cost,body_total,body_profit);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load',rowsTable);
+        },
+
+    });
+}

+ 917 - 0
static/src/js/reports/report_sale_journal.js

@@ -0,0 +1,917 @@
+function report_sale_journal(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSaleJournalWidget = reporting.Base.extend({
+        template: 'ReportSaleJournal',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        clickAnalysisDetail: function(e, row, $element,field){
+            // if (field == 'number'){
+            //     this.do_action({
+            //         name:"Factura",
+            //         type: 'ir.actions.act_window',
+            //         res_model: "account.invoice",
+            //         views: [[false,'form']],
+            //         target: 'new',
+            //         domain: [['id','=', row.id]],
+            //         context: {},
+            //         flags: {'form': {'action_buttons': false, 'options': {'mode': 'view'}}},
+            //         res_id: row.id,
+            //     });
+            // }
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                self.fecthCheckType();
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.fetchPosOrder();
+            }).then(function (PosOrder){
+                self.PosOrder = PosOrder;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fecthCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('point_of_sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','sale']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open','paid']],
+                ['type', '=', 'out_invoice'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+
+            if(state != 9999999){
+                domain.push(['state','=',state]);
+            }
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            POS ORDER
+        ====================================================================*/
+        fetchPosOrder: function () {
+            var self = this;
+            var type = $('#current-type').val();
+            var modules = self.checkModel('point_of_sale');
+            if (type && modules.length > 0){
+                if(type != 'sale'){
+                    var store = self.$el.find('#current-store').val();
+                    var company = self.$el.find('#current-company').val();
+                    var journal = self.$el.find('#current-journal').val();
+                    var date = self.$el.find('#current-date').val();
+                    var desde = self.$el.find('#from').val();
+                    var hasta = self.$el.find('#to').val();
+
+                    if(store && store != 9999999){
+                        var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                            return item.store_ids == store;
+                        }), function(map){
+                            return map.id;
+                        });
+                    }else{
+                        var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                            return item.id;
+                        }));
+                    }
+
+                    var domain = [
+                        ['state', 'not in',['draft','cancel']],
+                        ['sale_journal','in',journal_ids],
+                    ];
+
+                    if(company && company != 9999999){
+                        domain.push(['company_id','=',parseInt(company)]);
+                    }
+
+                    if(journal && journal != 9999999){
+                        domain.push(['sale_journal','=',parseInt(journal)]);
+                    }
+
+                    if(date && date != 9999999){
+                        if(date == 'range'){
+                            if(desde){
+                                var date = desde.split('/')
+                                date = (date[2]+"-"+date[1]+"-"+date[0]);
+                                domain.push(['date_order','>=',date]);
+                            }
+                        }
+                    }
+                    var PosOrder = new model.web.Model('account.invoice');
+                    return PosOrder.call('getPosOrder',[domain], {
+                        context: new model.web.CompoundContext()
+                    });
+                }
+            }else{
+                var PosOrder = [];
+                return PosOrder;
+            }
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var domain = [[1,'=',1]];
+            var ResCompany = new model.web.Model('res.company');
+            return ResCompany.call('getResCompany',[domain],{
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+        /*============================
+            GET POS ORDER
+        ============================*/
+        getPosOrder:function() {
+            var self = this;
+            var content = self.PosOrder;
+            var date = self.$el.find('#current-date').val();
+            var period = self.$el.find('#current-period').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(period && period != 9999999){
+                var data = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                    utc = moment(utc._d).format('YYYY-MM-DD');
+                    return moment(utc).format('MM/YYYY') === data[0].name;
+                }));
+            }
+            return content;
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var type = $('#current-type').val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            /*
+            ==========================================
+                POS ORDER
+            ==========================================
+            */
+            var PosOrder = self.getPosOrder();
+            _.each(PosOrder, function(item){
+                var gravada = 0;
+                var impuesto = 0;
+                var exenta = 0;
+                var utc = moment.utc(item.date_order,'YYYY-MM-DD h:mm:ss A');
+                if(item.amount_tax_currency == 0){
+                    exenta = item.amount_total_currency;
+                }else{
+                    gravada =item.amount_total_currency - item.amount_tax_currency;
+                }
+                data.push({
+                    /*=======================
+                        IDS
+                    =======================*/
+                    id : item.id,
+                    /*=======================
+                        INFO
+                    =======================*/
+                    number : item.name,
+                    supplier_invoice_number: self.valorNull(item.supplier_invoice_number),
+                    date_invoice : moment(utc._d).format('DD/MM/YYYY'),
+                    date : item.date_order,
+                    partner_id : self.valorNull(item.partner_id[1]),
+                    partner_ruc : self.valorNull(item.partner_id[2]),
+                    gravada_total : accounting.formatMoney(gravada, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    percetage_total : '',
+                    tax_total : accounting.formatMoney(item.amount_tax_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    exenta_total : accounting.formatMoney(exenta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    ret_iva_total : 0,
+                    ret_renta_total : 0,
+                    amount_total : accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*=======================
+                        VALORES SIN FORMATEAR
+                    =======================*/
+                    gravada : gravada,
+                    percetage : '',
+                    tax : item.amount_tax_currency,
+                    exenta : exenta,
+                    ret_iva : 0,
+                    ret_renta : 0,
+                    amount : item.amount_total_currency,
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                });
+            });
+            /*
+            ==========================================
+                ACCOUNT INVOICE
+            ==========================================
+            */
+            if(type == 'sale' || type == 9999999){
+                var AccountInvoice = self.AccountInvoice;
+                _.each(AccountInvoice, function(item){
+                    var gravada = 0;
+                    var impuesto = 0;
+                    var exenta = 0;
+                    if(item.amount_tax_currency == 0){
+                        exenta = item.amount_total_currency;
+                    }else{
+                        gravada = item.amount_total_currency - item.amount_tax_currency;
+                    }
+                    data.push({
+                        /*=======================
+                            IDS
+                        =======================*/
+                        id : item.id,
+                        /*=======================
+                            INFO
+                        =======================*/
+                        number : item.number,
+                        supplier_invoice_number: self.valorNull(item.supplier_invoice_number),
+                        date_invoice : moment(item.date_invoice).format('DD/MM/YYYY'),
+                        date : item.date_invoice,
+                        partner_id : self.valorNull(item.partner_id[1]),
+                        partner_ruc : self.valorNull(item.partner_id[2]),
+                        gravada_total : accounting.formatMoney(gravada, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        percetage_total : '',
+                        tax_total : accounting.formatMoney(item.amount_tax_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        exenta_total : accounting.formatMoney(exenta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        ret_iva_total : 0,
+                        ret_renta_total : 0,
+                        amount_total : accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        /*=======================
+                            VALORES SIN FORMATEAR
+                        =======================*/
+                        gravada : gravada,
+                        tax : item.amount_tax_currency,
+                        exenta : exenta,
+                        ret_iva : 0,
+                        ret_renta : 0,
+                        amount : item.amount_total_currency,
+                        /*==============================
+                            TOTAL FOOTER CONFIGURATION
+                        ==============================*/
+                        decimal_places : CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+                    });
+                });
+            }
+            // data.sort(function(a,b){
+            //     // return new Date(a.date) - new Date(b.date);
+            //     return new Date(b.date) - new Date(a.date);
+            // });
+
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return 1;
+                }
+                if (a.date < b.date) {
+                    return -1;
+                }
+                return 0;
+            });
+
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            var date = $('#current-company').val();
+            var period = $('#current-period').val();
+            var pdf_type = $('#current-pdf-type').val();
+            var desde = $('#from').val();
+            var hasta = $('#to').val();
+            if(period && period != 9999999){
+                var data = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                desde = moment(data[0].date_start).format('DD/MM/YYYY');
+                hasta = moment(data[0].date_stop).format('DD/MM/YYYY');
+            }
+
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var gravada = _.reduce(_.map(row, function (map) {
+                return map.gravada;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var tax = _.reduce(_.map(row, function (map) {
+                return map.tax;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var exenta = _.reduce(_.map(row, function (map) {
+                return map.exenta;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var ret_iva = _.reduce(_.map(row, function (map) {
+                return map.ret_iva;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var ret_renta = _.reduce(_.map(row, function (map) {
+                return map.ret_renta;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var total = _.reduce(_.map(row, function (map) {
+                return map.amount;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            row.push({
+                number : 'Items: ',
+                supplier_invoice_number: row.length,
+                date_invoice : ' ',
+                partner_id : 'TOTALES: ',
+                partner_ruc : ' ',
+                gravada_total : accounting.formatMoney(gravada, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                tax_total : accounting.formatMoney(tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                exenta_total : accounting.formatMoney(exenta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                ret_iva_total : accounting.formatMoney(ret_iva, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                ret_renta_total : accounting.formatMoney(ret_renta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                amount_total : accounting.formatMoney(total, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Libro de Ventas.';
+                var pdf_name = 'libro_de_ventas_';
+                if(pdf_type == 1){
+                    pdf_type = 'l';
+                    var pdf_columnStyles = {
+                        number :{columnWidth: 27, halign:'center'},
+                        supplier_invoice_number: {columnWidth: 24, halign:'center'},
+                        date_invoice :{columnWidth: 24, halign:'center'},
+                        partner_id :{columnWidth: 52, halign:'left'},
+                        partner_ruc : {columnWidth: 18, halign:'left'},
+                        gravada_total : {columnWidth: 24.2, halign:'right'},
+                        percetage_total : {columnWidth: 8.9, halign:'right'},
+                        tax_total : {columnWidth: 24, halign:'right'},
+                        exenta_total : {columnWidth: 21, halign:'right'},
+                        ret_iva_total : {columnWidth: 18, halign:'right'},
+                        ret_renta_total : {columnWidth: 20, halign:'right'},
+                        amount_total : {columnWidth: 24, halign:'right'},
+                    };
+                }else{
+                    pdf_type = '';
+                    var pdf_columnStyles = {
+                        number :{columnWidth: 25, halign:'center'},
+                        supplier_invoice_number: {columnWidth: 24, halign:'center'},
+                        date_invoice :{columnWidth: 16, halign:'center'},
+                        partner_id :{columnWidth: 35, halign:'left'},
+                        partner_ruc : {columnWidth: 16.8, halign:'left'},
+                        gravada_total : {columnWidth: 18, halign:'right'},
+                        percetage_total : {columnWidth: 4, halign:'right'},
+                        tax_total : {columnWidth: 15, halign:'right'},
+                        exenta_total : {columnWidth: 16, halign:'right'},
+                        ret_iva_total : {columnWidth: 7, halign:'right'},
+                        ret_renta_total : {columnWidth: 7, halign:'right'},
+                        amount_total : {columnWidth: 18, halign:'right'},
+                    };
+                }
+
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawSaleJournalPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    desde,
+                    hasta,
+                );
+            }
+        },
+    });
+}

+ 847 - 0
static/src/js/reports/report_sale_journal_detallado.js

@@ -0,0 +1,847 @@
+function report_sale_journal_detallado(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSaleJournalDetalladoWidget = reporting.Base.extend({
+        template: 'ReportSaleJournalDetallado',
+        rowsData :[],
+        content :[],
+        modules: ['sale'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        clickAnalysisDetail: function(e, row, $element,field){
+
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            // console.log(self);
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                self.fecthCheckType();
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.fetchAccountInvoiceLine(AccountInvoice);
+            }).then(function (AccountInvoiceLine) {
+              self.AccountInvoiceLine = AccountInvoiceLine;
+              return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fecthCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            // var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','sale']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this
+            // console.log(self);
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open','paid']],
+                ['type', '=', 'out_invoice'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+
+            if(state != 9999999){
+                domain.push(['state','=',state]);
+            }
+
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var domain = [[1,'=',1]];
+            var ResCompany = new model.web.Model('res.company');
+            return ResCompany.call('getResCompany',[domain],{
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todas los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+
+        /*====================================================================
+            GET ACCOUNT INVOICE LINE
+        ====================================================================*/
+        getAccountInvoiceLine: function (id) {
+            var self = this;
+            return _.flatten(_.filter(self.AccountInvoiceLine,function (item) {
+                return item.invoice_id == id;
+            }));
+        },
+
+
+        // Invoice line (Linea de Factura)
+        /*====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================*/
+        fetchAccountInvoiceLine: function () {
+          var self = this;
+          var domain = [];
+          var invoice_ids = _.flatten(_.map(self.AccountInvoice, function (item) {
+              return item.id;
+          }));
+          var domain = [
+              ['invoice_id','in',invoice_ids],
+          ];
+
+          var AccountInvoiceLine = new model.web.Model('account.invoice.line');
+          return AccountInvoiceLine.call('getAccountInvoiceLine',[domain], {
+              context: new model.web.CompoundContext()
+          });
+        },
+
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var company = $('#current-company').val();
+
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+            /*
+            ==========================================
+                ACCOUNT INVOICE
+            ==========================================
+            */
+            // if(type == 'purchase'){
+                var AccountInvoice = self.AccountInvoice;
+                _.each(AccountInvoice, function(item){
+                    // console.log(item);
+                    var gravada = 0;
+                    var impuesto = 0;
+                    var exenta = 0;
+                    var tasa_10 = 0;
+                    var tasa_5 = 0;
+                    var iva_5 = 0;
+                    var iva_10 = 0;
+                    var IVA = 0;
+                    var TAX = 0;
+                    var total = 0;
+
+                    var untaxed = 0;
+
+                    var AccountInvoiceLine = self.getAccountInvoiceLine(item.id);
+
+                    if(item.amount_tax_currency == 0){
+                        exenta = item.amount_total_currency;
+                    }else{
+                        gravada = item.amount_total_currency - item.amount_tax_currency;
+                    }
+                    total = item.amount_total_currency + item.amount_tax_currency;
+                        _.each(AccountInvoiceLine,function(index2) {
+                            // if(item.id == index2.invoice_id){
+                                var IVA = 0;
+                                var TAX = 0;
+                                // Manejo de impuestos
+                                IVA = accounting.formatNumber(((index2.price_unit*index2.quantity) / 11),"","");
+                                TAX = accounting.formatNumber(((index2.price_unit*index2.quantity)-index2.price_subtotal),"","");
+
+                                // Determinar si fue aplicado algun impuesto a la factura.
+                                if(index2.price_subtotal == (index2.price_unit*index2.quantity)){
+                                    untaxed = untaxed + index2.price_subtotal;
+                                    //  untaxed = accounting.formatNumber(item.price_subtotal,"","");
+                                }else{
+                                    // Si fue aplicado impuesto, determina si fue de 10% o 5%.
+                                    if(IVA == TAX){
+                                        iva_10 = iva_10 + ((index2.price_unit*index2.quantity)-index2.price_subtotal);
+                                        tasa_10 = tasa_10 + (index2.price_unit*index2.quantity);
+
+                                        // iva_10 = accounting.formatNumber(((item.price_unit*item.quantity)-item.price_subtotal),"","");;
+                                        // tasa_10 = accounting.formatNumber((item.price_unit*item.quantity) ,"","");
+                                    }else{
+
+                                        iva_5 = iva_5 + ((index2.price_unit*index2.quantity)-index2.price_subtotal);
+                                        tasa_5 = tasa_5 + (index2.price_unit*index2.quantity);
+
+                                        //  iva_5 = accounting.formatNumber(((item.price_unit*item.quantity)-item.price_subtotal),"","");;
+                                        // tasa_5 = accounting.formatNumber((item.price_unit*item.quantity) ,"","");
+                                    }
+
+                                }
+                        });
+
+
+                    data.push({
+                        /*=======================
+                            IDS
+                        =======================*/
+                        id : item.id,
+                        /*=======================
+                            INFO
+                        =======================*/
+                        number : item.number,
+                        supplier_invoice_number: self.valorNull(item.supplier_invoice_number),
+                        date_invoice : moment(item.date_invoice).format('DD/MM/YYYY'),
+                        date : item.date_invoice,
+                        partner_id : self.valorNull(item.partner_id[1]),
+                        partner_ruc : self.valorNull(item.partner_id[2]),
+                        tasa_10 : accounting.formatMoney(tasa_10, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        iva_10 : accounting.formatMoney(iva_10, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        tasa_5 : accounting.formatMoney(tasa_5, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        iva_5 : accounting.formatMoney(iva_5, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        amount_untaxed: accounting.formatMoney(untaxed, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                      //  gravada_total : accounting.formatMoney(gravada, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        percetage_total : '',
+                        tax_total : accounting.formatMoney(item.amount_tax_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                      //  exenta_total : accounting.formatMoney(exenta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        ret_iva_total : 0,
+                        ret_renta_total : 0,
+                        amount_total : accounting.formatMoney(total, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                        /*=======================
+                            VALORES SIN FORMATEAR
+                        =======================*/
+                        gravada : gravada,
+                        tax : item.amount_tax_currency,
+                        exenta : exenta,
+                        sftasa_10 : tasa_10,
+                        sfiva_10 : iva_10,
+                        sftasa_5 : tasa_5,
+                        sfiva_5 : iva_5,
+                        sfamount_untaxed: untaxed,
+                        ret_iva : 0,
+                        ret_renta : 0,
+                        amount : total,
+                        /*==============================
+                            TOTAL FOOTER CONFIGURATION
+                        ==============================*/
+                        decimal_places : CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+                    });
+                });
+
+            // data.sort(function(a,b){
+            //     // return new Date(a.date) - new Date(b.date);
+            //     return new Date(b.date) - new Date(a.date);
+            // });
+
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return 1;
+                }
+                if (a.date < b.date) {
+                    return -1;
+                }
+                return 0;
+            });
+
+            self.content = data;
+            self.loadTable(data);
+
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            var date = $('#current-company').val();
+            var period = $('#current-period').val();
+            var pdf_type = $('#current-pdf-type').val();
+            var desde = $('#from').val();
+            var hasta = $('#to').val();
+            if(period && period != 9999999){
+                var data = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                desde = moment(data[0].date_start).format('DD/MM/YYYY');
+                hasta = moment(data[0].date_stop).format('DD/MM/YYYY');
+            }
+
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+
+            var sftasa_10 = _.reduce(_.map(row, function (map) {
+                return map.sftasa_10;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var sfiva_10 = _.reduce(_.map(row, function (map) {
+                return map.sfiva_10;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var sftasa_5 = _.reduce(_.map(row, function (map) {
+                return map.sftasa_5;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var sfiva_5 = _.reduce(_.map(row, function (map) {
+                return map.sfiva_5;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+ /*           var gravada = _.reduce(_.map(row, function (map) {
+                return map.gravada;
+            }), function (memo, num) {
+                return memo + num;
+            });*/
+
+            var sfamount_untaxed = _.reduce(_.map(row, function (map) {
+                return map.sfamount_untaxed;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var tax = _.reduce(_.map(row, function (map) {
+                return map.tax;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+
+            var ret_iva = _.reduce(_.map(row, function (map) {
+                return map.ret_iva;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var ret_renta = _.reduce(_.map(row, function (map) {
+                return map.ret_renta;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            var total = _.reduce(_.map(row, function (map) {
+                return map.amount;
+            }), function (memo, num) {
+                return memo + num;
+            });
+
+            row.push({
+                number : 'Items: ',
+                supplier_invoice_number: row.length,
+                date_invoice : ' ',
+                partner_id : 'TOTALES: ',
+                partner_ruc : ' ',
+                tasa_10 : accounting.formatMoney(sftasa_10, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                iva_10 : accounting.formatMoney(sfiva_10, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                tasa_5 : accounting.formatMoney(sftasa_5, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                iva_5 : accounting.formatMoney(sfiva_5, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                amount_untaxed : accounting.formatMoney(sfamount_untaxed, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                percetage_total : '',
+                tax_total : accounting.formatMoney(tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+               // exenta_total : accounting.formatMoney(exenta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                ret_iva_total : accounting.formatMoney(ret_iva, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                ret_renta_total : accounting.formatMoney(ret_renta, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                amount_total : accounting.formatMoney(total, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Libro de Ventas.';
+                var pdf_name = 'libro_de_ventas_';
+                if(pdf_type == 1){
+                    pdf_type = 'l';
+                    var pdf_columnStyles = {
+                        number :{columnWidth: 27, halign:'center'},
+                        supplier_invoice_number: {columnWidth: 24, halign:'center'},
+                        date_invoice :{columnWidth: 24, halign:'center'},
+                        partner_id :{columnWidth: 52, halign:'left'},
+                        partner_ruc : {columnWidth: 17.3, halign:'left'},
+                        tasa_5 : {columnWidth: 14.7, halign:'right'},
+                        iva_5 : {columnWidth: 12.7, halign:'right'},
+                        tasa_10 : {columnWidth: 14.7, halign:'right'},
+                        iva_10 : {columnWidth: 12.7, halign:'right'},
+                        amount_untaxed : {columnWidth: 12.8, halign:'right'},
+                       // percetage_total : {columnWidth: 3, halign:'right'},
+                        tax_total : {columnWidth: 24, halign:'right'},
+                        ret_iva_total : {columnWidth: 18, halign:'right'},
+                        ret_renta_total : {columnWidth: 18, halign:'right'},
+                        amount_total : {columnWidth: 27, halign:'right'},
+                    };
+                }else{
+                    pdf_type = '';
+                    var pdf_columnStyles = {
+                        number :{columnWidth: 25, halign:'center'},
+                        supplier_invoice_number: {columnWidth: 24, halign:'center'},
+                        date_invoice :{columnWidth: 16, halign:'center'},
+                        partner_id :{columnWidth: 32, halign:'left'},
+                        partner_ruc : {columnWidth: 17.3, halign:'left'},
+                        tasa_5 : {columnWidth: 15.0, halign:'right'},
+                        iva_5 : {columnWidth: 13.0, halign:'right'},
+                        tasa_10 : {columnWidth: 14.7, halign:'right'},
+                        iva_10 : {columnWidth: 12.7, halign:'right'},
+                        amount_untaxed : {columnWidth: 12.8, halign:'right'},
+                       // percetage_total : {columnWidth: 1, halign:'right'},
+                       // tax_total : {columnWidth: 15, halign:'right'},
+                      //  ret_iva_total : {columnWidth: 7, halign:'right'},
+                       // ret_renta_total : {columnWidth: 7, halign:'right'},
+                        amount_total : {columnWidth: 16, halign:'right'},
+                    };
+                }
+
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawSaleJournalPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    desde,
+                    hasta,
+                );
+            }
+        },
+    });
+}

+ 923 - 0
static/src/js/reports/report_sale_ranking_product.js

@@ -0,0 +1,923 @@
+function report_sale_ranking_product(reporting) {
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSaleRankingProductWidget = reporting.Base.extend({
+        template: 'ReportSaleRankingProduct',
+        rowsData: [],
+        content: [],
+        modules: ['product_brand', 'point_of_sale'],
+
+        events: {
+            'click #generate': 'fetchGenerate',
+            'change #current-company': 'updateSelections',
+            'change #current-attribute': 'updateAttributeSelections',
+            'change #current-store': 'updateJournalSelections',
+            'change #current-date': 'ShowDateRange',
+            'click .build-chart':'CallChart',
+            'click .print-report':'clickOnAction',
+        },
+
+        init: function(parent) {
+            this._super(parent);
+        },
+
+        start: function() {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull: function(dato) {
+            var valor = "";
+            if (dato) {
+                valor = dato;
+            }
+            return valor;
+        },
+
+        checkModule: function(module) {
+            var self = this;
+            return _.filter(self.session.module_list, function(item) {
+                return item == module;
+            });
+        },
+
+        ShowDateRange: function() {
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if (date == 'range') {
+                self.$el.find('.datepicker').css('display', 'block');
+            }
+            if (date != 'range') {
+                self.$el.find('.datepicker').css('display', 'none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                if(self.AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(self.AccountJournal,function(item){
+                        if(item.type == 'sale'){
+                            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                        }
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                /*
+                =================================
+                    PRODUCT CATEGORY
+                =================================
+                */
+                self.ProductCategory = IntialSQL.categories;
+                if(self.ProductCategory.length > 1){
+                    self.$el.find('#current-category').append('<option value="9999999">Todos las Categorias</option>');
+                    _.each(self.ProductCategory,function(item){
+                        self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }
+                self.ProductBrand = IntialSQL.brands;
+                if(self.ProductBrand.length > 1){
+                    self.$el.find('#current-brand').append('<option value="9999999">Todas las Marcas</option>');
+                    _.each(self.ProductBrand,function(item){
+                        self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.brand').css('display','none');
+                }
+                self.ProductAttribute = IntialSQL.attributes;
+                if(self.ProductAttribute.length > 1){
+                    self.$el.find('#current-attribute').append('<option value="9999999">Todas los atributos</option>');
+                    _.each(self.ProductAttribute,function(item){
+                        self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute').css('display','none');
+                }
+                self.ProductAttributeValue = IntialSQL.attribute_values;
+                if(self.ProductAttributeValue.length > 1){
+                    self.$el.find('#current-attribute-value').append('<option value="9999999">Todas los valores de atributos</option>');
+                    _.each(self.ProductAttributeValue,function(item){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute-value').css('display','none');
+                }
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchCheckType();
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.chart-container').css('display', 'none');
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoiceLine = DataSQL.invoice_lines;
+                self.PosOrderLine = DataSQL.order_lines;
+                self.ProductProduct = DataSQL.products;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-sale-product-ranking');
+            return data;
+        },
+
+        fetchCheckType: function() {
+            var self = this;
+            var modules = self.checkModule('point_of_sale');
+            if (modules.length == 0) {
+                self.$el.find('.type').css('display', 'none');
+            }
+        },
+
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateAttributeSelections: function () {
+            var self = this;
+            var attribute_value;
+            var attribute = self.$el.find('#current-attribute').val();
+            if(attribute != 9999999){
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    if(parseFloat(attribute) == item.attribute_id){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var journal;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_id){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getPosOrderLine:function() {
+            var self = this;
+            var content = self.PosOrderLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var type = self.$el.find('#current-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'sale'){
+                    content = [];
+                }
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        getAccountInvoiceLine:function() {
+            var self = this;
+            var content = self.AccountInvoiceLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var type = self.$el.find('#current-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'tpv'){
+                    content = [];
+                }
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        getAccountInvoiceLineByProduct:function(product_id,type) {
+            var self = this;
+            return  _.filter(self.AccountInvoiceLine,function (item) {
+                return item.product_id == product_id && item.type == type;
+            });
+        },
+
+        getPosOrderLineByProduct:function(product_id) {
+            var self = this;
+            return  _.filter(self.PosOrderLine,function (item) {
+                return item.product_id == product_id;
+            });
+        },
+
+        BuildTable: function() {
+            var self = this;
+            var data = [];
+            var display_name;
+            var modules = self.checkModule('product_brand');
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            self.AccountInvoiceLine = self.getAccountInvoiceLine();
+            self.PosOrderLine = self.getPosOrderLine();
+            var ProductProduct = self.ProductProduct;
+            _.each(ProductProduct, function(item) {
+                if(item.attribute_values[0] == null){
+                    display_name = item.product_name;
+                }else{
+                    display_name = item.product_name + ' (' + _.uniq(item.attribute_values) + ')';
+                }
+                if(modules.length > 0){
+                    if(item.product_brand_id != null){
+                        display_name = display_name + ' ( ' + item.brand_name + ')';
+                    }
+                }
+                /*
+                    INVOICE
+                */
+                var AccountInvoiceLine = self.getAccountInvoiceLineByProduct(item.product_id,'out_invoice');
+                var InvoiceLineQuantity = _.reduce(_.map(AccountInvoiceLine, function(map) {
+                    return map.quantity;
+                }), function(meno, num) {
+                    return meno + num;
+                }, 0);
+                var InvoiceLineAmount = _.reduce(_.map(AccountInvoiceLine, function(map) {
+                    return map.subtotal + map.tax;
+                }), function(meno, num) {
+                    return meno + num;
+                }, 0);
+                /*
+                    INVOICE REFUND
+                */
+                var AccountInvoiceLineRefund = self.getAccountInvoiceLineByProduct(item.product_id,'out_refund');
+                var InvoiceLineRefundQuantity = _.reduce(_.map(AccountInvoiceLineRefund, function(map) {
+                    return map.quantity;
+                }), function(meno, num) {
+                    return meno + num;
+                }, 0);
+                var InvoiceLineRefundAmount = _.reduce(_.map(AccountInvoiceLineRefund, function(map) {
+                    return map.subtotal + map.tax;
+                }), function(meno, num) {
+                    return meno + num;
+                }, 0);
+                /*
+                    POSORDER
+                */
+                var PosOrderLine = self.getPosOrderLineByProduct(item.product_id);
+                var PosOrderQuantity = _.reduce(_.map(PosOrderLine, function(map) {
+                    return map.quantity;
+                }), function(meno, num) {
+                    return meno + num;
+                }, 0);
+                var PosOrderAmount = _.reduce(_.map(PosOrderLine, function(map) {
+                    return map.subtotal + map.tax;
+                }), function(meno, num) {
+                    return meno + num;
+                }, 0);
+
+                var quantity = PosOrderQuantity + InvoiceLineQuantity - InvoiceLineRefundQuantity;
+                var amount = PosOrderAmount + InvoiceLineAmount - InvoiceLineRefundAmount;
+
+                if(quantity != 0 || amount != 0){
+                    if(amount < 0 && quantity > 0){
+                        quantity = quantity * -1;
+                    }
+                    data.push({
+                        id:item.product_id,
+                        name:display_name,
+                        brand_name: item.brand_name,
+                        attribute_value_ids:item.attribute_value_ids,
+                        quantity:accounting.formatNumber(quantity,2,'.',','),
+                        amount:accounting.formatMoney(amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                        /*
+                            NO FORMAT
+                        */
+                        quantity_no_format:quantity,
+                        amount_no_format:amount,
+                        /*
+                            FOOTER
+                        */
+                        decimal_places: CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+                    });
+                }
+            });
+
+            data.sort(function(a, b) {
+                return b.amount_no_format - a.amount_no_format;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display', 'block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+        /*
+        ======================================================================
+            LLAMAR LOS GRAFICOS
+        ======================================================================
+        */
+        CallChart: function() {
+            var self = this;
+            var data = self.content;
+            var i,item,num,amount_total;
+            var rank = 10;
+            var label = [];
+            var body = [];
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            /*
+            ================================================
+                BAR CHART
+            ================================================
+            */
+            var BarChart = new reporting.ReportChartWidget(self);
+            for (i = 0; i < rank; i++) {
+                if (data[i]) {
+                    item = data[i];
+                }else {
+                    item = {};
+                    item.name = "N/A";
+                    item.amount_no_format = 0;
+                }
+                label.push(item.name.trim());
+                body.push(item.amount_no_format);
+            }
+            BarChart.BuildBarChart(data, CurrencyBase, label, body);
+            /*
+            ================================================
+                PIE CHART
+            ================================================
+            */
+            var PieChart = new reporting.ReportChartWidget(self);
+            label = [];
+            body = [];
+            amount_total = _.reduce(_.map(data, function(map) {
+                return map.amount_no_format;
+            }), function(meno, num) {
+                return meno + num;
+            }, 0);
+            for (i = 0; i < rank; i++) {
+                if (data[i]) {
+                    item = data[i];
+                } else {
+                    item = {};
+                    item.name = "N/A";
+                    item.amount_no_format = 0;
+                }
+                label.push(item.name.trim());
+                body.push((item.amount_no_format / amount_total) * 100);
+            }
+            num = 0;
+            for (i = 9; i < data.length; i++) {
+                num += data[i].amount_no_format;
+            }
+            if (num > 0) {
+                label.push('Otros Productos');
+                body.push((num / amount_total) * 100);
+            }
+            PieChart.BuildPieChart(data, CurrencyBase, label, body);
+            /*
+            ================================================
+                DOUGHNUT CHART
+            ================================================
+            */
+            var DoughnutChart = new reporting.ReportChartWidget(self);
+            var info = [];
+            var content = [];
+            var ProductAttributeValue = self.ProductAttributeValue;
+            if (ProductAttributeValue.length > 0) {
+                _.each(ProductAttributeValue, function(item) {
+                    content = _.filter(data, function(index) {
+                        return _.contains(index.attribute_value_ids, item.id);
+                    });
+
+                    var amount = _.reduce(_.map(content, function(map) {
+                        return map.amount_no_format;
+                    }), function(meno, num) {
+                        return meno + num;
+                    }, 0);
+                    if (amount > 0) {
+                        info.push({
+                            name: item.attribute_name + ' - ' + item.name + ' - ' + accounting.formatMoney(amount, CurrencyBase.symbol, CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                            amount_no_format: amount
+                        });
+                    }
+                });
+                info.sort(function(a, b) {
+                    return b.amount_no_format - a.amount_no_format;
+                });
+
+                rank = 9;
+                label = [];
+                body = [];
+
+                amount_total = _.reduce(_.map(data, function(map) {
+                    return map.amount_no_format;
+                }), function(meno, num) {
+                  return meno + num;
+                }, 0);
+
+                for (i = 0; i < rank; i++) {
+                    if (info[i]) {
+                        item = info[i];
+                    } else {
+                        item = {};
+                        item.name = "N/A";
+                        item.amount_no_format = 0;
+                    }
+                    label.push(item.name.trim());
+                    body.push((item.amount_no_format / amount_total) * 100);
+                }
+                num = 0;
+                for (i = 9; i < info.length; i++) {
+                    num += info[i].amount_no_format;
+                }
+                if (num > 0) {
+                    label.push('Otros Atributos');
+                    body.push((num / amount_total) * 100);
+                }
+                DoughnutChart.BuildDoughnutChart(data, CurrencyBase, label, body);
+                self.$el.find('.doughnut-chart').css('display', 'block');
+            }
+            self.$el.find('.chart-container').css('display', 'block');
+        },
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable: function(rowsTable) {
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function(e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.CompanyLogo,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = ResCompany[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns = [];
+            var rows = [];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var quantity = QuantityFooter(row);
+            var amount = TotalFooter(row);
+            row.push({
+                name:'Totales',
+                brand_name: brand_name,
+                quantity:quantity,
+                amount:amount,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Ranking de productos (+Vendidos).';
+                var pdf_type = '';
+                var pdf_name = 'ranking_productos_';
+                var pdf_columnStyles = {
+                    name: {halign: 'left'},
+                    brand_name: {columnWidth: 15, halign: 'left'},
+                    quantity: {columnWidth: 30, halign: 'right'},
+                    amount: {columnWidth: 30, halign: 'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function() {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var type = self.$el.find('#current-type').val();
+            var category = self.$el.find('#current-category').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if (company && company != 9999999) {
+                var ResCompany = _.filter(self.ResCompany, function(item) {
+                    return item.id == company;
+                });
+                filter.push({
+                    title: 'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if (store && store != 9999999) {
+                var ResStore = _.filter(self.ResStore, function(item) {
+                    return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value: ResStore[0].name,
+                });
+            }
+            if (type && type != 9999999) {
+                filter.push({
+                    title: 'Tipo de Venta',
+                    value: $("#current-type option:selected").text(),
+                });
+            }
+            if (category && category != 9999999) {
+                var categ = _.filter(self.ProductCategory, function(item) {
+                    return item.id == category;
+                });
+                filter.push({
+                    title: 'Categoría',
+                    value: categ[0].name,
+                });
+            }
+            if (date && date != 9999999) {
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+                if (date == 'range') {
+                    filter.push({
+                        title: 'Fecha',
+                        value: desde + ' al ' + hasta,
+                    });
+                } else {
+                    var fecha;
+                    if (date == 'today') {
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if (date == 'yesterday') {
+                        fecha = moment().add(-1, 'days').format('DD/MM/YYYY');
+                    }
+                    if (date == 'currentMonth') {
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if (date == 'lastMonth') {
+                        fecha = moment().add(-1, 'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value: fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 565 - 0
static/src/js/reports/report_sale_summary.js

@@ -0,0 +1,565 @@
+function report_sale_summary(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSaleSummaryWidget = reporting.Base.extend({
+        template: 'ReportSaleSummary',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                if(self.AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(self.AccountJournal,function(item){
+                        if(item.type == 'sale'){
+                            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                        }
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoice = DataSQL.invoices;
+                self.PosOrder = DataSQL.orders;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-sale-summary');
+            return data;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getAccountInvoiceByStore: function (id,type) {
+            var self = this;
+            return _.filter(self.AccountInvoice,function (item) {
+                return item.store_id == id & item.type == type;
+            });
+        },
+
+        getPosOrderByStore: function (id) {
+            var self = this;
+            return _.filter(self.PosOrder,function (item) {
+                return item.store_id == id;
+            });
+        },
+
+        getResStore: function () {
+            var self = this;
+            var content = self.ResStore;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.company_id[0] === parseInt(company);
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (inv) {
+                    return inv.id === parseInt(store);
+                }));
+            }
+            return content;
+        },
+
+        getPosOrder:function() {
+            var self = this;
+            var content = self.PosOrder;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        getAccountInvoice:function() {
+            var self = this;
+            var content = self.AccountInvoice;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            self.AccountInvoice = self.getAccountInvoice();
+            self.PosOrder = self.getPosOrder();
+            var amount = 0;
+            var AccountInvoice = [];
+            var AccountInvoiceRefund = [];
+            var PosOrder = [];
+            var ResStore = self.getResStore();
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            _.each(ResStore,function(item) {
+                var info = [];
+                AccountInvoice = self.getAccountInvoiceByStore(item.id,'out_invoice');
+                AccountInvoice = _.reduce(_.map(AccountInvoice, function (map) {
+                    return map.amount;
+                }), function (meno,num) {
+                    return meno + num;
+                }, 0);
+
+                PosOrder = self.getPosOrderByStore(item.id);
+                PosOrder = _.reduce(_.map(PosOrder, function (map) {
+                    return map.amount;
+                }), function (meno,num) {
+                    return meno + num;
+                }, 0);
+
+                AccountInvoiceRefund = self.getAccountInvoiceByStore(item.id,'out_refund');
+                AccountInvoiceRefund = _.reduce(_.map(AccountInvoiceRefund, function (map) {
+                    return map.amount;
+                }), function (meno,num) {
+                    return meno + num;
+                }, 0);
+
+                info.push({
+                    name:'Ventas',
+                    amount_total:accounting.formatMoney(AccountInvoice + PosOrder, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    amount:AccountInvoice + PosOrder,
+                });
+
+                info.push({
+                    name:'Notas de Crédito',
+                    amount_total:accounting.formatMoney(AccountInvoiceRefund, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    amount:AccountInvoiceRefund,
+                });
+
+                amount = (AccountInvoice + PosOrder) - AccountInvoiceRefund;
+
+                data.push({
+                    store: item.name,
+                    amount_total: accounting.formatMoney(amount, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    amount: amount,
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                    /*
+                    ================================
+                        DATA
+                    ================================
+                    */
+                    info: info,
+                });
+            });
+            data.sort(function(a, b) {
+                return b.amount - a.amount;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            var CurrencyBase;
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.CompanyLogo,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = ResCompany[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var amount = totalFormatter(row);
+            row.push({
+                store: 'Totales',
+                amount_total: amount,
+            });
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Resumen de Ventas';
+                var pdf_type = '';
+                var pdf_name = 'resumen_ventas_';
+                var pdf_columnStyles =  {
+                    store:{halign:'left'},
+                    amount_total:{columnWidth: 50, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                    return item.id == store;
+                });
+
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde + ' al ' + hasta,
+                    });
+                }
+                else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        }
+    });
+}

+ 991 - 0
static/src/js/reports/report_sale_utility_analytic.js

@@ -0,0 +1,991 @@
+function report_sale_utility_analytic(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSaleUtilityAnalyticWidget = reporting.Base.extend({
+        template: 'ReportSaleUtilityAnalytic',
+        rowsData :[],
+        content :[],
+        modules: ['product_brand','point_of_sale'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-attribute' : 'updateAttributeSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+        },
+
+        clickAnalysisDetail: function(e, row, $element,field){
+            if (field == 'product_name'){
+                this.do_action({
+                    name:"Producto",
+                    type: 'ir.actions.act_window',
+                    res_model: "product.product",
+                    views: [[false,'form']],
+                    target: 'new',
+                    domain: [['id','=', row.product_id]],
+                    context: {},
+                    flags: {'form': {'action_buttons': false, 'options': {'mode': 'view'}}},
+                    res_id: row.product_id,
+                });
+            }
+            e.stopImmediatePropagation();
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModule : function(module){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === module;
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                if(self.AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(self.AccountJournal,function(item){
+                        if(item.type == 'sale'){
+                            self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                        }
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                /*
+                =================================
+                    PRODUCT CATEGORY
+                =================================
+                */
+                self.ProductCategory = IntialSQL.categories;
+                if(self.ProductCategory.length > 1){
+                    self.$el.find('#current-category').append('<option value="9999999">Todos las Categorias</option>');
+                    _.each(self.ProductCategory,function(item){
+                        self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }
+                self.ProductBrand = IntialSQL.brands;
+                if(self.ProductBrand.length > 1){
+                    self.$el.find('#current-brand').append('<option value="9999999">Todas las Marcas</option>');
+                    _.each(self.ProductBrand,function(item){
+                        self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.brand').css('display','none');
+                }
+                self.ProductAttribute = IntialSQL.attributes;
+                if(self.ProductAttribute.length > 1){
+                    self.$el.find('#current-attribute').append('<option value="9999999">Todas los atributos</option>');
+                    _.each(self.ProductAttribute,function(item){
+                        self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute').css('display','none');
+                }
+                self.ProductAttributeValue = IntialSQL.attribute_values;
+                if(self.ProductAttributeValue.length > 1){
+                    self.$el.find('#current-attribute-value').append('<option value="9999999">Todas los valores de atributos</option>');
+                    _.each(self.ProductAttributeValue,function(item){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute-value').css('display','none');
+                }
+                return self.fetchIrModuleModule();
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchCheckType();
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountInvoiceLine = DataSQL.invoice_lines;
+                self.PosOrderLine = DataSQL.order_lines;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-sale-utility-analytic');
+            return data;
+        },
+
+        fetchIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        fetchCheckType: function(){
+            var self = this;
+            var modules = self.checkModule('point_of_sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateAttributeSelections: function () {
+            var self = this;
+            var attribute_value;
+            var attribute = self.$el.find('#current-attribute').val();
+            if(attribute != 9999999){
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    if(parseFloat(attribute) == item.attribute_id){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var journal;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_id){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getProductCategory: function (id) {
+            var self = this;
+            var category;
+            category =  _.filter(self.ProductCategory,function (item) {
+                return item.id == id;
+            });
+            if(category.length > 0)
+                return category[0].name;
+        },
+
+        getPosOrderLine:function() {
+            var self = this;
+            var content = self.PosOrderLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var type = self.$el.find('#current-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'sale'){
+                    content = [];
+                }
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                            utc = moment(utc._d).format('YYYY-MM-DD');
+                            return moment(utc).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        var utc = moment.utc(inv.date,'YYYY-MM-DD h:mm:ss A');
+                        utc = moment(utc._d).format('YYYY-MM-DD');
+                        return moment(utc).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        getAccountInvoiceLine:function(invoice_type) {
+            var self = this;
+            var content = self.AccountInvoiceLine;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var type = self.$el.find('#current-type').val();
+            var journal = self.$el.find('#current-journal').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            content = _.flatten(_.filter(content,function (item) {
+                return item.type == invoice_type;
+            }));
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(type && type != 9999999){
+                if(type == 'tpv'){
+                    content = [];
+                }
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            if(category && category != 9999999){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                content = _.flatten(_.filter(content,function (inv) {
+                    return _.contains(categ_ids, inv.categ_id);
+                }));
+            }
+            if(brand && brand != 9999999){
+                content = _.filter(content,function (item) {
+                    return item.product_brand_id == parseInt(brand);
+                });
+            }
+            if(attribute && attribute != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_value_ids, parseInt(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        BuildTable: function(){
+            var self = this;
+
+            var data = [];
+            var CurrencyBase = self.ResCompany[0].currency_id;
+            var PosOrderLine = self.getPosOrderLine();
+            var display_name;
+            var modules = self.checkModule('product_brand');
+            var margin;
+            _.each(PosOrderLine,function(item) {
+                var category = self.getProductCategory(item.categ_id);
+                if(item.attribute_values[0] == null){
+                    display_name = item.product_name;
+                }else{
+                    display_name = item.product_name + ' (' + _.uniq(item.attribute_values) + ')';
+                }
+                if(modules.length > 0){
+                    if(item.product_brand_id != null){
+                        display_name = display_name + ' ( ' + item.brand_name + ')';
+                    }
+                }
+                margin = (((item.subtotal) - (item.cost * item.quantity)) / (item.subtotal)) * 100;
+                data.push({
+                    /*
+                    =============================
+                        IDS
+                    =============================
+                    */
+                    id:item.order_line_id,
+                    product_id:item.product_id,
+                    /*
+                    =============================
+                        INFO
+                    =============================
+                    */
+                    number:item.name,
+                    date_invoice:moment(item.date).format('DD/MM/YYYY'),
+                    product_name:display_name,
+                    cost:accounting.formatMoney(item.cost, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    price_unit:accounting.formatMoney(item.price_unit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    quantity:accounting.formatNumber(item.quantity,2,'.',','),
+                    cost_total:accounting.formatMoney(item.cost * item.quantity, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    subtotal:accounting.formatMoney(item.subtotal, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.subtotal + item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    margin:accounting.formatNumber(margin,2,'.',',') + '%',
+                    profit:accounting.formatMoney((item.subtotal) - (item.cost * item.quantity), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*
+                    =============================
+                        VALORES SIN FORMATEAR
+                    =============================
+                    */
+                    date:item.date,
+                    cost_value:item.cost,
+                    price_unit_value:item.price_unit,
+                    quantity_value:item.quantity,
+                    cost_total_value:item.cost * item.quantity,
+                    subtotal_value:item.subtotal,
+                    tax_value:item.tax,
+                    total_value:item.subtotal + item.tax,
+                    profit_value:(item.subtotal) - (item.cost * item.quantity),
+                    /*
+                    ==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            var AccountInvoiceLine = self.getAccountInvoiceLine('out_invoice');
+            _.each(AccountInvoiceLine,function(item) {
+                var category = self.getProductCategory(item.categ_id);
+                if(item.attribute_values[0] == null){
+                    display_name = item.product_name;
+                }else{
+                    display_name = item.product_name + ' (' + _.uniq(item.attribute_values) + ')';
+                }
+                if(modules.length > 0){
+                    if(item.product_brand_id != null){
+                        display_name = display_name + ' ( ' + item.brand_name + ')';
+                    }
+                }
+                margin = (((item.subtotal) - (item.cost * item.quantity)) / (item.subtotal)) * 100;
+                data.push({
+                    /*
+                    =============================
+                        IDS
+                    =============================
+                    */
+                    id:item.account_invoice_line_id,
+                    product_id:item.product_id,
+                    /*
+                    =============================
+                        INFO
+                    =============================
+                    */
+                    number:item.number,
+                    date_invoice:moment(item.date).format('DD/MM/YYYY'),
+                    product_name:display_name,
+                    cost:accounting.formatMoney(item.cost, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    price_unit:accounting.formatMoney(item.price_unit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    quantity:accounting.formatNumber(item.quantity,2,'.',','),
+                    cost_total:accounting.formatMoney(item.cost * item.quantity, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    subtotal:accounting.formatMoney(item.subtotal, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney(item.subtotal + item.tax, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    margin:accounting.formatNumber(margin,2,'.',',') + '%',
+                    profit:accounting.formatMoney((item.subtotal) - (item.cost * item.quantity), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*
+                    =============================
+                        VALORES SIN FORMATEAR
+                    =============================
+                    */
+                    date:item.date,
+                    cost_value:item.cost,
+                    price_unit_value:item.price_unit,
+                    quantity_value:item.quantity,
+                    cost_total_value:item.cost * item.quantity,
+                    subtotal_value:item.subtotal,
+                    tax_value:item.tax,
+                    total_value:item.subtotal + item.tax,
+                    profit_value: (item.subtotal) - (item.cost * item.quantity),
+                    /*
+                    ==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            var AccountInvoiceLineRefund = self.getAccountInvoiceLine('out_refund');
+            _.each(AccountInvoiceLineRefund,function(item) {
+                var category = self.getProductCategory(item.categ_id);
+                if(item.attribute_values[0] == null){
+                    display_name = item.product_name;
+                }else{
+                    display_name = item.product_name + ' (' + _.uniq(item.attribute_values) + ')';
+                }
+                if(modules.length > 0){
+                    if(item.product_brand_id != null){
+                        display_name = display_name + ' ( ' + item.brand_name + ')';
+                    }
+                }
+                margin = 0 + '%';
+                data.push({
+                    /*
+                    =============================
+                        IDS
+                    =============================
+                    */
+                    id:item.account_invoice_line_id,
+                    product_id:item.product_id,
+                    /*
+                    =============================
+                        INFO
+                    =============================
+                    */
+                    number:item.number,
+                    date_invoice:moment(item.date).format('DD/MM/YYYY'),
+                    product_name:display_name,
+                    cost:accounting.formatMoney(item.cost * -1, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    price_unit:accounting.formatMoney(item.price_unit * -1, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    quantity:accounting.formatNumber(item.quantity * -1,2,'.',','),
+                    cost_total:accounting.formatMoney((item.cost * item.quantity) * -1, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    subtotal:accounting.formatMoney(item.subtotal * -1, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    tax:accounting.formatMoney(item.tax * -1, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    total:accounting.formatMoney((item.subtotal + item.tax) * -1, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    margin:accounting.formatNumber(margin,2,'.',',') + '%',
+                    profit:accounting.formatMoney((item.subtotal - (item.cost * item.quantity)) * -1, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*
+                    =============================
+                        VALORES SIN FORMATEAR
+                    =============================
+                    */
+                    date:item.date,
+                    cost_value:item.cost*-1,
+                    price_unit_value:item.price_unit*-1,
+                    quantity_value:item.quantity*-1,
+                    cost_total_value:(item.cost * item.quantity)*-1,
+                    subtotal_value:item.subtotal*-1,
+                    tax_value:item.tax*-1,
+                    total_value:(item.subtotal + item.tax)*-1,
+                    profit_value:(item.subtotal - (item.cost * item.quantity))*-1,
+                    /*
+                    ==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+            });
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return -1;
+                }
+                if (a.date < b.date) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.CompanyLogo,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = ResCompany[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns = [];
+            var rows = [];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var quantity = QuantityFooter(row);
+            var cost_total = CostTotalFooter(row);
+            var subtotal = SubtotalFooter(row);
+            var tax = TaxFooter(row);
+            var total = TotalFooter(row);
+            var profit = ProfitFooter(row);
+
+            row.push({
+                number:'Totales',
+                quantity:quantity,
+                cost_total:cost_total,
+                subtotal:subtotal,
+                tax:tax,
+                total:total,
+                profit:profit,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Análisis de Utilidad.';
+                var pdf_type = 'l';
+                var pdf_name = 'analisis_de_utilidad_de_ventas';
+                var pdf_columnStyles = {
+                    number:{columnWidth: 25, halign:'center'},
+                    date_invoice:{columnWidth: 18, halign:'center'},
+                    product_name:{columnWidth: 'auto', halign:'left'},
+                    cost:{columnWidth: 20, halign:'right'},
+                    price_unit:{columnWidth: 20, halign:'right'},
+                    quantity:{columnWidth: 20, halign:'right'},
+                    cost_total:{columnWidth: 20, halign:'right'},
+                    subtotal:{columnWidth: 20, halign:'right'},
+                    tax:{columnWidth: 20, halign:'right'},
+                    total:{columnWidth: 20, halign:'right'},
+                    margin:{columnWidth: 20, halign:'right'},
+                    profit:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+               );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var journal = self.$el.find('#current-journal').val();
+            var type = self.$el.find('#current-type').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                    return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(journal && journal != 9999999){
+                var AccountJournal = _.filter(self.AccountJournal, function(item){
+                    return item.id == journal;
+                });
+                filter.push({
+                    title:'Factura',
+                    value: AccountJournal[0].name,
+                });
+            }
+            if(type && type != 9999999){
+                filter.push({
+                    title: 'Tipo de Venta',
+                    value:  $("#current-type option:selected").text(),
+                });
+            }
+            if(category && category != 9999999){
+                var categ =  _.filter(self.ProductCategory,function (item) {
+                    return item.id == category;
+                });
+                filter.push({
+                    title: 'Categoría',
+                    value: categ[0].name,
+                });
+            }
+            if(brand && brand != 9999999){
+                var content =  _.filter(self.ProductBrand,function (item) {
+                    return item.id == brand;
+                });
+                filter.push({
+                    title: 'Marca',
+                    value: brand[0].name,
+                });
+            }
+            if(attribute && attribute != 9999999){
+                var attr =  _.filter(self.ProductAttribute,function (item) {
+                    return item.id == attribute;
+                });
+                filter.push({
+                    title: 'Atributo',
+                    value: attr[0].name,
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                var attr_value =  _.filter(self.ProductAttributeValue,function (item) {
+                    return item.id == attribute_value;
+                });
+                filter.push({
+                    title: 'Valor de Atributo',
+                    value: attr_value[0].name,
+                });
+            }
+
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else{
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title:'Fecha',
+                        value:fecha,
+                    });
+                }
+            }
+            return filter;
+        }
+    });
+}

+ 580 - 0
static/src/js/reports/report_stock_history.js

@@ -0,0 +1,580 @@
+function report_stock_history(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportStockHistoryWidget = reporting.Base.extend({
+        template: 'ReportStockHistory',
+        rowsData :[],
+        content :[],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-store' : 'updateTypeSelections',
+            'change #current-date' : 'ShowDateRange',
+            'change #current-company': 'updateSelections',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                  self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                  _.each(ResCompany,function(item){
+                    self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                  });
+                }else{
+                  self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 0){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchStockPickingType();
+            }).then(function(StockPickingType){
+                self.StockPickingType = StockPickingType;
+                if(StockPickingType.length > 0){
+                    self.$el.find('#current-type').append('<option value="9999999">Todas las operaciones</option>');
+                    _.each(StockPickingType,function(item){
+                        self.$el.find('#current-type').append('<option value="' + item.id + '">' + item.warehouse_id[1] +' '+item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.type').css('display','none');
+                }
+                return self.fetchStockLocation();
+            }).then(function(StockLocation){
+                self.StockLocation = StockLocation;
+                if(StockLocation.length > 1){
+                    self.$el.find('#current-location').append('<option value="9999999">Todas las ubicaciones</option>');
+                    _.each(StockLocation,function(item){
+                        self.$el.find('#current-location').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                    });
+
+                    self.$el.find('#current-location2').append('<option value="9999999">Todas las ubicaciones</option>');
+                    _.each(StockLocation,function(item){
+                        self.$el.find('#current-location2').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.location').css('display','none');
+                }
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+
+            self.fetchStockPicking().then(function(StockPicking) {
+                return StockPicking;
+            }).then(function (StockPicking) {
+                self.StockPicking = StockPicking;
+                return self.fetchStockMove();
+            }).then(function (StockMove){
+                self.StockMove = StockMove;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fetchIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed']];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            STOCK PICKING TYPE
+        ====================================================================*/
+        fetchStockPickingType:function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('stock.picking.type');
+            var field=['id','name','code','warehouse_id','store_id'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+        /*====================================================================
+            STOCK LOCATION
+        ====================================================================*/
+        fetchStockLocation: function () {
+            var self = this;
+            var domain = [
+                ['active', '=',true],
+            ];
+            var StockLocation = new model.web.Model('stock.location');
+            return StockLocation.call('getStockLocation',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+          STOCK MOVE
+        ====================================================================*/
+        fetchStockMove: function () {
+            var self = this;
+
+            var picking_ids = _.flatten(_.map(self.StockPicking, function (item) {
+                return item.id;
+            }));
+            var domain = [
+                ['state','=','done'],
+                ['picking_id','in',picking_ids],
+            ];
+
+            var StockMove = new model.web.Model('stock.move');
+            return StockMove.call('getStockMove',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            STOCK PICKING
+        ====================================================================*/
+        fetchStockPicking: function () {
+            var self = this;
+            var categ_ids = [];
+            var company = $('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var type = self.$el.find('#current-type').val();
+            var type_code = self.$el.find('#current-type-code').val();
+
+            var domain = [
+                ['state','=','done'],
+            ];
+
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+
+            if(type && type != 9999999){
+              domain.push(['picking_type_id','=',  parseInt(type)]);
+            }
+
+            if(type_code && type_code != 9999999){
+              domain.push(['picking_type_id.code','=', type_code]);
+            }
+
+            if(store && store != 9999999){
+              domain.push(['store_id', '=', parseInt(store)]);
+            }
+
+            if(date && date != 9999999){
+
+                if(desde){
+                    var date = desde.split('/')
+                    date = (date[2]+"-"+date[1]+"-"+date[0]);
+                    domain.push(['create_date','>=',date]);
+                }
+
+                if(hasta){
+                    var date = hasta.split('/')
+                    date = (date[2]+"-"+date[1]+"-"+date[0]);
+                    domain.push(['create_date','<=',date]);
+                }
+
+                if(date == 'today'){
+                  var today = moment().format('YYYY-MM-DD ');
+                  domain.push(['create_date','like',today]);
+
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD ');
+                    domain.push(['create_date','like',yesterday]);
+                }
+
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['create_date','like',currentMonth]);
+                }
+
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['create_date','like',lastMonth]);
+                }
+            }
+
+            var StockPicking = new model.web.Model('stock.picking');
+            return StockPicking.call('getStockPicking',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateTypeSelections: function () {
+          var self = this;
+          var store = self.$el.find('#current-store').val();
+          var type = self.$el.find('#current-type').empty();
+          self.$el.find('#current-type').append('<option value="9999999">Todas las operaciones</option>');
+          if(store != 9999999){
+            _.each(self.StockPickingType,function(item){
+              if(parseFloat(store) == item.store_id[0]){
+                self.$el.find('#current-type').append('<option value="' + item.id + '">' + item.warehouse_id[1] +' '+item.name + '</option>');
+              }
+            });
+          }else{
+            _.each(self.StockPickingType,function(item){
+              self.$el.find('#current-type').append('<option value="' + item.id + '">' + item.warehouse_id[1] +' '+item.name + '</option>');
+            });
+          }
+        },
+
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        /*====================================================================
+          GET STOCK MOVE
+        ====================================================================*/
+        getStockMove: function (id) {
+            var self = this;
+            return _.filter(self.StockMove,function (item) {
+                return item.picking_id.id == id;
+            })
+        },
+
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var StockPicking = self.StockPicking;
+            _.each(StockPicking, function(item){
+                var info = [];
+                var sum_item = 0;
+                var StockMove = self.getStockMove(item.id);
+                _.each(StockMove, function(item_move){
+                  sum_item = sum_item +  item_move.product_uom_qty;
+                  info.push({
+                      id : item_move.id,
+
+                      origin : self.valorNull(item_move.origin),
+                      product_id : item_move.product_id.display_name,
+                      location_id : item_move.location_id.complete_name,
+                      qty : item_move.product_uom_qty,
+                      location_dest_id : item_move.location_dest_id.complete_name,
+                });
+
+              });
+
+              data.push({
+                id: item.id,
+                name : item.name,
+                partner_name : self.valorNull(item.partner_id.name),
+                date : moment(item.date).format('DD/MM/YYYY'),
+                picking_type_name : item.picking_type_id.name,
+                sum_item : accounting.formatNumber(sum_item,'','.',','),
+
+                sum_item_no_format: sum_item,
+
+                info: info,
+
+              });
+            });
+
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var action = this.$el.find(e.target).val();
+            var company = self.$el.find('#current-company').val();
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var ResCompany = self.ResCompany[0];
+
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+            }
+
+            var total = totalFormatter(row);
+
+            row.push({
+              name: 'Totales',
+              sum_item: total,
+            })
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Historial de Inventario.';
+                var pdf_type = '';
+                var pdf_name = 'historial_de_inventario_';
+                var pdf_columnStyles = {
+                  name : {columnWidth: 30, halign:'left'},
+                  partner_name : {columnWidth: 65, halign:'left'},
+                  date : {columnWidth: 20, halign:'center'},
+                  picking_type_name : {columnWidth: 50, halign:'left'},
+                  sum_item : {columnWidth: 30, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var type = self.$el.find('#current-type').val();
+          var type_code = self.$el.find('#current-type-code').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+
+          }
+
+          if(type && type != 9999999){
+            var StockPickingType = _.filter(self.StockPickingType, function(item){
+              return item.id == type;
+            });
+            filter.push({
+              title: 'Nombre de Operación',
+              value: StockPickingType[0].name,
+            })
+          }
+
+          if(type_code && type_code != 9999999){
+            filter.push({
+                title: 'Tipo de Operación',
+                value:  $("#current-type-code option:selected").text(),
+            });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        }
+    });
+}

+ 750 - 0
static/src/js/reports/report_stock_movement.js

@@ -0,0 +1,750 @@
+function report_stock_movement(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportStockMovementWidget = reporting.Base.extend({
+        template: 'ReportStockMovement',
+        rowsData :[],
+        content :[],
+        modules: ['product_brand'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-attribute' : 'updateAttributeSelections',
+            'change #current-date' : 'ShowDateRange',
+            'change #current-company':'updateSelections',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                  self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                  _.each(ResCompany,function(item){
+                    self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                  });
+                }else{
+                  self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 0){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchStockLocation();
+            }).then(function(StockLocation){
+                self.StockLocation = StockLocation;
+                if(StockLocation.length > 1){
+                    self.$el.find('#current-location').append('<option value="9999999">Todas las ubicaciones</option>');
+                    _.each(StockLocation,function(item){
+                        self.$el.find('#current-location').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                    });
+
+                    self.$el.find('#current-location2').append('<option value="9999999">Todas las ubicaciones</option>');
+                    _.each(StockLocation,function(item){
+                        self.$el.find('#current-location2').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.location').css('display','none');
+                }
+                return self.fetchProductBrand();
+            }).then(function(ProductBrand){
+                self.ProductBrand = ProductBrand;
+                if(ProductBrand.length > 1){
+                    self.$el.find('#current-brand').append('<option value="9999999">Todas las marcas</option>');
+                    _.each(ProductBrand,function(item){
+                        self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.brand').css('display','none');
+                }
+                return self.fetchProductCategory();
+            }).then(function(ProductCategory){
+                self.ProductCategory = ProductCategory;
+                if(ProductCategory.length > 1){
+                    self.$el.find('#current-category').append('<option value="9999999">Todas las categorias</option>');
+                    _.each(ProductCategory,function(item){
+                        self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.category').css('display','none');
+                }
+                return self.fetchProductAttribute();
+            }).then(function(ProductAttribute){
+                self.ProductAttribute = ProductAttribute;
+                if(ProductAttribute.length > 0){
+                    self.$el.find('#current-attribute').append('<option value="9999999">Todos los atributos</option>');
+                    _.each(ProductAttribute,function(item){
+                        self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute').css('display','none');
+                }
+                return self.fetchProductAttributeValue();
+            }).then(function(ProductAttributeValue){
+                self.ProductAttributeValue = ProductAttributeValue;
+                if(ProductAttributeValue.length > 1){
+                    self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                    _.each(ProductAttributeValue,function(item){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute-value').css('display','none');
+                }
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.fetchStockMove().then(function(StockMove) {
+                return StockMove;
+            }).then(function (StockMove) {
+                self.StockMove = StockMove;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fetchIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            STOCK LOCATION
+        ====================================================================*/
+        fetchStockLocation: function () {
+            var self = this;
+            var domain = [
+                ['active', '=',true],
+            ];
+            var StockLocation = new model.web.Model('stock.location');
+            return StockLocation.call('getStockLocation',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            PRODUCT BRAND
+        ====================================================================*/
+        fetchProductBrand: function () {
+            var self = this;
+            var domain = [];
+            var modules = self.checkModel('product_brand');
+            if (modules.length > 0){
+                var ProductBrand = new model.web.Model('product.product');
+                return ProductBrand.call('getProductBrand',[domain], {
+                    context: new model.web.CompoundContext()
+                });
+            }else{
+                var ProductBrand = [];
+                return ProductBrand;
+            }
+        },
+
+        /*====================================================================
+            PRODUCT CATEGORY
+        ====================================================================*/
+        fetchProductCategory: function () {
+            var self = this;
+            var domain = [];
+            var ProductCategory = new model.web.Model('product.category');
+            return ProductCategory.call('getProductCategory',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            PRODUCT ATTRIBUTE
+        ====================================================================*/
+        fetchProductAttribute: function () {
+            var self = this;
+            var domain = [];
+            var ProductAttribute = new model.web.Model('product.attribute');
+            return ProductAttribute.call('getProductAttribute',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            PRODUCT ATTRIBUTE VALUE
+        ====================================================================*/
+        fetchProductAttributeValue: function () {
+            var self = this;
+            var domain = [];
+            var ProductAttributeValue = new model.web.Model('product.attribute.value');
+            return ProductAttributeValue.call('getProductAttributeValue',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            STOCK MOVE
+        ====================================================================*/
+        fetchStockMove: function () {
+            var self = this;
+            var categ_ids = [];
+            var company = $('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var category = self.$el.find('#current-category').val();
+            var brand = self.$el.find('#current-brand').val();
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            var location = self.$el.find('#current-location').val();
+            var location2 = self.$el.find('#current-location2').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            var location_ids = _.flatten(_.map(self.StockLocation, function (item) {
+                return item.id;
+            }));
+            var domain = [
+                ['location_id', 'in',location_ids],
+                ['location_dest_id', 'in',location_ids],
+                ['state','=','done'],
+            ];
+
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+
+            if(store && store != 9999999){
+
+              domain.push('|',['location_id.store_id', '=', parseInt(store)],['location_dest_id.store_id', '=', parseInt(store)]);
+
+            }
+
+            if(brand && brand != 9999999){
+                 domain.push(['product_id.product_brand_id','=',parseInt(brand)]);
+            }
+
+            if(location && location != 9999999){
+                domain.push(['location_id','=',parseInt(location)]);
+            }
+
+            if(location2 && location2 != 9999999){
+                domain.push(['location_dest_id','=',parseInt(location2)]);
+            }
+
+            if(date && date != 9999999){
+
+                if(desde){
+                    var date = desde.split('/')
+                    date = (date[2]+"-"+date[1]+"-"+date[0]);
+                    domain.push(['create_date','>=',date]);
+                }
+
+                if(hasta){
+                    var date = hasta.split('/')
+                    date = (date[2]+"-"+date[1]+"-"+date[0]);
+                    domain.push(['create_date','<=',date]);
+                }
+
+                if(date == 'today'){
+                  var today = moment().format('YYYY-MM-DD ');
+                  domain.push(['create_date','like',today]);
+
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD ');
+                    domain.push(['create_date','like',yesterday]);
+                }
+
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['create_date','like',currentMonth]);
+                }
+
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['create_date','like',lastMonth]);
+                }
+            }
+
+            if(category){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id[0] == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id[0]) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id[0]) || item.id == category;
+                }), function(map){
+                    return map.id;
+                }) ;
+                categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id[0]) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+            };
+
+            if(category && category != 9999999){
+                domain.push(['product_id.categ_id','in',categ_ids]);
+            }
+
+            var attribute_ids = _.map(_.filter(self.ProductAttribute,function (item) {
+                return item.id == attribute;
+            }), function(map){
+                return map.id;
+            });
+
+            var attribute_value_ids = _.map(_.filter(self.ProductAttributeValue,function (item) {
+                return item.id == attribute_value;
+            }), function(map){
+                return map.id;
+            });
+
+
+            if(attribute && attribute != 9999999){
+              domain.push(['product_id.attribute_line_ids.attribute_id', 'in', attribute_ids]);
+            }
+
+            if(attribute_value && attribute_value != 9999999){
+              domain.push(['product_id.attribute_value_ids', 'in', attribute_value_ids]);
+            }
+
+            var StockMove = new model.web.Model('stock.move');
+            return StockMove.call('getStockMove',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+
+                /*=====================
+                    LOCATION SELECTION
+                =====================*/
+                var location = self.$el.find('#current-location').empty();
+                self.$el.find('#current-location').append('<option value="9999999">Todas las ubicaciones</option>');
+                _.each(self.StockLocation,function(item){
+                    self.$el.find('#current-location').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                });
+
+                var location2 = self.$el.find('#current-location2').empty();
+                self.$el.find('#current-location2').append('<option value="9999999">Todas las ubicaciones</option>');
+                _.each(self.StockLocation,function(item){
+                    self.$el.find('#current-location2').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                });
+
+        },
+
+        updateAttributeSelections: function () {
+            var self = this;
+            var attribute = self.$el.find('#current-attribute').val();
+            if(attribute != 9999999){
+                /*=============================
+                    ATTRIBUTE VALUE SELECTION
+                =============================*/
+                var attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    if(parseFloat(attribute) == item.attribute_id[0]){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ATTRIBUTE VALUE SELECTION
+                =============================*/
+                var attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var domain = true;
+            var StockMove = self.StockMove;
+            _.each(StockMove, function(item){
+
+              data.push({
+                /*=======================
+                        IDS
+                =======================*/
+                id : item.id,
+                /*=======================
+                        INFO
+                =======================*/
+
+                picking_id : self.valorNull(item.picking_id.name),
+                origin : self.valorNull(item.origin),
+                partner_id : self.valorNull(item.partner_id.name),
+                create_date :moment(item.create_date).format('DD-MM-YYYY'),
+                product_id : item.product_id.display_name,
+                location_id : item.location_id.complete_name,
+                qty : item.product_uom_qty,
+                location_dest_id : item.location_dest_id.complete_name,
+              });
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var action = this.$el.find(e.target).val();
+            var company = self.$el.find('#current-company').val();
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var ResCompany = self.ResCompany[0];
+
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+            }
+
+            row.push({});
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Movimiento de Inventario.';
+                var pdf_type = 'l';
+                var pdf_name = 'movimiento_de_inventario_';
+                var pdf_columnStyles = {
+                  picking_id : {columnWidth: 30, halign:'left'},
+                  origin : {columnWidth: 15, halign:'left'},
+                  partner_id : {columnWidth: 40, halign:'left'},
+                  create_date :{columnWidth: 16, halign:'left'},
+                  product_id : {columnWidth: 65, halign:'left'},
+                  location_id : {columnWidth: 50, halign:'left'},
+                  qty : {columnWidth: 17, halign:'center'},
+                  location_dest_id : {columnWidth: 50, halign:'left'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var location = self.$el.find('#current-location').val();
+          var location2 = self.$el.find('#current-location2').val();
+          var brand = self.$el.find('#current-brand').val();
+          var category = self.$el.find('#current-category').val();
+          var attribute = self.$el.find('#current-attribute').val();
+          var attribute_value = self.$el.find('#current-attribute-value').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+
+          }
+          if(location && location != 9999999){
+            var ResLocation = _.filter(self.StockLocation, function(item){
+              return item.id == location;
+            })
+            filter.push({
+              title: 'Ubicación de Origen',
+              value: ResLocation[0].display_name,
+            })
+          }
+
+          if(location2 && location2 != 9999999){
+            var ResLocation2 = _.filter(self.StockLocation, function(item){
+              return item.id == location2;
+            })
+            filter.push({
+              title: 'Ubicación de Destino',
+              value: ResLocation2[0].display_name,
+            })
+          }
+
+          if(brand && brand != 9999999){
+            var ProductBrand =  _.filter(self.ProductBrand,function (item) {
+                return item.id == brand;
+            });
+            filter.push({
+                 title: 'Marca',
+                 value:  ProductBrand[0].name,
+               });
+          }
+
+          if(category && category != 9999999){
+            var ProductCategory =  _.filter(self.ProductCategory,function (item) {
+                return item.id == category;
+            });
+            filter.push({
+                 title: 'Categoría',
+                 value:  ProductCategory[0].name,
+               });
+          }
+
+          if(attribute && attribute != 9999999){
+            var attr =  _.filter(self.ProductAttribute,function (item) {
+                return item.id == attribute;
+            });
+            filter.push({
+                 title: 'Atributo',
+                 value: attr[0].name,
+               });
+          }
+
+          if(attribute_value && attribute_value != 9999999){
+            var attr_value =  _.filter(self.ProductAttributeValue,function (item) {
+                return item.id == attribute_value;
+            });
+            filter.push({
+                 title: 'Valor de Atributo',
+                 value: attr_value[0].name,
+               });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        },
+    });
+}

+ 761 - 0
static/src/js/reports/report_stock_valuation.js

@@ -0,0 +1,761 @@
+function report_stock_valuation(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportStockValuationWidget = reporting.Base.extend({
+        template: 'ReportStockValuation',
+        rowsData :[],
+        content :[],
+        modules: ['product_brand'],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+            'change #current-company' : 'updateSelections',
+            'change #current-attribute' : 'updateAttributeSelections',
+            'click #btnPrint' : 'callprint',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        clickAnalysisDetail: function(e, row, $element,field){
+            if (field == 'name'){
+                this.do_action({
+                    name:"Producto",
+                    type: 'ir.actions.act_window',
+                    res_model: "product.product",
+                    views: [[false,'form']],
+                    target: 'new',
+                    domain: [['id','=', row.id]],
+                    context: {},
+                    flags: {'form': {'action_buttons': false, 'options': {'mode': 'view'}}},
+                    res_id: row.id,
+                });
+            }
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchStockLocation();
+            }).then(function(StockLocation){
+                self.StockLocation = StockLocation;
+                if(StockLocation.length > 1){
+                    self.$el.find('#current-location').append('<option value="9999999">Todas las ubicaciones</option>');
+                    _.each(StockLocation,function(item){
+                        self.$el.find('#current-location').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.location').css('display','none');
+                }
+                return self.fetchProductBrand();
+            }).then(function(ProductBrand){
+                self.ProductBrand = ProductBrand;
+                if(ProductBrand.length > 1){
+                    self.$el.find('#current-brand').append('<option value="9999999">Todas las marcas</option>');
+                    _.each(ProductBrand,function(item){
+                        self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.brand').css('display','none');
+                }
+                return self.fetchProductCategory();
+            }).then(function(ProductCategory){
+                self.ProductCategory = ProductCategory;
+                if(ProductCategory.length > 1){
+                    self.$el.find('#current-category').append('<option value="9999999">Todas las categorias</option>');
+                    _.each(ProductCategory,function(item){
+                        self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.category').css('display','none');
+                }
+                return self.fetchProductAttribute();
+            }).then(function(ProductAttribute){
+                self.ProductAttribute = ProductAttribute;
+                if(ProductAttribute.length > 1){
+                    self.$el.find('#current-attribute').append('<option value="9999999">Todos los atributos</option>');
+                    _.each(ProductAttribute,function(item){
+                        self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute').css('display','none');
+                }
+                return self.fetchProductAttributeValue();
+            }).then(function(ProductAttributeValue){
+                self.ProductAttributeValue = ProductAttributeValue;
+                if(ProductAttributeValue.length > 1){
+                    self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                    _.each(ProductAttributeValue,function(item){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.attribute-value').css('display','none');
+                }
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.fetchStockQuant().then(function(StockQuant) {
+                return StockQuant;
+            }).then(function (StockQuant) {
+                self.StockQuant = StockQuant;
+                return self.fetchProductProduct();
+            }).then(function (ProductProduct){
+                self.ProductProduct = ProductProduct;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            STOCK LOCATION
+        ====================================================================*/
+        fetchStockLocation: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var domain = [
+                ['active', '=',true],
+                ['usage', '=','internal'],
+            ];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseInt(company)]);
+            }
+            var StockLocation = new model.web.Model('stock.location');
+            return StockLocation.call('getStockLocation',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            PRODUCT BRAND
+        ====================================================================*/
+        fetchProductBrand: function () {
+            var self = this;
+            var domain = [];
+            var modules = self.checkModel('product_brand');
+            if (modules.length > 0){
+                var ProductBrand = new model.web.Model('product.product');
+                return ProductBrand.call('getProductBrand',[domain], {
+                    context: new model.web.CompoundContext()
+                });
+            }else{
+                var ProductBrand = [];
+                return ProductBrand;
+            }
+        },
+
+        /*====================================================================
+            PRODUCT CATEGORY
+        ====================================================================*/
+        fetchProductCategory: function () {
+            var self = this;
+            var domain = [];
+            var ProductCategory = new model.web.Model('product.category');
+            return ProductCategory.call('getProductCategory',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            PRODUCT ATTRIBUTE
+        ====================================================================*/
+        fetchProductAttribute: function () {
+            var self = this;
+            var domain = [];
+            var ProductAttribute = new model.web.Model('product.attribute');
+            return ProductAttribute.call('getProductAttribute',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            PRODUCT ATTRIBUTE VALUE
+        ====================================================================*/
+        fetchProductAttributeValue: function () {
+            var self = this;
+            var domain = [];
+            var ProductAttributeValue = new model.web.Model('product.attribute.value');
+            return ProductAttributeValue.call('getProductAttributeValue',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            return ResCurrency.call('getResCurrency',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            STOCK QUANT
+        ====================================================================*/
+        fetchStockQuant: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var location = self.$el.find('#current-location').val();
+            var location_ids = _.flatten(_.map(self.StockLocation, function (item) {
+                return item.id;
+            }));
+            var domain = [
+                ['location_id', 'in',location_ids],
+            ];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseInt(company)]);
+            }
+            if(location && location != 9999999){
+                domain.push(['location_id','=',parseInt(location)]);
+            }
+            var StockQuant = new model.web.Model('stock.quant');
+            return StockQuant.call('getStockQuant',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            PRODUCT PRODUCT
+        ====================================================================*/
+        fetchProductProduct: function () {
+            var self = this;
+            var categ_ids = [];
+            var company = self.$el.find('#current-company').val();
+            var brand = self.$el.find('#current-brand').val();
+            var category = self.$el.find('#current-category').val();
+            var state = self.$el.find('#current-state').val();
+            var domain = [
+                ['active','=',true],
+                ['type','=','product'],
+            ];
+            if(state == 'available'){
+                var product_ids = _.flatten(_.map(self.StockQuant, function (item) {
+                    return item.product_id[0];
+                }));
+                domain.push(['id','in',product_ids]);
+            };
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseInt(company)]);
+            };
+            if(category){
+                var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return item.id == category || item.parent_id[0] == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_ids, item.parent_id[0]) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+                var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_children_ids, item.parent_id[0]) || item.id == category;
+                }), function(map){
+                    return map.id;
+                }) ;
+                categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+                    return _.contains(category_grandchildren_ids, item.parent_id[0]) || item.id == category;
+                }), function(map){
+                    return map.id;
+                });
+            };
+            if(brand && brand != 9999999){
+                domain.push(['product_brand_id','=',parseInt(brand)]);
+            }
+            if(category && category != 9999999){
+                domain.push(['categ_id','in',categ_ids]);
+            }
+            var ProductProduct = new model.web.Model('product.product');
+            return ProductProduct.call('getProductProductStock',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*======================
+                    LOCATION SELECTION
+                ======================*/
+                var location = self.$el.find('#current-location').empty();
+                self.$el.find('#current-location').append('<option value="9999999">Todas las ubicaciones</option>');
+                _.each(self.StockLocation,function(item){
+                    if(parseInt(company) == item.company_id[0]){
+                        self.$el.find('#current-location').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                    }
+                });
+            }else{
+                /*=====================
+                    LOCATION SELECTION
+                =====================*/
+                var location = self.$el.find('#current-location').empty();
+                self.$el.find('#current-location').append('<option value="9999999">Todas las ubicaciones</option>');
+                _.each(self.StockLocation,function(item){
+                    self.$el.find('#current-location').append('<option value="' + item.id + '">' + item.display_name + '</option>');
+                });
+            }
+        },
+
+        updateAttributeSelections: function () {
+            var self = this;
+            var attribute = self.$el.find('#current-attribute').val();
+            if(attribute != 9999999){
+                /*=============================
+                    ATTRIBUTE VALUE SELECTION
+                =============================*/
+                var attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    if(parseFloat(attribute) == item.attribute_id[0]){
+                        self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ATTRIBUTE VALUE SELECTION
+                =============================*/
+                var attribute_value = self.$el.find('#current-attribute-value').empty();
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(self.ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET CURRENT LOCATION
+        ====================================================================*/
+        getCurrentLocation: function (id) {
+            var self = this;
+            return _.filter(self.StockLocation,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            GET PRODUCT PRODUCT
+        ====================================================================*/
+        getProductProduct: function () {
+            var self = this;
+            var content = self.ProductProduct;
+            var attribute = self.$el.find('#current-attribute').val();
+            var attribute_value = self.$el.find('#current-attribute-value').val();
+            if(attribute && attribute != 9999999 && attribute_value == 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.attribute_ids, parseInt(attribute));
+                });
+            }
+            if(attribute_value && attribute_value != 9999999){
+                content = _.filter(content,function (item) {
+                    return _.contains(item.atribute_value_ids, parseFloat(attribute_value));
+                });
+            }
+            return content;
+        },
+
+        /*====================================================================
+            GET STOCK QUANT
+        ====================================================================*/
+        getStockQuant: function(id){
+            var self = this;
+            return _.filter(self.StockQuant, function(item){
+                return item.product_id[0] === id;
+            });
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var company = $('#current-company').val();
+            var state = $('#current-state').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var ProductProduct = self.getProductProduct();
+            _.each(ProductProduct, function(item){
+                var quantity = 0;
+                var StockQuant = self.getStockQuant(item.id);
+                if(StockQuant.length > 0){
+                    quantity = _.reduce(_.map(StockQuant,function(item){
+                        return item.qty;
+                    }),function(mamo, num){
+                        return mamo + num;
+                    },0);
+                };
+                data.push({
+                    /*=======================
+                        IDS
+                    =======================*/
+                    id : item.id,
+                    /*=======================
+                        INFO
+                    =======================*/
+                    name : item.display_name,
+                    ean13 : self.valorNull(item.ean13),
+                    default_code : self.valorNull(item.default_code),
+                    factory_reference : self.valorNull(item.factory_reference),
+                    category : item.categ_id.complete_name,
+                    standard_price_total : accounting.formatMoney(item.standard_price, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    lst_price_total : accounting.formatMoney(item.lst_price, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    quantity : accounting.formatNumber(quantity,2,'.',','),
+                    valuation_cost_total : accounting.formatMoney((item.standard_price * quantity), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    valuation_sale_total : accounting.formatMoney((item.lst_price * quantity), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    utility_total : accounting.formatMoney(((item.lst_price * quantity)-(item.standard_price * quantity)), '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    /*=======================
+                        VALORES SIN FORMATEAR
+                    =======================*/
+                    qty : quantity,
+                    standard_price : item.standard_price,
+                    lst_price : item.lst_price,
+                    valuation_cost : item.standard_price * quantity,
+                    valuation_sale : item.lst_price * quantity,
+                    utility : (item.lst_price * quantity)-(item.standard_price * quantity),
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                });
+
+                if(state && state == 'available' && quantity <= 0){
+                    data.pop();
+                }
+
+                if(state && state == 'unavailable' && quantity > 0){
+                    data.pop();
+                }
+
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        callprint: function (e) {
+            var self = this;
+            var pdf = new reporting.ReportPdfWidget(self);
+            pdf.getPDFFileButton();
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            var location = $('#current-location').val();
+            var pdf_type = $('#current-pdf-type').val();
+            var current_location = [];
+            if(location && location != 9999999){
+                current_location = self.getCurrentLocation(location);
+            }
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var qty = qtyFormatter(row);
+            var valuation_cost_total = CostValuationFormatter(row);
+            var valuation_sale_total = SaleValuationFormatter(row);
+            var utility_total = UtilityFormatter(row);
+
+            row.push({
+                name : 'Totales',
+                quantity : qty,
+                valuation_cost_total : valuation_cost_total,
+                valuation_sale_total : valuation_sale_total,
+                utility_total : utility_total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                        if(item.field != 'image'){
+                            getColumns.push([{
+                                title: item.title,
+                                dataKey: item.field
+                            }]);
+                        }
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Valoracion de Inventario';
+                var pdf_name = 'valoracion_de_inventario_';
+                if(pdf_type == 1){
+                    pdf_type = 'l';
+                    var pdf_columnStyles = {
+                        name :{halign:'left'},
+                        ean13 :{columnWidth: 21, halign:'center'},
+                        factory_reference : {columnWidth: 11, halign:'left'},
+                        category :{halign:'left'},
+                        standard_price_total :{columnWidth: 17, halign:'right'},
+                        lst_price_total :{columnWidth: 17, halign:'right'},
+                        quantity : {columnWidth: 10, halign:'right'},
+                        valuation_cost_total : {columnWidth: 18, halign:'right'},
+                        valuation_sale_total : {columnWidth: 18, halign:'right'},
+                        utility_total : {columnWidth: 17, halign:'right'},
+                    };
+                }else{
+                    pdf_type = '';
+                    var pdf_columnStyles = {
+                        name :{halign:'left'},
+                        ean13 :{columnWidth: 21, halign:'center'},
+                        factory_reference : {columnWidth: 11, halign:'left'},
+                        category :{halign:'left'},
+                        standard_price_total :{columnWidth: 17, halign:'right'},
+                        lst_price_total :{columnWidth: 17, halign:'right'},
+                        quantity : {columnWidth: 10, halign:'right'},
+                        valuation_cost_total : {columnWidth: 18, halign:'right'},
+                        valuation_sale_total : {columnWidth: 18, halign:'right'},
+                        utility_total : {columnWidth: 17, halign:'right'},
+                    };
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var location = self.$el.find('#current-location').val();
+          var brand = self.$el.find('#current-brand').val();
+          var category = self.$el.find('#current-category').val();
+          var attribute = self.$el.find('#current-attribute').val();
+          var attribute_value = self.$el.find('#current-attribute-value').val();
+          var state = self.$el.find('#current-state').val();
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(location && location != 9999999){
+            var StockLocation =  _.filter(self.StockLocation,function (item) {
+                return item.id == location;
+            });
+
+            filter.push({
+                 title: 'Ubicación',
+                 value:  StockLocation[0].display_name,
+               });
+
+          }
+
+          if(brand && brand != 9999999){
+            var brand =  _.filter(self.ProductBrand,function (item) {
+                return item.id == brand;
+            });
+            filter.push({
+                 title: 'Marca',
+                 value: brand[0].name,
+               });
+          }
+
+          if(category && category != 9999999){
+            var categ =  _.filter(self.ProductCategory,function (item) {
+                return item.id == category;
+            });
+            filter.push({
+                 title: 'Categoría',
+                 value: categ[0].name,
+               });
+          }
+
+          if(attribute && attribute != 9999999){
+            var attr =  _.filter(self.ProductAttribute,function (item) {
+                return item.id == attribute;
+            });
+            filter.push({
+                 title: 'Atributo',
+                 value: attr[0].name,
+               });
+          }
+
+          if(attribute_value && attribute_value != 9999999){
+            var attr_value =  _.filter(self.ProductAttributeValue,function (item) {
+                return item.id == attribute_value;
+            });
+            filter.push({
+                 title: 'Valor de Atributo',
+                 value: attr_value[0].name,
+               });
+          }
+
+          if(state && state != 9999999){
+            filter.push({
+                 title: 'Estado',
+                 value:  $("#current-state option:selected").text(),
+               });
+          }
+          return filter;
+        }
+    });
+}

+ 358 - 0
static/src/js/reports/report_supplier.js

@@ -0,0 +1,358 @@
+function report_supplier(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSupplierWidget = reporting.Base.extend({
+        template: 'ReportSupplier',
+        rowsData :[],
+        content :[],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'click-row.bs.table #table' : 'clickAnalysisDetail',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        clickAnalysisDetail: function(e, row, $element,field){
+            if (field == 'name'){
+                this.do_action({
+                    name:"Registro de Cliente",
+                    type: 'ir.actions.act_window',
+                    res_model: "res.partner",
+                    views: [[false,'form']],
+                    target: 'new',
+                    domain: [['id','=', row.id]],
+                    context: {},
+                    flags: {'form': {'action_buttons': false, 'options': {'mode': 'view'}}},
+                    res_id: row.id,
+                });
+            }
+            e.stopImmediatePropagation();
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            this.fetchResUser().then(function(ResUser) {
+                return ResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchResPartner().then(function(ResPartner) {
+                return ResPartner;
+            }).then(function (ResPartner) {
+                self.ResPartner = ResPartner;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+
+        /*====================================================================
+            RES PARTNER
+        ====================================================================*/
+        fetchResPartner: function() {
+            var self = this;
+            var state = self.$el.find('#current-state').val();
+            var company = self.$el.find('#current-company').val();
+            var type = self.$el.find('#current-type').val();
+            var domain = [['active', '=', true], ['supplier', '=', true]];
+            if(state == 'with'){
+                domain.push(['debit','<',0]);
+            }
+            if(state == 'without'){
+                domain.push(['debit','=',0]);
+            }
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseInt(company)]);
+            }
+            if(type == 'company'){
+                domain.push(['is_company','=',true]);
+            }
+            if(type == 'people'){
+                domain.push(['is_company','!=',true]);
+            }
+            var ResPartner = new model.web.Model('res.partner');
+            return ResPartner.call('getResPartner',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var ResPartner = self.ResPartner;
+            _.each(ResPartner, function(item){
+                data.push({
+                    id : item.id,
+                    ruc : self.valorNull(item.ruc),
+                    name : item.name,
+                    street : self.valorNull(item.street),
+                    city : self.valorNull(item.city),
+                    phone : self.valorNull(item.phone),
+                    mobile : self.valorNull(item.mobile),
+                    email : self.valorNull(item.email),
+                    property_product_pricelist_purchase : self.valorNull(item.property_product_pricelist_purchase),
+                    debit : accounting.formatMoney(item.debit, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    amount : item.debit,
+                    /*==============================
+                        TOTAL FOOTER CONFIGURATION
+                    ==============================*/
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                });
+            });
+
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var amount = totalFormatter(row);
+
+            row.push({
+                ruc: 'Total',
+                debit: amount,
+            })
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Proveedores.';
+                var pdf_type = 'l';
+                var pdf_name = 'proveedores_';
+                var pdf_columnStyles = {
+                    ruc :{columnWidth: 20, halign:'left'},
+                    name :{halign:'left'},
+                    street :{halign:'left'},
+                    city:{halign:'left'},
+                    phone : {columnWidth: 30, halign:'left'},
+                    mobile :{columnWidth: 30, halign:'left'},
+                    email:{columnWidth: 30, halign:'left'},
+                    property_product_pricelist_purchase:{columnWidth: 30, halign:'center'},
+                    debit:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var state = self.$el.find('#current-state').val();
+          var type = self.$el.find('#current-type').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(state && state != 9999999){
+            filter.push({
+              title: 'Estado',
+              value: $("#current-state option:selected").text(),
+            })
+          }
+
+          if(type && type != 9999999){
+            filter.push({
+              title: 'Tipo de Proveedor',
+              value: $('#current-type option:selected').text(),
+            })
+          }
+          return filter;
+        },
+    });
+}

+ 524 - 0
static/src/js/reports/report_supplier_payment.js

@@ -0,0 +1,524 @@
+function report_supplier_payment(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSupplierPaymentWidget = reporting.Base.extend({
+        template: 'ReportSupplierPayment',
+        rowsData :[],
+        content :[],
+        modules: ['point_of_sale'],
+
+        events:{
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-date' : 'ShowDateRange',
+            'click .print-report':'clickOnAction',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        checkModel : function(model){
+            var self = this;
+            return _.filter(self.IrModuleModule,function(item){
+                return item.name === model;
+            });
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fetchIntialSQL().then(function (IntialSQL) {
+                return IntialSQL;
+            }).then(function(IntialSQL) {
+                /*
+                =================================
+                    RES COMPANY
+                =================================
+                */
+                self.ResCompany = IntialSQL.companies;
+                self.CompanyLogo = IntialSQL.logo;
+                if(self.ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(self.ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                /*
+                =================================
+                    RES STORE
+                =================================
+                */
+                self.ResStore = IntialSQL.stores;
+                if(self.ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(self.ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                /*
+                =================================
+                    ACCOUNT JOURNAL
+                =================================
+                */
+                self.AccountJournal = IntialSQL.journals;
+                var journal = _.flatten(_.filter(self.AccountJournal,function (item) {
+                    return item.type == 'cash' || item.type == 'bank';
+                }));
+                if(journal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todos los métodos de pago</option>');
+                    _.each(journal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fethIrModuleModule();
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fethCheckType();
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchDataSQL().then(function(DataSQL) {
+                return DataSQL;
+            }).then(function (DataSQL) {
+                self.AccountVoucher = DataSQL.vouchers;
+                self.AccountInvoice = DataSQL.invoices;
+                return self.BuildTable();
+            });
+        },
+
+        fetchIntialSQL: function() {
+            var self = this;
+            var data = $.get('/report-filter-data');
+            return data;
+        },
+
+        fetchDataSQL: function() {
+            var self = this;
+            var data = $.get('/report-supplier-account-voucher');
+            return data;
+        },
+
+        fethIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed'],['name','in',self.modules]];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            Check type
+        =====================================================================*/
+        fethCheckType: function(){
+            var self = this;
+            var modules = self.checkModel('point_of_sale');
+            if(modules.length == 0){
+                self.$el.find('.type').css('display','none');
+            }
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var store;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var journal;
+            var AccountJournal = _.flatten(_.filter(self.AccountJournal,function (item) {
+                return item.type == 'cash' || item.type == 'bank';
+            }));
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todos los métodos de pago</option>');
+                _.each(AccountJournal,function(item){
+                    if(item.store_id == store){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todos los métodos de pago</option>');
+                _.each(AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        getAccountVoucher:function(number) {
+            var self = this;
+            var content = self.AccountVoucher;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var journal = self.$el.find('#current-journal').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+
+            content = _.filter(content,function (item) {
+                return item.reference == number;
+            })
+
+            if((store && store == 9999999)||(company && company == 9999999)){
+                var store_ids = _.flatten(_.map(self.ResStore, function (item) {
+                    return item.id;
+                }));
+                var company_ids = _.flatten(_.map(self.ResCompany, function (item) {
+                    return item.id;
+                }));
+                content = _.flatten(_.filter(content,function (item) {
+                    return _.contains(store_ids, item.store_id) && _.contains(company_ids, item.company_id);
+                }));
+            }
+
+            if(company && company != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.company_id == company;
+                }));
+            }
+            if(store && store != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.store_id == store;
+                }));
+            }
+            if(journal && journal != 9999999){
+                content = _.flatten(_.filter(content,function (item) {
+                    return item.journal_id == journal;
+                }));
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        date = desde.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') >= date;
+                        }));
+                    }
+                    if(hasta){
+                        date = hasta.split('/');
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        content = _.flatten(_.filter(content,function (inv) {
+                            return moment(inv.date).format('YYYY-MM-DD') <= date;
+                        }));
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === today;
+                    }));
+                }
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM-DD') === yesterday;
+                    }));
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === currentMonth;
+                    }));
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    content = _.flatten(_.filter(content,function (inv) {
+                        return moment(inv.date).format('YYYY-MM') === lastMonth;
+                    }));
+                }
+            }
+            return content;
+        },
+
+        BuildTable: function(){
+            var self = this;
+
+            var data = [];
+            var residual = 0;
+            var CurrencyBase = self.ResCompany[0].currency_id;
+
+              var AccountInvoice = self.AccountInvoice;
+
+            _.each(AccountInvoice, function(each){
+              var AccountVoucher = self.getAccountVoucher(each.number);
+              _.each(AccountVoucher, function(item){
+
+                var amount = item.amount_currency;
+                if(item.currency_id != null){
+                    amount = amount + '('  + item.amount + ')';
+                }
+                data.push({
+                    id:item.id,
+                    date:moment(item.date).format('DD/MM/YYYY'),
+                    origin:item.origin,
+                    name:item.name,
+                    number:item.number,
+                    partner_name:item.partner_name,
+                    journal_name:item.journal_name,
+                    reference:item.reference,
+                    total:accounting.formatMoney(amount,'',CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    /*
+                    =======================
+                        NO FORMAT
+                    =======================
+                    */
+                    date_no_format: moment(item.date).format('YYYY-MM-DD'),
+                    total_no_format:item.amount_currency,
+                    /*
+                    =======================
+                        FOOTER
+                    =======================
+                    */
+                    decimal_places:CurrencyBase.decimal_places,
+                    thousands_separator:CurrencyBase.thousands_separator,
+                    decimal_separator:CurrencyBase.decimal_separator,
+                });
+              });
+            });
+            data.sort(function (a, b) {
+                if (a.date_no_format > b.date_no_format) {
+                    return -1;
+                }
+                if (a.date_no_format < b.date_no_format) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var CurrencyBase;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = _.flatten(_.filter(self.ResCompany,function (inv) {
+                    return inv.id == company;
+                }));
+                ResCompany = CompanyLogo[0];
+                CurrencyBase = ResCompany[0].currency_id;
+            }else{
+                ResCompany = self.CompanyLogo[0];
+                CurrencyBase = self.ResCompany[0].currency_id;
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+            var total = TotalFooter(row);
+            row.push({
+                date:'Totales',
+                total:total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){
+                    return val.field;
+                });
+                _.each(_.map(column,function(val){
+                    return val;
+                }), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Pagos de proveedores.';
+                var pdf_type = '';
+                var pdf_name = 'pagos_de_proveedores';
+                var pdf_columnStyles = {
+                    date:{columnWidth: 20, halign:'center'},
+                    origin:{columnWidth: 'auto', halign:'left'},
+                    name:{columnWidth: 'auto', halign:'center'},
+                    number:{columnWidth: 40, halign:'left'},
+                    reference:{columnWidth: 40, halign:'left'},
+                    partner_name:{columnWidth: 'auto'},
+                    journal_name:{columnWidth: 'auto'},
+                    total:{columnWidth: 20, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter
+                );
+            }
+        },
+        getFilter: function(){
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            var store = self.$el.find('#current-store').val();
+            var state = self.$el.find('#current-state').val();
+            var journal = self.$el.find('#current-journal').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var filter = [];
+            if(company && company != 9999999){
+                var ResCompany = _.filter(self.ResCompany, function(item){
+                    return item.id == company;
+                });
+                filter.push({
+                    title:'Empresa',
+                    value: ResCompany[0].name,
+                });
+            }
+            if(store && store != 9999999){
+                var ResStore =  _.filter(self.ResStore,function (item) {
+                        return item.id == store;
+                });
+                filter.push({
+                    title: 'Sucursal',
+                    value:  ResStore[0].name,
+                });
+            }
+            if(journal && journal != 9999999){
+                var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                    return item.id == journal;
+                });
+                filter.push({
+                   title: 'Método de pago',
+                   value: AccountJournal[0].name,
+                });
+            }
+            if(date && date != 9999999){
+                moment.locale('es', {
+                    months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+                });
+
+                if(date == 'range'){
+                    filter.push({
+                        title: 'Fecha',
+                        value:  desde +' al '+hasta,
+                    });
+                }else {
+                    var fecha;
+                    if(date == 'today'){
+                        fecha = moment().format('DD/MM/YYYY');
+                    }
+                    if(date == 'yesterday'){
+                        fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+                    }
+                    if(date == 'currentMonth'){
+                        fecha = moment().format('MMMM/YYYY');
+                    }
+                    if(date == 'lastMonth'){
+                        fecha = moment().add(-1,'months').format('MMMM/YYYY');
+                    }
+                    filter.push({
+                        title: 'Fecha',
+                        value:  fecha,
+                    });
+                }
+            }
+            return filter;
+        },
+    });
+}

+ 1097 - 0
static/src/js/reports/report_supplier_ranking.js

@@ -0,0 +1,1097 @@
+function report_supplier_ranking(reporting){
+  "use strict";
+
+  var model = openerp;
+
+  reporting.ReportSupplierRankingWidget = reporting.Base.extend({
+    template : 'ReportSupplierRanking',
+    rowsData : [],
+    content : [],
+    modules : ['product_brand'],
+    events : {
+      'click #toolbar > button' : 'clickOnAction',
+      'click #generate' : 'fetchGenerate',
+      'click-row.bs.table #table' : 'clickAnalysisDetail',
+      'change #current-date' : 'ShowDateRange',
+      'change #current-period':'updatePeriodSelections',
+      'change #current-store': 'updateUsers',
+    },
+
+    init : function(parent){
+      this._super(parent);
+    },
+
+    start : function(){
+      var date = new reporting.ReportDatePickerWidget(self);
+      date.fecthFecha();
+      this.fetchInitial();
+    },
+
+    valorNull : function(dato){
+      var valor = "";
+      if (dato){
+        valor = dato;
+      }
+      return valor;
+    },
+
+    checkModel : function(model){
+      var self = this;
+      return _.filter(self.IrModuleModule, function(item){
+        return item.name == model;
+      });
+    },
+
+    ShowDateRange : function(){
+        var self = this;
+        var date = self.$el.find('#current-date').val();
+        if(date == 'range'){
+            self.$el.find('.datepicker').css('display','block');
+        }
+        if(date != 'range'){
+            self.$el.find('.datepicker').css('display','none');
+        }
+
+    },
+
+    clickAnalysisDetail : function(e, row, $element, field){
+
+      if(field == 'name'){
+        this.do_action({
+          name : 'Proveedor',
+          type : 'ir.actions.act_window',
+          res_model : 'res.partner',
+          views : [[false,'form']],
+          target  : 'new',
+          domain : [['id','=',row.partner_id]],
+          context : {},
+          flags : {'form' : {'action_buttons' : false, 'options' : {'mode' : 'view'}}},
+          res_id : row.partner_id,
+        });
+      }
+
+      if(field == 'number'){
+        this.do_action({
+          name : 'Factura',
+          type : 'ir.actions.act_window',
+          res_model : 'account.invoice',
+          views : [[false,'form']],
+          target  : 'new',
+          domain : [['id','=',row.invoice_id]],
+          context : {},
+          flags : {'form' : {'action_buttons' : false, 'options' : {'mode' : 'view'}}},
+          res_id : row.invoice_id,
+        });
+      }
+      e.stopImmediatePropagation();
+    },
+
+    fetchInitial: function () {
+        var self = this;
+        self.fetchIrModuleModule().then(function (IrModuleModule) {
+            return IrModuleModule;
+        }).then(function(IrModuleModule) {
+            self.IrModuleModule = IrModuleModule;
+            return self.fetchResUser();
+        }).then(function (ResUser) {
+            self.ResUser = ResUser;
+            if(ResUser.length > 1){
+                self.$el.find('#current-user').append('<option value="9999999">Todos los vendedores</option>');
+                _.each(ResUser,function(item){
+                    self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }else{
+                self.$el.find('.user').css('display','none');
+            }
+            return self.fetchResCompany();
+        }).then(function(ResCompany){
+            self.ResCompany = ResCompany;
+            if(ResCompany.length > 1){
+                self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                _.each(ResCompany,function(item){
+                    self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }else{
+                self.$el.find('.company').css('display','none');
+            }
+            return self.fetchResStore();
+        }).then(function(ResStore){
+            self.ResStore = ResStore;
+            if(ResStore.length > 1){
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }else{
+                self.$el.find('.store').css('display','none');
+            }
+
+            return self.fetchAccountPeriod();
+        }).then(function(AccountPeriod){
+            self.AccountPeriod = AccountPeriod;
+            self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+            _.each(AccountPeriod,function(item){
+              self.$el.find('#current-period').append('<option value="' +  item.id + '">' + item.name + '</option>');
+            });
+            return self.fetchProductCategory();
+        }).then(function(ProductCategory){
+            self.ProductCategory = ProductCategory;
+            self.$el.find('#current-category').append('<option value="9999999">Todas las categorias</option>');
+            _.each(ProductCategory,function(item){
+                self.$el.find('#current-category').append('<option value="' + item.id + '">' + item.complete_name + '</option>');
+            });
+            return self.fetchProductBrand();
+        }).then(function(ProductBrand){
+            self.ProductBrand = ProductBrand;
+            if(ProductBrand.length > 0){
+                self.$el.find('#current-brand').append('<option value="9999999">Todas las marcas</option>');
+                _.each(ProductBrand,function(item){
+                    self.$el.find('#current-brand').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }else{
+                self.$el.find('.brand').css('display','none');
+            }
+            return self.fetchProductAttribute();
+        }).then(function(ProductAttribute){
+            self.ProductAttribute = ProductAttribute;
+            if(ProductAttribute.length > 0){
+                self.$el.find('#current-attribute').append('<option value="9999999">Todos los atributos</option>');
+                _.each(ProductAttribute,function(item){
+                    self.$el.find('#current-attribute').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }else{
+                self.$el.find('.attribute').css('display','none');
+            }
+            return self.fetchProductAttributeValue();
+        }).then(function(ProductAttributeValue){
+            self.ProductAttributeValue = ProductAttributeValue;
+            if(ProductAttributeValue.length > 0){
+                self.$el.find('#current-attribute-value').append('<option value="9999999">Todos los valores de atributos</option>');
+                _.each(ProductAttributeValue,function(item){
+                    self.$el.find('#current-attribute-value').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }else{
+                self.$el.find('.attribute-value').css('display','none');
+            }
+            return self.fetchProductTemplate();
+        }).then(function(ProductTemplate){
+            self.ProductTemplate = ProductTemplate;
+            if(ProductTemplate.length > 0){
+                self.$el.find('#current-product').append('<option value="9999999">Todos los productos</option>');
+                _.each(ProductTemplate,function(item){
+                    self.$el.find('#current-product').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }else{
+                self.$el.find('.product').css('display','none');
+            }
+            return self.fetchResCurrency();
+        }).then(function(ResCurrency){
+            self.ResCurrency = ResCurrency;
+            return self.fetchAccountJournal();
+        }).then(function(AccountJournal){
+            self.AccountJournal = AccountJournal;
+        });
+        self.$el.find('#generate').css('display','inline');
+        return;
+    },
+
+    fetchGenerate: function () {
+        var self = this;
+        self.$el.find('.search-form').block({
+            message: null,
+            overlayCSS: {
+                backgroundColor: '#FAFAFA'
+            }
+        });
+        self.$el.find('.report-form').block({
+            message: null,
+            overlayCSS: {
+                backgroundColor: '#FAFAFA'
+            }
+        });
+
+        this.fetchAccountInvoice().then(function(AccountInvoice) {
+            return AccountInvoice;
+        }).then(function (AccountInvoice) {
+            self.AccountInvoice = AccountInvoice;
+            return self.fetchAccountInvoiceLine();
+        }).then(function (AccountInvoiceLine){
+            self.AccountInvoiceLine = AccountInvoiceLine;
+            return self.fetchResPartner();
+        }).then(function (ResPartner) {
+            self.ResPartner = ResPartner;
+            return self.BuildTable();
+        });
+    },
+
+    /*=====================================================================
+        IR MODULE
+    =====================================================================*/
+    fetchIrModuleModule: function(){
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['name','id'];
+        var domain=[['state','=','installed'],['name','in',self.modules]];
+        var IrModuleModule = new model.web.Model('ir.module.module');
+        IrModuleModule.query(fields).filter(domain).all().then(function(results){
+            defer.resolve(results);
+        })
+        return defer;
+    },
+
+    /*=====================================================================
+        USER
+    =====================================================================*/
+    fetchResUser: function() {
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['id','name','store_id'];
+        var ResUser = new model.web.Model('res.users');
+        ResUser.query(fields).filter().all().then(function (results) {
+            defer.resolve(results);
+        });
+        return defer;
+    },
+
+    /*====================================================================
+        RES COMPANY
+    ====================================================================*/
+    fetchResCompany: function(){
+        var self = this;
+        var defer = $.Deferred();
+        var currency = new model.web.Model('res.company');
+        var field=['id','name','currency_id','logo'];
+        currency.query(field).filter().all().then(function(results){
+            defer.resolve(results);
+        });
+        return defer;
+    },
+
+    /*====================================================================
+        ACCOUNT JOURNAL
+    ====================================================================*/
+    fetchAccountJournal: function(){
+        var self = this;
+        var domain = [['active','=',true],['type','=','purchase']];
+        var AccountJournal = new model.web.Model('account.journal');
+        return AccountJournal.call('getAccountJournal',[domain], {
+            context: new model.web.CompoundContext()
+        });
+    },
+
+    /*====================================================================
+        RES STORE
+    ====================================================================*/
+    fetchResStore: function(){
+        var self = this;
+        var defer = $.Deferred();
+        var field = ['id','name','company_id'];
+        var ResStore = new model.web.Model('res.store');
+        ResStore.query(field).all().then(function(results){
+            defer.resolve(results);
+        });
+        return defer;
+    },
+
+    /*=====================================================================
+        ACCOUNT PERIOD
+    =====================================================================*/
+    fetchAccountPeriod: function () {
+        var self = this;
+        var defer = $.Deferred();
+        var domain = [['special','=',false]];
+        var field =['id', 'name', 'date_start','date_stop','company_id'];
+        var AccountPeriod = new model.web.Model('account.period');
+        AccountPeriod.query(field).filter(domain).all().then(function (results) {
+            defer.resolve(results);
+        });
+        return defer;
+    },
+
+    /*====================================================================
+        PRODUCT TEMPLATE
+    ====================================================================*/
+    fetchProductTemplate: function(){
+        var self = this;
+        var defer = $.Deferred();
+        var field = ['id','name','product_variant_ids','store_id'];
+        var domain = [
+          ['active','=', true],
+          ['purchase_ok','=',true]];
+        var ProductTemplate = new model.web.Model('product.template');
+        ProductTemplate.query(field).filter(domain).all().then(function(results){
+            defer.resolve(results);
+        });
+        return defer;
+    },
+
+    /*====================================================================
+        PRODUCT CATEGORY
+    ====================================================================*/
+    fetchProductCategory : function(){
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['id','name','parent_id','complete_name'];
+        var ProductCategory = new model.web.Model('product.category');
+        ProductCategory.query(fields).filter().all().then(function(results) {
+            defer.resolve(results);
+        });
+        return defer;
+    },
+
+    /*====================================================================
+        PRODUCT BRAND
+    ====================================================================*/
+    fetchProductBrand : function(){
+        var self = this;
+        var defer = $.Deferred();
+        var modules = self.checkModel('product_brand');
+        if (modules.length > 0){
+            var fields = ['id','name'];
+            var ProductBrand = new model.web.Model('product.brand');
+            ProductBrand.query(fields).filter().all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        }else{
+            var ProductBrand = [];
+            return ProductBrand;
+        }
+    },
+
+    /*====================================================================
+        PRODUCT ATTRIBUTE
+    ====================================================================*/
+    fetchProductAttribute : function(){
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['id','name'];
+        var ProductAttribute = new model.web.Model('product.attribute');
+        ProductAttribute.query(fields).filter().all().then(function(results) {
+            defer.resolve(results);
+        });
+        return defer;
+    },
+
+    /*====================================================================
+        PRODUCT ATTRIBUTE VALUE
+    ====================================================================*/
+    fetchProductAttributeValue : function(){
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['id','name','attribute_id'];
+        var ProductAttributeValue = new model.web.Model('product.attribute.value');
+        ProductAttributeValue.query(fields).filter().all().then(function(results) {
+            defer.resolve(results);
+        });
+        return defer;
+    },
+
+    /*====================================================================
+        RES CURRENCY
+    ====================================================================*/
+    fetchResCurrency : function(){
+        var self = this;
+        var defer = $.Deferred();
+        var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+        var domain = [['active', '=', true]];
+        var ResCurrency = new model.web.Model('res.currency');
+        ResCurrency.query(fields).filter(domain).all().then(function(results) {
+            defer.resolve(results);
+        });
+        return defer;
+    },
+
+    /*====================================================================
+        ACCOUNT INVOICE
+    ====================================================================*/
+    fetchAccountInvoice: function () {
+        var self = this;
+        var user = self.$el.find('#current-user').val();
+        var store = self.$el.find('#current-store').val();
+        var period = self.$el.find('#current-period').val();
+        var company = self.$el.find('#current-company').val();
+        var date = self.$el.find('#current-date').val();
+        var desde = self.$el.find('#from').val();
+        var hasta = self.$el.find('#to').val();
+
+        if(store && store != 9999999){
+            var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                return item.store_ids[0] == store;
+            }), function(map){
+                return map.id;
+            });
+        }else{
+            var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                return item.id;
+            }));
+        }
+
+        var domain = [
+            ['state', 'in',['open','paid']],
+            ['type', '=', 'in_invoice'],
+            ['journal_id','in',journal_ids],
+        ];
+
+        if(company && company != 9999999){
+            domain.push(['company_id','=',parseInt(company)]);
+        }
+
+        if(user && user != 9999999){
+            domain.push(['user_id','=',parseInt(user)]);
+        }
+
+        if(period && period != 9999999){
+            domain.push(['period_id','=',parseInt(period)]);
+        }
+
+        if(date && date != 9999999){
+
+            if(desde){
+                var date = desde.split('/')
+                date = (date[2]+"-"+date[1]+"-"+date[0]);
+                domain.push(['date_invoice','>=',date]);
+            }
+
+            if(hasta){
+                var date = hasta.split('/')
+                date = (date[2]+"-"+date[1]+"-"+date[0]);
+                domain.push(['date_invoice','<=',date]);
+            }
+
+            if(date == 'today'){
+                var today = moment().format('YYYY-MM-DD');
+                domain.push(['date_invoice','=',today]);
+            }
+
+            if(date == 'yesterday'){
+                var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                domain.push(['date_invoice','=',yesterday]);
+            }
+
+            if(date == 'currentMonth'){
+                var currentMonth = moment().format('YYYY-MM');
+                domain.push(['date_invoice','like',currentMonth]);
+            }
+
+            if(date == 'lastMonth'){
+                var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                domain.push(['date_invoice','like',lastMonth]);
+            }
+        }
+
+        var AccountInvoice = new model.web.Model('account.invoice');
+        return AccountInvoice.call('getAccountInvoice',[domain], {
+            context: new model.web.CompoundContext()
+        });
+    },
+
+    /*====================================================================
+        ACCOUNT INVOICE LINE
+    ====================================================================*/
+    fetchAccountInvoiceLine: function () {
+      var self = this;
+      var domain = [];
+      var product_ids =[];
+      var categ_ids = [];
+      var templates_ids = [];
+      var brand = self.$el.find('#current-brand').val();
+      var product = self.$el.find('#current-product').val();
+      var category = self.$el.find('#current-category').val();
+      var invoice_ids = _.flatten(_.map(self.AccountInvoice, function (item) {
+          return item.id;
+      }));
+      var domain = [
+          ['invoice_id','in',invoice_ids],
+      ];
+
+      if(product && product != 9999999){
+        _.map(_.filter(self.ProductTemplate, function (item) {
+          return item.id == product;
+        }), function(map){
+          if(map.product_variant_ids.length > 1){
+            _.each(map.product_variant_ids, function(each){
+              product_ids.push(each);
+            });
+          }
+          else{
+            product_ids.push(map.product_variant_ids[0]);
+          }
+        });
+        domain.push(['product_id','in', product_ids]);
+      }
+
+      if(brand && brand != 9999999){
+          domain.push(['product_id.product_brand_id','=',parseInt(brand)]);
+      }
+
+      /*
+      =================================================
+          OBTENER CATEGORIAS EN CASCADA
+      =================================================
+      */
+      if(category){
+          // Nivel 0, nivel 1
+          var category_ids = _.map(_.filter(self.ProductCategory,function (item) {
+              return item.id == category || item.parent_id[0] == category;
+          }), function(map){
+              return map.id;
+          });
+
+          // Nivel 0, nivel 1, nivel 2
+          var category_children_ids = _.map(_.filter(self.ProductCategory,function (item) {
+              return _.contains(category_ids, item.parent_id[0]) || item.id == category;
+          }), function(map){
+              return map.id;
+          });
+
+          // Nivel 0, nivel 1, nivel 2, nivel 3
+          var category_grandchildren_ids = _.map(_.filter(self.ProductCategory,function (item) {
+              return _.contains(category_children_ids, item.parent_id[0]) || item.id == category;
+          }), function(map){
+              return map.id;
+          }) ;
+
+          // Nivel 0, nivel 1, nivel 2, nivel 3, nivel 4
+          categ_ids =  _.map(_.filter(self.ProductCategory,function (item) {
+              return _.contains(category_grandchildren_ids, item.parent_id[0]) || item.id == category;
+          }), function(map){
+              return map.id;
+          });
+      };
+
+      if(category && category != 9999999){
+          domain.push(['product_id.categ_id','in',categ_ids]);
+      }
+
+      var AccountInvoiceLine = new model.web.Model('account.invoice.line');
+      return AccountInvoiceLine.call('getAccountInvoiceLine',[domain], {
+          context: new model.web.CompoundContext()
+      });
+    },
+
+    /*====================================================================
+        UPDATE SELECTIONS
+    ====================================================================*/
+    updateSelections: function () {
+        var self = this;
+        var company = self.$el.find('#current-company').val();
+        if(company != 9999999){
+            /*===================
+                STORE SELECTION
+            ===================*/
+            var store = self.$el.find('#current-store').empty();
+            self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+            _.each(self.ResStore,function(item){
+                if(parseFloat(company) == item.company_id[0]){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                }
+            });
+            /*====================
+                PERIOD SELECTION
+            ====================*/
+            var period = self.$el.find('#current-period').empty();
+            self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+            _.each(self.AccountPeriod,function(item){
+                if(parseFloat(company) == item.company_id[0]){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                }
+            });
+        }else{
+            /*===================
+                STORE SELECTION
+            ===================*/
+            var store = self.$el.find('#current-store').empty();
+            self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+            _.each(self.ResStore,function(item){
+                self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+            });
+            /*====================
+                PERIOD SELECTION
+            ====================*/
+            var period = self.$el.find('#current-period').empty();
+            self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+            _.each(self.AccountPeriod,function(item){
+                self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+            });
+        }
+    },
+    updatePeriodSelections: function () {
+        var self = this;
+        var period = self.$el.find('#current-period').val();
+        if(period != 9999999){
+            self.$el.find('#current-date').val(9999999);
+            self.$el.find('#current-date').prop('disabled','disabled');
+            self.$el.find('.datepicker').css('display','none');
+        }else{
+            self.$el.find('#current-date').prop('disabled',false);
+        }
+    },
+
+    updateUsers: function(){
+      var self = this;
+      var store = self.$el.find('#current-store').val();
+      if(store != 9999999){
+          var user = self.$el.find('#current-user').empty();
+          self.$el.find('#current-user').append('<option value="9999999">Todos los vendedores</option>');
+          _.each(self.ResUser,function(item){
+              if(parseFloat(store) == item.store_id[0]){
+                  self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+              }
+          });
+      }else{
+          var user = self.$el.find('#current-user').empty();
+          self.$el.find('#current-user').append('<option value="9999999">Todos los vendedores</option>');
+          _.each(self.ResUser,function(item){
+              self.$el.find('#current-user').append('<option value="' + item.id + '">' + item.name + '</option>');
+          });
+      }
+    },
+
+    /*====================================================================
+        GET RES COMPANY
+    ====================================================================*/
+    getResCompany: function (id) {
+        var self = this;
+        return _.filter(self.ResCompany,function (item) {
+            return item.id == id;
+        })
+    },
+
+    /*====================================================================
+        GET RES CURRENCY BASE
+    ====================================================================*/
+    getResCurrency: function (id) {
+        var self = this;
+        return _.filter(self.ResCurrency,function (item) {
+            return item.id === id;
+        })
+    },
+
+    /*====================================================================
+        GET ACCOUNT INVOICE
+    ====================================================================*/
+    getAccountInvoice: function (id) {
+        var self = this;
+        return _.flatten(_.filter(self.AccountInvoice,function (item) {
+            return item.partner_id[0] == id;
+        }));
+    },
+
+    /*====================================================================
+        GET ACCOUNT INVOICE LINE
+    ====================================================================*/
+    getAccountInvoiceLine: function (id) {
+        var self = this;
+        return _.flatten(_.filter(self.AccountInvoiceLine,function (item) {
+            return item.invoice_id == id;
+        }));
+    },
+
+    /*====================================================================
+        RES PARTNER
+    ====================================================================*/
+    fetchResPartner : function () {
+        var self = this;
+        var partner_ids = _.flatten(_.map(self.AccountInvoice, function (item) {
+            return item.partner_id[0];
+        }));
+
+        var domain = [
+          ['id','in',partner_ids],
+          ['active', '=', true],
+          ['supplier', '=', true]];
+
+        var ResPartner = new model.web.Model('res.partner');
+        return ResPartner.call('getResPartner',[domain], {
+            context: new model.web.CompoundContext()
+        });
+    },
+
+
+    /*====================================================================
+        BUILD
+    ====================================================================*/
+    BuildTable: function(){
+        var self = this;
+        var data = [];
+        var company = $('#current-company').val();
+        if(company && company != 9999999){
+            var ResCompany = self.getResCompany(company).shift();
+            var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+        }else{
+            var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+        }
+
+        var ResPartner = self.ResPartner;
+        _.each(ResPartner, function(item){
+            var suma_invoice = 0;
+            var invoice_item = 0;
+            var info = [];
+
+            /*====================================================================
+                RECORRER ACCOUNT INVOCE
+            ====================================================================*/
+
+            var AccountInvoice = self.getAccountInvoice(item.id);
+            _.each(AccountInvoice,function(index) {
+                var AccountInvoiceLine = self.getAccountInvoiceLine(index.id);
+                _.each(AccountInvoiceLine,function(index2) {
+                    invoice_item = invoice_item + index2.quantity;
+                    suma_invoice = suma_invoice + (index2.price_unit*index2.quantity);
+                });
+                info.push({
+                    /*=======================
+                        IDS
+                    =======================*/
+                    invoice_id: index.id,
+                    /*=======================
+                        DATAS
+                    =======================*/
+                    number: index.number,
+                    date: moment(index.date_invoice).format('DD/MM/YYYY'),
+                    customer: index.partner_id[1],
+                    amount: accounting.formatMoney(index.amount_total,'',CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                });
+            });
+            if(suma_invoice > 0){
+                data.push({
+                    //IDS
+                    partner_id: item.id,
+                    //DATAS
+                    name : item.name,
+                    suma_invoice : accounting.formatMoney(suma_invoice,'',CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator),
+                    invoice_item : accounting.formatNumber(invoice_item,CurrencyBase.decimal_places,CurrencyBase.thousands_separator,CurrencyBase.decimal_separator),
+                    //VALORES SIN FORMATEAR
+                    suma_invoice_not_format : suma_invoice,
+                    invoice_item_no_format: invoice_item,
+                    //TOTAL FOOTER CONFIGURATION
+                    decimal_places : CurrencyBase.decimal_places,
+                    thousands_separator: CurrencyBase.thousands_separator,
+                    decimal_separator: CurrencyBase.decimal_separator,
+                    info :info,
+                });
+            }
+        });
+        data.sort(function(a, b) {
+            return b.suma_invoice_not_format - a.suma_invoice_not_format
+        });
+        self.content = data;
+        self.CallCharts(data,CurrencyBase);
+        self.loadTable(data);
+    },
+
+    /*
+    ======================================================================
+        LLAMAR LOS GRAFICOS
+    ======================================================================
+    */
+    CallCharts: function(data,CurrencyBase){
+        var self = this;
+        /*
+        ================================================
+        GRAFICO DE BARRAS
+        ================================================
+        */
+        var BarChart = new reporting.ReportChartWidget(self);
+        var rank = 10;
+        var item;
+        var label = [];
+        var body = [];
+        for (var i = 0; i < rank; i++) {
+            if (data[i]){
+                item = data[i];
+            }else{
+                item = {};
+                item.name = "N/A";
+                item.suma_invoice_not_format = 0;
+            }
+            label.push(item.name.trim());
+            body.push(item.suma_invoice_not_format);
+        }
+        BarChart.BuildBarChart(data,CurrencyBase,label,body);
+
+        /*
+        ================================================
+        GRAFICO CIRCULAR
+        ================================================
+        */
+        var PieChart = new reporting.ReportChartWidget(self);
+        var rank = 9;
+        var item;
+        var label = [];
+        var body = [];
+        var amount_total = _.reduce(_.map(data, function (map) {
+            return map.suma_invoice_not_format
+        }), function (meno,num) {
+            return meno + num
+        }, 0);
+        for (var i = 0; i < rank; i++) {
+            if (data[i]){
+                item = data[i];
+            }else{
+                item = {};
+                item.name = "N/A";
+                item.suma_invoice_not_format = 0;
+            }
+            label.push(item.name.trim());
+            body.push((item.suma_invoice_not_format/amount_total)*100);
+        }
+        var num = 0;
+        for (var i = 9; i < data.length; i++) {
+            num += data[i].suma_invoice_not_format;
+        }
+        if(num > 0){
+            label.push('Otros Productos');
+            body.push((num/amount_total)*100);
+        }
+        PieChart.BuildPieChart(data,CurrencyBase,label,body);
+        self.$el.find('.report-form').css('display','block');
+        self.$el.find('.search-form').unblock();
+        self.$el.find('.report-form').unblock();
+    },
+
+
+
+    /*====================================================================
+        LOAD BOOTSTRAP TABLE
+    ====================================================================*/
+
+    loadTable: function(rowsTable) {
+      var self = this;
+      var data = [];
+      self.rowsData = rowsTable;
+      var table = this.$el.find('#table');
+
+      table.bootstrapTable({
+        data: rowsTable,
+        detailView: true,
+        onExpandRow: function(index, row, $detail) {
+          $detail.html('<div class="panel panel-first-style"><div class="panel-heading panel-header-first-style">Facturas de Proveedor</div><table id="table2"></table></div>').find('table').bootstrapTable({
+            columns: [{
+                field: 'number',
+                title: 'Factura',
+                align: 'left',
+                class: 'hover',
+              },
+              {
+                field: 'date',
+                title: 'Fecha',
+                align: 'left',
+              },
+              {
+                field: 'amount',
+                title: 'Monto',
+                align: 'right',
+              },
+            ],
+
+            data: row.info,
+          })
+          $('#table2').removeClass('table-hover').addClass('table-no-bordered');
+          $('thead').css('background', 'none');
+        }
+      })
+
+      table.bootstrapTable('load', rowsTable);
+    },
+
+    /*====================================================================
+        PRINT PDF
+    ====================================================================*/
+    clickOnAction: function (e) {
+        var self = this;
+        var ResCompany;
+        var action = this.$el.find(e.target).val();
+        var company = $('#current-company').val();
+        if(company && company != 9999999){
+            var ResCompany = self.getResCompany(company).shift();
+            var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+        }else{
+            ResCompany = self.ResCompany[0];
+            var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+        }
+        var getColumns=[];
+        var rows=[];
+        var table = this.$el.find("#table");
+        var column = table.bootstrapTable('getVisibleColumns');
+        var row = table.bootstrapTable('getData');
+
+        var amount = totalAmountFormatter(row);
+        var qty = totalQtyFormatter(row);
+
+        row.push({
+            name: 'Totales',
+            suma_invoice: amount,
+            invoice_item: qty,
+        })
+
+        if (action === 'pdf') {
+            var data = _.map(column, function (val){ return val.field});
+            _.each(_.map(column,function(val){
+                return val}), function(item){
+                getColumns.push([{
+                    title: item.title,
+                    dataKey: item.field
+                }]);
+            });
+            /*
+            ============================================================
+                CONFIGURACION DEL PDF
+            ============================================================
+            */
+            var pdf_title = 'Ranking de Proveedores';
+            var pdf_type = '';
+            var pdf_name = 'ranking_proveedores_';
+            var pdf_columnStyles = {
+                name :{columnWidth: 100, halign:'left'},
+                invoice_item : {columnWidth: 45, halign:'right'},
+                suma_invoice :{columnWidth: 45, halign:'right'},
+            };
+            /*
+            ============================================================
+                LLAMAR FUNCION DE IMPRESION
+            ============================================================
+            */
+            var filter = self.getFilter();
+            var pdf = new reporting.ReportPdfWidget(self);
+            pdf.drawPDF(
+                _.flatten(getColumns),
+                row,
+                ResCompany,
+                pdf_title,
+                pdf_type,
+                pdf_name,
+                pdf_columnStyles,
+                filter,
+            );
+        }
+    },
+    getFilter: function(){
+      var self = this;
+      var company = self.$el.find('#current-company').val();
+      var store = self.$el.find('#current-store').val();
+      var user = self.$el.find('#current-user').val();
+      var product = self.$el.find('#current-product').val();
+      var brand = self.$el.find('#current-brand').val();
+      var category = self.$el.find('#current-category').val();
+      var period = self.$el.find('#current-period').val();
+      var date = self.$el.find('#current-date').val();
+      var desde = self.$el.find('#from').val();
+      var hasta = self.$el.find('#to').val();
+      var filter = [];
+
+      if(company && company != 9999999){
+        var ResCompany = _.filter(self.ResCompany, function(item){
+          return item.id == company;
+        });
+        filter.push({
+          title:'Empresa',
+          value: ResCompany[0].name,
+        });
+      }
+
+      if(store && store != 9999999){
+        var ResStore =  _.filter(self.ResStore,function (item) {
+            return item.id == store;
+        });
+
+        filter.push({
+             title: 'Sucursal',
+             value:  ResStore[0].name,
+           });
+      }
+
+      if(user && user != 9999999){
+        var ResUser =  _.filter(self.ResUser,function (item) {
+            return item.id == user;
+        });
+
+        filter.push({
+             title: 'Vendedor',
+             value:  ResUser[0].name,
+           });
+      }
+
+      if(product && product != 9999999){
+        var Product =  _.filter(self.ProductTemplate,function (item) {
+            return item.id == product;
+        });
+        filter.push({
+             title: 'Producto',
+             value:  Product[0].name,
+           });
+      }
+
+      if(brand && brand != 9999999){
+        var brand =  _.filter(self.ProductBrand,function (item) {
+            return item.id == brand;
+        });
+        filter.push({
+             title: 'Marca',
+             value: brand[0].name,
+           });
+      }
+
+      if(category && category != 9999999){
+        var categ =  _.filter(self.ProductCategory,function (item) {
+            return item.id == category;
+        });
+        filter.push({
+             title: 'Categoría',
+             value: categ[0].name,
+           });
+      }
+
+      if(period && period != 9999999){
+
+        var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+            return item.id == period;
+        });
+        filter.push({
+             title: 'Periodo',
+             value:  AccountPeriod[0].name,
+           });
+      }
+
+      if(date && date != 9999999){
+        moment.locale('es', {
+          months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+        });
+
+        if(date == 'range'){
+          filter.push({
+              title: 'Fecha',
+              value:  desde +' al '+hasta,
+          });
+
+        }
+        else {
+          if(date == 'today'){
+              var fecha = moment().format('DD/MM/YYYY');
+          }
+
+          if(date == 'yesterday'){
+              var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+          }
+          if(date == 'currentMonth'){
+              var fecha = moment().format('MMMM/YYYY');
+          }
+          if(date == 'lastMonth'){
+              var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+          }
+
+          filter.push({
+              title: 'Fecha',
+              value:  fecha,
+          });
+        }
+      }
+
+      return filter;
+    }
+
+
+
+  });
+}

+ 1027 - 0
static/src/js/reports/report_supplier_refund.js

@@ -0,0 +1,1027 @@
+function report_supplier_refund(reporting){
+    "use strict";
+
+    var model = openerp;
+
+    reporting.ReportSupplierRefundWidget = reporting.Base.extend({
+        template: 'ReportSupplierRefund',
+        rowsData :[],
+        content :[],
+
+        events:{
+            'click #toolbar > button' : 'clickOnAction',
+            'click #generate' : 'fetchGenerate',
+            'change #current-company' : 'updateSelections',
+            'change #current-store' : 'updateJournalSelections',
+            'change #current-period' : 'updatePeriodSelections',
+            'change #current-date' : 'ShowDateRange',
+        },
+
+        init : function(parent){
+            this._super(parent);
+        },
+
+        start: function () {
+            var table = this.$el.find('#table');
+            table.bootstrapTable({data : self.rowsData});
+            var date = new reporting.ReportDatePickerWidget(self);
+            date.fecthFecha();
+            this.fetchInitial();
+        },
+
+        valorNull:function(dato){
+            var valor = "";
+            if (dato){
+                valor = dato;
+            }
+            return valor;
+        },
+
+        ShowDateRange : function(){
+            var self = this;
+            var date = self.$el.find('#current-date').val();
+            if(date == 'range'){
+                self.$el.find('.datepicker').css('display','block');
+            }
+            if(date != 'range'){
+                self.$el.find('.datepicker').css('display','none');
+            }
+
+        },
+
+        fetchInitial: function () {
+            var self = this;
+            self.fecthIrModuleModule().then(function (IrModuleModule) {
+                return IrModuleModule;
+            }).then(function(IrModuleModule) {
+                self.IrModuleModule = IrModuleModule;
+                return self.fetchResUser;
+            }).then(function (ResUser) {
+                self.ResUser = ResUser;
+                return self.fetchResCompany();
+            }).then(function(ResCompany){
+                self.ResCompany = ResCompany;
+                if(ResCompany.length > 1){
+                    self.$el.find('#current-company').append('<option value="9999999">Todas las empresas</option>');
+                    _.each(ResCompany,function(item){
+                        self.$el.find('#current-company').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.company').css('display','none');
+                }
+                return self.fetchResStore();
+            }).then(function(ResStore){
+                self.ResStore = ResStore;
+                if(ResStore.length > 1){
+                    self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                    _.each(ResStore,function(item){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.store').css('display','none');
+                }
+                return self.fetchAccountJournal();
+            }).then(function(AccountJournal){
+                self.AccountJournal = AccountJournal;
+                if(AccountJournal.length > 1){
+                    self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                    _.each(AccountJournal,function(item){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    });
+                }else{
+                    self.$el.find('.journal').css('display','none');
+                }
+                return self.fetchAccountPeriod();
+            }).then(function(AccountPeriod){
+                self.AccountPeriod = AccountPeriod;
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                return self.fetchResCurrency();
+            }).then(function(ResCurrency){
+                self.ResCurrency = ResCurrency;
+            });
+            self.$el.find('#generate').css('display','inline');
+            return;
+        },
+
+        fetchGenerate: function () {
+            var self = this;
+            self.$el.find('.search-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            self.$el.find('.report-form').block({
+                message: null,
+                overlayCSS: {
+                    backgroundColor: '#FAFAFA'
+                }
+            });
+            this.fetchAccountInvoice().then(function(AccountInvoice) {
+                return AccountInvoice;
+            }).then(function (AccountInvoice) {
+                self.AccountInvoice = AccountInvoice;
+                return self.fetchAccountInvoiceLine();
+            }).then(function (AccountInvoiceLine){
+                self.AccountInvoiceLine = AccountInvoiceLine;
+                return self.fetchAccountVoucher();
+            }).then(function (AccountVoucher){
+                self.AccountVoucher = AccountVoucher;
+                return self.BuildTable();
+            });
+        },
+
+        /*=====================================================================
+            IR MODULE
+        =====================================================================*/
+        fecthIrModuleModule: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['name','id'];
+            var domain=[['state','=','installed']];
+            var IrModuleModule = new model.web.Model('ir.module.module');
+            IrModuleModule.query(fields).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            })
+            return defer;
+        },
+
+        /*=====================================================================
+            USER
+        =====================================================================*/
+        fetchResUser: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name','store_id'];
+            var domain = [['id','=',self.session.uid]];
+            var ResUser = new model.web.Model('res.users');
+            ResUser.query(fields).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*=====================================================================
+            ACCOUNT PERIOD
+        =====================================================================*/
+        fetchAccountPeriod: function () {
+            var self = this;
+            var defer = $.Deferred();
+            var domain = [['special','=',false]];
+            var field =['id', 'name', 'date_start','date_stop','company_id'];
+            var AccountPeriod = new model.web.Model('account.period');
+            AccountPeriod.query(field).filter(domain).all().then(function (results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES STORE
+        ====================================================================*/
+        fetchResStore: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var field = ['id','name','company_id'];
+            var ResStore = new model.web.Model('res.store');
+            ResStore.query(field).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT JOURNAL
+        ====================================================================*/
+        fetchAccountJournal: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var company = $('#current-company').val();
+            var store = $('#current-store').val();
+            var domain = [['active','=',true],['type','=','purchase_refund']];
+            if(company && company != 9999999){
+                domain.push(['company_id','=',parseFloat(company)]);
+            }
+            if(store && store != 9999999){
+                domain.push(['store_ids','=',parseFloat(store)]);
+            }
+            var field = ['id', 'name','store_ids'];
+            var AccountJournal = new model.web.Model('account.journal');
+            AccountJournal.query(field).filter(domain).all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE
+        ====================================================================*/
+        fetchAccountInvoice: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            var period = self.$el.find('#current-period').val();
+            var state = self.$el.find('#current-state').val();
+            var date = self.$el.find('#current-date').val();
+            var desde = self.$el.find('#from').val();
+            var hasta = self.$el.find('#to').val();
+            var journal = self.$el.find('#current-journal').val();
+            if(store && store != 9999999){
+                var journal_ids = _.map(_.filter(self.AccountJournal,function (item) {
+                    return item.store_ids == store;
+                }), function(map){
+                    return map.id;
+                });
+            }else{
+                var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
+                    return item.id;
+                }));
+            }
+            var domain = [
+                ['state', 'in',['open','paid']],
+                ['type', '=', 'in_refund'],
+                ['journal_id','in',journal_ids],
+            ];
+            if(period != 9999999){
+                domain.push(['period_id','=',parseInt(period)]);
+            }
+            if(journal && journal != 9999999){
+                domain.push(['journal_id','=',parseInt(journal)]);
+            }
+            if(state != 9999999){
+                domain.push(['state','=',state]);
+            }
+            if(date && date != 9999999){
+                if(date == 'range'){
+                    if(desde){
+                        var date = desde.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','>=',date]);
+                    }
+                    if(hasta){
+                        var date = hasta.split('/')
+                        date = (date[2]+"-"+date[1]+"-"+date[0]);
+                        domain.push(['date_invoice','<=',date]);
+                    }
+                }
+                if(date == 'today'){
+                    var today = moment().format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',today]);
+                }
+
+                if(date == 'yesterday'){
+                    var yesterday = moment().add(-1,'days').format('YYYY-MM-DD');
+                    domain.push(['date_invoice','=',yesterday]);
+                }
+                if(date == 'currentMonth'){
+                    var currentMonth = moment().format('YYYY-MM');
+                    domain.push(['date_invoice','like',currentMonth]);
+                }
+                if(date == 'lastMonth'){
+                    var lastMonth = moment().add(-1,'months').format('YYYY-MM');
+                    domain.push(['date_invoice','like',lastMonth]);
+                }
+            }
+            var AccountInvoice = new model.web.Model('account.invoice');
+            return AccountInvoice.call('getAccountInvoice',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            ACCOUNT INVOICE LINE
+        ====================================================================*/
+        fetchAccountInvoiceLine: function (){
+            var self = this;
+            var invoice_ids = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.id;
+            }));
+            var domain = [
+                ['invoice_id','in',invoice_ids],
+            ];
+            var AccountInvoiceLine = new model.web.Model('account.invoice.line');
+            return AccountInvoiceLine.call('getAccountInvoiceLine',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+
+        /*=====================================================================
+            ACCOUNT VOUCHER
+        =====================================================================*/
+        fetchAccountVoucher: function () {
+            var self = this;
+            var invoice_numbers = _.flatten(_.map(self.AccountInvoice, function (item) {
+                return item.number;
+            }));
+            var domain = [
+                ['type','=','payment'],
+                ['state','=','posted'],
+                ['reference','in',invoice_numbers]
+            ];
+            var AccountVoucher = new model.web.Model('account.voucher');
+            return AccountVoucher.call('getAccountVoucher',[domain], {
+                context: new model.web.CompoundContext()
+            });
+        },
+
+        /*====================================================================
+            RES COMPANY
+        ====================================================================*/
+        fetchResCompany: function(){
+            var self = this;
+            var defer = $.Deferred();
+            var currency = new model.web.Model('res.company');
+            var field=['id','name','currency_id','logo'];
+            currency.query(field).filter().all().then(function(results){
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            RES CURRENCY
+        ====================================================================*/
+        fetchResCurrency : function(){
+            var self = this;
+            var defer = $.Deferred();
+            var fields = ['id','name', 'symbol', 'rate_silent', 'base', 'decimal_separator', 'decimal_places', 'thousands_separator', 'symbol_position'];
+            var domain = [['active', '=', true]];
+            var ResCurrency = new model.web.Model('res.currency');
+            ResCurrency.query(fields).filter(domain).all().then(function(results) {
+                defer.resolve(results);
+            });
+            return defer;
+        },
+
+        /*====================================================================
+            UPDATE SELECTIONS
+        ====================================================================*/
+        updateSelections: function () {
+            var self = this;
+            var company = self.$el.find('#current-company').val();
+            if(company != 9999999){
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    if(parseFloat(company) == item.company_id[0]){
+                        self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*===================
+                    STORE SELECTION
+                ===================*/
+                var store = self.$el.find('#current-store').empty();
+                self.$el.find('#current-store').append('<option value="9999999">Todas las sucursales</option>');
+                _.each(self.ResStore,function(item){
+                    self.$el.find('#current-store').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+                /*====================
+                    PERIOD SELECTION
+                ====================*/
+                var period = self.$el.find('#current-period').empty();
+                self.$el.find('#current-period').append('<option value="9999999">Todos los periodos</option>');
+                _.each(self.AccountPeriod,function(item){
+                    self.$el.find('#current-period').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updateJournalSelections: function () {
+            var self = this;
+            var store = self.$el.find('#current-store').val();
+            if(store != 9999999){
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    if(parseFloat(store) == item.store_ids){
+                        self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                    }
+                });
+            }else{
+                /*=============================
+                    ACCOUNT JOURNAL SELECTION
+                =============================*/
+                var journal = self.$el.find('#current-journal').empty();
+                self.$el.find('#current-journal').append('<option value="9999999">Todas las facturas</option>');
+                _.each(self.AccountJournal,function(item){
+                    self.$el.find('#current-journal').append('<option value="' + item.id + '">' + item.name + '</option>');
+                });
+            }
+        },
+
+        updatePeriodSelections: function () {
+            var self = this;
+            var period = self.$el.find('#current-period').val();
+            if(period != 9999999){
+                self.$el.find('#current-date').val(9999999);
+                self.$el.find('#current-date').prop('disabled','disabled');
+                self.$el.find('.datepicker').css('display','none');
+            }else{
+                self.$el.find('#current-date').prop('disabled',false);
+            }
+        },
+
+        /*====================================================================
+            GET RES COMPANY
+        ====================================================================*/
+        getResCompany: function (id) {
+            var self = this;
+            return _.filter(self.ResCompany,function (item) {
+                return item.id == id;
+            })
+        },
+
+        /*====================================================================
+            GET RES CURRENCY BASE
+        ====================================================================*/
+        getResCurrency: function (id) {
+            var self = this;
+            return _.filter(self.ResCurrency,function (item) {
+                return item.id === id;
+            })
+        },
+
+        /*====================================================================
+            GET ACCOUNT INVOICE LINE
+        ====================================================================*/
+        getAccountInvoiceLine: function (id) {
+            var self = this;
+            return _.filter(self.AccountInvoiceLine,function (item) {
+                return item.invoice_id === id;
+            })
+        },
+
+
+        /*====================================================================
+            GET ACCOUNT VOUCHER
+        ====================================================================*/
+        getAccountVoucher: function (number) {
+            var self = this;
+            return _.filter(self.AccountVoucher,function (item) {
+                return item.reference == number;
+            })
+        },
+
+
+        /*============================
+            ACCOUNT DATA BY MONTH
+        ============================*/
+        getContent:function(mes) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM') === moment(mes).format('YYYY-MM');
+            }));
+        },
+
+        /*============================
+            ACCOUNT DATA BY DAY
+        ============================*/
+        getContentByDay:function(date) {
+            var self = this;
+            return _.flatten(_.filter(self.content,function (inv) {
+                return moment(inv.date).format('YYYY-MM-DD') === date;
+            }));
+        },
+
+
+        /*====================================================================
+            BUILD
+        ====================================================================*/
+        BuildTable: function(){
+            var self = this;
+            var data = [];
+            var info = [];
+            var payments = [];
+
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                var ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+
+                var AccountInvoice = self.AccountInvoice;
+                _.each(AccountInvoice, function(item){
+                    info = [];
+                    payments = [];
+                    var AccountInvoiceLine = self.getAccountInvoiceLine(item.id);
+                    var AccountVoucher = self.getAccountVoucher(item.number);
+                    var Currency = self.getResCurrency(item.invoice_currency[0]).shift();
+                    _.each(AccountInvoiceLine, function(index){
+                        var price_unit = 0;
+                        var amount = 0;
+                        if(Currency.id != CurrencyBase.id){
+                            price_unit = accounting.formatMoney(index.price_unit_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.price_unit, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) +')';
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.price_subtotal, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) +')';
+                        }else{
+                            price_unit = accounting.formatMoney(index.price_unit_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                            amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        }
+                        info.push({
+                            product_name : index.product_id[1],
+                            price_unit : price_unit,
+                            quantity : index.quantity,
+                            amount: amount,
+                        });
+                    });
+                    if(AccountVoucher.length > 0){
+                        _.each(AccountVoucher, function(index){
+                            var CurrencyVoucher = self.getResCurrency(index.currency_id[0]).shift();
+                            var amount = 0;
+                            if(CurrencyVoucher.id != CurrencyBase.id){
+                                amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + ' (' + accounting.formatMoney(index.amount, '', CurrencyVoucher.decimal_places, CurrencyVoucher.thousands_separator, CurrencyVoucher.decimal_separator) +')';
+                            }else{
+                                amount = accounting.formatMoney(index.amount_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                            }
+                            payments.push({
+                                date : moment(index.date).format('DD/MM/YYYY'),
+                                journal_name : index.journal_id[1],
+                                amount : amount,
+                            });
+                        });
+                    }
+
+                    var residual_total = 0;
+                    var amount_untaxed_total = 0;
+                    var amount_tax_total = 0;
+                    var amount_total = 0;
+
+                    if(Currency.id != CurrencyBase.id){
+                        residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.residual, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                        amount_untaxed_total = accounting.formatMoney(item.amount_untaxed_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.amount_untaxed, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                        amount_tax_total = accounting.formatMoney(item.amount_tax_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.amount_tax, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                        amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator) + '  (' + accounting.formatMoney(item.amount_total, '', Currency.decimal_places, Currency.thousands_separator, Currency.decimal_separator) + ')';
+                    }else{
+                        residual_total = accounting.formatMoney(item.residual_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        amount_untaxed_total = accounting.formatMoney(item.amount_untaxed_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        amount_tax_total = accounting.formatMoney(item.amount_tax_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                        amount_total = accounting.formatMoney(item.amount_total_currency, '', CurrencyBase.decimal_places, CurrencyBase.thousands_separator, CurrencyBase.decimal_separator);
+                    }
+
+                    data.push({
+                        /*=======================
+                            IDS
+                        =======================*/
+                        id : item.id,
+                        /*=======================
+                            INFO
+                        =======================*/
+                        number : item.number,
+                        date_invoice : moment(item.date_invoice).format('DD/MM/YYYY'),
+                        date : moment(item.date_invoice).format('YYYY-MM-DD'),
+                        origin : self.valorNull(item.origin),
+                        user_id : item.user_id[1],
+                        partner_id : self.valorNull(item.partner_id[1]),
+                        residual_total : residual_total,
+                        amount_untaxed_total : amount_untaxed_total,
+                        amount_tax_total : amount_tax_total,
+                        amount_total : amount_total,
+                        /*=======================
+                            VALORES SIN FORMATEAR
+                        =======================*/
+                        residual : item.residual_currency,
+                        amount_untaxed : item.amount_untaxed_currency,
+                        amount_tax : item.amount_tax_currency,
+                        amount : item.amount_total_currency,
+                        /*==============================
+                            TOTAL FOOTER CONFIGURATION
+                        ==============================*/
+                        decimal_places : CurrencyBase.decimal_places,
+                        thousands_separator: CurrencyBase.thousands_separator,
+                        decimal_separator: CurrencyBase.decimal_separator,
+                        /*==============================
+                            DATA
+                        ==============================*/
+                        info : info,
+                        payments : payments,
+                    });
+                });
+
+            data.sort(function (a, b) {
+                if (a.date > b.date) {
+                    return -1;
+                }
+                if (a.date < b.date) {
+                    return 1;
+                }
+                return 0;
+            });
+            self.content = data;
+            self.loadTable(data);
+            self.BuildChartByPeriod();
+        },
+
+        /*====================================================================
+            BUILD CHART BY PERIOD
+        ====================================================================*/
+        BuildChartByPeriod: function(){
+            var self = this;
+            var data = [];
+            var label = [];
+            var body = [];
+            var period = self.$el.find('#current-period').val();
+            var date = self.$el.find('#current-date').val();
+            var AccountPeriod = self.AccountPeriod;
+            var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL PERIODO
+            =============================================================================
+            */
+            if(period != 9999999){
+                var range = _.filter(self.AccountPeriod,function (inv) {
+                    return inv.id == parseInt(period);
+                });
+                var date = range[0].date_start;
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > range[0].date_stop){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL RANGO DE FECHAS
+            =============================================================================
+            */
+            if(date == 'range'){
+
+                // DESDE
+                var desde = self.$el.find('#from').val();
+                desde = desde.split('/');
+                desde = (desde[2] + "-" + desde[1] + "-" + desde[0]);
+
+                // HASTA
+                var hasta = self.$el.find('#to').val();
+                if(hasta){
+                    hasta = hasta.split('/');
+                    hasta = (hasta[2] + "-" + hasta[1] + "-" + hasta[0]);
+                }else{
+                    hasta = moment().format('YYYY-MM-DD');
+                }
+                // DETERMINAR RANGO DE FECHAS
+                const diff = moment(hasta).diff(moment(desde),'days');
+
+                if(diff > 0 & diff < 32){
+                    self.$el.find('.chart-container').css('display','block');
+                    var date = desde;
+                    for (var i = 0; i < 32; i++) {
+                        if(i > 0){
+                            date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                        }
+                        if(date > hasta){
+                            break;
+                        }
+                        var data = self.getContentByDay(date);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(moment(date).format('DD/MM/YYYY'));
+                            body.push(total);
+                        }
+                    }
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff > 31){
+                    self.$el.find('.chart-container').css('display','block');
+                    _.each(AccountPeriod, function(item){
+                        var data = self.getContent(item.date_start);
+                        if(data.length > 0){
+                            var total = _.reduce(_.map(data,function(item) {
+                                return item.amount;
+                            }),function(memo, num) {
+                                return memo + num;
+                            },0);
+                            label.push(item.name);
+                            body.push(total);
+                        }
+                    });
+                    self.$el.find('.chart-container').css('display','block');
+                }
+                if(diff == 0){
+                    self.$el.find('.chart-container').css('display','none');
+                }
+            }
+            /*
+            =============================================================================
+                OCULTAR GRAFICO EN EL CASO DE QUE EL FILTRO SEA AYER U HOY
+            =============================================================================
+            */
+            if(date == 'today' || date == 'yesterday'){
+                self.$el.find('.chart-container').css('display','none');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES ACTUAL
+            =============================================================================
+            */
+            if(date == 'currentMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR TENIENDO EN CUENTA EL MES PASADO
+            =============================================================================
+            */
+            if(date == 'lastMonth'){
+                self.$el.find('.chart-container').css('display','block');
+                var date = moment().add(-1,'month').startOf('month').format('YYYY-MM-DD');
+                var hasta = moment().add(-1,'month').endOf('month').format('YYYY-MM-DD');
+                for (var i = 0; i < 32; i++) {
+                    if(i > 0){
+                        date = moment(date).add(1,'day').format('YYYY-MM-DD');
+                    }
+                    if(date > hasta){
+                        break;
+                    }
+                    var data = self.getContentByDay(date);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(moment(date).format('DD/MM/YYYY'));
+                        body.push(total);
+                    }
+                }
+                self.$el.find('.chart-container').css('display','block');
+            }
+            /*
+            =============================================================================
+                GRAFICAR SIN FILTRO
+            =============================================================================
+            */
+            if(date == 9999999 & period == 9999999){
+                _.each(AccountPeriod, function(item){
+                    var data = self.getContent(item.date_start);
+                    if(data.length > 0){
+                        var total = _.reduce(_.map(data,function(item) {
+                            return item.amount;
+                        }),function(memo, num) {
+                            return memo + num;
+                        },0);
+                        label.push(item.name);
+                        body.push(total);
+                    }
+                });
+                self.$el.find('.chart-container').css('display','block');
+            }
+
+            var chart = new reporting.ReportChartWidget(self);
+            chart.BuildLineChart(label,body,CurrencyBase);
+            self.$el.find('.report-form').css('display','block');
+            self.$el.find('.search-form').unblock();
+            self.$el.find('.report-form').unblock();
+        },
+
+        /*====================================================================
+            LOAD BOOTSTRAP TABLE
+        ====================================================================*/
+        loadTable:function(rowsTable){
+            var self = this;
+            self.rowsData = rowsTable;
+            var table = this.$el.find('#table');
+            table.bootstrapTable('load', rowsTable);
+        },
+
+        /*====================================================================
+            PRINT PDF
+        ====================================================================*/
+        clickOnAction: function (e) {
+            var self = this;
+            var ResCompany;
+            var action = this.$el.find(e.target).val();
+            var company = $('#current-company').val();
+            if(company && company != 9999999){
+                ResCompany = self.getResCompany(company).shift();
+                var CurrencyBase = self.getResCurrency(ResCompany.currency_id[0]).shift();
+            }else{
+                ResCompany = self.ResCompany[0];
+                var CurrencyBase = self.getResCurrency(self.ResCompany[0].currency_id[0]).shift();
+            }
+            var getColumns=[];
+            var rows=[];
+            var table = this.$el.find("#table");
+            var column = table.bootstrapTable('getVisibleColumns');
+            var row = table.bootstrapTable('getData');
+
+            var residual = totalResidualFormatter(row);
+            var untaxed = totalUntaxedFormatter(row);
+            var tax = totalTaxFormatter(row);
+            var total = totalFormatter(row);
+
+            row.push({
+                number : 'Totales',
+                residual_total : residual,
+                amount_untaxed_total : untaxed,
+                amount_tax_total : tax,
+                amount_total : total,
+            });
+
+            if (action === 'pdf') {
+                var data = _.map(column, function (val){ return val.field});
+                _.each(_.map(column,function(val){
+                    return val}), function(item){
+                    getColumns.push([{
+                        title: item.title,
+                        dataKey: item.field
+                    }]);
+                });
+                /*
+                ============================================================
+                    CONFIGURACION DEL PDF
+                ============================================================
+                */
+                var pdf_title = 'Notas de Débito.';
+                var pdf_type = '';
+                var pdf_name = 'notas_de_debito_';
+                var pdf_columnStyles = {
+                    number :{columnWidth: 28, halign:'center'},
+                    date_invoice :{columnWidth: 16, halign:'center'},
+                    user_id :{columnWidth: 16, halign:'left'},
+                    origin :{columnWidth: 23, halign:'left'},
+                    partner_id : {columnWidth: 19, halign:'left'},
+                    residual_total : {columnWidth: 19, halign:'right'},
+                    amount_untaxed_total : {columnWidth: 20, halign:'right'},
+                    amount_tax_total : {columnWidth: 20, halign:'right'},
+                    amount_total : {columnWidth: 19, halign:'right'},
+                };
+                /*
+                ============================================================
+                    LLAMAR FUNCION DE IMPRESION
+                ============================================================
+                */
+                var filter = self.getFilter();
+                var pdf = new reporting.ReportPdfWidget(self);
+                pdf.drawPDF(
+                    _.flatten(getColumns),
+                    row,
+                    ResCompany,
+                    pdf_title,
+                    pdf_type,
+                    pdf_name,
+                    pdf_columnStyles,
+                    filter,
+                );
+            }
+        },
+        getFilter: function(){
+          var self = this;
+          var company = self.$el.find('#current-company').val();
+          var store = self.$el.find('#current-store').val();
+          var state = self.$el.find('#current-state').val();
+          var period = self.$el.find('#current-period').val();
+          var journal = self.$el.find('#current-journal').val();
+          var date = self.$el.find('#current-date').val();
+          var desde = self.$el.find('#from').val();
+          var hasta = self.$el.find('#to').val();
+
+          var filter = [];
+
+          if(company && company != 9999999){
+            var ResCompany = _.filter(self.ResCompany, function(item){
+              return item.id == company;
+            });
+            filter.push({
+              title:'Empresa',
+              value: ResCompany[0].name,
+            });
+          }
+
+          if(store && store != 9999999){
+            var ResStore =  _.filter(self.ResStore,function (item) {
+                return item.id == store;
+            });
+
+            filter.push({
+                title: 'Sucursal',
+                value:  ResStore[0].name,
+            });
+
+          }
+          if(state && state != 9999999){
+            filter.push({
+                title: 'Estado',
+                value:  $("#current-state option:selected").text(),
+            });
+          }
+
+          if(period && period != 9999999){
+
+            var AccountPeriod =  _.filter(self.AccountPeriod,function (item) {
+                return item.id == period;
+            });
+            filter.push({
+                 title: 'Periodo',
+                 value:  AccountPeriod[0].name,
+               });
+          }
+
+          if(journal && journal != 9999999){
+            var AccountJournal =  _.filter(self.AccountJournal,function (item) {
+                return item.id == journal;
+            });
+            filter.push({
+                 title: 'Factura',
+                 value: AccountJournal[0].name,
+               });
+          }
+
+          if(date && date != 9999999){
+            moment.locale('es', {
+              months: 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
+            });
+
+            if(date == 'range'){
+              filter.push({
+                  title: 'Fecha',
+                  value:  desde +' al '+hasta,
+              });
+
+            }
+            else {
+              if(date == 'today'){
+                  var fecha = moment().format('DD/MM/YYYY');
+              }
+
+              if(date == 'yesterday'){
+                  var fecha = moment().add(-1,'days').format('DD/MM/YYYY');
+              }
+              if(date == 'currentMonth'){
+                  var fecha = moment().format('MMMM/YYYY');
+              }
+              if(date == 'lastMonth'){
+                  var fecha = moment().add(-1,'months').format('MMMM/YYYY');
+              }
+
+              filter.push({
+                  title: 'Fecha',
+                  value:  fecha,
+              });
+            }
+          }
+          return filter;
+        },
+    });
+}

+ 219 - 0
static/src/reports/report_account_payable.xml

@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportAccountPayable">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Compras a Pagar</h1>
+            </div>
+
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                  <div class="text-center" style="padding-top:20px;">
+                      <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                  </div>
+                  <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+
+                <div class="chart-container center-block" style="padding-top:10px; height:300px;width:90%;">
+                    <canvas class="reporting-chart"></canvas>
+                </div>
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-height="auto"
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-detail-view="true"
+                        data-detail-formatter="detailFormatter"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="number" data-align="center" data-footer-formatter="Totales">Factura</th>
+                                <th data-field="supplier_invoice_number" data-align="center" data-visible="false">Factura Física</th>
+                                <th data-field="date_invoice" data-align="center">Fecha</th>
+                                <th data-field="user_id" data-align="left">Responsable</th>
+                                <th data-field="partner_id" data-align="left">Proveedor</th>
+                                <th data-field="amount_total" data-align="right" data-footer-formatter="totalFormatter">Total</th>
+                                <th data-field="amortized_total" data-align="right" data-footer-formatter="totalAmortizedFormatter">Amortizado</th>
+                                <th data-field="residual_total" data-align="right" data-footer-formatter="totalResidualFormatter">A Pagar</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    DETAIL
+                -->
+                function detailFormatter(index, row) {
+                    var html = [];
+                    html.push('<div class="panel panel-third-style">');
+                    html.push('<div class="panel-heading panel-header-third-style">Cuotas</div>');
+                    html.push('<div class="panel-body">');
+                    html.push('<table class="table table-condensed table-no-bordered">');
+                    html.push('<thead style="background:none;"><tr><th>Descripción</th><th>Fecha de Vencimiento</th><th>Estado</th><th style="text-align:right;">Total</th></tr></thead>');
+                    if(row.info.length > 0){
+                        _.each(row.info,function(item) {
+                            html.push('<tr><td>' + item.name + '</td><td>' + item.date + '</td><td>' + item.state + '</td><td style="text-align:right;">' + item.amount + '</td></tr>');
+                        });
+                    }
+                    html.push('</table>');
+                    html.push('</div></div>');
+                    if(row.payments.length > 0){
+                        html.push('<div class="panel panel-second-style">');
+                        html.push('<div class="panel-heading panel-header-second-style">Pagos</div>');
+                        html.push('<div class="panel-body">');
+                        html.push('<table class="table table-condensed table-no-bordered">');
+                        html.push('<thead style="background:none;"><tr><th>Fecha</th><th>Responsable</th><th>Método de Pago</th><th style="text-align:right;">Monto</th></tr></thead>');
+                        _.each(row.payments,function(item) {
+                            html.push('<tr><td>' + item.date + '</td><td>' + item.user + '</td><td>' + item.journal_name + '</td><td style="text-align:right;">' + item.amount + '</td></tr>');
+                        });
+                        html.push('</table>');
+                        html.push('</div></div>');
+                    }
+                    return html.join('');
+                }
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    AMORTIZADO
+                -->
+                function totalAmortizedFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amortized);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    RESIDUAL TOTAL
+                -->
+                function totalResidualFormatter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.residual);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 218 - 0
static/src/reports/report_account_payable_expenses.xml

@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportAccountPayableExpenses">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Gastos a Pagar</h1>
+            </div>
+
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                  <div class="text-center" style="padding-top:20px;">
+                      <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                  </div>
+                  <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+
+                <div class="chart-container center-block" style="padding-top:10px; height:300px;width:90%;">
+                    <canvas class="reporting-chart"></canvas>
+                </div>
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-height="auto"
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-detail-view="true"
+                        data-detail-formatter="detailFormatter"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="number" data-align="center" data-footer-formatter="Totales">Factura</th>
+                                <th data-field="date_invoice" data-align="center">Fecha</th>
+                                <th data-field="user_id" data-align="left">Responsable</th>
+                                <th data-field="partner_id" data-align="left">Proveedor</th>
+                                <th data-field="amount_total" data-align="right" data-footer-formatter="totalFormatter">Total</th>
+                                <th data-field="amortized_total" data-align="right" data-footer-formatter="totalAmortizedFormatter">Amortizado</th>
+                                <th data-field="residual_total" data-align="right" data-footer-formatter="totalResidualFormatter">A Pagar</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    DETAIL
+                -->
+                function detailFormatter(index, row) {
+                    var html = [];
+                    html.push('<div class="panel panel-third-style">');
+                    html.push('<div class="panel-heading panel-header-third-style">Cuotas</div>');
+                    html.push('<div class="panel-body">');
+                    html.push('<table class="table table-condensed table-no-bordered">');
+                    html.push('<thead style="background:none;"><tr><th>Descripción</th><th>Fecha de Vencimiento</th><th>Estado</th><th style="text-align:right;">Total</th></tr></thead>');
+                    if(row.info.length > 0){
+                        _.each(row.info,function(item) {
+                            html.push('<tr><td>' + item.name + '</td><td>' + item.date + '</td><td>' + item.state + '</td><td style="text-align:right;">' + item.amount + '</td></tr>');
+                        });
+                    }
+                    html.push('</table>');
+                    html.push('</div></div>');
+                    if(row.payments.length > 0){
+                        html.push('<div class="panel panel-second-style">');
+                        html.push('<div class="panel-heading panel-header-second-style">Pagos</div>');
+                        html.push('<div class="panel-body">');
+                        html.push('<table class="table table-condensed table-no-bordered">');
+                        html.push('<thead style="background:none;"><tr><th>Fecha</th><th>Responsable</th><th>Método de Pago</th><th style="text-align:right;">Monto</th></tr></thead>');
+                        _.each(row.payments,function(item) {
+                            html.push('<tr><td>' + item.date + '</td><td>' + item.user + '</td><td>' + item.journal_name + '</td><td style="text-align:right;">' + item.amount + '</td></tr>');
+                        });
+                        html.push('</table>');
+                        html.push('</div></div>');
+                    }
+                    return html.join('');
+                }
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    AMORTIZADO
+                -->
+                function totalAmortizedFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amortized);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    RESIDUAL TOTAL
+                -->
+                function totalResidualFormatter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.residual);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 216 - 0
static/src/reports/report_account_receivable.xml

@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportAccountReceivable">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Cuentas a Cobrar</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                          Generar
+                      </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+
+                <div class="chart-container center-block" style="padding-top:10px; height:300px;width:90%;">
+                    <canvas class="reporting-chart"></canvas>
+                </div>
+                <div id="toolbar">
+                      <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-detail-view="true"
+                        data-detail-formatter="detailFormatter"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="number" data-align="center" data-footer-formatter="Totales">Factura</th>
+                                <th data-field="supplier_invoice_number" data-align="center" data-visible="false">Factura Física</th>
+                                <th data-field="date_invoice" data-align="center">Fecha</th>
+                                <th data-field="user_id" data-align="left">Responsable</th>
+                                <th data-field="partner_id" data-align="left">Cliente</th>
+                                <th data-field="amount_total" data-align="right" data-footer-formatter="totalFormatter" data-width="12%">Total</th>
+                                <th data-field="amortized_total" data-align="right" data-footer-formatter="totalAmortizedFormatter" data-width="12%">Amortizado</th>
+                                <th data-field="residual_total" data-align="right" data-footer-formatter="totalResidualFormatter" data-width="12%">Pendiente</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    DETAIL
+                -->
+                function detailFormatter(index, row) {
+                    var html = [];
+                    html.push('<div class="panel panel-third-style">');
+                    html.push('<div class="panel-heading panel-header-third-style">Cuotas</div>');
+                    html.push('<div class="panel-body">');
+                    html.push('<table class="table table-condensed table-no-bordered">');
+                    html.push('<thead style="background:none;"><tr><th>Descripción</th><th>Fecha de Vencimiento</th><th>Estado</th><th style="text-align:right;">Total</th></tr></thead>');
+                    if(row.info.length > 0){
+                        _.each(row.info,function(item) {
+                            html.push('<tr><td>' + item.name + '</td><td>' + item.date + '</td><td>' + item.state + '</td><td style="text-align:right;">' + item.amount + '</td></tr>');
+                        });
+                    }
+                    html.push('</table>');
+                    html.push('</div></div>');
+                    if(row.payments.length > 0){
+                        html.push('<div class="panel panel-second-style">');
+                        html.push('<div class="panel-heading panel-header-second-style">Pagos</div>');
+                        html.push('<div class="panel-body">');
+                        html.push('<table class="table table-condensed table-no-bordered">');
+                        html.push('<thead style="background:none;"><tr><th>Fecha</th><th>Responsable</th><th>Método de Pago</th><th style="text-align:right;">Monto</th></tr></thead>');
+                        _.each(row.payments,function(item) {
+                            html.push('<tr><td>' + item.date + '</td><td>' + item.user + '</td><td>' + item.journal_name + '</td><td style="text-align:right;">' + item.amount + '</td></tr>');
+                        });
+                        html.push('</table>');
+                        html.push('</div></div>');
+                    }
+                    return html.join('');
+                }
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    AMORTIZADO
+                -->
+                function totalAmortizedFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amortized);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    RESIDUAL TOTAL
+                -->
+                function totalResidualFormatter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.residual);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 112 - 0
static/src/reports/report_customer.xml

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportCustomer">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Clientes</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:95%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <!-- <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los Clientes</option>
+                            <option value="with">Con Saldo</option>
+                            <option value="without">Sin Saldo</option>
+                        </select>
+                    </div> -->
+                    <div class="col-lg-3 filter-style">
+                        <label>Tipo</label>
+                        <select id="current-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los tipos</option>
+                            <option value="company">Empresa</option>
+                            <option value="people">Persona</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="oe_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:95%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-hover table-condensed  table-no-bordered"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="ruc" data-align="left" data-footer-formatter="Total">RUC.</th>
+                                <th data-field="name" data-align="left">Nombre y Apellido</th>
+                                <th data-field="street" data-align="left">Dirección</th>
+                                <th data-field="city" data-align="left">Ciudad</th>
+                                <th data-field="phone" data-align="left">Teléfono</th>
+                                <th data-field="mobile" data-align="left">Celular</th>
+                                <th data-field="email" data-align="left">Email</th>
+				<th data-field="property_product_pricelist" data-align="left">Lista de precios</th>
+                                <!-- <th data-field="credit" data-align="right" data-footer-formatter="totalFormatter" data-width="12%">A Cobrar</th> -->
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+            <script>
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 181 - 0
static/src/reports/report_customer_payment.xml

@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportCustomerPayment">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Pagos de Clientes</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:95%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Método de pago</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="print-report oe_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:95%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination-v-align="top"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                              <th data-field="number"
+                                    data-align="left"
+                                    data-footer-formatter="Totales"
+                                    >Número de Pago</th>
+                              <th data-field="partner_name"
+                                    data-align="left"
+                                    >Cliente</th>
+                              <th data-field="invoice_number"
+                                    data-align="left"
+                                    >Número Fact.</th>
+                              <th data-field="name"
+                                    data-align="left"
+                                    >Recibo Nº</th>
+                              <th data-field="origin"
+                                    data-align="left"
+                                    >Origen</th>
+                              <th data-field="description"
+                                  data-align="left"
+                                  >Cuotas</th>
+                                <th data-field="date"
+                                    data-align="left"
+                                    >Fecha pago</th>
+                                <th data-field="date_maturity"
+                                    data-align="left"
+                                    >Vencimiento</th>
+                                <th data-field="journal_name"
+                                    data-align="left"
+                                    >Método de Pago</th>
+                                <th data-field="user_name"
+                                    data-align="left"
+                                    >Vendedor</th>
+                                <th data-field="amount_original"
+                                    data-align="right"
+                                    data-footer-formatter="amountOriginalFormatter"
+                                    >Monto de la cuota</th>
+                                <th data-field="total"
+                                    data-align="right"
+                                    data-footer-formatter="totalFormatter"
+                                    >Monto Pagado</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+            <script>
+                <!--
+                    TOTAL
+                -->
+                function amountOriginalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return item.amount_original_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0)
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0)
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+
+
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 178 - 0
static/src/reports/report_customer_paymentespecial.xml

@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportCustomerPaymentEspecial">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Pagos de Clientes y Devoluciones</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:95%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Método de pago</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="print-report oe_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:95%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination-v-align="top"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                              <th data-field="number"
+                                    data-align="left"
+                                    data-footer-formatter="Totales"
+                                    >Número de Pago</th>
+                              <th data-field="partner_name"
+                                    data-align="left"
+                                    >Cliente</th>
+                              <th data-field="invoice_number"
+                                    data-align="left"
+                                    >Número Fact.</th>
+                              <th data-field="origin"
+                                    data-align="left"
+                                    >Origen</th>
+                              <th data-field="description"
+                                  data-align="left"
+                                  >Cuotas</th>
+                                <th data-field="date"
+                                    data-align="left"
+                                    >Fecha de pago</th>
+                                <th data-field="date_maturity"
+                                    data-align="left"
+                                    >Vencimiento</th>
+                                <th data-field="journal_name"
+                                    data-align="left"
+                                    >Método de Pago</th>
+                                <th data-field="user_name"
+                                    data-align="left"
+                                    >Vendedor</th>
+                                <th data-field="amount_original"
+                                    data-align="right"
+                                    data-footer-formatter="amountOriginalFormatter"
+                                    >Monto cuota</th>
+                                <th data-field="total"
+                                    data-align="right"
+                                    data-footer-formatter="totalFormatter"
+                                    >Monto Pagado</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+            <script>
+                <!--
+                    TOTAL
+                -->
+                function amountOriginalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return item.amount_original_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0)
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0)
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+
+
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 178 - 0
static/src/reports/report_customer_ranking.xml

@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportCustomerRanking">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Ranking de Clientes</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:95%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 type filter-style">
+                        <label>Tipo de Venta</label>
+                        <select id="current-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los tipos</option>
+                            <option value="tpv">Terminal</option>
+                            <option value="sale">Normal</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 category filter-style">
+                        <label>Categoría</label>
+                        <select id="current-category" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 brand filter-style">
+                        <label>Marca</label>
+                        <select id="current-brand" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute filter-style">
+                        <label>Atributo</label>
+                        <select id="current-attribute" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute-value filter-style">
+                        <label>Valor del Atributo</label>
+                        <select id="current-attribute-value" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                  <div class="text-center" style="padding-top:20px;">
+                      <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                  </div>
+                  <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="myButton print-report" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:95%;">
+                    <table class="table" id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination-v-align="top"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="ruc"
+                                    data-align="left"
+                                    data-footer-formatter="Totales"
+                                    >RUC</th>
+                                <th data-field="name"
+                                    data-align="left"
+                                    >Clientes</th>
+                                <th data-field="total"
+                                    data-align="right"
+                                    data-footer-formatter="TotalFooter"
+                                    >Monto</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+            <script>
+                <!--
+                    TOTAL CANTIDAD
+                -->
+
+                function QuantityFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return item.quantity_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL MONTO
+                -->
+                function TotalFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 163 - 0
static/src/reports/report_customer_ratings.xml

@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportCustomerRatings">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Informe de Deudores</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 partner filter-style">
+                        <label>Cliente</label>
+                        <select id="current-partner" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 state filter-style">
+                        <label>Ordenar por</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                              <option value="day_of_delay">Días atrasados</option>
+                              <option value="due_qty">Cantidad de cuotas vencidas</option>
+                              <option value="amount_delay">Monto atrasado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+
+                    <div class="col-lg-3 filter-style">
+                       <label>Fecha de Vencimiento</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                  <div class="text-center" style="padding-top:20px;">
+                      <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                  </div>
+                  <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+              <div class="chart-container center-block" style="padding-top:20px; height:300px; padding-bottom:20px;">
+                  <canvas class="reporting-chart"></canvas>
+              </div>
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="center"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-detail-view="true">
+
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="partner_ruc" data-align="left" data-footer-formatter="Totales">Nº Doc.</th>
+                                <th data-field="partner_name" data-align="left">Cliente</th>
+                                <th data-field="due_qty" data-align="center" data-footer-formatter="qtyFormatter">Cuotas vencidas</th>
+                                <th data-field="max_days_of_delay" data-align="center">Días atrasados</th>
+                                <th data-field="amount" data-align="right" data-footer-formatter="amountFormatter">Monto total atrasado</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+            <script>
+
+              function qtyFormatter(rowsTable) {
+                var decimal_places = 0;
+                var thousands_separator = '.';
+                var decimal_separator = ',';
+                if (rowsTable.length > 0) {
+                  decimal_places = rowsTable[0].decimal_places;
+                  thousands_separator = rowsTable[0].thousands_separator;
+                  decimal_separator = rowsTable[0].decimal_separator;
+                }
+                var amount = _.reduce(_.map(rowsTable, function(item) {
+                  return (item.due_qty);
+                }), function(memo, num) {
+                  return memo + num;
+                }, 0)
+                return accounting.formatNumber(amount, decimal_places, thousands_separator, decimal_separator);
+              };
+
+              function amountFormatter(rowsTable) {
+                var decimal_places = 0;
+                var thousands_separator = '.';
+                var decimal_separator = ',';
+                if (rowsTable.length > 0) {
+                  decimal_places = rowsTable[0].decimal_places;
+                  thousands_separator = rowsTable[0].thousands_separator;
+                  decimal_separator = rowsTable[0].decimal_separator;
+                }
+                var amount = _.reduce(_.map(rowsTable, function(item) {
+                  return (item.amount_no_format);
+                }), function(memo, num) {
+                  return memo + num;
+                }, 0)
+                return accounting.formatNumber(amount, decimal_places, thousands_separator, decimal_separator);
+              };
+
+               <!-- FOOTER STYLE -->
+
+              function footerStyle(row, index) {
+                return {
+                  css: {
+                    "font-weight": "bold",
+                  }
+                };
+              };
+            </script>
+        </div>
+    </t>
+</template>

+ 249 - 0
static/src/reports/report_customer_refund.xml

@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportCustomerRefund">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Histórico de Notas de Crédito</h1>
+            </div>
+
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="open">Abierto</option>
+                            <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                  <div class="text-center" style="padding-top:20px;">
+                      <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                  </div>
+                  <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+
+                <div class="chart-container center-block" style="padding-top:10px; height:300px;width:90%;">
+                    <canvas class="reporting-chart"></canvas>
+                </div>
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-height="auto"
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-detail-view="true"
+                        data-detail-formatter="detailFormatter"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="number" data-align="center" data-footer-formatter="Totales">Factura</th>
+                                <th data-field="date_invoice" data-align="center">Fecha</th>
+                                <th data-field="user_id" data-align="left">Responsable</th>
+                                <th data-field="partner_id" data-align="left">Cliente</th>
+                                <th data-field="origin" data-align="left">Origen</th>
+                                <th data-field="residual_total" data-align="right" data-footer-formatter="totalResidualFormatter" data-width="12%">Saldo</th>
+                                <th data-field="amount_untaxed_total" data-align="right" data-footer-formatter="totalUntaxedFormatter" data-width="12%">SubTotal</th>
+                                <th data-field="amount_tax_total" data-align="right" data-footer-formatter="totalTaxFormatter" data-width="12%">Impuesto</th>
+                                <th data-field="amount_total"
+                                    data-align="right"
+                                    data-footer-formatter="totalFormatter"
+                                    data-width="12%"
+                                    data-sortable="true"
+                                    >Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    DETAIL
+                -->
+                function detailFormatter(index, row) {
+                    var html = [];
+                    html.push('<div class="panel panel-first-style">');
+                    html.push('<div class="panel-heading panel-header-first-style">Detalles de la Factura</div>');
+                    html.push('<div class="panel-body">');
+                    html.push('<table class="table table-condensed table-no-bordered">');
+                    html.push('<thead style="background:none;"><tr><th>Producto</th><th style="text-align:right;">Precio Unitario</th><th style="text-align:right;">Cantidad</th><th style="text-align:right;">Total</th></tr></thead>');
+                    if(row.info.length > 0){
+                        _.each(row.info,function(item) {
+                            html.push('<tr><td>' + item.product_name + '</td><td style="text-align:right;">' + item.price_unit + '</td><td style="text-align:right;">' + item.quantity + '</td><td style="text-align:right;">' + item.amount + '</td></tr>');
+                        });
+                    }
+                    html.push('</table>');
+                    html.push('</div></div>');
+                    if(row.payments.length > 0){
+                        html.push('<div class="panel panel-second-style">');
+                        html.push('<div class="panel-heading panel-header-second-style">Pagos</div>');
+                        html.push('<div class="panel-body">');
+                        html.push('<table class="table table-condensed table-no-bordered">');
+                        html.push('<thead style="background:none;"><tr><th>Fecha</th><th>Método de Pago</th><th style="text-align:right;">Monto</th></tr></thead>');
+                        _.each(row.payments,function(item) {
+                            html.push('<tr><td>' + item.date + '</td><td>' + item.journal_name + '</td><td style="text-align:right;">' + item.amount + '</td></tr>');
+                        });
+                        html.push('</table>');
+                        html.push('</div></div>');
+                    }
+                    return html.join('');
+                }
+
+                <!--
+                    RESIDUAL TOTAL
+                -->
+                function totalResidualFormatter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.residual);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    UNTAXED TOTAL
+                -->
+                function totalUntaxedFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount_untaxed);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TAX TOTAL
+                -->
+                function totalTaxFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount_tax);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 176 - 0
static/src/reports/report_daily_sale.xml

@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+  <t t-name="ReportDailySale">
+    <div class="report_view">
+      <div class="reporting_page_header">
+        <h1 class="report_title">Resumen de Ventas Diarias</h1>
+      </div>
+      <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+        <div class="row">
+          <div class="col-lg-3 company filter-style">
+            <label>Empresa</label>
+            <select id="current-company" class="form-control form-control-sm"></select>
+          </div>
+          <div class="col-lg-3 user filter-style">
+            <label>Vendedor</label>
+            <select id="current-user" class="form-control form-control-sm"></select>
+          </div>
+          <div class="col-lg-3 store filter-style">
+            <label>Sucursal</label>
+            <select id="current-store" class="form-control form-control-sm"></select>
+          </div>
+          <div class="col-lg-3 filter-style">
+            <label>Periodo</label>
+            <select id="current-period" class="form-control form-control-sm"></select>
+          </div>
+          <div class="col-lg-3 type filter-style">
+            <label>Tipo de Venta</label>
+            <select id="current-type" class="form-control form-control-sm">
+              <option value="9999999">Todos los Tipos</option>
+              <option value="tpv">Terminal</option>
+              <option value="sale">Normal</option>
+            </select>
+          </div>
+          <div class="col-lg-3 filter-style">
+            <label>Fechas</label>
+            <select id="current-date" class="form-control form-control-sm">
+              <option value="9999999">Sin fechas</option>
+              <option value="today">Hoy</option>
+              <option value="yesterday">Ayer</option>
+              <option value="currentMonth">Mes Actual</option>
+              <option value="lastMonth">Mes Pasado</option>
+              <option value="range">Busqueda Avanzada</option>
+            </select>
+          </div>
+        </div>
+        <div class="row" >
+          <div class="datepicker" style="display:none;">
+            <div class="col-lg-3 filter-style col-md-offset-3">
+              <div class="input-group">
+                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                  <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+              </div>
+            </div>
+            <div class="col-lg-3 filter-style">
+              <div class="input-group">
+                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                  <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <div class="row">
+          <div class="text-center" style="padding-top:20px;">
+            <button id="generate" class="myButton" aria-label="Left Align">
+              Generar
+          </button>
+          </div>
+          <br/>
+        </div>
+        </div>
+
+      <div class="report-form" style="display:none;">
+        <div id="toolbar">
+          <button class="oe_button myButton" value="pdf">Imprimir Informe</button>
+        </div>
+        <div class="container" style="width:90%;">
+          <table id="table"
+            data-pagination="true"
+            data-toggle="table"
+            data-toolbar="#toolbar"
+            data-show-columns="true"
+            data-classes="table table-condensed  table-no-bordered"
+            data-search="true"
+            data-show-export="true"
+            data-show-toggle="true"
+            data-pagination-detail-h-align="left"
+            data-show-footer="true"
+            data-footer-style="footerStyle"
+            data-buttons-class="oe_button myButton"
+            data-show-pagination-switch="true"
+            data-page-size="10"
+            data-search-on-enter-key="true"
+            data-undefined-text=" "
+            data-detail-view="true"
+            data-detail-formatter="detailFormatter">
+
+            <thead style="background:none;">
+              <tr>
+                <th data-field="user" data-align="left" data-footer-formatter="Totales">Vendedor</th>
+                <th data-field="qty" data-align="center" data-footer-formatter="qtyTotalFormatter">Cantidad</th>
+                <th data-field="price" data-align="right" data-footer-formatter="priceTotalFormatter">Monto Total de Venta</th>
+              </tr>
+            </thead>
+          </table>
+        </div>
+      </div>
+      <script>
+        function qtyTotalFormatter(rowsTable) {
+            var decimal_places = 0;
+            var thousands_separator = '.';
+            var decimal_separator = ',';
+            if(rowsTable.length > 0){
+                decimal_places = rowsTable[0].decimal_places;
+                thousands_separator = rowsTable[0].thousands_separator;
+                decimal_separator = rowsTable[0].decimal_separator;
+            }
+            var amount =  _.reduce(_.map(rowsTable,function(item){
+                return (item.qty_no_format);
+            }), function(memo, num){
+            return memo + num; },0)
+            return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+        }
+
+        function priceTotalFormatter(rowsTable) {
+            var decimal_places = 0;
+            var thousands_separator = '.';
+            var decimal_separator = ',';
+            if(rowsTable.length > 0){
+                decimal_places = rowsTable[0].decimal_places;
+                thousands_separator = rowsTable[0].thousands_separator;
+                decimal_separator = rowsTable[0].decimal_separator;
+            }
+            var amount =  _.reduce(_.map(rowsTable,function(item){
+                return (item.price_no_format);
+            }), function(memo, num){
+            return memo + num; },0)
+            return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+        }
+        <!-- Each Row Details -->
+        function detailFormatter(index, row) {
+          var html = [];
+          html.push('<div class="container" style="padding:30px;">');
+          html.push('<div class="panel panel-first-style">');
+          html.push('<table class="table-condensed table-no-bordered">');
+          html.push('<thead class="panel-header-first-style"><tr>');
+          html.push('<th style="padding:8px; text-align:center">Fecha</th>');
+          html.push('<th style="padding:8px; text-align:center">Sucursal</th>');
+          html.push('<th style="padding:8px; text-align:center">Cantidad</th>');
+          html.push('<th style="padding:8px; text-align:right">Monto de Venta</th>');
+          html.push('<th style="padding:8px; text-align:right">Monto Promedio de Venta</th>');
+          html.push('</tr></thead>');
+          if(row.info.length > 0){
+            _.each(row.info,function(item) {
+              html.push('<tr><td style="text-align:center">' + item.date + '</td><td style="text-align:center">' + item.store  + '</td><td style="text-align:center">' + item.qty + '</td><td style="text-align:right">' + item.price + '</td><td style="text-align:right">' + item.average + '</td></tr>');
+            });
+          }
+
+          html.push('</table>');
+          html.push('</div>');
+          html.push('</div>');
+          return html.join('');
+        }
+
+        function footerStyle(row, index) {
+            return {
+                css: {
+                  "font-weight": "bold"
+                }
+            };
+        };
+
+      </script>
+    </div>
+  </t>
+</template>

+ 181 - 0
static/src/reports/report_dues_analysis.xml

@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportDuesAnalysis">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Análisis de Cuotas</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 state filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                              <option value="expired">Vencido</option>
+                              <option value="to_receive">A cobrar</option>
+                              <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fecha de Vencimiento</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                  <div class="text-center" style="padding-top:20px;">
+                      <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                  </div>
+                  <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="center"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        >
+                        <!-- data-height="auto" -->
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="partner_ruc" data-align="left" data-footer-formatter="Totales">RUC</th>
+                                <th data-field="partner_name" data-align="left">Cliente</th>
+                                <th data-field="partner_mobile" data-align="left" data-visible="false">Celular</th>
+                                <th data-field="partner_phone" data-align="left" data-visible="false">Teléfono</th>
+                                <th data-field="invoice" data-align="left">Referencia</th>
+                                <th data-field="supplier_invoice_number" data-align="left">Fact. Fisica</th>
+                                <th data-field="origin" data-align="left">Orig.</th>
+                                <th data-field="date_invoice" data-align="center">Fecha Fact.</th>
+                                <th data-field="name" data-align="center">Cuota</th>
+                                <th data-field="date" data-align="center">Vence</th>
+                                <th data-field="date_pay" data-align="center">F.Pago</th>
+                                <th data-field="state" data-align="center">Estado</th>
+                                <th data-field="days_of_delays" data-align="center">Días atrasos</th>
+                                <th data-field="amount" data-align="right" data-footer-formatter="totalAmountFormatter" data-width="130px">Valor cuota</th>
+                                <th data-field="due_interest" data-align="right" data-width="130px">Interés</th>
+                                <th data-field="residual" data-align="right" data-footer-formatter="totalResidualFormatter" data-width="130px">Saldo cuota</th>
+                                <th data-field="invoice_total" data-align="right" data-width="130px">Total factura</th>
+                                <th data-field="invoice_residual" data-align="right" data-width="130px">Saldo cuenta</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    TOTAL
+                -->
+                function totalAmountFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount_no_format);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    RESIDUAL
+                -->
+                function totalResidualFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.residual_no_format);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 179 - 0
static/src/reports/report_duessupplier_analysis.xml

@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportDuesSupplierAnalysis">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Análisis de Cuotas Proveedor</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 state filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                              <option value="expired">Vencido</option>
+                              <option value="to_receive">A cobrar</option>
+                              <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fecha de Vencimiento</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                  <div class="text-center" style="padding-top:20px;">
+                      <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                  </div>
+                  <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="center"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        >
+                        <!-- data-height="auto" -->
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="partner_ruc" data-align="left" data-footer-formatter="Totales">RUC</th>
+                                <th data-field="partner_name" data-align="left">Proveedor</th>
+                                <th data-field="partner_mobile" data-align="left" data-visible="false">Celular</th>
+                                <th data-field="partner_phone" data-align="left" data-visible="false">Teléfono</th>
+                                <th data-field="invoice" data-align="left">Referencia</th>
+                                <th data-field="supplier_invoice_number" data-align="left">Fact. Fisica</th>
+                                <th data-field="date_invoice" data-align="center">Fecha Fact.</th>
+                                <th data-field="name" data-align="center">Cuota</th>
+                                <th data-field="date" data-align="center">Vencimiento</th>
+                                <th data-field="state" data-align="center">Estado</th>
+                                <th data-field="days_of_delays" data-align="center">Días atrasados</th>
+                                <th data-field="amount" data-align="right" data-footer-formatter="totalAmountFormatter" data-width="130px">Valor cuota</th>
+                                <th data-field="due_interest" data-align="right" data-width="130px">Interés</th>
+                                <th data-field="residual" data-align="right" data-footer-formatter="totalResidualFormatter" data-width="130px">Saldo cuota</th>
+                                <th data-field="invoice_total" data-align="right" data-width="130px">Total factura</th>
+                                <th data-field="invoice_residual" data-align="right" data-width="130px">Saldo cuenta</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    TOTAL
+                -->
+                function totalAmountFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount_no_format);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    RESIDUAL
+                -->
+                function totalResidualFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.residual_no_format);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 230 - 0
static/src/reports/report_expense.xml

@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportExpense">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Histórico de Gastos </h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="open">Abierto</option>
+                            <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 user filter-style">
+                        <label>Responsable</label>
+                        <select id="current-user" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="myButton print-report" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination-v-align="top"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="number"
+                                    data-align="left"
+                                    data-footer-formatter="Totales"
+                                    >Referencia</th>
+                                <th data-field="supplier_invoice_number"
+                                    data-align="left"
+                                    data-visible="false"
+                                    >Factura Física</th>
+                                <th data-field="date"
+                                    data-align="center"
+                                    >Fecha</th>
+                                <th data-field="user_name"
+                                    data-align="left"
+                                    >Responsable</th>
+                                <th data-field="customer_ruc"
+                                    data-align="left"
+                                    >RUC</th>
+                                <th data-field="supplier_name"
+                                    data-align="left"
+                                    >Proveedor</th>
+                                <th data-field="residual"
+                                    data-align="right"
+                                    data-footer-formatter="ResidualFooter"
+                                    data-width="150px"
+                                    >Saldo</th>
+                                <th data-field="untaxed"
+                                    data-align="right"
+                                    data-footer-formatter="UntaxedFooter"
+                                    data-width="150px"
+                                    >SubTotal</th>
+                                <th data-field="tax"
+                                    data-align="right"
+                                    data-footer-formatter="TaxFooter"
+                                    data-width="150px">Impuesto</th>
+                                <th data-field="total"
+                                    data-align="right"
+                                    data-footer-formatter="TotalFooter"
+                                    data-width="150px"
+                                    >Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+            <script>
+                <!--
+                    RESIDUAL
+                -->
+                function ResidualFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.residual_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    UNTAXED
+                -->
+                function UntaxedFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.untaxed_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TAX
+                -->
+                function TaxFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.tax_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL
+                -->
+                function TotalFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 259 - 0
static/src/reports/report_expense_analytic.xml

@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportExpenseAnalytic">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Análisis de Gastos</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Categoria</label>
+                        <select id="current-category" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 brand filter-style">
+                        <label>Marca</label>
+                        <select id="current-brand" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute filter-style">
+                        <label>Atributo</label>
+                        <select id="current-attribute" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute-value filter-style">
+                        <label>Valor del Atributo</label>
+                        <select id="current-attribute-value" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                          Generar
+                      </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="myButton print-report" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-hover table-condensed"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination-v-align="top"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="number"
+                                    data-align="center"
+                                    data-footer-formatter="Totales"
+                                    >Referencia</th>
+                                <th data-field="supplier_invoice_number"
+                                    data-align="left"
+                                    data-visible="false"
+                                    >Factura Física</th>
+                                <th data-field="date"
+                                    data-align="center"
+                                    >Fecha</th>
+                                <th data-field="ruc"
+                                    data-align="left"
+                                    data-visible="false"
+                                    >CIN/RUC</th>
+                                <th data-field="supplier_name"
+                                    data-align="left"
+                                    >Proveedor</th>
+                                <th data-field="product_name"
+                                    data-align="left"
+                                    >Producto</th>
+                                <th data-field="product_category"
+                                    data-align="left"
+                                    >Categoria</th>
+                                <th data-field="price_unit"
+                                    data-align="right"
+                                    data-footer-formatter="PriceUnitFooter"
+                                    data-width="200px"
+                                    >Precio</th>
+                                <th data-field="quantity"
+                                    data-align="center"
+                                    data-footer-formatter="QuantityFooter"
+                                    data-width="100px"
+                                    >Cantidad</th>
+                                <th data-field="untaxed"
+                                    data-align="right"
+                                    data-footer-formatter="UntaxedFooter"
+                                    data-width="200px"
+                                    >SubTotal</th>
+                                <th data-field="tax"
+                                    data-align="right"
+                                    data-footer-formatter="TaxFooter"
+                                    data-width="200px"
+                                    >Impuesto</th>
+                                <th data-field="total"
+                                    data-align="right"
+                                    data-footer-formatter="TotalFooter"
+                                    data-width="200px"
+                                    >Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+            <script>
+                <!--
+                    PRICE UNIT
+                -->
+                function PriceUnitFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.price_unit_no_fortmat;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    QUANTITY
+                -->
+                function QuantityFooter(rowsTable) {
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.quantity_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,2,'.',',');
+                }
+                <!--
+                    UNTAXED
+                -->
+                function UntaxedFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.untaxed_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TAX
+                -->
+                function TaxFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.tax_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL
+                -->
+                function TotalFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 143 - 0
static/src/reports/report_income_summary.xml

@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportIncomeSummary">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Resumen de Ingresos</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:95%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                      <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div class="chart-container center-block" style="padding-top:20px; height:300px; padding-bottom:20px;">
+                    <canvas class="reporting-chart"></canvas>
+                </div>
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:95%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-height="auto"
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        >
+                        <thead style="background:none;">
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+            <script>
+                function detailFormatter(index, row) {
+                    var html = [];
+                    html.push('<div class="panel panel-first-style">');
+                    html.push('<div class="panel-heading panel-header-first-style">Detalles</div>');
+                    html.push('<div class="panel-body">');
+                    html.push('<table class="table table-condensed table-no-bordered">');
+                    html.push('<thead style="background:none;"><tr><th>Metodo de Pago</th><th style="text-align:right;">Monto</th></tr></thead>');
+                    if(row.info.length > 0){
+                        _.each(row.info,function(item) {
+                            html.push('<tr><td class="col-md-6">' + item.journal + '</td><td style="text-align:right;">' + item.amount_total + '</td></tr>');
+                        });
+                    }
+                    html.push('</table>');
+                    html.push('</div></div>');
+                    return html.join('');
+                }
+
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 144 - 0
static/src/reports/report_outcome_summary.xml

@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportOutcomeSummary">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Resumen de Egresos</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:95%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                      <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div class="chart-container center-block" style="padding-top:20px; height:300px; padding-bottom:20px;">
+                    <canvas class="reporting-chart"></canvas>
+                </div>
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:95%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        >
+                        <thead style="background:none;">
+                        </thead>
+                    </table>
+
+                </div>
+            </div>
+
+            <script>
+
+                function detailFormatter(index, row) {
+                    var html = [];
+                    html.push('<div class="panel panel-first-style">');
+                    html.push('<div class="panel-heading panel-header-first-style">Detalles</div>');
+                    html.push('<div class="panel-body">');
+                    html.push('<table class="table table-condensed table-no-bordered">');
+                    html.push('<thead style="background:none;"><tr><th>Metodo de Pago</th><th style="text-align:right;">Monto</th></tr></thead>');
+                    if(row.info.length > 0){
+                        _.each(row.info,function(item) {
+                            html.push('<tr><td class="col-md-6">' + item.journal + '</td><td style="text-align:right;">' + item.amount_total + '</td></tr>');
+                        });
+                    }
+                    html.push('</table>');
+                    html.push('</div></div>');
+                    return html.join('');
+                }
+
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount_no_format);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 191 - 0
static/src/reports/report_product_list.xml

@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportProductList">
+      <head>
+        <script src="//cdnjs.cloudflare.com/ajax/libs/holder/2.6.0/holder.js"></script>
+      </head>
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Lista de Productos</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:95%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="available">Disponible</option>
+                            <option value="unavailable">No Disponible</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Tipo</label>
+                        <select id="current-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los tipos</option>
+                            <option value="product">Almacenable</option>
+                            <option value="service">Servicio</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 salePrice filter-style">
+                        <label>Precio de Venta</label>
+                        <select id="current-sale-price" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 purchasePrice filter-style">
+                        <label>Precio de Costo </label>
+                        <select id="current-purchase-price" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Categoria</label>
+                        <select id="current-category" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 brand filter-style">
+                        <label>Marca</label>
+                        <select id="current-brand" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute filter-style">
+                        <label>Atributo</label>
+                        <select id="current-attribute" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute-value filter-style">
+                        <label>Valor del Atributo</label>
+                        <select id="current-attribute-value" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="oe_button oe_form_button myButton">Generar</button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:95%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-height="auto"
+                        data-classes="table table-hover table-condensed  table-no-bordered"
+                        data-row-style="rowStyle"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                               <th data-field="image_medium" data-formatter="imageFormatter" data-footer-formatter="Totales">Imagen</th>
+                                <th data-field="default_code" data-align="left" >Referencia Interna</th>
+                                <th data-field="name" data-align="left">Producto</th>
+                                <th data-field="brand" data-align="left">Marca</th>
+                                <th data-field="categ_id" data-align="left">Categoría</th>
+                                <th data-field="standard_price" data-align="right" data-footer-formatter="purchaseTotalFormatter">Precio Costo</th>
+                                <th data-field="lst_price" data-align="right" data-footer-formatter="saleTotalFormatter">Precio Venta </th>
+                                <th data-field="qty_available" data-align="center" data-footer-formatter="qtyTotalFormatter">Cantidad Disponible</th>
+                                <!-- <th data-field="minimo_quantity" data-align="center">Stock Minimo</th> -->
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+            <script>
+
+              function imageFormatter(value) {
+              return '<img style="width:60px; height:60px" src="'+ value +'"></img>';
+
+              }
+                <!--
+                    TOTAL
+                -->
+                function purchaseTotalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    var symbol;
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places_purchase;
+                        thousands_separator = rowsTable[0].thousands_separator_purchase;
+                        decimal_separator = rowsTable[0].decimal_separator_purchase;
+                        symbol=rowsTable[0].symbol_purchase;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.standard_price_no_format);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatMoney(amount,symbol,decimal_places,thousands_separator,decimal_separator,'%s %v');
+                }
+
+                function saleTotalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    var symbol;
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places_sale;
+                        thousands_separator = rowsTable[0].thousands_separator_sale;
+                        decimal_separator = rowsTable[0].decimal_separator_sale;
+                        symbol = rowsTable[0].symbol_sale;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.lst_price_no_formart);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatMoney(amount,symbol,decimal_places,thousands_separator,decimal_separator,'%s %v');
+                }
+
+                function qtyTotalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.qty_no_formart);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(amount,'',thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 150 - 0
static/src/reports/report_profit_and_loss.xml

@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportProfitAndLoss">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title">Pérdidas y Ganancias</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:95%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <!-- <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div> -->
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                          Generar
+                      </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <!-- <div class="chart-container center-block" style="padding-top:20px; height:300px; padding-bottom:20px;">
+                    <canvas class="reporting-chart"></canvas>
+                </div> -->
+                <div id="toolbar">
+                    <button class="oe_button oe_form_button oe_highlight myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:95%;">
+                     <!-- table-no-bordered -->
+                    <table id="table"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-classes="table table-condensed"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button oe_form_button oe_highlight myButton"
+                        data-undefined-text=" "
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="description" data-align="left" data-footer-formatter="Resultado" data-formatter="desciptionFormatter">Descripción</th>
+                                <th data-field="store" data-align="left" data-formatter="nameFormatter"></th>
+                                <th data-field="amount_total" data-align="right" data-footer-formatter="totalFormatter" data-formatter="nameFormatter">Valor</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+            <script>
+
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var amount =  _.reduce(_.map(rowsTable,function(item){
+                        if(item.footer_amount != undefined){
+                            return item.footer_amount
+                        }else{
+                            return 0
+                        }
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(amount,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+                <!--
+                    COLUMN STYLES
+                -->
+                function desciptionFormatter(value, row) {
+                    if(value != undefined){
+                        if(row.expense == true){
+                            return '<div style="font-weight:bold;">' + value + '</div>';
+                        }else{
+                            return '<div style="font-weight:bold;">' + value + '</div>';
+                        };
+                    };
+                };
+                function nameFormatter(value, row) {
+                    if(value != undefined){
+                        if(row.check == true || row.profit == true){
+                            return '<div style="font-weight:bold;color:#0288d1;">' + value + '</div>';
+                        };
+                        return value;
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 234 - 0
static/src/reports/report_purchase.xml

@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportPurchase">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Histórico de Compras </h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="open">Abierto</option>
+                            <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 user filter-style">
+                        <label>Responsable</label>
+                        <select id="current-user" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                          Generar
+                      </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="myButton print-report" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-pagination-v-align="top"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="supplier_invoice_number"
+                                    data-align="left"
+                                    data-footer-formatter="Totales"
+                                    >Factura</th>
+                                <th data-field="number"
+                                    data-align="left"
+                                    >Referencia</th>
+                                <th data-field="date"
+                                    data-align="center"
+                                    >Fecha</th>
+                                <th data-field="user_name"
+                                    data-align="left"
+                                    >Responsable</th>
+                                <th data-field="customer_ruc"
+                                    data-align="left"
+                                    >RUC</th>
+                                <th data-field="partner_name"
+                                    data-align="left"
+                                    >Proveedor</th>
+                                <th data-field="residual"
+                                    data-align="right"
+                                    data-footer-formatter="ResidualFooter"
+                                    data-width="12%"
+                                    >Saldo</th>
+                                <th data-field="untaxed"
+                                    data-align="right"
+                                    data-footer-formatter="UntaxedFooter"
+                                    data-width="12%"
+                                    >SubTotal</th>
+                                <th data-field="tax"
+                                    data-align="right"
+                                    data-footer-formatter="TaxFooter"
+                                    data-width="12%"
+                                    >Impuesto</th>
+                                <th data-field="total"
+                                    data-align="right"
+                                    data-footer-formatter="TotalFooter"
+                                    data-width="12%"
+                                    >Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    RESIDUAL
+                -->
+                function ResidualFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.residual_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    UNTAXED
+                -->
+                function UntaxedFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.untaxed_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TAX
+                -->
+                function TaxFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.tax_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL
+                -->
+                function TotalFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                            "font-weight": "bold",
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 260 - 0
static/src/reports/report_purchase_analytic.xml

@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportPurchaseAnalytic">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Análisis de Compras</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Categoria</label>
+                        <select id="current-category" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 brand filter-style">
+                        <label>Marca</label>
+                        <select id="current-brand" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute filter-style">
+                        <label>Atributo</label>
+                        <select id="current-attribute" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute-value filter-style">
+                        <label>Valor del Atributo</label>
+                        <select id="current-attribute-value" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                          Generar
+                      </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="myButton print-report" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination-v-align="top"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="number"
+                                    data-align="center"
+                                    data-footer-formatter="Totales"
+                                    >Referencia</th>
+                                <th data-field="supplier_invoice_number"
+                                    data-align="left"
+                                    data-visible="false"
+                                    >Factura Física</th>
+                                <th data-field="date"
+                                    data-align="center"
+                                    >Fecha</th>
+                                <th data-field="supplier_name"
+                                    data-align="left"
+                                    >Proveedor</th>
+                                <th data-field="ruc"
+                                    data-align="left"
+                                    data-visible="false"
+                                    >CIN/RUC</th>
+                                <th data-field="product_name"
+                                    >Producto</th>
+                                <th data-field="product_category"
+                                    data-align="left"
+                                    data-width="250px"
+                                    >Categoria</th>
+                                <th data-field="price_unit"
+                                    data-align="right"
+                                    data-footer-formatter="PriceUnitFooter"
+                                    data-width="200px"
+                                    >Precio</th>
+                                <th data-field="quantity"
+                                    data-align="right"
+                                    data-footer-formatter="QuantityFooter"
+                                    data-width="50px"
+                                    >Cantidad</th>
+                                <th data-field="untaxed"
+                                    data-align="right"
+                                    data-footer-formatter="UntaxedFooter"
+                                    data-width="200px"
+                                    >SubTotal</th>
+                                <th data-field="tax"
+                                    data-align="right"
+                                    data-footer-formatter="TaxFooter"
+                                    data-width="200px"
+                                    >Impuesto</th>
+                                <th data-field="total"
+                                    data-align="right"
+                                    data-footer-formatter="TotalFooter"
+                                    data-width="200px"
+                                    >Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    PRICE UNIT
+                -->
+                function PriceUnitFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.price_unit_no_fortmat;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    QUANTITY
+                -->
+                function QuantityFooter(rowsTable) {
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.quantity_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0)
+                    return accounting.formatNumber(total,2,'.',',');
+                }
+                <!--
+                    UNTAXED
+                -->
+                function UntaxedFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.untaxed_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TAX
+                -->
+                function TaxFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.tax_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL
+                -->
+                function TotalFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 257 - 0
static/src/reports/report_purchase_journal.xml

@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportPurchaseJournal">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Libro de Compras</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="open">Abierto</option>
+                            <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Orientacion de impresión</label>
+                        <select id="current-pdf-type" class="form-control form-control-sm">
+                            <option value="0">Vertical</option>
+                            <option value="1">Horizontal</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="oe_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-classes="table table-hover table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination="true"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-pagination-detail-h-align="left"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th colspan="3" data-align="center">DOCUMENTO</th>
+                                <th colspan="2" data-align="center">PROVEEDORES</th>
+                                <th colspan="8" data-align="center">TOTAL COMPRAS</th>
+                            </tr>
+                            <tr>
+                                <th data-field="number" data-align="center" data-footer-formatter="Items:">Num.</th>
+                                <th data-field="supplier_invoice_number" data-align="center" data-footer-formatter="itemsCount">N° Fact.</th>
+                                <th data-field="date_invoice" data-align="center">Fecha</th>
+                                <th data-field="partner_id" data-align="left" data-width="15%" data-footer-formatter="TOTALES:">Razón Social</th>
+                                <th data-field="partner_ruc" data-align="left" data-width="10%">RUC</th>
+                                <th data-field="gravada_total" data-align="right" data-width="12%" data-footer-formatter="totalGravadas">Gravadas</th>
+                                <th data-field="percetage_total" data-align="right">%</th>
+                                <th data-field="tax_total" data-align="right" data-footer-formatter="totalTax" data-width="11%">Impuestos</th>
+                                <th data-field="exenta_total" data-align="right" data-footer-formatter="totalExentas" data-width="11%">Exentas</th>
+                                <th data-field="ret_iva_total" data-align="right" data-footer-formatter="totalRetIVA" data-width="9%">Ret. IVA</th>
+                                <th data-field="ret_renta_total" data-align="right" data-footer-formatter="totalRetRenta" data-width="9%">Ret. Renta</th>
+                                <th data-field="amount_total" data-align="right" data-footer-formatter="totalFormatter" data-width="12%">Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    ITEMS COUNT
+                -->
+                function itemsCount(rowsTable) {
+                    return rowsTable.length;
+                }
+
+                <!--
+                    GRAVADAS
+                -->
+                function totalGravadas(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.gravada);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    IMPUESTOS
+                -->
+                function totalTax(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.tax);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    EXENTAS
+                -->
+                function totalExentas(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.exenta);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    RET IVA
+                -->
+                function totalRetIVA(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.ret_iva);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    RET RENTA
+                -->
+                function totalRetRenta(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.ret_renta);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 327 - 0
static/src/reports/report_purchase_journal_detallado.xml

@@ -0,0 +1,327 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportPurchaseJournalDetallado">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Libro de Compras</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="open">Abierto</option>
+                            <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Orientacion de impresión</label>
+                        <select id="current-pdf-type" class="form-control form-control-sm">
+                            <option value="0">Vertical</option>
+                            <option value="1">Horizontal</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="oe_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-classes="table table-hover table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination="true"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-pagination-detail-h-align="left"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th colspan="3" data-align="center">DOCUMENTO</th>
+                                <th colspan="2" data-align="center">PROVEEDORES</th>
+                                <th colspan="8" data-align="center">TOTAL COMPRAS</th>
+                            </tr>
+                            <tr>
+                                <th data-field="number" data-align="center" data-footer-formatter="Items:">Num.</th>
+                                <th data-field="supplier_invoice_number" data-align="center" data-footer-formatter="itemsCount">N° Fact.</th>
+                                <th data-field="date_invoice" data-align="center">Fecha</th>
+                                <th data-field="partner_id" data-align="left" data-width="15%" data-footer-formatter="TOTALES:">Razón Social</th>
+                                <th data-field="partner_ruc" data-align="left" data-width="10%">RUC</th>
+                                <th data-field="tasa_5" data-align="right" data-width="10%"
+                                data-footer-formatter="totalTasa5">Monto compra c/ Tasa 5%</th>
+                                <th data-field="iva_5" data-align="right" data-width="10%"
+                                data-footer-formatter="totalIva5">IVA Crédito 5%</th>
+                                <th data-field="tasa_10" data-align="right" data-width="10%"
+                                data-footer-formatter="totalTasa10">Monto compra c/ Tasa 10%</th>
+                                <th data-field="iva_10" data-align="right" data-width="10%"
+                                data-footer-formatter="totalIva10">IVA Crédito 10%</th>
+                                <th data-field="amount_untaxed" data-align="right" data-width="10%"
+                                data-footer-formatter="totalUntaxed">Monto Compra no Gravada o Exenta</th>
+                                <th data-field="percetage_total" data-align="right">%</th>
+                                <th data-field="tax_total" data-align="right" data-footer-formatter="totalTax" data-width="11%">Impuestos</th>
+                             <!--    <th data-field="exenta_total" data-align="right" data-footer-formatter="totalExentas" data-width="11%">Exentas</th> -->
+                                 <th data-field="ret_iva_total" data-align="right" data-footer-formatter="totalRetIVA" data-width="9%">Ret. IVA</th>
+                                <th data-field="ret_renta_total" data-align="right" data-footer-formatter="totalRetRenta" data-width="9%">Ret. Renta</th>
+                                <th data-field="amount_total" data-align="right" data-footer-formatter="totalFormatter" data-width="12%">Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    ITEMS COUNT
+                -->
+                function itemsCount(rowsTable) {
+                    return rowsTable.length;
+                }
+
+
+                <!--
+                    TOTAL IVA 5
+                -->
+                function totalIva5(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sfiva_5);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    TOTAL TASA 10
+                -->
+                function totalTasa10(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sftasa_10);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    TOTAL IVA 10
+                -->
+                function totalIva10(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sfiva_10);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    TOTAL TASA 5
+                -->
+                function totalTasa5(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sftasa_5);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+
+                <!--
+                    EXENTAS
+                -->
+                 function totalUntaxed(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sfamount_untaxed);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+
+                 <!--
+                    IMPUESTOS
+                -->
+                  function totalTax(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.tax);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    RET IVA
+                -->
+<!--                 function totalRetIVA(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.ret_iva);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                } -->
+                <!--
+                    RET RENTA
+                -->
+  <!--               function totalRetRenta(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.ret_renta);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                } -->
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 261 - 0
static/src/reports/report_sale.xml

@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportSale">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Histórico de Ventas </h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="open">Abierto</option>
+                            <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 invoice-type filter-style">
+                        <label>Tipo de Factura</label>
+                        <select id="current-invoice-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los tipos</option>
+                            <option value="credit">Crédito</option>
+                            <option value="cash">Contado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 user filter-style">
+                        <label>Vendedor</label>
+                        <select id="current-user" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 type filter-style">
+                        <label>Tipo de Venta</label>
+                        <select id="current-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los Tipos</option>
+                            <option value="tpv">Terminal</option>
+                            <option value="sale">Normal</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="myButton print-report" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination-v-align="top"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="number"
+                                    data-align="left"
+                                    data-footer-formatter="Totales"
+                                    data-width="160"
+                                    >Factura</th>
+                                <th data-field="supplier_invoice_number"
+                                    data-align="left"
+                                    data-visible="false"
+                                    >Factura Física</th>
+                                <th data-field="origin"
+                                    data-align="center"
+                                    data-visible="false"
+                                    >Origen</th>
+                                <th data-field="date"
+                                    data-align="center"
+                                    data-width="160"
+                                    >Fecha</th>
+                                <th data-field="user_name"
+                                    data-align="left"
+                                    >Vendedor</th>
+                                <th data-field="customer_ruc"
+                                    data-align="left"
+                                    >RUC</th>
+                                <th data-field="customer_name"
+                                    data-align="left"
+                                    data-width="220"
+                                    >Cliente</th>
+                                <th data-field="residual"
+                                    data-align="right"
+                                    data-footer-formatter="ResidualFooter"
+                                    data-width="180"
+                                    >Saldo</th>
+                                <th data-field="untaxed"
+                                    data-align="right"
+                                    data-footer-formatter="UntaxedFooter"
+                                    data-width="180"
+                                    >SubTotal</th>
+                                <th data-field="tax"
+                                    data-align="right"
+                                    data-footer-formatter="TaxFooter"
+                                    data-width="130"
+                                    >Impuesto</th>
+                                <th data-field="total"
+                                    data-align="right"
+                                    data-footer-formatter="TotalFooter"
+                                    data-width="180"
+                                    >Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+            <script>
+                <!--
+                    RESIDUAL
+                -->
+                function ResidualFooter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.residual_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    UNTAXED
+                -->
+                function UntaxedFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.untaxed_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TAX
+                -->
+                function TaxFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.tax_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL
+                -->
+                function TotalFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 300 - 0
static/src/reports/report_sale_analytic.xml

@@ -0,0 +1,300 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportSaleAnalytic">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Análisis de Ventas</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:95%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 type filter-style">
+                        <label>Tipo de Venta</label>
+                        <select id="current-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los Tipos</option>
+                            <option value="tpv">Terminal</option>
+                            <option value="sale">Normal</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Categoria</label>
+                        <select id="current-category" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 brand filter-style">
+                        <label>Marca</label>
+                        <select id="current-brand" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute filter-style">
+                        <label>Atributo</label>
+                        <select id="current-attribute" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 attribute-value filter-style">
+                        <label>Valor del Atributo</label>
+                        <select id="current-attribute-value" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Fechas</label>
+                        <select id="current-date" class="form-control form-control-sm">
+                            <option value="9999999">Sin fechas</option>
+                            <option value="today">Hoy</option>
+                            <option value="yesterday">Ayer</option>
+                            <option value="currentMonth">Mes Actual</option>
+                            <option value="lastMonth">Mes Pasado</option>
+                            <option value="range">Busqueda Avanzada</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="myButton print-report" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:95%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-pagination-v-align="top"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="number"
+                                    data-align="center"
+                                    data-footer-formatter="Totales"
+                                    >Factura</th>
+                                <th data-field="date"
+                                    data-align="center"
+                                    >Fecha</th>
+                                <th data-field="ruc"
+                                    data-align="left"
+                                    >Cliente</th>
+                                <th data-field="customer_name"
+                                    data-align="left"
+                                    >CIN/RUC</th>
+                                <th data-field="product_name"
+                                    data-align="left"
+                                    data-width="200px"
+                                    >Producto</th>
+                                <th data-field="product_category"
+                                    data-align="left"
+                                    data-width="200px"
+                                    >Categoria</th>
+                                <th data-field="price_unit"
+                                    data-align="right"
+                                    data-footer-formatter="PriceUnitFooter"
+                                    data-width="150"
+                                    >Precio Unitario</th>
+                                <th data-field="quantity"
+                                    data-align="right"
+                                    data-footer-formatter="QuantityFooter"
+                                    data-width="100px"
+                                    >Cantidad</th>
+                                <th data-field="discount"
+                                    data-align="center"
+                                    data-visible="false"
+                                    >Descuento (%)</th>
+                                <th data-field="discount_amount"
+                                    data-align="right"
+                                    data-visible="false"
+                                    data-footer-formatter="DiscountFooter"
+                                    data-width="150"
+                                    >Descuento (Monto)</th>
+                                <th data-field="untaxed"
+                                    data-align="right"
+                                    data-footer-formatter="UntaxedFooter"
+                                    data-width="150"
+                                    >SubTotal</th>
+                                <th data-field="tax"
+                                    data-align="right"
+                                    data-footer-formatter="TaxFooter"
+                                    data-width="150"
+                                    >Impuesto</th>
+                                <th data-field="total"
+                                    data-align="right"
+                                    data-footer-formatter="TotalFooter"
+                                    data-width="150"
+                                    >Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+
+                <!--
+                    PRICE UNIT
+                -->
+                function PriceUnitFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.price_unit_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    QUANTITY
+                -->
+                function QuantityFooter(rowsTable) {
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.quantity_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,2,'.',',');
+                }
+                <!--
+                    DISCOUNT AMOUNT
+                -->
+                function DiscountFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.discount_amount_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    SUBTOTAL
+                -->
+                function UntaxedFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.untaxed_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TAX
+                -->
+                function TaxFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.tax_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL
+                -->
+                function TotalFooter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return item.total_no_format;
+                    }), function(memo, num){
+                        return memo + num;
+                    },0);
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+            </script>
+        </div>
+    </t>
+</template>

+ 237 - 0
static/src/reports/report_sale_gross.xml

@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportSaleGross">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Utilidad de Ventas </h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 type filter-style">
+                        <label>Tipo de Venta</label>
+                        <select id="current-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los Tipos</option>
+                            <option value="tpv">Terminal</option>
+                            <option value="sale">Normal</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="today">Hoy</option>
+                           <option value="yesterday">Ayer</option>
+                           <option value="currentMonth">Mes Actual</option>
+                           <option value="lastMonth">Mes Pasado</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+            <div class="report-form" style="display:none;">
+                <div class="chart-container center-block" style="height:300px;width:90%;">
+                    <canvas class="reporting-chart"></canvas>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-pagination="true"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-show-columns="true"
+                        data-classes="table table-condensed  table-no-bordered"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-pagination-detail-h-align="left"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-detail-view="true"
+                        data-detail-formatter="detailFormatter"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th data-field="name" data-align="center" data-footer-formatter="Totales">Nombre</th>
+                                <th data-field="subtotal_amount" data-align="right" data-footer-formatter="subtotalFormatter">Subtotal</th>
+                                <th data-field="tax_amount" data-align="right" data-footer-formatter="taxFormatter">Impuestos</th>
+                                <th data-field="cost_amount" data-align="right" data-footer-formatter="costFormatter">Coste</th>
+                                <th data-field="margin" data-align="center">Margen</th>
+                                <th data-field="total_amount" data-align="right" data-footer-formatter="totalFormatter">Total</th>
+                                <th data-field="profit_amount" data-align="right" data-footer-formatter="profitFormatter">Beneficio</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+            <script>
+
+                <!--
+                    DETAIL
+                -->
+                function detailFormatter(index, row) {
+                    var html = [];
+                    html.push('<div class="panel panel-first-style">');
+                    html.push('<div class="panel-heading panel-header-first-style">Detalles</div>');
+                    html.push('<div class="panel-body">');
+                    html.push('<table class="table table-condensed table-no-bordered">');
+                    html.push('<thead style="background:none;"><tr><th>Periodo</th><th style="text-align:right;">Sub-Total</th><th style="text-align:right;">Impuesto</th><th style="text-align:right;">Coste</th><th style="text-align:center;">Margen</th><th style="text-align:right;">Total</th><th style="text-align:right;">Beneficio</th></tr></thead>');
+                    if(row.info.length > 0){
+                        _.each(row.info,function(item) {
+                            html.push('<tr><td>' + item.period + '</td><td style="text-align:right;">' + item.subtotal + '</td><td style="text-align:right;">' + item.tax + '</td><td style="text-align:right;">' + item.cost + '</td><td style="text-align:center;">' + item.margin + '</td><td style="text-align:right;">' + item.total + '</td><td style="text-align:right;">' + item.profit + '</td></tr>');
+                        });
+                    }
+                    html.push('</table>');
+                    html.push('</div></div>');
+                    return html.join('');
+                }
+
+                <!-- Footer Subtotal -->
+                function subtotalFormatter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.subtotal);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!-- Footer tax -->
+                function taxFormatter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.tax);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!-- Footer cost -->
+                function costFormatter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.cost);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!-- Footer total -->
+                function totalFormatter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.total);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!-- Footer Profit -->
+                function profitFormatter(rowsTable) {
+                    var self = this;
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.profit);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!-- Footer Style -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 265 - 0
static/src/reports/report_sale_journal.xml

@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportSaleJournal">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Libro de Ventas</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="open">Abierto</option>
+                            <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 type filter-style">
+                        <label>Tipo de Venta</label>
+                        <select id="current-type" class="form-control form-control-sm">
+                            <option value="9999999">Todos los Tipos</option>
+                            <option value="tpv">Terminal</option>
+                            <option value="sale">Normal</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Orientacion de impresión</label>
+                        <select id="current-pdf-type" class="form-control form-control-sm">
+                            <option value="0">Vertical</option>
+                            <option value="1">Horizontal</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="oe_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-classes="table table-hover table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination="true"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-pagination-detail-h-align="left"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th colspan="3" data-align="center">DOCUMENTO</th>
+                                <th colspan="2" data-align="center">CLIENTES</th>
+                                <th colspan="8" data-align="center">TOTAL VENTAS</th>
+                            </tr>
+                            <tr>
+                                <th data-field="number" data-align="center" data-footer-formatter="Items:">Num.</th>
+                                <th data-field="supplier_invoice_number" data-align="center" data-footer-formatter="itemsCount">N° Fact.</th>
+                                <th data-field="date_invoice" data-align="center">Fecha</th>
+                                <th data-field="partner_id" data-align="left" data-width="15%" data-footer-formatter="TOTALES:">Razón Social</th>
+                                <th data-field="partner_ruc" data-align="left" data-width="10%">RUC</th>
+                                <th data-field="gravada_total" data-align="right" data-width="12%" data-footer-formatter="totalGravadas">Gravadas</th>
+                                <th data-field="percetage_total" data-align="right">%</th>
+                                <th data-field="tax_total" data-align="right" data-footer-formatter="totalTax" data-width="11%">Impuestos</th>
+                                <th data-field="exenta_total" data-align="right" data-footer-formatter="totalExentas" data-width="11%">Exentas</th>
+                                <th data-field="ret_iva_total" data-align="right" data-footer-formatter="totalRetIVA" data-width="9%">Ret. IVA</th>
+                                <th data-field="ret_renta_total" data-align="right" data-footer-formatter="totalRetRenta" data-width="9%">Ret. Renta</th>
+                                <th data-field="amount_total" data-align="right" data-footer-formatter="totalFormatter" data-width="12%">Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    ITEMS COUNT
+                -->
+                function itemsCount(rowsTable) {
+                    return rowsTable.length;
+                }
+
+                <!--
+                    GRAVADAS
+                -->
+                function totalGravadas(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.gravada);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    IMPUESTOS
+                -->
+                function totalTax(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.tax);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    EXCENTAS
+                -->
+                function totalExentas(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.exenta);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    RET IVA
+                -->
+                function totalRetIVA(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.ret_iva);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    RET RENTA
+                -->
+                function totalRetRenta(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.ret_renta);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

+ 326 - 0
static/src/reports/report_sale_journal_detallado.xml

@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="ReportSaleJournalDetallado">
+        <div class="report_view">
+            <div class="reporting_page_header">
+                <h1 class="report_title"> Libro de Ventas</h1>
+            </div>
+            <div class="container search-form" style="border-bottom:1px solid #eee; width:90%;">
+                <div class="row">
+                    <div class="col-lg-3 company filter-style">
+                        <label>Empresa</label>
+                        <select id="current-company" class="form-control form-control-sm"></select>
+                    </div>
+                    <div class="col-lg-3 store filter-style">
+                        <label>Sucursal</label>
+                        <select id="current-store" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Estado</label>
+                        <select id="current-state" class="form-control form-control-sm">
+                            <option value="9999999">Todos los estados</option>
+                            <option value="open">Abierto</option>
+                            <option value="paid">Pagado</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Periodo</label>
+                        <select id="current-period" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 journal filter-style">
+                        <label>Factura</label>
+                        <select id="current-journal" class="form-control form-control-sm">
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                        <label>Orientacion de impresión</label>
+                        <select id="current-pdf-type" class="form-control form-control-sm">
+                            <option value="0">Vertical</option>
+                            <option value="1">Horizontal</option>
+                        </select>
+                    </div>
+                    <div class="col-lg-3 filter-style">
+                       <label>Fechas</label>
+                       <select id="current-date" class="form-control form-control-sm">
+                           <option value="9999999">Sin fechas</option>
+                           <option value="range">Busqueda Avanzada</option>
+                       </select>
+                   </div>
+                </div>
+                <div class="row" >
+                    <div class="datepicker" style="display:none;">
+                        <div class="col-lg-3 filter-style col-md-offset-3">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Desde</span>
+                                <input type="text" id="from" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 filter-style">
+                            <div class="input-group">
+                                <span class="input-group-addon" id="basic-addon1">Hasta</span>
+                                <input type="text" id="to" class="form-control" aria-describedby="basic-addon1"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <div class="text-center" style="padding-top:20px;">
+                        <button id="generate" class="myButton" aria-label="Left Align" style="color:#fff;display:none;">
+                            Generar
+                        </button>
+                    </div>
+                    <br/>
+                </div>
+            </div>
+
+            <div class="report-form" style="display:none;">
+                <div id="toolbar">
+                    <button class="oe_button myButton" value="pdf">Imprimir Informe</button>
+                </div>
+                <div class="container" style="width:90%;">
+                    <table id="table"
+                        data-toggle="table"
+                        data-toolbar="#toolbar"
+                        data-classes="table table-hover table-condensed"
+                        data-search="true"
+                        data-show-export="true"
+                        data-show-toggle="true"
+                        data-show-footer="true"
+                        data-footer-style="footerStyle"
+                        data-buttons-class="oe_button myButton"
+                        data-search-on-enter-key="true"
+                        data-undefined-text=" "
+                        data-pagination="true"
+                        data-show-pagination-switch="true"
+                        data-page-size="10"
+                        data-pagination-detail-h-align="left"
+                        >
+                        <thead style="background:none;">
+                            <tr>
+                                <th colspan="3" data-align="center">DOCUMENTO</th>
+                                <th colspan="2" data-align="center">CLIENTES</th>
+                                <th colspan="8" data-align="center">TOTAL VENTAS</th>
+                            </tr>
+                            <tr>
+                                <th data-field="number" data-align="center" data-footer-formatter="Items:">Num.</th>
+                                <th data-field="supplier_invoice_number" data-align="center" data-footer-formatter="itemsCount">N° Fact.</th>
+                                <th data-field="date_invoice" data-align="center">Fecha</th>
+                                <th data-field="partner_id" data-align="left" data-width="15%" data-footer-formatter="TOTALES:">Razón Social</th>
+                                <th data-field="partner_ruc" data-align="left" data-width="10%">RUC</th>
+                                <th data-field="tasa_5" data-align="right" data-width="10%"
+                                data-footer-formatter="totalTasa5">Monto venta c/ Tasa 5%</th>
+                                <th data-field="iva_5" data-align="right" data-width="10%"
+                                data-footer-formatter="totalIva5">IVA Crédito 5%</th>
+                                <th data-field="tasa_10" data-align="right" data-width="10%"
+                                data-footer-formatter="totalTasa10">Monto venta c/ Tasa 10%</th>
+                                <th data-field="iva_10" data-align="right" data-width="10%"
+                                data-footer-formatter="totalIva10">IVA Crédito 10%</th>
+                                <th data-field="amount_untaxed" data-align="right" data-width="10%"
+                                data-footer-formatter="totalUntaxed">Monto Venta no Gravada o Exenta</th>
+                                <th data-field="percetage_total" data-align="right">%</th>
+                                <th data-field="tax_total" data-align="right" data-footer-formatter="totalTax" data-width="11%">Impuestos</th>
+                             <!--    <th data-field="exenta_total" data-align="right" data-footer-formatter="totalExentas" data-width="11%">Exentas</th> -->
+                                 <th data-field="ret_iva_total" data-align="right" data-footer-formatter="totalRetIVA" data-width="9%">Ret. IVA</th>
+                                <th data-field="ret_renta_total" data-align="right" data-footer-formatter="totalRetRenta" data-width="9%">Ret. Renta</th>
+                                <th data-field="amount_total" data-align="right" data-footer-formatter="totalFormatter" data-width="12%">Total</th>
+                            </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+
+
+            <script>
+                <!--
+                    ITEMS COUNT
+                -->
+                function itemsCount(rowsTable) {
+                    return rowsTable.length;
+                }
+
+                <!--
+                    TOTAL TASA 5
+                -->
+                function totalTasa5(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sftasa_5);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    TOTAL IVA 5
+                -->
+                function totalIva5(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sfiva_5);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    TOTAL TASA 10
+                -->
+                function totalTasa10(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sftasa_10);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+                <!--
+                    TOTAL IVA 10
+                -->
+                function totalIva10(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sfiva_10);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+
+                <!--
+                    EXENTAS
+                -->
+                 function totalUntaxed(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.sfamount_untaxed);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+
+
+                 <!--
+                    IMPUESTOS
+                -->
+                  function totalTax(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.tax);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    RET IVA
+                -->
+<!--                 function totalRetIVA(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.ret_iva);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                } -->
+                <!--
+                    RET RENTA
+                -->
+  <!--               function totalRetRenta(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.ret_renta);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                } -->
+                <!--
+                    TOTAL
+                -->
+                function totalFormatter(rowsTable) {
+                    var decimal_places = 0;
+                    var thousands_separator = '.';
+                    var decimal_separator = ',';
+                    if(rowsTable.length > 0){
+                        decimal_places = rowsTable[0].decimal_places;
+                        thousands_separator = rowsTable[0].thousands_separator;
+                        decimal_separator = rowsTable[0].decimal_separator;
+                    }
+                    var total =  _.reduce(_.map(rowsTable,function(item){
+                        return (item.amount);
+                    }), function(memo, num){
+                    return memo + num; },0)
+                    return accounting.formatNumber(total,decimal_places,thousands_separator,decimal_separator);
+                }
+                <!--
+                    FOOTER STYLE
+                -->
+                function footerStyle(row, index) {
+                    return {
+                        css: {
+                          "font-weight": "bold"
+                        }
+                    };
+                };
+
+            </script>
+        </div>
+    </t>
+</template>

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません