Browse Source

[IMP] pos structure

Gogs 6 năm trước cách đây
mục cha
commit
a1de371035

+ 3 - 1
__openerp__.py

@@ -11,7 +11,9 @@
         'eiru_bank_payments_references',
         'eiru_product_extra_price',
         'multi_store',
-        'sale',
+        # 'multi_store_stock',
+        # 'multi_store_partner',
+        'sale'
     ],
     'data': [
         'templates.xml',

+ 59 - 0
controllers/account_bank_statement.py

@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'account.bank.statement'
+
+'''
+    Create account bank statement lines
+'''
+def create_bank_statement_lines(account_voucher_id, reference=None):
+    account_voucher = request.env['account.voucher'].browse(account_voucher_id)
+
+    return [[0, False, {
+        'name': account_voucher.reference,
+        'amount': account_voucher.amount,
+        'partner_id': account_voucher.partner_id.id,
+        'voucher_id': account_voucher.id,
+        'journal_id': account_voucher.journal_id.id,
+        'account_id': account_voucher.account_id.id,
+        'journal_entry_id': account_voucher.move_id.id,
+        'currency_id': account_voucher.currency_id.id,
+        'ref': 'POS/' + (reference or '')
+    }]]
+
+'''
+    Create account bank statement
+'''
+def create_bank_statement(account_voucher_id, date_today):
+    account_voucher = request.env['account.voucher'].browse(account_voucher_id)
+
+    domain = [
+        ('journal_id', '=', account_voucher.journal_id.id),
+        ('date', '=', date_today)
+    ]
+
+    account_bank_statement = request.env[_MODEL].search(domain)
+    account_bank_statement_lines = create_bank_statement_lines(account_voucher_id)
+
+    account_bank_statement_values = {
+        'date': date_today,
+        'user_id': request.env.user.id,
+        'journal_id': account_voucher.journal_id.id,
+        'period_id': account_voucher.period_id.id,
+        'line_ids': account_bank_statement_lines,
+        'state': 'open' if account_voucher.journal_id.type == 'cash' else 'draft'
+    }
+
+    if account_bank_statement:
+        size = len(account_bank_statement)
+
+        if size == 1:
+            account_bank_statement.write(account_bank_statement_values)
+        else:
+            account_bank_statement[size - 1].write(account_bank_statement_values)
+    else:
+        account_bank_statement.create(account_bank_statement_values)
+
+    return account_bank_statement
+
+

+ 127 - 0
controllers/account_invoice.py

@@ -0,0 +1,127 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, float_round
+from dateutil.parser import parse
+from dateutil.relativedelta import relativedelta as rd
+
+_MODEL = 'account.invoice'
+
+'''
+'''
+def create_invoice(sale_order_id, currency_id, date_today):
+    sale_order = request.env['sale.order'].browse(sale_order_id)
+    invoice_id = sale_order.action_invoice_create()
+    invoice = request.env[_MODEL].browse(invoice_id)
+
+    for picking in sale_order.picking_ids:
+        picking.force_assign()
+        picking.action_done()
+
+    date_due = parse(date_today) + rd(days=max(invoice.payment_term.line_ids.mapped(lambda x: x.days + x.days2)))
+
+    invoice.write({
+        'currency_id': currency_id,
+        'date_invoice': date_today,
+        'date_due': date_due.strftime(DEFAULT_SERVER_DATE_FORMAT),
+        'state': 'open'
+    })
+
+    return invoice
+
+'''
+    Create move lines
+'''
+def create_invoice_move_lines(invoice_id, paid_amount, date_today):
+    invoice = request.env[_MODEL].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.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)
+    total, total_currency, invoice_move_lines = invoice.with_context(context).compute_invoice_totals(invoice.company_id.currency_id, invoice.reference, invoice_move_lines)
+
+    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(DEFAULT_SERVER_DATE_FORMAT)
+
+        if paid_percentage and paid_percentage < 1.0:
+            payment_lines.append([date_today, paid_percentage])
+            paid_percentage = paid_amount = 0
+
+            if date_due == date_today and line.value_amount:
+                distributed_percentage = -((payment_lines[0][1] - line.value_amount)  / (len(invoice.payment_term.line_ids) - 1))
+                continue
+        
+        if line.value != 'balance':
+            payment_lines.append([date_due, line.value_amount + distributed_percentage])
+            continue
+
+        payment_lines.append([date_due, line.value_amount])
+
+        for payment_line in payment_lines:
+            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': price,
+                'account_id': invoice.account_id.id,
+                'date_maturity': payment_line[0],
+                'amount_currency': amount_currency,
+                'currency_id': diff_currency and invoice.currency_id.id,
+                'ref': invoice.reference
+            })
+            
+        payment_lines = []
+
+    return invoice_move_lines
+
+'''
+    Number to invoice
+'''
+def number_invoice(invoice_id):
+    request.env[_MODEL].browse(invoice_id).action_number()
+
+'''
+    Close a invoice
+'''
+def close_invoice(invoice_id):
+    invoice = request.env[_MODEL].browse(invoice_id)
+
+    if invoice.residual == 0:
+        invoice.write({
+            'state': 'paid'
+        })

+ 64 - 0
controllers/account_journal.py

