Pārlūkot izejas kodu

[ADD] Transferencia, Entrada y Salida de dinero, Cierre de Caja y ajsuste de saldo, creacion de caja

adrielso 6 gadi atpakaļ
vecāks
revīzija
ee4b4d5245
55 mainītis faili ar 4125 papildinājumiem un 315 dzēšanām
  1. 232 0
      controllers/account_bank_statement.py
  2. 49 0
      controllers/account_bank_statement_config.py
  3. 46 0
      controllers/account_bank_statement_line.py
  4. 14 0
      controllers/account_bank_statement_type.py
  5. 65 0
      controllers/cashbox_confirm.py
  6. 55 0
      controllers/cashbox_input.py
  7. 55 0
      controllers/cashbox_output.py
  8. 75 0
      controllers/cashbox_transfer.py
  9. 89 15
      controllers/main.py
  10. 36 0
      controllers/res_store.py
  11. 17 0
      controllers/res_users.py
  12. 21 0
      controllers/server_datetime.py
  13. 30 30
      package.json
  14. 130 154
      src/App.vue
  15. 3 3
      src/components/common/AddCard.vue
  16. 37 14
      src/components/common/Card.vue
  17. 111 17
      src/components/common/CardGrid.vue
  18. 166 0
      src/components/common/CardGridStatement.vue
  19. 165 0
      src/components/common/CardStatement.vue
  20. 8 4
      src/components/common/InputDropdown.vue
  21. 3 1
      src/components/common/index.js
  22. 9 0
      src/components/filters/absolute.js
  23. 40 0
      src/components/filters/currency.js
  24. 89 0
      src/components/forms/CardOperationDetails.vue
  25. 69 0
      src/components/forms/OperationDetails.vue
  26. 42 16
      src/components/forms/StatementActionForm.vue
  27. 242 0
      src/components/modal/BankStatementModal.vue
  28. 247 0
      src/components/steps/CardGridItem.vue
  29. 279 0
      src/components/steps/CardItem.vue
  30. 186 0
      src/components/steps/DetailsStep.vue
  31. 137 0
      src/components/steps/StatementConfirmStep.vue
  32. 57 0
      src/components/steps/StatementDestStep.vue
  33. 85 0
      src/components/steps/StatementModify.vue
  34. 106 0
      src/components/steps/StatementOperationStep.vue
  35. 74 7
      src/components/steps/StatementStep.vue
  36. 0 11
      src/constants/app.js
  37. 0 7
      src/constants/resourcePaths.js
  38. 6 7
      src/index.js
  39. 184 0
      src/store/actions.js
  40. 13 0
      src/store/getters.js
  41. 43 0
      src/store/index.js
  42. 41 0
      src/store/modules/currencies.js
  43. 58 0
      src/store/modules/date.js
  44. 63 0
      src/store/modules/journals.js
  45. 74 0
      src/store/modules/resUsers.js
  46. 164 0
      src/store/modules/statement.js
  47. 132 0
      src/store/modules/statementAction.js
  48. 147 0
      src/store/modules/statementConfig.js
  49. 55 0
      src/store/modules/statementType.js
  50. 41 0
      src/store/modules/user.js
  51. 10 0
      src/store/mutations.js
  52. 6 0
      src/store/state.js
  53. 0 25
      src/templates.xml
  54. 14 2
      views/templates.xml
  55. 5 2
      webpack.config.js

+ 232 - 0
controllers/account_bank_statement.py

@@ -0,0 +1,232 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+'''
+    ██████   █████  ███    ██ ██   ██    ███████ ████████  █████  ████████ ███████ ███    ███ ███████ ███    ██ ████████
+    ██   ██ ██   ██ ████   ██ ██  ██     ██         ██    ██   ██    ██    ██      ████  ████ ██      ████   ██    ██
+    ██████  ███████ ██ ██  ██ █████      ███████    ██    ███████    ██    █████   ██ ████ ██ █████   ██ ██  ██    ██
+    ██   ██ ██   ██ ██  ██ ██ ██  ██          ██    ██    ██   ██    ██    ██      ██  ██  ██ ██      ██  ██ ██    ██
+    ██████  ██   ██ ██   ████ ██   ██ ██ ███████    ██    ██   ██    ██    ███████ ██      ██ ███████ ██   ████    ██
+'''
+
+_MODEL = 'account.bank.statement'
+
+'''
+         ██████  ███████ ████████
+        ██       ██         ██
+        ██   ███ █████      ██
+        ██    ██ ██         ██
+         ██████  ███████    ██
+'''
+def search_account_bank_statement(statementId):
+    casbox= []
+    statement = request.env['account.bank.statement'].browse(statementId)
+
+    if (statement):
+        casbox = {
+            'id': statement.id,
+            'name': statement.name,
+            'accountId': statement.journal_id.internal_account_id.id,
+            'journalId': statement.journal_id.id,
+            'balanceEnd': statement.balance_end
+        }
+
+    return casbox
+
+'''
+         ██████ ██████  ███████  █████  ████████ ███████
+        ██      ██   ██ ██      ██   ██    ██    ██
+        ██      ██████  █████   ███████    ██    █████
+        ██      ██   ██ ██      ██   ██    ██    ██
+         ██████ ██   ██ ███████ ██   ██    ██    ███████ ██ Account Bank Statement
+'''
+def create_account_bank_statement(data):
+    from account_bank_statement_config import get_bank_statement_config
+
+    config = get_bank_statement_config()
+    if (not config):
+        return {
+            'state': False,
+            'message': 'No existe configuración de caja'
+        }
+
+    domain = [('journal_id', '=', data['journal_id']),('type_statement', '=', data['type_statement']),('user_id', '=', data['user_id']),('state', '=', 'open')]
+    statementVerify = request.env[_MODEL].search(domain)
+    if ((not config.statement_open_config) and (statementVerify)):
+        return {
+            'state': False,
+            'message': 'Ya existe una caja abierta con los mismos parámetros'
+        }
+
+    ''' Create CashBox '''
+    statement = request.env[_MODEL].sudo().create(data)
+    if(not statement):
+        return {
+            'state': False,
+            'message': 'No fue posible crear la caja'
+        }
+
+    ''' Open cashBox '''
+    openStatement = statement.sudo().button_open()
+    if (not openStatement):
+        return {
+            'state': False,
+            'message': 'No fue posible abrir la caja '
+        }
+
+    return {
+        'state': openStatement,
+        'message': 'Caja creada con éxito',
+        'data' : {
+            'id': statement.id,
+            'name': statement.name,
+            'date': statement.date,
+            'state': statement.state,
+            'balanceEnd': statement.balance_end,
+            'user': {
+                'id': statement.user_id.id,
+                'name': statement.user_id.name,
+                'displayName': statement.user_id.display_name
+            },
+            'userSession': request.env.user.id,
+            'journal': {
+                'id': statement.journal_id.id,
+                'name': statement.journal_id.name,
+                'displayName': statement.journal_id.display_name,
+                'code': statement.journal_id.code,
+                'cashControl': statement.journal_id.cash_control,
+                'type': statement.journal_id.type,
+                'currency': {
+                    'id': statement.journal_id.currency.id,
+                    'name': statement.journal_id.currency.name,
+                    'displayName': statement.journal_id.currency.display_name
+                }
+            },
+            'line': [{
+                'id': line.id,
+                'date': line.date,
+                'name': line.name,
+                'ref': line.ref,
+                'amount': line.amount,
+                'patner':{
+                    'id': line.partner_id.id,
+                    'name': line.partner_id.name,
+                    'displayName': line.partner_id.display_name
+                },
+            } for line in statement.line_ids],
+            'typeStatement': {
+                'id': statement.type_statement.id,
+                'name': statement.type_statement.name,
+                'code': statement.type_statement.code
+            },
+            'currency':{
+                'id': statement.currency.id,
+                'name': statement.currency.display_name,
+                'base': statement.currency.base,
+                'symbol': statement.currency.symbol,
+                'position': statement.currency.position,
+                'rateSilent': statement.currency.rate_silent,
+                'decimalSeparator': statement.currency.decimal_separator,
+                'decimalPlaces': statement.currency.decimal_places,
+                'thousandsSeparator': statement.currency.thousands_separator
+            }
+        }
+    }
+
+'''
+         ██████ ██       ██████  ███████ ██ ███    ██  ██████
+        ██      ██      ██    ██ ██      ██ ████   ██ ██
+        ██      ██      ██    ██ ███████ ██ ██ ██  ██ ██   ███
+        ██      ██      ██    ██      ██ ██ ██  ██ ██ ██    ██
+         ██████ ███████  ██████  ███████ ██ ██   ████  ██████   bank Statement
+'''
+def closing_statement(data):
+    from account_bank_statement_line import create_statement_line
+    from cashbox_confirm import get_cashbox_statement_confirm, create_cashbox_statement_confirm, write_cashbox_statement_confirm
+    from server_datetime import get_date
+    lineDifference = []
+    lineclosing = []
+    statement = request.env[_MODEL].browse(data['statementId'])
+
+    if (not statement):
+        return {
+            'state': False,
+            'message': 'No fue posible localizar la caja.'
+        }
+    amountStatement = statement.balance_end or 0.0
+    '''  Registrar Diferencia entre saldos '''
+    if (statement.balance_end != data['amount']):
+        lineDifference = create_statement_line({
+            'statement_id': statement.id,
+            'name': "Diferencia entre valor teórico de cierre y valor real de cierre.",
+            'amount': data['amount'] - statement.balance_end,
+            'ref': 'AJUSTE DE CIERRE',
+            'account_id': statement.journal_id.internal_account_id.id,
+            'journal_id': statement.journal_id.id,
+            # 'is_deleted': True
+        })
+
+        if (not lineDifference):
+            return {
+                'state': False,
+                'message': 'No fue posible registrar el ajuste de cierre.'
+            }
+
+    ''' Resgitro de saldo '''
+    if (statement.balance_end != 0):
+        lineclosing = create_statement_line({
+            'statement_id': statement.id,
+            'name': "Registro de saldo para próxima apertura.",
+            'amount': - statement.balance_end if (statement.balance_end > 0)  else abs(statement.balance_end),
+            'ref': 'CIERRE DE CAJA',
+            'account_id': statement.journal_id.internal_account_id.id,
+            'journal_id': statement.journal_id.id,
+            # 'is_deleted': True
+        })
+        if (not lineclosing):
+            return {
+                'state': False,
+                'message': 'No fue posible registrar el cierre de caja.'
+            }
+
+        amountNexOpen = abs(lineclosing.amount) if (lineclosing.amount < 0 ) else  - (lineclosing.amount)
+    # import web_pdb; web_pdb.set_trace()
+    ''' Registro de Cierre de caja '''
+    statementConfirm = get_cashbox_statement_confirm([('statement_id.id', '=', statement.id)])
+
+
+    cashboxConfirm = {
+        'name': "CIERRE DE CAJA /"+str(statement.name),
+        'date': get_date(),
+        'ref': data['description'],
+        'statement_id': statement.id,
+        'user_statement': statement.user_id.id,
+        'user_confirm': request.env.user.id,
+        'journal_id' : statement.journal_id.id,
+        'amount_statement': amountStatement,
+        'amount_real': data['amount'],
+        'line_difference': lineDifference.id if (lineDifference) else '',
+        'amount_difference': lineDifference.amount if (lineDifference) else 0.0,
+        'line_next_open': lineclosing.id if(lineclosing) else '',
+        'amount_next_open': amountNexOpen if(lineclosing) else 0.0,
+        'state_avaliable': True if(lineclosing and abs(lineclosing.amount) > 0) else False,
+    }
+
+    confirm = create_cashbox_statement_confirm(cashboxConfirm) if (not statementConfirm) else write_cashbox_statement_confirm(statementConfirm.id, cashboxConfirm)
+
+    if (not confirm):
+        return {
+            'state': False,
+            'message': 'No fue posible crear el cierre de caja'
+        }
+
+    response = statement.button_confirm_cash()
+    if (not response):
+        return {
+            'state': False,
+            'message': 'No fue posible cerrar la caja'
+        }
+
+    return {
+        'state': True,
+        'message': 'Cierre de caja, realizada con éxito.'
+    }

+ 49 - 0
controllers/account_bank_statement_config.py

@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'account.bank.statement.config'
+
+def get_bank_statement_config():
+    return request.env[_MODEL].search([('active', '=', True)])
+
+    # import pdb_pdb; pdb_pdb.set_trace()
+
+
+'''
+name = fields.Char('Name', required=True, default="Configuración Cajas")
+active = fields.Boolean('Active', default=True)
+
+## Forma de Importar Pagso en caja Ventas/compras/RRHH
+import_statement_payments = fields.Selection([('automatic_import', 'Automático'),('manual_import','Manual')],'Importar pagos en caja',default='automatic_import',help='Tipo de importar los pago en caja', required=True)
+import_statement_payslip = fields.Selection([('automatic_import', 'Automático'),('manual_import','Manual')],'Importar pagos de RRHH en caja',default='automatic_import',help='Tipo de importar los pago en caja', required=True)
+
+## TRANSFERENCIA
+transfer_user_ids = fields.Many2many('res.users', 'statement_config_transfer_user', 'account_bank_statement_config_id','res_users_id', string='statement_transfer_user')
+transfer_statement_ids = fields.Many2many('account.bank.statement.type', 'statement_config_transfer_statement', 'account_bank_statement_config_id', 'account_bank_statement_type_id', string="statement_config_transfer_statement")
+transfer_negative_amount = fields.Boolean('transfer_negative_amount', default=False, help="Permitir transferencia sin saldo en caja")
+delete_transfer_user_ids = fields.Many2many('res.users', 'statement_config_deleted_transfer_user', 'account_bank_statement_config_id','res_users_id', string='statement_delete_transfer_user')
+
+## Poner Dinero
+input_cash_box_user_id = fields.Many2many('res.users', 'statement_config_input_user', 'account_bank_statement_config_id', 'res_users_id', string='statement_input_user')
+input_cash_box_statement_ids = fields.Many2many('account.bank.statement.type', 'statement_config_input_statement', 'account_bank_statement_config_id', 'account_bank_statement_type_id', string="statement_config_input_statement")
+delete_input_user_ids = fields.Many2many('res.users', 'statement_config_deleted_input_user', 'account_bank_statement_config_id','res_users_id', string='statement_delete_input_user')
+
+## Sacar Dinero
+output_cash_box_user_id = fields.Many2many('res.users', 'statement_config_output_user', 'account_bank_statement_config_id', 'res_users_id', string='statement_output_user')
+output_cash_box_statement_ids = fields.Many2many('account.bank.statement.type', 'statement_config_output_statement', 'account_bank_statement_config_id', 'account_bank_statement_type_id', string="statement_config_output_statement")
+output_negative_amount = fields.Boolean('output_negative_amount', default=False, help="Permitir sacar dinero sin saldo en caja")
+delete_output_user_ids = fields.Many2many('res.users', 'statement_config_deleted_output_user', 'account_bank_statement_config_id','res_users_id', string='statement_delete_output_user')
+
+## Abrir Cajas
+statement_open_config = fields.Boolean('statement_open_config', default=False, help="Permitir abrir mas de una caja(por usuario, por diario, por tipo de caja)")
+
+## statement confirm
+statement_confirm_user = fields.Many2many('res.users', 'statement_config_confirm_user', 'account_bank_statement_config_id', 'res_users_id', string='Usuario permitido para cerrar Caja ')
+statement_confirm_transfer_user = fields.Many2many('res.users', 'statement_config_confirm_transfer_user', 'account_bank_statement_config_id', 'res_users_id', string='Usuario permitido para realizar transferencia')
+statement_confirm_balance = fields.Many2many('res.users', 'statement_config_confirm_balance', 'account_bank_statement_config_id', 'res_users_id', string='Usuario permitido para ajuste de cierre')
+statement_confirm_negative_amount = fields.Many2many('res.users', 'statement_confirm_negative_amount', 'account_bank_statement_config_id', 'res_users_id', string='Usuario permitido para cerrar caja sin saldo ')
+## statement Cancel
+statement_cancel_user = fields.Many2many('res.users', 'statement_config_cancel_user', 'account_bank_statement_config_id', 'res_users_id', string='Usuarios permitidos para cancelar Cajas')
+## Statement Unlink
+statement_unlink_user = fields.Many2many('res.users', 'statement_config_unlink_user', 'account_bank_statement_config_id', 'res_users_id', string='Usuarios permitidos para Eliminar Cajas')
+'''

+ 46 - 0
controllers/account_bank_statement_line.py

@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+from openerp.http import request
+
+_MODEL= 'account.bank.statement.line'
+
+
+'''
+    Create Statement line
+'''
+def create_statement_line(values):
+    return request.env[_MODEL].sudo().create(values)
+
+    # '''
+    #     Create Line statement.
+    # '''
+    # def _create_statement_line_transfer(self, statement, name, amount, ref):
+    #     statementLine = {
+    #         'statement_id': statement.id,
+    #         'name': name,
+    #         'amount': amount ,
+    #         'ref': ref,
+    #         'account_id': statement.journal_id.internal_account_id.id,
+    #         'journal_id': statement.journal_id.id,
+    #         'is_deleted': True
+    #     }
+    #
+    #     line = self.env['account.bank.statement.line'].create(statementLine)
+    #     return line
+    #
+    #
+    # '''
+    #     Create cash box transfer
+    # '''
+    # def _create_cash_box_transfer(self, ref, amount, lineInput, lineOutput):
+    #     cash = {
+    #         'name': "TRANSFERENCIA %s a %s" %((lineOutput.statement_id.name),(lineInput.statement_id.name)),
+    #         'amount': amount,
+    #         'ref': ref,
+    #         'input_line': lineInput.id,
+    #         'output_line': lineOutput.id,
+    #         'input_statement': lineInput.statement_id.id,
+    #         'output_statement': lineOutput.statement_id.id,
+    #         'date': lineOutput.date
+    #     }
+    #     return self.env['cash.box.transfer'].create(cash)

+ 14 - 0
controllers/account_bank_statement_type.py

@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+
+from openerp.http import request
+
+_MODEL = 'account.bank.statement.type'
+
+def get_account_bank_statement_type():
+    return[{
+        'id': type.id,
+        'name': type.name,
+        'code': type.code,
+        'comment': type.comment,
+        'isDefault': type.is_default
+    }for type in request.env['account.bank.statement.type'].search([('active', '=', True)])]

+ 65 - 0
controllers/cashbox_confirm.py

