34 Commits

Author SHA1 Message Date
03d8711ab3 Se limpia la casa 2023-08-28 13:38:23 -05:00
d60c932b45 Se limpia la casa 2023-08-28 13:34:37 -05:00
0e7694b347 feat: Se agregan traducciones a botones 2023-08-15 11:26:34 -05:00
7556fd3789 fix se corrige vistas de botones del restaurante 2023-08-14 14:10:20 -05:00
b737a14857 fix: clean home 2023-08-13 15:14:22 -05:00
cosmos
4e0c39fd78 Add fields kitchen and bar in form product 2023-08-11 18:05:25 -05:00
root
e18d857ed6 change impreso buttons 2023-08-02 21:17:53 +00:00
cosmos
3b058e0e4a Add button Impreso 2023-08-02 15:45:55 -05:00
a4a4481312 fix: se corrige error en on_change_product linea 230 2023-08-02 02:12:27 +00:00
a244f18bf9 chore: Se agrega Total de la venta a la vista tree de la venta 2023-07-31 10:43:37 -05:00
aca4b9e1b4 chore: Se agrega zona y mesa a la vista tree de la venta 2023-07-31 10:27:53 -05:00
693f2d2e04 Error Bug 2023-07-27 07:33:36 -05:00
2ab5993a90 finish bill ticket 2023-07-26 13:09:21 -05:00
7b244fa0da add information for print bill ticket 2023-07-26 00:36:00 -05:00
1c65c9da81 add button bill 2023-07-25 23:06:21 -05:00
5bb58622c3 field shop to sale 2023-07-25 22:20:50 -05:00
4f378cbae9 add printer by zone 2023-07-22 11:27:17 -05:00
a118d64c71 Add field Tip 2023-07-19 02:04:57 +00:00
root
d0bde61593 update print buttons 2023-07-11 19:37:12 +00:00
root
8f079d4f65 add bar button 2023-07-11 19:26:23 +00:00
62144b60ca add decode method to customer_order 2023-07-11 12:10:30 -05:00
bfdffca9e3 Merge branch '6.4' of https://gitea.onecluster.org/OneTeam/trytondo-sale_fast_food into 6.4
add report customer_order
2023-07-10 14:38:08 -05:00
69966b529a add report 2023-07-10 14:37:53 -05:00
root
55cefcb8ca add button kitchen 2023-07-10 19:32:48 +00:00
b38ac4cb3e Merge branch '6.4' of https://gitea.onecluster.org/OneTeam/trytondo-sale_fast_food into 6.4 2023-07-09 10:02:04 -05:00
2494b0b906 add print button kitchen 2023-07-09 10:01:00 -05:00
5054666e40 No requirido lineas de typo = Titulo 2023-06-28 20:01:20 +00:00
d9df054288 No requirido lineas de typo = Titulo 2023-06-28 20:00:31 +00:00
a723842c36 No requirido lineas de typo = Titulo 2023-06-28 19:58:33 +00:00
24da82aa41 add line of title to the sale 2023-06-28 10:18:35 -05:00
0bfc36b7c2 update production 2023-06-25 01:50:26 -05:00
8049d555f2 add production 2023-06-24 23:02:37 -05:00
e170c152ab delete element expand in label product template 2023-06-25 02:26:56 +00:00
975b64f44f add boms to template product 2023-06-24 10:29:11 -05:00
13 changed files with 1614 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
from trytond.pool import Pool
from . import product, sale
from . import product, sale, production, invoice
__all__ = ['register']
@@ -7,8 +7,10 @@ __all__ = ['register']
def register():
Pool.register(
product.Product,
invoice.InvoiceLine,
sale.Sale,
sale.Line,
production.Production,
module='sale_fast_food', type_='model')
Pool.register(
module='sale_fast_food', type_='wizard')

16
invoice.py Normal file
View File

@@ -0,0 +1,16 @@
from trytond.pool import Pool, PoolMeta
from trytond.model import ModelView, fields
from trytond.exceptions import UserError
from trytond.pyson import Eval
class InvoiceLine(metaclass=PoolMeta):
__name__ = 'account.invoice.line'
@classmethod
def __setup__(cls):
super(InvoiceLine, cls).__setup__()
cls.product.states['required'] = (Eval('type') == 'line')
cls.unit_price.domain = []

View File