@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+from res_users import get_current_user
+from res_config import get_pos_config
+
+_MODEL = 'account.journal'
+
+'''
+'''
+def get_journals():
+    domain = [
+        ('type', 'in', ['bank', 'cash']),
+        ('active', '=', True)
+    ]
+
+    if not get_pos_config().get('allowCurrencyExchange'):
+        currency_id = get_current_user().get('company').get('currencyId')
+
+        domain.append('|')
+        domain.append(('currency', '=', currency_id))
+        domain.append(('company_id.currency_id', '=', currency_id))
+
+    return [
+        {
+            'id': journal.id,
+            'name': journal.display_name,
+            'code': journal.code,
+            'type': journal.type,
+            'subtype': journal.subtype or None,
+            'currencyId': journal.currency.id or journal.company_id.currency_id.id
+        } for journal in request.env[_MODEL].search(domain, order='id')
+    ]
+
+'''
+'''
+def get_currencies_from_journals():
+    domain = [
+        ('type', 'in', ['bank', 'cash']),
+        ('active', '=', True)
+    ]
+    currencies = []
+
+    for journal in request.env[_MODEL].search(domain):
+        currency = journal.currency or journal.company_id.currency_id
+
+        currencies.append({
+            'id': currency.id,
+            'name': currency.display_name,
+            '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
+        })
+            
+    return {c['id']:c for c in currencies}.values()
+
+'''
+'''
+def get_currency(journal_id):
+    journal = request.env['account.journal'].browse(journal_id)
+    return journal.default_credit_account_id.currency_id.id or journal.default_credit_account_id.company_currency_id.id

+ 49 - 0
controllers/account_move.py

@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'account.move'
+
+'''
+    Create account move
+'''
+def create_account_move(invoice_id, invoice_move_lines):
+    invoice = request.env['account.invoice'].browse(invoice_id)
+    accounting_partner = request.env['res.partner']._find_accounting_partner(invoice.partner_id)
+
+    move_line_values = [(0, 0, invoice.line_get_convert(line, accounting_partner.id, invoice.date_invoice)) for line in invoice_move_lines]
+    move_line_values = invoice.group_lines(invoice_move_lines, move_line_values)
+    move_line_values = invoice.finalize_invoice_move_lines(move_line_values)
+
+    ctx = dict(request.context, lang=invoice.partner_id.lang, company_id=invoice.company_id.id)
+    period = invoice.period_id
+
+    if not period:
+        period = period.with_context(ctx).find(invoice.date_invoice)[:1]
+
+    if period:
+        for line in move_line_values:
+            line[2]['period_id'] = period.id
+
+    ctx['invoice'] = invoice
+    ctx_nolang = ctx.copy()
+    ctx_nolang.pop('lang', None)
+
+    account_move = request.env[_MODEL].with_context(ctx_nolang).create({
+        'ref': invoice.reference or invoice.name,
+        'line_id': move_line_values,
+        'journal_id': invoice.journal_id.id,
+        'date': invoice.date_invoice,
+        'narration': invoice.comment,
+        'company_id': invoice.company_id.id,
+        'period_id': period.id
+    })
+
+    invoice.with_context(ctx).write({
+        'move_id': account_move.id,
+        'period_id': account_move.period_id.id,
+        'move_name': account_move.name,
+    })
+
+    account_move.post()
+
+    return account_move

+ 27 - 0
controllers/account_payment_term.py

@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'account.payment.term'
+
+'''
+'''
+def get_payment_terms():
+    domain = [
+        ('active', '=', True)
+    ]
+
+    return [
+        {
+            'id': payment_term.id,
+            'name': payment_term.display_name,
+            'lines': [
+                {
+                    'id': line.id,
+                    'days': line.days,
+                    'days2': line.days2,
+                    'value': line.value,
+                    'valueAmount': line.value_amount
+                } for line in payment_term.line_ids
+            ]
+        } for payment_term in request.env[_MODEL].search(domain)
+    ]

+ 41 - 0
controllers/account_voucher.py

@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'account.voucher'
+
+'''
+    Create voucher
+'''
+def create_account_voucher(account_move_id, journal_id, currency_id, paid_amount):
+    account_move = request.env['account.move'].browse(account_move_id)
+    account_journal = request.env['account.journal'].browse(journal_id)
+
+    values = {
+        'reference': account_move.name,
+        'type': 'receipt',
+        'journal_id': account_journal.id,
+        'company_id': account_move.company_id.id,
+        'pre_line': True,
+        'amount': paid_amount,
+        'period_id': account_move.period_id.id,
+        'date': account_move.date,
+        'partner_id': account_move.partner_id.id,
+        'account_id': account_journal.default_credit_account_id.id,
+        'currency_id': currency_id,
+        'line_cr_ids': [[0, False, {
+            'date_due': l.date_maturity,
+            'account_id': l.account_id.id,
+            'date_original': l.invoice.date_invoice,
+            'move_line_id': l.id,
+            'amount_original': abs(l.credit or l.debit or 0.0),
+            'amount_unreconciled': abs(l.amount_residual),
+            'amount': abs(l.debit) if account_move.date == l.date_maturity else 0.0,
+            'reconcile': account_move.date == l.date_maturity,
+            'currency_id': currency_id
+        }] for l in account_move.line_id]
+    }
+
+    account_voucher = request.env[_MODEL].create(values)
+    account_voucher.action_move_line_create()
+
+    return account_voucher

+ 39 - 0
controllers/http_response.py

