trytonpsk-dash_sale/sale.py

311 lines
9.6 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 ModelView, ModelSQL, fields
class Sale(metaclass=PoolMeta):
__name__ = 'sale.sale'
@classmethod
def __setup__(cls):
super(Sale, cls).__setup__()
@classmethod
def dash_quote(cls, args, ctx):
Shop = Pool().get('sale.shop')
Product = Pool().get('product.product')
Party = Pool().get('party.party')
User = Pool().get('res.user')
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('unit_price_w_tax'):
del v['unit_price_w_tax']
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'])],
}
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')
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 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_(['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):
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
report = args['report']
period = periods[0]
selector_periods = Period.search([
('fiscalyear', '=', period.fiscalyear.id),
('type', '=', 'standard')
])
currency = Currency(ctx['currency'])
selector = {p.id: p.name for p in selector_periods}
description = currency.code
value = cls._get_sales_in_period(period, ctx['currency'],
report.in_thousands)
res = {
'value': value,
'description': description,
'selector': selector,
'default_option': period.id,
'meta': period.name,
'in_thousands': report.in_thousands
}
return res
@classmethod
def report_sales_by_month(cls, args, ctx):
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']
values = []
labels = []
report = args['report']
for p in periods:
val = cls._get_sales_in_period(p, ctx['currency'], report.in_thousands)
if val > 0:
values.append(val)
labels.append(p.name)
currency = Currency(ctx['currency'])
res = {
'values': values,
'labels': labels,
'description': 'report_sales_by_month',
'meta': currency.code,
'in_thousands': report.in_thousands
}
return res
class AppDelivery(ModelSQL, ModelView):
'App Delivery'
__name__ = 'dash.app.delivery'
company = fields.Many2One('company.company', 'Company', required=True)
code = fields.Char('Code')
@classmethod
def __setup__(cls):
super(AppDelivery, cls).__setup__()
@staticmethod
def default_company():
return Transaction().context.get('company') or None
class AppSaleOrder(ModelSQL, ModelView):
'App Sale Order'
__name__ = 'dash.app.sale_order'
company = fields.Many2One('company.company', 'Company', required=True)
allow_discount = fields.Boolean('Allow Discount')
@classmethod
def __setup__(cls):
super(AppSaleOrder, cls).__setup__()
@staticmethod
def default_company():
return Transaction().context.get('company') or None