diff --git a/sale (copy).py b/sale (copy).py new file mode 100644 index 0000000..a37ceea --- /dev/null +++ b/sale (copy).py @@ -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' diff --git a/sale.py b/sale.py index f6bff35..c480b2d 100644 --- a/sale.py +++ b/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'] @@ -996,4 +1000,4 @@ class AppOrderNotification(DashAppBase): class AppSaleAudit(DashAppBase): 'App Sale Audit' - __name__ = 'dash.app.sale_audit' \ No newline at end of file + __name__ = 'dash.app.sale_audit' diff --git a/tryton.cfg b/tryton.cfg index 7f180f3..08f84b2 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -1,5 +1,5 @@ [tryton] -version=6.0.16 +version=6.0.17 depends: party product