@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+from werkzeug.wrappers import Response
+from werkzeug.datastructures import Headers
+from gzip import GzipFile
+
+import simplejson as json
+import gzip
+
+try:
+    from cStringIO import StringIO as IO
+except ImportError:
+    from StringIO import StringIO as IO
+
+GZIP_COMPRESSION_LEVEL = 9
+
+'''
+    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')

+ 76 - 744
controllers/main.py

@@ -1,785 +1,116 @@
 # -*- coding: utf-8 -*-
-
-from openerp import api, http
+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
-from dateutil.relativedelta import relativedelta as rd
-from dateutil.parser import parse
-from pytz import timezone
-from gzip import GzipFile
-import simplejson as json
-import gzip
+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
+
+from res_config import get_pos_config, save_pos_config
+from server_datetime import get_datetime, get_date
+from res_users import get_current_user
+from account_journal import get_journals, get_currencies_from_journals, get_currency
+from res_partner import get_customers, create_customer
+from product_template import get_products, create_product
+from account_payment_term import get_payment_terms
+from res_bank import get_banks
+from res_bank_payment_type import get_bank_payment_types
+from res_bank_cheque_type import get_cheque_types
+from sale_order import create_sale_from_cart, confirm_sale_order
+from account_invoice import create_invoice, create_invoice_move_lines, number_invoice, close_invoice
+from account_move import create_account_move
+from account_voucher import create_account_voucher
+from account_bank_statement import create_bank_statement
+from res_bank_payment import create_bank_payment_statement
+
+from http_response import make_gzip_response
 import logging
 
-try:
-    from cStringIO import StringIO as IO
-except ImportError:
-    from StringIO import StringIO as IO
-
 LOGGER = logging.getLogger(__name__)
-GZIP_COMPRESSION_LEVEL = 9
 
-'''
-         ___ ___  __      __   __       ___  __   __             ___  __      ___  __   __      __   __   __  
-    |__|  |   |  |__)    /  ` /  \ |\ |  |  |__) /  \ |    |    |__  |__)    |__  /  \ |__)    |__) /  \ /__` 
-    |  |  |   |  |       \__, \__/ | \|  |  |  \ \__/ |___ |___ |___ |  \    |    \__/ |  \    |    \__/ .__/
-
-    # Resource paths
-        - /init:            return json response gzip compressed contains values for sale operation 
-        - /create_product:  create product on the fly POS and return it
-        - /create_customer: create customer on the fly and return it
-        - /process_sale:    processing sale and return true if completed
-                                                                                                              
-'''
 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_settings(self):
-        settings = request.env['base.config.settings'].search([], limit=1, order='id desc')
-
-        return {
-            'imageType': settings.image_type,
-            'allowCurrencyExchange': settings.allow_currency_exchange,
-            'viewCurrencyExchanges': settings.view_currency_exchanges,
-            'currencies': [
-                {
-                    'id': currency.id,
-                    'name': currency.display_name,
-                    'symbol': currency.symbol,
-                    'position': currency.position,
-                    'rateSilent': currency.rate_silent,
-                    'decimalSeparator': currency.decimal_separator,
-                    'decimalPlaces': currency.decimal_places,
-                    'thousandsSeparator': currency.thousands_separator
-                } for currency in settings.currency_ids
-            ]
-        }
-
-    '''
-        Get timezone
-    '''
-    def get_timezone(self):
-        return timezone(request.context['tz'])
-
-    '''
-        Get server date
-    '''
-    def get_server_datetime(self):
-        return datetime.now(self.get_timezone()).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
-
-    '''
-        Check if module is installed
-    '''
-    def is_module_installed(self, module_name):
-        domain = [('name', '=', module_name), ('state', '=', 'installed')]
-        module = request.env['ir.module.module'].search(domain)
-
-        return len(module) != 0
-    
-    '''
-        Get current user information
-    '''
-    def get_user(self):
-        user = request.env.user
-
-        return {
-            'id': user.id,
-            'name': user.display_name,
-            'company': {
-                'id': user.company_id.id,
-                'name': user.company_id.display_name,
-                'phone': user.company_id.phone or None,
-                'city': user.company_id.city or None,
-                'currencyId': user.company_id.currency_id.id or None
-            },
-            'isManager': 'Gerente' in user.groups_id.filtered(lambda g: g.category_id.name == 'Eiru POS').mapped(lambda g: g.name)
-        }
-    
-    '''
-        Get currencies from configured journals
-    '''
-    def get_currencies_from_journals(self):
-        domain = [('type', 'in', ['bank', 'cash']), ('active', '=', True)]
-        currencies = []
-
-        for journal in request.env['account.journal'].search(domain):
-            currency = journal.currency or journal.company_id.currency_id
-
-            currencies.append({
-                'id': currency.id,
-                'name': currency.display_name,
-                '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
-            })
-            
-        return {c['id']:c for c in currencies}.values()
-
-    '''
-        Get all active journals
-    '''
-    def get_journals(self):
-        domain = [('type', 'in', ['bank', 'cash']), ('active', '=', True)]
-        has_subtype = self.is_module_installed('eiru_bank_payments_references')
-
-        if not self.get_pos_settings().get('allowCurrencyExchange'):
-            currency_id = self.get_user().get('company').get('currencyId')
-
-            domain.append('|')
-            domain.append(('currency', '=', currency_id))
-            domain.append(('company_id.currency_id', '=', currency_id))
-
-        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')]
-    
-    '''
-        Get banks
-    '''
-    def get_banks(self):
-        banks = []
-
-        if self.is_module_installed('eiru_bank_payments_references'):
-            banks = [
-                {
-                    'id': bank.id,
-                    'name': bank.display_name
-                } for bank in request.env['res.bank'].search([('active', '=', True)])
-            ]
-
-        return banks
-
-    '''
-        Get bank payment types
-    '''
-    def get_bank_payment_types(self):
-        bank_types = []
-
-        if self.is_module_installed('eiru_bank_payments_references'):
-            domain = [('is_receipt', '=', True)]
-
-            bank_types = [
-                {
-                    'id': type.id,
-                    'name': type.display_name,
-                    '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(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, image_type='small'):
-        domain = [('customer', '=', True), ('active', '=', True)]
-
-        return [
-            {
-                'id': customer.id,
-                'name': customer.display_name,
-                '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,
-                'email': customer.email or None
-            } for customer in request.env['res.partner'].search(domain)
-        ]
-
-    '''
-        Get all saleable and active products
-    '''
-    def get_products(self, image_type='small'):
-        domain = [('sale_ok', '=', True), ('list_price', '>', 0), ('active', '=', True)]
-
-        return [
-            {
-                'id': product.id,
-                'name': product.display_name,
-                'ean13': product.ean13,
-                'defaultCode': product.default_code,
-                'image': product.image_small if image_type == 'small' else product.image_medium,
-                'listPrice': product.list_price,
-                'variantCount': product.product_variant_count,
-                'quantity': 1,
-                'price': product.list_price,
-                'minimumPrice': product.minimum_price,
-                'maximumPrice': product.maximum_price,
-                'discount': 0,
-                'variants': [{
-                    'id': variant.id,
-                    'name': variant.display_name,
-                    'ean13': variant.ean13,
-                    'defaultCode': product.default_code,
-                    'image': variant.image_small if image_type == 'small' else variant.image_medium,
-                    'listPrice': variant.list_price,
-                    'quantity': 1,
-                    'price': variant.list_price,
-                    'minimumPrice': product.minimum_price,
-                    'maximumPrice': product.maximum_price,
-                    'discount': 0,
-                } for variant in product.product_variant_ids if variant.active]
-            } for product in request.env['product.template'].search(domain)
-        ]
-
-    '''
-        Get all active payment terms
-    '''
-    def get_payment_terms(self):
-        domain = [('active', '=', True)]
-
-        return [
-            {
-                'id': payment_term.id,
-                'name': payment_term.display_name,
-                'lines': [{
-                    'id': line.id,
-                    'days': line.days,
-                    'days2': line.days2,
-                    'value': line.value,
-                    'valueAmount': line.value_amount
-                } for line in payment_term.line_ids]
-            } for payment_term in request.env['account.payment.term'].search(domain)
-        ]
-
-    '''
-        Get currency from journal
-    '''
-    def get_currency(self, journal_id):
-        journal = request.env['account.journal'].browse(journal_id)
-        return journal.default_credit_account_id.currency_id.id or journal.default_credit_account_id.company_currency_id.id
-
-    '''
-        Check currency in pricelist and get it
-    '''
-    def get_pricelist(self, currency_id):
-        pricelist = request.env['product.pricelist'].search([('active', '=', True), ('type', '=', 'sale')])
-
-        if not True in pricelist.mapped(lambda p: p.currency_id.id == currency_id):
-            pricelist = pricelist[0].copy()
-            pricelist.write({
-                'currency_id': currency_id
-            })
-        else:
-            pricelist = pricelist.filtered(lambda p: p.currency_id.id == currency_id)
-        
-        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):
-        values = {
-            'partner_id': partner_id,
-            'order_line': [[0, False, {
-                'product_id': int(line.get('id')),
-                'product_uom_qty': float(line.get('quantity')),
-                '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,
-            'currency_id': currency_id,
-            'pricelist_id': pricelist_id,
-            'payment_term': payment_term_id,
-            'state': 'draft',
-        }
-
-        return request.env['sale.order'].create(values)
-
-    '''
-        Confirm sale order
-    '''
-    def confirm_sale_order(self, sale_order_id):
-        sale_order = request.env['sale.order'].browse(sale_order_id)
-        sale_order.write({
-            'state': 'manual'
-        })
-
-        return sale_order.action_button_confirm()
-
-    '''
-        Create invoice from sale order
-    '''
-    def create_invoice(self, sale_order_id, currency_id, date_today):
-        sale_order = request.env['sale.order'].browse(sale_order_id)
-        invoice_id = sale_order.action_invoice_create()
-        invoice = request.env['account.invoice'].browse(invoice_id)
-
-        for picking in sale_order.picking_ids:
-            picking.force_assign()
-            picking.action_done()
-
-        date_due = parse(date_today) + rd(days=max(invoice.payment_term.line_ids.mapped(lambda x: x.days + x.days2)))
-
-        invoice.write({
-            'currency_id': currency_id,
-            'date_invoice': date_today,
-            'date_due': date_due.strftime(DEFAULT_SERVER_DATE_FORMAT),
-            'state': 'open'
-        })
-
-        return invoice
-
-    '''
-        Create move lines
-    '''
-    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.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)
-        total, total_currency, invoice_move_lines = invoice.with_context(context).compute_invoice_totals(invoice.company_id.currency_id, invoice.reference, invoice_move_lines)
-
-        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(DEFAULT_SERVER_DATE_FORMAT)
-
-            if paid_percentage and paid_percentage < 1.0:
-                payment_lines.append([date_today, paid_percentage])
-                paid_percentage = paid_amount = 0
-
-                if date_due == date_today and line.value_amount:
-                    distributed_percentage = -((payment_lines[0][1] - line.value_amount)  / (len(invoice.payment_term.line_ids) - 1))
-                    continue
-            
-            if line.value != 'balance':
-                payment_lines.append([date_due, line.value_amount + distributed_percentage])
-                continue
-
-            payment_lines.append([date_due, line.value_amount])
-
-            for payment_line in payment_lines:
-                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': price,
-                    'account_id': invoice.account_id.id,
-                    'date_maturity': payment_line[0],
-                    'amount_currency': amount_currency,
-                    'currency_id': diff_currency and invoice.currency_id.id,
-                    'ref': invoice.reference
-                })
-                
-            payment_lines = []
-
-        return invoice_move_lines
-
-    '''
-        Create account move
-    '''
-    def create_account_move(self, invoice_id, invoice_move_lines):
-        invoice = request.env['account.invoice'].browse(invoice_id)
-        accounting_partner = request.env['res.partner']._find_accounting_partner(invoice.partner_id)
-
-        move_line_values = [(0, 0, invoice.line_get_convert(line, accounting_partner.id, invoice.date_invoice)) for line in invoice_move_lines]
-        move_line_values = invoice.group_lines(invoice_move_lines, move_line_values)
-        move_line_values = invoice.finalize_invoice_move_lines(move_line_values)
-
-        ctx = dict(request.context, lang=invoice.partner_id.lang, company_id=invoice.company_id.id)
-        period = invoice.period_id
-
-        if not period:
-            period = period.with_context(ctx).find(invoice.date_invoice)[:1]
-
-        if period:
-            for line in move_line_values:
-                line[2]['period_id'] = period.id
-
-        ctx['invoice'] = invoice
-        ctx_nolang = ctx.copy()
-        ctx_nolang.pop('lang', None)
  
-        account_move = request.env['account.move'].with_context(ctx_nolang).create({
-            'ref': invoice.reference or invoice.name,
-            'line_id': move_line_values,
-            'journal_id': invoice.journal_id.id,
-            'date': invoice.date_invoice,
-            'narration': invoice.comment,
-            'company_id': invoice.company_id.id,
-            'period_id': period.id
-        })
-
-        invoice.with_context(ctx).write({
-            'move_id': account_move.id,
-            'period_id': account_move.period_id.id,
-            'move_name': account_move.name,
-        })
-
-        account_move.post()
-
-        return account_move
-
-    '''
-        Number to invoice
     '''
-    def number_invoice(self, invoice_id):
-        request.env['account.invoice'].browse(invoice_id).action_number()
-
-    '''
-        Create voucher
     '''
-    def create_account_voucher(self, account_move_id, journal_id, currency_id, paid_amount):
-        account_move = request.env['account.move'].browse(account_move_id)
-        account_journal = request.env['account.journal'].browse(journal_id)
-
-        account_voucher = request.env['account.voucher'].create({
-            'reference': account_move.name,
-            'type': 'receipt',
-            'journal_id': account_journal.id,
-            'company_id': account_move.company_id.id,
-            'pre_line': True,
-            'amount': paid_amount,
-            'period_id': account_move.period_id.id,
-            'date': account_move.date,
-            'partner_id': account_move.partner_id.id,
-            'account_id': account_journal.default_credit_account_id.id,
-            'currency_id': currency_id,
-            'line_cr_ids': [[0, False, {
-                'date_due': l.date_maturity,
-                'account_id': l.account_id.id,
-                'date_original': l.invoice.date_invoice,
-                'move_line_id': l.id,
-                'amount_original': abs(l.credit or l.debit or 0.0),
-                'amount_unreconciled': abs(l.amount_residual),
-                'amount': abs(l.debit) if account_move.date == l.date_maturity else 0.0,
-                'reconcile': account_move.date == l.date_maturity,
-                'currency_id': currency_id
-            }] for l in account_move.line_id]
-        })
-
-        account_voucher.action_move_line_create()
-
-        return account_voucher
-
-    '''
-        Close a invoice
-    '''
-    def close_invoice(self, invoice_id):
-        invoice = request.env['account.invoice'].browse(invoice_id)
-
-        if invoice.residual == 0:
-            invoice.write({
-                'state': 'paid'
-            })
-
-    '''
-        Create account bank statement lines
-    '''
-    def create_bank_statement_lines(self, account_voucher_id, reference=None):
-        account_voucher = request.env['account.voucher'].browse(account_voucher_id)
-
-        return [[0, False, {
-            'name': account_voucher.reference,
-            'amount': account_voucher.amount,
-            'partner_id': account_voucher.partner_id.id,
-            'voucher_id': account_voucher.id,
-            'journal_id': account_voucher.journal_id.id,
-            'account_id': account_voucher.account_id.id,
-            'journal_entry_id': account_voucher.move_id.id,
-            'currency_id': account_voucher.currency_id.id,
-            'ref': 'POS/' + (reference or '')
-        }]]
-
-    '''
-        Create account bank statement
-    '''
-    def create_bank_statement(self, account_voucher_id, account_bank_statement_lines, date_today):
-        account_voucher = request.env['account.voucher'].browse(account_voucher_id)
-        account_bank_statement = request.env['account.bank.statement'].search([('journal_id', '=', account_voucher.journal_id.id), ('date', '=', date_today)])
-
-        account_bank_statement_values = {
-            'date': date_today,
-            'user_id': request.env.user.id,
-            'journal_id': account_voucher.journal_id.id,
-            'period_id': account_voucher.period_id.id,
-            'line_ids': account_bank_statement_lines,
-            'state': 'open' if account_voucher.journal_id.type == 'cash' else 'draft'
-        }
-
-        if account_bank_statement:
-            size = len(account_bank_statement)
-
-            if size == 1:
-                account_bank_statement.write(account_bank_statement_values)
-            else:
-                account_bank_statement[size - 1].write(account_bank_statement_values)
-        else:
-            account_bank_statement.create(account_bank_statement_values)
-
-        return account_bank_statement
-
-    '''
-    '''
-    def create_bank_payment_statement(self):
-        pass
+    def make_info_log(self, log):
+        LOGGER.info('\033[1;34m[INFO] --> \033[m{}'.format(log))
 
     '''
         New purchase resource route
     '''
     @http.route('/eiru_sales/init', auth='user', methods=['GET'], cors='*')
-    def init_sale(self, **kw):
+    def _init_sale(self, **kw):
         self.make_info_log('Sending JSON response')
         
-        settings = self.get_pos_settings()
-
-        return self.make_gzip_response(
-            {
-                'settings': settings,
-                '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=settings.get('imageType')),
-                'products': self.get_products(image_type=settings.get('imageType')),
-                'paymentTerms': self.get_payment_terms(),
-                'banks': self.get_banks(),
-                'bankPaymentTypes': self.get_bank_payment_types(),
-                'chequeTypes': self.get_cheque_types()
-            }
-        )
+        config = get_pos_config()
+
+        return make_gzip_response({
+            'settings': config,
+            'date': get_datetime(),
+            'user': get_current_user(),
+            'currencies': get_currencies_from_journals(),
+            'journals': get_journals(),
+            'customers': get_customers(image_type=config.get('imageType')),
+            'products': get_products(image_type=config.get('imageType')),
+            'paymentTerms': get_payment_terms(),
+            'banks': get_banks(),
+            'bankPaymentTypes': get_bank_payment_types(),
+            'chequeTypes': get_cheque_types()
+        })
     
     '''
         Get products data only
     '''
     @http.route('/eiru_sales/get_images', auth='user', methods=['GET'], cors='*')
-    def get_images_only(self, **kw):
-        settings = self.get_pos_settings()
-        image_type = str(settings.get('imageType'))
+    def _get_images_only(self, **kw):
+        image_type = str(get_pos_config().get('imageType'))
 
-        return self.make_gzip_response(
-            {
-                'customers': self.get_customers(image_type=image_type),
-                'products': self.get_products(image_type=image_type)
-            }
-        )
+        return make_gzip_response({
+            'customers': get_customers(image_type=image_type),
+            'products': 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):
+    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
-        }
+        return create_customer(kw)
     
     '''
         Save settings
     '''
     @http.route('/eiru_sales/save_settings', type='json', auth='user', methods=['POST'], cors='*')
-    def save_settings(self, **kw):
+    def _save_config(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)
-
-        settings = request.env['base.config.settings'].search([], limit=1, order='id desc')
-        settings.write(values)
-        settings.execute()
-        
-        return self.get_pos_settings()
+        return save_pos_config(kw)
     
     '''
         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]
