Fix
This commit is contained in:
parent
33c4c95df6
commit
e7b78bb847
|
@ -0,0 +1,998 @@
|
|||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import math
|
||||
from operator import attrgetter
|
||||
from decimal import Decimal
|
||||
from sql import Table
|
||||
from sql.aggregate import Sum
|
||||
from datetime import date, timedelta, datetime
|
||||
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.model import fields
|
||||
from trytond.modules.dash.dash import DashAppBase
|
||||
from .process_pay import (
|
||||
get_pay, get_response_pay, process_response, get_dict_response_pay)
|
||||
|
||||
|
||||
class Sale(metaclass=PoolMeta):
|
||||
__name__ = 'sale.sale'
|
||||
|
||||
@classmethod
|
||||
def dash_faster_process(cls, records):
|
||||
for rec in records:
|
||||
cls.faster_process({'id': rec.id})
|
||||
|
||||
@classmethod
|
||||
def dash_quote(cls, args, ctx=None):
|
||||
# Deprecation warning use create sale instead
|
||||
print("Deprecation Warning: use method create_sale instead")
|
||||
cls.create_sale(cls, args, ctx=None)
|
||||
|
||||
@classmethod
|
||||
def send_order(cls, args, ctx=None):
|
||||
Product = Pool().get('product.product')
|
||||
if args['id'] <= 0:
|
||||
res = cls.create_sale(args, ctx)
|
||||
return res
|
||||
else:
|
||||
records = cls.browse([args['id']])
|
||||
lines_tuple = args.get('lines')
|
||||
action, lines = lines_tuple
|
||||
if action == 'create' and len(lines) > 0:
|
||||
for line in lines:
|
||||
product = Product(line['product'])
|
||||
cls._add_values(product.template, line)
|
||||
cls.write(records, args)
|
||||
res = {
|
||||
'record': {'id': args['id']},
|
||||
'msg': 'Pedido Actualizado!!!',
|
||||
'type': 'success',
|
||||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def _add_values(cls, template, line):
|
||||
line['status_order'] = 'requested'
|
||||
line['unit'] = template.default_uom.id
|
||||
line['description'] = template.name
|
||||
taxes = list(template.account_category.customer_taxes_used)
|
||||
taxes_ids = [t.id for t in taxes]
|
||||
line['taxes'] = [('add', taxes_ids)]
|
||||
|
||||
@classmethod
|
||||
def create_sale(cls, args, ctx=None):
|
||||
Shop = Pool().get('sale.shop')
|
||||
Product = Pool().get('product.product')
|
||||
Party = Pool().get('party.party')
|
||||
User = Pool().get('res.user')
|
||||
ctx = Transaction().context
|
||||
if ctx.get('shop'):
|
||||
shop = Shop(ctx['shop'])
|
||||
if args.get('shop'):
|
||||
shop = Shop(args['shop'])
|
||||
else:
|
||||
user_id = ctx.get('user')
|
||||
user = User(user_id)
|
||||
shop = user.shop
|
||||
|
||||
lines = args['lines']
|
||||
nested_values = None
|
||||
for line in lines:
|
||||
if line and line[0] == 'create':
|
||||
nested_values = line[1]
|
||||
if nested_values:
|
||||
lines = nested_values
|
||||
for v in lines:
|
||||
if v.get('id'):
|
||||
del v['id']
|
||||
if v.get('amount'):
|
||||
del v['amount']
|
||||
if v.get('unit_price_w_tax'):
|
||||
del v['unit_price_w_tax']
|
||||
if v.get('total_amount'):
|
||||
del v['total_amount']
|
||||
v['type'] = 'line'
|
||||
v['status_order'] = 'requested'
|
||||
v['unit_price'] = round(Decimal(v['unit_price']), 4)
|
||||
product = Product(v['product'])
|
||||
|
||||
if v.get('discount') and v['discount'] != '':
|
||||
v['discount'] = Decimal(v['discount']) / 100
|
||||
elif v.get('discount'):
|
||||
del v['discount']
|
||||
|
||||
template = product.template
|
||||
cls._add_values(template, v)
|
||||
|
||||
try:
|
||||
price_list = args['price_list']['id']
|
||||
except Exception:
|
||||
price_list = args.get('price_list', None)
|
||||
|
||||
try:
|
||||
# for kid
|
||||
party, = Party.browse([args['party']['id']])
|
||||
except Exception:
|
||||
# for fastkid
|
||||
party, = Party.browse([args['party']])
|
||||
if args.get('shipment_address'):
|
||||
try:
|
||||
# for kid
|
||||
shipment_address_id = args.get('shipment_address')['id']
|
||||
except Exception:
|
||||
# for fastkid
|
||||
shipment_address_id = args.get('shipment_address')
|
||||
else:
|
||||
shipment_address_id = party.addresses[0].id
|
||||
|
||||
agent_id = None
|
||||
if args.get('agent'):
|
||||
try:
|
||||
# option kid
|
||||
agent_id = args['agent']['id']
|
||||
except Exception:
|
||||
# option fastkid
|
||||
agent_id = args['agent']
|
||||
|
||||
shipment_date = None
|
||||
if args.get('shipment_date'):
|
||||
shipment_date = args['shipment_date']
|
||||
|
||||
description = args.get('description', '')
|
||||
comment = args.get('comment', '')
|
||||
today = date.today()
|
||||
to_create = {
|
||||
'shop': shop.id,
|
||||
'invoice_type': 'P',
|
||||
'company': shop.company.id,
|
||||
'party': party.id,
|
||||
'sale_date': today,
|
||||
'shipment_date': shipment_date,
|
||||
'shipment_address': shipment_address_id,
|
||||
'invoice_address': shipment_address_id,
|
||||
'agent': agent_id,
|
||||
'price_list': price_list,
|
||||
'payment_term': shop.payment_term.id,
|
||||
'state': 'draft',
|
||||
'description': description,
|
||||
'comment': comment,
|
||||
'lines': [('create', lines)],
|
||||
}
|
||||
if args.get('consumer'):
|
||||
to_create['consumer'] = args['consumer']
|
||||
if args.get('salesman'):
|
||||
to_create['salesman'] = args['salesman']
|
||||
if args.get('table_assigned'):
|
||||
to_create['table_assigned'] = args['table_assigned']
|
||||
sale, = cls.create([to_create])
|
||||
if hasattr(sale, 'order_status'):
|
||||
cls.write([sale], {'order_status': 'requested'})
|
||||
|
||||
# cls.write([sale], {'state': 'quotation'})
|
||||
cls.set_number([sale])
|
||||
sale.save()
|
||||
record = args.copy()
|
||||
record.update({
|
||||
'id': sale.id,
|
||||
'state': sale.state,
|
||||
'number': sale.number,
|
||||
'total_amount': sale.total_amount,
|
||||
})
|
||||
res = {
|
||||
'record': record,
|
||||
'msg': f'Pedido No. {sale.number}',
|
||||
'type': 'success',
|
||||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def get_pay_from_card(cls, args):
|
||||
sale, = cls.browse([args['id']])
|
||||
fields = ['total_amount', 'number', 'sale_taxes', 'shop']
|
||||
total_amount, number, sale_taxes, shop = attrgetter(*fields)(sale)
|
||||
terminal = shop.pos_terminal
|
||||
dic_values = {
|
||||
'Operacion': '0',
|
||||
'Valor': int(total_amount),
|
||||
'Propina': 0,
|
||||
'IVA': 0,
|
||||
'Factura': number,
|
||||
'Base Devolución IVA': 0,
|
||||
'Código del Cajero': 0,
|
||||
'Impuesto al Consumo': 0,
|
||||
'Monto Base IVA': 0,
|
||||
'Monto Base Impuesto al Consumo': 0,
|
||||
'Recibo': number
|
||||
}
|
||||
for t in sale_taxes:
|
||||
if t == '01':
|
||||
dic_values['IVA'] = int(t['value_tax'])
|
||||
dic_values['Monto Base IVA'] = int(t['base'])
|
||||
elif t == '04':
|
||||
dic_values['Impuesto al Consumo'] = int(t['value_tax'])
|
||||
dic_values['Monto Base Impuesto al Consumo'] = int(t['base'])
|
||||
|
||||
data = ','.join(map(str, dic_values.values()))
|
||||
|
||||
# data = "0,15630,1200,2500,1234567,10630,987653,800,14000,1630,12345"
|
||||
# terminal = "AAC08581"
|
||||
|
||||
response = get_pay(data, terminal)
|
||||
response_pay = process_response(response)
|
||||
print(response_pay, 'this is response pay')
|
||||
if response_pay == 'OK':
|
||||
res = {
|
||||
'status': 'ok',
|
||||
'terminal': terminal
|
||||
}
|
||||
else:
|
||||
res = {
|
||||
'status': 'error'
|
||||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def get_response_pay_from_card(cls, args):
|
||||
# response_process_pay = None
|
||||
terminal = args['terminal']
|
||||
response = get_response_pay(terminal)
|
||||
response_process_pay = process_response(response)
|
||||
if response_process_pay:
|
||||
data_pay = get_dict_response_pay(response_process_pay)
|
||||
result = {
|
||||
'pay': data_pay,
|
||||
'status': 'ok',
|
||||
'msg': 'Pago exitoso'
|
||||
}
|
||||
else:
|
||||
result = {
|
||||
'pay': None,
|
||||
'status': 'error',
|
||||
'msg': 'error al procesar pago'
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def process_pay_sale(cls, args):
|
||||
pool = Pool()
|
||||
Device = pool.get('sale.device')
|
||||
StatementLine = pool.get('account.statement.line')
|
||||
Date = pool.get('ir.date')
|
||||
|
||||
payment = args['pay']
|
||||
sale_id = args['sale_id']
|
||||
|
||||
sale, = cls.browse([sale_id])
|
||||
if sale.residual_amount == sale.total_amount:
|
||||
device, = Device.search([
|
||||
('shop', '=', sale.shop.id),
|
||||
])
|
||||
sale.sale_device = device
|
||||
|
||||
payment_means_code = '48' if payment['tipo_cuenta'] == 'CR' else '49'
|
||||
journal_id = None
|
||||
journal_name = None
|
||||
for journal in device.journals:
|
||||
if journal.payment_means_code == payment_means_code:
|
||||
journal_id = journal.id
|
||||
journal_name = journal.rec_name
|
||||
break
|
||||
|
||||
statement_open_id = cls.is_statement_open(
|
||||
journal_id, sale.sale_device.id)
|
||||
if not statement_open_id:
|
||||
return {
|
||||
'status': 'error',
|
||||
'message': f'Pago no se puede procesar; No se encontró un estado de cuenta abierto para el diario {journal_name}'
|
||||
}
|
||||
to_create = {
|
||||
'sale': sale_id,
|
||||
'date': Date.today(),
|
||||
'statement': statement_open_id,
|
||||
'amount': sale.total_amount,
|
||||
'party': sale.party.id,
|
||||
'account': sale.party.account_receivable.id,
|
||||
'description': sale.invoice_number or '',
|
||||
'number': payment['consecutivo_transaccion']
|
||||
}
|
||||
line, = StatementLine.create([to_create])
|
||||
line.create_move()
|
||||
cls.wizard_generate_invoice([sale])
|
||||
barcode = sale.number
|
||||
data_order = cls.get_order2print({'sale_id': sale_id, 'repeat': True})
|
||||
data_invoice = cls.get_data({'sale_id': sale_id, 'type_doc': 'invoice'})
|
||||
data_invoice['barcode'] = barcode
|
||||
for d in data_order[0].values():
|
||||
d['barcode'] = barcode
|
||||
ctx = sale.get_printing_context({'device_id': sale.sale_device.id})
|
||||
# shop = sale.shop
|
||||
# ctx = {
|
||||
# 'company': sale.company.party.name,
|
||||
# 'sale_device': sale.sale_device.name,
|
||||
# 'shop': shop.name,
|
||||
# 'street': shop.address.street,
|
||||
# 'user': "app.user",
|
||||
# 'city': shop.address.city_code.name,
|
||||
# 'zip': "00000",
|
||||
# 'phone': sale.company.party.phone,
|
||||
# 'id_number': sale.company.party.id_number,
|
||||
# 'tax_regime': "NA",
|
||||
# }
|
||||
|
||||
return {
|
||||
'status': 'ok',
|
||||
'data_order': data_order[0],
|
||||
'data_invoice': data_invoice,
|
||||
'ctx': ctx,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def dash_get_reverse_sale_price_taxed(cls, args):
|
||||
pool = Pool()
|
||||
Tax = pool.get('account.tax')
|
||||
Product = pool.get('product.product')
|
||||
product = Product(args['product'])
|
||||
sale_price_taxed = args['sale_price_taxed']
|
||||
taxes = product.customer_taxes_used
|
||||
unit_price = Tax.reverse_compute(Decimal(sale_price_taxed), taxes)
|
||||
return {'unit_price': unit_price}
|
||||
|
||||
@classmethod
|
||||
def dash_get_line(cls, args, ctx):
|
||||
if not args.get('product'):
|
||||
return {}
|
||||
|
||||
Product = Pool().get('product.product')
|
||||
PriceListLine = Pool().get('product.price_list.line')
|
||||
product_id = args['product']['id']
|
||||
product = Product(product_id)
|
||||
|
||||
context = {
|
||||
'company': ctx['company'],
|
||||
'currency': ctx['currency'],
|
||||
}
|
||||
price_list_id = None
|
||||
price_list = args.get('price_list', None)
|
||||
if price_list:
|
||||
price_list_id = price_list['id']
|
||||
context['price_list'] = price_list_id
|
||||
|
||||
with Transaction().set_context(context):
|
||||
unit_price = product.list_price
|
||||
|
||||
if price_list_id:
|
||||
price_lines = PriceListLine.search([
|
||||
('price_list', '=', price_list_id),
|
||||
('product', '=', product_id),
|
||||
])
|
||||
if price_lines:
|
||||
price_line = price_lines[0]
|
||||
unit_price = float(unit_price)
|
||||
unit_price = Decimal(eval(price_line.formula))
|
||||
# percent_commission = price_line.price_list.percent_commission
|
||||
|
||||
# ADD TAXES
|
||||
# taxes_ids = [t.id for t in product.customer_taxes_used]
|
||||
# res = cls.get_price_with_tax([line], ['amount_w_tax', 'unit_price_w_tax'])
|
||||
res = {
|
||||
'unit_price_w_tax': math.ceil(product.sale_price_taxed),
|
||||
# 'amount_w_tax': math.ceil(res['amount_w_tax'][None]),
|
||||
# 'taxes': [[('add'), taxes_ids]],
|
||||
'unit_price': math.ceil(unit_price),
|
||||
'unit': product.template.default_uom.id,
|
||||
'type': 'line',
|
||||
}
|
||||
# if percent_commission:
|
||||
# res['commission_amount'] = round(
|
||||
# (unit_price * quantity * percent_commission), 0
|
||||
# )
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def dash_create_order_call(cls, args):
|
||||
Shop = Pool().get('sale.shop')
|
||||
Product = Pool().get('product.product')
|
||||
Party = Pool().get('party.party')
|
||||
OrderStatusTime = Pool().get('sale.order_status.time')
|
||||
Configuration = Pool().get('sale.configuration')
|
||||
config = Configuration(1)
|
||||
User = Pool().get('res.user')
|
||||
ctx = Transaction().context
|
||||
|
||||
user = User(ctx.get('user'))
|
||||
shop = Shop(args['shop'])
|
||||
attribs_del = ['id', 'amount', 'unit_price_w_tax', 'total_amount']
|
||||
lines = args['lines']
|
||||
nested_values = None
|
||||
for line in lines:
|
||||
if line and line[0] == 'create':
|
||||
nested_values = line[1]
|
||||
if nested_values:
|
||||
lines = nested_values
|
||||
for v in lines:
|
||||
keys = v.keys()
|
||||
for k in attribs_del:
|
||||
if k in keys:
|
||||
del v[k]
|
||||
v['type'] = 'line'
|
||||
product = Product(v['product'])
|
||||
v['unit_price'] = Decimal(str(v['unit_price']))
|
||||
v['base_price'] = Decimal(str(v['base_price']))
|
||||
if v.get('discount'):
|
||||
v['discount'] = Decimal(str(v['discount']))
|
||||
|
||||
taxes = list(product.account_category.customer_taxes_used)
|
||||
taxes_ids = [t.id for t in taxes]
|
||||
v['taxes'] = [('add', taxes_ids)]
|
||||
|
||||
price_list = args.get('price_list', None)
|
||||
party = Party(args['party'])
|
||||
if args.get('shipment_address'):
|
||||
shipment_address_id = args.get('shipment_address')
|
||||
else:
|
||||
shipment_address_id = party.addresses[0].id
|
||||
|
||||
agent_id = None
|
||||
if args.get('agent'):
|
||||
agent_id = args['agent']
|
||||
|
||||
shipment_date = None
|
||||
if args.get('shipment_date'):
|
||||
shipment_date = args['shipment_date']
|
||||
delivery = args.get('delivery_amount', 0)
|
||||
if args.get('delivery_invoice') and delivery and int(delivery) > 0:
|
||||
product = config.delivery_product
|
||||
lines.append({
|
||||
'product': product.id,
|
||||
'quantity': 1,
|
||||
'type': 'line',
|
||||
'description': product.name,
|
||||
'unit': product.default_uom.id,
|
||||
'unit_price': Decimal(delivery)})
|
||||
delivery = 0
|
||||
|
||||
|
||||
description = args.get('description', '')
|
||||
comment = args.get('comment', '')
|
||||
date_ = datetime.now() - timedelta(hours=5)
|
||||
today = date(date_.year, date_.month, date_.day)
|
||||
to_create = {
|
||||
'consumer': args['consumer'],
|
||||
'source': args['source'],
|
||||
'kind': args['kind'],
|
||||
'delivery_amount': delivery,
|
||||
'shop': shop.id,
|
||||
'invoice_type': args.get('invoice_type'),
|
||||
'position': args.get('position', ''),
|
||||
'payment_method': args['payment_method'],
|
||||
'warehouse': shop.warehouse.id,
|
||||
'salesman': user.employee,
|
||||
'company': shop.company.id,
|
||||
'party': party.id,
|
||||
'sale_date': today,
|
||||
'shipment_date': shipment_date,
|
||||
'shipment_address': shipment_address_id,
|
||||
'invoice_address': shipment_address_id,
|
||||
'agent': agent_id,
|
||||
'price_list': price_list if price_list else shop.price_list.id,
|
||||
'payment_term': shop.payment_term.id,
|
||||
'state': 'draft',
|
||||
'order_status': 'requested',
|
||||
'description': description,
|
||||
'comment': comment,
|
||||
'lines': [('create', lines)],
|
||||
}
|
||||
if args.get('consumer'):
|
||||
to_create['consumer'] = args['consumer']
|
||||
order_status_time = OrderStatusTime.create([{ 'requested': datetime.now()}])
|
||||
to_create['order_status_time'] = order_status_time[0].id
|
||||
print(to_create, 'validate to create')
|
||||
sale, = cls.create([to_create])
|
||||
OrderStatusTime.write(order_status_time, {'sale': sale.id})
|
||||
cls.set_number([sale])
|
||||
record = args.copy()
|
||||
record.update({
|
||||
'id': sale.id,
|
||||
'state': sale.state,
|
||||
'number': sale.number,
|
||||
'total_amount': sale.total_amount,
|
||||
})
|
||||
res = {
|
||||
'record': record,
|
||||
'msg': f'Venta creada {sale.number}',
|
||||
'type': 'success',
|
||||
'status': 'ok',
|
||||
'open_modal': True,
|
||||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def _set_line(cls, val, context):
|
||||
del val['id']
|
||||
Product = Pool().get('product.product')
|
||||
val['type'] = 'line'
|
||||
product = Product(val['product'])
|
||||
with Transaction().set_context(context):
|
||||
unit_price = product.list_price
|
||||
unit_price = unit_price.quantize(Decimal(str(10.0 ** -4)))
|
||||
val['unit_price'] = unit_price
|
||||
val['base_price'] = unit_price
|
||||
val['unit'] = product.template.default_uom.id
|
||||
val['description'] = product.name
|
||||
taxes = list(product.account_category.customer_taxes_used)
|
||||
taxes_ids = [t.id for t in taxes]
|
||||
val['taxes'] = [('add', taxes_ids)]
|
||||
return val
|
||||
|
||||
@classmethod
|
||||
def command(cls, args):
|
||||
Shop = Pool().get('sale.shop')
|
||||
ShopTable = Pool().get('sale.shop.table')
|
||||
User = Pool().get('res.user')
|
||||
context = Transaction().context
|
||||
user_id = context.get('user')
|
||||
user = User(user_id)
|
||||
action = 'create'
|
||||
if args['id'] > 0:
|
||||
action = 'edit'
|
||||
|
||||
table = None
|
||||
if args.get('table_assigned'):
|
||||
try:
|
||||
table_id = args.get('table_assigned')['id']
|
||||
except:
|
||||
table_id = args.get('table_assigned')
|
||||
table = ShopTable(table_id)
|
||||
if action == 'create':
|
||||
if context.get('shop'):
|
||||
shop = Shop(context['shop'])
|
||||
else:
|
||||
shop = user.shop
|
||||
context['price_list'] = shop.price_list
|
||||
for v in args['lines']:
|
||||
cls._set_line(v, context)
|
||||
|
||||
party = shop.party
|
||||
today = date.today()
|
||||
to_create = {
|
||||
'shop': shop.id,
|
||||
'party': party.id,
|
||||
'invoice_type': 'P',
|
||||
'table_assigned': table.id,
|
||||
'shipment_address': party.addresses[0].id,
|
||||
'invoice_address': party.addresses[0].id,
|
||||
'company': shop.company.id,
|
||||
'sale_date': today,
|
||||
'shipment_date': today,
|
||||
'kind': 'to_table',
|
||||
'price_list': shop.price_list,
|
||||
'payment_term': shop.payment_term.id,
|
||||
'state': 'draft',
|
||||
'salesman': user.employee.id if user.employee else None,
|
||||
'order_status': 'commanded',
|
||||
'sale_device': user.sale_device.id,
|
||||
'lines': [('create', args['lines'])],
|
||||
}
|
||||
if args.get('description'):
|
||||
to_create['description'] = args.get('description')
|
||||
try:
|
||||
sale, = cls.create([to_create])
|
||||
sale.set_number([sale])
|
||||
ShopTable.write([table], {
|
||||
'state': 'occupied',
|
||||
'sale': sale.id,
|
||||
})
|
||||
return {'status': 'success', 'record': {'id': sale.id}, 'msg': "Orden Comandada exitosamente!"}
|
||||
except Exception as e:
|
||||
print(e, 'error')
|
||||
return {'status': 'error'}
|
||||
else:
|
||||
sale = cls(args['id'])
|
||||
to_add = []
|
||||
to_write = {}
|
||||
if sale.table_assigned.id != table.id:
|
||||
to_write['table_assigned'] = table.id
|
||||
ShopTable.write([sale.table_assigned], {
|
||||
'state': 'available',
|
||||
'sale': None,
|
||||
})
|
||||
ShopTable.write([table], {
|
||||
'state': 'occupied',
|
||||
'sale': sale.id,
|
||||
})
|
||||
for v in args['lines']:
|
||||
line_id = v.get('id')
|
||||
if line_id < 0:
|
||||
context['price_list'] = sale.shop.price_list
|
||||
to_add.append(cls._set_line(v, context))
|
||||
try:
|
||||
if to_add:
|
||||
to_write['lines'] = [('create', to_add)]
|
||||
|
||||
cls.write([sale], to_write)
|
||||
return {'status': 'success', 'record': {'id': sale.id}, 'msg': "Orden Comandada exitosamente!"}
|
||||
except Exception as e:
|
||||
return {'status': 'error', 'record': {'id': sale.id}, 'msg': "Orden no Comandada"}
|
||||
print(e, 'error')
|
||||
|
||||
@classmethod
|
||||
def dash_get_amount_w_tax(cls, args):
|
||||
Product = Pool().get('product.product')
|
||||
product = Product(args['product'])
|
||||
return product.template.compute_list_price_w_tax(
|
||||
Decimal(args['list_price']))
|
||||
|
||||
@classmethod
|
||||
def _get_sales_report(cls, dates, currency_id, in_thousands=False):
|
||||
invoice = Table('account_invoice')
|
||||
period = dates.get('period', None)
|
||||
if period:
|
||||
start_date = period.start_date
|
||||
end_date = period.end_date
|
||||
else:
|
||||
start_date = dates.get('start_date')
|
||||
end_date = dates.get('end_date')
|
||||
|
||||
cursor = Transaction().connection.cursor()
|
||||
select = invoice.select(Sum(invoice.untaxed_amount_cache), limit=1)
|
||||
select.where = (
|
||||
invoice.type == 'out') & (
|
||||
invoice.invoice_date >= start_date) & (
|
||||
invoice.currency == currency_id) & (
|
||||
invoice.invoice_date <= end_date) & (
|
||||
invoice.state.in_(['validated', 'posted', 'paid'])
|
||||
)
|
||||
|
||||
cursor.execute(*select)
|
||||
values = cursor.fetchone()
|
||||
value = 0
|
||||
if values and values[0]:
|
||||
value = int(values[0])
|
||||
if in_thousands:
|
||||
value = int(value / 1000)
|
||||
return value
|
||||
|
||||
@classmethod
|
||||
def report_sales_month(cls, args, ctx=None):
|
||||
# Dash Report
|
||||
pool = Pool()
|
||||
Period = pool.get('account.period')
|
||||
Currency = pool.get('currency.currency')
|
||||
res = {}
|
||||
today = date.today()
|
||||
_date = today
|
||||
moment = args.get('moment', None)
|
||||
if moment == 'previous':
|
||||
_date = today - timedelta(days=30)
|
||||
|
||||
periods = Period.search([
|
||||
('start_date', '<=', _date),
|
||||
('end_date', '>=', _date),
|
||||
('type', '=', 'standard')
|
||||
])
|
||||
if not periods:
|
||||
return res
|
||||
|
||||
period = periods[0]
|
||||
selector_periods = Period.search([
|
||||
('fiscalyear', '=', period.fiscalyear.id),
|
||||
('type', '=', 'standard')
|
||||
])
|
||||
selector = {p.id: p.name for p in selector_periods}
|
||||
|
||||
currency_id = Transaction().context.get('currency')
|
||||
if args.get('currency'):
|
||||
currency_id = ctx.get('currency')
|
||||
currency = Currency(currency_id)
|
||||
|
||||
dates = {'period': period}
|
||||
value = cls._get_sales_report(dates, currency_id, in_thousands=True)
|
||||
|
||||
month_name = _date.strftime("%b %Y")
|
||||
res = {
|
||||
'value': value,
|
||||
'selector': selector,
|
||||
'header_meta': month_name,
|
||||
'desc': 'In thousands',
|
||||
'desc_meta': currency.code,
|
||||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def report_sales_by_month(cls, args, ctx=None):
|
||||
# Dash Report
|
||||
pool = Pool()
|
||||
Fiscalyear = pool.get('account.fiscalyear')
|
||||
Currency = pool.get('currency.currency')
|
||||
today = date.today()
|
||||
moment = args.get('moment', None)
|
||||
_date = today
|
||||
if moment == 'previous':
|
||||
_date = today - timedelta(days=365)
|
||||
|
||||
fiscalyear, = Fiscalyear.search([
|
||||
('start_date', '<=', _date),
|
||||
('end_date', '>=', _date),
|
||||
], limit=1)
|
||||
if not fiscalyear:
|
||||
return {}
|
||||
|
||||
periods = [p for p in fiscalyear.periods if p.type == 'standard']
|
||||
currency_id = Transaction().context.get('currency')
|
||||
if args.get('currency'):
|
||||
currency_id = args.get('currency')
|
||||
|
||||
currency = Currency(currency_id)
|
||||
|
||||
values = []
|
||||
labels = []
|
||||
for p in periods:
|
||||
month = p.start_date.strftime("%b")
|
||||
labels.append(month)
|
||||
dates = {'period': p}
|
||||
val = cls._get_sales_report(dates, currency_id, True)
|
||||
if not val:
|
||||
val = 0
|
||||
values.append(val)
|
||||
|
||||
res = {
|
||||
'values': values,
|
||||
'labels': labels,
|
||||
'header_meta': fiscalyear.name,
|
||||
'desc': 'In thousands',
|
||||
'desc_meta': currency.code,
|
||||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def report_sales_year(cls, args, ctx=None):
|
||||
# Dash Report
|
||||
pool = Pool()
|
||||
Fiscalyear = pool.get('account.fiscalyear')
|
||||
Currency = pool.get('currency.currency')
|
||||
today = date.today()
|
||||
moment = args.get('moment', None)
|
||||
_date = today
|
||||
if moment == 'previous':
|
||||
_date = today - timedelta(days=365)
|
||||
|
||||
fiscalyear, = Fiscalyear.search([
|
||||
('start_date', '<=', _date),
|
||||
('end_date', '>=', _date),
|
||||
], limit=1)
|
||||
if not fiscalyear:
|
||||
return {}
|
||||
|
||||
selector_fy = Fiscalyear.search([
|
||||
('id', '=', fiscalyear.id),
|
||||
])
|
||||
selector = {p.id: p.name for p in selector_fy}
|
||||
|
||||
periods = [p for p in fiscalyear.periods if p.type == 'standard']
|
||||
currency_id = Transaction().context.get('currency')
|
||||
if args.get('currency'):
|
||||
currency_id = args.get('currency')
|
||||
|
||||
currency = Currency(currency_id)
|
||||
|
||||
values = []
|
||||
labels = []
|
||||
for p in periods:
|
||||
labels.append(p.name)
|
||||
dates = {'period': p}
|
||||
val = cls._get_sales_report(dates, currency_id, True)
|
||||
if val:
|
||||
values.append(val)
|
||||
|
||||
res = {
|
||||
'value': sum(values),
|
||||
'header_meta': fiscalyear.name,
|
||||
'desc': 'In thousands',
|
||||
'desc_meta': currency.code,
|
||||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def report_sales_day(cls, args, ctx=None):
|
||||
# Dash Report
|
||||
pool = Pool()
|
||||
Currency = pool.get('currency.currency')
|
||||
currency_id = Transaction().context.get('currency')
|
||||
if args.get('currency'):
|
||||
currency_id = args.get('currency')
|
||||
|
||||
currency = Currency(currency_id)
|
||||
today = date.today()
|
||||
_date = today
|
||||
|
||||
moment = args.get('moment', None)
|
||||
if moment == 'previous':
|
||||
_date = today - timedelta(days=1)
|
||||
dates = {
|
||||
'start_date': _date,
|
||||
'end_date': _date
|
||||
}
|
||||
|
||||
values = cls._get_sales_report(dates, currency_id, True)
|
||||
res = {
|
||||
'value': values,
|
||||
'header_meta': str(_date),
|
||||
'desc': 'In thousands',
|
||||
'desc_meta': currency.code,
|
||||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def report_fulfillment_goal_month(cls, args, ctx=None):
|
||||
# Dash Report
|
||||
pool = Pool()
|
||||
Currency = pool.get('currency.currency')
|
||||
Period = pool.get('account.period')
|
||||
GoalPeriod = pool.get('goal.period')
|
||||
Goal = pool.get('goal')
|
||||
currency_id = Transaction().context.get('currency')
|
||||
if args.get('currency'):
|
||||
currency_id = args.get('currency')
|
||||
|
||||
currency = Currency(currency_id)
|
||||
today = date.today()
|
||||
|
||||
_date = today
|
||||
moment = args.get('moment', None)
|
||||
if moment == 'previous':
|
||||
_date = today - timedelta(days=31)
|
||||
|
||||
dates = {
|
||||
'start_date': _date,
|
||||
'end_date': _date
|
||||
}
|
||||
|
||||
period, = Period.search([
|
||||
('start_date', '<=', _date),
|
||||
('end_date', '>=', _date),
|
||||
])
|
||||
|
||||
month = period.start_date.strftime("%b")
|
||||
dates = {'period': period}
|
||||
|
||||
goals = GoalPeriod.search([
|
||||
('goal.kind', '=', 'sales'),
|
||||
('period', '=', period.id),
|
||||
], limit=1)
|
||||
|
||||
goal = goals[0] if goals else {}
|
||||
|
||||
sales = cls._get_sales_report(dates, currency_id, True)
|
||||
fulfillment = 0
|
||||
value = 0
|
||||
if goal:
|
||||
value = goal.total_amount / 1000
|
||||
if sales:
|
||||
fulfillment = round((sales * 100) / value, 2)
|
||||
print(sales, goal.total_amount, fulfillment)
|
||||
|
||||
month = _date.strftime("%b %Y")
|
||||
res = {
|
||||
'value': value,
|
||||
'args': {'legend': f'{fulfillment}%'},
|
||||
'header_meta': month,
|
||||
'desc': 'In thousands',
|
||||
'desc_meta': currency.code,
|
||||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def report_fulfillment_goal_year(cls, args, ctx=None):
|
||||
pool = Pool()
|
||||
Fiscalyear = pool.get('account.fiscalyear')
|
||||
Goal = pool.get('goal')
|
||||
today = date.today()
|
||||
_date = today
|
||||
moment = args.get('moment', None)
|
||||
if moment == 'previous':
|
||||
_date = today - timedelta(days=365)
|
||||
|
||||
fiscalyear, = Fiscalyear.search([
|
||||
('start_date', '<=', _date),
|
||||
('end_date', '>=', _date),
|
||||
], limit=1)
|
||||
if not fiscalyear:
|
||||
return {}
|
||||
|
||||
periods = [p for p in fiscalyear.periods if p.type == 'standard']
|
||||
currency_id = Transaction().context.get('currency')
|
||||
if args.get('currency'):
|
||||
currency_id = args.get('currency')
|
||||
|
||||
# currency = Currency(currency_id)
|
||||
values = []
|
||||
labels = []
|
||||
for p in periods:
|
||||
labels.append(p.name)
|
||||
dates = {'period': p}
|
||||
val = cls._get_sales_report(dates, currency_id, True)
|
||||
if val:
|
||||
values.append(val)
|
||||
|
||||
sum_values = sum(values)
|
||||
goals = Goal.search([
|
||||
('fiscalyear', '=', fiscalyear.id),
|
||||
('kind', '=', 'sales'),
|
||||
], limit=1)
|
||||
if not goals:
|
||||
goal_rate = 0
|
||||
missing = 0
|
||||
else:
|
||||
goal = goals[0].total_amount / 1000
|
||||
missing = goal - sum_values
|
||||
goal_rate = int((sum_values / goal) * 100)
|
||||
|
||||
res = {
|
||||
'labels': ["Sales", "Missing"],
|
||||
'values': [sum(values), missing],
|
||||
'center_label': str(goal_rate) + '%',
|
||||
'header_meta': fiscalyear.name,
|
||||
}
|
||||
return res
|
||||
|
||||
|
||||
class AppDelivery(DashAppBase):
|
||||
'App Delivery'
|
||||
__name__ = 'dash.app.delivery'
|
||||
company = fields.Many2One('company.company', 'Company', required=True)
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(AppDelivery, cls).__setup__()
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company') or None
|
||||
|
||||
|
||||
class AppTakeOrder(DashAppBase):
|
||||
'App Take Order'
|
||||
__name__ = 'dash.app.take_order'
|
||||
|
||||
|
||||
class AppOrderViewer(DashAppBase):
|
||||
'App Order Viewer'
|
||||
__name__ = 'dash.app.order_viewer'
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company') or None
|
||||
|
||||
|
||||
class AppSaleOrder(DashAppBase):
|
||||
'App Sale Order'
|
||||
__name__ = 'dash.app.sale_order'
|
||||
allow_discount = fields.Boolean('Allow Discount')
|
||||
allow_manual_pricing = fields.Boolean('Allow Manual Pricing',
|
||||
help='Allow manual pricing to user')
|
||||
|
||||
|
||||
class AppSelfServiceSale(DashAppBase):
|
||||
'App Self Service Sale'
|
||||
__name__ = 'dash.app.self_service_sale'
|
||||
|
||||
def validate_app(self, args):
|
||||
|
||||
return {'status': 'ok'}
|
||||
|
||||
|
||||
class AppSaleCallCenter(DashAppBase):
|
||||
'App Sale Call Center'
|
||||
__name__ = 'dash.app.sale_call_center'
|
||||
|
||||
|
||||
class AppSaleTurn(DashAppBase):
|
||||
'App Sale Turn'
|
||||
__name__ = 'dash.app.sale_turn'
|
||||
|
||||
|
||||
class AppOrderNotification(DashAppBase):
|
||||
'App Order Notification'
|
||||
__name__ = 'dash.app.order_notification'
|
28
sale.py
28
sale.py
|
@ -37,13 +37,12 @@ class Sale(metaclass=PoolMeta):
|
|||
return res
|
||||
else:
|
||||
records = cls.browse([args['id']])
|
||||
lines = args.get('lines')
|
||||
for ln in lines:
|
||||
if ln[0] == 'create' and len(ln[1]) > 0:
|
||||
for p in ln[1]:
|
||||
p['status_order'] = 'requested'
|
||||
product = Product(p['product'])
|
||||
p['description'] = product.template.name
|
||||
lines_tuple = args.get('lines')
|
||||
action, lines = lines_tuple
|
||||
if action == 'create' and len(lines) > 0:
|
||||
for line in lines:
|
||||
product = Product(line['product'])
|
||||
cls._add_values(product.template, line)
|
||||
cls.write(records, args)
|
||||
res = {
|
||||
'record': {'id': args['id']},
|
||||
|
@ -52,6 +51,15 @@ class Sale(metaclass=PoolMeta):
|
|||
}
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def _add_values(cls, template, line):
|
||||
line['status_order'] = 'requested'
|
||||
line['unit'] = template.default_uom.id
|
||||
line['description'] = template.name
|
||||
taxes = list(template.account_category.customer_taxes_used)
|
||||
taxes_ids = [t.id for t in taxes]
|
||||
line['taxes'] = [('add', taxes_ids)]
|
||||
|
||||
@classmethod
|
||||
def create_sale(cls, args, ctx=None):
|
||||
Shop = Pool().get('sale.shop')
|
||||
|
@ -95,11 +103,7 @@ class Sale(metaclass=PoolMeta):
|
|||
del v['discount']
|
||||
|
||||
template = product.template
|
||||
v['unit'] = template.default_uom.id
|
||||
v['description'] = template.name
|
||||
taxes = list(template.account_category.customer_taxes_used)
|
||||
taxes_ids = [t.id for t in taxes]
|
||||
v['taxes'] = [('add', taxes_ids)]
|
||||
cls._add_values(template, v)
|
||||
|
||||
try:
|
||||
price_list = args['price_list']['id']
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[tryton]
|
||||
version=6.0.16
|
||||
version=6.0.17
|
||||
depends:
|
||||
party
|
||||
product
|
||||
|
|
Loading…
Reference in New Issue