Browse Source

[ADD] features

Gogs 6 years ago
parent
commit
53981eaa98
49 changed files with 1572 additions and 1199 deletions
  1. 2 1
      __openerp__.py
  2. 260 137
      controllers/main.py
  3. 10 0
      data/eiru_pos_data.xml
  4. 1 0
      models/__init__.py
  5. 15 0
      models/eiru_pos.py
  6. 2 0
      security/ir.model.access.csv
  7. 58 25
      src/App.vue
  8. 10 3
      src/components/common/Card.vue
  9. 9 3
      src/components/common/CardGrid.vue
  10. 11 5
      src/components/common/Cart.vue
  11. 3 3
      src/components/common/CartItem.vue
  12. 55 11
      src/components/common/DropdownSearcher.vue
  13. 9 5
      src/components/common/InputDropdown.vue
  14. 63 0
      src/components/common/SettingsButton.vue
  15. 1 0
      src/components/common/Spinner.vue
  16. 71 0
      src/components/common/SwitchButtonInput.vue
  17. 5 1
      src/components/common/index.js
  18. 2 1
      src/components/forms/CustomerForm.vue
  19. 202 63
      src/components/modals/BankPaymentModal.vue
  20. 31 7
      src/components/modals/DiscountModal.vue
  21. 6 1
      src/components/modals/DocumentSelector.vue
  22. 122 0
      src/components/modals/SettingsModal.vue
  23. 7 1
      src/components/modals/VariantModal.vue
  24. 23 4
      src/components/steps/Customer.vue
  25. 109 40
      src/components/steps/Payment.vue
  26. 0 180
      src/components/steps/PaymentAmount.vue
  27. 0 148
      src/components/steps/PaymentMethod.vue
  28. 4 4
      src/components/steps/Product.vue
  29. 1 2
      src/index.js
  30. 86 175
      src/store/actions.js
  31. 23 28
      src/store/getters.js
  32. 4 2
      src/store/index.js
  33. 22 32
      src/store/modules/bank.js
  34. 35 35
      src/store/modules/bankPaymentType.js
  35. 3 2
      src/store/modules/cart.js
  36. 62 0
      src/store/modules/chequeType.js
  37. 24 11
      src/store/modules/currency.js
  38. 37 59
      src/store/modules/customer.js
  39. 9 19
      src/store/modules/date.js
  40. 22 97
      src/store/modules/journal.js
  41. 65 11
      src/store/modules/payment.js
  42. 32 63
      src/store/modules/product.js
  43. 7 0
      src/store/modules/user.js
  44. 15 3
      src/store/mutations.js
  45. 4 1
      src/store/state.js
  46. 10 0
      src/utils/db.js
  47. 5 0
      src/utils/index.js
  48. 3 3
      templates.xml
  49. 12 13
      webpack.config.js

+ 2 - 1
__openerp__.py

@@ -6,6 +6,7 @@
     'version': '0.1',
     'depends': ['base', 'sale', 'account', 'multi_store', 'eiru_product_extra_price', 'currency_utility'],
     'data': [
-        'templates.xml'
+        'templates.xml',
+        'data/eiru_pos_data.xml'
     ]
 }

+ 260 - 137
controllers/main.py

@@ -2,6 +2,7 @@
 
 from openerp import http
 from openerp.http import request
+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, float_round
 from werkzeug.wrappers import Response
 from werkzeug.datastructures import Headers
 from datetime import datetime
@@ -19,8 +20,6 @@ except ImportError:
     from StringIO import StringIO as IO
 
 LOGGER = logging.getLogger(__name__)
-DATE_FORMAT = '%Y-%m-%d'
-DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
 GZIP_COMPRESSION_LEVEL = 9
 
 '''
@@ -36,6 +35,48 @@ GZIP_COMPRESSION_LEVEL = 9
                                                                                                               
 '''
 class PosSales(http.Controller):
+    
+    '''
+        Make JSON response
+    '''
+    def make_json_response(self, data=None, status=200):
+        return Response(json.dumps(data), status=status, content_type='application/json')
+
+    '''
+        Make GZIP to JSON response
+    '''
+    def make_gzip_response(self, data=None, status=200):
+        gzip_buffer = IO()
+
+        with GzipFile(mode='wb', compresslevel=GZIP_COMPRESSION_LEVEL, fileobj=gzip_buffer) as gzip_file:
+            gzip_file.write(json.dumps(data))
+        
+        contents = gzip_buffer.getvalue()
+        gzip_buffer.close()
+
+        headers = Headers()
+        headers.add('Content-Encoding', 'gzip')
+        headers.add('Vary', 'Accept-Encoding')
+        headers.add('Content-Length', len(contents))
+
+        return Response(contents, status=status, headers=headers, content_type='application/json')
+    
+    '''
+    '''
+    def make_info_log(self, log):
+        LOGGER.info(log)
+
+    '''
+        Get POS data
+    '''
+    def get_pos_data(self):
+        pos = request.env['eiru.pos'].search([])
+
+        return {
+            'imageType': pos.image_type,
+            'allowCurrencyExchange': pos.allow_currency_exchange,
+            'viewCurrencyExchanges': pos.view_currency_exchanges
+        }
 
     '''
         Get timezone
@@ -47,7 +88,7 @@ class PosSales(http.Controller):
         Get server date
     '''
     def get_server_datetime(self):
-        return datetime.now(self.get_timezone()).strftime(DATETIME_FORMAT)
+        return datetime.now(self.get_timezone()).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
 
     '''
         Check if module is installed
@@ -74,7 +115,7 @@ class PosSales(http.Controller):
                 'city': user.company_id.city or None
             }
         }
-
+    
     '''
         Get currencies from configured journals
     '''
@@ -91,6 +132,7 @@ class PosSales(http.Controller):
                 'base': currency.base,
                 'symbol': currency.symbol,
                 'position': currency.position,
+                'rateSilent': currency.rate_silent,
                 'decimalSeparator': currency.decimal_separator,
                 'decimalPlaces': currency.decimal_places,
                 'thousandsSeparator': currency.thousands_separator
@@ -103,12 +145,14 @@ class PosSales(http.Controller):
     '''
     def get_journals(self):
         domain = [('type', 'in', ['bank', 'cash']), ('active', '=', True)]
+        has_subtype = self.is_module_installed('eiru_bank_payments_references')
 
         return [{
             'id': journal.id,
             'name': journal.display_name,
             'code': journal.code,
             'type': journal.type,
+            'subtype': (has_subtype and journal.subtype) or None,
             'currencyId': journal.currency.id or journal.company_id.currency_id.id
         } for journal in request.env['account.journal'].search(domain, order='id')]
     
@@ -135,28 +179,51 @@ class PosSales(http.Controller):
         bank_types = []
 
         if self.is_module_installed('eiru_bank_payments_references'):
+            domain = [('is_receipt', '=', True)]
+
             bank_types = [
                 {
                     'id': type.id,
                     'name': type.display_name,
-                    'code': type.code,
+                    'isReceipt': type.is_receipt,
+                    'isPayment': type.is_payment,
+                    'fieldsAllowed': map(lambda x: x.strip(), (type.fields_allowed or []).split(',')),
+                    'subtype': type.subtype,
                     'defaultState': type.default_state
-                } for type in request.env['res.bank.payments.type'].search([('is_receipt', '=', True)])
+                } for type in request.env['res.bank.payments.type'].search(domain)
             ]
 
         return bank_types
 
+    '''
+        Get cheque
+    '''
+    def get_cheque_types(self):
+        cheque_types = []
+        
+        if self.is_module_installed('eiru_bank_payments_references'):
+            cheque_types = [
+                {
+                    'id': type.id,
+                    'name': type.display_name,
+                    'isBank': type.is_bank,
+                    'isCash': type.is_cash
+                } for type in request.env['res.bank.check.type'].search([])
+            ]
+
+        return cheque_types
+
     '''
         Get all active customers
     '''
-    def get_customers(self):
+    def get_customers(self, image_type='small'):
         domain = [('customer', '=', True), ('active', '=', True)]
 
         return [
             {
                 'id': customer.id,
                 'name': customer.display_name,
-                'image': customer.image_small,
+                'image': customer.image_small if image_type == 'small' else customer.image_medium,
                 'ruc': customer.ruc or None,
                 'phone': customer.phone or None,
                 'mobile': customer.mobile or None,
@@ -167,7 +234,7 @@ class PosSales(http.Controller):
     '''
         Get all saleable and active products
     '''
-    def get_products(self):
+    def get_products(self, image_type='small'):
         domain = [('sale_ok', '=', True), ('list_price', '>', 0), ('active', '=', True)]
 
         return [
@@ -176,7 +243,7 @@ class PosSales(http.Controller):
                 'name': product.display_name,
                 'ean13': product.ean13,
                 'defaultCode': product.default_code,
-                'image': product.image_small,
+                'image': product.image_small if image_type == 'small' else product.image_medium,
                 'listPrice': product.list_price,
                 'variantCount': product.product_variant_count,
                 'quantity': 1,
@@ -189,7 +256,7 @@ class PosSales(http.Controller):
                     'name': variant.display_name,
                     'ean13': variant.ean13,
                     'defaultCode': product.default_code,
-                    'image': variant.image_medium,
+                    'image': variant.image_small if image_type == 'small' else variant.image_medium,
                     'listPrice': variant.list_price,
                     'quantity': 1,
                     'price': variant.list_price,
@@ -220,117 +287,6 @@ class PosSales(http.Controller):
             } for payment_term in request.env['account.payment.term'].search(domain)
         ]
 
-    '''
-        Make JSON response
-    '''
-    def make_json_response(self, data=None, status=200):
-        return Response(json.dumps(data), status=status, content_type='application/json')
-
-    '''
-        Make GZIP to JSON response
-    '''
-    def make_gzip_response(self, data=None, status=200):
-        gzip_buffer = IO()
-
-        with GzipFile(mode='wb', compresslevel=GZIP_COMPRESSION_LEVEL, fileobj=gzip_buffer) as gzip_file:
-            gzip_file.write(json.dumps(data))
-        
-        contents = gzip_buffer.getvalue()
-        gzip_buffer.close()
-
-        headers = Headers()
-        headers.add('Content-Encoding', 'gzip')
-        headers.add('Vary', 'Accept-Encoding')
-        headers.add('Content-Length', len(contents))
-
-        return Response(contents, status=status, headers=headers, content_type='application/json')
-    
-    '''
-    '''
-    def make_info_log(self, log):
-        LOGGER.info(log)
-
-    '''
-        New purchase resource route
-    '''
-    @http.route('/eiru_sales/init', auth='user', methods=['GET'], cors='*')
-    def init_sale(self, **kw):
-        self.make_info_log('Sending JSON response')
-    
-        return self.make_gzip_response(
-            {
-                'date': self.get_server_datetime(),
-                'user': self.get_user(),
-                'currencies': self.get_currencies_from_journals(),
-                'journals': self.get_journals(),
-                'customers': self.get_customers(),
-                'products': self.get_products(),
-                'paymentTerms': self.get_payment_terms(),
-                'banks': self.get_banks(),
-                'bankPaymentTypes': self.get_bank_payment_types()
-            }
-        )
-
-    
-    '''
-        Create customer and return data
-    '''
-    @http.route('/eiru_sales/create_customer', type='json', auth='user', methods=['POST'], cors='*')
-    def create_customer(self, **kw):
-        self.make_info_log('Creating customer')
-
-        customer = request.env['res.partner'].create({
-            'name': kw.get('name'),
-            'ruc': kw.get('ruc'),
-            'mobile': kw.get('mobile'),
-            'customer': True
-        })
-
-        return {
-            'id': customer.id,
-            'name': customer.display_name,
-            'image': customer.image_small,
-            'ruc': customer.ruc or None,
-            'phone': customer.phone or None,
-            'mobile': customer.mobile or None,
-            'email': customer.email or None
-        }
-    
-    '''
-        Create product and return data
-    '''
-    @http.route('/eiru_sales/create_product', type='json', auth='user', methods=['POST'], cors='*')
-    def create_product(self, **kw):
-        self.make_info_log('Creating customer')
-
-        product = request.env['product.template'].create({
-            'name': kw.get('name'),
-            'list_price': float(kw.get('price')),
-            'ean13': kw.get('ean13')
-        })
-
-        return {
-            'id': product.id,
-            'name': product.display_name,
-            'ean13': product.ean13,
-            'image': product.image_small,
-            'listPrice': product.list_price,
-            'variantCount': product.product_variant_count,
-            'quantity': 1,
-            'price': product.list_price,
-            'discount': 0,
-            'variants': [{
-                'id': variant.id,
-                'name': variant.display_name,
-                'ean13': variant.ean13,
-                'image': variant.image_small,
-                'listPrice': variant.list_price,
-                'quantity': 1,
-                'price': variant.list_price,
-                'discount': 0,
-            } for variant in product.product_variant_ids if variant.active]
-        }
-
     '''
         Get currency from journal
     '''
@@ -354,16 +310,36 @@ class PosSales(http.Controller):
         
         return pricelist
 
+    '''
+    '''
+    def compute_cart_item_price(self, price, currency_id, partner_id=None):
+        from_currency = request.env.user.company_id.currency_id
+        to_currency = request.env['res.currency'].search([('id', '=', currency_id)])
+
+        return from_currency.compute(price, to_currency)
+
+    '''
+    '''
+    def compute_cart_item_discount(self, price, product_id, currency_id):
+        from_currency = request.env.user.company_id.currency_id
+        to_currency = request.env['res.currency'].search([('id', '=', currency_id)])
+
+        product = request.env['product.product'].search([('id', '=', product_id)])
+        computed_price = from_currency.compute(price, to_currency)
+
+        return 1.0 - (price / product.list_price)
+
     '''
         Create sale order from cart items values
     '''
     def create_sale_from_cart(self, partner_id, cart_items, date_confirm, currency_id, pricelist_id, payment_term_id=None):
-        return request.env['sale.order'].create({
+        values = {
             'partner_id': partner_id,
             'order_line': [[0, False, {
                 'product_id': int(line.get('id')),
                 'product_uom_qty': float(line.get('quantity')),
-                'price_unit': float(line.get('price'))
+                'price_unit': self.compute_cart_item_price(float(line.get('price')), currency_id),
+                'discount': self.compute_cart_item_discount(float(line.get('price')), float(line.get('id')), currency_id)
             }] for line in cart_items],
             'picking_policy': 'direct',
             'date_confirm': date_confirm,
@@ -371,7 +347,11 @@ class PosSales(http.Controller):
             'pricelist_id': pricelist_id,
             'payment_term': payment_term_id,
             'state': 'draft',
-        })
+        }
+
+        # import web_pdb; web_pdb.set_trace()
+
+        return request.env['sale.order'].create(values)
 
     '''
         Confirm sale order
@@ -401,7 +381,7 @@ class PosSales(http.Controller):
         invoice.write({
             'currency_id': currency_id,
             'date_invoice': date_today,
-            'date_due': date_due.strftime(DATE_FORMAT),
+            'date_due': date_due.strftime(DEFAULT_SERVER_DATE_FORMAT),
             'state': 'open'
         })
 
@@ -412,24 +392,33 @@ class PosSales(http.Controller):
     '''
     def create_invoice_move_lines(self, invoice_id, paid_amount, date_today):
         invoice = request.env['account.invoice'].browse(invoice_id)
+        context = dict(request.context, lang=invoice.partner_id.lang)
+
         invoice_move_lines = invoice._get_analytic_lines()
         decimal_precision = request.env['decimal.precision'].precision_get('Account')
 
-        compute_taxes = request.env['account.invoice.tax'].compute(invoice)
+        compute_taxes = request.env['account.invoice.tax'].compute(invoice.with_context(context))
         invoice.check_tax_lines(compute_taxes)
         invoice._recompute_tax_amount()
 
-        invoice_move_lines += request.env['account.invoice.tax'].move_line_get(invoice.id)
+        # import web_pdb; web_pdb.set_trace()
 
-        total, total_currency, invoice_move_lines = invoice.compute_invoice_totals(invoice.company_id.currency_id, invoice.reference, invoice_move_lines)
+        invoice_move_lines += request.env['account.invoice.tax'].move_line_get(invoice.id)
+        total, total_currency, invoice_move_lines = invoice.with_context(context).compute_invoice_totals(invoice.company_id.currency_id, invoice.reference, invoice_move_lines)
 
-        paid_percentage = paid_amount / round(total, decimal_precision)
+        paid_amount = float_round(paid_amount, precision_digits=decimal_precision)
+        paid_percentage = paid_amount / float_round(total_currency, precision_digits=decimal_precision)
         distributed_percentage = -(paid_percentage / len(invoice.payment_term.line_ids))
 
+        diff_currency = invoice.currency_id != invoice.company_id.currency_id
+
+        if diff_currency:
+            paid_amount = invoice.currency_id.compute(paid_amount, invoice.company_id.currency_id)
+        
         payment_lines = []
 
         for line in invoice.payment_term.line_ids:
-            date_due = (parse(date_today) + rd(days=line.days + line.days2)).strftime(DATE_FORMAT)
+            date_due = (parse(date_today) + rd(days=line.days + line.days2)).strftime(DEFAULT_SERVER_DATE_FORMAT)
 
             if paid_percentage and paid_percentage < 1.0:
                 payment_lines.append([date_today, paid_percentage])
@@ -446,21 +435,34 @@ class PosSales(http.Controller):
             payment_lines.append([date_due, line.value_amount])
 
             for payment_line in payment_lines:
-                current_price = round(total * payment_line[1], decimal_precision)
+                current_price = float_round(total * payment_line[1], precision_digits=decimal_precision)
 
                 if current_price < 0.0:
                     continue
 
                 paid_amount += current_price
 
+                # Compute move line price
+                if payment_line[1]:
+                    price = current_price
+                else:
+                    price = float_round(total - paid_amount, precision_digits=decimal_precision) or total
+
+                # Compute move line amount in currency
+                if diff_currency:
+                    amount_currency = invoice.company_id.currency_id.with_context(context).compute(price, invoice.currency_id)
+                else:
+                    amount_currency = False
+
+                # Create invoice move live value
                 invoice_move_lines.append({
                     'type': 'dest',
                     'name': '/',
-                    'price': current_price if payment_line[1] else round(total - paid_amount, decimal_precision) or total,
+                    'price': price,
                     'account_id': invoice.account_id.id,
                     'date_maturity': payment_line[0],
-                    'amount_currency': invoice.company_id.currency_id.compute(payment_line[1], invoice.currency_id) if invoice.currency_id != invoice.company_id.currency_id else False,
-                    'currency_id': invoice.currency_id != invoice.company_id.currency_id and invoice.currency_id.id,
+                    'amount_currency': amount_currency,
+                    'currency_id': diff_currency and invoice.currency_id.id,
                     'ref': invoice.reference
                 })
                 
@@ -584,7 +586,6 @@ class PosSales(http.Controller):
             'ref': 'POS/' + (reference or '')
         }]]
 