-        }
-
+    def _create_product(self, **kw):
+        return create_product(kw)
+        
     '''
         Process sale
     '''
     @http.route('/eiru_sales/process_sale', type='json', auth='user', methods=['POST'], cors='*')
-    def process_sale(self, **kw):
+    def _process_sale(self, **kw):
         self.make_info_log('Processing sale...')
 
-        # Get date
-        date_now = datetime.now(self.get_timezone()).strftime(DEFAULT_SERVER_DATE_FORMAT)
-        self.make_info_log('[OK] Getting date')
+        date_now = get_date()
+        journal_id = kw.get('journalId', None)
+        customer_id = kw.get('customerId', None)
+        cart_items = kw.get('items', [])
+        payment_term_id = kw.get('paymentTermId', None)
+        payment = float(kw.get('payment'))
+        bank_payment_data = kw.get('bankPaymentData', {})
 
         # Get currency
-        currency_id = self.get_currency(kw.get('journalId'))
+        currency_id = get_currency(journal_id)
         self.make_info_log('[OK] Getting journal')
 
-        # Get Pricelist
-        pricelist = self.get_pricelist(currency_id)
-        self.make_info_log('[OK] Getting product pricelist')
-
         # Create sale order
-        sale_order = self.create_sale_from_cart(kw.get('customerId'), kw.get('items'), date_now, currency_id, pricelist.id, kw.get('paymentTermId'))
+        sale_order = create_sale_from_cart(customer_id, cart_items, date_now, currency_id, payment_term_id)
         self.make_info_log('[OK] Creating sale order')
 
         # Check if budget
