diff --git a/sale.py b/sale.py index d5ee3f5..45886c0 100644 --- a/sale.py +++ b/sale.py @@ -169,70 +169,102 @@ class Sale(metaclass=PoolMeta): # ) return res + @classmethod + def _set_line(cls, val): + del val['id'] + Product = Pool().get('product.product') + val['type'] = 'line' + product = Product(val['product']) + 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 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 command(cls, args): Shop = Pool().get('sale.shop') Product = Pool().get('product.product') Party = Pool().get('party.party') + Line = Pool().get('sale.line') 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' - if context.get('shop'): - shop = Shop(context['shop']) + if action == 'create': + if context.get('shop'): + shop = Shop(context['shop']) + else: + user_id = context.get('user') + user = User(user_id) + shop = user.shop + for v in args['lines']: + cls._set_line(v) + + 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, + 'price_list': shop.price_list, + 'payment_term': shop.payment_term.id, + 'state': 'draft', + 'order_status': 'commanded', + 'lines': [('create', args['lines'])], + } + if args.get('description'): + to_create['description'] = args.get('description') + try: + sale, = cls.create([to_create]) + sale.set_number([sale]) + return sale.id + except Exception as e: + print(e, 'error') else: - shop = user.shop - context['price_list'] = shop.price_list - for v in args['lines']: - if v.get('id'): - del v['id'] - v['type'] = 'line' - product = Product(v['product']) - with Transaction().set_context(context): - unit_price = product.list_price - unit_price = unit_price.quantize(Decimal(str(10.0 ** -4))) - v['unit_price'] = unit_price - v['base_price'] = unit_price - 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)] - party = shop.party - to_create = { - 'shop': shop.id, - 'party': party.id, - 'invoice_type':'P', - 'table_assigned': args['table_assigned']['id'] if args.get('table_asigned') else None, - 'shipment_address': party.addresses[0].id, - 'invoice_address': party.addresses[0].id, - 'company': shop.company.id, - 'kind': 'to_table', - 'sale_date': today, - 'shipment_date': today, - 'salesman': user.employee, - 'sale_device': user.sale_device, - 'price_list': shop.price_list, - 'payment_term': shop.payment_term.id, - 'state': 'draft', - 'order_status': 'commanded', - 'lines': [('create', args['lines'])], - } - if args.get('description'): - to_create['description'] = args.get('description') - try: - sale, = cls.create([to_create]) - sale.set_number([sale]) - if sale.table_assigned: - ShopTable = Pool().get('sale.shop.table') - tables = ShopTable.search([('id', '=', sale.table_assigned.id)]) - if tables: - ShopTable.write(tables, {'sale': sale.id, 'state':'occupied'}) - return sale.id - except Exception as e: - print(e, 'error') + 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'] + for v in args['lines']: + line_id = v.get('id') + if line_id < 0: + to_add.append(cls._set_line(v)) + 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): @@ -374,15 +406,15 @@ class AppTakeOrder(ModelSQL, ModelView): return Transaction().context.get('company') or None -class AppOrderView(ModelSQL, ModelView): - 'App Order View' - __name__ = 'dash.app.order_view' +class AppOrderManage(ModelSQL, ModelView): + 'App Order Manage' + __name__ = 'dash.app.order_manage' company = fields.Many2One('company.company', 'Company', required=True) code = fields.Char('Code') @classmethod def __setup__(cls): - super(AppOrderView, cls).__setup__() + super(AppOrderManage, cls).__setup__() @staticmethod def default_company(): diff --git a/sale_mio.py b/sale_mio.py new file mode 100644 index 0000000..95beb77 --- /dev/null +++ b/sale_mio.py @@ -0,0 +1,437 @@ +# 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', 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 _set_line(cls, val): + del val['id'] + Product = Pool().get('product.product') + val['type'] = 'line' + product = Product(val['product']) + 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 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 command(cls, args): + Shop = Pool().get('sale.shop') + Party = Pool().get('party.party') + Line = Pool().get('sale.line') + User = Pool().get('res.user') + context = Transaction().context + today = date.today() + action = 'create' + if args['id'] > 0: + action = 'edit' + + if action == 'create': + if context.get('shop'): + shop = Shop(context['shop']) + else: + user_id = context.get('user') + user = User(user_id) + shop = user.shop + for v in args['lines']: + cls._set_line(v) + + 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, + 'price_list': shop.price_list, + 'payment_term': shop.payment_term.id, + 'state': 'draft', + 'order_status': 'commanded', + 'lines': [('create', args['lines'])], + } + if args.get('description'): + to_create['description'] = args.get('description') + try: + sale, = cls.create([to_create]) + sale.set_number([sale]) + 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'] + for v in args['lines']: + line_id = v.get('id') + if line_id < 0: + to_add.append(cls._set_line(v)) + 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_(['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 AppTakeOrder(ModelSQL, ModelView): + '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 AppOrderManage(ModelSQL, ModelView): + 'App Order Manage' + __name__ = 'dash.app.order_manage' + company = fields.Many2One('company.company', 'Company', required=True) + code = fields.Char('Code') + + @classmethod + def __setup__(cls): + super(AppOrderManage, 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') + allow_manual_pricing = fields.Boolean('Allow Manual Pricing', help='Allow manual pricing to user') + + @classmethod + def __setup__(cls): + super(AppSaleOrder, cls).__setup__() + + @staticmethod + def default_company(): + return Transaction().context.get('company') or None