-
     '''
         Create account bank statement
     '''
@@ -613,6 +614,128 @@ class PosSales(http.Controller):
 
         return account_bank_statement
 
+    '''
+        New purchase resource route
+    '''
+    @http.route('/eiru_sales/init', auth='user', methods=['GET'], cors='*')
+    def init_sale(self, **kw):
+        self.make_info_log('Sending JSON response')
+        
+        pos_data = self.get_pos_data()
+
+        return self.make_gzip_response(
+            {
+                'pos': pos_data,
+                'date': self.get_server_datetime(),
+                'user': self.get_user(),
+                'currencies': self.get_currencies_from_journals(),
+                'journals': self.get_journals(),
+                'customers': self.get_customers(image_type=pos_data['imageType']),
+                'products': self.get_products(image_type=pos_data['imageType']),
+                'paymentTerms': self.get_payment_terms(),
+                'banks': self.get_banks(),
+                'bankPaymentTypes': self.get_bank_payment_types(),
+                'chequeTypes': self.get_cheque_types()
+            }
+        )
+    
+    '''
+        Get products data only
+    '''
+    @http.route('/eiru_sales/get_images', auth='user', methods=['GET'], cors='*')
+    def get_images_only(self, **kw):
+        pos_data = self.get_pos_data()
+        image_type = str(pos_data['imageType'])
+
+        return self.make_gzip_response(
+            {
+                'customers': self.get_customers(image_type=image_type),
+                'products': self.get_products(image_type=image_type)
+            }
+        )
+
+    '''
+        Create customer and return data
+    '''
+    @http.route('/eiru_sales/create_customer', type='json', auth='user', methods=['POST'], cors='*')
+    def create_customer(self, **kw):
+        self.make_info_log('Creating customer')
+
+        customer = request.env['res.partner'].create({
+            'name': kw.get('name'),
+            'ruc': kw.get('ruc'),
+            'mobile': kw.get('mobile'),
+            'customer': True
+        })
+
+        return {
+            'id': customer.id,
+            'name': customer.display_name,
+            'image': customer.image_small,
+            'ruc': customer.ruc or None,
+            'phone': customer.phone or None,
+            'mobile': customer.mobile or None,
+            'email': customer.email or None
+        }
+    
+    '''
+        Save settings
+    '''
+    @http.route('/eiru_sales/save_settings', type='json', auth='user', methods=['POST'], cors='*')
+    def save_settings(self, **kw):
+        self.make_info_log('save settings')
+
+        values = {}
+        
+        if kw.get('setting') == 'imageType':
+            values['image_type'] = ('big', 'small')[kw.get('value', False)]
+        
+        if kw.get('setting') == 'allowCurrencyExchange':
+            values['allow_currency_exchange'] = kw.get('value', False)
+        
+        if kw.get('setting') == 'viewCurrencyExchanges':
+            values['view_currency_exchanges'] = kw.get('value', False)
+
+        pos = request.env['eiru.pos'].search([])
+        pos.write(values)
+        
+        return self.get_pos_data()
+    
+    '''
+        Create product and return data
+    '''
+    @http.route('/eiru_sales/create_product', type='json', auth='user', methods=['POST'], cors='*')
+    def create_product(self, **kw):
+        self.make_info_log('Creating customer')
+
+        product = request.env['product.template'].create({
+            'name': kw.get('name'),
+            'listPrice': float(kw.get('price')),
+            'ean13': kw.get('ean13')
+        })
+
+        return {
+            'id': product.id,
+            'name': product.display_name,
+            'ean13': product.ean13,
+            'image': product.image_small,
+            'listPrice': product.list_price,
+            'variantCount': product.product_variant_count,
+            'quantity': 1,
+            'price': product.list_price,
+            'discount': 0,
+            'variants': [{
+                'id': variant.id,
+                'name': variant.display_name,
+                'ean13': variant.ean13,
+                'image': variant.image_small,
+                'listPrice': variant.list_price,
+                'quantity': 1,
+                'price': variant.list_price,
+                'discount': 0,
+            } for variant in product.product_variant_ids if variant.active]
+        }
+
     '''
         Process sale
     '''
@@ -621,7 +744,7 @@ class PosSales(http.Controller):
         self.make_info_log('Processing sale...')
 
         # Get date
-        date_now = datetime.now(self.get_timezone()).strftime(DATE_FORMAT)
+        date_now = datetime.now(self.get_timezone()).strftime(DEFAULT_SERVER_DATE_FORMAT)
         self.make_info_log('[OK] Getting date')
 
         # Get currency

+ 10 - 0
data/eiru_pos_data.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="1">
+        <record id="eiru_pos" model="eiru.pos">
+            <field name="image_type">small</field>
+            <field name="allow_currency_exchange">False</field>
+            <field name="view_currency_exchanges">False</field>
+        </record>
+    </data>
+</openerp>

+ 1 - 0
models/__init__.py

@@ -1,3 +1,4 @@
 # -*- coding: utf-8 -*-
+import eiru_pos
 import account_invoice_line
 import sale_order_line

+ 15 - 0
models/eiru_pos.py

@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+from openerp import models, fields
+
+class EiruPointOfSale(models.Model):
+    _name = 'eiru.pos'
+
+    IMAGE_TYPES = [
+        ('small', 'Pequeña'),
+        ('big', 'Grande')
+    ]
+
+    image_type = fields.Selection(selection=IMAGE_TYPES, default=0)
+    allow_currency_exchange = fields.Boolean(default=False)
+    view_currency_exchanges = fields.Boolean(default=False)
+    

+ 2 - 0
security/ir.model.access.csv

@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_eiru_pos,access_eiru_pos,model_eiru_pos,,1,0,0,0

+ 58 - 25
src/App.vue

@@ -3,56 +3,94 @@
         form-wizard(
             title=''
             subtitle=''
-            finishButtonText='Finalizar' 
-            color='#7c7bad' 
-            nextButtonText='Continuar' 
-            backButtonText='Volver' 
+            color='#7c7bad'
             ref='wizard'
-            :hideButtons='processing' 
-            @on-complete='createSale'
         )
             tab-content(
-                title="Qué productos necesita?"
-                :beforeChange="checkCart"
+                title='Qué productos necesita?'
+                :beforeChange='checkCart'
             )
                 product-step
             tab-content(
-                title="Quién es el cliente?"
-                :beforeChange="checkCustomer"
+                title='Quién es el cliente?'
+                :beforeChange='checkCustomer'
             )
                 customer-step
             tab-content(
                 v-if='isSale'
-                title="Cómo quieres pagar?"
-                :beforeChange="checkPaymentMethod"
+                title='Cómo quieres pagar?'
+                :beforeChange='checkPaymentMethod'
             )
                 payment-step
+            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
+                div(
+                    class='wizard-footer-right'
+                )
+                    wizard-button(
+                        v-if='!props.isLastStep'
+                        class='wizard-footer-right'
+                        :style='props.fillButtonStyle'
+                        @click.native='props.nextTab()'
+                    ) Continuar
+                    wizard-button(
+                        v-else
+                        class='wizard-footer-right finish-button'
+                        :style='props.fillButtonStyle'
+                        @click.native='createSale'
+                    ) {{ props.isLastStep ? 'Finalizar' : 'Continuar' }}
+        settings-button(
+            v-show='!loading'
+            @onClick='toggleSettingsVisibility'
+        )
+        settings-modal(
+            :show='settingsVisibility'
+            :settings='settings'
+            @onClose='toggleSettingsVisibility'
+            @onChangeSetting='changeSetting'
+        )
         loading-overlay(:show='loading')
 </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'
 
     import ProductStep from '@@/steps/Product'
     import CustomerStep from '@@/steps/Customer'
     import PaymentStep from '@@/steps/Payment'
-    import { LoadingOverlay } from './components/common'
+    import SettingsModal from './components/modals/SettingsModal'
+    import { LoadingOverlay, SettingsButton } from './components/common'
 
     export default {
         components: {
             FormWizard,
             TabContent,
+            WizardButton,
             ProductStep,
             CustomerStep,
             PaymentStep,
-            LoadingOverlay
+            LoadingOverlay,
+            SettingsButton,
+            SettingsModal
         },
         computed: mapGetters([
             'isSale',
-            'selectedBank',
+            'footerButtonsVisibility',
+            'settingsVisibility',
+            'settings',
             'loading',
             'completed'
         ]),
@@ -62,23 +100,18 @@
             'checkCustomer',
             'checkPaymentMethod',
             'checkAmountReceived',
+            'toggleSettingsVisibility',
+            'changeSetting',
             'createSale',
             'resetSale'
         ]),
         watch: {
-            selectedBank(value) {
-                if (!value) {
-                    return
-                }
-
-                this.$refs.wizard.changeTab(2, 3, false)
-            },
             completed(value) {
                 if (!value) {
                     return
                 }
                 
-                this.$refs.wizard.changeTab(3, 0, false)
+                this.$refs.wizard.changeTab(2, 0, false)
 
                 this.resetSale()
             }
@@ -129,7 +162,7 @@
                 width: 100%
                 height: 50px
                 position: absolute
-                bottom: 10px
+                bottom: 0
                 .wizard-btn
                     width: 160px
                     height: 40px

+ 10 - 3
src/components/common/Card.vue

@@ -28,15 +28,21 @@
                 type: Boolean,
                 default: true
             },
-            options: {
+            currencyOptions: {
                 type: Object,
-                default: {}
+                default: {
+                    symbol: '$',
+                    position: 'before',
+                    thousandsSeparator: '.',
+                    decimalPlaces: 2,
+                    decimalSeparator: ',' 
+                }
             }
         },
         methods: {
             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
@@ -71,6 +77,7 @@
             margin-top: 10px
             position: absolute
             top: 0
+            z-index: 1
         .card-image
             width: 75px
             height: 75px

+ 9 - 3
src/components/common/CardGrid.vue

@@ -12,7 +12,7 @@
                 :image='item.image'
                 :isSelected='item.id === selectedId'
                 :details='computeDetails(item)'
-                :options='defaultOptions.currency'
+                :currencyOptions='currencyOptions'
                 @onClick='onClickCard(item)'
             )
 </template>
@@ -36,9 +36,15 @@
                 type: Array,
                 default: []
             },
-            options: {
+            currencyOptions: {
                 type: Object,
-                default: {}
+                default: {
+                    symbol: '$',
+                    position: 'before',
+                    thousandsSeparator: '.',
+                    decimalPlaces: 2,
+                    decimalSeparator: ',' 
+                }
             }
         },
         components: {

+ 11 - 5
src/components/common/Cart.vue

@@ -1,7 +1,7 @@
 <template lang="pug">
     .cart(:style='{ width: defaultOptions.layout.width, height: defaultOptions.layout.height }')
         .cart-total
-            h2.currency-cart-total {{ total | currency(...defaultOptions.currency) }}
+            h2.currency-cart-total {{ total | currency(...currencyOptions) }}
         .cart-items-wrapper
             transition-group(
                 name='list' 
@@ -13,7 +13,7 @@
                     :key='index'
                     :index='index'
                     :item='item'
-                    :options='defaultOptions.currency'
+                    :currencyOptions='currencyOptions'
                     @onClickQuantity='onClickQuantity'
                     @onChange='onItemChanged'
                     @onClickIncrement='onIncrementQty'
@@ -37,9 +37,15 @@
                 default: [],
                 required: true
             },
-            options: {
-                type: Object || String,
-                default: null
+            currencyOptions: {
+                type: Object,
+                default: {
+                    symbol: '$',
+                    position: 'before',
+                    thousandsSeparator: '.',
+                    decimalPlaces: 2,
+                    decimalSeparator: ',' 
+                }
             }
         },
         methods: {

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

@@ -8,9 +8,9 @@
             @blur='onBlur'
         )
         span.item-x x
-        span.item-price {{ item.price | currency(...options) }}
+        span.item-price {{ item.price | currency(...currencyOptions) }}
         span.item-equals =
-        span.item-subtotal {{ (item.price * (item.quantity || 1)) | currency(...options) }}
+        span.item-subtotal {{ (item.price * (item.quantity || 1)) | currency(...currencyOptions) }}
         .cart-item-options-wrapper
             .cart-item-options
                 .cart-item-option(
@@ -47,7 +47,7 @@
                 type: Object,
                 default: null
             },
-            options: {
+            currencyOptions: {
                 type: Object,
                 default: {
                     symbol: '$',

+ 55 - 11
src/components/common/DropdownSearcher.vue

@@ -1,18 +1,25 @@
 <template lang="pug">
     .searcher
-        span.input-icon.fa.fa-search(@click='onClickOptions')
+        span.input-icon.fa.fa-search(
+            ref='searchSpan'
+            @click='onClickOptions'
+        )
         input.search-input(
+            autofocus
             v-model='search'
             :placeholder='placeholder'
-            autofocus
         )
-        .dropdown-options(:class="{'input-show': showOptions }")
+        .dropdown-options(
+            ref='dropdownOptions'
+            :class="{'input-show': showOptions }"
+        )
             ul.input-options
                 li.input-option(
                     v-for='option in getOptions()'
                     :key='option.id'
                     @click='onSelectOption(option)'
-                ) {{ option.name }}
+                ) 
+                    h2 {{ option.name }}
 </template>
 
 <script>
@@ -20,7 +27,7 @@
         props: {
             placeholder: {
                 type: String,
-                default: 'Buscar'
+                default: ''
             },
             autofocus: {
                 type: Boolean,
@@ -78,6 +85,9 @@
                     }
                 }
             },
+            hideOptions() {
+                this.showOptions = false
+            },
             onClickOptions() {
                 this.showOptions = !this.showOptions || !!this.search
             },
@@ -88,8 +98,33 @@
                 this.results = []
                 
                 this.$emit('onSelect', item)
+            },
+            onClickOutside(e) {
+                let searchSpan = this.$refs.searchSpan
+
+                if (!searchSpan) {
+                    return
+                }
+
+                let target = e.target
+
+                if (target === searchSpan) {
+                    return
+                }
+
+                let el = this.$refs.dropdownOptions
+
+                if (el !== target && !el.contains(target))  {
+                    this.hideOptions()
+                }
             }
         },