@@ -789,43 +120,44 @@ class PosSales(http.Controller):
             }
 
         # Confirm sale
-        self.confirm_sale_order(sale_order.id)
+        confirm_sale_order(sale_order.id)
         self.make_info_log('[OK] Confirm sale order')
 
         # Create invoice
-        invoice = self.create_invoice(sale_order.id, currency_id, date_now)
+        invoice = create_invoice(sale_order.id, currency_id, date_now)
         self.make_info_log('[OK] Creating invoice')
 
         # Create invoice move lines
-        invoice_move_lines = self.create_invoice_move_lines(invoice.id, float(kw.get('payment')), date_now)
+        invoice_move_lines = create_invoice_move_lines(invoice.id, payment, date_now)
         self.make_info_log('[OK] Creating invoice move lines')
 
         # Create account move
-        account_move = self.create_account_move(invoice.id, invoice_move_lines)
+        account_move = create_account_move(invoice.id, invoice_move_lines)
         self.make_info_log('[OK] Creating account move')
 
         # Number invoice
-        self.number_invoice(invoice.id)
+        number_invoice(invoice.id)
         self.make_info_log('[OK] Number invoice')
 
         # Create account voucher
-        account_voucher = self.create_account_voucher(account_move.id, kw.get('journalId'), currency_id, float(kw.get('payment')))
+        account_voucher = create_account_voucher(account_move.id, journal_id, currency_id, payment)
         self.make_info_log('[OK] Creating account voucher')
 
         # Close invoice