@@ -6,6 +6,34 @@ msgctxt "field:product.template,pizza:"
msgid "Pizza"
msgstr "Pizza"
msgctxt "field:product.template,pizza:"
msgctxt "field:product.template,pizza_topping:"
msgid "Topping Pizza"
msgstr "Adiciónes"
msgctxt "field:product.template,boms:"
msgid "Boms"
msgstr "Lista de Materiales"
msgctxt "field:product.template,tip:"
msgid "Tip"
msgstr "Propina"
msgctxt "field:product.template,kitchen:"
msgid "Kitchen"
msgstr "Cocina"
msgctxt "model:ir.model.button,string:sale_add_pizza_button"
msgid "Add Pizza"
msgstr "Agregar Pizza"
msgctxt "model:ir.model.button,string:sale_order_kitchen_button"
msgid "Kitchen"
msgstr "Cocina"
msgctxt "model:ir.model.button,string:sale_order_bar_button"
msgid "Bar"
msgstr "Bar"
msgctxt "model:ir.model.button,string:sale_print_bill_button"
msgid "Bill"
msgstr "Subtotal"

View File

@@ -1,5 +1,6 @@
from trytond.pool import Pool, PoolMeta
from trytond.model import fields
from trytond.pyson import Eval, Bool
class Product(metaclass=PoolMeta):
@@ -7,4 +8,9 @@ class Product(metaclass=PoolMeta):
__name__ = 'product.template'
pizza = fields.Boolean("Pizza")
Pizza_topping = fields.Boolean("Topping Pizza")
pizza_topping = fields.Boolean("Topping Pizza")
tip = fields.Boolean("Tip")
kitchen = fields.Boolean("Kitchen")
bar = fields.Boolean("Bar")
boms = fields.Many2One('production.bom', "Boms",
states={'required': Eval('producible', True)})

62
production.py Normal file
View File

@@ -0,0 +1,62 @@
# 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 decimal import Decimal
from trytond.pool import Pool, PoolMeta
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',
'company', 'inputs', 'outputs']
class Production(metaclass=PoolMeta):
"Production"
__name__ = 'production'
@fields.depends(*BOM_CHANGES)
def explode_bom(self):
pool = Pool()
Uom = pool.get('product.uom')
if not (self.bom and self.product and self.uom):
return
factor = self.bom.compute_factor(self.product, self.quantity or 0,
self.uom)
inputs = []
for input_ in self.bom.inputs:
if input_.product.producible:
for input_ in input_.product.template.boms.inputs:
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)
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)
self.inputs = inputs
outputs = []
for output in self.bom.outputs:
quantity = output.compute_quantity(factor)
move = self._explode_move_values(
self.location, self.output_location, self.company, output,
quantity)
if move:
move.unit_price = Decimal(0)
outputs.append(move)
self.outputs = outputs

1206
report/customer_order.fodt Normal file

File diff suppressed because it is too large Load Diff

232
sale.py
View File

