6 Commits
6.8 ... 6.4

Author SHA1 Message Date
4738104006 fix: Se añade total_tip 2024-03-05 14:42:20 -05:00
1ad532c033 fix: UPDATE on_change_lines 2024-03-04 13:17:35 -05:00
57f95f0b7d fix: Se elimina producto Tip de Bill report 2024-03-03 10:18:38 -05:00
cd199fbaa0 Fix: UPDATE Total descuento 2024-03-03 10:03:00 -05:00
c2b590b052 feat: Se añade campo rate in SaleLine 2024-02-25 14:05:35 -05:00
0bc83265e1 feat: Se añade tip in totals 2024-02-20 02:17:05 +00:00
23 changed files with 184 additions and 1243 deletions

View File

@@ -1,6 +1,5 @@
from trytond.pool import Pool from trytond.pool import Pool
from . import ( from . import product, sale, production, invoice, user, report_close_statement
product, sale, production, invoice, user, report_close_statement, report)
__all__ = ['register'] __all__ = ['register']
@@ -11,14 +10,9 @@ def register():
invoice.InvoiceLine, invoice.InvoiceLine,
sale.Sale, sale.Sale,
sale.Line, sale.Line,
sale.SaleLineDeletedLog,
user.User, user.User,
production.Production, production.Production,
report_close_statement.ReportCloseStatementStart, report_close_statement.ReportCloseStatementStart,
report.ReportSaleProduct,
report.ReportSaleByUser,
report.ReportSaleByZone,
report.ReportSaleContext,
module='sale_fast_food', type_='model') module='sale_fast_food', type_='model')
Pool.register( Pool.register(
report_close_statement.PrintReportCloseStatement, report_close_statement.PrintReportCloseStatement,

View File

@@ -1,4 +1,6 @@
from trytond.pool import PoolMeta from trytond.pool import Pool, PoolMeta
from trytond.model import ModelView, fields
from trytond.exceptions import UserError
from trytond.pyson import Eval from trytond.pyson import Eval
@@ -11,3 +13,4 @@ class InvoiceLine(metaclass=PoolMeta):
cls.product.states['required'] = (Eval('type') == 'line') cls.product.states['required'] = (Eval('type') == 'line')
cls.unit_price.domain = [] cls.unit_price.domain = []

View File

@@ -58,98 +58,6 @@ msgctxt "field:sale.print_cash_register.start,shop:"
msgid "Shop" msgid "Shop"
msgstr "Tienda" msgstr "Tienda"
msgctxt "field:sale_fast_food.report.context,from_date:"
msgid "From Date"
msgstr "Desde la Fecha"
msgctxt "field:sale_fast_food.report.context,to_date:"
msgid "To Date"
msgstr "Hasta la Fecha"
msgctxt "model:ir.action,name:act_report_sale_fast_food_product_pizza"
msgid "Pizzas Sold by Product"
msgstr "Pizzas Vendidas Por Producto"
msgctxt "model:ir.ui.menu,name:menu_sale_fast_food_pizza"
msgid "Pizzas Sold by Product"
msgstr "Pizzas Vendidas Por Producto"
msgctxt "model:ir.action,name:act_report_sale_fast_food_by_user"
msgid "Sales by User"
msgstr "Ventas Por Usuario"
msgctxt "model:ir.ui.menu,name:menu_sale_fast_food_by_user"
msgid "Sales by User"
msgstr "Ventas Por Usuario"
msgctxt "model:ir.action,name:act_report_sale_fast_food_zone"
msgid "Sales by Zone"
msgstr "Ventas Por Zona"
msgctxt "model:ir.ui.menu,name:menu_sale_fast_food_zone"
msgid "Sales by Zone"
msgstr "Ventas Por Zona"
msgctxt "field:sale_fast_food.reporting.product,product_pizza:"
msgid "Product"
msgstr "Pizza"
msgctxt "field:sale_fast_food.reporting.product,quantity:"
msgid "Quantity"
msgstr "Cantidad"
msgctxt "field:sale_fast_food.reporting.by_user,user:"
msgid "User"
msgstr "Usuario"
msgctxt "field:sale_fast_food.reporting.by_user,completed_sales:"
msgid "Completed Sales"
msgstr "# Ventas"
msgctxt "field:sale_fast_food.reporting.by_user,untaxed_amount:"
msgid "Untaxed Amount"
msgstr "Base Imponible"
msgctxt "field:sale_fast_food.reporting.by_user,tax_amount:"
msgid "Tax Amount"
msgstr "Impuestos"
msgctxt "field:sale_fast_food.reporting.by_user,total_amount:"
msgid "Total Amount"
msgstr "Total"
msgctxt "field:sale_fast_food.reporting.by_user,total_tip_amount:"
msgid "Total Tip Amount"
msgstr "Propinas"
msgctxt "field:sale_fast_food.reporting.zone,zone:"
msgid "Zone"
msgstr "Zona"
msgctxt "field:sale_fast_food.reporting.zone,table:"
msgid "Table"
msgstr "Mesa"
msgctxt "field:sale_fast_food.reporting.zone,completed_sales:"
msgid "Completed Sales"
msgstr "# Ventas"
msgctxt "field:sale_fast_food.reporting.zone,untaxed_amount:"
msgid "Untaxed Amount"
msgstr "Base Imponible"
msgctxt "field:sale_fast_food.reporting.zone,tax_amount:"
msgid "Tax Amount"
msgstr "Impuestos"
msgctxt "field:sale_fast_food.reporting.zone,total_amount:"
msgid "Total Amount"
msgstr "Total"
msgctxt "field:sale_fast_food.reporting.zone,total_tip_amount:"
msgid "Total Tip Amount"
msgstr "Propinas"
msgctxt "wizard_button:sale.print_cash_register,start,end:" msgctxt "wizard_button:sale.print_cash_register,start,end:"
msgid "Cancel" msgid "Cancel"
msgstr "Cancelar" msgstr "Cancelar"

View File

@@ -1,6 +1,6 @@
from trytond.pool import PoolMeta from trytond.pool import Pool, PoolMeta
from trytond.model import fields from trytond.model import fields
from trytond.pyson import Eval from trytond.pyson import Eval, Bool
class Product(metaclass=PoolMeta): class Product(metaclass=PoolMeta):

View File

@@ -1,21 +1,23 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of # This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms. # this repository contains the full copyright notices and license terms.
from decimal import Decimal from decimal import Decimal
from trytond.pool import Pool, PoolMeta from trytond.pool import Pool, PoolMeta
from trytond.model import fields from trytond.model import fields
from trytond.modules.product import price_digits, round_price
from trytond.exceptions import UserError
BOM_CHANGES = ['bom', 'product', 'quantity', 'uom', 'warehouse', 'location', BOM_CHANGES = ['bom', 'product', 'quantity', 'uom', 'warehouse', 'location',
'company', 'inputs', 'outputs'] 'company', 'inputs', 'outputs']
class Production(metaclass=PoolMeta): class Production(metaclass=PoolMeta):
"Production" "Production"
__name__ = 'production' __name__ = 'production'
@fields.depends(
'bom', 'product', 'uom', 'quantity', 'company', 'inputs', 'outputs', @fields.depends(*BOM_CHANGES)
methods=['_explode_move_values'])
def explode_bom(self): def explode_bom(self):
pool = Pool() pool = Pool()
Uom = pool.get('product.uom') Uom = pool.get('product.uom')
@@ -27,29 +29,32 @@ class Production(metaclass=PoolMeta):
inputs = [] inputs = []
for input_ in self.bom.inputs: for input_ in self.bom.inputs:
# if input_.product.producible: if input_.product.producible:
# for input_ in input_.product.template.boms.inputs: for input_ in input_.product.template.boms.inputs:
quantity = input_.compute_quantity(factor) quantity = input_.compute_quantity(factor)
move = self._explode_move_values('input', input_, quantity) move = self._explode_move_values(
self.picking_location, self.location, self.company,
input_, quantity)
if move: if move:
inputs.append(move) inputs.append(move)
quantity = Uom.compute_qty( quantity = Uom.compute_qty(input_.uom, quantity,
input_.uom, quantity, input_.product.default_uom, round=False)
else:
quantity = input_.compute_quantity(factor)
move = self._explode_move_values(
self.picking_location, self.location, self.company,
input_, quantity)
if move:
inputs.append(move)
quantity = Uom.compute_qty(input_.uom, quantity,
input_.product.default_uom, round=False) input_.product.default_uom, round=False)
# else:
# quantity = input_.compute_quantity(factor)
# move = self._explode_move_values('output', input_, quantity)
# if move:
# inputs.append(move)
# quantity = Uom.compute_qty(
# input_.uom, quantity,
# input_.product.default_uom, round=False)
self.inputs = inputs self.inputs = inputs
outputs = [] outputs = []
for output in self.bom.outputs: for output in self.bom.outputs:
quantity = output.compute_quantity(factor) quantity = output.compute_quantity(factor)
move = self._explode_move_values('output', output, move = self._explode_move_values(
self.location, self.output_location, self.company, output,
quantity) quantity)
if move: if move:
move.unit_price = Decimal(0) move.unit_price = Decimal(0)

280
report.py
View File

@@ -1,280 +0,0 @@
from trytond.model import ModelSQL, ModelView, fields
from trytond.pool import Pool
from trytond.pyson import If, Eval
from sql import Literal, Null
from sql.aggregate import Min, Sum, Count
from sql.functions import CurrentTimestamp
from trytond.transaction import Transaction
import datetime
class ReportSaleContext(ModelView):
"""Contexto de reportes de miembros de familia"""
__name__ = 'sale_fast_food.report.context'
from_date = fields.Date(
"From Date",
domain=[
If(Eval('to_date') & Eval('from_date'),
('from_date', '<=', Eval('to_date')),
()),
If(Eval('from_date'),
('from_date', '<=', datetime.date.today()))
])
to_date = fields.Date(
"To Date",
domain=[
If(Eval('from_date') & Eval('to_date'),
('to_date', '>=', Eval('from_date')),
()),
If(Eval('to_date'),
('to_date', '<=', datetime.date.today()))
])
class ReportSaleAbstract(ModelSQL):
@classmethod
def table_query(cls):
from_item, tables = cls._joins()
final_query = from_item.select(
*cls._columns(tables),
where=cls._where(tables),
group_by=cls._group_by(tables)
)
return final_query
@classmethod
def _joins(cls):
pool = Pool()
tables = {}
Sale = pool.get('sale.sale')
tables['sale.sale'] = sale = Sale.__table__()
SaleLine = pool.get('sale.line')
tables['sale.line'] = sale_line = SaleLine.__table__()
ProductTemplate = pool.get('product.template')
tables[
'product.template'
] = product_template = ProductTemplate.__table__()
ProductProduct = pool.get('product.product')
tables['product.product'] = product = ProductProduct.__table__()
from_item = sale_line.left_join(
product,
condition=product.id == sale_line.product
).left_join(
product_template,
condition=product.template == product_template.id
).left_join(
sale,
condition=sale.id == sale_line.sale
)
return from_item, tables
@classmethod
def _columns(cls, tables):
columns = [
cls._column_id(tables).as_('id'),
Literal(0).as_('create_uid'),
CurrentTimestamp().as_('create_date'),
cls.write_uid.sql_cast(Literal(Null)).as_('write_uid'),
cls.write_date.sql_cast(Literal(Null)).as_('write_date'),
]
return columns
@classmethod
def _where(cls, tables):
context = Transaction().context
where = Literal(True)
from_date = context.get('from_date')
to_date = context.get('to_date')
sale = tables['sale.sale']
if from_date:
where &= sale.sale_date >= from_date
if to_date:
where &= sale.sale_date <= to_date
return where
@classmethod
def _group_by(cls, tables):
raise NotImplementedError()
@classmethod
def _column_id(cls, tables):
sale_line = tables['sale.line']
return Min(sale_line.id)
class ReportSaleProduct(ReportSaleAbstract, ModelView):
"""Report Sale Group by Product"""
__name__ = 'sale_fast_food.reporting.product'
product_pizza = fields.Many2One('product.product', "Product")
quantity = fields.Float("Quantity")
@classmethod
def _columns(cls, tables):
sale_line = tables['sale.line']
return super(ReportSaleProduct, cls)._columns(tables) + [
sale_line.product.as_('product_pizza'),
Sum(sale_line.quantity).as_('quantity')
]
@classmethod
def _group_by(cls, tables):
sale_line = tables['sale.line']
return [
sale_line.product
]
@classmethod
def _where(cls, tables):
where = super(ReportSaleProduct, cls)._where(tables)
product_template = tables['product.template']
where &= product_template.pizza == Literal(True)
return where
class ReportSaleByUser(ReportSaleAbstract, ModelView):
"""Report Sale Group by User"""
__name__ = 'sale_fast_food.reporting.by_user'
user = fields.Many2One('res.user', "User")
completed_sales = fields.Integer("Completed Sales")
untaxed_amount = fields.Numeric(
"Untaxed Amount", digits='currency', readonly=True)
tax_amount = fields.Numeric(
"Tax Amount", digits='currency', readonly=True)
total_amount = fields.Numeric(
"Total Amount", digits='currency', readonly=True)
total_tip_amount = fields.Numeric(
"Total Tip Amount", digits='currency', readonly=True)
currency = fields.Many2One(
'currency.currency', 'Currency', required=True)
@classmethod
def _joins(cls):
pool = Pool()
tables = {}
Sale = pool.get('sale.sale')
tables['sale.sale'] = sale = Sale.__table__()
from_item = sale
return from_item, tables
@classmethod
def _columns(cls, tables):
sale = tables['sale.sale']
return super(ReportSaleByUser, cls)._columns(tables) + [
sale.create_uid.as_('user'),
Count(Literal(1)).as_('completed_sales'),
Sum(sale.untaxed_amount_cache).as_('untaxed_amount'),
Sum(sale.tax_amount_cache).as_('tax_amount'),
Sum(sale.total_amount_cache).as_('total_amount'),
Sum(sale.total_tip_cache).as_('total_tip_amount'),
sale.currency.as_('currency'),
]
@classmethod
def _group_by(cls, tables):
sale = tables['sale.sale']
return [
sale.create_uid,
sale.currency
]
@classmethod
def _column_id(cls, tables):
sale = tables['sale.sale']
return Min(sale.id)
class ReportSaleByZone(ReportSaleAbstract, ModelView):
"""Report Sale Group by Zone"""
__name__ = 'sale_fast_food.reporting.zone'
zone = fields.Many2One('sale.zone', "Zone")
table = fields.Many2One('sale.table', "Table")
completed_sales = fields.Integer("Completed Sales")
untaxed_amount = fields.Numeric(
"Untaxed Amount", digits='currency', readonly=True)
tax_amount = fields.Numeric(
"Tax Amount", digits='currency', readonly=True)
total_amount = fields.Numeric(
"Total Amount", digits='currency', readonly=True)
total_tip_amount = fields.Numeric(
"Total Tip Amount", digits='currency', readonly=True)
currency = fields.Many2One(
'currency.currency', 'Currency', required=True)
@classmethod
def _joins(cls):
pool = Pool()
tables = {}
Sale = pool.get('sale.sale')
tables['sale.sale'] = sale = Sale.__table__()
Table = pool.get('sale.table')
tables['sale.table'] = table = Table.__table__()
Zone = pool.get('sale.zone')
tables['sale.table'] = zone = Zone.__table__()
from_item = sale.left_join(
table,
condition=table.id == sale.table
).left_join(
zone,
condition=zone.id == table.zone
)
return from_item, tables
@classmethod
def _columns(cls, tables):
sale = tables['sale.sale']
return super(ReportSaleByZone, cls)._columns(tables) + [
sale.zone.as_('zone'),
sale.table.as_('table'),
Count(Literal(1)).as_('completed_sales'),
Sum(sale.untaxed_amount_cache).as_('untaxed_amount'),
Sum(sale.tax_amount_cache).as_('tax_amount'),
Sum(sale.total_amount_cache).as_('total_amount'),
Sum(sale.total_tip_cache).as_('total_tip_amount'),
sale.currency.as_('currency'),
]
@classmethod
def _group_by(cls, tables):
sale = tables['sale.sale']
return [
sale.zone,
sale.table,
sale.currency
]
@classmethod
def _column_id(cls, tables):
sale = tables['sale.sale']
return Min(sale.id)

View File

@@ -1,103 +0,0 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.ui.view" id="sale_fast_food_report_view_form">
<field name="model">sale_fast_food.report.context</field>
<field name="type">form</field>
<field name="name">sale_fast_food_report_context_form</field>
</record>
<!-- Report by Product-->
<record model="ir.ui.view" id="report_sale_fast_food_product_pizza_view_list">
<field name="model">sale_fast_food.reporting.product</field>
<field name="type">tree</field>
<field name="name">pizzas_sold_by_product_list</field>
</record>
<record model="ir.action.act_window" id="act_report_sale_fast_food_product_pizza">
<field name="name">Pizzas Sold by Product</field>
<field name="res_model">sale_fast_food.reporting.product</field>
<field name="context_model">sale_fast_food.report.context</field>
</record>
<record model="ir.action.act_window.view" id="act_report_sale_fast_food_product_pizza_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="report_sale_fast_food_product_pizza_view_list"/>
<field name="act_window" ref="act_report_sale_fast_food_product_pizza"/>
</record>
<!-- Report by Product-->
<record model="ir.ui.view" id="report_sale_fast_food_by_user_view_list">
<field name="model">sale_fast_food.reporting.by_user</field>
<field name="type">tree</field>
<field name="name">sales_by_user_list</field>
</record>
<record model="ir.action.act_window" id="act_report_sale_fast_food_by_user">
<field name="name">Sales by User</field>
<field name="res_model">sale_fast_food.reporting.by_user</field>
<field name="context_model">sale_fast_food.report.context</field>
</record>
<record model="ir.action.act_window.view" id="act_report_sale_fast_food_by_user_view1">
<field name="sequence" eval="20"/>
<field name="view" ref="report_sale_fast_food_by_user_view_list"/>
<field name="act_window" ref="act_report_sale_fast_food_by_user"/>
</record>
<!-- Report by Zone-->
<record model="ir.ui.view" id="report_sale_fast_food_zone_view_list">
<field name="model">sale_fast_food.reporting.zone</field>
<field name="type">tree</field>
<field name="name">sales_by_zone_list</field>
</record>
<record model="ir.action.act_window" id="act_report_sale_fast_food_zone">
<field name="name">Sales by Zone</field>
<field name="res_model">sale_fast_food.reporting.zone</field>
<field name="context_model">sale_fast_food.report.context</field>
</record>
<record model="ir.action.act_window.view" id="act_report_sale_fast_food_zone_view1">
<field name="sequence" eval="20"/>
<field name="view" ref="report_sale_fast_food_zone_view_list"/>
<field name="act_window" ref="act_report_sale_fast_food_zone"/>
</record>
<menuitem
name="Pizzas Sold by Product"
parent="sale.menu_reporting"
sequence="10"
id="menu_sale_fast_food_pizza"
icon="tryton-graph"/>
<menuitem
name="Sales by User"
parent="sale.menu_reporting"
sequence="20"
id="menu_sale_fast_food_by_user"
icon="tryton-graph"/>
<menuitem
name="Sales by Zone"
parent="sale.menu_reporting"
sequence="30"
id="menu_sale_fast_food_zone"
icon="tryton-graph"/>
<record model="ir.action.keyword" id="act_report_sale_fast_food_product_pizza_keyword1">
<field name="keyword">tree_open</field>
<field name="model" ref="menu_sale_fast_food_pizza"/>
<field name="action" ref="act_report_sale_fast_food_product_pizza"/>
</record>
<record model="ir.action.keyword" id="act_report_sale_fast_food_by_user_keyword1">
<field name="keyword">tree_open</field>
<field name="model" ref="menu_sale_fast_food_by_user"/>
<field name="action" ref="act_report_sale_fast_food_by_user"/>
</record>
<record model="ir.action.keyword" id="act_report_sale_fast_food_zone_keyword1">
<field name="keyword">tree_open</field>
<field name="model" ref="menu_sale_fast_food_zone"/>
<field name="action" ref="act_report_sale_fast_food_zone"/>
</record>
</data>
</tryton>

View File

@@ -43,11 +43,10 @@ class ReportCloseStatementStart(ModelView):
@classmethod @classmethod
def default_shop(cls): def default_shop(cls):
context = Transaction().context context = Transaction().context
if context:
shop = context['shop'] shop = context['shop']
if shop: if shop:
return shop return shop
return
class PrintReportCloseStatement(Wizard): class PrintReportCloseStatement(Wizard):
@@ -174,7 +173,7 @@ class CashRegister(Report):
amount_tips.append(info_pizzas_sold['amount_tip']) amount_tips.append(info_pizzas_sold['amount_tip'])
total_amount += sale.total_amount total_amount += sale.total_amount
untaxed_amount_for_tax = round((tax_amount * 100) / Decimal('8.0'), 2) untaxed_amount_for_tax = round((tax_amount * 100)/Decimal('8.0'), 2)
statements = cls._get_statements_by_date(data['date']) statements = cls._get_statements_by_date(data['date'])
if statements: if statements:

181
sale.py
View File

@@ -2,6 +2,7 @@ from trytond.pool import Pool, PoolMeta
from trytond.model import ModelView, fields from trytond.model import ModelView, fields
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.modules.currency.fields import Monetary from trytond.modules.currency.fields import Monetary
from trytond.pyson import Eval
from decimal import Decimal from decimal import Decimal
import requests import requests
@@ -13,19 +14,17 @@ class Sale(metaclass=PoolMeta):
__name__ = 'sale.sale' __name__ = 'sale.sale'
pizza_number = fields.Integer("Number pizza") pizza_number = fields.Integer("Number pizza")
credito = fields.Boolean("Credito")
total_discount = fields.Function( total_discount = fields.Function(
Monetary( Monetary(
"Total Discount", digits='currency', currency='currency'), "Total Discount", digits='currency', currency='currency'),
'get_amount') 'get_amount')
total_discount_cache = fields.Numeric( total_discount_cache = fields.Numeric("Total Discount cache", digits='currency')
"Total Discount cache", digits='currency')
total_tip = fields.Function( total_tip = fields.Function(
Monetary( Monetary(
"Total Tip", digits='currency', currency='currency'), "Total Tip", digits='currency', currency='currency'),
'get_amount') 'get_amount')
total_tip_cache = fields.Numeric( total_tip_cache = fields.Numeric("Total Tip cache", digits="currency")
"Total Tip cache", digits="currency")
@classmethod @classmethod
def __setup__(cls): def __setup__(cls):
@@ -102,18 +101,13 @@ class Sale(metaclass=PoolMeta):
else: else:
untaxed_amount[sale.id] = round(sum( untaxed_amount[sale.id] = round(sum(
(line.amount for line in sale.lines (line.amount for line in sale.lines
if line.type == 'line'), Decimal(0)), 2) if line.type == 'line'), Decimal(0)),2)
total_discount[sale.id] = round(sum( total_discount[sale.id] = round(sum(
(line.discount_amount * Decimal( (line.discount_amount * Decimal(line.quantity) for line in sale.lines
line.quantity) for line in sale.lines if line.discount_amount and line.type == 'line'), Decimal(0)), 2)
if line.discount_amount and line.type == 'line' total_tip[sale.id] = round(sum(
), Decimal(0)), 2) (line.amount for line in sale.lines if line.product and line.product.tip and line.type == 'line'),
total_tip[sale.id] = round( Decimal(0)), 2)
sum((
line.amount for line in sale.lines
if line.product and line.product.tip and (
line.type == 'line')
), Decimal(0)), 2)
if compute_taxes: if compute_taxes:
tax_amount[sale.id] = sale.get_tax_amount() tax_amount[sale.id] = sale.get_tax_amount()
total_amount[sale.id] = ( total_amount[sale.id] = (
@@ -124,7 +118,7 @@ class Sale(metaclass=PoolMeta):
'tax_amount': tax_amount, 'tax_amount': tax_amount,
'total_amount': total_amount, 'total_amount': total_amount,
'total_discount': total_discount, 'total_discount': total_discount,
'total_tip': total_tip 'total_tip' : total_tip
} }
for key in list(result.keys()): for key in list(result.keys()):
if key not in names: if key not in names:
@@ -147,6 +141,10 @@ class Sale(metaclass=PoolMeta):
@classmethod @classmethod
def get_invoice(cls, record): def get_invoice(cls, record):
pool = Pool()
ctx = Transaction().context
Shop = pool.get('sale.shop')
shop = Shop.search([('id', '=', ctx["shop"])])[0]
if record.state != 'draft' and record.invoices: if record.state != 'draft' and record.invoices:
invoice = record.invoices[0] invoice = record.invoices[0]
data = {} data = {}
@@ -168,11 +166,8 @@ class Sale(metaclass=PoolMeta):
data = {} data = {}
shop = Shop.search([('id', '=', ctx["shop"])])[0] shop = Shop.search([('id', '=', ctx["shop"])])[0]
data["shop_name"] = shop.name data["shop_name"] = shop.name
data["shop_nit"] = shop.company.party.tax_identifier.code
data["shop_address"] = shop.address.street data["shop_address"] = shop.address.street
data['invoice'] = cls.get_invoice(record) data['invoice'] = cls.get_invoice(record)
data['fe_cufe'] = record.fe_qrcode
data['cufe'] = record.fe_cufe
data["party"] = record.party.name data["party"] = record.party.name
data["tax_identifier_type"] = record.party.tax_identifier.type_string data["tax_identifier_type"] = record.party.tax_identifier.type_string
data["tax_identifier_code"] = record.party.tax_identifier.code data["tax_identifier_code"] = record.party.tax_identifier.code
@@ -185,19 +180,17 @@ class Sale(metaclass=PoolMeta):
"product": line.product.name if line.type != 'title' else None, "product": line.product.name if line.type != 'title' else None,
"quantity": line.quantity if line.type != 'title' else None, "quantity": line.quantity if line.type != 'title' else None,
"uom": line.unit.symbol if line.type != 'title' else None, "uom": line.unit.symbol if line.type != 'title' else None,
"unit_price": str(line.amount_w_tax) "unit_price": str(line.amount_w_tax) if line.type != 'title' else None,
if line.type != 'title' else None, "taxes": str(round(line.taxes[0].rate * 100, 2))+'%'
"taxes": str(round(line.taxes[0].rate * 100, 2)) + '%'
if line.type != 'title' and line.taxes else None if line.type != 'title' and line.taxes else None
} for line in record.lines] } for line in record.lines if line.type == 'line' and not line.product.tip]
data["total_discount"] = str(round(record.total_discount, 2)) data["total_discount"] = str(round(record.total_discount,2))
data["untaxed_amount"] = str(record.untaxed_amount) data["untaxed_amount"] = str(record.untaxed_amount)
data["tax_amount"] = str(record.tax_amount)
data["total_tip"] = str(record.total_tip) data["total_tip"] = str(record.total_tip)
data["tax_amount"] = str(record.tax_amount)
data["total"] = str(record.total_amount) data["total"] = str(record.total_amount)
data["state"] = \ data["state"] = "SUBTOTAL" if record.state == "draft" else "CUENTA FINAL"
"SUBTOTAL" if record.state == "draft" else "CUENTA FINAL"
if record.payments: if record.payments:
data['payments'] = [{ data['payments'] = [{
@@ -219,18 +212,20 @@ class Sale(metaclass=PoolMeta):
data["city"] = report.invoice_address.subdivision_municipality.name data["city"] = report.invoice_address.subdivision_municipality.name
data["zone"] = report.zone.name if report.zone else "" data["zone"] = report.zone.name if report.zone else ""
data["table"] = report.table.name if report.table else "" data["table"] = report.table.name if report.table else ""
# data["lines"] = [{
# 'type': line.type,
# "product": line.product.name if line.type != 'title' else None,
# "quantity": line.quantity if line.type != 'title' else None,
# "uom": line.unit.name if line.type != 'title' else None}
# for line in report.lines]
data["lines"] = [{ data["lines"] = [{
"type": line.type, 'type': line.type,
"product": line.product.name if line.type != "title" else None, "product": line.product.name if line.type != 'title' else None,
"description": line.description if line.type != "title" else None, "description": line.description if line.type != 'title' else None,
"quantity": line.quantity if line.type != "title" else None, "quantity": line.quantity if line.type != 'title' else None,
"uom": line.unit.name if line.type != "title" else None} "uom": line.unit.name if line.type != 'title' else None}
for line in report.lines if not line.impreso] for line in report.lines if not line.impreso]
data["deleted_lines"] = [{
"product": line.product.name,
"quantity": str(-1 * line.quantity),
"unit": line.unit.symbol
} for line in report.delete_lines if not line.printed]
return data return data
@@ -253,10 +248,6 @@ class Sale(metaclass=PoolMeta):
line.analytic_accounts = tuple() line.analytic_accounts = tuple()
line.impreso = True line.impreso = True
line.save() line.save()
for line in record.delete_lines:
line.printed = True
line.save()
record.save() record.save()
@classmethod @classmethod
@@ -280,28 +271,13 @@ class Sale(metaclass=PoolMeta):
user_name = context['employee.rec_name'] user_name = context['employee.rec_name']
else: else:
user_name = "" user_name = ""
content = {"content": str(json.dumps(bill)),
content = { "ip_printer": str(printer.ip_address),
"content": str(json.dumps(bill)), "user_name": user_name}
"printer_type": "",
"ip_printer": "",
"user_name": user_name,
"idVendor": "",
"idProduct": ""}
if printer.type_ == 'network':
content["printer_type"] = "Network"
content["ip_printer"] = str(printer.ip_address)
else:
if printer.type_ == 'usb':
content["printer_type"] = "USB"
content["idVendor"] = str(printer.idVendor)
content["idProduct"] = str(printer.idProduct)
headers = {"accept": 'application/json', headers = {"accept": 'application/json',
'Content-Type': 'application/json'} 'Content-Type': 'application/json'}
requests.post(
url, data=json.dumps(content), headers=headers, timeout=5) response = requests.post(url, data=json.dumps(content), headers=headers)
@classmethod @classmethod
@ModelView.button @ModelView.button
@@ -324,29 +300,13 @@ class Sale(metaclass=PoolMeta):
user_name = context['employee.rec_name'] user_name = context['employee.rec_name']
else: else:
user_name = "" user_name = ""
content = {"content": str(json.dumps(customer_order)), content = {"content": str(json.dumps(customer_order)),
"printer_type": "", "ip_printer": str(printer.ip_address),
"ip_printer": "", "user_name": user_name}
"user_name": user_name,
"idVendor": "",
"idProduct": ""}
if printer.type_ == 'network':
content["printer_type"] = "Network"
content["ip_printer"] = str(printer.ip_address)
else:
if printer.type_ == 'usb':
content["printer_type"] = "USB"
content["idVendor"] = str(printer.idVendor)
content["idProduct"] = str(printer.idProduct)
headers = {"accept": 'application/json', headers = {"accept": 'application/json',
'Content-Type': 'application/json'} 'Content-Type': 'application/json'}
cls.impreso([record]) cls.impreso([record])
response = requests.post(url, data=json.dumps(content),
requests.post(
url, data=str(json.dumps(content)),
headers=headers) headers=headers)
@classmethod @classmethod
@@ -367,33 +327,16 @@ class Sale(metaclass=PoolMeta):
url = f"http://{printer.api.ip_address}/order_bar" url = f"http://{printer.api.ip_address}/order_bar"
customer_order = cls.report_customer_order(records) customer_order = cls.report_customer_order(records)
cls.impreso([record]) cls.impreso([record])
if 'employee.rec_name' in context.keys(): if 'employee.rec_name' in context.keys():
user_name = context['employee.rec_name'] user_name = context['employee.rec_name']
else: else:
user_name = "" user_name = ""
content = {"content": str(json.dumps(customer_order)),
content = { "ip_printer": str(printer.ip_address),
"content": str(json.dumps(customer_order)), "user_name": user_name}
"printer_type": "", headers = {"accept": 'application/json',
"ip_printer": "",
"user_name": user_name,
"idVendor": "",
"idProduct": ""}
if printer.type_ == 'network':
content["printer_type"] = "Network"
content["ip_printer"] = str(printer.ip_address)
else:
if printer.type_ == 'usb':
content["printer_type"] = "USB"
content["idVendor"] = str(printer.idVendor)
content["idProduct"] = str(printer.idProduct)
headers = {
"accept": 'application/json',
'Content-Type': 'application/json'} 'Content-Type': 'application/json'}
requests.post(url, data=json.dumps(content), response = requests.post(url, data=json.dumps(content),
headers=headers) headers=headers)
@@ -404,38 +347,38 @@ class Line(metaclass=PoolMeta):
pizza = fields.Integer("Pizza") pizza = fields.Integer("Pizza")
impreso = fields.Boolean("Impreso") impreso = fields.Boolean("Impreso")
bought_pizza = fields.Boolean("Sold pizza") bought_pizza = fields.Boolean("Sold pizza")
rate = fields.Numeric(
"Rate", digits=(16, 4),
states={
'invisible': Eval('type') != 'line',
'readonly': Eval('sale_state') != 'draft',
},
depends=['type', 'sale_state'])
@classmethod @classmethod
def delete(cls, lines): def default_rate(cls):
for line in lines: return 0
if line.impreso and line.type == 'line':
cls._create_sale_line_deleted_log(line)
super(Line, cls).delete(lines)
@fields.depends('product', 'unit', 'sale', @fields.depends('product', 'unit', 'sale',
'_parent_sale.party', '_parent_sale.invoice_party', '_parent_sale.party', '_parent_sale.invoice_party',
'_parent_sale.pizza_number', '_parent_sale.pizza_number',
'_parent_product.template',
'_parent_product._parent_template.pizza',
methods=['compute_taxes', 'compute_unit_price', methods=['compute_taxes', 'compute_unit_price',
'on_change_with_amount']) 'on_change_with_amount'])
def on_change_product(self): def on_change_product(self):
super(Line, self).on_change_product() super(Line, self).on_change_product()
if self.product and self.product.template.pizza: if self.product and self.product.pizza:
self.pizza = self.sale.pizza_number self.pizza = self.sale.pizza_number
self.bought_pizza = True self.bought_pizza = True
else: else:
self.bought_pizza = False self.bought_pizza = False
def get_production(self, product_quantities): def get_production(self):
"Return production for the sale line" "Return production for the sale line"
Production = super(Line, self).get_production(product_quantities) Production = super(Line, self).get_production()
return Production return Production
@fields.depends('discount_rate')
class SaleLineDeletedLog(metaclass=PoolMeta): def on_change_discount_rate(self):
"""Sale Line Deleted Log""" if self.discount_rate:
__name__ = 'sale.line_deleted' self.rate = self.discount_rate
printed = fields.Boolean("Printed")

View File

@@ -2,7 +2,6 @@
<!--This file file is part of Tryton. The COPYRIGHT file at the top level <!--This file file is part of Tryton. The COPYRIGHT file at the top level
of this repository contains the full copyright notices and license terms. --> of this repository contains the full copyright notices and license terms. -->
<tryton> <tryton>
<data>
<record model="ir.ui.view" id="sale_view_tree"> <record model="ir.ui.view" id="sale_view_tree">
<field name="model">sale.sale</field> <field name="model">sale.sale</field>
<field name="inherit" ref="sale.sale_view_tree"/> <field name="inherit" ref="sale.sale_view_tree"/>
@@ -54,5 +53,4 @@
<field name="model">sale.sale,-1</field> <field name="model">sale.sale,-1</field>
<field name="action" ref="report_customer_order"/> <field name="action" ref="report_customer_order"/>
</record> </record>
</data>
</tryton> </tryton>

View File

@@ -127,7 +127,7 @@ setup(name=name,
], ],
license='GPL-3', license='GPL-3',
python_requires='>=3.7', python_requires='>=3.7',
# install_requires=requires, install_requires=requires,
extras_require={ extras_require={
'test': tests_require, 'test': tests_require,
}, },

View File

@@ -1,258 +0,0 @@
=============================
Sale Line Delete Log Scenario
=============================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.tests.tools import activate_modules
>>> from trytond.modules.company.tests.tools import create_company, get_company
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, create_tax, get_accounts)
>>> from trytond.modules.account_invoice.tests.tools import (
... create_payment_term, set_fiscalyear_invoice_sequences)
>>> import datetime as dt
>>> today = dt.date.today()
>>> from trytond.tests.tools import set_user
>>> from trytond.modules.sale_shop.tests.tools import create_shop
>>> from trytond.modules.sale_line_delete_log.sale import SaleLineDeleted
Activate modules::
>>> config = activate_modules('sale_fast_food')
>>> User = Model.get('res.user')
>>> Party = Model.get('party.party')
>>> Employee = Model.get('company.employee')
>>> Journal = Model.get('account.journal')
>>> PaymentMethod = Model.get('account.invoice.payment.method')
>>> Party = Model.get('party.party')
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> Sale = Model.get('sale.sale')
>>> SaleLine = Model.get('sale.line')
Create company::
>>> _ = create_company()
>>> company = get_company()
Set employee::
>>> employee_party = Party(name="Employee")
>>> employee_party.save()
>>> employee = Employee(party=employee_party)
>>> employee.save()
>>> user = User(config.user)
>>> user.employees.append(employee)
>>> user.employee = employee
>>> user.save()
>>> set_user(user.id)
Create fiscal year::
>>> fiscalyear = set_fiscalyear_invoice_sequences(create_fiscalyear(company, today))
>>> fiscalyear.click('create_period')
Create chart of accounts::
>>> _ = create_chart(company)
>>> accounts = get_accounts(company)
>>> revenue = accounts['revenue']
>>> expense = accounts['expense']
>>> cash = accounts['cash']
>>> cash_journal, = Journal.find([('type', '=', 'cash')])
>>> cash_journal.save()
>>> payment_method = PaymentMethod()
>>> payment_method.name = 'Cash'
>>> payment_method.journal = cash_journal
>>> payment_method.credit_account = cash
>>> payment_method.debit_account = cash
>>> payment_method.save()
Create tax::
>>> tax = create_tax(Decimal('.10'))
>>> tax.save()
Create parties::
>>> supplier = Party(name='Supplier')
>>> supplier.save()
>>> customer = Party(name='Customer')
>>> customer.save()
Create account categories::
>>> ProductCategory = Model.get('product.category')
>>> account_category = ProductCategory(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_expense = expense
>>> account_category.account_revenue = revenue
>>> account_category.save()
>>> account_category_tax, = account_category.duplicate()
>>> account_category_tax.customer_taxes.append(tax)
>>> account_category_tax.save()
Create product::
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.salable = True
>>> template.pizza = True
>>> template.list_price = Decimal('10')
>>> template.account_category = account_category_tax
>>> template.save()
>>> product_pizza, = template.products
>>> template = ProductTemplate()
>>> template.name = 'service'
>>> template.default_uom = unit
>>> template.type = 'service'
>>> template.pizza = False
>>> template.salable = True
>>> template.list_price = Decimal('30')
>>> template.account_category = account_category
>>> template.save()
>>> service, = template.products
Create payment term::
>>> payment_term = create_payment_term()
>>> payment_term.save()
Create product price list::
>>> ProductPriceList = Model.get('product.price_list')
>>> product_price_list = ProductPriceList()
>>> product_price_list.name = 'Price List'
>>> product_price_list.company = company
>>> product_price_list.save()
Create an Inventory::
>>> Inventory = Model.get('stock.inventory')
>>> Location = Model.get('stock.location')
>>> storage, = Location.find([
... ('code', '=', 'STO'),
... ])
>>> inventory = Inventory()
>>> inventory.location = storage
>>> inventory_line = inventory.lines.new(product=product_pizza)
>>> inventory_line.quantity = 100.0
>>> inventory_line.expected_quantity = 0.0
>>> inventory.click('confirm')
>>> inventory.state
'done'
Create Sale Shop::
>>> shop = create_shop(payment_term, product_price_list)
>>> shop.save()
>>> Device = Model.get('sale.device')
>>> device = Device()
>>> device.name = "SE Device"
>>> device.shop = shop
>>> device.save()
Save Sale Shop User::
>>> User = Model.get('res.user')
>>> user, = User.find([])
>>> user.shops.append(shop)
>>> user.shop = shop
>>> user.save()
>>> set_user(user)
Crear Una Zona de Venta::
>>> Zone = Model.get('sale.zone')
>>> zone = Zone()
>>> zone.name = "Main"
>>> zone.save()
>>> zone1 = Zone()
>>> zone1.name = "SE"
>>> zone1.shop = shop
>>> zone1.device = device
>>> zone1.parent = zone
>>> zone1.save()
>>> table1 = zone1.tables.new()
>>> table1.name = "CH1"
>>> table1.save()
>>> table2 = zone1.tables.new()
>>> table2.name = "CH1"
>>> table2.save()
Sale 5 products::
>>> sale = Sale()
>>> sale.party = customer
>>> sale.payment_term = payment_term
>>> sale.zone = zone1
>>> sale.table = table1
>>> sale.invoice_method = 'order'
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.product = product_pizza
>>> sale_line.quantity = 2.0
>>> sale_line.impreso = True
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.product = product_pizza
>>> sale_line.quantity = 3.0
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.product = service
>>> sale_line.quantity = 5.0
>>> sale.save()
>>> len(sale.lines)
3
Sale Fast Food Pizzas Sell by Product::
>>> ReportSellPizzas = Model.get('sale_fast_food.reporting.product')
>>> reports = ReportSellPizzas.find([])
>>> expected_report = {
... (product_pizza, 5.0)
... }
>>> actual_report = {(r.product_pizza, r.quantity) for r in reports}
>>> assert expected_report == actual_report, f"\n Expect: {expected_report} \n Actual: {actual_report}"
Sale Fast Food Sales by User::
>>> User = Model.get('res.user')
>>> user = User(config.user)
>>> ReportSalesByUser = Model.get('sale_fast_food.reporting.by_user')
>>> reports = ReportSalesByUser.find([])
>>> expected_report = {
... (user, 1)
... }
>>> actual_report = {(r.user, r.completed_sales) for r in reports}
>>> assert expected_report == actual_report, f"\n Expect: {expected_report} \n Actual: {actual_report}"
Sale Fast Food Sales by Zone::
>>> ReportSalesByZone = Model.get('sale_fast_food.reporting.zone')
>>> reports = ReportSalesByZone.find([])
>>> expected_report = {
... (table1, zone)
... }
>>> actual_report = {(r.table, r.zone) for r in reports}
>>> assert expected_report == actual_report, f"\n Expect: {expected_report} \n Actual: {actual_report}"

View File

@@ -1,213 +0,0 @@
=============================
Sale Line Delete Log Scenario
=============================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.tests.tools import activate_modules
>>> from trytond.modules.company.tests.tools import create_company, get_company
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, create_tax, get_accounts)
>>> from trytond.modules.account_invoice.tests.tools import (
... create_payment_term, set_fiscalyear_invoice_sequences)
>>> import datetime as dt
>>> today = dt.date.today()
>>> from trytond.tests.tools import set_user
>>> from trytond.modules.sale_shop.tests.tools import create_shop
>>> from trytond.modules.sale_line_delete_log.sale import SaleLineDeleted
Activate modules::
>>> config = activate_modules('sale_fast_food')
Initial data::
>>> User = Model.get('res.user')
>>> Party = Model.get('party.party')
>>> Employee = Model.get('company.employee')
>>> Journal = Model.get('account.journal')
>>> PaymentMethod = Model.get('account.invoice.payment.method')
>>> Party = Model.get('party.party')
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> Sale = Model.get('sale.sale')
>>> SaleLine = Model.get('sale.line')
Create company::
>>> _ = create_company()
>>> company = get_company()
Set employee::
>>> employee_party = Party(name="Employee")
>>> employee_party.save()
>>> employee = Employee(party=employee_party)
>>> employee.save()
>>> user = User(config.user)
>>> user.employees.append(employee)
>>> user.employee = employee
>>> user.save()
>>> set_user(user.id)
Create fiscal year::
>>> fiscalyear = set_fiscalyear_invoice_sequences(create_fiscalyear(company, today))
>>> fiscalyear.click('create_period')
Create chart of accounts::
>>> _ = create_chart(company)
>>> accounts = get_accounts(company)
>>> revenue = accounts['revenue']
>>> expense = accounts['expense']
>>> cash = accounts['cash']
>>> cash_journal, = Journal.find([('type', '=', 'cash')])
>>> cash_journal.save()
>>> payment_method = PaymentMethod()
>>> payment_method.name = 'Cash'
>>> payment_method.journal = cash_journal
>>> payment_method.credit_account = cash
>>> payment_method.debit_account = cash
>>> payment_method.save()
Create tax::
>>> tax = create_tax(Decimal('.10'))
>>> tax.save()
Create parties::
>>> supplier = Party(name='Supplier')
>>> supplier.save()
>>> customer = Party(name='Customer')
>>> customer.save()
Create account categories::
>>> ProductCategory = Model.get('product.category')
>>> account_category = ProductCategory(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_expense = expense
>>> account_category.account_revenue = revenue
>>> account_category.save()
>>> account_category_tax, = account_category.duplicate()
>>> account_category_tax.customer_taxes.append(tax)
>>> account_category_tax.save()
Create product::
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.salable = True
>>> template.pizza = True
>>> template.list_price = Decimal('10')
>>> template.account_category = account_category_tax
>>> template.save()
>>> product, = template.products
>>> template = ProductTemplate()
>>> template.name = 'service'
>>> template.default_uom = unit
>>> template.type = 'service'
>>> template.salable = True
>>> template.list_price = Decimal('30')
>>> template.account_category = account_category
>>> template.save()
>>> service, = template.products
Create payment term::
>>> payment_term = create_payment_term()
>>> payment_term.save()
Create product price list::
>>> ProductPriceList = Model.get('product.price_list')
>>> product_price_list = ProductPriceList()
>>> product_price_list.name = 'Price List'
>>> product_price_list.company = company
>>> product_price_list.save()
Create an Inventory::
>>> Inventory = Model.get('stock.inventory')
>>> Location = Model.get('stock.location')
>>> storage, = Location.find([
... ('code', '=', 'STO'),
... ])
>>> inventory = Inventory()
>>> inventory.location = storage
>>> inventory_line = inventory.lines.new(product=product)
>>> inventory_line.quantity = 100.0
>>> inventory_line.expected_quantity = 0.0
>>> inventory.click('confirm')
>>> inventory.state
'done'
Create Sale Shop::
>>> shop = create_shop(payment_term, product_price_list)
>>> shop.save()
Save Sale Shop User::
>>> User = Model.get('res.user')
>>> user, = User.find([])
>>> user.shops.append(shop)
>>> user.shop = shop
>>> user.save()
>>> set_user(user)
Sale 5 products::
>>> sale = Sale()
>>> sale.party = customer
>>> sale.payment_term = payment_term
>>> sale.invoice_method = 'order'
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.product = product
>>> sale_line.quantity = 2.0
>>> sale_line.impreso = True
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.type = 'comment'
>>> sale_line.description = 'Comment'
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.product = product
>>> sale_line.quantity = 3.0
>>> sale.save()
>>> len(sale.lines)
3
>>> sale.untaxed_amount, sale.tax_amount, sale.total_amount
(Decimal('50.00'), Decimal('5.00'), Decimal('55.00'))
Create a sale line delete log it's was printed::
>>> sale.reload()
>>> sale.lines[0].delete()
>>> sale.lines[1].delete()
>>> sale.save()
>>> len(sale.lines)
1
>>> sale.reload()
>>> len(sale.delete_lines)
1
>>> sale.delete_lines[0]
proteus.Model.get('sale.line_deleted')(1)
>>> assert isinstance(sale.delete_lines[0], Model.get('sale.line_deleted')), "it's not instance SaleLineDeleted"

View File

@@ -1,8 +0,0 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.tests.test_tryton import load_doc_tests
def load_tests(*args, **kwargs):
return load_doc_tests(__name__, __file__, *args, **kwargs)

View File

@@ -1,21 +1,17 @@
[tryton] [tryton]
version=6.8.0 version=6.4
depends: depends:
ir ir
res res
product product
sale sale
sale_discount
sale_supply_production sale_supply_production
sale_line_delete_log #sale_printer
sale_printer
production production
account_invoice account_invoice
sale_shop sale_shop
sale_pos_table
xml: xml:
product.xml product.xml
sale.xml sale.xml
user.xml user.xml
report_close_statement.xml report_close_statement.xml
report.xml

View File

@@ -1,6 +1,5 @@
from trytond.model import fields from trytond.model import fields
from trytond.pool import PoolMeta from trytond.pool import Pool, PoolMeta
class User(metaclass=PoolMeta): class User(metaclass=PoolMeta):
"User" "User"

View File

@@ -1,7 +0,0 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree>
<field name="product_pizza"/>
<field name="quantity" sum="1"/>
</tree>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<form>
<label name="from_date"/>
<group id="dates" col="-1">
<field name="from_date"/>
<label name="to_date"/>
<field name="to_date"/>
</group>
</form>

View File

@@ -12,16 +12,11 @@ this repository contains the full copyright notices and license terms. -->
</group> </group>
<newline/> <newline/>
</xpath> </xpath>
<xpath expr="/form/notebook/page[@id='sale']/group[@id='amount']/field[@name='tax_amount']" <xpath expr="/form/notebook/page[@id='sale']/group[@id='amount']/field[@name='tax_amount']" position="after">
position="after">
<label name="total_discount"/> <label name="total_discount"/>
<field name="total_discount"/> <field name="total_discount"/>
<label name="total_tip"/> <label name="total_tip"/>
<field name="total_tip"/> <field name="total_tip"/>
</xpath>
<xpath expr="/form/notebook/page[@id='sale']/group[@id='amount']/field[@name='total_amount']"
position="after">
<label name="credito"/>
<field name="credito"/>
</xpath> </xpath>
</data> </data>

View File

@@ -10,4 +10,8 @@
<label name="bought_pizza"/> <label name="bought_pizza"/>
<field name="bought_pizza"/> <field name="bought_pizza"/>
</xpath> </xpath>
<xpath expr="//field[@name='discount_rate']" position="after">
<label name="discount_rate"/>
<field name="discount_rate" factor="100"/>
</xpath>
</data> </data>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree>
<field name="user"/>
<field name="completed_sales" sum="1"/>
<field name="untaxed_amount" sum="1"/>
<field name="tax_amount" sum="1"/>
<field name="total_amount" sum="1"/>
<field name="total_tip_amount" sum="1"/>
</tree>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree>
<field name="zone"/>
<field name="table"/>
<field name="completed_sales" sum="1"/>
<field name="untaxed_amount" sum="1"/>
<field name="tax_amount" sum="1"/>
<field name="total_amount" sum="1"/>
<field name="total_tip_amount" sum="1"/>
</tree>