-        self.close_invoice(invoice.id)
+        close_invoice(invoice.id)
         self.make_info_log('[OK] Closing invoice')
 
-        # Create account bank statement lines
-        account_bank_statement_lines = self.create_bank_statement_lines(account_voucher.id)
-        self.make_info_log('[OK] Creating account bank statement lines')
-
         # Create bank statement
-        self.create_bank_statement(account_voucher.id, account_bank_statement_lines, date_now)
+        create_bank_statement(account_voucher.id, date_now)
         self.make_info_log('[OK] Creating account bank statement')
 
+        # Create bank payment statement
+        if (kw.get('paymentMethod', False), ):
+            create_bank_payment_statement(bank_payment_data, currency_id, invoice.date_invoice, customer_id)
+            self.make_info_log('[OK] Creating bank payment statement')
+
         return {
             'process': True,
             'name': sale_order.display_name,
-            'date': self.get_server_datetime()
+            'date': get_datetime
         }

+ 77 - 0
controllers/product_template.py

@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'product.template'
+
+'''
+'''
+def get_products(image_type='small'):
+    domain = [
+        ('sale_ok', '=', True), 
+        ('list_price', '>', 0),
+        ('active', '=', True)
+    ]
+
+    return [
+        {
+            'id': product.id,
+            'name': product.display_name,
+            'ean13': product.ean13,
+            'defaultCode': product.default_code,
+            'image': product.image_small if image_type == 'small' else product.image_medium,
+            'listPrice': product.list_price,
+            'variantCount': product.product_variant_count,
+            'quantity': 1,
+            'price': product.list_price,
+            'minimumPrice': product.minimum_price,
+            'maximumPrice': product.maximum_price,
+            'discount': 0,
+            'variants': [{
+                'id': variant.id,
+                'name': variant.display_name,
+                'ean13': variant.ean13,
+                'defaultCode': product.default_code,
+                'image': variant.image_small if image_type == 'small' else variant.image_medium,
+                'listPrice': variant.list_price,
+                'quantity': 1,
+                'price': variant.list_price,
+                'minimumPrice': product.minimum_price,
+                'maximumPrice': product.maximum_price,
+                'discount': 0,
+            } for variant in product.product_variant_ids if variant.active]
+        } for product in request.env[_MODEL].search(domain)
+    ]
+
+'''
+    Create product and return
+'''
+def create_product(**kw):
+    product = request.env[_MODEL].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]
+    }
+
+

+ 16 - 0
controllers/res_bank.py

