trytonpsk-dash_sale/sale.py

477 lines
15 KiB
Python

# This file is part of purchase_discount module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
import math
from decimal import Decimal
from sql import Table
from sql.aggregate import Sum
from datetime import date
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
from trytond.model import fields
from trytond.modules.dash.dash import DashAppBase
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):
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'])
else:
user_id = ctx.get('user')
user = User(user_id)
shop = user.shop
today = date.today()
for v in args['lines']:
if v.get('id'):
del v['id']
if v.get('amount'):
del v['amount']
if v.get('total_amount'):
del v['total_amount']
v['type'] = 'line'
product = Product(v['product'])
if v.get('discount') and v['discount'] != '':
v['discount'] = Decimal(v['discount'])/100
# unit_price = product.list_price - (product.list_price * Decimal(v['discount']))
# v['unit_price'] = Decimal(unit_price).quantize(Decimal(str(10.0 ** -4)))
elif v.get('discount'):
del v['discount']
# v['unit'] = product.template.default_uom.id
v['description'] = product.name
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)
if price_list:
price_list = price_list['id']
if args.get('shipment_address'):
shipment_address_id = args.get('shipment_address')['id']
else:
party = Party(args['party']['id'])
shipment_address_id = party.addresses[0].id
agent_id = None
if args.get('agent'):
agent_id = args['agent']['id']
shipment_date = None
if args.get('shipment_date'):
shipment_date = args['shipment_date']
description = args.get('description', '')
comment = args.get('comment', '')
to_create = {
'shop': shop.id,
'invoice_type': 'P',
'company': shop.company.id,
'party': args['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', args['lines'])],
}
print('sale_to_ create', to_create)
sale, = cls.create([to_create])
for line in sale.lines:
if line.discount and line.discount > 0:
line.on_change_discount()
cls.quote([sale])
record = args.copy()
record.update({
'id': sale.id,
'state': sale.state,
'number': sale.number,
'total_amount': sale.total_amount,
})
res = {
'record': record,
'msg': 'successful_order',
'type': 'success',
'open_modal': True,
}
return res
@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 args.get('quantity'):
quantity = int(args.get('quantity'))
else:
quantity = 1
# percent_commission = 0
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 mark_commanded(cls, args):
"""
This method mark as commanded all products in sale, previous
positive response of local printer
"""
print(args)
sale = cls(args['sale_id'])
for line in sale.lines:
line.order_sended = True
line.save()
@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 = product.template.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
today = date.today()
user_id = context.get('user')
user = User(user_id)
action = 'create'
if args['id'] > 0:
action = 'edit'
table = None
if args.get('table_assigned'):
table_id = args.get('table_assigned')['id']
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
to_create = {
'shop': shop.id,
'party': party.id,
'invoice_type': 'P',
'table_assigned': args['table_assigned']['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 sale.id
except Exception as e:
print(e, 'error')
else:
sale = cls(args['id'])
to_add = []
to_write = {}
if sale.table_assigned.id != args['table_assigned']['id']:
to_write['table_assigned'] = args['table_assigned']['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 sale.id
except Exception as e:
print(e, 'error')
@classmethod
def report_sales_day(cls, args, ctx):
pass
@classmethod
def _get_sales_in_period(cls, period, currency_id, in_thousands=False):
invoice = Table('account_invoice')
start_date = period.start_date
end_date = period.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):
pool = Pool()
Period = pool.get('account.period')
Currency = pool.get('currency.currency')
res = {}
today = date.today()
periods = Period.search([
('start_date', '<=', today),
('end_date', '>=', today),
('type', '=', 'standard')
])
if not periods:
return res
period = periods[0]
selector_periods = Period.search([
('fiscalyear', '=', period.fiscalyear.id),
('type', '=', 'standard')
])
if args.get('currency'):
currency_id = ctx.get('currency')
else:
currency_id = Transaction().context.get('currency')
currency = Currency(currency_id)
selector = {p.id: p.name for p in selector_periods}
description = currency.code
value = cls._get_sales_in_period(
period, currency_id, in_thousands=True)
res = {
'value': value,
'description': description,
'selector': selector,
'default_option': period.id,
'meta': period.name,
'in_thousands': True
}
return res
@classmethod
def report_sales_by_month(cls, args, ctx=None):
pool = Pool()
Fiscalyear = pool.get('account.fiscalyear')
Currency = pool.get('currency.currency')
today = date.today()
fiscalyears = Fiscalyear.search([
('start_date', '<=', today),
('end_date', '>=', today),
])
if not fiscalyears:
return {}
periods = [p for p in fiscalyears[0].periods if p.type == 'standard']
if args.get('currency'):
currency_id = args.get('currency')
else:
currency_id = Transaction().context.get('currency')
currency = Currency(currency_id)
values = []
labels = []
for p in periods:
val = cls._get_sales_in_period(p, currency_id, True)
if val > 0:
values.append(val)
labels.append(p.name)
res = {
'values': values,
'labels': labels,
'description': 'report_sales_by_month',
'meta': currency.code,
'in_thousands': True
}
return res
@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(args['list_price'])
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'
# company = fields.Many2One('company.company', 'Company', required=True)
# code = fields.Char('Code')
@classmethod
def __setup__(cls):
super(AppTakeOrder, cls).__setup__()
@staticmethod
def default_company():
return Transaction().context.get('company') or None
class AppOrderViewer(DashAppBase):
'App Order Viewer'
__name__ = 'dash.app.order_viewer'
# company = fields.Many2One('company.company', 'Company', required=True)
# code = fields.Char('Code')
@classmethod
def __setup__(cls):
super(AppOrderViewer, cls).__setup__()
@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'
@classmethod
def __setup__(cls):
super(AppSelfServiceSale, cls).__setup__()
@staticmethod
def default_company():
return Transaction().context.get('company') or None