Feat: Sale Fast Food Product by Pizza

This commit is contained in:
sinergia 2024-10-20 20:03:09 -05:00
parent 2480d43167
commit c34f782480
8 changed files with 430 additions and 2 deletions

View File

@ -1,5 +1,6 @@
from trytond.pool import Pool
from . import product, sale, production, invoice, user, report_close_statement
from . import (
product, sale, production, invoice, user, report_close_statement, report)
__all__ = ['register']
@ -14,6 +15,8 @@ def register():
user.User,
production.Production,
report_close_statement.ReportCloseStatementStart,
report.ReportSaleProduct,
report.ReportSaleContext,
module='sale_fast_food', type_='model')
Pool.register(
report_close_statement.PrintReportCloseStatement,

151
report.py Normal file
View File

@ -0,0 +1,151 @@
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
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

48
report.xml Normal file
View File

@ -0,0 +1,48 @@
<?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>
<!-- Family Members Per State -->
<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">Pizza 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>
<menuitem
name="Reporting"
parent="sale.menu_sale"
sequence="999"
id="menu_sale_fast_food_reporting"/>
<menuitem
name="Sale Fast Food Pizza"
parent="menu_sale_fast_food_reporting"
sequence="10"
id="menu_sale_fast_food_pizza"
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_reporting"/>
<field name="action" ref="act_report_sale_fast_food_product_pizza"/>
</record>
</data>
</tryton>

View File

@ -0,0 +1,206 @@
=============================
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.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()
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_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, 2)
... }
>>> 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}"

View File

@ -107,6 +107,7 @@ Create 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()

View File

@ -18,3 +18,4 @@ xml:
sale.xml
user.xml
report_close_statement.xml
report.xml

View File

@ -0,0 +1,7 @@
<?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

@ -0,0 +1,11 @@
<?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>