@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'res.bank'
+
+'''
+'''
+def get_banks():
+    banks = [
+        {
+            'id': bank.id,
+            'name': bank.display_name
+        } for bank in request.env[_MODEL].search([('active', '=', True)])
+    ]
+
+    return banks

+ 16 - 0
controllers/res_bank_cheque_type.py

@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'res.bank.check.type'
+
+'''
+'''
+def get_cheque_types():
+    return [
+        {
+            'id': type.id,
+            'name': type.display_name,
+            'isBank': type.is_bank,
+            'isCash': type.is_cash
+        } for type in request.env[_MODEL].search([])
+    ]

+ 24 - 0
controllers/res_bank_payment.py

@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'res.bank.payments'
+
+'''
+'''
+def create_bank_payment_statement(data, currency_id, date, partner_id=None, supplier_id=None):
+    values = {    
+        'bank_id': data.get('bankId', None),
+        'bank_payments_type_id': data.get('bankPaymentTypeId', None),
+        'currency_id': currency_id,
+        'date': date,
+        'partner_id': partner_id,
+        'number_cta': data.get('accountNumber', None),
+        'number_cta_origin': data.get('originAccount', None),
+        'name_holder': data.get('accountHolder', None),
+        'number': data.get('voucherNumber'),
+        'date_maturity': str(data.get('dueDate', '')),
+        'supplier_id': supplier_id,
+        'amount_total': data.get('amount', None)
+    }
+
+    request.env['res.bank.payments'].create(values)

+ 24 - 0
controllers/res_bank_payment_type.py

@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'res.bank.payments.type'
+
+'''
+    Get bank payment types
+'''
+def get_bank_payment_types():
+    domain = [
+        ('is_receipt', '=', True)
+    ]
+
+    return [
+        {
+            'id': type.id,
+            'name': type.display_name,
+            '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[_MODEL].search(domain)
+    ]

+ 47 - 0
controllers/res_config.py

@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'base.config.settings'
+
+'''
+'''
+def get_pos_config():
+    config = request.env[_MODEL].search([], limit=1, order='id desc')
+
+    return {
+        'imageType': config.image_type,
+        'allowCurrencyExchange': config.allow_currency_exchange,
+        'viewCurrencyExchanges': config.view_currency_exchanges,
+        'currencies': [
+            {
+                'id': currency.id,
+                'name': currency.display_name,
+                'symbol': currency.symbol,
+                'position': currency.position,
+                'rateSilent': currency.rate_silent,
+                'decimalSeparator': currency.decimal_separator,
+                'decimalPlaces': currency.decimal_places,
+                'thousandsSeparator': currency.thousands_separator
+            } for currency in config.currency_ids
+        ]
+    }
+
+'''
+'''
+def save_pos_config(**kw):
+    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)
+
+    settings = request.env[_MODEL].search([], limit=1, order='id desc')
+    settings.write(values)
+    settings.execute()
+    
+    return get_pos_config()

+ 45 - 0
controllers/res_partner.py

@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'res.partner'
+
+'''
+'''
+def get_customers(image_type='small'):
+    domain = [
+        ('customer', '=', True),
+        ('active', '=', True)
+    ]
+
+    return [
+        {
+            'id': customer.id,
+            'name': customer.display_name,
+            '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,
+            'email': customer.email or None
+        } for customer in request.env['res.partner'].search(domain)
+    ]
+
+'''
+    Create and get customer
+'''
+def create_customer(**kw):
+    customer = request.env[_MODEL].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
+    }

+ 8 - 0
controllers/res_store.py

@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+'''
+'''
+def get_res_store(self, **args):
+    return {
+        'stores': []
+    }

+ 18 - 0
controllers/res_users.py

@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+def get_current_user():
+    user = request.env.user
+
+    return {
+        'id': user.id,
+        'name': user.display_name,
+        'company': {
+            'id': user.company_id.id,
+            'name': user.company_id.display_name,
+            'phone': user.company_id.phone or None,
+            'city': user.company_id.city or None,
+            'currencyId': user.company_id.currency_id.id or None
+        },
+        'isManager': 'Gerente' in user.groups_id.filtered(lambda g: g.category_id.name == 'Eiru POS').mapped(lambda g: g.name)
+    }

+ 76 - 0
controllers/sale_order.py