+        created() {
+            document.addEventListener('click', this.onClickOutside)
+        },
+        destroyed() {
+            document.removeEventListener('click', this.onClickOutside)
+        },
         data() {
             return {
                 search: '',
@@ -109,7 +144,7 @@
         position: relative
         .input-icon
             position: absolute
-            top: 14px
+            top: 10px
             right: 10px
             font-size: 12pt
             color: $app-dark-color
@@ -121,14 +156,17 @@
             border-radius: 0
             font-size: 12pt
             font-weight: normal
+            padding-right: 35px
         .dropdown-options
+            width: 100%
+            height: 150px
             display: none
             position: absolute
             background: $app-light-color
             border: 1px solid $app-separator-color
             box-shadow: 0 3px 5px $app-separator-color
             z-index: 10
-            top: 45px
+            top: 35px
             left: 0
             right: 0
             bottom: -325px
@@ -137,13 +175,15 @@
             overflow-y: auto
             &.input-show
                 display: block
-            ul
-                li
+            .input-options
+                padding-left: 0
+                .input-option
                     height: 35px
                     display: block
                     text-align: left
-                    margin: 10px 0 0 10px
-                    font-size: 12pt
+                    margin-top: 5px
+                    padding-top: 5px
+                    font-size: 10pt
                     font-weight: normal
                     border-bottom: 1px solid $app-border-color
                     &:last-child
@@ -151,4 +191,8 @@
                     &:hover
                         border-bottom: 2px solid $app-main-color
                         cursor: pointer
+                    h2
+                        font-size: 10pt
+                        font-weight: normal
+                        margin: 0
 </style>

+ 9 - 5
src/components/common/InputDropdown.vue

@@ -31,8 +31,8 @@
     export default {
         props: {
             value: {
-                type: String,
-                default: ''
+                type: Number,
+                default: 0
             },
             format: {
                 type: String,
@@ -67,6 +67,7 @@
                     if (this.format === 'number') {
                         value = this.formatValue(value)
                         value = !!this.value ? value : value.replace(/\d/, '')
+                        value = value.length === 0 ? 0 : value
                     }
 
                     return value
@@ -130,10 +131,10 @@
                 this.$emit('onChangeValue', value)
             },
             hasPrefix() {
-                return this.prefix.length !== 0
+                return !!this.prefix && this.prefix.length !== 0
             },
             hasSuffix() {
-                return this.suffix.length !== 0
+                return !!this.suffix && this.suffix.length !== 0
             },
             hasOptions() {
                 return this.options.length !== 0
@@ -185,6 +186,8 @@
 </script>
 
 <style lang="sass">
+    @import '../../assets/variables'
+
     .input-group
         position: relative
         width: 100%
@@ -226,7 +229,8 @@
                 border: 1px solid #ccc
                 border-radius: 0
                 box-shadow: none
-                background: #e0e0e0
+                background: $app-main-color
+                color: #fff
                 z-index: 2
                 position: relative
                 user-select: none

+ 63 - 0
src/components/common/SettingsButton.vue

@@ -0,0 +1,63 @@
+<template lang="pug">
+    .settings-button(
+        @click='onClick'
+        @mouseover='onHover'
+        @mouseleave='onHover'
+    )
+        i.fa.fa-cog(
+            aria-hidden='true'
+            :class="{'fa-spin': hovered}"
+        )
+</template>
+
+<script>
+    export default {
+        methods: {
+            onHover(e) {
+                if (e.type === 'mouseover') {
+                    this.hovered = true
+                    return
+                }
+
+                this.hovered = false
+            },
+            onClick(e) {
+                this.$emit('onClick')
+            }
+        },
+        data() {
+            return {
+                hovered: false
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .settings-button
+        width: 45px;
+        height: 45px;
+        position: absolute;
+        top: 0;
+        right: 0;
+        background: $app-main-color;
+        border-radius: 0 0 0 90%;
+        &:hover
+            cursor: pointer
+        .fa
+            display: inline-block
+            position: relative
+            font-size: 18pt
+            margin: 0
+            border: none
+            top: 45%
+            left: 60%
+            transform: translate(-50%, -50%)
+            color: $app-bg-color
+            &.fa-spin
+                top: 18% !important
+                left: 38% !important
+                border: none !important
+</style>

+ 1 - 0
src/components/common/Spinner.vue

@@ -32,6 +32,7 @@
 
 <style lang="sass">
     @import '../../assets/variables'
+    
     .spinner
         .spinner-wave
             $rect-count: 5

+ 71 - 0
src/components/common/SwitchButtonInput.vue

@@ -0,0 +1,71 @@
+<template lang="pug">
+    .switch-button-input
+        button.switch-option(
+            id='primary'
+            :value='primaryValue'
+            :class="{'selected-option': selectedOption}"
+            @click.prevent='onChange'
+        ) {{ primaryValue }}
+        button.switch-option(
+            id='secondary'
+            :value='secondaryValue'
+            :class="{'selected-option': !selectedOption}"
+            @click.prevent='onChange'
+        ) {{ secondaryValue }}
+</template>
+
+<script>
+    export default {
+        props: {
+            primaryValue: {
+                type: String,
+                required: true
+            },
+            secondaryValue: {
+                type: String,
+                required: true
+            },
+            selectedValue: {
+                type: String,
+                default: null
+            }
+        },
+        methods: {
+            onChange(e) {
+                this.selectedOption = e.target.id === 'primary'
+                this.selectedValue = e.target.value
+
+                this.$emit('onChange', this.selectedOption)
+            }
+        },
+        data() {
+            return {
+                selectedOption: true
+            }
+        },
+        mounted() {
+            this.selectedOption = this.selectedValue === this.primaryValue
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+
+    .switch-button-input
+        .switch-option
+            width: 50%
+            height: 35px
+            border: 1px solid transparent
+            border-color: #adadad
+            box-shadow: none
+            border-radius: 0
+            background: $app-bg-color
+            &:hover
+                background: $app-light-color
+            &.selected-option
+                background: $app-main-color
+                box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125)
+                border-color: $app-main-color
+                color: $app-bg-color
+</style>

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

@@ -6,6 +6,8 @@ import Spinner from './Spinner'
 import DropdownSearcher from './DropdownSearcher'
 import InputDropdown from './InputDropdown'
 import LoadingOverlay from './LoadingOverlay'
+import SettingsButton from './SettingsButton'
+import SwitchButtonInput from './SwitchButtonInput'
 
 export {
     CardGrid,
@@ -15,5 +17,7 @@ export {
     Spinner,
     DropdownSearcher,
     InputDropdown,
-    LoadingOverlay
+    LoadingOverlay,
+    SettingsButton,
+    SwitchButtonInput
 }

+ 2 - 1
src/components/forms/CustomerForm.vue

@@ -84,7 +84,8 @@
 </script>
 
 <style lang="sass">
-    @import '../../assets/variables' 
+    @import '../../assets/variables'
+    
     .customer-form
         &.customer-form-small
             width: 320px

+ 202 - 63
src/components/modals/BankPaymentModal.vue

@@ -3,7 +3,7 @@
         name='payment-bank-modal'
         adaptive='true'
         width='800px'
-        height='500px'
+        height='auto'
         transition='nice-modal-fade'
         :classes="['v--modal', 'payment-bank-modal']"
         @before-close='beforeClose'
@@ -11,60 +11,125 @@
         form-wizard(
             title='Pago Bancario'
             subtitle=''
-            next-button-text='Continuar'
-            back-button-text='Volver'
-            finish-button-text='Completar'
             color='#7c7bad'
         )
             tab-content(
                 title='Qué tipo de operación es?'
+                :beforeChange='checkJournalSelectionStep'
             )
-                form.journal-form
-                    ul
-                        li
-                            input.form-input(
-                                type='radio'
-                                id='cash'
-                            )
-                            label Banco (PYG)
-                        li
-                            input.form-input(
-                                type='radio'
-                                id='cash'
-                            )
-                            label Cheques (PYG)
-                        li
-                            input.form-input(
-                                type='radio'
-                                id='cash'
-                            )
-                            label Tarjeta de crédito (PYG)
-                        li
-                            input.form-input(
-                                type='radio'
-                                id='cash'
-                            )
-                            label Tarjeta de débito (PYG)
-                        li
-                            input.form-input(
-                                type='radio'
-                                id='cash'
-                            )
-                            label Billera Tigo (PYG)
-            tab-content(
-                title='Qué detalles necesita?'
-            )
-            tab-content(
-                title='De qué monto es la operación?'
+                card-grid(
+                    :items='journals'
+                    @onSelect='selectBankJournal'
+                )
+            tab-content(title='Qué detalles necesita?')
+                form.payment-details-form
+                    .form-item
+                        label.form-label Tipo de Pago
+                        select.form-input(v-model='selectedBankPaymentTypeId')
+                            option(
+                                v-for='bankPaymentType in bankPaymentTypes'
+                                :value='bankPaymentType.id'
+                            ) {{ bankPaymentType.name }}
+                    .form-item(v-show="canBeShow('number_cta')")
+                        label.form-label Nº de Cuenta
+                        input.form-input
+                    .form-item(v-show="canBeShow('date_maturity')")
+                        label.form-label Vencimiento
+                        input.form-input
+                    .form-item(v-show="canBeShow('check_type_id')")
+                        label.form-label Tipo de Cheque
+                        select.form-input(v-model='selectedChequeTypeId')
+                            option(
+                                v-for='chequeType in chequeTypes'
+                                :value='chequeType.id'
+                            ) {{ chequeType.name }}
+                    .form-item(v-show="canBeShow('name_holder')")
+                        label.form-label Titular
+                        input.form-input
+                    .form-item
+                        label.form-label Nº de Comprobante
+                        input.form-input
+                    .form-item(v-show="canBeShow('bank_id')")
+                        label.form-label Banco
+                        dropdown-searcher.form-input(
+                            :items='banks'
+                            @onSelect='selectBank'
+                        )
+                    .form-item(v-show="canBeShow('number')")
+                        label.form-label Nº de Vale
+                        input.form-input
+                    .form-item(v-show="canBeShow('number_cta_origin')")
+                        label.form-label Nº de Cuenta Origen
+                        input.form-input
+            tab-content(title='De qué monto es la operación?')
+                form.payment-details-form
+                    .form-item(v-show="canBeShow('amount_total')")
+                        label.form-label Monto del Pago
+                        input.form-input
+            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='props.nextTab()'
+                    ) Siguiente
+                    wizard-button(
+                        v-else
+                        class='wizard-footer-right finish-button'
+                        :style='props.fillButtonStyle'
+                        @click.native='onDone'
+                    ) {{ props.isLastStep ? 'Hecho' : 'Siguiente' }}
 </template>
 
 <script>
-    import { FormWizard, TabContent } from 'vue-form-wizard'
+    import { FormWizard, TabContent, WizardButton } from 'vue-form-wizard'
+    import { CardGrid, DropdownSearcher } from '../common'
 
     export default {
         props: {
+            journals: {
+                type: Array,
+                required: true
+            },
+            hasSelectedJournal: {
+                type: Boolean,
+                required: true
+            },
+            banks: {
+                type: Array,
+                required: true
+            },
+            bankPaymentTypes: {
+                type: Array,
+                required: true
+            },
+            selectedBankPaymentType: {
+                type: Object,
+                required: true
+            },
+            chequeTypes: {
+                type: Array,
+                required: true
+            },
+            selectedChequeType: {
+                type: Object,
+                required: true
+            },
             show: {
                 type: Boolean,
                 required: true
@@ -72,7 +137,28 @@
         },
         components: {
             FormWizard,
-            TabContent
+            TabContent,
+            WizardButton,
+            DropdownSearcher,
+            CardGrid
+        },
+        computed: {
+            selectedBankPaymentTypeId: {
+                get() {
+                    return this.selectedBankPaymentType && this.selectedBankPaymentType.id
+                },
+                set(value) {
+                    this.changeBankPaymentType(value)
+                }
+            },
+            selectedChequeTypeId: {
+                get() {
+                    return this.selectedChequeType && this.selectedChequeType.id
+                },
+                set(value) {
+                    this.changeChequeType(value)
+                }
+            }
         },
         watch: {
             show(value) {
@@ -81,6 +167,12 @@
                     return
                 }
 
+                if (this.journals.length === 0) {
+                    this.onCancel()
+                    this.notify('No hay diarios definidos para pagos bancarios')
+                    return
+                }
+
                 this.$modal.show('payment-bank-modal')
             }
         },
@@ -89,11 +181,40 @@
                 if (this.show) {
                     e.stop()
                 }
+            },
+            checkJournalSelectionStep() {
+                if (!this.hasSelectedJournal) {
+                    this.notify('Debes seleccionar el tipo de operación')
+                    return false
+                }
+
+                if (this.bankPaymentTypes.length === 0) {
+                    this.notify('No hay tipos de pago definidos para éste tipo de operación')
+                    return false
+                }
 
-                console.log(this.show)
+                return true
+            },
+            canBeShow(formItem) {
+                return this.selectedBankPaymentType && this.selectedBankPaymentType.fieldsAllowed.indexOf(formItem) !== -1
+            },
+            selectBankJournal(journal) {
+                this.$emit('onChangeBankJournal', journal.id)
+            },
+            changeBankPaymentType(id) {
+                this.$emit('onChangeBankPaymentType', id)
+            },
+            notify(message) {
+                this.$emit('onNotify', message)
+            },
+            changeChequeType(id) {
+                this.$emit('onChangeChequeType', id)
+            },
+            selectBank(bank) {
+                this.$emit('onSelectBank', bank.id)
             },
-            onFinalize() {
-                this.$emit('onFinalize')
+            onDone() {
+                this.$emit('onDone')
             },
             onCancel() {
                 this.$emit('onCancel')
@@ -112,21 +233,39 @@
             background-size: cover
             filter: blur(3px)
             z-index: -1
-        .wizard-tab-container
-            display: flex !important
-            justify-content: center !important
-            align-items: center !important
-            .journal-form
-                width: 400px
-                background: #fff
-                ul
-                    list-style: none
-                    li
-                        margin-bottom: 3px
-                        input
-                            width: 20px
-                            height: 20px
-                        label
+        .wizard-tab-content
+            padding-bottom: 50px !important
+            .wizard-tab-container
+                justify-content: center !important
+                align-items: center !important
+                .payment-details-form
+                    width: 100%
+                    .form-item
+                        width: 100%
+                        height: 35px
+                        margin-bottom: 15px
+                        & > .form-label, > .form-input
+                            display: inline-block
+                            vertical-align: top
+                        .form-label
+                            width: 200px
+                            height: 35px
+                            font-size: 13pt
+                            line-height: 30px
+                        .form-input
+                            width: 400px
+                            height: 35px
                             font-size: 12pt
-                            margin: 0 35px 15px 5px
+                            border-radius: 0
+                            &.input-only
+                                margin-left: 200px
+                                margin-bottom: 15px
+                        .form-item-option
+                            display: inline-block
+                            input
+                                width: 20px
+                                height: 20px
+                            label
+                                font-size: 12pt
+                                margin: 0 35px 15px 5px
 </style>

+ 31 - 7
src/components/modals/DiscountModal.vue

@@ -1,24 +1,48 @@
 <template lang="pug">
-    modal(name='product-discount' transition='nice-modal-fade' @before-close='beforeClose' :classes="['v--modal', 'product-discount']")
+    modal(
+        name='product-discount'
+        transition='nice-modal-fade'
+        :classes="['v--modal', 'product-discount']"
+        @before-close='beforeClose'
+    )
         form
             .discount-item
                 label.discount-label Precio unitario
-                input.discount-input(:value='(!item || item.price) | currency(...options)' readonly)
+                input.discount-input(
+                    readonly
+                    :value='(!item || item.price) | currency(...options)'
+                )
             .discount-item
                 label.discount-label Precio mínimo
-                input.discount-input(:value='(!item || item.minimumPrice) | currency(...options)' readonly)
+                input.discount-input(
+                    readonly
+                    :value='(!item || item.minimumPrice) | currency(...options)'
+                )
             .discount-item
                 label.discount-label Precio máximo
-                input.discount-input(:value='(!item || item.maximumPrice) | currency(...options)' readonly)
+                input.discount-input(
+                    readonly
+                    :value='(!item || item.maximumPrice) | currency(...options)'
+                )
             hr
             .discount-item
                 label.discount-label Precio aplicado
-                input.discount-input(v-model='formattedAmmount' :class="{'discount-input-invalid': !isValid()}" autofocus)
+                input.discount-input(
+                    autofocus
+                    v-model='formattedAmmount'
+                    :class="{'discount-input-invalid': !isValid()}"
+                )
             .discount-item
                 label.discount-label {{ discount < 0 ? 'Ganancia' : 'Descuento' }}
-                input.discount-input(:value='discount | absolute | currency(...options)' readonly)
+                input.discount-input(
+                    readonly
+                    :value='discount | absolute | currency(...options)'
+                )
             .discount-options
-                button.discount-button(@click.prevent='onAccept' :disabled='isValid() === false') Aceptar
+                button.discount-button(
+                    :disabled='isValid() === false'
+                    @click.prevent='onAccept'
+                ) Aceptar
                 button.discount-button(@click.prevent='onCancel') Cancelar
 </template>
 

+ 6 - 1
src/components/modals/DocumentSelector.vue

@@ -1,5 +1,10 @@
 <template lang="pug">
-    modal(name='document-modal' transition='nice-modal-fade' @before-close='beforeClose' :classes="['v--modal', 'document-modal']")
+    modal(
+        name='document-modal'
+        transition='nice-modal-fade'
+        :classes="['v--modal', 'document-modal']"
+        @before-close='beforeClose'
+    )
         h2.document-title Seleccione el tipo de impresión
         ul.document-types
             li.document-choice(@click="onClick('ticket')")

+ 122 - 0
src/components/modals/SettingsModal.vue

@@ -0,0 +1,122 @@
+<template lang="pug">
+    modal(
+        name='settings-modal'
+        adaptive='true'
+        transition='nice-modal-fade'
+        :classes="['v--modal', 'settings-modal']"
+        @before-close='beforeClose'
+    )
+        .form-header
+            h2 Configuraciones
+            hr
+        form.settings-form
+            .form-item
+                label.form-label Imagen
+                switch-button-input.form-input(
+                    primary-value='Pequeña'
+                    secondary-value='Grande'
+                    :selected-value="settings.imageType ? 'Pequeña' : 'Grande'"
+                    @onChange='changeImageType'
+                )
+            .form-item
+                label.form-label Cambio de moneda
+                switch-button-input.form-input(
+                    primary-value='Permitir'
+                    secondary-value='No permitir'
+                    :selected-value="settings.allowExchange ? 'Permitir' : 'No permitir'"
+                    @onChange='changeAllowExchange'
+                )
+            .form-item
+                label.form-label Ver en otras cotizaciones
+                switch-button-input.form-input(
+                    primary-value='Sí'
+                    secondary-value='No'
+                    :selected-value="settings.viewExchanges ? 'Sí' : 'No'"
+                    @onChange='changeViewExchanges'
+                )
+</template>
+
+<script>
+    import { SwitchButtonInput } from '../common'
+
+    export default {
+        props: {
+            show: {
+                type: Boolean,
+                required: true
+            },
+            settings: {
+                type: Object,
+                required: true
+            }
+        },
+        components: {
+            SwitchButtonInput
+        },
+        watch: {
+            show(value) {
+                if (value) {
+                    this.$modal.show('settings-modal')
+                    return
+                }
+
+                this.$modal.hide('settings-modal')
+            }
+        },
+        methods: {
+            beforeClose(e) {
+                this.$emit('onClose')
+            },
+            changeImageType(value) {
+                this.changeSettings('imageType', value)  
+            },
+            changeAllowExchange(value) {
+                this.changeSettings('allowCurrencyExchange', value)
+            },
+            changeViewExchanges(value) {
+                this.changeSettings('viewCurrencyExchanges', value)
+            },
+            changeSettings(setting, value) {
+                this.$emit('onChangeSetting', {
+                    setting,
+                    value
+                })
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables' 
+
+    .settings-modal
+        .form-header
+            h2
+                font-size: 10pt
+                color: $app-border-color
+                margin-left: 15px
+            hr
+                margin: 0 15px
+        .settings-form
+            padding: 25px 35px
+            .form-item
+                width: 100%
+                height: 35px
+                margin-bottom: 15px
+                & > .form-label, > .form-input
+                    display: inline-block
+                    vertical-align: top
+                .form-label
+                    width: 250px
+                    height: 35px
+                    font-size: 13pt
+                    line-height: 30px
+                .form-input
+                    width: 250px
+                    height: 35px
+                    font-size: 12pt
+                    border-radius: 0
+                    &.input-only
+                        margin-left: 200px
+                        margin-bottom: 15px
+</style>

+ 7 - 1
src/components/modals/VariantModal.vue

@@ -1,5 +1,11 @@
 <template lang="pug">
-    modal(name='variant-selector' transition='nice-modal-fade' height="500" @closed='handleClosed' :classes="['v--modal', 'variant-modal']")
+    modal(
+        name='variant-selector'
+        transition='nice-modal-fade'
+        height='500'
+        :classes="['v--modal', 'variant-modal']"
+        @closed='handleClosed'
+    )
         searcher(:items='getItems()' :keys="['name']" @onSearch='filterVariants')
         .product-variants
             .product-variant(v-for='item in getItems()' :key='item.id' @click='selectProduct(item)')

+ 23 - 4
src/components/steps/Customer.vue

@@ -2,11 +2,30 @@
     .pos-step
         .customer-selection-step
             .customer-selector
-                searcher(:items='customers' :keys="['name', 'phone', 'mobile', 'email']" @onSearch='filterCustomers')
-                card-grid(:items='visibleCustomers' :loading='loadingCustomers' canAdd @onAdd='showCustomerForm' @onSelect='selectCustomer')
-                customer-modal(:show='showingCustomerForm' @onAccept='submitCustomer' @onCancel='hideCustomerForm')
+                searcher(
+                    :items='customers'
+                    :keys="['name', 'phone', 'mobile', 'email']"
+                    @onSearch='filterCustomers'
+                )
+                card-grid(
+                    canAdd
+                    :items='visibleCustomers'
+                    :loading='loadingCustomers'
+                    @onAdd='showCustomerForm'
+                    @onSelect='selectCustomer'
+                )
+                customer-modal(
+                    :show='showingCustomerForm'
+                    @onAccept='submitCustomer'
+                    @onCancel='hideCustomerForm'
+                )
             transition(name='slide-fade')
-                customer-form(v-if='!!selectedCustomer' :customer='selectedCustomer' mode='details' type='small')
+                customer-form(
+                    type='small'
+                    mode='details'
+                    v-if='!!selectedCustomer'
+                    :customer='selectedCustomer'
+                )
 </template>
 
 <script>

+ 109 - 40
src/components/steps/Payment.vue

@@ -1,29 +1,25 @@
 <template lang="pug">
     .pos-step
-        ticket
+        ticket(
+            :companyName='companyName' 
+            :items='cartItems'
+            :total='amountToPay'
+            :defaultCurrency='selectedCurrency'
+            :customerName='selectedCustomerName'
+        )
         form
             //- input para forma de pago
             .form-item
                 label.form-label Forma de Pago
-                .form-item-option
-                    input.form-input(
-                        type='radio'
-                        id='cash'
-                        value='cash'
-                        v-model='selectedPaymentType'
-                    )
-                    label(for='cash') Contado
-                .form-item-option
-                    input.form-input(
-                        type='radio'
-                        id='credit'
-                        value='credit'
-                        v-model='selectedPaymentType'
-                    )
-                    label(for='credit') Crédito
+                switch-button-input.form-input(
+                    primary-value='Contado'
+                    secondary-value='Crédito'
+                    :selected-value="paymentType === 'cash' ? 'Contado' : 'Crédito'"
+                    @onChange="changePaymentType($event ? 'cash' : 'credit')"
+                )
             //- input para condiciones de pago en caso de pago a crédito
             transition(name='fade')
-                .form-item(v-show="selectedPaymentType === 'credit'")
+                .form-item(v-show="paymentType === 'credit'")
                     select.form-input.input-only(v-model='paymentTermId')
                         option(
                             :value='term.id' 
@@ -34,8 +30,8 @@
             .form-item
                 label.form-label Monto a Pagar
                 input-dropdown.form-input(
-                    value='0'
                     format='number'
+                    :value='amountToPay'
                     :editable='false'
                     :suffix='currencySymbol'
                     :options='currencySymbols'
@@ -46,19 +42,25 @@
             .form-item
                 label.form-label Monto Recibido
                 input-dropdown.form-input(
-                    value='0'
+                    ref='initialAmount'
                     format='number'
+                    :value='initialPayment'
                     :suffix='paymentMethod'
                     :options='paymentMethods'
                     :focus='true'
                     @onClickOption='changePaymentMethod'
+                    @onChangeValue='changeAmountReceived($event)'
                 )
             //- input para el vuelto del pago en caso de pago en efectivo
-            div(v-show="selectedPaymentType === 'cash'")
+            div(v-show="paymentType === 'cash'")
                 hr
                 .form-item
                     label.form-label Vuelto
-                    input-dropdown.form-input(value='0')
+                    input-dropdown.form-input(
+                        format='number'
+                        :value='amountResidual'
+                        :editable='false'
+                    )
             //- input para el monto de cuotas calculadas en caso de pago a crédito
             transition(name='fade')
                 .form-item-table(v-show="paymentType === 'credit'")
@@ -67,63 +69,128 @@
                             tr
                                 th Monto a Pagar
                                 th Fecha de Pago
+                        tbody
+                            tr(v-for='line in paymentLines')
+                                td {{ line.total | currency(...selectedCurrency) }}
+                                td {{ line.date }}
         bank-payment-modal(
+            :journals='bankJournals'
+            :hasSelectedJournal='hasBankJournalSelected'
+            :banks='banks'
+            :bankPaymentTypes='bankPaymentTypes'
+            :selectedBankPaymentType='selectedBankPaymentType'
+            :chequeTypes='chequeTypes'
+            :selectedChequeType='selectedChequeType'
             :show='showBankPayment'
-            @onAccept='',
-            @onCancel=`changePaymentMethod('Efectivo')`
+            @onNotify='notify'
+            @onChangeBankJournal='changeBankJournal'
+            @onChangeBankPaymentType='changeBankPaymentType'
+            @onChangeChequeType='changeChequeType'
+            @onSelectBank='changeBank'
+            @onDone='endBankPayment'
+            @onCancel='cancelBankPayment'
         )
 </template>
 
 <script>
     import { mapGetters, mapActions } from 'vuex'
-    import { Ticket, InputDropdown } from '../common'
+    import { Ticket, SwitchButtonInput, InputDropdown } from '../common'
     import BankPaymentModal from '../modals/BankPaymentModal'
 
     export default {
         components: {
             Ticket,
+            SwitchButtonInput,
             InputDropdown,
             BankPaymentModal
         },
         computed: {
-            selectedPaymentType: {
-                get() {
-                    return this.paymentType
-                },
-                set(value) {
-                    this.changePaymentType(value)
-                }
-            },
             paymentTermId: {
                 get() {
                     return (this.paymentTerm && this.paymentTerm.id) || -1
                 },
                 set(value) {
                     this.selectPaymentTerm(value)
+
+                    if (this.paymentType === 'credit') {
+                        this.computePaymentLines()		
+                    }
                 }
             },
             ...mapGetters([
+                'companyName',
+                'amountToPay',
+                'initialPayment',
+                'amountResidual',
+                'paymentLines',
+                'cartItems',
                 'paymentType',
                 'paymentTerm',
                 'paymentMethod',
-                'currency',
                 'currencySymbol',
+                'showBankPayment',
+                'hasBankJournalSelected',
+                'selectedCustomerName',
+                'selectedCurrency',
+                'selectedJournal',
+                'selectedBankPaymentType',
+                'selectedChequeType',
                 'currencies',
                 'currencySymbols',
-                'selectedJournal',
                 'journals',
+                'bankJournals',
                 'paymentTerms',
                 'paymentMethods',
-                'showBankPayment'
+                'banks',
+                'bankPaymentTypes',
+                'chequeTypes'
             ])
         },
+        watch: {
+            paymentType() {
+                this.focusInitialPayment()
+            },
+            paymentTerm() {
+                this.focusInitialPayment()
+            },
+            selectedCurrency() {
+                this.focusInitialPayment()
+            }
+        },
         methods: {
+            focusInitialPayment() {
+                this.$nextTick(() => this.$refs.initialAmount.$el.children[0].children[0].focus())
+            },
+            endBankPayment() {
+                this.toggleBankPayment()
+            },
+            changeBankJournal(journalId) {
+                this.selectJournal(journalId)
+                this.changeBankPaymentType()
+            },
+            cancelBankPayment() {
+                console.log('canceling')
+                this.toggleBankPayment()
+                this.changePaymentMethod('Efectivo')
+                this.autoSelectJournal()
+            },
+            changeAmountReceived(amount) {
+                this.changeInitialPayment(amount)
+            },
             ...mapActions([
-                'changePaymentType',
-                'changePaymentMethod',
+                'autoSelectJournal',
+                'changeCurrency',
                 'selectPaymentTerm',
                 'selectJournal',
-                'changeCurrency'
+                'changePaymentType',
+                'changePaymentMethod',
+                'changeBankPaymentType',
+                'changeChequeType',
+                'changeBank',
+                'changeInitialPayment',
+                'computePaymentLines',
+                'toggleBankPayment',
+                'notify'
             ])
         }
     }
@@ -131,6 +198,7 @@
 
 <style lang="sass">
     @import '../../assets/variables'
+
     .pos-step
         width: 100%
         height: calc(100% - 50px)
@@ -152,8 +220,9 @@
                 .form-label
                     width: 200px
                     height: 35px
-                    font-size: 13pt
+                    font-size: 12pt
                     line-height: 30px
+                    color: $app-dark-color
                 .form-input
                     width: 400px
                     height: 35px

+ 0 - 180
src/components/steps/PaymentAmount.vue

@@ -1,180 +0,0 @@
-<template lang="pug">
-    .pos-step
-        ticket(:customerName='selectedCustomer && selectedCustomer.name' :companyName='user && user.company.name' :total='cartTotal' :items='cartItems' :defaultCurrency='selectedCurrency')
-        form.payment-amount
-            .form-loading(v-show='processing')
-                .form-overlay
-                .form-spinner
-                    spinner(type='wave')
-            .form-separator
-                h3 Detalles del Pago
-                hr
-            .form-item
-                label.form-label Monto a Pagar
-                input.form-input(:value='cartTotal | currency(...selectedCurrency)' readonly)
-            .form-item
-                label.form-label Monto Recibido
-                input.form-input(v-model='amountReceived' autofocus)
-            .form-item(v-show="paymentType === 'cash'")
-                hr
-                label.form-label Monto a Devolver
-                input.form-input(:value='paymentResidual | currency(...selectedCurrency)' readonly)
-            .form-item-table(v-show="paymentType === 'credit'")
-                table
-                    thead
-                        tr
-                            th Monto a Pagar
-                            th Fecha de Pago
-                    tbody
-                        tr(v-for='line in paymentLines')
-                            td {{ line.total | currency(...selectedCurrency) }}
-                            td {{ line.date }}
-        document-selector(:show='askForPrint' @onPrint='processPrint' @onCancel='processPrint')
-</template>
-
-<script>
-    import { mapGetters, mapActions } from 'vuex'
-
-    import Ticket from '@@/common/Ticket'
-    import Spinner from '@/components/common/Spinner'
-    import DocumentSelector from '@/components/modals/DocumentSelector'
-
-    import { CHANGE_INITIAL_PAYMENT, COMPUTE_PAYMENT_LINES, PROCESS_PRINT } from '@/constants/actionTypes'
-
-    export default {
-        components: {
-            Ticket,
-            Spinner,
-            DocumentSelector
-        },
-        computed: {
-            amountReceived: {
-                get() {
-                    let formatted = this.$options.filters.currency(this.initialPayment, {...this.selectedCurrency})
-
-                    return !!this.initialPayment ? formatted : formatted.replace(/\d/, '')
-                },
-                set(value) {
-                    value = value.replace(/[\.|,](\d{0,2}$)/, '?$1').split(/\?/)
-                    value[0] = value[0].replace(/[^0-9]/g, '')
-                    value = Number.parseFloat(value.join('.')) || 0
-
-                    this.changeInitialPayment(value)
-                    this.computePaymentResidual(value)
-
-                    if (this.paymentType === 'credit') {
-                       this.computePaymentLines()		
-                    }
-                }
-            },
-            ...mapGetters([
-                'user',
-                'selectedCustomer',
-                'cartItems',
-                'cartTotal',
-                'paymentTerms',
-                'paymentType',
-                'paymentLines',
-                'initialPayment',
-                'paymentResidual',
-                'selectedCurrency',
-                'processing',
-                'askForPrint'
-            ])
-        },
-        methods: {
-            computePaymentResidual(value) {
-                this.paymentResidual = value < this.cartTotal ? 0 : value - this.cartTotal
-            },
-            ...mapActions([
-                CHANGE_INITIAL_PAYMENT,
-                COMPUTE_PAYMENT_LINES,
-                PROCESS_PRINT
-            ])
-        },
-        data() {
-            return {
-                paymentResidual: 0
-            }
-        }
-    }
-</script>
-
-<style lang="sass">
-    @import '../../assets/variables'
-    .pos-step
-        width: 100%
-        height: calc(100% - 50px)
-        padding-bottom: 50px
-        display: flex
-        .payment-amount
-            width: calc(100% - 450px)
-            height: 100%
-            margin-right: 50px
-            padding: 35px
-            background: $app-light-color
-            position: relative
-            .form-loading
-                width: 90%
-                height: 90%
-                position: absolute
-                .form-overlay
-                    width: 100%
-                    height: 100%
-                    background: $app-bg-color
-                    opacity: 0.5
-                    position: absolute
-                .form-spinner
-                    width: 100%
-                    height: 100%
-                    display: flex
-                    justify-content: center
-                    align-items: center
-            .form-separator
-                h3
-                    color: $app-separator-color
-                    font-size: 8pt
-                    margin: 0
-                hr
-                    margin-top: 15px
-            .form-item
-                width: 100%px
-                height: 45px
-                margin-bottom: 15px
-                .form-label
-                    width: 250px
-                    height: 45px
-                    font-size: 14pt
-                .form-input
-                    width: 350px
-                    height: 45px
-                    font-size: 14pt
-                    border-radius: 0
-                    &.input-only
-                        margin-left: 250px
-                        margin-bottom: 15px
-            .form-item-table
-                width: 100%
-                height: 200px
-                border: 1px solid $app-border-color
-                overflow-y: auto
-                table
-                    width: 100%
-                    thead
-                        th
-                            line-height: 35px
-                            padding-left: 10px
-                        th:nth-child(1)
-                            width: 200px
-                        th:nth-child(2)
-                            width: 200px
-                    tbody
-                        td
-                            height: 35px
-                            padding-left: 10px
-
-                        td:nth-child(1)
-                            width: 200px
-                        td:nth-child(2)
-                            width: 200px
-</style>

+ 0 - 148
src/components/steps/PaymentMethod.vue

@@ -1,148 +0,0 @@
-<template lang="pug">
-    .pos-step
-        ticket(:customerName='selectedCustomer && selectedCustomer.name' :companyName='user && user.company.name' :total='cartTotal' :items='cartItems' :defaultCurrency='selectedCurrency')
-        form.payment-method
-            .form-separator
-                h3 Detalles del Cliente
-                hr
-            .form-item
-                label.form-label Cliente
-                input.form-input(:value='selectedCustomer && selectedCustomer.name' readonly)
-            transition(name='fade')
-                .form-item(v-if="payment === 'credit'")
-                    label.form-label Crédito
-                    input.form-input(:value='customerCredit' readonly)
-            .form-separator
-                h3 Detalles del Pago
-                hr
-            .form-item
-                label.form-label Forma de Pago
-                .form-item-option
-                    input.form-input(type='radio' id='cash' value='cash' v-model='payment')
-                    label(for='cash') Contado
-                .form-item-option
-                    input.form-input(type='radio' id='credit' value='credit' v-model='payment')
-                    label(for='credit') Crédito
-            transition(name='fade')
-                .form-item(v-if="payment === 'credit'")
-                    select.form-input.input-only(v-model='paymentTermId')
-                        option(v-for='term in paymentTerms' :value='term.id' v-if="term.lines.length > 0 && (term.lines[0].days !== 0 || term.lines[0].value !==  'balance')") {{ term.displayName }}
-                .form-item(v-else)
-                    label.form-label Método de Pago
-                    select.form-input(v-model='journalId')
-                        option(v-for='journal in journals' :value='journal.id') {{ journal.displayName }}
-        payment-bank-modal(:show='!!showBankPaymentModal' :banks='banks' :paymentTypes='bankPaymentTypes' @onSubmit='submitBankPayment')
-</template>
-
-<script>
-    import { mapGetters, mapActions } from 'vuex'
-
-    import Ticket from '@@/common/Ticket'
-    import PaymentBankModal from '@@/modals/PaymentBankModal'
-
-    export default {
-        components: {
-            Ticket,
-            PaymentBankModal
-        },
-        computed: {
-            paymentTermId: {
-                get() {
-                    return (this.selectedPaymentTerm && this.selectedPaymentTerm.id) || -1
-                },
-                set(value) {
-                    this.selectPaymentTerm(value)
-                }
-            },
-            journalId: {
-                get() {
-                    return (this.selectedJournal && this.selectedJournal.id) || -1
-                },
-                set(value) {
-                   this.selectJournal(value)
-                }
-            },
-            payment: {
-                get() {
-                    return this.paymentType
-                },
-                set(value) {
-                    this.changePaymentType(value)
-
-                    if (value == 'credit') {
-                        this.computePaymentLines()
-                    }
-                }
-            },
-            ...mapGetters([
-                'user',
-                'selectedCustomer',
-                'cartItems',
-                'cartTotal',
-                'customerCredit',
-                'paymentTerms',
-                'paymentType',
-                'selectedPaymentTerm',
-                'journals',
-                'selectedCurrency',
-                'selectedJournal',
-                'showBankPaymentModal',
-                'banks',
-                'bankPaymentTypes'
-            ])
-        },
-        methods: mapActions([
-            'changePaymentType',
-            'selectJournal',
-            'selectPaymentTerm',
-            'computePaymentLines',
-            'submitBankPayment'
-        ])
-    }
-</script>
-
-<style lang="sass">
-    @import '../../assets/variables'
-    .pos-step
-        width: 100%
-        height: calc(100% - 50px)
-        padding-bottom: 50px
-        display: flex
-        .payment-method
-            width: calc(100% - 450px)
-            height: 100%
-            margin-right: 50px
-            padding: 35px
-            background: $app-light-color
-            .form-separator
-                h3
-                    color: $app-separator-color
-                    font-size: 8pt
-                    margin: 0
-                hr
-                    margin-top: 15px
-            .form-item
-                width: 100%px
-                height: 45px
-                margin-bottom: 15px
-                .form-label
-                    width: 250px
-                    height: 45px
-                    font-size: 14pt
-                .form-input
-                    width: 350px
-                    height: 45px
-                    font-size: 14pt
-                    border-radius: 0
-                    &.input-only
-                        margin-left: 250px
-                        margin-bottom: 15px
-                .form-item-option
-                    display: inline-block
-                    input
-                        width: 20px
-                        height: 20px
-                    label
-                        font-size: 12pt
-                        margin: 0 45px 15px 5px
-</style>

+ 4 - 4
src/components/steps/Product.vue

@@ -11,7 +11,7 @@
                 @onAdd='showProductForm'
                 :items='visibleProducts'
                 :details="['price:c']"
-                :options='currency'
+                :currencyOptions='baseCurrency'
                 :loading='loadingProducts'
                 @onSelect='selectProduct'
             )
@@ -23,14 +23,14 @@
             variant-modal
             discount-modal(
                 :item='itemToDiscount' 
-                :options='currency'
+                :options='baseCurrency'
                 :show='!!itemToDiscount'
                 @onAccept='applyPrice'
                 @onCancel='applyPrice'
             )
         cart(
             :items='cartItems' 
-            :options='currency'
+            :currencyOptions='baseCurrency'
             @onTotalComputed='changeCartTotal'
             @onIncrementQty='addToCart'
             @onUndoPrice='undoPrice'
@@ -64,7 +64,7 @@
                 'showingProductForm',
                 'cartItems',
                 'itemToDiscount',
-                'currency'
+                'baseCurrency'
             ])
         },
         methods: mapActions([

+ 1 - 2
src/index.js

@@ -32,7 +32,7 @@ openerp.eiru_pos = (instance, local) => {
                 components: {
                     App
                 },
-                data: { 
+                data: {
                     mode: this.mode
                 }
             });
@@ -58,4 +58,3 @@ openerp.eiru_pos = (instance, local) => {
 
     instance.web.client_actions.add('eiru_pos.action_launch', 'instance.eiru_pos.PosWidget')
 }
-

+ 86 - 175
src/store/actions.js

@@ -1,165 +1,123 @@
 import axios from 'axios'
 
-import { 
-    INIT_SALE_URL, 
-    CREATE_PRODUCT_URL, 
-    CREATE_CUSTOMER_URL, 
-    PROCESS_SALE_URL 
-} from '@/constants/resourcePaths'
-
-import {
-    SET_MODE,
-    SET_PROCESSING,
-    SET_DATE,
-    SET_ASK_FOR_PRINT,
-    SET_COMPLETED,
-    SET_RESULT
-} from '@/constants/mutationTypes'
-
-import { 
-    INIT_SALE,
-    NOTIFY, 
-    EXPLODE_DATA, 
-    CREATE_PRODUCT, 
-    CREATE_CUSTOMER, 
-    RECEIVE_PRODUCT, 
-    RECEIVE_CUSTOMER, 
-    CHECK_CART, 
-    CHECK_CUSTOMER, 
-    CHECK_PAYMENT_METHOD,
-    CHECK_AMOUNT_RECEIVED, 
-    CREATE_SALE,
-    PROCESS_PRINT,
-    PRINT_TICKET,
-    COMPLETE_SALE,
-    RESET_SALE
-} from '@/constants/actionTypes'
-
 const actions = {
-    /**
-     * 
-     * @param {*} param0 
-     * @param {*} payload 
-     */
-    notify({ commit }, payload) {
-        openerp.web.notification.do_warn('Atención', payload)
+    notify({ commit }, message) {
+        openerp.web.notification.do_warn('Atención', message)
         return false
     },
-    /**
-     * 
-     * @param {*} param0 
-     */
     initSale({ getters, commit, dispatch }, payload) {
         commit('setMode', payload || getters.mode)
         commit('setResult', '')
-        
-        return axios.get(INIT_SALE_URL).then(response => {
+
+        return axios.get('/eiru_sales/init').then(({data}) => {
             commit('setLoading', false)
-            
+            commit('toggleFooterButtonsVisibility')
+
             dispatch('completeSale', false)
-            dispatch('explodeData', response.data)            
+            dispatch('explodeData', data)
         }).catch(error => {
-            console.log(error)
+            console.error(error)
         })
     },
-    /**
-     * 
-     * @param {*} param0 
-     * @param {*} payload 
-     */
-    explodeData({ dispatch }, payload) {
+    explodeData({ dispatch, commit }, payload) {
         for (let value in payload) {
+            if (value === 'pos') {
+                commit('updateSettings', payload[value])
+                continue
+            }
+
             dispatch(`init${value[0].toUpperCase()}${value.slice(1)}`, payload[value])
         }
     },
-    /**
-     * 
-     * @param {*} param0 
-     * @param {*} payload 
-     */
     createProduct({ dispatch }, payload) {
-        const data = {
+        return axios.post('createProductUrl', {
             jsonrpc: '2.0',
             method: 'call',
             params: {
                 ...payload
             }
-        }
-
-        return axios.post(CREATE_PRODUCT_URL, data).then(response => {
-            dispatch(RECEIVE_PRODUCT, response.data.result)
+        }).then(({data}) => {
+            dispatch('receiveProduct', data.result)
         }).catch(error => {
-            console.log(error)
+            console.error(error)
         })
     },
-    /**
-     * 
-     * @param {*} param0 
-     * @param {*} payload 
-     */
-    [CREATE_CUSTOMER] ({ dispatch }, payload) {
-        const data = {
+    createCustomer({ dispatch }, payload) {
+        return axios.post('createCustomerUrl', {
             jsonrpc: '2.0',
             method: 'call',
             params: {
                 ...payload
             }
-        }
-
-        return axios.post(CREATE_CUSTOMER_URL, data).then(response => {
-            dispatch(RECEIVE_CUSTOMER, response.data.result)
+        }).then(({data}) => {
+            dispatch('receiveCustomer', data.result)
         }).catch(error => {
-            console.log(error)
+            console.error(error)
         })
     },
-    /**
-     * 
-     * @param {*} param0 
-     */
-    [CHECK_CART] ({ getters, dispatch }) {
-        return !!getters.cartItems.length || dispatch(NOTIFY, 'Necesitas agregar productos al carrito para continuar')
+    checkCart({ getters, dispatch }) {
+        return !!getters.cartItems.length || dispatch('notify', 'Necesitas agregar productos al carrito para continuar')
     },
-    /**
-     * 
-     * @param {*} param0 
-     */
-    [CHECK_CUSTOMER] ({ getters, dispatch }) {
+    checkCustomer({ getters, dispatch }) {
         if (getters.processing) {
-            return dispatch(NOTIFY, 'Espere mientras se está procesando')
+            return dispatch('notify', 'Espere mientras se está procesando')
         }
 
-        return !!getters.selectedCustomer || dispatch(NOTIFY, 'Necesitas seleccionar un cliente para continuar')
+        return !!getters.selectedCustomer || dispatch('notify', 'Necesitas seleccionar un cliente para continuar')
     },
-    /**
-     * 
-     * @param {*} param0 
-     */
-    [CHECK_PAYMENT_METHOD] ({ getters }) {
+    checkPaymentMethod({ getters }) {
         if (getters.processing) {
-            return dispatch(NOTIFY, 'Espere mientras se está procesando')
+            return dispatch('notify', 'Espere mientras se está procesando')
         }
 
         return true
     },
-    /**
-     * 
-     * @param {*} param0 
-     */
-    [CHECK_AMOUNT_RECEIVED] ({ getters, dispatch }) {
+    checkAmountReceived({ getters, dispatch }) {
         if (getters.paymentType == 'cash') {
-            return getters.initialPayment >= getters.cartTotal || dispatch(NOTIFY, 'El monto recibido no puede ser menor al monto a pagar')
+            return getters.initialPayment >= getters.cartTotal || dispatch('notify', 'El monto recibido no puede ser menor al monto a pagar')
         } else {
-            return getters.initialPayment < getters.cartTotal || dispatch(NOTIFY, 'El monto recibido no puede ser igual o mayor al monto a pagar')
+            return getters.initialPayment < getters.cartTotal || dispatch('notify', 'El monto recibido no puede ser igual o mayor al monto a pagar')
         }
     },
-    /**
-     * 
-     * @param {*} param0 
-     */
-    [CREATE_SALE] ({ getters, commit, dispatch }, payload) {
-        commit(SET_PROCESSING, true)        
+    toggleSettingsVisibility({ commit }) {
+        commit('setSettingsVisibility')
+    },
+    changeSetting({dispatch, commit}, setting) {
+        commit('setLoading', true)
 
-        const data = {
+        return axios.post('/eiru_sales/save_settings', {
+            jsonrpc: '2.0',
+            method: 'call',
+            params: {
+                ...setting
+            }
+        }).then(({data}) => {
+            dispatch('updateImages', data.result)
+
+            commit('updateSettings', data.result)
+            commit('setLoading', false)
+        }).catch(error => {
+            console.log(error)
+        })
+    },
+    updateImages({ commit, getters }, data) {
+        const imageType = getters.settings.imageType ? 'small' : 'big'
+
+        if (imageType === data.imageType) {
+            return
+        }
+
+        return axios.get('/eiru_sales/get_images').then(({data}) => {
+            commit('setProducts', data.products)
+            commit('setCustomers', data.customers)
+        }).catch(error =>  {
+            console.error(error)
+        })
+    },
+    createSale({ getters, commit, dispatch }) {
+        commit('setLoading', true)
+
+        return axios.post('/eiru_sales/process_sale', {
             jsonrpc: '2.0',
             method: 'call',
             params: {
@@ -173,73 +131,26 @@ const actions = {
                 }),
                 total: getters.cartTotal,
                 customerId: getters.selectedCustomer.id,
-                paymentTermId: getters.selectedPaymentTerm.id,
+                paymentTermId: getters.paymentTerm.id,
                 journalId: getters.selectedJournal.id,
-                payment: getters.initialPayment > getters.cartTotal ? getters.cartTotal : getters.initialPayment
+                payment: getters.initialPayment > getters.amountToPay ? getters.amountToPay : getters.initialPayment,
+                currencyId: getters.selectedCurrency.id
             }
-        }
-
-        return axios.post(PROCESS_SALE_URL, data).then(response => {
-            commit(SET_DATE, response.data.result.date)
-            commit(SET_PROCESSING, !response.data.result.process)
-            commit(SET_RESULT, response.data.result.name)
-
-            dispatch(COMPLETE_SALE, response.data.result.process)
+        }).then(({data}) => {
+            commit('setLoading', false)
+            commit('setCompleted', true)
         }).catch(error => {
-            console.log(error)
-
-            commit(SET_PROCESSING, false)
+            commit('setLoading', false)
+            commit('setCompleted', true)
         })
     },
-    /**
-     * 
-     * @param {*} param0 
-     * @param {*} payload 
-     */
-    [COMPLETE_SALE] ({ commit }, payload) {
-        commit(SET_ASK_FOR_PRINT, !!payload)
-    },
-    [PROCESS_PRINT] ({ commit, dispatch }, payload) {
-        if (payload) {
-            if (payload === 'ticket') {
-                dispatch(PRINT_TICKET)
-            }
-        } 
-        
-        commit(SET_ASK_FOR_PRINT, false)
-        commit(SET_COMPLETED, true)
+    completeSale({ commit }, payload) {
+        commit('setAskForPrint', !!payload)
     },
-    /**
-     * 
-     */
-    [PRINT_TICKET] ({ getters }) {
-        let data = {
-            company: getters.user.company.name.toUpperCase(),
-            city:  getters.user.company.city,
-            street: getters.user.company.street,
-            state: getters.user.company.state.displayName.toUpperCase(),
-            phone:  getters.user.company.phone,
-            website: getters.user.company.website,
-            customer: getters.selectedCustomer.name.toUpperCase(),
-            ruc: getters.selectedCustomer.ruc,
-            date: getters.date,
-            symbol: getters.selectedCurrency ? getters.selectedCurrency.symbol : '$',
-            items: getters.cartItems.map(item => {
-                return [item.name.toUpperCase(), item.price, item.quantity, item.price * item.quantity]
-            }),
-            total: getters.cartTotal,
-            payment: getters.initialPayment,
-            cashier: getters.user.name.toUpperCase(),
-            result: getters.result
-        }
-
-        openerp.print_engine.socket_manager.printTicket(data.company, data.city, data.street, data.state, data.phone, data.website, data.date, data.symbol, data.items, data.total, data.payment, data.customer, data.ruc, data.cashier, data.result)
+    resetSettings() {
+        // Ignore this
     },
-    /**
-     * 
-     * @param {*} param0 
-     */
-    [RESET_SALE] ({ rootState, commit, dispatch }) {
+    resetSale({rootState, commit, dispatch}) {
         for (let key in rootState) {
             if (!(rootState[key] instanceof Object)) {
                 continue
@@ -248,8 +159,8 @@ const actions = {
             dispatch(`reset${key[0].toUpperCase()}${key.slice(1)}`)
         }
 
-        dispatch(INIT_SALE)
+        dispatch('initSale')
     }
 }
 
-export default actions
+export default actions

+ 23 - 28
src/store/getters.js

@@ -1,50 +1,45 @@
 const getters = {
-    /**
-     * 
-     * @param {*} state 
-     */
     mode(state) {
         return state.mode
     },
-    /**
-     * 
-     * @param {*} state 
-     */
     isSale(state) {
         return state.mode === 'sale'
     },
-    /**
-     * 
-     * @param {*} state 
-     */
     loading(state) {
         return state.loading
     },
-    /**
-     * 
-     * @param {*} state 
-     */
+    footerButtonsVisibility(state) {
+        return state.footerButtonsVisibility
+    },
+    settingsVisibility(state) {
+        return state.settingsVisibility
+    },
+    settings(state) {
+        let values = {
+            imageType: true,
+            allowExchange: false,
+            viewExchanges: false
+        }
+
+        if (!state.settings) {
+            return values
+        }
+
+        values.imageType = state.settings.imageType === 'small'
+        values.allowExchange = state.settings.allowCurrencyExchange
+        values.viewExchanges = state.settings.viewCurrencyExchanges
+
+        return values
+    },
     result(state) {
         return state.result
     },
-    /**
-     * 
-     * @param {*} state 
-     */
     completed(state) {
         return state.completed
     },
-    /**
-     * 
-     * @param {*} state 
-     */
     askForPrint(state) {
         return state.askForPrint
     },
-    /**
-     * 
-     * @param {*} state 
-     */
     error(state) {
         return state.error
     }

+ 4 - 2
src/store/index.js

@@ -17,6 +17,7 @@ import product from '@/store/modules/product'
 import user from '@/store/modules/user'
 import bank from '@/store/modules/bank'
 import bankPaymentType from '@/store/modules/bankPaymentType'
+import chequeType from './modules/chequeType'
 
 Vue.use(Vuex)
 
@@ -35,9 +36,10 @@ const store = new Vuex.Store({
         product,
         user,
         bank,
-        bankPaymentType
+        bankPaymentType,
+        chequeType
     },
     strict: true
 })
 
-export default store
+export default store

+ 22 - 32
src/store/modules/bank.js

@@ -1,55 +1,38 @@
 const state = {
+    loadingBanks: false,
     banks: [],
     selectedBank: null,
-    bankOperationNumber: null,
-    bankDueDate: null,
-    accountBankNumber: null,
-    holderBankName: null,
     showBankPayment: false
 }
 
 const getters = {
+    loadingBanks(state) {
+        return state.loadingBanks
+    },
     banks(state) {
         return state.banks
     },
     selectedBank(state) {
         return state.selectedBank
     },
-    bankOperationNumber(state) {
-        return state.bankOperationNumber
-    },
-    bankDueDate(state) {
-        return state.dueDate
-    },
-    accountBankNumber(state) {
-        return state.accountBankNumber
-    },
-    holderBankName(state) {
-        return state.holderBankName
-    },
     showBankPayment(state) {
         return state.showBankPayment
     }
 }
 
 const mutations = {
+    setLoadingBanks(state, loading) {    
+        state.loadingBanks = !!loading
+    },
     setBanks (state, payload) {
         state.banks = payload
     },
-    setSelectedBank(state, payload) {
-        state.selectedBank = payload
-    },
-    setBankOperationNumber(state, payload) {
-        state.bankOperationNumber = payload
-    },
-    setBankDueDate(state, payload) {
-        state.bankDueDate = payload
-    },
-    setAccountBankNumber(state, payload) {
-        state.accountBankNumber = payload
-    },
-    setHolderBankName(state, payload) {
-        state.holderBankName = payload
+    setSelectedBank(state, bankId) {
+        if (!bankId) {
+            return
+        }
+
+        state.selectedBank = state.banks.find(b => b.id === bankId)
     },
     toggleBankPayment(state) {
         state.showBankPayment = !state.showBankPayment
@@ -59,12 +42,19 @@ const mutations = {
 const actions = {
     initBanks ({ commit}, payload) {
         commit('setBanks', payload)
+        commit('setLoadingBanks')
     },
     toggleBankPayment({ commit }) {
+        commit('toggleFooterButtonsVisibility')
         commit('toggleBankPayment')
     },
-    resetBanks ({ commit }) {
-
+    changeBank({ commit }, bankId) {
+        commit('setSelectedBank', bankId)
+    },
+    resetBank ({ commit }) {
+        commit('setLoadingBanks', true)
+        commit('setBanks', [])
+        commit('setSelectedBank', null)
     }
 }
 

+ 35 - 35
src/store/modules/bankPaymentType.js

@@ -1,60 +1,60 @@
 const state = {
+    loadingBankPaymentTypes: false,
     bankPaymentTypes: [],
     selectedBankPaymentType: null
 }
 
 const getters = {
-    /**
-     * 
-     * @param {*} state 
-     */
-    bankPaymentTypes (state) {
+    loadingBankPaymentTypes(state) {
+        return state.loadingBankPaymentTypes
+    },
+    bankPaymentTypes(state, getters) {
+        if (getters.selectedJournal && getters.selectedJournal.subtype) {
+            return state.bankPaymentTypes.filter(b => b.subtype === getters.selectedJournal.subtype)
+        }
+
         return state.bankPaymentTypes
     },
-    /**
-     * 
-     * @param {*} state 
-     */
     selectedBankPaymentType (state) {
         return state.selectedBankPaymentType
     }
 }
 
 const mutations = {
-    /**
-     * 
-     * @param {*} state 
-     * @param {*} payload 
-     */
-    setBankPaymentTypes (state, payload) {
-        state.bankPaymentTypes = payload
+    setLoadingBankPaymentTypes(state, loading) {
+        state.loadingBankPaymentTypes = !!loading
     },
-    /**
-     * 
-     * @param {*} state 
-     * @param {*} payload 
-     */
-    setSelectedBankPaymentType (state, payload) {
-        state.selectedBankPaymentType = payload
-    }
+    setBankPaymentTypes (state, bankPaymentTypes) {
+        state.bankPaymentTypes = bankPaymentTypes
+    },
+    setSelectedBankPaymentType (state, id) {
+        if (id) {
+            state.selectedBankPaymentType = this.getters.bankPaymentTypes.find(b => b.id === id)
+            return
+        }
 
+        if (state.bankPaymentTypes.length > 0) {
+            state.selectedBankPaymentType = this.getters.bankPaymentTypes[0]
+            return
+        }
+
+        state.selectedBankPaymentType = null
+    }
 }
 
 const actions = {
-    /**
-     * 
-     * @param {*} param0 
-     * @param {*} payload 
-     */
     initBankPaymentTypes ({ commit }, payload) {
         commit('setBankPaymentTypes', payload)
+        commit('setSelectedBankPaymentType')
+        commit('setLoadingBankPaymentTypes')
     },
-    /**
-     * 
-     * @param {*} param0 
-     */
-    resetBankPaymentTypes ({ commit }) {
-
+    changeBankPaymentType({ commit }, id) {
+        commit('setSelectedBankPaymentType', id)
+    },
+    resetBankPaymentType ({ commit }) {
+        commit('setLoadingBankPaymentTypes', true)
+        commit('setBankPaymentTypes', [])
+        commit('setSelectedBankPaymentType')
     }
 }
 

+ 3 - 2
src/store/modules/cart.js

@@ -16,7 +16,7 @@ const getters = {
      * 
      * @param {*} state 
      */
-    cartTotal (state) {
+    cartTotal (state, getters) {
         return state.cartTotal
     },
     /**
@@ -183,8 +183,9 @@ const actions = {
      * @param {*} param0 
      * @param {*} payload 
      */
-    changeCartTotal ({ commit }, payload) {
+    changeCartTotal ({ commit, dispatch }, payload) {
         commit('setCartTotal', payload)
+        dispatch('changeAmountToPay', payload)
     },
     /**
      * 

+ 62 - 0
src/store/modules/chequeType.js

@@ -0,0 +1,62 @@
+const state = {
+    loadingChequeTypes: false,
+    chequeTypes: [],
+    selectedChequeType: 0
+}
+
+const getters = {
+    loadingChequeTypes(state) {
+        return state.loadingChequeTypes
+    },
+    chequeTypes(state) {
+        return state.chequeTypes
+    },
+    selectedChequeType(state) {
+        return state.selectedChequeType
+    }
+}
+
+const mutations = {
+    setLoadingChequeTypes(state, loading) {
+        state.loadingChequeTypes = !!loading
+    },
+    setChequeTypes(state, chequeTypes) {
+        state.chequeTypes = chequeTypes
+    },
+    setSelectedChequeType(state, id) {
+        if (id) {
+            state.selectedChequeType = state.chequeTypes.find(c => c.id === id)
+            return
+        }
+
+        if (state.chequeTypes.length > 0) {
+            state.selectedChequeType = state.chequeTypes[0]
+            return
+        }
+
+        state.selectedChequeType = null
+    }
+}
+
+const actions = {
+    initChequeTypes({ commit}, chequeTypes) {
+        commit('setChequeTypes', chequeTypes)
+        commit('setSelectedChequeType')
+        commit('setLoadingChequeTypes')
+    },
+    changeChequeType({ commit }, id) {
+        commit('setSelectedChequeType', id)
+    },
+    resetChequeType({ commit }) {
+        commit('setLoadingChequeTypes')
+        commit('setChequeTypes', [])
+        commit('setSelectedChequeType')
+    }
+}
+
+export default {
+    state,
+    getters,
+    actions,
+    mutations
+}

+ 24 - 11
src/store/modules/currency.js

@@ -1,6 +1,6 @@
 const state = {
     currencies: [],
-    currency: null, 
+    selectedCurrency: null, 
     loadingCurrencies: false,
 }
 
@@ -9,13 +9,16 @@ const getters = {
         return state.currencies
     },
     currencySymbols(state) {
-        return state.currencies && state.currencies.filter(c => state.currency.id !== c.id).map(c => c.symbol)
+        return (state.currencies && state.selectedCurrency) && state.currencies.filter(c => state.selectedCurrency.id !== c.id).map(c => c.symbol)
     },
-    currency(state) {
-        return state.currency
+    baseCurrency(state) {
+        return state.currencies.find(c => c.base === true)
+    },
+    selectedCurrency(state) {
+        return state.selectedCurrency
     },
     currencySymbol(state) {
-        return state.currency && state.currency.symbol
+        return state.selectedCurrency && state.selectedCurrency.symbol
     },
     loadingCurrencies(state) {
         return state.loadingCurrencies
@@ -23,13 +26,13 @@ const getters = {
 }
 
 const mutations = {
-    setCurrency(state, currencySymbol) {
+    setSelectedCurrency(state, currencySymbol) {
         if (currencySymbol) {
-            state.currency = state.currencies.find(c => (c.symbol === currencySymbol))
+            state.selectedCurrency = state.currencies.find(c => c.symbol === currencySymbol)
             return
         }
         
-        state.currency = state.currencies.find(c => (c.base === true))
+        state.selectedCurrency = state.currencies.find(c => c.base === true)
     },
     /**
      * 
@@ -57,7 +60,7 @@ const actions = {
      */
     initCurrencies({ commit }, payload) {
         commit('setCurrencies', payload)
-        commit('setCurrency')
+        commit('setSelectedCurrency')
         commit('setLoadingCurrencies')
     },
     /**
@@ -74,8 +77,18 @@ const actions = {
      * @param {*} param0 
      * @param {*} payload 
      */
-    changeCurrency({ commit }, currencySymbol) {
-        commit('setCurrency', currencySymbol)
+    changeCurrency({ commit, dispatch, getters }, currencySymbol) {
+        commit('computePaymentInCurrency', {
+            fromSymbol: getters.currencySymbol,
+            toSymbol: currencySymbol
+        });
+        commit('setSelectedCurrency', currencySymbol)
+
+        if (getters.paymentType === 'credit') {
+            dispatch('computePaymentLines')
+        }
+
+        dispatch('autoSelectJournal')
     }
 }
 

+ 37 - 59
src/store/modules/customer.js

@@ -1,26 +1,5 @@
-import { 
-    SET_CUSTOMERS,
-    SET_FILTERED_CUSTOMERS,
-    SET_LOADING_CUSTOMERS, 
-    SET_SELECTED_CUSTOMER, 
-    SET_SHOW_CUSTOMER_FORM,
-    ADD_CUSTOMER
-} from '@/constants/mutationTypes'
 
-import { 
-    INIT_CUSTOMERS,
-    FILTER_CUSTOMERS,
-    SHOW_CUSTOMER_FORM, 
-    HIDE_CUSTOMER_FORM, 
-    SUBMIT_CUSTOMER, 
-    CREATE_CUSTOMER, 
-    RECEIVE_CUSTOMER, 
-    SELECT_CUSTOMER, 
-    RESET_CUSTOMER,
-    NOTIFY
-} from '@/constants/actionTypes'
-
-const initialState = {
+const state = {
     customers: [],
     filteredCustomers: [],
     loadingCustomers: false,
@@ -28,14 +7,6 @@ const initialState = {
     selectedCustomer: null
 }
 
-const state = {
-    customers: initialState.customers,
-    filteredCustomers: initialState.filteredCustomers,
-    loadingCustomers: !initialState.loadingCustomers,
-    showingCustomerForm: initialState.showingCustomerForm,
-    selectedCustomer: initialState.selectedCustomer
-}
-
 const getters = {
     /**
      * 
@@ -72,6 +43,13 @@ const getters = {
     selectedCustomer(state) {
         return state.selectedCustomer
     },
+    /**
+     * 
+     * @param {*} state 
+     */
+    selectedCustomerName(state) {
+        return state.selectedCustomer && state.selectedCustomer.name
+    },
     /**
      * 
      * @param {*} state 
@@ -87,7 +65,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_CUSTOMERS] (state, payload) {
+    setCustomers(state, payload) {
         state.customers = payload
     },
     /**
@@ -95,7 +73,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_FILTERED_CUSTOMERS] (state, payload) {
+    setFilteredCustomers(state, payload) {
         state.filteredCustomers = [...payload]
     },
     /**
@@ -103,7 +81,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_LOADING_CUSTOMERS] (state, payload) {
+    setLoadingCustomers(state, payload) {
         state.loadingCustomers = !!payload
     },
     /**
@@ -111,7 +89,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_SHOW_CUSTOMER_FORM] (state, payload) {
+    setShowCustomerForm(state, payload) {
         state.showingCustomerForm = !!payload
     },
     /**
@@ -119,7 +97,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [ADD_CUSTOMER] (state, payload) {
+    addCustomer(state, payload) {
         state.customers = [payload, ...state.customers]
     },
     /**
@@ -127,7 +105,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_SELECTED_CUSTOMER] (state, payload) {
+    setSelectedCustomer(state, payload) {
         state.selectedCustomer = payload
     }
 }
@@ -138,67 +116,67 @@ const actions = {
      * @param {*} param0 
      * @param {*} payload 
      */
-    [INIT_CUSTOMERS] ({ commit }, payload) {
-        commit(SET_CUSTOMERS, payload)
-        commit(SET_LOADING_CUSTOMERS)
+    initCustomers({ commit }, payload) {
+        commit('setCustomers', payload)
+        commit('setLoadingCustomers')
     },
     /**
      * 
      * @param {*} param0 
      * @param {*} payload 
      */
-    [FILTER_CUSTOMERS] ({ commit }, payload) {
-        commit(SET_FILTERED_CUSTOMERS, payload)
+    filterCustomers({ commit }, payload) {
+        commit('setFilteredCustomers', payload)
     },
     /**
      * 
      * @param {*} param0 
      * @param {*} payload 
      */
-    [SHOW_CUSTOMER_FORM] ({ commit }) {
-        commit(SET_SHOW_CUSTOMER_FORM, true)
+    showCustomerForm({ commit }) {
+        commit('setShowCustomerForm', true)
     },
     /**
      * 
      * @param {*} param0 
      */
-    [HIDE_CUSTOMER_FORM] ({ commit }) {
-        commit(SET_SHOW_CUSTOMER_FORM, false)
+    hideCustomerForm({ commit }) {
+        commit('setShowCustomerForm', false)
     },
     /**
      * 
      * @param {*} param0 
      */
-    [SUBMIT_CUSTOMER] ({ commit, dispatch }, payload) {
-        commit(SET_LOADING_CUSTOMERS, true)
-        dispatch(CREATE_CUSTOMER, payload)
-        dispatch(HIDE_CUSTOMER_FORM)
+    submitCustomer({ commit, dispatch }, payload) {
+        commit('setLoadingCustomers', true)
+        dispatch('createCustomer', payload)
+        dispatch('hideCustomerForm')
     },
     /**
      * 
      * @param {*} param0 
      * @param {*} payload 
      */
-    [RECEIVE_CUSTOMER] ({ commit }, payload) {
-        commit(ADD_CUSTOMER, payload)
-        commit(SET_LOADING_CUSTOMERS, false)
+    receiveCustomer({ commit }, payload) {
+        commit('addCustomer', payload)
+        commit('setLoadingCustomers', false)
     },
     /**
      * 
      * @param {*} param0 
      */
-    [SELECT_CUSTOMER] ({ commit }, payload) {
-        commit(SET_SELECTED_CUSTOMER, payload)
+    selectCustomer({ commit }, payload) {
+        commit('setSelectedCustomer', payload)
     },
     /**
      * 
      * @param {*} param0 
      */
-    [RESET_CUSTOMER] ({ commit }) {
-        commit(SET_LOADING_CUSTOMERS, true)
-        commit(SET_CUSTOMERS, [])
-        commit(SET_FILTERED_CUSTOMERS, [])
-        commit(SET_SELECTED_CUSTOMER, null)
+    resetCustomer({ commit }) {
+        commit('setLoadingCustomers', true)
+        commit('setCustomers', [])
+        commit('setFilteredCustomers', [])
+        commit('setSelectedCustomer', null)
     }
 }
 

+ 9 - 19
src/store/modules/date.js

@@ -1,13 +1,3 @@
-import { 
-    SET_DATE, 
-    SET_LOADING_DATE 
-} from '@/constants/mutationTypes'
-
-import { 
-    INIT_DATE, 
-    RESET_DATE 
-} from '@/constants/actionTypes'
-
 const initialState = {
     date: null,
     loadingDate: false
@@ -41,7 +31,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_DATE] (state, payload) {
+    setDate(state, payload) {
         state.date = payload
     },
     /**
@@ -49,8 +39,8 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_LOADING_DATE] (state, payload) {
-        state.loadingDate = !!payload
+    setLoadingDate(state, loading) {
+        state.loadingDate = !!loading
     }
 }
 
@@ -60,17 +50,17 @@ const actions = {
      * @param {*} param0 
      * @param {*} payload 
      */
-    [INIT_DATE] ({ commit }, payload) {
-        commit(SET_DATE, payload)
-        commit(SET_LOADING_DATE)
+    initDate({ commit }, payload) {
+        commit('setDate', payload)
+        commit('setLoadingDate')
     },
     /**
      * 
      * @param {*} param0 
      */
-    [RESET_DATE] ({ commit }) {
-        commit(SET_LOADING_DATE, true)
-        commit(SET_DATE, null)
+    resetDate({ commit }) {
+        commit('setLoadingDate', true)
+        commit('setDate', null)
     }
 }
 

+ 22 - 97
src/store/modules/journal.js

@@ -1,145 +1,70 @@
 const state = {
     journals: [],
     loadingJournals: false,
-    selectedJournal: null,
-    showBankPaymentModal: false
+    selectedJournal: null
 }
 
 const getters = {
-    /**
-     * 
-     * @param {*} state 
-     */
     journals(state) {
         return state.journals
     },
-    /**
-     * 
-     * @param {*} state 
-     */
+    bankJournals(state, getters) {
+        return state.journals.filter(j => j.type === 'bank' && j.currencyId === getters.selectedCurrency.id)
+    },
     loadingJournals(state) {
         return state.loadingJournals
     },
-    /**
-     * 
-     * @param {*} state 
-     */
     selectedJournal(state) {
         return state.selectedJournal
     },
-    /**
-     * 
-     * @param {*} state 
-     */
-    showBankPaymentModal(state) {
-        return state.showBankPaymentModal
+    hasJournalSelected(state) {
+        return !!state.selectedJournal
+    },
+    hasCashJournalSelected(state) {
+        return !!state.selectedJournal && state.selectedJournal.type === 'cash'
+    },
+    hasBankJournalSelected(state) {
+        return !!state.selectedJournal && state.selectedJournal.type === 'bank'
     }
 }
 
 const mutations = {
-    /**
-     * 
-     * @param {*} state 
-     * @param {*} payload 
-     */
     setJournals (state, payload) {
         state.journals = payload
     },
-    /**
-     * 
-     * @param {*} state 
-     * @param {*} payload 
-     */
     setLoadingJournals (state, payload) {
         state.loadingJournals = !!payload
     },
-    /**
-     * 
-     * @param {*} state 
-     * @param {*} payload 
-     */
     autoSelectJournal (state) {
-        state.selectedJournal = state.journals.find(j => j.type === 'cash')
+        const { selectedCurrency } = this.getters
+        state.selectedJournal = state.journals.find(j => j.type === 'cash' && j.currencyId === selectedCurrency.id)
     },
-    /**
-     * 
-     * @param {*} state 
-     * @param {*} payload 
-     */
-    setSelectedJournal (state, payload) {
-        if (!payload) {
-            state.selectedJournal = payload
+    setSelectedJournal (state, journalId) {
+        if (!journalId) {
+            state.selectedJournal = null
             return
         }
 
-        state.selectedJournal = state.journals.find(item => item.id === payload)
-
-        if (state.selectedJournal.type && state.selectedJournal.type === 'bank') {
-            state.showBankPaymentModal = true;
-        }
-
-        if (state.selectedJournal.type && state.selectedJournal.type === 'cash') {
-            state.showBankPaymentModal = false;
-        }
-    },
-    /**
-     * 
-     * @param {*} state 
-     */
-    setShowBankPaymentModal (state, payload) {
-        state.showBankPaymentModal = !!payload
+        state.selectedJournal = state.journals.find(item => item.id === journalId)
     }
 }
 
 const actions = {
-    /**
-     * 
-     * @param {*} param0 
-     * @param {*} payload 
-     */
     initJournals ({ commit }, payload) {
         commit('setJournals', payload)
         commit('autoSelectJournal')
         commit('setLoadingJournals')
     },
-    /**
-     * 
-     * @param {*} param0 
-     * @param {*} payload 
-     */
-    selectJournal ({ commit }, payload) {
-        commit('setSelectedJournal', payload)
+    autoSelectJournal({ commit }) {
+        commit('autoSelectJournal')
     },
-    /**
-     * 
-     * @param {*} param0 
-     * @param {*} payload 
-     */
-    submitBankPayment({ commit }, payload) {
-        if (!payload.bank) {
-            commit('autoSelectJournal')
-            commit('setShowBankPaymentModal', false)
-            return
-        }
-        
-        commit('setSelectedBank', payload.bank)
-        commit('setSelectedBankPaymentType', payload.bankType)
-        commit('setBankOperationNumber', payload.bankNumber)
-        commit('setBankDueDate', payload.dueDate)
-        commit('setAccountBankNumber', payload.accountNumber)
-        commit('setHolderBankName', payload.holder)
-
-        commit('setShowBankPaymentModal', false)
+    selectJournal ({ commit }, journalId) {
+        commit('setSelectedJournal', journalId)
     },
-    /**
-     * 
-     * @param {*} param0 
-     */
     resetJournal ({ commit }) {
         commit('setLoadingJournals', true)
         commit('setJournals', [])
         commit('setSelectedJournal', null)
-        commit('setShowBankPaymentModal', false)
     }
 }
 

+ 65 - 11
src/store/modules/payment.js

@@ -5,8 +5,9 @@ const state = {
     paymentTerm: null,
     paymentType: 'cash',
     paymentMethod: 'Efectivo',
+    amountToPay: 0,
     initialPayment: 0,
-    paymentResidual: 0,
+    amountResidual: 0,
     paymentLines: []
 }
 
@@ -29,9 +30,15 @@ const getters = {
     paymentMethod(state) {
         return state.paymentMethod
     },
+    amountToPay(state) {
+        return state.amountToPay
+    },
     initialPayment(state) {
         return state.initialPayment
     },
+    amountResidual(state) {
+        return state.amountResidual
+    },
     paymentLines(state) {
         return state.paymentLines
     }
@@ -65,6 +72,36 @@ const mutations = {
     setPaymentMethod(state, payload) {
         state.paymentMethod = payload
     },
+    setAmountToPay(state, amount) {
+        if (!this.getters.baseCurrency) {
+            return
+        }
+
+        let rate = 1
+
+        if (this.getters.baseCurrency.id !== this.getters.selectedCurrency.id) {
+            rate = this.getters.baseCurrency.rateSilent / this.getters.selectedCurrency.rateSilent
+        }
+
+        state.amountToPay = amount / rate
+    },
+    setAmountResidual(state) {
+        state.amountResidual = state.initialPayment < state.amountToPay ? 0 : state.initialPayment - state.amountToPay
+    },
+    computePaymentInCurrency(state, { fromSymbol, toSymbol }) {
+        const fromCurrency = this.getters.currencies.find(c => c.symbol === fromSymbol)
+        const toCurrency = this.getters.currencies.find(c => c.symbol === toSymbol)
+
+        if (!fromCurrency || !toCurrency) {
+            return
+        }
+
+        const rate = fromCurrency.rateSilent / toCurrency.rateSilent
+
+        state.amountToPay = state.amountToPay / rate
+        state.initialPayment = state.initialPayment / rate
+        state.amountResidual = state.amountResidual / rate
+    },
     setInitialPayment(state, payload) {
         state.initialPayment = payload
     },
@@ -82,13 +119,15 @@ const mutations = {
         let dueDate = null
 
         for (let line of state.paymentTerm.lines) {
-            dueDate = moment(payload.date).add(line.days + line.days2, 'days').format('YYYY-MM-DD')
+            dueDate = moment(payload.date).add(line.days + line.days2, 'days').format('DD/MM/YYYY')
 
             if(percentPaid && percentPaid < 1) {
-                totals.push([payload.date, percentPaid])
+                let firstDate = moment(payload.date).format('DD/MM/YYYY')
+
+                totals.push([firstDate, percentPaid])
                 percentPaid = 0
 
-                if (dueDate === payload.date) {
+                if (dueDate === firstDate) {
                     distributedPercentage = ((totals[0][1] - line.valueAmount) / (state.paymentTerm.lines.length - 1))
                     continue
                 }
@@ -112,7 +151,7 @@ const mutations = {
 
                 state.paymentLines.push({
                     date: line[0],
-                    total: currentPrice !== parseFloat(0).toFixed(2) ? currentPrice : residual.toFixed(2)
+                    total: parseFloat(currentPrice !== parseFloat(0).toFixed(2) ? currentPrice : residual.toFixed(2))
                 })
             }
 
@@ -134,11 +173,15 @@ const actions = {
 
         commit('setPaymentTerm', payload)
     },
-    changePaymentType({ commit }, payload) {
-        commit('setPaymentType', payload)
-        commit('autoSelectPaymentTerm', payload)
+    changePaymentType({ commit, dispatch, getters }, paymentType) {
+        commit('setPaymentType', paymentType)
+        commit('autoSelectPaymentTerm', paymentType)
         commit('setInitialPayment', 0)
         commit('setPaymentLines')
+
+        if (getters.paymentType === 'credit') {
+            dispatch('computePaymentLines')
+        }
     },
     changePaymentMethod({ commit, dispatch }, methodName) {
         if (methodName === 'Banco') {
@@ -147,21 +190,32 @@ const actions = {
 
         commit('setPaymentMethod', methodName)
     },
-    changeInitialPayment({ commit }, payload) {
+    changeAmountToPay({ commit }, amount) {
+        commit('setAmountToPay', amount)
+    },
+    changeInitialPayment({ commit, dispatch, getters }, payload) {
         commit('setInitialPayment', payload)
+        commit('setAmountResidual')
+
+        if (getters.paymentType === 'credit') {
+            dispatch('computePaymentLines')
+        }
     },
     computePaymentLines({ commit, getters }) {
         commit('setPaymentLines', {
             date: getters.date,
-            total: getters.cartTotal
+            total: getters.amountToPay
         })
     },
     resetPayment({ commit }) {
-        commit('setLoading', true)
+        commit('setLoadingPaymentTerms', true)
         commit('setPaymentTerms', [])
         commit('setPaymentTerm', null)
         commit('setPaymentType', 'cash')
+        commit('setPaymentMethod', 'Efectivo')
+        commit('setAmountToPay', 0)
         commit('setInitialPayment', 0)
+        commit('setAmountResidual')
     }
 }
 

+ 32 - 63
src/store/modules/product.js

@@ -1,26 +1,4 @@
-import { 
-    SET_PRODUCTS,
-    SET_FILTERED_PRODUCTS,
-    SET_LOADING_PRODUCTS, 
-    SET_SHOW_PRODUCT_FORM, 
-    SET_PRODUCT_WITH_VARIANT, 
-    ADD_PRODUCT 
-} from '@/constants/mutationTypes'
-
-import { 
-    INIT_PRODUCTS,
-    FILTER_PRODUCTS,
-    SHOW_PRODUCT_FORM, 
-    HIDE_PRODUCT_FORM, 
-    SUBMIT_PRODUCT, 
-    CREATE_PRODUCT, 
-    RECEIVE_PRODUCT, 
-    SELECT_PRODUCT, 
-    ADD_TO_CART,
-    RESET_PRODUCT
-} from '@/constants/actionTypes'
-
-const initialState = {
+const state = {
     products: [],
     filteredProducts: [],
     loadingProducts: false,
@@ -29,15 +7,6 @@ const initialState = {
     productWithVariant: null
 }
 
-const state = {
-    products: initialState.products,
-    filteredProducts: initialState.filteredProducts,
-    loadingProducts: !initialState.loadingProducts,
-    showingProductForm: initialState.showingProductForm,
-    showVariants: initialState.showVariants,
-    productWithVariant: initialState.productWithVariant
-}
-
 const getters = {
     /**
      * 
@@ -89,7 +58,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_PRODUCTS] (state, payload) {
+    setProducts(state, payload) {
         state.products = payload
     },
     /**
@@ -97,7 +66,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_FILTERED_PRODUCTS] (state, payload) {
+    setFilteredProducts(state, payload) {
         state.filteredProducts = [...payload]
     },
     /**
@@ -105,7 +74,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_LOADING_PRODUCTS] (state, payload) {
+    setLoadingProducts(state, payload) {
         state.loadingProducts = !!payload
     },
     /**
@@ -113,7 +82,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_SHOW_PRODUCT_FORM] (state, payload) {
+    setShowProductForm(state, payload) {
         state.showingProductForm = !!payload
     },
     /**
@@ -121,7 +90,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [ADD_PRODUCT] (state, payload) {
+    addProduct(state, payload) {
         state.products = [payload, ...state.products]
     },
     /**
@@ -129,7 +98,7 @@ const mutations = {
      * @param {*} state 
      * @param {*} payload 
      */
-    [SET_PRODUCT_WITH_VARIANT] (state, payload) {
+    setProductWithVariant(state, payload) {
         state.productWithVariant = payload
     }
 }
@@ -140,51 +109,51 @@ const actions = {
      * @param {*} param0 
      * @param {*} payload 
      */
-    [INIT_PRODUCTS] ({ commit }, payload) {
-        commit(SET_PRODUCTS, payload)
-        commit(SET_LOADING_PRODUCTS)
+    initProducts({ commit }, payload) {
+        commit('setProducts', payload)
+        commit('setLoadingProducts')
     },
     /**
      * 
      * @param {*} param0 
      * @param {*} payload 
      */
-    [FILTER_PRODUCTS] ({ commit }, payload) {
-        commit(SET_FILTERED_PRODUCTS, payload)
+    filterProducts({ commit }, payload) {
+        commit('setFilteredProducts', payload)
     },
     /**
      * 
      * @param {*} param0 
      * @param {*} payload 
      */
-    [SHOW_PRODUCT_FORM] ({ commit }) {
-        commit(SET_SHOW_PRODUCT_FORM, true)
+    showProductForm({ commit }) {
+        commit('setShowProductForm', true)
     },
     /**
      * 
      * @param {*} param0 
      */
-    [HIDE_PRODUCT_FORM] ({ commit }) {
-        commit(SET_SHOW_PRODUCT_FORM, false)
+    hideProductForm({ commit }) {
+        commit('setShowProductForm', false)
     },
     /**
      * 
      * @param {*} param0 
      * @param {*} payload 
      */
-    [SUBMIT_PRODUCT] ({ commit, dispatch }, payload) {
-        commit(SET_LOADING_PRODUCTS, true)
-        dispatch(CREATE_PRODUCT, payload)
-        dispatch(HIDE_PRODUCT_FORM)
+    submitProduct({ commit, dispatch }, payload) {
+        commit('setLoadingProducts', true)
+        dispatch('createProduct', payload)
+        dispatch('hideProductForm')
     },
     /**
      * 
      * @param {*} param0 
      * @param {*} payload 
      */
-    [RECEIVE_PRODUCT] ({ commit }, payload) {
-        commit(ADD_PRODUCT, payload)
-        commit(SET_LOADING_PRODUCTS, false)
+    receiveProduct({ commit }, payload) {
+        commit('addProduct', payload)
+        commit('setLoadingProducts', false)
     },
     /**
      * 
@@ -193,30 +162,30 @@ const actions = {
      */
     selectProduct({ commit, dispatch }, payload) {
         if (!payload) {
-            commit(SET_PRODUCT_WITH_VARIANT, null)
+            commit('setProductWithVariant', null)
             return
         }
 
         if (payload.variantCount > 1) {
-            commit(SET_PRODUCT_WITH_VARIANT, payload)
+            commit('setProductWithVariant', payload)
             return
         }
 
         if (!payload.variantCount) {
-            dispatch(ADD_TO_CART, payload)
-            commit(SET_PRODUCT_WITH_VARIANT, null)
+            dispatch('addToCart', payload)
+            commit('setProductWithVariant', null)
         } else {
-            dispatch(ADD_TO_CART, payload.variants[0])
+            dispatch('addToCart', payload.variants[0])
         }
     },
     /**
      * 
      * @param {*} param0 
      */
-    [RESET_PRODUCT] ({ commit }) {
-        commit(SET_LOADING_PRODUCTS, true)
-        commit(SET_PRODUCTS, [])
-        commit(SET_FILTERED_PRODUCTS, [])
+    resetProduct({ commit }) {
+        commit('setLoadingProducts', true)
+        commit('setProducts', [])
+        commit('setFilteredProducts', [])
     }
 }
 

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

@@ -26,6 +26,13 @@ const getters = {
     user(state) {
         return state.user
     },
+    /**
+     * 
+     * @param {*} state 
+     */
+    companyName(state) {
+        return state.user && state.user.company.name
+    },
     /**
      * 
      * @param {*} state 

+ 15 - 3
src/store/mutations.js

@@ -8,12 +8,24 @@ const mutations = {
     setAskForPrint(state, payload) {
         state.askForPrint = payload
     },
-    setCompleted(state, payload) {
-        state.completed = payload
+    setCompleted(state, completed) {
+        state.completed = completed
     },
     setResult(state, payload) {
         state.result = payload
+    },
+    toggleFooterButtonsVisibility(state) {
+        state.footerButtonsVisibility = !state.footerButtonsVisibility
+    },
+    setSettingsVisibility(state) {
+        state.settingsVisibility = !state.settingsVisibility
+    },
+    updateSettings(state, settings) {
+        state.settings = settings
+    },
+    updateImages(state, values) {
+        console.log(values)
     }
 }
 
-export default mutations
+export default mutations

+ 4 - 1
src/store/state.js

@@ -1,5 +1,8 @@
 const state = {
     mode: 'sale',
+    settings: null,
+    footerButtonsVisibility: false,
+    settingsVisibility: false,
     loading: true,
     completed: false,
     result: '',
@@ -7,4 +10,4 @@ const state = {
     error: false
 }
 
-export default state
+export default state

+ 10 - 0
src/utils/db.js

@@ -0,0 +1,10 @@
+export class Store {
+
+    /**
+     * 
+     * @param {*} model 
+     * @param {*} data 
+     */
+    save(model, data) {
+    }
+}

+ 5 - 0
src/utils/index.js

@@ -0,0 +1,5 @@
+import { Store } from './db'
+
+export {
+    Store
+}

+ 3 - 3
templates.xml

@@ -19,7 +19,7 @@
             <field name="params">{'mode': 'budget'}</field>
         </record>
 
-        <menuitem id="eiru_pos.new_sale" name="Nueva venta" parent="eiru_dashboard.eiru_dashboard_main" action="eiru_pos.pos_action" sequence="2"/>
-        <menuitem id="eiru_pos.new_budget" name="Nuevo presupuesto" parent="eiru_dashboard.eiru_dashboard_main" action="eiru_pos.budget_action" sequence="3"/>
+        <!-- <menuitem id="eiru_pos.new_sale" name="Nueva venta" parent="eiru_dashboard.eiru_dashboard_main" action="eiru_pos.pos_action" sequence="2" /> -->
+        <!-- <menuitem id="eiru_pos.new_budget" name="Nuevo presupuesto" parent="eiru_dashboard.eiru_dashboard_main" action="eiru_pos.budget_action" sequence="3" /> -->
     </data>
-</openerp>
+</openerp>

+ 12 - 13
webpack.config.js

@@ -3,7 +3,6 @@ var LiveReloadPlugin = require('webpack-livereload-plugin')
 var HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
 var ExtractTextPlugin = require('extract-text-webpack-plugin')
 
-
 var prod = process.env.NODE_ENV === 'production'
 
 module.exports = {
@@ -24,18 +23,18 @@ module.exports = {
         new LiveReloadPlugin({
             appendScriptTag: true
         }),
-        new HardSourceWebpackPlugin({
-            cacheDirectory: 'node_modules/.cache/hard-source/[confighash]',
-            recordsPath: 'node_modules/.cache/hard-source/[confighash]/records.json',
-            configHash: function(webpackConfig) {
-                return require('node-object-hash')({sort: false}).hash(webpackConfig)
-            },
-            environmentHash: {
-                root: process.cwd(),
-                directories: [],
-                files: ['package-lock.json', 'yarn.lock'],
-            }
-        }),
+        // new HardSourceWebpackPlugin({
+        //     cacheDirectory: 'node_modules/.cache/hard-source/[confighash]',
+        //     recordsPath: 'node_modules/.cache/hard-source/[confighash]/records.json',
+        //     configHash: function(webpackConfig) {
+        //         return require('node-object-hash')({sort: false}).hash(webpackConfig)
+        //     },
+        //     environmentHash: {
+        //         root: process.cwd(),
+        //         directories: [],
+        //         files: ['package-lock.json', 'yarn.lock'],
+        //     }
+        // }),
         new ExtractTextPlugin('main.css')
     ],
     module: {