@@ -0,0 +1,65 @@
+# -*- conding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'cashbox.statement.confirm'
+
+'''
+    GET
+'''
+def get_cashbox_statement_confirm(domain):
+    return request.env[_MODEL].search(domain)
+
+'''
+    CREATE
+'''
+def create_cashbox_statement_confirm(data):
+    return request.env[_MODEL].sudo().create(data)
+
+'''
+    WRITE
+'''
+def write_cashbox_statement_confirm(confirmId, data):
+    confirm = request.env[_MODEL].browse(confirmId)
+    return  confirm.sudo().write(data)
+
+#
+# def _create_cashbox_statement_confirm(self,values, statement):
+#     casbox = self.env['cashbox.statement.confirm'].search([('statement_id.id', '=', statement.id)])
+#     if (not casbox):
+#         confirm = self.env['cashbox.statement.confirm'].create(values)
+#     else:
+#         confirm = casbox.write(values)
+#         if (confirm):
+#             confirm = self.env['cashbox.statement.confirm'].search([('statement_id.id', '=', statement.id)])
+#
+#     return confirm
+
+'''
+    name = fields.Char('name', required=True)
+    ref = fields.Char('Ref')
+    date = fields.Date()
+    active = fields.Boolean('Active', default=True)
+    message_confirm = fields.Text('Message Confirm')
+    message_deleted = fields.Text('Message Deleted')
+    ### Statement confirm - open
+    statement_id = fields.Many2one('account.bank.statement', 'Bank Statement Confirm')
+    statement_open = fields.Many2one('account.bank.statement', 'Bank Statement Open')
+    ## User statement - User Confirm
+    user_statement = fields.Many2one('res.users', 'Res user')
+    user_confirm = fields.Many2one('res.users', 'Res user')
+    ## Journal
+    journal_id = fields.Many2one('account.journal', 'Journal')
+    ## Line
+    line_difference = fields.Many2one('account.bank.statement.line', 'Bank statement line difference')
+    line_next_open = fields.Many2one('account.bank.statement.line', 'Bank statement line next open statement')
+    line_open = fields.Many2one('account.bank.statement.line', 'Bank statement line open')
+    ### Amount
+    amount_statement = fields.Float('Amount Statement', digits_compute=dp.get_precision('Account'), required=True)
+    amount_real = fields.Float('Amount Real', digits_compute=dp.get_precision('Account'), required=True)
+    amount_difference = fields.Float('Amount Difference', digits_compute=dp.get_precision('Account'), required=True)
+    amount_next_open =  fields.Float('Amount Next open statement', digits_compute=dp.get_precision('Account'), required=True)
+    ## estado del regsitro
+    state_avaliable = fields.Boolean('Avaliable', default=True, help="True : disponible, False : Utilizado")
+    # casbox_transfer_id =fields.Many2one('cash.box.transfer', 'cashBox transfer')
+    cashbox_transfer_ids =fields.One2many('cash.box.transfer', 'cashbox_confirm_id', string="transfer id")
+'''

+ 55 - 0
controllers/cashbox_input.py

@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL='cash.box.in'
+
+
+def create_cashbox_input(data):
+    from account_bank_statement import search_account_bank_statement
+    from account_bank_statement_line import create_statement_line
+
+    ''' Statement '''
+    statement = search_account_bank_statement(data['casboxOriginId'])
+    if (not statement):
+        return {
+            'state': False,
+            'message': 'Error. Obtener la Caja'
+        }
+
+    lineInput = create_statement_line({
+        'statement_id': statement['id'],
+        'name': "ENTRADA DE DINERO - Ref. %s" % (data['description']),
+        'amount': data['amount'] ,
+        'ref': 'ENTRADA DE DINERO',
+        'account_id': statement['accountId'],
+        'journal_id': statement['journalId'],
+        # 'is_deleted': True
+    })
+
+    if (not lineInput):
+        return {
+            'state': False,
+            'message': 'Error en la entrada de dinero de la caja.'
+        }
+
+    casboxInput = request.env[_MODEL].sudo().create({
+        'name': "ENTRADA DE DINERO %s" %(statement['name']),
+        'amount': data['amount'],
+        'ref': data['description'],
+        'date': lineInput.date,
+        'line_id': lineInput.id,
+        'statement_id': statement['id'],
+    })
+
+    result ={
+        'state': False,
+        'message': "Error en la entrada de dinero de la caja"
+    }
+
+    if (casboxInput):
+        result ={
+            'state': True,
+            'message': "Entrada de dinero registrada con suceso."
+        }
+
+    return result

+ 55 - 0
controllers/cashbox_output.py

@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL='cash.box.out'
+
+
+def create_cashbox_output(data):
+    from account_bank_statement import search_account_bank_statement
+    from account_bank_statement_line import create_statement_line
+
+    ''' Statement '''
+    statement = search_account_bank_statement(data['casboxOriginId'])
+    if (not statement):
+        return {
+            'state': False,
+            'message': 'Error. Obtener la Caja'
+        }
+
+    lineOutput = create_statement_line({
+        'statement_id': statement['id'],
+        'name': "SALIDA DE DINERO - Ref. %s" % (data['description']),
+        'amount': -data['amount'],
+        'ref': 'SALIDA DE DINERO',
+        'account_id': statement['accountId'],
+        'journal_id': statement['journalId'],
+        # 'is_deleted': True
+    })
+
+    if (not lineOutput):
+        return {
+            'state': False,
+            'message': 'Error en la salida de dinero de la caja.'
+        }
+
+    casboxInput = request.env[_MODEL].sudo().create({
+        'name': "SALIDA DE DINERO %s" %(statement['name']),
+        'amount': data['amount'],
+        'ref': data['description'],
+        'date': lineOutput.date,
+        'line_id': lineOutput.id,
+        'statement_id': statement['id'],
+    })
+
+    result ={
+        'state': False,
+        'message': "Error en la salida de dinero de la caja"
+    }
+
+    if (casboxInput):
+        result ={
+            'state': True,
+            'message': "Extracción de dinero registrada con suceso."
+        }
+
+    return result

+ 75 - 0
controllers/cashbox_transfer.py

@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'cash.box.transfer'
+
+
+def create_cashbox_transfer(data):
+    from account_bank_statement import search_account_bank_statement
+    from account_bank_statement_line import create_statement_line
+
+    ''' Statement Origin '''
+    statementOrigin = search_account_bank_statement(data['casboxOriginId'])
+    if (not statementOrigin):
+        return {
+            'state': False,
+            'message': 'Error. Obtener la Caja'
+        }
+    ''' Statement Destino '''
+    statementDest = search_account_bank_statement(data['casboxDestID'])
+    if (not statementDest):
+        return {
+            'state': False,
+            'message': 'Error. Obtener la Caja'
+        }
+
+    ''' Caja Origin (line) '''
+    lineOrigin = create_statement_line({
+        'statement_id': statementOrigin['id'],
+        'name': "TRANSFERIDO A(%s) Ref. %s" % (statementDest['name'], data['description']),
+        'amount': -data['amount'] ,
+        'ref': 'TRANSFERENCIA',
+        'account_id': statementOrigin['accountId'],
+        'journal_id': statementOrigin['journalId'],
+        # 'is_deleted': True
+    })
+    if (not lineOrigin):
+        return {
+            'state': False,
+            'message': 'Error de transferencia, registro de salida de caja.'
+        }
+
+    ''' Caja Destino (line) '''
+    lineDest = create_statement_line({
+        'statement_id': statementDest['id'],
+        'name': "TRANSFERIDO DE(%s) Ref. %s" % (statementOrigin['name'], data['description']),
+        'amount': abs(data['amount']),
+        'ref': 'TRANSFERENCIA',
+        'account_id': statementDest['accountId'],
+        'journal_id': statementDest['journalId'],
+        # 'is_deleted': True
+    })
+
+    cash = {
+        'name': "TRANSFERENCIA %s a %s" %(statementOrigin['name'], statementDest['name']),
+        'amount': abs(data['amount']),
+        'ref': data['description'],
+        'input_line': lineDest.id,
+        'output_line': lineOrigin.id,
+        'input_statement': statementDest['id'],
+        'output_statement': statementOrigin['id'],
+        'date': lineDest.date
+    }
+    transfer = request.env[_MODEL].sudo().create(cash)
+    result = {
+        'state': True,
+        'message': "Transferencia realizada con suceso."
+    }
+
+    if (not transfer):
+        result = {
+            'state': False,
+            'message': "Error.. En la creación de la transferencia."
+        }
+
+    return result

+ 89 - 15
controllers/main.py

@@ -18,7 +18,7 @@ DATE_FORMAT = '%Y-%m-%d'
 DATETIME_FORMAT = '%Y-%m-%d %H:%m:%S'
 GZIP_COMPRESSION_LEVEL = 9
 
-class Purchases(http.Controller):
+class Statement(http.Controller):
 
     ''' Get timezone '''
     def get_timezone(self):
@@ -52,7 +52,7 @@ class Purchases(http.Controller):
     def get_currencies_from_journal(self):
         domain = [
             ('type', 'in', ['bank', 'cash']),
-            ('default_debit_account_id.currency_id', '=', False),
+            # ('default_debit_account_id.currency_id', '=', False),
             ('active', '=', True)
         ]
 
@@ -88,7 +88,8 @@ class Purchases(http.Controller):
                 if (journalID.type in ['bank', 'cash']):
                     journal.append(journalID.id)
 
-        domain = [('type', 'in', type), ('default_debit_account_id.currency_id', '=', False), ('active', '=', True)]
+        # domain = [('type', 'in', type), ('default_debit_account_id.currency_id', '=', False), ('active', '=', True)]
+        domain = [('type', 'in', type),('active', '=', True)]
 
         if (journal):
             domain.append(('id', 'in', journal ))
@@ -100,6 +101,7 @@ class Purchases(http.Controller):
             'code': journal.code,
             'cashControl': journal.cash_control,
             'type': journal.type,
+            'storeIds': map(lambda x: x.id, journal.store_ids),
             'currency': {
                 'id': journal.currency.id,
                 'name': journal.currency.name,
@@ -140,12 +142,14 @@ class Purchases(http.Controller):
             'id': statement.id,
             'name': statement.name,
             'date': statement.date,
+            'state': statement.state,
             'balanceEnd': statement.balance_end,
             'user': {
                 'id': statement.user_id.id,
                 'name': statement.user_id.name,
                 'displayName': statement.user_id.display_name
             },
+            'userSession': request.env.user.id,
             'journal': {
                 'id': statement.journal_id.id,
                 'name': statement.journal_id.name,
@@ -175,6 +179,17 @@ class Purchases(http.Controller):
                 'id': statement.type_statement.id,
                 'name': statement.type_statement.name,
                 'code': statement.type_statement.code
+            },
+            'currency':{
+                'id': statement.currency.id,
+                'name': statement.currency.display_name,
+                'base': statement.currency.base,
+                'symbol': statement.currency.symbol,
+                'position': statement.currency.position,
+                'rateSilent': statement.currency.rate_silent,
+                'decimalSeparator': statement.currency.decimal_separator,
+                'decimalPlaces': statement.currency.decimal_places,
+                'thousandsSeparator': statement.currency.thousands_separator
             }
         } for statement in request.env['account.bank.statement'].search(domain)]
 
@@ -236,25 +251,84 @@ class Purchases(http.Controller):
     def make_info_log(self, log):
         LOGGER.info('\033[1;34m[INFO] --> \033[m{}'.format(log))
 
-    ''' Bank statement Init '''
+    '''
+        ██ ███    ██ ██ ████████
+        ██ ████   ██ ██    ██
+        ██ ██ ██  ██ ██    ██
+        ██ ██  ██ ██ ██    ██
+        ██ ██   ████ ██    ██
+    '''
     @http.route('/eiru_bank_statement/init', auth='user', methods=['GET'], cors='*')
     def init_bank_statement(self,**kw):
-
+        from account_bank_statement_type import get_account_bank_statement_type
+        from res_store import get_res_store
+        from res_users import get_res_users
         self.make_info_log('Preparing data to {}'.format(kw.get('mode')))
-        journals = self.get_journals([kw.get('mode')]),
+        store = get_res_store(kw.get('mode'))
 
         return self.make_gzip_response({
             'date': self.get_server_date(),
             'user': self.get_user(),
             'currencies': self.get_currencies_from_journal(),
-            'journals': journals,
-            'statement': self.get_account_bank_statement(map(lambda x: x['id'], journals[0])),
+            'journals': self.get_journals([kw.get('mode')]),
+            # 'statement': self.get_account_bank_statement(map(lambda x: x['id'], journals[0])),
+            'statement': self.get_account_bank_statement(store['journalIds']),
             'statementConfig' : self.get_account_bank_statement_config(),
-        #     'suppliers': self.get_suppliers(),
-        #     'products': self.get_products(kw.get('mode')),
-        #     'pickingTypes': self.get_picking_types(),
-        #     'paymentTerms': self.get_payment_terms(),
-        #     'banks': self.get_banks(),
-        #     'bankPaymentTypes': self.get_bank_payment_types(),
-        #     'chequeTypes': self.get_cheque_types()
+            'statementType': get_account_bank_statement_type(),
+            'resUsers': get_res_users(store['userIds'])
         })
+
+    '''
+      ██████  █████  ███████ ██   ██ ██████   ██████  ██   ██     ███    ███  ██████  ██    ██ ███████
+     ██      ██   ██ ██      ██   ██ ██   ██ ██    ██  ██ ██      ████  ████ ██    ██ ██    ██ ██
+     ██      ███████ ███████ ███████ ██████  ██    ██   ███       ██ ████ ██ ██    ██ ██    ██ █████
+     ██      ██   ██      ██ ██   ██ ██   ██ ██    ██  ██ ██      ██  ██  ██ ██    ██  ██  ██  ██
+      ██████ ██   ██ ███████ ██   ██ ██████   ██████  ██   ██     ██      ██  ██████    ████   ███████
+        * Transfer.
+        * Input.
+        * Output.
+    '''
+    @http.route('/eiru_bank_statement/create_cashbox_move', type='json', auth='user', methods=['POST'],cors='*')
+    def _create_cashbox_move(self, **kw):
+        from account_bank_statement_line import create_statement_line
+        from cashbox_transfer import create_cashbox_transfer
+        from cashbox_input import create_cashbox_input
+        from cashbox_output import create_cashbox_output
+        data = kw.get('data')
+
+        ''' Transferencia '''
+        if (data['transfer']):
+            return create_cashbox_transfer(data)
+
+        ''' Entrada de Dinero '''
+        if (data['input']):
+            return create_cashbox_input(data)
+
+        ''' Salida de Dinero '''
+        if (data['output']):
+            return create_cashbox_output(data)
+
+    '''
+      ██████ ██████  ███████  █████  ████████ ███████
+     ██      ██   ██ ██      ██   ██    ██    ██
+     ██      ██████  █████   ███████    ██    █████
+     ██      ██   ██ ██      ██   ██    ██    ██
+      ██████ ██   ██ ███████ ██   ██    ██    ███████ Statement
+    '''
+    @http.route('/eiru_bank_statement/create_account_bank_statement', type='json', auth='user', methods=['POST'],cors='*')
+    def _create_account_bank_statement(self, **kw):
+        from account_bank_statement import create_account_bank_statement
+
+        return create_account_bank_statement(kw.get('data'))
+    '''
+         ██████ ██       ██████  ███████ ██ ███    ██  ██████
+        ██      ██      ██    ██ ██      ██ ████   ██ ██
+        ██      ██      ██    ██ ███████ ██ ██ ██  ██ ██   ███
+        ██      ██      ██    ██      ██ ██ ██  ██ ██ ██    ██
+         ██████ ███████  ██████  ███████ ██ ██   ████  ██████    STATEMENT
+    '''
+    @http.route('/eiru_bank_statement/process_closing_statement', type='json', auth='user', methods=['POST'],cors='*')
+    def _process_closing_statement(self, **kw):
+        from account_bank_statement import closing_statement
+
+        return closing_statement(kw.get('data'))

+ 36 - 0
controllers/res_store.py

@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL='res.store'
+'''
+        ██████  ███████ ███████    ███████ ████████  ██████  ██████  ███████
+        ██   ██ ██      ██         ██         ██    ██    ██ ██   ██ ██
+        ██████  █████   ███████    ███████    ██    ██    ██ ██████  █████
+        ██   ██ ██           ██         ██    ██    ██    ██ ██   ██ ██
+        ██   ██ ███████ ███████ ██ ███████    ██     ██████  ██   ██ ███████
+'''
+'''
+  ██████  ███████ ████████
+ ██       ██         ██
+ ██   ███ █████      ██
+ ██    ██ ██         ██
+  ██████  ███████    ██
+'''
+def get_res_store(mode):
+    userIds = []
+    journalIds = []
+
+    user = request.env.user
+    for store in request.env['res.store'].search([('id', 'in', map(lambda x: x.id, user.store_ids))]):
+        for  user in store.user_ids:
+            userIds.append(user.id)
+
+        for journal in store.journal_ids:
+            if (journal.type == mode):
+                journalIds.append(journal.id)
+
+    return {
+        'userIds': userIds,
+        'journalIds': journalIds
+    }
+    # user_ids

+ 17 - 0
controllers/res_users.py

@@ -0,0 +1,17 @@
+# -*- codign: utf-8 -*-
+from openerp.http import request
+
+_MODEL='res.users'
+
+def get_res_users(store):
+    domain = [('active', '=', True)]
+
+    if (store):
+        domain.append(('id', 'in', store))
+    return[{
+        'id':  users.id,
+        'name': users.name,
+        'displayName': users.display_name,
+        'image': users.image_medium,
+        'storeIds': map(lambda x: x.id, users.store_ids),
+    } for users in request.env[_MODEL].search(domain)]

+ 21 - 0
controllers/server_datetime.py

@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
+from pytz import timezone
+from datetime import datetime
+
+'''
+
+'''
+def get_timezone():
+    return timezone(request.context['tz'])
+
+'''
+'''
+def get_datetime():
+    return datetime.now(get_timezone()).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
+
+'''
+'''
+def get_date():
+    return datetime.now(get_timezone()).strftime(DEFAULT_SERVER_DATE_FORMAT)

+ 30 - 30
package.json