@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+_MODEL = 'sale.order'
+
+'''
+    Create sale from pos cart
+'''
+def create_sale_from_cart(partner_id, cart_items, date_confirm, currency_id, payment_term_id=None):
+    '''
+    '''
+    def get_pricelist(currency_id):
+        domain = [
+            ('active', '=', True),
+            ('type', '=', 'sale')
+        ]
+        pricelist = request.env['product.pricelist'].search(domain)
+
+        if not True in pricelist.mapped(lambda p: p.currency_id.id == currency_id):
+            pricelist = pricelist[0].copy()
+            pricelist.write({
+                'currency_id': currency_id
+            })
+        else:
+            pricelist = pricelist.filtered(lambda p: p.currency_id.id == currency_id)
+        
+        return pricelist
+
+    '''
+    '''
+    def compute_cart_item_price(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(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)
+
+    pricelist = get_pricelist(currency_id)
+
+    values = {
+        'partner_id': partner_id,
+        'order_line': [[0, False, {
+            'product_id': int(line.get('id')),
+            'product_uom_qty': float(line.get('quantity')),
+            'price_unit': compute_cart_item_price(float(line.get('price')), currency_id),
+            'discount': 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,
+        'currency_id': currency_id,
+        'pricelist_id': pricelist.id,
+        'payment_term': payment_term_id,
+        'state': 'draft',
+    }
+
+    return request.env[_MODEL].create(values)
+
+'''
+'''
+def confirm_sale_order(sale_order_id):
+    sale_order = request.env['sale.order'].browse(sale_order_id)
+    sale_order.write({
+        'state': 'manual'
+    })
+
+    return sale_order.action_button_confirm()

+ 20 - 0
controllers/server_datetime.py

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

+ 12 - 0
controllers/utils.py

@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request
+
+
+'''
+    Check if module is installed
+'''
+def is_module_installed(module_name):
+    domain = [('name', '=', module_name), ('state', '=', 'installed')]
+    module = request.env['ir.module.module'].search(domain)
+
+    return len(module) != 0

+ 1 - 0
package.json

@@ -33,6 +33,7 @@
 		"vue": "^2.5.13",
 		"vue-form-wizard": "^0.8.2",
 		"vue-js-modal": "^1.3.9",
+		"vue2-datepicker": "^2.0.3",
 		"vuex": "^3.0.1",
 		"vuex-persistedstate": "^2.5.2"
 	}

+ 30 - 5
src/components/modals/BankPaymentModal.vue

@@ -32,10 +32,16 @@
                             ) {{ bankPaymentType.name }}
                     .form-item(v-show="canBeShow('number_cta')")
                         label.form-label Nº de Cuenta
-                        input.form-input(v-model='voucherNumber')
+                        input.form-input(v-model='accountNumber')
                     .form-item(v-show="canBeShow('date_maturity')")
                         label.form-label Vencimiento
-                        input.form-input(v-model='dueDate')
+                        date-picker.form-input(
+                            v-model='dueDate'
+                            input-class='form-input'
+                            lang='es'
+                            :editable='false'
+                            :not-before="new Date()"
+                        )
                     .form-item(v-show="canBeShow('check_type_id')")
                         label.form-label Tipo de Cheque
                         select.form-input(v-model='selectedChequeTypeId')
@@ -63,7 +69,7 @@
                         input.form-input(v-model='originAccount')
             tab-content(title='De qué monto es la operación?')
                 form.payment-details-form
-                    .form-item(v-show="canBeShow('amount_total')")
+                    .form-item
                         label.form-label Monto del Pago
                         input.form-input(v-model='amount')
             template(
@@ -98,10 +104,15 @@
 
 <script>
     import { FormWizard, TabContent, WizardButton } from 'vue-form-wizard'
+    import DatePicker from 'vue2-datepicker'
     import { CardGrid, DropdownSearcher } from '../common'
 
     export default {
         props: {
+            initialAmount: {
+                type: Number,
+                required: true
+            },
             journals: {
                 type: Array,
                 required: true
@@ -140,7 +151,8 @@
             TabContent,
             WizardButton,
             DropdownSearcher,
-            CardGrid
+            CardGrid,
+            DatePicker
         },
         computed: {
             selectedBankPaymentTypeId: {
@@ -174,6 +186,9 @@
                 }
 
                 this.$modal.show('payment-bank-modal')
+            },
+            initialAmount(value) {
+                this.amount = value
             }
         },
         methods: {
@@ -226,8 +241,17 @@
                 this.$emit('onCancel')
             }
         },
+        mounted() {
+            this.accountNumber = ''
+            this.voucherNumber = ''
+            this.dueDate = ''
+            this.accountHolder = ''
+            this.originAccount =''
+            this.amount = 0
+        },
         data() {
             return {
+                accountNumber: '',
                 voucherNumber: '',
                 dueDate: '',
                 accountHolder: '',
@@ -265,13 +289,14 @@
                         .form-label
                             width: 200px
                             height: 35px
-                            font-size: 13pt
+                            font-size: 12pt
                             line-height: 30px
                         .form-input
                             width: 400px
                             height: 35px
                             font-size: 12pt
                             border-radius: 0
+                            color: #666
                             &.input-only
                                 margin-left: 200px
                                 margin-bottom: 15px

+ 1 - 0
src/components/steps/Payment.vue

@@ -76,6 +76,7 @@
                             td {{ line.total | currency(...selectedCurrency) }}
                             td {{ line.date }}
         bank-payment-modal(
+            :initialAmount='amountToPay'
             :journals='bankJournals'
             :hasSelectedJournal='hasBankJournalSelected'
             :banks='banks'

+ 1 - 0
src/store/actions.js

@@ -145,6 +145,7 @@ const actions = {
                 journalId: getters.selectedJournal.id,
                 payment: getters.initialPayment > getters.amountToPay ? getters.amountToPay : getters.initialPayment,
                 currencyId: getters.selectedCurrency.id,
+                paymentMethod: getters.paymentMethod,
                 bankPaymentData: {
                     bankPaymentTypeId: (getters.selectedBankPaymentType && getters.selectedBankPaymentType.id) || null,
                     chequeTypeId: (getters.selectedChequeType && getters.selectedChequeType.id) || null,

+ 5 - 1
src/store/modules/payment.js

@@ -232,8 +232,12 @@ const actions = {
             dispatch('computePaymentLines')
         }
     },
-    changeBankPaymentData({ commit }, bankPaymentData) {
+    changeBankPaymentData({ commit, dispatch }, bankPaymentData) {
         commit('setBankPaymentData', bankPaymentData)
+
+        if (bankPaymentData.amount) {
+            dispatch('changeInitialPayment', bankPaymentData.amount)
+        }
     },
     computePaymentLines({ commit, getters }) {
         commit('setPaymentLines', {

+ 10 - 0
yarn.lock

@@ -1743,6 +1743,10 @@ faye-websocket@~0.10.0:
   dependencies:
     websocket-driver ">=0.5.1"
 
+fecha@^2.3.3:
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd"
+
 file-loader@^1.1.6:
   version "1.1.6"
   resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.6.tgz#7b9a8f2c58f00a77fddf49e940f7ac978a3ea0e8"
@@ -4344,6 +4348,12 @@ vue-template-es2015-compiler@^1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
 
+vue2-datepicker@^2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/vue2-datepicker/-/vue2-datepicker-2.0.3.tgz#69513825cb31690773e81b66019aeb2092d4c809"
+  dependencies:
+    fecha "^2.3.3"
+
 vue@^2.5.13:
   version "2.5.13"
   resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.13.tgz#95bd31e20efcf7a7f39239c9aa6787ce8cf578e1"