|
@@ -1,785 +1,116 @@
|
|
# -*- coding: utf-8 -*-
|
|
# -*- coding: utf-8 -*-
|
|
-
|
|
|
|
-from openerp import api, http
|
|
|
|
|
|
+from openerp import http
|
|
from openerp.http import request
|
|
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
|
|
import logging
|
|
|
|
|
|
-try:
|
|
|
|
- from cStringIO import StringIO as IO
|
|
|
|
-except ImportError:
|
|
|
|
- from StringIO import StringIO as IO
|
|
|
|
-
|
|
|
|
LOGGER = logging.getLogger(__name__)
|
|
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):
|
|
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
|
|
New purchase resource route
|
|
'''
|
|
'''
|
|
@http.route('/eiru_sales/init', auth='user', methods=['GET'], cors='*')
|
|
@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')
|
|
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
|
|
Get products data only
|
|
'''
|
|
'''
|
|
@http.route('/eiru_sales/get_images', auth='user', methods=['GET'], cors='*')
|
|
@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
|
|
Create customer and return data
|
|
'''
|
|
'''
|
|
@http.route('/eiru_sales/create_customer', type='json', auth='user', methods=['POST'], cors='*')
|
|
@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')
|
|
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
|
|
Save settings
|
|
'''
|
|
'''
|
|
@http.route('/eiru_sales/save_settings', type='json', auth='user', methods=['POST'], cors='*')
|
|
@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')
|
|
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
|
|
Create product and return data
|
|
'''
|
|
'''
|
|
@http.route('/eiru_sales/create_product', type='json', auth='user', methods=['POST'], cors='*')
|
|
@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
|
|
Process sale
|
|
'''
|
|
'''
|
|
@http.route('/eiru_sales/process_sale', type='json', auth='user', methods=['POST'], cors='*')
|
|
@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...')
|
|
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
|
|
# Get currency
|
|
- currency_id = self.get_currency(kw.get('journalId'))
|
|
|
|
|
|
+ currency_id = get_currency(journal_id)
|
|
self.make_info_log('[OK] Getting journal')
|
|
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
|
|
# 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')
|
|
self.make_info_log('[OK] Creating sale order')
|
|
|
|
|
|
# Check if budget
|
|
# Check if budget
|
|
@@ -789,43 +120,44 @@ class PosSales(http.Controller):
|
|
}
|
|
}
|
|
|
|
|
|
# Confirm sale
|
|
# Confirm sale
|
|
- self.confirm_sale_order(sale_order.id)
|
|
|
|
|
|
+ confirm_sale_order(sale_order.id)
|
|
self.make_info_log('[OK] Confirm sale order')
|
|
self.make_info_log('[OK] Confirm sale order')
|
|
|
|
|
|
# Create invoice
|
|
# 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')
|
|
self.make_info_log('[OK] Creating invoice')
|
|
|
|
|
|
# Create invoice move lines
|
|
# 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')
|
|
self.make_info_log('[OK] Creating invoice move lines')
|
|
|
|
|
|
# Create account move
|
|
# 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')
|
|
self.make_info_log('[OK] Creating account move')
|
|
|
|
|
|
# Number invoice
|
|
# Number invoice
|
|
- self.number_invoice(invoice.id)
|
|
|
|
|
|
+ number_invoice(invoice.id)
|
|
self.make_info_log('[OK] Number invoice')
|
|
self.make_info_log('[OK] Number invoice')
|
|
|
|
|
|
# Create account voucher
|
|
# 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')
|
|
self.make_info_log('[OK] Creating account voucher')
|
|
|
|
|
|
# Close invoice
|
|
# Close invoice
|
|
- self.close_invoice(invoice.id)
|
|
|
|
|
|
+ close_invoice(invoice.id)
|
|
self.make_info_log('[OK] Closing invoice')
|
|
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
|
|
# 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')
|
|
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 {
|
|
return {
|
|
'process': True,
|
|
'process': True,
|
|
'name': sale_order.display_name,
|
|
'name': sale_order.display_name,
|
|
- 'date': self.get_server_datetime()
|
|
|
|
|
|
+ 'date': get_datetime
|
|
}
|
|
}
|