@@ -9,36 +9,36 @@
     "build": "export NODE_ENV=production &&./node_modules/.bin/webpack --progress --config webpack.config.js"
   },
   "devDependencies": {
- 		"babel-core": "^6.26.0",
- 		"babel-loader": "^7.1.2",
- 		"babel-preset-env": "^1.6.1",
- 		"babel-preset-stage-2": "^6.24.1",
- 		"copy-webpack-plugin": "^4.5.2",
- 		"css-loader": "^0.28.9",
- 		"extract-text-webpack-plugin": "^3.0.2",
- 		"file-loader": "^1.1.6",
- 		"hard-source-webpack-plugin": "^0.5.16",
- 		"node-sass": "^4.7.2",
- 		"offline-plugin": "^5.0.5",
- 		"pug": "^2.0.0-rc.4",
- 		"sass-loader": "^6.0.6",
- 		"style-loader": "^0.20.1",
- 		"url-loader": "^0.6.2",
- 		"vue-loader": "^14.0.3",
- 		"vue-template-compiler": "^2.5.13",
- 		"webpack": "^3.10.0",
- 		"webpack-livereload-plugin": "^1.0.0"
- 	},
+    "babel-core": "^6.26.0",
+    "babel-loader": "^7.1.2",
+    "babel-preset-env": "^1.6.1",
+    "babel-preset-stage-2": "^6.24.1",
+    "copy-webpack-plugin": "^4.5.2",
+    "css-loader": "^0.28.9",
+    "extract-text-webpack-plugin": "^3.0.2",
+    "file-loader": "^1.1.6",
+    "hard-source-webpack-plugin": "^0.5.16",
+    "node-sass": "^4.7.2",
+    "offline-plugin": "^5.0.5",
+    "pug": "^2.0.0-rc.4",
+    "sass-loader": "^6.0.6",
+    "style-loader": "^0.20.1",
+    "url-loader": "^0.6.2",
+    "vue-loader": "^14.0.3",
+    "vue-template-compiler": "^2.5.13",
+    "webpack": "^3.10.0",
+    "webpack-livereload-plugin": "^1.0.0"
+  },
   "dependencies": {
-      "axios": "^0.17.1",
-      "fuse.js": "^3.2.0",
-      "install": "^0.12.1",
-      "velocity-animate": "^2.0.5",
-      "vue": "^2.5.13",
-      "vue-form-wizard": "^0.8.2",
-      "vue-js-modal": "^1.3.9",
-      "vue2-datepicker": "^2.0.3",
-      "vuex": "^3.0.1",
-      "vuex-persistedstate": "^2.5.4"
+    "axios": "^0.17.1",
+    "fuse.js": "^3.2.0",
+    "install": "^0.12.1",
+    "velocity-animate": "^2.0.5",
+    "vue": "^2.5.13",
+    "vue-form-wizard": "^0.8.2",
+    "vue-js-modal": "^1.3.9",
+    "vue2-datepicker": "^2.0.3",
+    "vuex": "^3.0.1",
+    "vuex-persistedstate": "^2.5.4"
   }
 }

+ 130 - 154
src/App.vue

@@ -1,163 +1,136 @@
 <template lang="pug">
     .statement
-        form-wizard(title='' subtitle='' finishButtonText='Finalizar' color='#7c7bad' nextButtonText='Continuar' backButtonText='Volver' @on-complete='createPurchase' ref='wizard')
-            tab-content(title='Seleccione la caja')
-                statement-step
+        form-wizard(
+            title=''
+            subtitle=''
+            color='#7c7bad'
+            ref='wizard'
+        )
+            //- @on-change="(prev, next) => stepChange(prev, next)"
+            // Step Initial
+            template
+                tab-content( title='Seleccione la caja' :beforeChange='checkStatement' )
+                    statement-step(@actionSelected='actionSelected')
+            // Step Transfer
+            template(v-if='!!isTransfer')
+                // Step Transfer 2
+                tab-content( title="A que caja vas a transferir" :beforeChange='checkStatementDest')
+                    statement-dest-step
+                // Step Transfer 3
+                tab-content( title="Que valor vas a transferir")
+                    statement-operation-step
+            // step Imput
+            template( v-if='!!isInputCashbox')
+                // step Imput 2
+                tab-content( title="Que valor vas a colocar")
+                    statement-operation-step
+            // Step Output
+            template(v-if='!!isOutputCashbox')
+                // Step Output 2
+                tab-content( title="Que valor vas a sacar")
+                    statement-operation-step
+            // step confirm
+            template(v-if='!!isStatmentConfirm')
+                // step confirm 2
+                tab-content(title='Que ajuste deseas hacer')
+                    statement-confirm-step
+            // STEP MODIFY STATMENT
+            template
+                tab-content(title="Que vas a modificar")
+                    statement-modify
+            // Footer
+            template(
+                slot='footer'
+                slot-scope='props'
+            )
+                .wizard-footer-left
+                    wizard-button(
+                        v-if='props.activeTabIndex > 0'
+                        @click.native='goBack'
+                        :style='props.fillButtonStyle'
+                    ) Volver
+                .wizard-footer-right
+                    wizard-button(
+                        v-if='!props.isLastStep'
+                        class='wizard-footer-right'
+                        :style='props.fillButtonStyle'
+                        @click.native='goNext'
+                    ) Continuar
+                    wizard-button(
+                        v-else-if='props.activeTabIndex > 0'
+                        class='wizard-footer-right finish-button'
+                        :style='props.fillButtonStyle'
+                        @click.native='endProcess'
+                    ) {{ props.isLastStep ? 'Finalizar' : 'Continuar' }}
 </template>
 <script>
     import { mapGetters, mapActions } from 'vuex'
 
-    import { FormWizard, TabContent } from 'vue-form-wizard'
+    import { FormWizard, TabContent, WizardButton } from 'vue-form-wizard'
     import 'vue-form-wizard/dist/vue-form-wizard.min.css'
 
     /* steps */
     import StatementStep from '@/components/steps/StatementStep'
-    // import SupplierStep from '@/components/steps/SupplierStep'/
-    // import ProductStep from '@/components/steps/ProductStep'
-    // import PaymentStep from '@/components/steps/PaymentStep'
+    import StatementDestStep from '@/components/steps/StatementDestStep'
+    import StatementOperationStep from '@/components/steps/StatementOperationStep'
+    import StatementConfirmStep from '@/components/steps/StatementConfirmStep'
+    import StatementModify from '@/components/steps/StatementModify'
+    // import DetailsStep from '@/components/steps/DetailsStep'
     // import { LoadingOverlay } from '@/components/common'
 
     export default {
         components: {
             FormWizard,
             TabContent,
-            StatementStep
-            // SupplierStep,
-            // ProductStep,
-            // PaymentStep,
-            // LoadingOverlay
-        },
-        // computed: mapGetters([
-        //     'isLoading',
-        //     'isCompleted',
-        //     'isProcessing',
-        //     'state',
-        //     'mode'
-        // ]),
-        // methods: {
-        //     ...mapActions([
-        //         'initPurchase',
-        //         'checkSupplier',
-        //         'checkCart',
-        //         'checkAmountReceived',
-        //         'createPurchase',
-        //         'resetPurchase'
-        //     ])
-        // },
-        // watch: {
-        //     isCompleted(value) {
-        //         if (!value) {
-        //             return
-        //         }
-        //
-        //         this.$refs.wizard.changeTab(2, 0, false)
-        //         this.resetPurchase()
-        //     }
-        // },
-        // mounted() {
-        //     this.initPurchase(this.$root.mode)
-        // }
-    }
-</script>
-
-<style lang="sass">
-    @import './assets/variables'
-
-    .statement
-        width: 100%
-        height: 100%
-        position: absolute
-        .vue-form-wizard
-            width: 100%
-            height: 100%
-            padding-bottom: 0
-            .wizard-header
-                display: none
-            .wizard-navigation
-                width: 100%
-                height: 100%
-                .wizard-progress-with-circle
-                    top: 35px
-                .wizard-icon-circle
-                    width: 60px
-                    height: 60px
-                .wizard-tab-content
-                    width: 100%
-                    height: calc(100% - 82px)
-                    padding: 0
-                    overflow: hidden
-                    .wizard-tab-container
-                        width: calc(100% - 20px)
-                        height: calc(100% - 20px)
-                        margin: 10px
-                        .purchase-step
-                            width: 100%
-                            height: 100%
-                            background: $app-bg-color
-            .wizard-card-footer
-                width: 100%
-                height: 50px
-                position: absolute
-                bottom: 10px
-                .wizard-btn
-                    width: 160px
-                    height: 40px
-                    border-radius: 0
-                    box-shadow: none
-                    border: none
-                    &:hover, &:focus
-                        background: $app-main-color
-</style>
-
-<!--
-<template lang="pug">
-    .purchases
-        form-wizard(title='' subtitle='' finishButtonText='Finalizar' :hideButtons='isProcessing' color='#7c7bad' nextButtonText='Continuar' backButtonText='Volver' @on-complete='createPurchase' ref='wizard')
-            tab-content(title='Cuál es su proveedor?' :before-change='checkSupplier')
-                supplier-step
-            tab-content(:title="mode === 'purchase' ? 'Qué productos comprarás?' : 'En que gastarás?'" :before-change='checkCart')
-                product-step
-            tab-content(title='Cómo quieres pagar?' :before-change='checkAmountReceived')
-                payment-step
-        loading-overlay(:show='isLoading')
-</template>
-
-<script>
-    import { mapGetters, mapActions } from 'vuex'
-
-    import { FormWizard, TabContent } from 'vue-form-wizard'
-    import 'vue-form-wizard/dist/vue-form-wizard.min.css'
-
-    import SupplierStep from '@/components/steps/SupplierStep'
-    import ProductStep from '@/components/steps/ProductStep'
-    import PaymentStep from '@/components/steps/PaymentStep'
-
-    import { LoadingOverlay } from '@/components/common'
-
-    export default {
-        components: {
-            FormWizard,
-            TabContent,
-            SupplierStep,
-            ProductStep,
-            PaymentStep,
-            LoadingOverlay
+            WizardButton,
+            StatementStep,
+            StatementDestStep,
+            StatementOperationStep,
+            StatementConfirmStep,
+            StatementModify,
         },
         computed: mapGetters([
-            'isLoading',
-            'isCompleted',
-            'isProcessing',
-            'state',
-            'mode'
+            'isTransfer',           // Transfer
+            'isInputCashbox',       // Input
+            'isOutputCashbox',      // Output
+            'isStatmentConfirm',    // codnfirm
+
+            'selectedActions',
+            'selectedStatement',
+            'selectedStatementDest',
         ]),
         methods: {
+            goNext() {
+                this.$refs.wizard.nextTab()
+                // if (this.$refs.wizard.activeTabIndex >= 1) {
+                //     this.changeInitialPayment(this.initialPayment)
+                // }
+            },
+            goBack() {
+                // if (this.$refs.wizard.activeTabIndex === 1 ) {
+                // this.resetStoreModules(this.$refs.wizard.activeTabIndex)
+                // }
+                this.$refs.wizard.prevTab()
+            },
+            // actionSelected() {
+                // this.stepChange(0, 1)
+            // },
+            /*
+            stepChange(prev, next) {
+                console.log(prev);
+                console.log(next);
+                // if ((this.$refs.wizard.maxStep === 0) && (this.$refs.wizard.maxStep === this.$refs.wizard.activeTabIndex)){
+                //     this.goNext()
+                //     return false
+                //}
+            },
+            */
             ...mapActions([
-                'initPurchase',
-                'checkSupplier',
-                'checkCart',
-                'checkAmountReceived',
-                'createPurchase',
-                'resetPurchase'
+                'initProcessBank',
+                'endProcess',
+                'checkStatement',
+                'checkStatementDest',
+                'resetStoreModules',
             ])
         },
         watch: {
@@ -165,13 +138,12 @@
                 if (!value) {
                     return
                 }
-
                 this.$refs.wizard.changeTab(2, 0, false)
-                this.resetPurchase()
+        //         this.resetPurchase()
             }
         },
         mounted() {
-            this.initPurchase(this.$root.mode)
+            this.initProcessBank(this.$root.mode)
         }
     }
 </script>
@@ -179,7 +151,7 @@
 <style lang="sass">
     @import './assets/variables'
 
-    .purchases
+    .statement
         width: 100%
         height: 100%
         position: absolute
@@ -206,7 +178,7 @@
                         width: calc(100% - 20px)
                         height: calc(100% - 20px)
                         margin: 10px
-                        .purchase-step
+                        .statement-step
                             width: 100%
                             height: 100%
                             background: $app-bg-color
@@ -214,13 +186,17 @@
                 width: 100%
                 height: 50px
                 position: absolute
-                bottom: 10px
-                .wizard-btn
-                    width: 160px
-                    height: 40px
-                    border-radius: 0
-                    box-shadow: none
-                    border: none
-                    &:hover, &:focus
-                        background: $app-main-color
-</style> -->
+                bottom: 0
+                text-align: center
+                box-shadow: 2px 0px 5px rgba(0, 0, 0, 0.26)
+                .wizard-footer-left, .wizard-footer-right
+                    margin-top: 3px
+                    .wizard-btn
+                        width: 160px
+                        height: 40px
+                        border-radius: 0
+                        box-shadow: none
+                        border: none
+                        &:hover, &:focus
+                            background: $app-main-color
+</style>

+ 3 - 3
src/components/common/AddCard.vue

@@ -17,8 +17,8 @@
     @import '../../assets/variables'
 
     .add-card
-        width: 130px
-        height: 160px
+        width: 180px
+        height: 130px
         margin: 5px
         border: 1px solid $app-border-color
         display: inline-block
@@ -35,4 +35,4 @@
             margin-right: -50%
             transform: translate(-50%, -50%)
             color: $app-main-color
-</style>
+</style>

+ 37 - 14
src/components/common/Card.vue

@@ -1,6 +1,10 @@
 <template lang="pug">
-    .card(@click='onClick' :class="{ 'selected-card': isSelected }")
-        h2.card-title {{ title }}
+    .card(
+        :class="{ 'selected-card': isSelected }"
+        @click='onClick'
+    )
+        .card-title
+            h2.card-title-item(v-for='t in getTitle()') {{ t }}
         img.card-image(:src="'data:image/png;base64,' + (image || 'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAAAAACPAi4CAAAACXZwQWcAAABAAAAAQADq8/hgAAAEWklEQVRYw9WX6XKjRhCAef8HiySQvGt5vfZuEselOUAcEpe4GdI9MAgQOjb5k3SVyzY1801PX9OtNf9StP80QJR5miRpXtb/AFCnvmMySgmhlJn2Mal+BSBSj1NCGeNSGAMOd0/iQYCI95TAXnm+FCr/I2ZYPwJILEJhPaGm7flBFIW+Z5sUvwEivguovG7pMR0cV2e+BbYArF3cBqQclKfEvryvSB2KaHa6BYhgDSP7ZN7gmUNQCf86wCdgcBaKq04/cTzAuwbA/czKb8VdZYMSI8IAEOJ+XjTiFkF4SDjOARIIHLiBK+4E/xHOIdEloMSAAwZx7hEOBKIquwA4lFPbR/3uEhzCqSUmgBiwrGgeIlQm5b0zO0CN3yKw34QgQC4JKZqrGAFC0MpWvuwJ3V6hWD3BI5wchoDaBAumzYQgmsrd7ewZx5bosHIAAAtQp4+nXUuA+2yXy9Xyi4OsIorjauBLZQWtd0Gqrt3EvCXQlb4BMZYfsPP7cr0gvS4FaNw6Qus0ovtez8DZcYyHt8Wmk9XWdF+Mjf570Ke4q46UgAgUCtX55mKl/wSbsD83hrEE0VGJ1RrEWHz2aaXuIAEe7b3SNG/601oSzL/W20/T2r2uDNACARvjWelZQTTaCiCg2vSR1bzrsFgSQMk8SbPi8FWX+0GFbX2OXMarDoAmOGfo+wpXt7cwj4Hv+1n+rSMYW3HOfS4TAgHZIDIVYG38wNzchyB+kj4ZUwB4npw6ABokmgA2qz9kfbIkoWDLzQSQ0tbw2gA20kA/nmyqCHG8nmqQd2prbSKQZAIwnk5B5PSE/EWfACCUZGFSgHQKeE6DsCcExfc5wKEDRLMaJHBwTwA/zFzhOLBBPGODoCfEyYUb0XVBB1AGHXvho/SVDsSjF15QrtMG1xlpsDbCrCewj7UxAWAJSjsAlJOuHI0AX9Mi8IMgsJnMC2MMOJA2f7RhXI8AG/2LVxZZVlQWmKElnAFiT5nMH62L67Mb3lTmbIzVK3Uc9r6GvJAEyMa6d0KXP1oXliqbRPPzN0NvBcrBAmSpr37wlrB8GeRS6zkJECZVNRKeuLfty1C+wc/zp7TD9jVQN7DUDq2vkUEzfAymIl9uZ5iL1B0U1Rw7surmc4SE/sUBE3KaDB8Wd1QS7hJQga4Kayow2aAsXiV0L458HE/jx9UbPi33CIf+ITwDSnxM/IcIcAGIrHzaH+BX8Ky4awdq41nBZYsjG4/kEQLjg9Q5A9A1jJ7u3CJEa1OzmuvSKgubwPA24IT7WT7fJ5YmEtwbASWO2AkP94871WpPOCc8vmYHaORhv5lf75VrV3bD+9nZIrUJamhXN9v9kMlu3wonYVlGe9msU1/cGTgKpx0YmO2fsrKq66rMk8Bh7dd99sDIk+xxxsE5icqhqfsLflkz1pkbukSCBzI5bqG0EGrPGvfK2FeGDseRi1I5eVFuB8WvDp51FvsH13Fcz4+y6n86Oz8kfwPMD02INEiadQAAAABJRU5ErkJggg==')")
         .card-details(v-if='details.length > 0')
             span(v-for='detail in details') {{ computeDetail(detail) }}