@@ -1,6 +1,9 @@
from trytond.pool import Pool, PoolMeta
from trytond.model import ModelView, fields
from trytond.exceptions import UserError
from trytond.transaction import Transaction
import requests
import json
class Sale(metaclass=PoolMeta):
@@ -8,39 +11,250 @@ class Sale(metaclass=PoolMeta):
__name__ = 'sale.sale'
pizza_number = fields.Integer("Number pizza")
@classmethod
def __setup__(cls):
super(Sale, cls).__setup__()
cls._buttons.update({
'add_pizza': {},
'kitchen': {},
'bar': {},
'print_bill': {},
'impreso': {},
})
@classmethod
def default_pizza_number(cls):
return 0
def get_invoice_resolution(subtype):
if subtype:
resolution = subtype.sequence.invoice_resolution
if resolution:
return dict([
('resolution_number', resolution.resolution_number),
('resolution_prefix', resolution.prefix),
('valid_date_time_from', str(resolution.valid_date_time_from)),
('valid_date_time_to', str(resolution.valid_date_time_to)),
('from_number', resolution.from_number),
('to_number', resolution.to_number)])
@classmethod
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:
invoice = record.invoices[0]
data = {}
data['invoice_number'] = invoice.number
subtype = invoice.subtype
data['resolution'] = cls.get_invoice_resolution(subtype)
return data
@classmethod
def report_bill(cls, records):
if not records:
return
pool = Pool()
ctx = Transaction().context
record = records[0]
Shop = pool.get('sale.shop')
data = {}
shop = Shop.search([('id', '=', ctx["shop"])])[0]
data["shop_name"] = shop.name
data["shop_address"] = shop.address.street
data['invoice'] = cls.get_invoice(record)
data["party"] = record.party.name
data["tax_identifier_type"] = record.party.tax_identifier.type_string
data["tax_identifier_code"] = record.party.tax_identifier.code
data["address"] = record.invoice_address.street
data["city"] = record.invoice_address.subdivision_municipality.name
data["zone"] = record.zone.name if record.zone else ""
data["table"] = record.table.name if record.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.symbol if line.type != 'title' else None,
"unit_price": str(line.amount_w_tax) if line.type != 'title' else None,
"taxes": str(round(line.taxes[0].rate * 100, 2))+'%'
if line.type != 'title' and line.taxes else None
} for line in record.lines]
data["untaxed_amount"] = str(record.untaxed_amount)
data["tax_amount"] = str(record.tax_amount)
data["total"] = str(record.total_amount)
if record.payments:
data['payments'] = [{
"statement": payment.statement.journal.name,
"amount": str(payment.amount)} for payment in record.payments]
return data
def report_customer_order(records):
if not records:
return
report = records[0]
data = {}
data["party"] = report.party.name
data["tax_identifier_type"] = report.party.tax_identifier.type_string
data["tax_identifier_code"] = report.party.tax_identifier.code
data["address"] = report.invoice_address.street
data["city"] = report.invoice_address.subdivision_municipality.name
data["zone"] = report.zone.name if report.zone 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"] = [{
'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 if not line.impreso]
return data
@classmethod
@ModelView.button
def add_pizza(cls, records):
pool = Pool()
saleLine = pool.get('sale.line')
for record in records:
record.pizza_number +=1
record.pizza_number += 1
record.lines += (saleLine(type="title",
description="Pizza Combinada"),)
record.save()
@classmethod
@ModelView.button
def impreso(cls, records):
record = records[0]
for line in record.lines:
line.analytic_accounts = tuple()
line.impreso = True
line.save()
record.save()
@classmethod
@ModelView.button
def print_bill(cls, records):
pool = Pool()
context = Transaction().context
shop = context['shop']
Printer = pool.get('sale.printer')
printers = Printer.search([
('zone', '=', 'reception'),
('shop', '=', shop)])
if not printers:
return
printer = printers[0]
url = f"http://{printer.api.ip_address}/print_bill"
bill = cls.report_bill(records)
if 'employee.rec_name' in context.keys():
user_name = context['employee.rec_name']
else:
user_name = ""
content = {"content": str(json.dumps(bill)),
"ip_printer": str(printer.ip_address),
"user_name": user_name}
headers = {"accept": 'application/json',
'Content-Type': 'application/json'}
response = requests.post(url, data=json.dumps(content), headers=headers)
@classmethod
@ModelView.button
def kitchen(cls, records):
pool = Pool()
context = Transaction().context
shop = context['shop']
Printer = pool.get('sale.printer')
printers = Printer.search([('zone', '=', 'kitchen'),
('shop', '=', shop)])
record = records[0]
if not printers:
return
printer = printers[0]
url = f"http://{printer.api.ip_address}/order_kitchen"
customer_order = cls.report_customer_order(records)
if 'employee.rec_name' in context.keys():
user_name = context['employee.rec_name']
else:
user_name = ""
content = {"content": str(json.dumps(customer_order)),
"ip_printer": str(printer.ip_address),
"user_name": user_name}
headers = {"accept": 'application/json',
'Content-Type': 'application/json'}
cls.impreso([record])
response = requests.post(url, data=json.dumps(content),
headers=headers)
@classmethod
@ModelView.button
def bar(cls, records):
pool = Pool()
context = Transaction().context
shop = context['shop']
Printer = pool.get('sale.printer')
printers = Printer.search([('zone', '=', 'bar'),
('shop', '=', shop)])
record = records[0]
if not printers:
return
printer = printers[0]
url = f"http://{printer.api.ip_address}/order_bar"
customer_order = cls.report_customer_order(records)
cls.impreso([record])
if 'employee.rec_name' in context.keys():
user_name = context['employee.rec_name']
else:
user_name = ""
content = {"content": str(json.dumps(customer_order)),
"ip_printer": str(printer.ip_address),
"user_name": user_name}
headers = {"accept": 'application/json',
'Content-Type': 'application/json'}
response = requests.post(url, data=json.dumps(content),
headers=headers)
class Line(metaclass=PoolMeta):
"Sale Line Fast Food"
__name__ = 'sale.line'
pizza = fields.Integer("Pizza")
impreso = fields.Boolean("Impreso")
@fields.depends('product', 'unit', 'sale',
'_parent_sale.party', '_parent_sale.invoice_party',
'_parent_sale.party', '_parent_sale.invoice_party',
'_parent_sale.pizza_number',
methods=['compute_taxes', 'compute_unit_price',
'on_change_with_amount'])
methods=['compute_taxes', 'compute_unit_price',
'on_change_with_amount'])
def on_change_product(self):
super(Line, self).on_change_product()
if self.product.pizza:
if self.product and self.product.pizza:
self.pizza = self.sale.pizza_number
def get_production(self):
"Return production for the sale line"
Production = super(Line, self).get_production()
return Production

