|
@@ -9,11 +9,15 @@ from dateutil.relativedelta import relativedelta as rd
|
|
|
from dateutil.parser import parse
|
|
|
from pytz import timezone
|
|
|
from gzip import GzipFile
|
|
|
-from StringIO import StringIO as IO
|
|
|
import simplejson as json
|
|
|
import gzip
|
|
|
import logging
|
|
|
|
|
|
+try:
|
|
|
+ from cStringIO import StringIO as IO
|
|
|
+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'
|
|
@@ -48,11 +52,12 @@ class PosSales(http.Controller):
|
|
|
'''
|
|
|
Check if module is installed
|
|
|
'''
|
|
|
- def check_module(self, module_name):
|
|
|
- module = request.env['ir.module.module'].search([('name', '=', module_name), ('state', '=', '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
|
|
|
'''
|
|
@@ -61,87 +66,51 @@ class PosSales(http.Controller):
|
|
|
|
|
|
return {
|
|
|
'id': user.id,
|
|
|
- 'name': user.name,
|
|
|
- 'displayName': user.display_name,
|
|
|
- 'currency': {
|
|
|
- 'id': user.company_id.currency_id.id,
|
|
|
- 'name': user.company_id.currency_id.name,
|
|
|
- 'displayName': user.company_id.currency_id.display_name,
|
|
|
- 'symbol': user.company_id.currency_id.symbol
|
|
|
- },
|
|
|
+ 'name': user.display_name,
|
|
|
'company': {
|
|
|
'id': user.company_id.id,
|
|
|
- 'name': user.company_id.name,
|
|
|
- 'displayName': user.company_id.display_name,
|
|
|
+ 'name': user.company_id.display_name,
|
|
|
'phone': user.company_id.phone or None,
|
|
|
- 'city': user.company_id.city or None,
|
|
|
- 'website': user.company_id.website,
|
|
|
- 'state': {
|
|
|
- 'id': user.company_id.state_id.id,
|
|
|
- 'name': user.company_id.state_id.name,
|
|
|
- 'displayName': user.company_id.state_id.display_name
|
|
|
- }
|
|
|
+ 'city': user.company_id.city or None
|
|
|
}
|
|
|
}
|
|
|
|
|
|
'''
|
|
|
- Get currencies
|
|
|
+ Get currencies from configured journals
|
|
|
'''
|
|
|
- def get_currencies(self):
|
|
|
- return [{
|
|
|
- 'id': currency.id,
|
|
|
- 'name': currency.name,
|
|
|
- 'displayName': currency.display_name,
|
|
|
- 'base': currency.base,
|
|
|
- 'accuracy': currency.accuracy,
|
|
|
- 'rateSilent': currency.rate_silent,
|
|
|
- 'rounding': currency.rounding,
|
|
|
- 'symbol': currency.symbol,
|
|
|
- 'position': currency.position,
|
|
|
- 'decimalSeparator': currency.decimal_separator,
|
|
|
- 'decimalPlaces': currency.decimal_places,
|
|
|
- 'thousandsSeparator': currency.thousands_separator
|
|
|
- } for currency in request.env['res.currency'].search([('active', '=', True)])]
|
|
|
+ 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,
|
|
|
+ '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)]
|
|
|
+
|
|
|
return [{
|
|
|
'id': journal.id,
|
|
|
- 'name': journal.name,
|
|
|
- 'displayName': journal.display_name,
|
|
|
+ 'name': journal.display_name,
|
|
|
'code': journal.code,
|
|
|
- 'cashControl': journal.cash_control,
|
|
|
'type': journal.type,
|
|
|
- 'currency': {
|
|
|
- 'id': journal.currency.id,
|
|
|
- 'name': journal.currency.name,
|
|
|
- 'displayName': journal.currency.display_name
|
|
|
- },
|
|
|
- 'defaultCreditAccount': {
|
|
|
- 'id': journal.default_credit_account_id.id,
|
|
|
- 'name': journal.default_credit_account_id.name,
|
|
|
- 'displayName': journal.default_credit_account_id.display_name,
|
|
|
- 'code': journal.default_credit_account_id.code,
|
|
|
- 'exchangeRate': journal.default_credit_account_id.exchange_rate,
|
|
|
- 'foreignBalance': journal.default_credit_account_id.foreign_balance,
|
|
|
- 'reconcile': journal.default_credit_account_id.reconcile,
|
|
|
- 'debit': journal.default_credit_account_id.debit,
|
|
|
- 'credit': journal.default_credit_account_id.credit,
|
|
|
- 'currencyMode': journal.default_credit_account_id.currency_mode,
|
|
|
- 'companyCurrency': {
|
|
|
- 'id': journal.default_credit_account_id.company_currency_id.id,
|
|
|
- 'name': journal.default_credit_account_id.company_currency_id.name,
|
|
|
- 'displayName': journal.default_credit_account_id.company_currency_id.display_name,
|
|
|
- },
|
|
|
- 'currency': {
|
|
|
- 'id': journal.default_credit_account_id.currency_id.id,
|
|
|
- 'name': journal.default_credit_account_id.currency_id.name,
|
|
|
- 'displayName': journal.default_credit_account_id.currency_id.display_name
|
|
|
- },
|
|
|
- }
|
|
|
- } for journal in request.env['account.journal'].search([('type', 'in', ['bank', 'cash']), ('default_credit_account_id.currency_id', '=', False), ('active', '=', True)], order='id')]
|
|
|
+ 'currencyId': journal.currency.id or journal.company_id.currency_id.id
|
|
|
+ } for journal in request.env['account.journal'].search(domain, order='id')]
|
|
|
|
|
|
'''
|
|
|
Get banks
|
|
@@ -149,12 +118,13 @@ class PosSales(http.Controller):
|
|
|
def get_banks(self):
|
|
|
banks = []
|
|
|
|
|
|
- if self.check_module('eiru_bank_payments_references'):
|
|
|
- banks = [{
|
|
|
+ if self.is_module_installed('eiru_bank_payments_references'):
|
|
|
+ banks = [
|
|
|
+ {
|
|
|
'id': bank.id,
|
|
|
- 'name': bank.name,
|
|
|
- 'displayName': bank.display_name
|
|
|
- } for bank in request.env['res.bank'].search([('active', '=', True)])]
|
|
|
+ 'name': bank.display_name
|
|
|
+ } for bank in request.env['res.bank'].search([('active', '=', True)])
|
|
|
+ ]
|
|
|
|
|
|
return banks
|
|
|
|
|
@@ -164,14 +134,15 @@ class PosSales(http.Controller):
|
|
|
def get_bank_payment_types(self):
|
|
|
bank_types = []
|
|
|
|
|
|
- if self.check_module('eiru_bank_payments_references'):
|
|
|
- bank_types = [{
|
|
|
+ if self.is_module_installed('eiru_bank_payments_references'):
|
|
|
+ bank_types = [
|
|
|
+ {
|
|
|
'id': type.id,
|
|
|
- 'name': type.name,
|
|
|
- 'displayName': type.display_name,
|
|
|
+ 'name': type.display_name,
|
|
|
'code': type.code,
|
|
|
'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([('is_receipt', '=', True)])
|
|
|
+ ]
|
|
|
|
|
|
return bank_types
|
|
|
|
|
@@ -179,67 +150,75 @@ class PosSales(http.Controller):
|
|
|
Get all active customers
|
|
|
'''
|
|
|
def get_customers(self):
|
|
|
- return [{
|
|
|
- 'id': customer.id,
|
|
|
- 'name': customer.name,
|
|
|
- 'displayName': customer.display_name,
|
|
|
- 'imageMedium': 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([('customer', '=', True), ('active', '=', True)])]
|
|
|
+ domain = [('customer', '=', True), ('active', '=', 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
|
|
|
+ } for customer in request.env['res.partner'].search(domain)
|
|
|
+ ]
|
|
|
|
|
|
'''
|
|
|
Get all saleable and active products
|
|
|
'''
|
|
|
def get_products(self):
|
|
|
- return [{
|
|
|
- 'id': product.id,
|
|
|
- 'name': product.name,
|
|
|
- 'displayName': product.display_name,
|
|
|
- 'ean13': product.ean13,
|
|
|
- 'defaultCode': product.default_code,
|
|
|
- 'imageMedium': 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.name,
|
|
|
- 'displayName': variant.display_name,
|
|
|
- 'ean13': variant.ean13,
|
|
|
+ domain = [('sale_ok', '=', True), ('list_price', '>', 0), ('active', '=', True)]
|
|
|
+
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ 'id': product.id,
|
|
|
+ 'name': product.display_name,
|
|
|
+ 'ean13': product.ean13,
|
|
|
'defaultCode': product.default_code,
|
|
|
- 'imageMedium': variant.image_medium,
|
|
|
- 'listPrice': variant.list_price,
|
|
|
+ 'image': product.image_small,
|
|
|
+ 'listPrice': product.list_price,
|
|
|
+ 'variantCount': product.product_variant_count,
|
|
|
'quantity': 1,
|
|
|
- 'price': variant.list_price,
|
|
|
+ 'price': product.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([('sale_ok', '=', True), ('list_price', '>', 0), ('active', '=', True)])]
|
|
|
+ 'variants': [{
|
|
|
+ 'id': variant.id,
|
|
|
+ 'name': variant.display_name,
|
|
|
+ 'ean13': variant.ean13,
|
|
|
+ 'defaultCode': product.default_code,
|
|
|
+ 'image': 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):
|
|
|
- return [{
|
|
|
- 'id': payment_term.id,
|
|
|
- 'name': payment_term.name,
|
|
|
- 'displayName': 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([('active', '=', True)])]
|
|
|
+ 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)
|
|
|
+ ]
|
|
|
|
|
|
'''
|
|
|
Make JSON response
|
|
@@ -252,6 +231,7 @@ class PosSales(http.Controller):
|
|
|
'''
|
|
|
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))
|
|
|
|
|
@@ -264,7 +244,7 @@ class PosSales(http.Controller):
|
|
|
headers.add('Content-Length', len(contents))
|
|
|
|
|
|
return Response(contents, status=status, headers=headers, content_type='application/json')
|
|
|
-
|
|
|
+
|
|
|
'''
|
|
|
'''
|
|
|
def make_info_log(self, log):
|
|
@@ -277,17 +257,19 @@ class PosSales(http.Controller):
|
|
|
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(),
|
|
|
- '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()
|
|
|
- })
|
|
|
+ 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()
|
|
|
+ }
|
|
|
+ )
|
|
|
|
|
|
|
|
|
'''
|
|
@@ -306,9 +288,8 @@ class PosSales(http.Controller):
|
|
|
|
|
|
return {
|
|
|
'id': customer.id,
|
|
|
- 'name': customer.name,
|
|
|
- 'displayName': customer.display_name,
|
|
|
- 'imageMedium': customer.image_medium,
|
|
|
+ 'name': customer.display_name,
|
|
|
+ 'image': customer.image_small,
|
|
|
'ruc': customer.ruc or None,
|
|
|
'phone': customer.phone or None,
|
|
|
'mobile': customer.mobile or None,
|
|
@@ -330,10 +311,9 @@ class PosSales(http.Controller):
|
|
|
|
|
|
return {
|
|
|
'id': product.id,
|
|
|
- 'name': product.name,
|
|
|
- 'displayName': product.display_name,
|
|
|
+ 'name': product.display_name,
|
|
|
'ean13': product.ean13,
|
|
|
- 'imageMedium': product.image_medium,
|
|
|
+ 'image': product.image_small,
|
|
|
'listPrice': product.list_price,
|
|
|
'variantCount': product.product_variant_count,
|
|
|
'quantity': 1,
|
|
@@ -341,10 +321,9 @@ class PosSales(http.Controller):
|
|
|
'discount': 0,
|
|
|
'variants': [{
|
|
|
'id': variant.id,
|
|
|
- 'name': variant.name,
|
|
|
- 'displayName': variant.display_name,
|
|
|
+ 'name': variant.display_name,
|
|
|
'ean13': variant.ean13,
|
|
|
- 'imageMedium': variant.image_medium,
|
|
|
+ 'image': variant.image_small,
|
|
|
'listPrice': variant.list_price,
|
|
|
'quantity': 1,
|
|
|
'price': variant.list_price,
|