@@ -10,7 +14,7 @@
     export default {
         props: {
             title: {
-                type: String,
+                type: String || Array,
                 default: 'Sin título'
             },
             image: {
@@ -25,15 +29,28 @@
                 type: Boolean,
                 default: true
             },
-            options: {
+            currencyOptions: {
                 type: Object,
-                default: {}
+                default: {
+                    symbol: '$',
+                    position: 'before',
+                    thousandsSeparator: '.',
+                    decimalPlaces: 2,
+                    decimalSeparator: ','
+                }
             }
         },
         methods: {
+            getTitle() {
+                if (typeof this.title === 'string') {
+                    return [this.title]
+                }
+
+                return this.title
+            },
             computeDetail(detail) {
                 if (detail.format === 'currency') {
-                    return this.$options.filters.currency(detail.value, {...this.options})
+                    return this.$options.filters.currency(detail.value, {...this.currencyOptions})
                 }
 
                 return detail.value
@@ -41,7 +58,7 @@
             onClick() {
                 this.$emit('onClick')
             }
-        } 
+        }
     }
 </script>
 
@@ -63,17 +80,23 @@
             cursor: pointer
         .card-title
             width: 100%
-            height: 30px
-            font-size: 9pt
-            text-align: center
-            margin-top: 10px
+            height: 60px
             position: absolute
             top: 0
+            z-index: 1
+            .card-title-item
+                font-size: 8pt
+                text-align: center
+                margin-top: 10px
+                margin-bottom: 0
+                &:nth-child(2n)
+                    margin-top: 5px
         .card-image
-            width: 80px
-            height: 80px;
+            width: 75px
+            height: 75px
             margin: 0
-            border: none
+            // border: none
+            border-radius: 50%
             position: absolute
             top: 50%
             left: 50%

+ 111 - 17
src/components/common/CardGrid.vue

@@ -1,15 +1,36 @@
 <template lang="pug">
     .card-grid-wrapper
         .card-grid
-            add-card(v-if='canAdd' @onClickAdd='onClickAdd')
-            card(v-for='item in items' :key='item.id' :title='item.name' :image='item.imageMedium' :isSelected='item.id === selectedId' :details='computeDetails(item)' :options='defaultOptions.currency' @onClick='onClickCard(item)')
+            add-card(
+                v-if='canAdd'
+                @onClickAdd='onClickAdd'
+            )
+            //- transition-group(
+            //-     name='card-fade'
+            //-     v-bind:css='false'
+            //-     v-on:before-enter='onBeforeEnter'
+            //-     v-on:enter='onEnter'
+            //-     v-on:leave='onLeaver'
+            //- )
+            card(
+                v-for='item in items'
+                :key='item.id'
+                :title='getHeader(item)'
+                :image='getImage(item)'
+                :isSelected='item.id === selectedId'
+                :details='getFooter(item)'
+                :currencyOptions='currencyOptions'
+                @onClick='onClickCard(item)'
+            )
         .no-items(v-show='!items || items.length == 0')
             p No hay items
 </template>
 
 <script>
+    import Velocity from 'velocity-animate'
     import AddCard from '@/components/common/AddCard'
     import Card from '@/components/common/Card'
+    import Spinner from '@/components/common/Spinner'
 
     export default {
         props: {
@@ -21,22 +42,33 @@
                 type: Boolean,
                 default: false
             },
-            details: {
+            headerKeys: {
                 type: Array,
                 default: []
             },
-            loading: {
-                type: Boolean,
-                default: false
+            imageKey: {
+                type: String,
+                default: null
+            },
+            footerKeys: {
+                type: Array,
+                default: []
             },
-            options: {
+            currencyOptions: {
                 type: Object,
-                default: {}
+                default: {
+                    symbol: '$',
+                    position: 'before',
+                    thousandsSeparator: '.',
+                    decimalPlaces: 2,
+                    decimalSeparator: ','
+                }
             }
         },
         components: {
             AddCard,
-            Card
+            Card,
+            Spinner
         },
         watch: {
             options(value) {
@@ -44,17 +76,45 @@
             }
         },
         methods: {
-            computeDetails(item) {
-                if (!this.details) {
+            getHeader(item) {
+                if (this.headerKeys.length == 0) {
+                    return item.name
+                }
+
+                return this.headerKeys.map(key => {
+                    let value = item
+
+                    for (let k of key.split('.')) {
+                        value = value[k]
+                    }
+                    console.log(item)
+                    return value
+                })
+            },
+            getImage(item) {
+                if (!this.imageKey) {
+                    return item.image
+                }
+
+                let image = item
+
+                for (let part of this.imageKey.split('.')) {
+                    image = image[part]
+                }
+
+                return image
+            },
+            getFooter(item) {
+                if (!this.footerKeys) {
                     return []
                 }
 
-                if (this.details.length === 0) {
+                if (this.footerKeys.length === 0) {
                     return []
                 }
 
                 let results = []
-                let computableDetails = this.details.map(item => item.split(/:/))
+                let computableDetails = this.footerKeys.map(item => item.split(/:/))
 
                 for (let detail of computableDetails) {
                     for (let field in item) {
@@ -65,7 +125,7 @@
                                     if (!detail[1] || detail[1] === 's') {
                                         return 'string'
                                     }
-                                    
+
                                     if (detail[1] === 'c') {
                                         return 'currency'
                                     }
@@ -98,6 +158,34 @@
                     this.defaultOptions.currency[key] = value[key]
                 }
             },
+            onBeforeEnter(el) {
+                el.style.opacity = 0
+                el.style.width = 0
+            },
+            onEnter(el, done) {
+                let delay = el.dataset.index * 150
+
+                setTimeout(() => {
+                    Velocity(el, {
+                        opacity: 1,
+                        width: '130px'
+                    }, {
+                        complete: done
+                    })
+                }, delay)
+            },
+            onLeave(el, done) {
+                let delay = el.dataset.index * 150
+
+                setTimeout(() => {
+                    Velocity(el, {
+                        opacity: 0,
+                        width: 0
+                    }, {
+                        complete: done
+                    })
+                }, delay)
+            },
             onClickAdd() {
                 this.$emit('onAdd')
             },
@@ -115,9 +203,9 @@
                         position: 'before',
                         thousandsSeparator: '.',
                         decimalPlaces: 2,
-                        decimalSeparator: ',' 
+                        decimalSeparator: ','
                     },
-                } 
+                }
             }
         }
     }
@@ -137,6 +225,12 @@
         &::-webkit-scrollbar-track
             -webkit-box-shadow: inset 0 0 6px #d3d3d3
             background: #f5f5f5
+        .card-grid-loading
+            width: 100%
+            height: 100%
+            display: flex
+            align-items: center
+            justify-content: center
         .card-grid
             width: 100%
         .no-items
@@ -148,4 +242,4 @@
             p
                 color: #9e9e9e
                 font-size: 11pt
-</style>
+</style>

+ 166 - 0
src/components/common/CardGridStatement.vue

@@ -0,0 +1,166 @@
+<template lang="pug">
+    .card-grid-wrapper-statement
+        .card-grid
+            add-card(
+                v-if='canAdd'
+                @onClickAdd='onClickAdd'
+            )
+            card(
+                v-for='item in items'
+                :key='item.id'
+                :title='item.name'
+                :date='item.date'
+                :journalName='item.journal.displayName'
+                :typeStatement='item.typeStatement.name'
+                :countLine='item.line.length'
+                :state='item.state'
+                :isSelected='item.id === selectedId'
+                :details='computeDetails(item)'
+                :options='item.currency'
+                @onClick='onClickCard(item)'
+            )
+        .no-items(v-show='!items || items.length == 0')
+            p No hay items
+</template>
+
+<script>
+    import AddCard from '@/components/common/AddCard'
+    import Card from '@/components/common/CardStatement'
+
+    export default {
+        props: {
+            items: {
+                type: Array,
+                default: []
+            },
+            canAdd: {
+                type: Boolean,
+                default: false
+            },
+            details: {
+                type: Array,
+                default: []
+            },
+            loading: {
+                type: Boolean,
+                default: false
+            },
+            options: {
+                type: Object,
+                default: {}
+            }
+        },
+        components: {
+            AddCard,
+            Card
+        },
+        watch: {
+            options(value) {
+                this.computeOptions(value)
+            }
+        },
+        methods: {
+            computeDetails(item) {
+                if (!this.details) {
+                    return []
+                }
+
+                if (this.details.length === 0) {
+                    return []
+                }
+
+                let results = []
+                let computableDetails = this.details.map(item => item.split(/:/))
+
+                for (let detail of computableDetails) {
+                    for (let field in item) {
+                        if (field === detail[0]) {
+                            results.push({
+                                value: item[field],
+                                format: (() => {
+                                    if (!detail[1] || detail[1] === 's') {
+                                        return 'string'
+                                    }
+
+                                    if (detail[1] === 'c') {
+                                        return 'currency'
+                                    }
+
+                                    if (detail[1] === 'd') {
+                                        return 'date'
+                                    }
+
+                                    return 'string'
+                                })()
+                            })
+
+                            break
+                        }
+                    }
+                }
+                return results
+            },
+            computeOptions(value) {
+                if (!value) {
+                    return
+                }
+
+                for(let key in value) {
+                    if(!this.defaultOptions.currency[key]) {
+                        continue
+                    }
+
+                    this.defaultOptions.currency[key] = value[key]
+                }
+            },
+            onClickAdd() {
+                this.$emit('onAdd')
+            },
+            onClickCard(item) {
+                this.selectedId = item.id
+                this.$emit('onSelect', item)
+            }
+        },
+        data() {
+            return {
+                selectedId: -1,
+                defaultOptions: {
+                    currency: {
+                        symbol: '$',
+                        position: 'before',
+                        thousandsSeparator: '.',
+                        decimalPlaces: 2,
+                        decimalSeparator: ','
+                    },
+                }
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    .card-grid-wrapper-statement
+        width: 100%
+        height: calc(100% - 50px)
+        margin-top: 10px
+        overflow-y: auto
+        &::-webkit-scrollbar
+            width: 2px
+            background: #f5f5f5
+        &::-webkit-scrollbar-thumb
+            background: #7c7bad
+        &::-webkit-scrollbar-track
+            -webkit-box-shadow: inset 0 0 6px #d3d3d3
+            background: #f5f5f5
+        .card-grid
+            width: 100%
+        .no-items
+            width: 100%
+            height: 100%
+            display: flex
+            align-items: center
+            justify-content: center
+            p
+                color: #9e9e9e
+                font-size: 11pt
+</style>

+ 165 - 0
src/components/common/CardStatement.vue

@@ -0,0 +1,165 @@
+<template lang="pug">
+    .card-statement(
+        @click='onClick'
+        :class="{ 'selected-card': isSelected }"
+    )
+        .card-date {{ date }}
+        .card-title {{ title }}
+        .card-journal {{ journalName }}
+        .card-type {{ typeStatement }}
+        .card-count-intem Lineas({{ countLine}})
+        .card-amount(:class="{'statement-confirm': !!(state === 'confirm')}")
+            span(v-for='detail in details') {{ computeDetail(detail) }}
+</template>
+
+<script>
+    export default {
+        props: {
+            title: {
+                type: String,
+                default: 'Sin título'
+            },
+            date: {
+                type: Date,
+                default: ''
+            },
+            state: {
+                type: String,
+                default:'open'
+            },
+            journalName: {
+                type: String,
+                default: ''
+            },
+            typeStatement: {
+                type: String,
+                default: ''
+            },
+            countLine: {
+                type: String,
+                default: 0
+            },
+            details: {
+                type: Array,
+                default: []
+            },
+            isSelected: {
+                type: Boolean,
+                default: true
+            },
+            options: {
+                type: Object,
+                default: {}
+            }
+        },
+        methods: {
+            computeDetail(detail) {
+                if (detail.format === 'currency') {
+                    return this.$options.filters.currency(detail.value, {...this.options})
+                }
+
+                return detail.value
+            },
+            onClick() {
+                this.$emit('onClick')
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .card-statement
+        width: 180px
+        height: 130px
+        margin: 5px
+        border: 1px solid $app-border-color
+        display: inline-block
+        position: relative
+        &.selected-card
+            transition-duration: 300ms
+            border: 2px solid $app-main-color
+        &:hover
+            cursor: pointer
+        .card-date
+            width: 100%
+            height: 30px
+            position: absolute
+            font-size: 9pt
+            margin-top: 10px
+            padding-right: 10px
+            text-align: right
+            font-weight: normal
+            top: 0
+
+        .card-title
+            width: 100%
+            height: 30px
+            position: absolute
+            font-size: 9pt
+            font-weight: bold
+            margin-top: 30px
+            text-align: center
+            padding-right: 5px
+            padding-left: 5px
+            top: 0
+
+        .card-journal
+            width: 100%
+            height: 30px
+            position: absolute
+            margin-top: 50px
+            font-size: 9pt
+            float: right
+            padding-right: 5px
+            padding-left: 5px
+            text-align: center
+            font-weight: normal
+            top: 0
+
+        .card-type
+            width: 50%
+            height: 30px
+            margin-top: 70px
+            font-size: 9pt
+            float: left
+            padding-left: 5px
+            text-align: center
+            font-weight: normal
+            top: 0
+
+        .card-count-intem
+            width: 50%
+            height: 30px
+            margin-top: 70px
+            font-size: 9pt
+            text-align: center
+            float: right
+            padding-right: 5px
+            font-weight: normal
+            top: 0
+
+        .card-amount
+            width: 100%
+            height: 30px
+            padding-top: 5px
+            text-align: center
+            font-weight: bold
+            font-size: 10pt
+            position: absolute
+            background: $app-main-color
+            color: $app-bg-color
+            margin-bottom: 0px
+            bottom: 0
+        .statement-confirm
+            background: #ccc
+
+        @keyframes card-bubble
+            30%
+                transform: scaleX(0.75) scaleY(1.25)
+            40%
+                transform: scaleX(1.25) scaleY(0.75)
+            60%
+                transform: scaleX(0.85) scaleY(1.15)
+</style>

+ 8 - 4
src/components/common/InputDropdown.vue

@@ -57,6 +57,10 @@
             options: {
                 type: Array,
                 default: []
+            },
+            currency: {
+                type: Array,
+                default: []
             }
         },
         computed: {
@@ -65,7 +69,7 @@
                     let value = this.value
 
                     if (this.format === 'number') {
-                        value = this.formatValue(value)
+                        value = this.formatValue(value, this.currency)
                         value = !!this.value ? value : value.replace(/\d/, '')
                         value = value.length === 0 ? 0 : value
                     }
@@ -143,7 +147,7 @@
                 if (!this.hasOptions()) {
                     return
                 }
-                
+
                 this.isShowOptions = !this.isShowOptions
             },
             onClickOutside(e) {
@@ -160,7 +164,7 @@
                 }
 
                 let el = this.$refs.suffixDropdown
-                
+
                 if (el !== target && !el.contains(target)) {
                     this.hideOptions()
                 }
@@ -276,4 +280,4 @@
                     &:hover, &:focus
                         text-decoration: none
                         border-bottom: 2px solid #7c7bad
-</style>
+</style>

+ 3 - 1
src/components/common/index.js

@@ -8,9 +8,11 @@ import Searcher from './Searcher'
 import Spinner from './Spinner'
 import SwitchButtonInput from './SwitchButtonInput'
 import Ticket from './Ticket'
+import CardGridStatement from './CardGridStatement'
 
 export {
     CardGrid,
+    CardGridStatement,
     Cart,
     DropdownSearcher,
     InputDropdown,
@@ -20,4 +22,4 @@ export {
     Spinner,
     SwitchButtonInput,
     Ticket
-}
+}

+ 9 - 0
src/components/filters/absolute.js

@@ -0,0 +1,9 @@
+/**
+ * 
+ * @param {*} value 
+ */
+const absolute = (value = 0) => {
+    return Math.abs(value)
+}
+
+export default absolute

+ 40 - 0
src/components/filters/currency.js

@@ -0,0 +1,40 @@
+/**
+ * 
+ */
+const currency = (value = 0, options = {}) => {
+    value = value.toString()
+
+    if (!(options instanceof Object)) {
+        options = {}
+    }
+
+    options.symbol = options.symbol || '$'
+    options.position = options.position || 'before'
+    options.thousandsSeparator = options.thousandsSeparator || '.'
+    options.decimalPlaces = options.decimalPlaces >= 0 || options.decimalPlaces <= 2 ? options.decimalPlaces : 2
+    options.decimalSeparator = options.decimalSeparator || ','
+    options.decimalZeros = !!options.decimalZeros
+
+    if (!!(`${options.thousandsSeparator}${options.decimalSeparator}`).replace(/\.,|,\./g, '')) {
+        throw new Error('Same thousands and decimal separator is not allowed')
+    }
+
+    value = value.split('.')
+
+    value[0] = value[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, `$1${options.thousandsSeparator}`)
+
+    if (!!value[1]) {
+        value[1] = Number.parseFloat(`1.${value[1]}e${options.decimalPlaces}`)
+        value[1] = Math.round(value[1]).toString().replace(/^1/, '')
+    }
+
+    value = value.join(options.decimalSeparator)
+
+    if (!options.decimalZeros) {
+        value = value.replace(/([\.|,]\d)0$/, '$1')
+    }
+
+    return options.position === 'before' ? `${options.symbol} ${value}` : `${value} ${options.symbol}`
+}
+
+export default currency

+ 89 - 0
src/components/forms/CardOperationDetails.vue

@@ -0,0 +1,89 @@
+<template lang="pug">
+    .form-card-operation
+        .form-item-satement
+            h3.statement-label Caja
+            h3.statement-item {{ nameStatement }}
+        .form-item-satement
+            h3.statement-label Responsable
+            h3.statement-item {{ userStatement }}
+        .form-item-satement
+            h3.statement-label Tipo de Caja
+            h3.statement-item {{ typeStatement }}
+        h3.statement-item-amount {{ computeDetail(amountStatement) }}
+</template>
+
+<script>
+    export default {
+        props: {
+            nameStatement: {
+                type: String,
+                default: ''
+            },
+            userStatement: {
+                type: String,
+                default: ''
+            },
+            typeStatement: {
+                type: String,
+                default: ''
+            },
+            amountStatement: {
+                type: String,
+                default: 0
+            },
+            currency: {
+                string: Object,
+                default: {}
+            }
+        },
+        methods: {
+            computeDetail(amount) {
+                return this.$options.filters.currency(amount, {...this.currency})
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .form-card-operation
+        width: 100%
+        height: 110px
+        margin: 5px
+        border: 1px solid $app-border-color
+        display: inline-block
+        position: relative
+        .form-item-satement
+            width: 100%
+            height: 25px
+            .statement-label
+                width: 150px
+                font-size: 10pt
+                padding-top: 5px
+                padding-left: 10px
+                color: $app-border-color
+                margin-top: 0px
+                margin-bottom: 1px
+                display: inline-block
+            .statement-item
+                width: calc(100% - 150px)
+                padding-top: 5px
+                padding-left: 10px
+                font-size: 10pt
+                margin-top: 0px
+                margin-bottom: 1px
+                float: right
+        .statement-item-amount
+            width: 100%
+            height: 30px
+            padding-top: 5px
+            text-align: center
+            font-weight: bold
+            font-size: 10pt
+            position: absolute
+            background: $app-main-color
+            color: $app-bg-color
+            margin-bottom: 0px
+            bottom: 0
+</style>

+ 69 - 0
src/components/forms/OperationDetails.vue

@@ -0,0 +1,69 @@
+<template lang="pug">
+    .form-operation-details
+        .form-details
+            h3.details-title {{ operationTitle }}
+            hr
+        .form-details(v-if='!!statementOrigin')
+            h3.details-title Origin
+            CardOperationDetails(
+                :nameStatement='statementOrigin.name'
+                :userStatement='statementOrigin.user.name'
+                :typeStatement='statementOrigin.typeStatement.name'
+                :amountStatement='statementOrigin.balanceEnd'
+                :currency='statementOrigin.currency'
+            )
+        .form-details(v-if='!!statementDest')
+            h3.details-title Destino
+            CardOperationDetails(
+                :nameStatement='statementDest.name'
+                :userStatement='statementDest.user.name'
+                :typeStatement='statementDest.typeStatement.name'
+                :amountStatement='statementDest.balanceEnd'
+                :currency='statementDest.currency'
+            )
+</template>
+
+<script>
+
+    import CardOperationDetails from '@/components/forms/CardOperationDetails'
+
+    export default {
+        props: {
+            operationTitle: {
+                type: String,
+                default: ''
+            },
+            statementOrigin: {
+                type: Object,
+                default: {}
+            },
+            statementDest: {
+                type: Object,
+                default: {}
+            }
+        },
+        components: {
+            CardOperationDetails
+        },
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .form-operation-details
+        width: 500px
+        height: 100%
+        margin-right: 50px
+        padding: 15px 35px
+        border: 1px solid$app-border-color
+        .form-details
+            width: 100%
+            .details-title
+                font-size: 13pt
+                margin: 10px 0 0
+                color: $app-dark-color
+                text-align: center
+            hr
+                color: $app-border-color
+</style>

+ 42 - 16
src/components/forms/StatementActionForm.vue

@@ -4,26 +4,50 @@
             h2 Acciones disponibles
             hr
             from.from-display
-                .form-separator
+                //-.form-separator
                     h3 Seleccione una opción
-                .form-item
-                    button.form-action Modificar
-                .form-item
-                    button.form-action Crear transferencia
-                .form-item
-                    button.form-action Poner dinero
-                .form-item
-                    button.form-action Sacar dinero
-                .form-item
-                    button.form-action  Procesar Cierre
-                .form-item
-                    button.form-action  Eliminar caja
-                .form-item
-                    button.form-action  Reabrir Caja
+                //- .form-item
+                    //- button.form-action Modificar
+                .form-item( v-if='!!actionTransfer')
+                    button.form-action(@click.prevent='clcikTransfer') Crear transferencia
+                .form-item(v-if ='!!actionInputCashbox')
+                    button.form-action(@click.prevent='clickInputCashbox' @actionSelected='actionSelected') Poner dinero
+                .form-item(v-if='!!actionOutputCashbox')
+                    button.form-action(@click.prevent='clickOutputCashbox' @actionSelected='actionSelected') Sacar dinero
+                .form-item(v-if='!!actionStatementConfirm')
+                    button.form-action(@click.prevent='clcikConfig' @actionSelected='actionSelected')  Procesar Cierre
+                //- .form-item
+                //-     button.form-action  Eliminar caja
+                //- .form-item
+                //-     button.form-action  Reabrir Caja
+        //-
 </template>
 
 <script>
+    import { mapGetters, mapActions } from 'vuex'
+
     export default {
+        methods: {
+            // clickTransfer(){
+            //     console.log("Click");
+            //     // this.$emit('actionSelected')
+            //     this.clcikTransfer(true)
+            // },
+            ...mapActions([
+                'clcikTransfer',
+                'clickInputCashbox',
+                'clickOutputCashbox',
+                'clcikConfig',
+            ])
+        },
+        computed: {
+            ...mapGetters([
+                'actionTransfer',
+                'actionInputCashbox',
+                'actionOutputCashbox',
+                'actionStatementConfirm'
+            ])
+        }
     }
 </script>
 
@@ -31,7 +55,7 @@
     @import '../../assets/variables'
 
     .statement-action
-        width: 250px
+        width: 230px
         height: 100%
         .form-header
             h2
@@ -51,6 +75,8 @@
                 .form-item
                     width: 100%
                     margin-bottom: 15px
+                    padding-left: 5px
+                    padding-right: 5px
                     .form-action
                         width: 100%
                         height: 40px

+ 242 - 0
src/components/modal/BankStatementModal.vue

@@ -0,0 +1,242 @@
+<template lang="pug">
+    modal(
+        name='statement-modal',
+        transition='nice-modal-fade'
+        :classes="['v--modal', 'statement-modal']"
+        adaptive='true'
+        width='800px'
+        height='auto'
+        @before-close='beforeClose'
+    )
+        form-wizard(
+            title="Crear nueva caja"
+            subtitle=""
+            color="#7c7bab"
+            ref="wizard"
+        )
+            tab-content( title="Seleccione el método de pago")
+                card-grid(
+                    :items='journals'
+                    @onSelect='selectStatementJournal'
+                )
+            tab-content(title="Seleccione el tipo de caja")
+                card-grid(
+                    :items='statementType'
+                    @onSelect='selectTypestatement'
+                )
+            tab-content(title="Seleccione el responsable")
+                card-grid(
+                    :items='users'
+                    @onSelect='selectUserStatement'
+                )
+            tab-content( title="Seleccione la fecha")
+                form.statement-modal-form
+                    .statement-details-form
+                        label.form-label Fecha de apertura
+                        date-picker.form-input(
+                            input-class="form-input"
+                            lang="es"
+                            format="DD/MM/YYYY"
+                            editable='false'
+                            v-model="date"
+                        )
+                    .statement-details-form
+                        label.form-label Método de pago
+                        input.form-input(readonly='readonly' v-model='journalName')
+                    .statement-details-form
+                        label.form-label Tipo de caja
+                        input.form-input(readonly='readonly' v-model='typeName')
+                    .statement-details-form
+                        label.form-label Responsable
+                        input.form-input(readonly='readonly' v-model='userName')
+            template( slot='footer' slot-scope='props' )
+                div(class='wizard-footer-left')
+                    wizard-button(
+                        v-if='props.activeTabIndex > 0'
+                        @click.native='props.prevTab()'
+                        :style='props.fillButtonStyle'
+                    ) Volver
+                    wizard-button(
+                        v-else
+                        @click.native='onCancel'
+                        :style='props.fillButtonStyle'
+                    ) Cancelar
+                div(class='wizard-footer-right')
+                    wizard-button(
+                        v-if='!props.isLastStep'
+                        class='wizard-footer-right'
+                        :style='props.fillButtonStyle'
+                        @click.native='goNext'
+                    ) Siguiente
+                    wizard-button(
+                        v-else
+                        class='wizard-footer-right finish-button'
+                        :style='props.fillButtonStyle'
+                        @click.native='onDone'
+                    ) {{ props.isLastStep ? 'Guardar' : 'Siguiente'}}
+</template>
+
+<script>
+    import { FormWizard, TabContent, WizardButton } from 'vue-form-wizard'
+    import DatePicker from 'vue2-datepicker'
+    import { CardGrid } from '../common'
+
+    export default {
+        props:{
+            title: {
+                type: String,
+                default: ''
+            },
+            show: {
+                type: Boolean,
+                default: false
+            },
+            journals: {
+                type: Array,
+                default: []
+            },
+            statementType: {
+                type: Array,
+                default: []
+            },
+            users: {
+                type: Array,
+                default: []
+            },
+            dateStatement: {
+                type: String,
+                default:''
+            },
+            journalName: {
+                type: String,
+                default: ''
+            },
+            typeName: {
+                type: String,
+                default: ''
+            },
+            userName: {
+                type: String,
+                default: ''
+            },
+        },
+        components: {
+            FormWizard,
+            TabContent,
+            WizardButton,
+            CardGrid,
+            DatePicker,
+        },
+        watch: {
+            show(value) {
+                if(!value){
+                    this.$modal.hide('statement-modal')
+                    return
+                }
+                this.$modal.show('statement-modal')
+            }
+        },
+        computed:{
+            date: {
+                get() {
+                    return this.dateStatement
+                },
+                set(value) {
+                    this.$emit('selectedDateStatement', !value ? moment().format('DD/MM/YYYY') :value)
+                }
+            },
+        },
+        methods: {
+            beforeClose(e) {
+                if (this.show) {
+                    e.stop()
+                }
+            },
+            selectStatementJournal(journal) {
+                this.$emit('onSelectStatementJournal', journal)
+                console.log(this.users);
+            },
+            selectTypestatement(type) {
+                this.$emit('onSelectStatementType', type)
+            },
+            selectUserStatement(user) {
+                this.$emit('onSetSelectUserStatement', user)
+            },
+            goNext () {
+                if (this.journalStepIncomplete()) {
+                    this.$emit('onNotify', "Necesitas seleccionar un método de pago para continuar")
+                    return
+                }
+                if (this.typeStepIncomplete()) {
+                    this.$emit('onNotify', "Necesitas seleccionar un tipo de caja para continuar")
+                    return
+                }
+                if (this.userStepIncomplete()) {
+                    this.$emit('onNotify', "Necesitas seleccionar un responsable de la caja")
+                    return
+                }
+                this.$refs.wizard.nextTab()
+            },
+            onCancel() {
+                this.$emit('onCancel')
+            },
+            onDone (){
+                if (this.dateStepIncomplete()) {
+                    this.$emit('onNotify', "Necesitas definir una fecha de apertura")
+                    return
+                }
+                this.$emit('onDone')
+            },
+
+            /*Validaciones */
+            journalStepIncomplete () {
+                return this.$refs.wizard.activeTabIndex === 0 && !this.journalName
+            },
+            typeStepIncomplete () {
+                return this.$refs.wizard.activeTabIndex === 1 && !this.typeName
+            },
+            userStepIncomplete () {
+                return this.$refs.wizard.activeTabIndex === 2 && !this.userName
+            },
+            dateStepIncomplete () {
+                return this.$refs.wizard.activeTabIndex === 3 && !this.dateStatement
+            },
+        },
+    }
+</script>
+
+<style lang="sass">
+
+    .statement-modal
+        padding: 0 !important
+        &::before
+            content: ''
+            display: block
+            position: absolute
+            background-size: cover
+            filter: blur(3px)
+            z-index: -1
+        .wizard-tab-content
+            padding-bottom: 50px !important
+            .wizard-tab-container
+                justify-content: center !important
+                align-items: center !important
+                .statement-modal-form
+                    width: 100%
+                    .statement-details-form
+                        width: 100%
+                        height: 45px
+                        margin-bottom: 20px
+                        .form-label
+                            width: 250px
+                            height: 45px
+                            font-size: 12pt
+                            text-align: right
+                            line-height: 40px
+                            padding-right: 15px
+                        .form-input
+                            width: 400px
+                            height: 45px
+                            font-size: 12pt
+                            color: #4c4c4c
+</style>

+ 247 - 0
src/components/steps/CardGridItem.vue

@@ -0,0 +1,247 @@
+<template lang="pug">
+    .card-grid-item
+        .card-grid-wrapper-header
+            card-item(
+                date='Fecha'
+                name='Comunicacion'
+                reference="Referencia"
+                partnerName="Socio"
+                amount="Importe"
+            )
+        .card-grid-wrapper-line
+            card-item(
+                v-for='item in items'
+                :date='item.date'
+                :name='item.name'
+                :reference='item.ref'
+                :partnerName= 'item.patner.displayName'
+                :amount='item.amount'
+            )
+</template>
+
+<script>
+    import CardItem from '@/components/steps/CardItem'
+
+    export default {
+        props: {
+            items: {
+                type: Array,
+                default: []
+            },
+        },
+        components: {
+            CardItem
+        },
+
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .card-grid-item
+        width: calc(100% - 10px)
+        height: calc(100% - 10px)
+        margin: 5px
+        text-align: center
+        .card-grid-wrapper-header
+            width: 100%
+            height: 36px
+            background: $app-border-color
+            // border-bottom: 1px solid$app-border-color
+        .card-grid-wrapper-line
+            width: 100%
+            height: calc(100% - 50px)
+            margin-top: 10px
+            overflow-y: auto
+            &::-webkit-scrollbar
+                width: 2px
+                background: #f5f5f5
+            &::-webkit-scrollbar-thumb
+                background: #7c7bad
+            &::-webkit-scrollbar-track
+                -webkit-box-shadow: inset 0 0 6px #d3d3d3
+                background: #f5f5f5
+            .card-grid
+                width: 100%
+            .no-items
+                width: 100%
+                height: 100%
+                display: flex
+                align-items: center
+                justify-content: center
+                p
+                    color: #9e9e9e
+                    font-size: 11pt
+</style>
+
+
+<!--
+<template lang="pug">
+    .card-grid-wrapper-statement
+        .card-grid
+            add-card(
+                v-if='canAdd'
+                @onClickAdd='onClickAdd'
+            )
+            card(
+                v-for='item in items'
+                :key='item.id'
+                :title='item.name'
+                :date='item.date'
+                :journalName='item.journal.displayName'
+                :typeStatement='item.typeStatement.name'
+                :countLine='item.line.length'
+                :state='item.state'
+                :isSelected='item.id === selectedId'
+                :details='computeDetails(item)'
+                :options='item.currency'
+                @onClick='onClickCard(item)'
+            )
+        .no-items(v-show='!items || items.length == 0')
+            p No hay items
+</template>
+
+<script>
+    import AddCard from '@/components/common/AddCard'
+    import Card from '@/components/common/CardStatement'
+
+    export default {
+        props: {
+            items: {
+                type: Array,
+                default: []
+            },
+            canAdd: {
+                type: Boolean,
+                default: false
+            },
+            details: {
+                type: Array,
+                default: []
+            },
+            loading: {
+                type: Boolean,
+                default: false
+            },
+            options: {
+                type: Object,
+                default: {}
+            }
+        },
+        components: {
+            AddCard,
+            Card
+        },
+        watch: {
+            options(value) {
+                this.computeOptions(value)
+            }
+        },
+        methods: {
+            computeDetails(item) {
+                if (!this.details) {
+                    return []
+                }
+
+                if (this.details.length === 0) {
+                    return []
+                }
+
+                let results = []
+                let computableDetails = this.details.map(item => item.split(/:/))
+
+                for (let detail of computableDetails) {
+                    for (let field in item) {
+                        if (field === detail[0]) {
+                            results.push({
+                                value: item[field],
+                                format: (() => {
+                                    if (!detail[1] || detail[1] === 's') {
+                                        return 'string'
+                                    }
+
+                                    if (detail[1] === 'c') {
+                                        return 'currency'
+                                    }
+
+                                    if (detail[1] === 'd') {
+                                        return 'date'
+                                    }
+
+                                    return 'string'
+                                })()
+                            })
+
+                            break
+                        }
+                    }
+                }
+                return results
+            },
+            computeOptions(value) {
+                if (!value) {
+                    return
+                }
+
+                for(let key in value) {
+                    if(!this.defaultOptions.currency[key]) {
+                        continue
+                    }
+
+                    this.defaultOptions.currency[key] = value[key]
+                }
+            },
+            onClickAdd() {
+                this.$emit('onAdd')
+            },
+            onClickCard(item) {
+                this.selectedId = item.id
+                this.$emit('onSelect', item)
+            }
+        },
+        data() {
+            return {
+                selectedId: -1,
+                defaultOptions: {
+                    currency: {
+                        symbol: '$',
+                        position: 'before',
+                        thousandsSeparator: '.',
+                        decimalPlaces: 2,
+                        decimalSeparator: ','
+                    },
+                }
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    .card-grid-wrapper-statement
+        width: 100%
+        height: calc(100% - 50px)
+        margin-top: 10px
+        overflow-y: auto
+        &::-webkit-scrollbar
+            width: 2px
+            background: #f5f5f5
+        &::-webkit-scrollbar-thumb
+            background: #7c7bad
+        &::-webkit-scrollbar-track
+            -webkit-box-shadow: inset 0 0 6px #d3d3d3
+            background: #f5f5f5
+        .card-grid
+            width: 100%
+        .no-items
+            width: 100%
+            height: 100%
+            display: flex
+            align-items: center
+            justify-content: center
+            p
+                color: #9e9e9e
+                font-size: 11pt
+</style>
+
+-->

+ 279 - 0
src/components/steps/CardItem.vue

@@ -0,0 +1,279 @@
+<template lang="pug">
+    .card-line-statement
+        label.item-date {{ date }}
+        label.item-name {{ name }}
+        label.item-ref {{ reference }}
+        label.item-partner {{ partnerName }}
+        label.item-amount {{ amount }}
+</template>
+
+<script>
+    import DatePicker from 'vue2-datepicker'
+
+    export default {
+        props:{
+            date: {
+                type: String,
+                default: ''
+            },
+            name: {
+                type: String,
+                default: ''
+            },
+            reference: {
+                type: String,
+                default: ''
+            },
+            partnerName: {
+                type: String,
+                default: ''
+            },
+            amount: {
+                type: String,
+                default: ''
+            },
+        },
+        components: {
+            DatePicker,
+        },
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .card-line-statement
+        width: 100%
+        height: 35px
+        // margin: 5px
+        // border: 1px solid $app-border-color
+        display: inline-block
+        position: relative
+        // background: cyan
+        // &.selected-card
+        //     transition-duration: 300ms
+        //     border: 2px solid $app-main-color
+        &:hover
+            cursor: pointer
+        .item-date
+            width: 100px
+            height: 100%
+            border: 1px solid$app-border-color
+            display: inline-block
+            float: left
+            padding-left: 10px
+            padding-top: 8px
+            margin-right: 5px
+            // background: cyan
+        .item-name
+            width: 250px
+            height: 100%
+            border: 1px solid$app-border-color
+            display: inline-block
+            float: left
+            padding-left: 10px
+            padding-top: 8px
+            margin-right: 5px
+
+            // background: cyan
+        .item-ref
+            width: 200px
+            height: 100%
+            border: 1px solid$app-border-color
+            display: inline-block
+            float: left
+            padding-left: 10px
+            margin-right: 5px
+            padding-top: 8px
+            // background: cyan
+        .item-partner
+            width: 200px
+            height: 100%
+            border: 1px solid$app-border-color
+            display: inline-block
+            float: left
+            padding-left: 10px
+            margin-right: 5px
+            padding-top: 8px
+            // background: cyan
+        .item-amount
+            width: 200px
+            height: 100%
+            border: 1px solid$app-border-color
+            display: inline-block
+            float: left
+            padding-top: 8px
+            margin-right: 5px
+            padding-left: 10px
+            // text-align: center
+            // background: cyan
+
+</style>
+<!--
+<template lang="pug">
+    .card-statement(
+        @click='onClick'
+        :class="{ 'selected-card': isSelected }"
+    )
+        .card-date {{ date }}
+        .card-title {{ title }}
+        .card-journal {{ journalName }}
+        .card-type {{ typeStatement }}
+        .card-count-intem Lineas({{ countLine}})
+        .card-amount(:class="{'statement-confirm': !!(state === 'confirm')}")
+            span(v-for='detail in details') {{ computeDetail(detail) }}
+</template>
+
+<script>
+    export default {
+        props: {
+            title: {
+                type: String,
+                default: 'Sin título'
+            },
+            date: {
+                type: Date,
+                default: ''
+            },
+            state: {
+                type: String,
+                default:'open'
+            },
+            journalName: {
+                type: String,
+                default: ''
+            },
+            typeStatement: {
+                type: String,
+                default: ''
+            },
+            countLine: {
+                type: String,
+                default: 0
+            },
+            details: {
+                type: Array,
+                default: []
+            },
+            isSelected: {
+                type: Boolean,
+                default: true
+            },
+            options: {
+                type: Object,
+                default: {}
+            }
+        },
+        methods: {
+            computeDetail(detail) {
+                if (detail.format === 'currency') {
+                    return this.$options.filters.currency(detail.value, {...this.options})
+                }
+
+                return detail.value
+            },
+            onClick() {
+                this.$emit('onClick')
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .card-statement
+        width: 180px
+        height: 130px
+        margin: 5px
+        border: 1px solid $app-border-color
+        display: inline-block
+        position: relative
+        &.selected-card
+            transition-duration: 300ms
+            border: 2px solid $app-main-color
+        &:hover
+            cursor: pointer
+        .card-date
+            width: 100%
+            height: 30px
+            position: absolute
+            font-size: 9pt
+            margin-top: 10px
+            padding-right: 10px
+            text-align: right
+            font-weight: normal
+            top: 0
+
+        .card-title
+            width: 100%
+            height: 30px
+            position: absolute
+            font-size: 9pt
+            font-weight: bold
+            margin-top: 30px
+            text-align: center
+            padding-right: 5px
+            padding-left: 5px
+            top: 0
+
+        .card-journal
+            width: 100%
+            height: 30px
+            position: absolute
+            margin-top: 50px
+            font-size: 9pt
+            float: right
+            padding-right: 5px
+            padding-left: 5px
+            text-align: center
+            font-weight: normal
+            top: 0
+
+        .card-type
+            width: 50%
+            height: 30px
+            margin-top: 70px
+            font-size: 9pt
+            float: left
+            padding-left: 5px
+            text-align: center
+            font-weight: normal
+            top: 0
+
+        .card-count-intem
+            width: 50%
+            height: 30px
+            margin-top: 70px
+            font-size: 9pt
+            text-align: center
+            float: right
+            padding-right: 5px
+            font-weight: normal
+            top: 0
+
+        .card-amount
+            width: 100%
+            height: 30px
+            padding-top: 5px
+            text-align: center
+            font-weight: bold
+            font-size: 10pt
+            position: absolute
+            background: $app-main-color
+            color: $app-bg-color
+            margin-bottom: 0px
+            bottom: 0
+        .statement-confirm
+            background: #ccc
+
+        @keyframes card-bubble
+            30%
+                transform: scaleX(0.75) scaleY(1.25)
+            40%
+                transform: scaleX(1.25) scaleY(0.75)
+            60%
+                transform: scaleX(0.85) scaleY(1.15)
+</style>
+
+-->

+ 186 - 0
src/components/steps/DetailsStep.vue

@@ -0,0 +1,186 @@
+<template lang="pug">
+    .statement-details-step
+        form
+            //.form-item-details
+            .form-details
+                h3.details-title {{ detailsTitle }}
+            .form-card-operation(v-if="!!statementOrigin")
+                .card-statement-operation
+                    .card-left
+                    h3.card-label Caja origen
+                    h3.card-title {{ statementOrigin }}
+            .form-card-operation(v-if="!!statementDest")
+                .card-statement-operation
+                    .card-right
+                    h3.card-label Caja destino
+                    h3.card-title {{ statementDest }}
+            //- .form-card-operation
+            hr
+            //- .form-details(v-if="transferCasBox")
+            //-     h3.details-item Caja origen {{ statementOrigin }} Caja destino {{ statementDest }}
+            //-     hr
+            //- .form-details(v-if="inputCasBox")
+            //-     h3.details-item Caja destino {{ statementOrigin }}
+            //-     hr
+            //- .form-details(v-if="outputCashBox")
+            //-     h3.details-item Caja origen {{ statementOrigin }}
+
+                hr
+            .form-item
+                label.form-label Valor de la operación
+                input-dropdown.form-input(
+                    format="number"
+                    :focus='true'
+                    :currency='currencyStatement'
+                    :suffix="currencyStatement.symbol"
+                    @onChangeValue="onChangeValue"
+                )
+            .form-item
+                label.form-label Motivo
+                textarea.form-textarea(:rows="3" v-model='descriptionOperation')
+</template>
+
+<script>
+    import { mapGetters, mapActions } from 'vuex'
+    import {SwitchButtonInput, InputDropdown } from '../common'
+
+    export default {
+        props: {
+            detailsTitle: {
+                type: String,
+                default: ''
+            },
+            transferCasBox: {
+                type: Boolean,
+                default: false
+            },
+            inputCasBox: {
+                type: Boolean,
+                default: false
+            },
+            outputCashBox: {
+                type: Boolean,
+                default: false
+            },
+            statementOrigin: {
+                type: String,
+                default: ''
+            },
+            statementDest: {
+                type: String,
+                default: ''
+            }
+        },
+        components: {
+            SwitchButtonInput,
+            InputDropdown
+        },
+        computed:{
+            descriptionOperation: {
+                get() {
+                    return this.description
+                },
+                set(value) {
+                    this.onChangeDescription(value)
+                }
+            },
+            ...mapGetters([
+                'currencyStatement',
+                'amountOperation',
+                'description',
+            ])
+        },
+        methods: {
+            onChangeValue(value) {
+                this.changeAmountOperation(value)
+            },
+            onChangeDescription(value) {
+                this.changeDescriptionOperation(value)
+            },
+            ...mapActions([
+                'changeAmountOperation',
+                'changeDescriptionOperation'
+            ])
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .statement-details-step
+        width: 100%
+        height: calc(100% - 50px)
+        padding-bottom: 50px
+        display: flex
+        form
+            width: 100%
+            height: 100%
+            margin-right: 50px
+            padding: 25px
+            background: $app-bg-color
+            .form-details
+                width: 100%
+                height: 35px
+                text-align: center
+                .details-title
+                    font-size: 13pt
+                    margin: 10px 0 0
+                    color: #d3d3d3
+                    text-align: center
+                // .details-item
+                    // font-size: 13pt
+                    // margin: 10px 0 0
+                    // text-align: center
+            .form-card-operation
+                width: 100%
+                height: 75px
+                margin-bottom: 5px
+                text-align: center
+                // .card-statement-operation
+                //     width: 300px
+                //     height: 100%
+                //     margin: 5px
+                //     border: 1px solid$app-border-color
+                //     display: inline-block
+                //     position: relative
+                //     .card-label
+                //         width: calc(100% - 20px)
+                //         font-size: 12pt
+                //         color: #d3d3d3
+                //         margin-top: 3px
+                //         border-bottom: 1px solid$app-border-color
+                //         margin-left: 10px
+                //         margin-right: 10px
+                //     .card-title
+                //         width: 100%
+                //         height: 35px
+                //         font-size: 16px
+
+                hr
+            .form-item
+                width: 100%
+                height: 35px
+                margin-bottom: 15px
+                margin-top: 15px
+                text-align: center
+                & > .form-label, > .form-input, > .form-textarea
+                    display: inline-block
+                    vertical-align: top
+                .form-label
+                    width: 200px
+                    height: 35px
+                    font-size: 12pt
+                    line-height: 30px
+                    color: $app-dark-color
+                .form-input
+                    width: 400px
+                    height: 35px
+                    font-size: 12pt
+                    border-radius: 0
+                .form-textarea
+                    width: 400px
+                    height: 72px
+                    font-size: 12pt
+                    border-radius: 0
+</style>

+ 137 - 0
src/components/steps/StatementConfirmStep.vue

@@ -0,0 +1,137 @@
+<template lang="pug">
+    .operation-step
+        operation-details(
+            :operationTitle='operationTitle'
+            :statementOrigin='selectedStatement'
+            :statementDest='selectedStatementDest'
+        )
+        .statement-details
+            form
+                .form-item
+                    label.form-label Saldo teórico de cierre
+                    input-dropdown.form-input(
+                        format="number"
+                        :value='amountStatementOrigin'
+                        :editable='false'
+                        :currency='currencyStatement'
+                        :suffix="currencyStatement.symbol"
+                    )
+                .form-item
+                    label.form-label Monto de cierre
+                    input-dropdown.form-input(
+                        format="number"
+                        :focus='true'
+                        :value='amountOperation'
+                        :currency='currencyStatement'
+                        :suffix="currencyStatement.symbol"
+                        @onChangeValue="amountClosing"
+                    )
+                .form-item
+                    label.form-label Diferencia
+                    input-dropdown.form-input(
+                        format="number"
+                        :value='this.amountDifference'
+                        :editable='false'
+                        :currency='currencyStatement'
+                        :suffix="currencyStatement.symbol"
+                    )
+                .form-item
+                    label.form-label Motivo
+                    textarea.form-textarea(placeholder="Observación de la operación" v-model='descriptionOperation')
+</template>
+
+<script>
+    import { mapGetters, mapActions } from 'vuex'
+    import {SwitchButtonInput, InputDropdown } from '../common'
+    import OperationDetails from '@/components/forms/OperationDetails'
+
+    export default {
+        components: {
+            SwitchButtonInput,
+            InputDropdown,
+            OperationDetails,
+        },
+        computed:{
+            descriptionOperation: {
+                get() {
+                    return this.description
+                },
+                set(value) {
+                    this.onChangeDescription(value)
+                }
+            },
+            ...mapGetters([
+                'currencyStatement',
+                'amountOperation',
+                'description',
+                'selectedStatement',
+                'selectedStatementDest',
+                'operationTitle',
+                'amountStatementOrigin',
+                'amountOperation',
+            ])
+        },
+        methods: {
+            onChangeDescription(value) {
+                this.changeDescriptionOperation(value)
+            },
+            amountClosing(value) {
+                this.changeAmountOperation(value)
+                this.amountDifference = this.amountOperation - this.amountStatementOrigin
+            },
+            ...mapActions([
+                'changeAmountOperation',
+                'changeDescriptionOperation'
+            ])
+        },
+        data() {
+            return {
+                amountDifference: 0
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .operation-step
+        width: 100%
+        height: 100%
+        padding-bottom: 50px
+        display: flex
+        .statement-details
+            width: calc(100% - 500px)
+            height: 100%
+            background: cyan
+            form
+                width: 100%
+                height: 100%
+                margin-right: 50px
+                padding: 25px
+                background: $app-bg-color
+                .form-item
+                    width: 100%
+                    height: 35px
+                    margin-bottom: 15px
+                    margin-top: 25px
+                    & > .form-label, > .form-input, > .form-textarea
+                        display: inline-block
+                        vertical-align: top
+                    .form-label
+                        width: 200px
+                        height: 35px
+                        font-size: 12pt
+                        line-height: 30px
+                        color: $app-dark-color
+                    .form-input
+                        width: 200px
+                        height: 35px
+                        font-size: 12pt
+                        border-radius: 0
+                    .form-textarea
+                        width: 400px
+                        height: 120px
+                        font-size: 12pt
+                        border-radius: 0
+</style>

+ 57 - 0
src/components/steps/StatementDestStep.vue

@@ -0,0 +1,57 @@
+<template lang="pug">
+    .statement-step
+        .statement-selection-setp
+            .statement-selector
+                searcher(
+                    mode='normal'
+                    :items='statementsDest'
+                    :keys="['name']"
+                    @onSearch='filteredStatementsDest'
+                )
+                card-grid(
+                    :canAdd='false'
+                    :items='visibleStatementDest'
+                    :details="['balanceEnd:c']"
+                    @onSelect='selectStatementsDest'
+                )
+</template>
+
+<script>
+    import { mapGetters, mapActions } from 'vuex'
+    import { Searcher, CardGrid } from '../common'
+
+    export default {
+        components: {
+            Searcher,
+            CardGrid,
+        },
+        computed:{
+            ...mapGetters([
+                'statementsDest',
+                'visibleStatementDest'
+            ])
+        },
+        methods: {
+            ...mapActions([
+                'filteredStatementsDest',
+                'selectStatementsDest'
+            ])
+        }
+    }
+</script>
+
+<style lang="sass">
+    .statement-step
+        .statement-selection-setp
+            width: 100%
+            height: 100%
+            display: flex
+            .statement-selector
+                width: 100%
+                height: 100%
+            .slide-fade-enter-active
+                transition: all 300ms ease
+            .slide-fade-enter
+                transition: translatex(300px)
+                opacity: 0
+</style>

+ 85 - 0
src/components/steps/StatementModify.vue

@@ -0,0 +1,85 @@
+<template lang="pug">
+    .statement-modify
+        .details-items
+            form
+                .form-item
+                    label.form-label Caja
+                    input.form-input(readonly='readonly' v-model="selectedStatement.name")
+                .form-item
+                    label.form-label Diario
+                    input.form-input(readonly='readonly' v-model='getJournalSelectedStatement')
+                .form-item
+                    label.form-label Tipo de Caja
+                    input.form-input(readonly='readonly' v-model="getTypeSelectedStatement")
+                .form-item
+                    label.form-label Responsable
+                    input.form-input(readonly='readonly' v-model='getUserSelectedStatement')
+        .details-items-line
+            card-grid-item(
+                :items='selectedStatement.line'
+            )
+</template>
+
+<script>
+    import { mapGetters, mapActions } from 'vuex'
+    import {SwitchButtonInput, InputDropdown } from '../common'
+    import CardGridItem from '@/components/steps/CardGridItem'
+
+    export default {
+
+        components: {
+            SwitchButtonInput,
+            InputDropdown,
+            CardGridItem
+        },
+        computed: mapGetters([
+            'selectedStatement',
+            'getJournalSelectedStatement',
+            'getTypeSelectedStatement',
+            'getUserSelectedStatement',
+        ]),
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .statement-modify
+        width: 100%
+        height: calc(100% - 50px)
+        .details-items
+            width: 100%
+            height: 200px
+            form
+                width: 100%
+                height: 100%
+                margin-right: 50px
+                padding: 25px
+                border: 1px solid$app-border-color
+                // background: $app-bg-color
+                .form-item
+                    width: 100%
+                    height: 35px
+                    margin-bottom: 5px
+                    margin-top: 5px
+                    text-align: center
+                    & > .form-label, > .form-input
+                        display: inline-block
+                        vertical-align: top
+                    .form-label
+                        width: 250px
+                        height: 35px
+                        font-size: 12pt
+                        line-height: 30px
+                        padding-left: 100px
+                        color: $app-dark-color
+                    .form-input
+                        width: 400px
+                        height: 35px
+                        font-size: 12pt
+                        border-radius: 0
+        .details-items-line
+            width: 100%
+            height: calc(100% - 200px)
+
+</style>

+ 106 - 0
src/components/steps/StatementOperationStep.vue

@@ -0,0 +1,106 @@
+<template lang="pug">
+    .operation-step
+        operation-details( :operationTitle='operationTitle' :statementOrigin='selectedStatement' :statementDest='selectedStatementDest')
+        .statement-details
+            form
+                .form-item
+                    label.form-label Valor de la operación
+                    input-dropdown.form-input(
+                        format="number"
+                        :focus='true'
+                        :currency='currencyStatement'
+                        :suffix="currencyStatement.symbol"
+                        @onChangeValue="onChangeValue"
+                    )
+                .form-item
+                    label.form-label Motivo
+                    textarea.form-textarea(placeholder="Observación de la operación" v-model='descriptionOperation')
+</template>
+
+<script>
+    import { mapGetters, mapActions } from 'vuex'
+    import {SwitchButtonInput, InputDropdown } from '../common'
+    import OperationDetails from '@/components/forms/OperationDetails'
+
+    export default {
+        components: {
+            SwitchButtonInput,
+            InputDropdown,
+            OperationDetails,
+        },
+        computed:{
+            descriptionOperation: {
+                get() {
+                    return this.description
+                },
+                set(value) {
+                    this.onChangeDescription(value)
+                }
+            },
+            ...mapGetters([
+                'currencyStatement',
+                'amountOperation',
+                'description',
+                'selectedStatement',
+                'selectedStatementDest',
+                'operationTitle',
+            ])
+        },
+        methods: {
+            onChangeValue(value) {
+                this.changeAmountOperation(value)
+            },
+            onChangeDescription(value) {
+                this.changeDescriptionOperation(value)
+            },
+            ...mapActions([
+                'changeAmountOperation',
+                'changeDescriptionOperation'
+            ])
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .operation-step
+        width: 100%
+        height: 100%
+        padding-bottom: 50px
+        display: flex
+        .statement-details
+            width: calc(100% - 500px)
+            height: 100%
+            background: cyan
+            form
+                width: 100%
+                height: 100%
+                margin-right: 50px
+                padding: 25px
+                background: $app-bg-color
+                .form-item
+                    width: 100%
+                    height: 35px
+                    margin-bottom: 15px
+                    margin-top: 40px
+                    & > .form-label, > .form-input, > .form-textarea
+                        display: inline-block
+                        vertical-align: top
+                    .form-label
+                        width: 160px
+                        height: 35px
+                        font-size: 12pt
+                        line-height: 30px
+                        color: $app-dark-color
+                    .form-input
+                        width: 400px
+                        height: 35px
+                        font-size: 12pt
+                        border-radius: 0
+                    .form-textarea
+                        width: 400px
+                        height: 120px
+                        font-size: 12pt
+                        border-radius: 0
+</style>

+ 74 - 7
src/components/steps/StatementStep.vue

@@ -2,22 +2,89 @@
     .statement-step
         .statement-selection-setp
             .statement-selector
-                searcher
-                card-grid
+                searcher(
+                    mode='normal'
+                    :items='statements'
+                    :keys="['name']"
+                    @onSearch='filteredStatements'
+                )
+                card-grid-statement(
+                    :canAdd='true'
+                    :items='visibleStatement'
+                    :loading='loadingStatements'
+                    :details="['balanceEnd:c']"
+                    @onAdd='addNewStatment'
+                    @onSelect='selectedStatements'
+                )
+                bank-statement-modal(
+                    :show='showStatement'
+                    :journals='journals'
+                    :statementType='statementType'
+                    :users='filterUserJournal'
+                    :dateStatement='dateStatement'
+                    :journalName='selectedJournalName'
+                    :typeName='selectedStatementTypeName'
+                    :userName='selectedUserName'
+                    @onSelectStatementJournal='selectJournal'
+                    @onSelectStatementType='selectStatementType'
+                    @onSetSelectUserStatement='setSelectUserStatement'
+                    @onSelectedDateStatement='dateNewStatement'
+                    @selectedDateStatement='dateNewStatement'
+                    @onCancel='onCancel'
+                    @onDone='endProcessNewStatement'
+                    @onNotify="notify"
+                )
             transition(name='slide-fade')
-                statement-action-form
+                statement-action-form(
+                    v-if='!!selectedStatement'
+                )
 </template>
 
 <script>
-
-    import { Searcher, CardGrid } from '../common'
+    import { mapGetters, mapActions } from 'vuex'
+    import { Searcher, CardGridStatement } from '../common'
     import StatementActionForm from '../forms/StatementActionForm'
+    import BankStatementModal from '../modal/BankStatementModal'
 
     export default {
         components: {
             Searcher,
-            CardGrid,
-            StatementActionForm
+            CardGridStatement,
+            StatementActionForm,
+            BankStatementModal,
+        },
+        computed: mapGetters([
+            'statements',
+            'visibleStatement',
+            'selectedStatement',
+            'showStatement',
+            'journals',
+            'statementType',
+            'user',
+            'filterUserJournal',
+            'selectedStatementTypeName',
+            'selectedUserName',
+            'selectedJournalName',
+            'dateStatement',
+        ]),
+        methods: {
+            addNewStatment () {
+                this.showStatementAdd(true)
+            },
+            onCancel(){
+                this.showStatementAdd(false)
+            },
+            ...mapActions([
+                'filteredStatements',
+                'selectedStatements',
+                'showStatementAdd',
+                'selectJournal', //Create Statement
+                'selectStatementType',//Create Statement
+                'setSelectUserStatement',//Create Statement
+                'dateNewStatement',//Create Statement
+                'notify',
+                'endProcessNewStatement',
+            ])
         }
     }
 </script>

+ 0 - 11
src/constants/app.js

@@ -1,11 +0,0 @@
-export const Modes = Object.freeze({
-    PURCHASE: 'purchase',
-    EXPENSE: 'expense'
-})
-
-export const States = Object.freeze({
-    NONE: 'none',
-    PROCESSING: 'processing',
-    DONE: 'done',
-    ERROR: 'error'
-})

+ 0 - 7
src/constants/resourcePaths.js

@@ -1,7 +0,0 @@
-const BASE_URL = '/eiru_purchases'
-
-export const INIT_PURCHASE_URL = `${BASE_URL}/init`
-
-export const CREATE_OBJECT_URL = `${BASE_URL}/create_object`
-
-export const PROCESS_PURCHASE_URL = `${BASE_URL}/process`

+ 6 - 7
src/index.js

@@ -1,13 +1,13 @@
 import Vue from 'vue'
 import App from '@/App'
 import VueModal from 'vue-js-modal'
-// import store from '@/store'
+import store from '@/store'
 
-// import currency from '@/components/filters/currency'
-// import absolute from '@/components/filters/absolute'
+import currency from '@/components/filters/currency'
+import absolute from '@/components/filters/absolute'
 
-// Vue.filter('currency', currency)
-// Vue.filter('absolute', absolute)
+Vue.filter('currency', currency)
+Vue.filter('absolute', absolute)
 
 Vue.use(VueModal)
 
@@ -23,11 +23,10 @@ openerp.eiru_bank_statement = (instance, local) => {
             this.mode = action.params.mode
         },
         start() {
-            console.log(this);
             this.sidebarFold()
 
             this.vm = new Vue({
-                // store,
+                store,
                 el: this.el,
                 template: '<App />',
                 components: {

+ 184 - 0
src/store/actions.js

@@ -0,0 +1,184 @@
+import axios from 'axios'
+
+const actions = {
+    notify(_, message) {
+        openerp.web.notification.do_warn('Atencion', message)
+        return false
+    },
+    initProcessBank({ getters, commit, dispatch}, mode) {
+        commit('setMode', mode || getters.mode)
+
+        return axios.get('/eiru_bank_statement/init', {
+            params: {
+                mode: getters.mode
+            }
+        }).then(({data}) => {
+
+            dispatch('explodeData', data)
+        }).catch(error => {
+            console.error(error);
+        })
+    },
+    explodeData({ dispatch }, data) {
+        for (let value in data) {
+            dispatch(`init${value[0].toUpperCase()}${value.slice(1)}`, data[value]);
+        }
+    },
+    /* Check Statement */
+    checkStatement({ getters, dispatch }) {
+        return !!getters.selectedStatement || dispatch('notify', 'Necesitas seleccionar una caja para continuar');
+    },
+    /* Check Statement Dest */
+    checkStatementDest({ getters, dispatch }) {
+        return !!getters.selectedStatementDest || dispatch('notify', 'Necesitas seleccionar una caja para la transferencia')
+    },
+    /*
+    checkAmount({ getters, dispatch}) {
+        return getters.amountOperation > 0 || dispatch('notify', 'El valor de la operación debe ser mayor que “0”.')
+    },*/
+//
+// description
+
+    /* Fin del processo */
+    endProcess({getters, commit, dispatch}) {
+        let data = {}
+        if (getters.isTransfer || getters.isInputCashbox || getters.isOutputCashbox) {
+            console.log("Transferencia, entrada o Salida")
+            /* Verift Amount Operation */
+            if (getters.amountOperation <= 0) {
+                dispatch('notify', 'El valor de la operación debe ser mayor que “0”.')
+                return false
+            }
+            /* Verify Description */
+            if (!getters.description.trim()) {
+                dispatch('notify', 'Necesitas ingresar una observación para la operación.')
+                return false
+            }
+            /* Generate Data */
+            data = {
+                transfer: getters.isTransfer,
+                input: getters.isInputCashbox,
+                output: getters.isOutputCashbox,
+                amount: getters.amountOperation,
+                description: getters.description,
+                casboxOriginId: getters.selectedStatement.id,
+                casboxDestID: !!getters.selectedStatementDest ? getters.selectedStatementDest.id: '',
+            }
+            commit('setDataEndProcess', data)
+            dispatch('createCasboxMove')
+        }
+        if (getters.isStatmentConfirm) {
+            console.log("CIERRE ")
+
+            let data = {}
+            if (!getters.description.trim()) {
+                dispatch('notify', 'Necesitas ingresar una observación para el cierre de caja.')
+                return false
+            }
+
+            data = {
+                statementId: getters.selectedStatement.id,
+                amount: getters.amountOperation,
+                description: getters.description,
+            }
+            commit('setDataEndProcess', data)
+            dispatch('processClosingStatement')
+        }
+    },
+
+    /**
+     * [createCasboxMove ]
+     * # Transferencia
+     * # input
+     * # Output
+     */
+    createCasboxMove({ getters, dispatch, commit }) {
+        return axios.post('/eiru_bank_statement/create_cashbox_move', {
+            jsonrpc: '2.0',
+            method: 'call',
+            params: {
+                data: getters.data
+            }
+        }).then(({data}) => {
+            // dispatch('notify', data.result.message)
+        }).catch(error => {
+            console.error(error)
+        })
+    },
+    processClosingStatement({ getters, dispatch, commit }) {
+        return axios.post('/eiru_bank_statement/process_closing_statement', {
+            jsonrpc: '2.0',
+            method: 'call',
+            params: {
+                data: getters.data
+            }
+        }).then(({data}) => {
+            dispatch('notify', data.result.message)
+        }).catch(error => {
+            console.error(error)
+        })
+    },
+
+
+    /*
+       ____ ____  _____    _  _____ _____   ____ _____  _  _____ _____ __  __ _____ _   _ _____
+      / ___|  _ \| ____|  / \|_   _| ____| / ___|_   _|/ \|_   _| ____|  \/  | ____| \ | |_   _|
+     | |   | |_) |  _|   / _ \ | | |  _|   \___ \ | | / _ \ | | |  _| | |\/| |  _| |  \| | | |
+     | |___|  _ <| |___ / ___ \| | | |___   ___) || |/ ___ \| | | |___| |  | | |___| |\  | | |
+      \____|_| \_\_____/_/   \_\_| |_____| |____/ |_/_/   \_\_| |_____|_|  |_|_____|_| \_| |_|
+     */
+    endProcessNewStatement({getters, commit, dispatch}){
+        let data = {}
+
+        data = {
+            journal_id: getters.selectedJournal,
+            type_statement: getters.selectedStatementType,
+            user_id: getters.selectedUserStatement,
+            date: getters.dateStatement,
+        }
+        commit('setDataEndProcess', data)
+        dispatch('createAccountBankStatement')
+    },
+    /*[CreateAccountBankStatement "Crear Caja"]*/
+    createAccountBankStatement({ getters, dispatch, commit}) {
+        return axios.post('/eiru_bank_statement/create_account_bank_statement', {
+            jsonrpc: '2.0',
+            method: 'call',
+            params: {
+                data: getters.data
+            }
+        }).then(({data}) => {
+            dispatch('notify', data.result.message)
+            if (data.result.state){
+                dispatch('receiveStatment',data.result.data)
+                dispatch('showStatementAdd',false)
+            }
+        }).catch(error => {
+            console.error(error)
+        })
+    },
+
+    resetStoreModules({ dispatch }, payload) {
+        // console.log(payload)
+        // console.log(
+        //     !!getters.isInputCashbox
+        //     !!getters.isOutputCashbox
+        // )
+        // if (!!getters.isInputCashbox || !!getters.isOutputCashbox && payload === 1) {
+        //
+        // }
+        // if (payload > 1 ){
+            // return
+        // }
+        // dispatch('resetStatementAction')
+        // dispatch('resetStatement')
+        // isTransfer
+        // isInputCashbox
+        // isOutputCashbox
+
+        // resetStatement
+        // resetStatementAction
+        return
+    }
+}
+export default actions

+ 13 - 0
src/store/getters.js

@@ -0,0 +1,13 @@
+const getters = {
+    mode(state) {
+        return state.mode
+    },
+    data(state) {
+        return state.data;
+    },
+
+    // selectedActions(state) {
+    //     return false;
+    // }
+}
+export default getters

+ 43 - 0
src/store/index.js

@@ -0,0 +1,43 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+/* Store*/
+import state from '@/store/state'
+import getters from '@/store/getters'
+import mutations from '@/store/mutations'
+import actions from '@/store/actions'
+// modules
+import dateModule from '@/store/modules/date'
+import currenciesModule from '@/store/modules/currencies'
+import journalsModule from '@/store/modules/journals'
+import statementModule from '@/store/modules/statement'
+import statementConfigModule from '@/store/modules/statementConfig'
+import userModule from '@/store/modules/user'
+import statementTypeModule from '@/store/modules/statementType'
+import resUsersModule from '@/store/modules/resUsers'
+//Actions Statement
+import statementAction from '@/store/modules/statementAction'
+
+/* Module */
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+    state,
+    getters,
+    mutations,
+    actions,
+    modules: {
+        dateModule,
+        currenciesModule,
+        journalsModule,
+        statementModule,
+        statementConfigModule,
+        userModule,
+        statementTypeModule,
+        resUsersModule,
+        statementAction,
+    },
+    strict: true
+})
+
+export default store

+ 41 - 0
src/store/modules/currencies.js

@@ -0,0 +1,41 @@
+const initialState = {
+    currencies: null,
+    loadingCurrencies: false
+}
+
+const state = {
+    currencies: initialState.currencies,
+    loadingCurrencies: initialState.loadingCurrencies
+}
+
+const getters = {
+    currencies(state) {
+        return state.currencies;
+    },
+    loadingCurrencies(state) {
+        return state.loadingCurrencies;
+    }
+}
+
+const mutations = {
+    setCurrencies(state, payload) {
+        state.currencies = payload
+    },
+    setLoadingCurrencies(state, payload) {
+        state.loadingCurrencies = !!payload
+    }
+}
+
+const actions = {
+    initCurrencies({ commit }, payload) {
+        commit('setCurrencies', payload)
+        commit('setLoadingCurrencies', payload)
+    }
+}
+
+export default {
+    state,
+    getters,
+    mutations,
+    actions
+}

+ 58 - 0
src/store/modules/date.js

@@ -0,0 +1,58 @@
+const initialState = {
+    date: null,
+    loadingDate: false,
+    dateStatement: '',
+}
+
+const state = {
+    date: initialState.date,
+    loadingDate: initialState.loadingDate,
+    dateStatement: initialState.dateStatement
+}
+
+const getters = {
+    date(state) {
+        return state.date
+    },
+    loadingDate(state) {
+        return state.loadingDate
+    },
+    dateStatement(state) {
+        console.log(state.dateStatement);
+        return !state.dateStatement ?moment(state.date).format('DD/MM/YYYY') :state.dateStatement
+    },
+}
+
+const mutations = {
+    setDate(state, payload) {
+        state.date = payload
+    },
+    setLoadingDate(state, loading) {
+        state.loadingDate = !!loading
+    },
+    setDateStatement(state, payload) {
+        console.log(payload);
+        state.dateStatement = moment(payload).format('DD/MM/YYYY')
+    },
+}
+
+const actions = {
+    initDate({ commit }, payload) {
+        commit('setDate',payload)
+        commit('setLoadingDate')
+    },
+    resetDate({ getters, commit }) {
+        commit('setLoadingDate', true)
+        commit('setDate',null)
+    },
+    dateNewStatement({ commit }, payload) {
+        commit('setDateStatement', payload)
+    }
+}
+
+export default {
+    state,
+    getters,
+    mutations,
+    actions
+}

+ 63 - 0
src/store/modules/journals.js

@@ -0,0 +1,63 @@
+const initialState ={
+    journals: null,
+    loadingJournals: false,
+    selectedJournal: null,
+    selectedJournalName: '',
+
+}
+
+const state = {
+    journals : initialState.journals,
+    loadingJournals: initialState.loadingJournals,
+    selectedJournal: initialState.selectedJournal,
+    selectedJournalName: initialState.selectedJournalName
+}
+
+const getters = {
+    journals(state) {
+        return state.journals
+    },
+    loadingJournals(state) {
+        return state.loadingJournals
+    },
+    selectedJournal(state) {
+        return state.selectedJournal
+    },
+    selectedJournalName(state){
+        return state.selectedJournalName
+    }
+}
+
+const mutations = {
+    setJournals(state, payload) {
+        state.journals = payload
+    },
+    setLoadingJournals(state, payload) {
+        state.loadingJournals = !!payload
+    },
+    setSelectedJournal(state, payload) {
+        state.selectedJournal = payload.id
+        state.selectedJournalName = payload.name
+
+    }
+}
+
+const actions = {
+    initJournals({ commit }, payload) {
+        commit('setJournals', payload)
+        commit('setLoadingJournals', payload)
+    },
+    /* Seleccionar Diario */
+    selectJournal({ commit , dispatch}, payload) {
+        commit('setSelectedJournal', payload)
+
+        dispatch('filterUserJournalSelected', payload)
+    }
+}
+
+export default {
+    state,
+    getters,
+    mutations,
+    actions
+}

+ 74 - 0
src/store/modules/resUsers.js

@@ -0,0 +1,74 @@
+const initialState ={
+    resUsers: [],
+    selectedUserStatement: null,
+    selectedUserName: '',
+    visibleUser: []
+}
+const state = {
+    resUsers: initialState.resUsers,
+    selectedUserStatement: initialState.selectedUserStatement,
+    visibleUser: initialState.visibleUser,
+    selectedUserName: initialState.selectedUserName,
+}
+
+const getters = {
+    resUsers(state) {
+        return state.resUsers
+    },
+    selectedUserStatement(state) {
+        return state.selectedUserStatement
+    },
+    filterUserJournal(state) {
+        return state.visibleUser.length === 0 ?state.resUsers :state.visibleUser
+    },
+    selectedUserName(state) {
+        return state.selectedUserName
+    }
+}
+
+const mutations = {
+    setResUsers(state, payload) {
+        state.resUsers = payload
+    },
+    setSelectedUserStatement(state, payload) {
+        state.selectedUserStatement = payload.id
+        state.selectedUserName = payload.name
+    },
+    setUserJournalSelected(state, payload) {
+        let userFilter = []
+        for (let store of payload.storeIds ){
+            for(let user of state.resUsers) {
+                if (!!user.storeIds.find(item => item === store)) {
+                    if ((userFilter.length === 0) || !(userFilter.find(item => item.id === user.id))){
+                        userFilter.push({
+                            'id':  user.id,
+                            'name': user.name,
+                            'displayName': user.displayName,
+                            'image': user.image,
+                        })
+                    }
+                }
+            }
+        }
+        state.visibleUser = userFilter
+    }
+}
+
+const actions = {
+    initResUsers({ commit }, payload){
+        commit('setResUsers', payload)
+    },
+    setSelectUserStatement({ commit }, payload) {
+        commit('setSelectedUserStatement', payload)
+    },
+    filterUserJournalSelected({ commit }, payload) {
+        commit('setUserJournalSelected', payload)
+    }
+}
+
+export default {
+    state,
+    getters,
+    mutations,
+    actions
+}

+ 164 - 0
src/store/modules/statement.js

@@ -0,0 +1,164 @@
+const initialState = {
+    statements: [],
+    filteredStatements: [],
+    loadingStatements: false,
+    selectedStatement: null,
+    currencyStatement: null,
+    showStatement: false,
+    /* transfer */
+    statementsDest : [],
+    filteredStatementDest: [],
+    selectedStatementDest: null,
+}
+
+const state = {
+    statements: initialState.statements,
+    filteredStatements: initialState.filteredStatements,
+    loadingStatements: initialState.loadingStatements,
+    selectedStatement: initialState.selectedStatement,
+    currencyStatement: initialState.currencyStatement,
+    showStatement: initialState.showStatement,
+    /* Transfer */
+    statementsDest: initialState.statementsDest,
+    filteredStatementDest: initialState.filteredStatementDest,
+    selectedStatementDest: initialState.selectedStatementDest
+}
+
+const getters = {
+    statements(state) {
+        return  state.statements
+    },
+    visibleStatement(state) {
+        return  state.filteredStatements.length === 0 ? state.statements :state.filteredStatements;
+    },
+    loadingStatements(state) {
+        return  state.loadingStatements
+    },
+    filteredStatements(state) {
+        return state.filteredStatements;
+    },
+    selectedStatement(state) {
+        return state.selectedStatement
+    },
+    showStatement(state) {
+        return state.showStatement
+    },
+    currencyStatement(state) {
+        return state.currencyStatement
+    },
+    statementsDest(state){
+        return state.statementsDest;
+    },
+    selectedStatementDest(state) {
+        return state.selectedStatementDest
+    },
+    filteredStatementDest(state) {
+        return state.filteredStatementDest
+    },
+    visibleStatementDest(state) {
+        return  state.filteredStatementDest.length === 0 ? state.statementsDest :state.filteredStatementDest;
+    },
+    amountStatementOrigin(state) {
+        return  !state.selectedStatement ? 0 : state.selectedStatement.balanceEnd
+    },
+    stateStatementSelected(state) {
+        return !state.selectedStatement ? "" : state.selectedStatement.state
+    },
+    getJournalSelectedStatement(state) {
+        return !state.selectedStatement || !state.selectedStatement.journal ? '' : state.selectedStatement.journal.displayName
+    },
+    getTypeSelectedStatement(state) {
+        return !state.selectedStatement || !state.selectedStatement.typeStatement ? '' : state.selectedStatement.typeStatement.name
+    },
+    getUserSelectedStatement(state) {
+        return !state.selectedStatement || !state.selectedStatement.user ? '' : state.selectedStatement.user.displayName
+
+    },
+}
+
+const mutations = {
+    setStatements(state, payload) {
+        state.statements = payload
+    },
+    setLoadingStatements(state, payload) {
+        state.loadingStatements = !!payload
+    },
+    setFilteredStatements(state, payload){
+        state.filteredStatements = payload
+    },
+    setSelectedStatement(state, payload){
+        state.selectedStatement = payload
+    },
+    setShowStatement(state, payload){
+        state.showStatement = !!payload
+    },
+    setSelectedStatementDest(state, payload) {
+        state.selectedStatementDest = payload
+    },
+    setCurrencyStatement(state, payload) {
+        state.currencyStatement = payload.currency
+    },
+    setStatementsDest(state, payload) {
+        state.statementsDest = state.statements.filter(item => item.id !== state.selectedStatement.id && item.journal.id === state.selectedStatement.journal.id && item.state === 'open')
+    },
+    setFilteredStatementsDest(state, payload) {
+        state.filteredStatementDest = payload
+    },
+    addStatment(state, payload) {
+        state.statements = [payload, ...state.statements]
+    },
+}
+
+const actions = {
+    initStatement({ commit }, payload) {
+        commit('setStatements', payload)
+        commit('setLoadingStatements', payload)
+    },
+    /* Filter */
+    filteredStatements( {commit}, payload){
+        commit('setFilteredStatements', payload)
+    },
+    filteredStatementsDest( {commit}, payload){
+        commit('setFilteredStatementsDest', payload)
+    },
+    showStatementAdd({ commit }, payload) {
+        commit('setShowStatement', payload)
+    },
+
+    /* Selected */
+    selectedStatements({ dispatch, commit }, payload) {
+        commit('setSelectedStatement', payload)
+        commit('setCurrencyStatement', payload)
+        commit('setStatementsDest', payload)
+
+        // commit('setFilteredStatements', [])
+
+        dispatch('verifyActionCashbox', payload)
+    },
+    selectStatementsDest( { commit },payload){
+        commit('setSelectedStatementDest', payload)
+    },
+    /* Resetar */
+    resetStatement({ commit }) {
+        commit('setLoadingStatements', false)
+        commit('setFilteredStatements', [])
+        commit('setSelectedStatement', null)
+        // commit('setStatementsDest')
+        commit('setFilteredStatementsDest', [])
+        commit('setSelectedStatementDest', null)
+    },
+
+    receiveStatment({ commit }, payload) {
+        commit('addStatment', payload)
+        commit('setLoadingStatements', false)
+
+    },
+
+}
+
+export default {
+    state,
+    getters,
+    mutations,
+    actions
+}

+ 132 - 0
src/store/modules/statementAction.js

@@ -0,0 +1,132 @@
+const initialState = {
+    isTransfer: false,
+    isInputCashbox: false,
+    isOutputCashbox: false,
+    isStatmentConfirm: false,
+    amountOperation: 0,
+    description: '',
+    // operationTitle: ''
+}
+
+const state = {
+    isTransfer: initialState.isTransfer,
+    isInputCashbox: initialState.isInputCashbox,
+    isOutputCashbox: initialState.isOutputCashbox,
+    isStatmentConfirm: initialState.isStatmentConfirm,
+    amountOperation: initialState.amountOperation,
+    description: initialState.description,
+    // operationTitle: initialState.operationTitle
+}
+
+const getters ={
+    isTransfer(state) {
+        return state.isTransfer;
+    },
+    isInputCashbox(state) {
+        return  state.isInputCashbox;
+    },
+    isOutputCashbox(state) {
+        return state.isOutputCashbox;
+    },
+    isStatmentConfirm(state) {
+        return state.isStatmentConfirm
+    },
+    amountOperation(state) {
+        return state.amountOperation
+    },
+
+    description(state) {
+        return state.description
+    },
+    operationTitle(state){
+        if (state.isTransfer) {
+            return 'Transferencia interna de cajas'
+        }
+        if (state.isInputCashbox) {
+            return 'Entrada de dinero'
+        }
+        if (state.isOutputCashbox) {
+            return 'Extracciónes de valores'
+        }
+        if (state.isStatmentConfirm) {
+            return 'Cierre de Caja'
+
+        }
+    }
+}
+
+const mutations = {
+    setTransfer(state, payload) {
+        state.isTransfer = !!payload
+    },
+    setInputCashbox(state, payload) {
+        state.isInputCashbox = !!payload
+    },
+    setOutputCashbox(state, payload) {
+        state.isOutputCashbox = !!payload
+    },
+    setStatmentConfirm( state, payload) {
+        state.isStatmentConfirm = !!payload
+    },
+
+    /* amountOperation */
+    setAmountOperation(state, payload) {
+        state.amountOperation = payload
+    },
+    setDescription(state, payload) {
+        state.description = payload
+    },
+}
+
+const actions = {
+    clcikTransfer({ commit }, payload) {
+        commit('setTransfer', payload)
+        commit('setInputCashbox', false)
+        commit('setOutputCashbox', false)
+        commit('setStatmentConfirm', false)
+    },
+    clickInputCashbox({ commit }, payload) {
+        commit('setTransfer', false)
+        commit('setInputCashbox', payload)
+        commit('setOutputCashbox', false)
+        commit('setStatmentConfirm', false)
+    },
+    clickOutputCashbox({ commit }, payload) {
+        commit('setTransfer', false)
+        commit('setInputCashbox', false)
+        commit('setOutputCashbox', payload)
+        commit('setStatmentConfirm', false)
+    },
+    clcikConfig({ commit, dispatch, getters },payload) {
+        commit('setStatmentConfirm', payload)
+        commit('setTransfer', false)
+        commit('setInputCashbox', false)
+        commit('setOutputCashbox', false)
+        /* Change amount operation */
+        dispatch('changeAmountOperation',getters.amountStatementOrigin)
+    },
+    /* AmountOperation */
+    changeAmountOperation({ commit }, payload) {
+        commit('setAmountOperation', payload)
+    },
+
+    /* Description */
+    changeDescriptionOperation({ commit }, payload){
+        commit('setDescription', payload)
+    },
+
+    resetStatementAction({ commit }) {
+        commit('setTransfer', false)
+        commit('setInputCashbox', false)
+        commit('setOutputCashbox', false)
+        commit('setAmountOperation', 0)
+        commit('setDescription', '')
+    }
+}
+
+export default {
+    state,
+    getters,
+    mutations,
+    actions
+}

+ 147 - 0
src/store/modules/statementConfig.js

@@ -0,0 +1,147 @@
+const initialState = {
+    statementConfig: [],
+    loadingStatementConfig: false,
+
+    actionTransfer: false,
+    actionInputCashbox: false,
+    actionOutputCashbox: false,
+    actionStatementConfirm: false
+}
+
+const state = {
+    statementConfig: initialState.statementConfig,
+    loadingStatementConfig: initialState.loadingStatementConfig,
+
+    actionTransfer: initialState.actionTransfer,
+    actionInputCashbox: initialState.actionInputCashbox,
+    actionOutputCashbox: initialState.actionOutputCashbox,
+    actionStatementConfirm: initialState.actionStatementConfirm
+}
+
+const getters = {
+    statementConfig(state) {
+        return state.statementConfig
+    },
+    loadingStatementConfig(state) {
+        return state.loadingStatementConfig
+    },
+
+    actionTransfer(state) {
+        return state.actionTransfer
+    },
+    actionInputCashbox(state) {
+        return state.actionInputCashbox
+    },
+    actionOutputCashbox(state) {
+        return state.actionOutputCashbox
+    },
+    actionStatementConfirm(state) {
+        return state.actionStatementConfirm
+    }
+}
+
+const mutations = {
+    setStatementConfig(state, payload) {
+        state.statementConfig = payload
+    },
+    setLoadingStatementConfig(state, payload) {
+        state.loadingStatementConfig = !!payload
+    },
+
+    /*  @ Transfer */
+    setActionTransfer(state, payload) {
+        let config = state.statementConfig.length > 0 ?  state.statementConfig[0] :false
+        if (!config){
+            state.actionTransfer = false
+            return
+        }
+        let result =  !!config.transfer.userIds.find(item => item === payload.userSession) && !!config.transfer.statementIds.find(item => item === payload.typeStatement.id)
+        state.actionTransfer = result
+    },
+
+    /* @ Input */
+    setActionInputCashbox(state, payload) {
+        let config = state.statementConfig.length > 0 ?  state.statementConfig[0] :false
+        if (!config){
+            state.actionInputCashbox = false
+            return
+        }
+        let result =  !!config.inputCashBox.userIds.find(item => item === payload.userSession) && !!config.inputCashBox.statementIds.find(item => item === payload.typeStatement.id)
+        state.actionInputCashbox = result
+    },
+
+    /*  @Output */
+    setActionOutputCashbox(state, payload) {
+        let config = state.statementConfig.length > 0 ?  state.statementConfig[0] :false
+        if (!config) {
+            state.actionOutputCashbox = false
+            return
+        }
+        let result =  !!config.outputCashBox.userIds.find(item => item === payload.userSession) && !!config.outputCashBox.statementIds.find(item => item === payload.typeStatement.id)
+        state.actionOutputCashbox = result
+    },
+    /* @Confirm */
+    setActionStatementConfirm(state, payload) {
+        let config = state.statementConfig.length > 0 ?  state.statementConfig[0] :false
+        if (!config){
+            state.actionStatementConfirm = false
+            return
+        }
+        let result =  !!config.statementConfirm.userIds.find(item => item === payload.userSession)
+        state.actionStatementConfirm = result
+    }
+}
+
+/*
+'transfer':{
+    'userIds'
+    'statementIds'
+    'negativeAmount':
+},
+'inputCashBox': {
+    'userIds',
+    'statementIds'
+},
+'outputCashBox': {
+    'userIds'
+    'statementIds'
+    'negativeAmount'
+},
+
+'delete': {
+    'outputUserIds'
+    'inputUserIds'
+    'transferUserIds'
+},
+'statementConfirm' :{
+    'userIds'
+    'transferUserIds'
+    'balanceUserIds'
+    'negativeAmountUserIds'
+},
+'statementOpen',
+'statementCancelUserIds',
+'statementUnlinkUserIds'
+ */
+
+
+const actions = {
+    initStatementConfig({ commit }, payload) {
+        commit('setStatementConfig',payload)
+        commit('setLoadingStatementConfig', payload)
+    },
+    verifyActionCashbox({ getters, commit }, payload){
+        // if (getters.stateStatementSelected === 'open')
+        commit('setActionTransfer', payload) // transfer
+        commit('setActionInputCashbox', payload) // Input
+        commit('setActionOutputCashbox', payload) // Output
+        commit('setActionStatementConfirm', payload) //Confirm
+    },
+}
+
+export default {
+    state,
+    getters,
+    mutations,
+    actions
+}

+ 55 - 0
src/store/modules/statementType.js

@@ -0,0 +1,55 @@
+const initialState = {
+    statementType: [],
+    loadingStatementType: false,
+    selectedStatementType: null, // is type statement Create Statement
+    selectedStatementTypeName: '' // is type statement Create Statement
+}
+const state ={
+    statementType: initialState.statementType,
+    loadingStatementType: initialState.loadingStatementType,
+    selectedStatementType: initialState.selectedStatementType,
+    selectedStatementTypeName: initialState.selectedStatementTypeName,
+}
+const getters = {
+    statementType(state) {
+        return  state.statementType;
+    },
+    loadingStatementType(state) {
+        return  state.loadingStatementType;
+    },
+    selectedStatementType(state) {
+        return  state.selectedStatementType;
+    },
+    selectedStatementTypeName(state) {
+        return state.selectedStatementTypeName
+    }
+}
+const mutations = {
+    setStatementType(state, payload) {
+        state.statementType = payload
+    },
+    setLoadingStatementType(state, payload) {
+        state.loadingStatementType = !!payload
+    },
+    setSelectedStatementType(state, payload) {
+        state.selectedStatementType = payload.id
+        state.selectedStatementTypeName = payload.name
+    }
+}
+const actions = {
+    initStatementType({ commit }, payload) {
+        commit('setStatementType', payload)
+        commit('setLoadingStatementType', payload)
+    },
+    selectStatementType({ commit }, payload) {
+        commit('setSelectedStatementType', payload)
+        
+    }
+}
+
+export default {
+    state,
+    getters,
+    mutations,
+    actions
+}

+ 41 - 0
src/store/modules/user.js

@@ -0,0 +1,41 @@
+const initialState = {
+    user: [],
+    loadingUser: false
+}
+
+const state = {
+    user: initialState.user,
+    loadingUser: initialState.loadingUser
+}
+
+const getters = {
+    user(state) {
+        return state.user;
+    },
+    loadingUser(state) {
+        return state.loadingUser
+    }
+}
+
+const mutations = {
+    setUser(state, payload) {
+        state.user = payload
+    },
+    setLoadingUser(state, payload) {
+        state.loadingUser = !!payload
+    }
+}
+
+const actions = {
+    initUser({ commit }, payload) {
+        commit('setUser', payload)
+        commit('setLoadingUser', payload)
+    }
+}
+
+export default{
+    state,
+    getters,
+    mutations,
+    actions
+}

+ 10 - 0
src/store/mutations.js

@@ -0,0 +1,10 @@
+const mutations = {
+    setMode(state, payload) {
+        state.mode = payload
+    },
+    setDataEndProcess(state, payload) {
+        state.data =  payload
+    }
+}
+
+export default mutations

+ 6 - 0
src/store/state.js

@@ -0,0 +1,6 @@
+const state = {
+    mode : 'cash',
+    data : [],
+}
+
+export default state

+ 0 - 25
src/templates.xml

@@ -1,25 +0,0 @@
-<openerp>
-    <data>
-        <template id="eiru_purchases.assets" name="Eiru Purchases" inherit_id="eiru_assets.assets">
-            <xpath expr="." position="inside">
-                <link rel="stylesheet" href="/eiru_purchases/static/src/main.css" />
-                <script type="text/javascript" src="/eiru_purchases/static/src/main.js" />
-            </xpath>
-        </template>
-
-        <record id="eiru_purchases.purchases_action" model="ir.actions.client">
-            <field name="name">Eiru Purchases</field>
-            <field name="tag">eiru_purchases.action_launch</field>
-            <field name="params">{'mode': 'purchase'}</field>
-        </record>
-
-        <record id="eiru_purchases.expenses_action" model="ir.actions.client">
-            <field name="name">Eiru Expenses</field>
-            <field name="tag">eiru_purchases.action_launch</field>
-            <field name="params">{'mode': 'expense'}</field>
-        </record>
-
-        <!-- <menuitem id="eiru_purchases.new_purchase" name="Nueva compra" parent="eiru_dashboard.eiru_dashboard_main" action="eiru_purchases.purchases_action" sequence="4" />
-        <menuitem id="eiru_purchases.new_expense" name="Nuevo gasto" parent="eiru_dashboard.eiru_dashboard_main" action="eiru_purchases.expenses_action" sequence="5" /> -->
-    </data>
-</openerp>

+ 14 - 2
views/templates.xml

@@ -6,12 +6,18 @@
                 <script type="text/javascript" src="/eiru_bank_statement/static/src/main.js" />
             </xpath>
         </template>
-
+        <!-- CASH -->
         <record id="eiru_bank_statement.cash" model="ir.actions.client">
             <field name="name">Eiru Caja </field>
             <field name="tag">eiru_bank_statement.action_launch</field>
             <field name="params">{'mode': 'cash'}</field>
         </record>
+        <!-- BANK  -->
+        <record id="eiru_bank_statement.bank_action" model="ir.actions.client">
+            <field name="name">Eiru Bank </field>
+            <field name="tag">eiru_bank_statement.action_launch</field>
+            <field name="params">{'mode': 'bank'}</field>
+        </record>
 
         <!-- <record id="eiru_purchases.expenses_action" model="ir.actions.client">
             <field name="name">Eiru Expenses</field>
@@ -20,11 +26,17 @@
         </record> -->
 
         <menuitem
-            id="eiru_bank_statement.bank"
+            id="eiru_bank_statement.menu_chas"
             name="Caja"
             parent="account.menu_finance_bank_and_cash"
             action="eiru_bank_statement.cash"
             sequence="0" />
+        <menuitem
+            id="eiru_bank_statement.menu_bank"
+            name="Banco"
+            parent="account.menu_finance_bank_and_cash"
+            action="eiru_bank_statement.bank_action"
+            sequence="0" />
         <!-- <menuitem id="eiru_purchases.new_expense" name="Nuevo gasto" parent="eiru_dashboard.eiru_dashboard_main" action="eiru_purchases.expenses_action" sequence="5" /> -->
     </data>
 </openerp>

+ 5 - 2
webpack.config.js

@@ -14,11 +14,14 @@ module.exports = {
         extensions: ['.js', '.vue', '.json'],
         alias: {
             'vue$': 'vue/dist/vue.esm.js',
-            '@': Path.resolve('src')
+            '@': Path.resolve('src'),
+            '@@': Path.resolve('src/components')
         }
     },
     plugins: [
-        new LiveReloadPlugin(),
+        new LiveReloadPlugin({
+            appendScriptTag: true
+        }),
         new ExtractTextPlugin('main.css')
     ],
     module: {