View File

@@ -22,4 +22,35 @@
<field name="string">Add Pizza</field>
<field name="model" search="[('model', '=', 'sale.sale')]"/>
</record>
<record model="ir.model.button" id="sale_order_kitchen_button">
<field name="name">kitchen</field>
<field name="string">Kitchen</field>
<field name="model" search="[('model', '=', 'sale.sale')]"/>
</record>
<record model="ir.model.button" id="sale_order_bar_button">
<field name="name">bar</field>
<field name="string">Bar</field>
<field name="model" search="[('model', '=', 'sale.sale')]"/>
</record>
<record model="ir.model.button" id="sale_print_bill_button">
<field name="name">print_bill</field>
<field name="string">Bill</field>
<field name="model" search="[('model', '=', 'sale.sale')]"/>
</record>
<record model="ir.model.button" id="sale_impreso_button">
<field name="name">impreso</field>
<field name="string">Impreso</field>
<field name="model" search="[('model', '=', 'sale.sale')]"/>
</record>
<record model="ir.action.report" id="report_customer_order">
<field name="name">Customer Order</field>
<field name="model">sale.sale</field>
<field name="report_name">sale.customer_order</field>
<field name="report">sale_fast_food/report/customer_order.fodt</field>
</record>
<record model="ir.action.keyword" id="report_customer_order_keyword">
<field name="keyword">form_print</field>
<field name="model">sale.sale,-1</field>
<field name="action" ref="report_customer_order"/>
</record>
</tryton>

View File

@@ -4,6 +4,10 @@ depends:
ir
product
sale
sale_supply_production
#sale_printer
production
account_invoice
xml:
product.xml
sale.xml

View File

@@ -7,5 +7,14 @@
<field name="pizza"/>
<label name="pizza_topping"/>
<field name="pizza_topping"/>
<label name="tip"/>
<field name="tip"/>
<label name="kitchen"/>
<field name="kitchen"/>
<label name="bar"/>
<field name="bar"/>
<newline/>
<label name="boms"/>
<field name="boms" xexpand="1"/>
</xpath>
</data>

View File

@@ -1,10 +1,15 @@
<?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. -->
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="//field[@name='reference']" position="after">
<label name="pizza_number"/>
<field name="pizza_number"/>
<button name="add_pizza"/>
<xpath expr="//field[@name='lines']" position="after">
<group col="-1" colspan="5" id="restaturant_buttons">
<button name="kitchen" icon="tryton-print"/>
<button name="bar" icon="tryton-print"/>
<button name="print_bill" icon="tryton-print"/>
<button name="add_pizza"/>
<button name="impreso"/>
</group>
<newline/>
</xpath>
</data>

View File

@@ -5,5 +5,7 @@
<xpath expr="//field[@name='product']" position="after">
<label name="pizza"/>
<field name="pizza"/>
<label name="impreso"/>
<field name="impreso"/>
</xpath>
</data>

12
view/sale_tree.xml Normal file
View File

@@ -0,0 +1,12 @@
<?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. -->
<data>
<xpath expr="//field[@name='shop']" position="after">
<field name="zone" string="Zona"/>
<field name="table" string="Mesa"/>
</xpath>
<xpath expr="//field[@name='untaxed_amount']" position="after">
<field name="total_amount"/>
</xpath>
</data>