printer-core 0.0.13__tar.gz → 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {printer_core-0.0.13 → printer_core-1.0.0}/PKG-INFO +1 -1
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/algorithms/products_modifiers_multiprinter.py +11 -9
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/algorithms/products_modifiers_multiprinter_family.py +11 -9
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/algorithms/products_modifiers_unique_ticket.py +8 -6
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/client_ticket_builder.py +10 -7
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/formatters/discount_formatter.py +2 -1
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_client_ticket_builder.py +60 -1
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_discount_formatter.py +2 -2
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_products_modifiers.py +78 -0
- printer_core-1.0.0/printer_core/utils/product_price_presenter.py +32 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/pyproject.toml +1 -1
- {printer_core-0.0.13 → printer_core-1.0.0}/.gitignore +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/README.md +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/algorithms/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/header_builder.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/kitchen_ticket_payload_builder.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/printer_products_grouper.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/clock.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/context/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/context/ticket_context_builder.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/dispatchers/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/dispatchers/kitchen_ticket_dispatcher.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/dispatchers/payload_dispatcher.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/entities/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/entities/print_context.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/entities/print_models.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/formatters/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/ports.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/selectors/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/selectors/family_product_selector.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/flows/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/flows/base.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/flows/client.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/flows/kitchen.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/march_printer_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/multi_printer_family_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/multi_printer_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/order_print_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/print_policy.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/unique_ticket_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/helpers.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_cases_output.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_family_product_selector.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_flows.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_header_builder_foodeo_printers.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_kitchen_ticket_dispatcher.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_kitchen_ticket_payload_builder.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_march_printer_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_multi_printer_family_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_multi_printer_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_order_print_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_payload_dispatcher.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_print_policy.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_printer_helpers.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_printer_products_grouper.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_ticket_context_builder.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_unique_ticket_service.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/utils/__init__.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/utils/printer_helpers.py +0 -0
- {printer_core-0.0.13 → printer_core-1.0.0}/scripts/link_backend_env.sh +0 -0
|
@@ -2,6 +2,7 @@ from typing import Any
|
|
|
2
2
|
|
|
3
3
|
from printer_core.entities import KitchenProductLine, PrintProductData, PrintRequestData, PrinterData
|
|
4
4
|
from printer_core.formatters.discount_formatter import DiscountFormatter
|
|
5
|
+
from printer_core.utils.product_price_presenter import prepare_product_price
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class ProductsModifiersMultiPrinter:
|
|
@@ -19,6 +20,7 @@ class ProductsModifiersMultiPrinter:
|
|
|
19
20
|
for product in products:
|
|
20
21
|
if product.printer == []:
|
|
21
22
|
continue
|
|
23
|
+
displayed_product, displayed_price = prepare_product_price(request, product)
|
|
22
24
|
printers = product.printer
|
|
23
25
|
if printers is None:
|
|
24
26
|
if main_printer is None:
|
|
@@ -26,24 +28,24 @@ class ProductsModifiersMultiPrinter:
|
|
|
26
28
|
printers = [self._resolve_printer(main_printer)]
|
|
27
29
|
for actual_printer in printers:
|
|
28
30
|
printer_payload = self._resolve_printer(actual_printer)
|
|
29
|
-
name =
|
|
31
|
+
name = displayed_product.product_name
|
|
30
32
|
if kitchen_ticket_settings.show_price_per_unit and not request.all_discounted:
|
|
31
|
-
name += self._formatter.format(
|
|
33
|
+
name += self._formatter.format(displayed_product, request.currency or "")
|
|
32
34
|
line = KitchenProductLine(
|
|
33
35
|
name=name,
|
|
34
|
-
qty=int(
|
|
35
|
-
option=
|
|
36
|
+
qty=int(displayed_product.qty),
|
|
37
|
+
option=displayed_product.option,
|
|
36
38
|
printer_r=printer_payload.name,
|
|
37
39
|
printer_w=printer_payload.printer_width,
|
|
38
|
-
details=
|
|
39
|
-
order=
|
|
40
|
+
details=displayed_product.details or "",
|
|
41
|
+
order=displayed_product.order or "",
|
|
40
42
|
tpv=printer_payload.tpv,
|
|
41
|
-
order_readable=
|
|
43
|
+
order_readable=displayed_product.order_readable or "",
|
|
42
44
|
)
|
|
43
45
|
if kitchen_ticket_settings.show_price_per_unit:
|
|
44
46
|
line = line.model_copy(update={
|
|
45
|
-
"price":
|
|
46
|
-
"unitary_price":
|
|
47
|
+
"price": displayed_price,
|
|
48
|
+
"unitary_price": displayed_product.product_price,
|
|
47
49
|
})
|
|
48
50
|
list_products_own_printer.append(line)
|
|
49
51
|
return list_products_own_printer
|
|
@@ -2,6 +2,7 @@ from typing import Any
|
|
|
2
2
|
|
|
3
3
|
from printer_core.entities import KitchenProductLine, PrintProductData, PrintRequestData, PrinterData
|
|
4
4
|
from printer_core.formatters.discount_formatter import DiscountFormatter
|
|
5
|
+
from printer_core.utils.product_price_presenter import prepare_product_price
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class ProductsModifiersMultiprinterFamily:
|
|
@@ -14,27 +15,28 @@ class ProductsModifiersMultiprinterFamily:
|
|
|
14
15
|
request: PrintRequestData,
|
|
15
16
|
kitchen_ticket_settings: Any,
|
|
16
17
|
) -> None:
|
|
18
|
+
displayed_product, displayed_price = prepare_product_price(request, product)
|
|
17
19
|
for actual_printer in product.printer or []:
|
|
18
20
|
printer_payload = self._resolve_printer(actual_printer)
|
|
19
|
-
name_with_discount: str =
|
|
21
|
+
name_with_discount: str = displayed_product.product_name
|
|
20
22
|
if not request.all_discounted:
|
|
21
|
-
name_with_discount += self._formatter.format(
|
|
23
|
+
name_with_discount += self._formatter.format(displayed_product, request.currency or "")
|
|
22
24
|
line = KitchenProductLine(
|
|
23
25
|
name=name_with_discount,
|
|
24
|
-
qty=int(
|
|
25
|
-
option=
|
|
26
|
+
qty=int(displayed_product.qty),
|
|
27
|
+
option=displayed_product.option,
|
|
26
28
|
printer_r=printer_payload.name,
|
|
27
29
|
printer_w=printer_payload.printer_width,
|
|
28
|
-
details=
|
|
29
|
-
order=
|
|
30
|
+
details=displayed_product.details or "",
|
|
31
|
+
order=displayed_product.order or "",
|
|
30
32
|
tpv=printer_payload.tpv,
|
|
31
|
-
order_readable=
|
|
33
|
+
order_readable=displayed_product.order_readable or "",
|
|
32
34
|
)
|
|
33
35
|
|
|
34
36
|
if kitchen_ticket_settings.show_price_per_unit:
|
|
35
37
|
line = line.model_copy(update={
|
|
36
|
-
"price":
|
|
37
|
-
"unitary_price":
|
|
38
|
+
"price": displayed_price,
|
|
39
|
+
"unitary_price": displayed_product.product_price,
|
|
38
40
|
})
|
|
39
41
|
|
|
40
42
|
list_products_own_printer.append(line)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from printer_core.entities import ClientTicketProduct, PrintProductData, PrintRequestData
|
|
2
2
|
from printer_core.formatters.discount_formatter import DiscountFormatter
|
|
3
|
+
from printer_core.utils.product_price_presenter import prepare_product_price
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class ProductsModifiersUniqueTicket:
|
|
@@ -16,16 +17,17 @@ class ProductsModifiersUniqueTicket:
|
|
|
16
17
|
def build(self, request: PrintRequestData, products: list[PrintProductData]) -> list[ClientTicketProduct]:
|
|
17
18
|
list_products_in_same_printers: list[ClientTicketProduct] = []
|
|
18
19
|
for product in products:
|
|
20
|
+
displayed_product, displayed_price = prepare_product_price(request, product)
|
|
19
21
|
with_discount = ""
|
|
20
22
|
if not request.all_discounted:
|
|
21
|
-
with_discount = self._formatter.format(
|
|
22
|
-
product_name =
|
|
23
|
+
with_discount = self._formatter.format(displayed_product, request.currency or "")
|
|
24
|
+
product_name = displayed_product.product_name + with_discount
|
|
23
25
|
list_products_in_same_printers.append(ClientTicketProduct(
|
|
24
26
|
name=product_name,
|
|
25
|
-
qty=int(
|
|
26
|
-
option=
|
|
27
|
-
price=str(
|
|
28
|
-
unitary_price=str(
|
|
27
|
+
qty=int(displayed_product.qty),
|
|
28
|
+
option=displayed_product.option,
|
|
29
|
+
price=str(displayed_price),
|
|
30
|
+
unitary_price=str(displayed_product.product_price),
|
|
29
31
|
))
|
|
30
32
|
if request.price_domicile_service:
|
|
31
33
|
list_products_in_same_printers.append(ClientTicketProduct(
|
|
@@ -13,6 +13,7 @@ from printer_core.entities import (
|
|
|
13
13
|
PrinterData,
|
|
14
14
|
)
|
|
15
15
|
from printer_core.ports import Clock
|
|
16
|
+
from printer_core.utils.product_price_presenter import prepare_product_price
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class ClientTicketBuilder:
|
|
@@ -69,16 +70,17 @@ class ClientTicketBuilder:
|
|
|
69
70
|
list_products: list[ClientTicketProduct] = []
|
|
70
71
|
currency_symbol = self._currency_symbol_resolver(request.currency or "")
|
|
71
72
|
for product in products:
|
|
73
|
+
displayed_product, displayed_price = prepare_product_price(request, product)
|
|
72
74
|
with_discount = ""
|
|
73
75
|
if not request.all_discounted:
|
|
74
|
-
with_discount = self._format_discount(
|
|
75
|
-
product_name =
|
|
76
|
+
with_discount = self._format_discount(displayed_product, currency_symbol)
|
|
77
|
+
product_name = displayed_product.product_name + with_discount
|
|
76
78
|
list_products.append(ClientTicketProduct(
|
|
77
79
|
name=product_name,
|
|
78
|
-
qty=int(
|
|
79
|
-
option=
|
|
80
|
-
price=str(
|
|
81
|
-
unitary_price=str(
|
|
80
|
+
qty=int(displayed_product.qty),
|
|
81
|
+
option=displayed_product.option,
|
|
82
|
+
price=str(displayed_price),
|
|
83
|
+
unitary_price=str(displayed_product.product_price),
|
|
82
84
|
))
|
|
83
85
|
if request.price_domicile_service:
|
|
84
86
|
list_products.append(ClientTicketProduct(
|
|
@@ -96,7 +98,8 @@ class ClientTicketBuilder:
|
|
|
96
98
|
|
|
97
99
|
def _format_discount(self, product: PrintProductData, currency_symbol: str) -> str:
|
|
98
100
|
if product.discount_type == "number":
|
|
99
|
-
|
|
101
|
+
total = Decimal(str(product.importe)) - Decimal(str(product.total_price))
|
|
102
|
+
return f" (Dto {total}{currency_symbol})"
|
|
100
103
|
if product.discount_type == "percent" and product.discount:
|
|
101
104
|
total = Decimal(str(product.importe)) - Decimal(str(product.total_price))
|
|
102
105
|
return f" (Dto {product.discount.value}% {total}{currency_symbol})"
|
|
@@ -10,7 +10,8 @@ class DiscountFormatter:
|
|
|
10
10
|
def format(self, product: PrintProductData, currency_code: str) -> str:
|
|
11
11
|
currency_symbol = self._currency_symbol_resolver(currency_code)
|
|
12
12
|
if product.discount_type == "number":
|
|
13
|
-
|
|
13
|
+
total = Decimal(str(product.importe)) - Decimal(str(product.total_price))
|
|
14
|
+
return f" (Dto {total}{currency_symbol})"
|
|
14
15
|
if product.discount_type == "percent" and product.discount:
|
|
15
16
|
total = Decimal(str(product.importe)) - Decimal(str(product.total_price))
|
|
16
17
|
return f" (Dto {product.discount.value}% {total}{currency_symbol})"
|
|
@@ -60,7 +60,66 @@ class ClientTicketBuilderTest(unittest.TestCase):
|
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
self.assertIn("Dto 10% 10€", payloads[0].data.products[0].name)
|
|
63
|
-
self.assertEqual(payloads[0].data.products[0].price, "
|
|
63
|
+
self.assertEqual(payloads[0].data.products[0].price, "90")
|
|
64
|
+
|
|
65
|
+
def test_discounted_product_consolidates_option_prices_without_mutating_input(self):
|
|
66
|
+
builder = ClientTicketBuilder(currency_symbol_resolver=lambda _: "€")
|
|
67
|
+
product = make_product(
|
|
68
|
+
total_price="14.25",
|
|
69
|
+
product_price="10.00",
|
|
70
|
+
importe="10.00",
|
|
71
|
+
discount_type="percent",
|
|
72
|
+
discount=DiscountData(value="5", type="percent"),
|
|
73
|
+
option=[{
|
|
74
|
+
"id": 7,
|
|
75
|
+
"name": "Extra queso",
|
|
76
|
+
"qty": 1,
|
|
77
|
+
"price": "5.00",
|
|
78
|
+
"unitary_price": "5.00",
|
|
79
|
+
}],
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
payload = builder.build(
|
|
83
|
+
request=make_request(),
|
|
84
|
+
products=[product],
|
|
85
|
+
printer=make_printer(),
|
|
86
|
+
ticket_settings=make_ticket_settings(),
|
|
87
|
+
tpv_key="TPV1",
|
|
88
|
+
)[0]
|
|
89
|
+
|
|
90
|
+
printed = payload.data.products[0]
|
|
91
|
+
self.assertEqual(printed.name, "Burger (Dto 5% 0.75€)")
|
|
92
|
+
self.assertEqual(printed.price, "14.25")
|
|
93
|
+
self.assertEqual(printed.unitary_price, "10.00")
|
|
94
|
+
self.assertEqual(printed.option[0]["price"], None)
|
|
95
|
+
self.assertEqual(printed.option[0]["unitary_price"], None)
|
|
96
|
+
self.assertEqual(product.option[0]["price"], "5.00")
|
|
97
|
+
|
|
98
|
+
def test_global_discount_preserves_current_product_and_option_prices(self):
|
|
99
|
+
product = make_product(
|
|
100
|
+
total_price="14.25",
|
|
101
|
+
importe="10.00",
|
|
102
|
+
discount_type="percent",
|
|
103
|
+
discount=DiscountData(value="5", type="percent"),
|
|
104
|
+
option=[{
|
|
105
|
+
"name": "Extra queso",
|
|
106
|
+
"qty": 1,
|
|
107
|
+
"price": "5.00",
|
|
108
|
+
"unitary_price": "5.00",
|
|
109
|
+
}],
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
printed = ClientTicketBuilder().build(
|
|
113
|
+
request=make_request(all_discounted=True),
|
|
114
|
+
products=[product],
|
|
115
|
+
printer=make_printer(),
|
|
116
|
+
ticket_settings=make_ticket_settings(),
|
|
117
|
+
tpv_key="TPV1",
|
|
118
|
+
)[0].data.products[0]
|
|
119
|
+
|
|
120
|
+
self.assertEqual(printed.name, "Burger")
|
|
121
|
+
self.assertEqual(printed.price, "10.00")
|
|
122
|
+
self.assertEqual(printed.option[0]["price"], "5.00")
|
|
64
123
|
|
|
65
124
|
def test_build_adds_domicile_service_line(self):
|
|
66
125
|
builder = ClientTicketBuilder(domicile_service_label="Service")
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_discount_formatter.py
RENAMED
|
@@ -8,11 +8,11 @@ from printer_core.tests.unitaries.helpers import make_product
|
|
|
8
8
|
class DiscountFormatterTest(unittest.TestCase):
|
|
9
9
|
def test_format_number_discount(self):
|
|
10
10
|
formatter = DiscountFormatter(currency_symbol_resolver=lambda _: "€")
|
|
11
|
-
product = make_product(total_price="5.00", discount_type="number")
|
|
11
|
+
product = make_product(total_price="5.00", importe="7.00", discount_type="number")
|
|
12
12
|
|
|
13
13
|
result = formatter.format(product, "EUR")
|
|
14
14
|
|
|
15
|
-
self.assertEqual(result, " (Dto
|
|
15
|
+
self.assertEqual(result, " (Dto 2.00€)")
|
|
16
16
|
|
|
17
17
|
def test_format_percent_discount(self):
|
|
18
18
|
formatter = DiscountFormatter(currency_symbol_resolver=lambda _: "€")
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_products_modifiers.py
RENAMED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import unittest
|
|
2
2
|
|
|
3
|
+
from printer_core.entities import DiscountData
|
|
3
4
|
from printer_core.algorithms.products_modifiers_multiprinter import ProductsModifiersMultiPrinter
|
|
4
5
|
from printer_core.algorithms.products_modifiers_multiprinter_family import ProductsModifiersMultiprinterFamily
|
|
5
6
|
from printer_core.algorithms.products_modifiers_unique_ticket import ProductsModifiersUniqueTicket
|
|
@@ -59,6 +60,33 @@ class ProductsModifiersMultiPrinterTest(unittest.TestCase):
|
|
|
59
60
|
self.assertEqual(lines[0].price, "8.00")
|
|
60
61
|
self.assertEqual(lines[0].unitary_price, "4.00")
|
|
61
62
|
|
|
63
|
+
def test_discounted_product_uses_total_and_hides_option_prices(self):
|
|
64
|
+
service = ProductsModifiersMultiPrinter(DiscountFormatter(lambda _: "€"))
|
|
65
|
+
product = make_product(
|
|
66
|
+
total_price="14.25",
|
|
67
|
+
importe="10.00",
|
|
68
|
+
discount_type="percent",
|
|
69
|
+
discount=DiscountData(value="5", type="percent"),
|
|
70
|
+
option=[{
|
|
71
|
+
"name": "Extra queso",
|
|
72
|
+
"qty": 1,
|
|
73
|
+
"price": "5.00",
|
|
74
|
+
"unitary_price": "5.00",
|
|
75
|
+
}],
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
line = service.build(
|
|
79
|
+
make_request(),
|
|
80
|
+
[product],
|
|
81
|
+
make_kitchen_settings(show_price_per_unit=True),
|
|
82
|
+
make_printer(),
|
|
83
|
+
)[0]
|
|
84
|
+
|
|
85
|
+
self.assertEqual(line.name, "Burger (Dto 5% 0.75€)")
|
|
86
|
+
self.assertEqual(line.price, "14.25")
|
|
87
|
+
self.assertEqual(line.option[0]["price"], None)
|
|
88
|
+
self.assertEqual(line.option[0]["unitary_price"], None)
|
|
89
|
+
|
|
62
90
|
|
|
63
91
|
class ProductsModifiersMultiprinterFamilyTest(unittest.TestCase):
|
|
64
92
|
def test_append_product_adds_lines(self):
|
|
@@ -92,6 +120,34 @@ class ProductsModifiersMultiprinterFamilyTest(unittest.TestCase):
|
|
|
92
120
|
self.assertEqual(lines[0].price, "6.00")
|
|
93
121
|
self.assertEqual(lines[0].unitary_price, "3.00")
|
|
94
122
|
|
|
123
|
+
def test_discounted_product_uses_total_and_hides_option_prices(self):
|
|
124
|
+
service = ProductsModifiersMultiprinterFamily(DiscountFormatter(lambda _: "€"))
|
|
125
|
+
product = make_product(
|
|
126
|
+
printer=[make_printer()],
|
|
127
|
+
total_price="14.25",
|
|
128
|
+
importe="10.00",
|
|
129
|
+
discount_type="percent",
|
|
130
|
+
discount=DiscountData(value="5", type="percent"),
|
|
131
|
+
option=[{
|
|
132
|
+
"name": "Extra queso",
|
|
133
|
+
"qty": 1,
|
|
134
|
+
"price": "5.00",
|
|
135
|
+
"unitary_price": "5.00",
|
|
136
|
+
}],
|
|
137
|
+
)
|
|
138
|
+
lines = []
|
|
139
|
+
|
|
140
|
+
service.append_product(
|
|
141
|
+
lines,
|
|
142
|
+
product,
|
|
143
|
+
make_request(),
|
|
144
|
+
make_kitchen_settings(show_price_per_unit=True),
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
self.assertEqual(lines[0].price, "14.25")
|
|
148
|
+
self.assertEqual(lines[0].option[0]["price"], None)
|
|
149
|
+
self.assertEqual(lines[0].option[0]["unitary_price"], None)
|
|
150
|
+
|
|
95
151
|
|
|
96
152
|
class ProductsModifiersUniqueTicketTest(unittest.TestCase):
|
|
97
153
|
def test_build_appends_domicile_service(self):
|
|
@@ -134,3 +190,25 @@ class ProductsModifiersUniqueTicketTest(unittest.TestCase):
|
|
|
134
190
|
lines = service.build(make_request(all_discounted=True), [product])
|
|
135
191
|
|
|
136
192
|
self.assertEqual(lines[0].price, "5.00")
|
|
193
|
+
|
|
194
|
+
def test_discounted_product_uses_total_and_hides_option_prices(self):
|
|
195
|
+
service = ProductsModifiersUniqueTicket(DiscountFormatter(lambda _: "€"))
|
|
196
|
+
product = make_product(
|
|
197
|
+
total_price="13.00",
|
|
198
|
+
importe="10.00",
|
|
199
|
+
discount_type="number",
|
|
200
|
+
discount=DiscountData(value="2", type="number"),
|
|
201
|
+
option=[{
|
|
202
|
+
"name": "Extra queso",
|
|
203
|
+
"qty": 1,
|
|
204
|
+
"price": "5.00",
|
|
205
|
+
"unitary_price": "5.00",
|
|
206
|
+
}],
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
line = service.build(make_request(), [product])[0]
|
|
210
|
+
|
|
211
|
+
self.assertEqual(line.name, "Burger (Dto 2.00€)")
|
|
212
|
+
self.assertEqual(line.price, "13.00")
|
|
213
|
+
self.assertEqual(line.option[0]["price"], None)
|
|
214
|
+
self.assertEqual(line.option[0]["unitary_price"], None)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from copy import deepcopy
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from printer_core.entities import PrintProductData, PrintRequestData
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def prepare_product_price(
|
|
9
|
+
request: PrintRequestData,
|
|
10
|
+
product: PrintProductData,
|
|
11
|
+
) -> tuple[PrintProductData, Any]:
|
|
12
|
+
"""Return a display copy and its total without mutating print-job data."""
|
|
13
|
+
if request.all_discounted or not product.discount or not product.discount_type:
|
|
14
|
+
return product, product.importe
|
|
15
|
+
|
|
16
|
+
options = deepcopy(product.option)
|
|
17
|
+
options_total = Decimal("0")
|
|
18
|
+
if isinstance(options, list):
|
|
19
|
+
for option in options:
|
|
20
|
+
if not isinstance(option, dict):
|
|
21
|
+
continue
|
|
22
|
+
if option.get("price") is not None:
|
|
23
|
+
options_total += Decimal(str(option["price"]))
|
|
24
|
+
option["price"] = None
|
|
25
|
+
option["unitary_price"] = None
|
|
26
|
+
|
|
27
|
+
gross_price = Decimal(str(product.importe or 0)) + options_total
|
|
28
|
+
presented = product.model_copy(update={
|
|
29
|
+
"importe": gross_price,
|
|
30
|
+
"option": options,
|
|
31
|
+
})
|
|
32
|
+
return presented, product.total_price
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/kitchen_ticket_payload_builder.py
RENAMED
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/printer_products_grouper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/dispatchers/kitchen_ticket_dispatcher.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/selectors/family_product_selector.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/multi_printer_family_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_cases_output.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_order_print_service.py
RENAMED
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_payload_dispatcher.py
RENAMED
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_print_policy.py
RENAMED
|
File without changes
|
{printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_printer_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|