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.
Files changed (65) hide show
  1. {printer_core-0.0.13 → printer_core-1.0.0}/PKG-INFO +1 -1
  2. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/algorithms/products_modifiers_multiprinter.py +11 -9
  3. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/algorithms/products_modifiers_multiprinter_family.py +11 -9
  4. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/algorithms/products_modifiers_unique_ticket.py +8 -6
  5. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/client_ticket_builder.py +10 -7
  6. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/formatters/discount_formatter.py +2 -1
  7. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_client_ticket_builder.py +60 -1
  8. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_discount_formatter.py +2 -2
  9. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_products_modifiers.py +78 -0
  10. printer_core-1.0.0/printer_core/utils/product_price_presenter.py +32 -0
  11. {printer_core-0.0.13 → printer_core-1.0.0}/pyproject.toml +1 -1
  12. {printer_core-0.0.13 → printer_core-1.0.0}/.gitignore +0 -0
  13. {printer_core-0.0.13 → printer_core-1.0.0}/README.md +0 -0
  14. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/__init__.py +0 -0
  15. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/algorithms/__init__.py +0 -0
  16. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/__init__.py +0 -0
  17. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/header_builder.py +0 -0
  18. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/kitchen_ticket_payload_builder.py +0 -0
  19. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/builders/printer_products_grouper.py +0 -0
  20. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/clock.py +0 -0
  21. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/context/__init__.py +0 -0
  22. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/context/ticket_context_builder.py +0 -0
  23. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/dispatchers/__init__.py +0 -0
  24. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/dispatchers/kitchen_ticket_dispatcher.py +0 -0
  25. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/dispatchers/payload_dispatcher.py +0 -0
  26. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/entities/__init__.py +0 -0
  27. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/entities/print_context.py +0 -0
  28. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/entities/print_models.py +0 -0
  29. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/formatters/__init__.py +0 -0
  30. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/ports.py +0 -0
  31. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/selectors/__init__.py +0 -0
  32. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/selectors/family_product_selector.py +0 -0
  33. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/__init__.py +0 -0
  34. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/flows/__init__.py +0 -0
  35. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/flows/base.py +0 -0
  36. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/flows/client.py +0 -0
  37. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/flows/kitchen.py +0 -0
  38. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/march_printer_service.py +0 -0
  39. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/multi_printer_family_service.py +0 -0
  40. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/multi_printer_service.py +0 -0
  41. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/order_print_service.py +0 -0
  42. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/print_policy.py +0 -0
  43. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/services/unique_ticket_service.py +0 -0
  44. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/__init__.py +0 -0
  45. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/__init__.py +0 -0
  46. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/helpers.py +0 -0
  47. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_cases_output.py +0 -0
  48. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_family_product_selector.py +0 -0
  49. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_flows.py +0 -0
  50. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_header_builder_foodeo_printers.py +0 -0
  51. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_kitchen_ticket_dispatcher.py +0 -0
  52. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_kitchen_ticket_payload_builder.py +0 -0
  53. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_march_printer_service.py +0 -0
  54. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_multi_printer_family_service.py +0 -0
  55. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_multi_printer_service.py +0 -0
  56. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_order_print_service.py +0 -0
  57. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_payload_dispatcher.py +0 -0
  58. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_print_policy.py +0 -0
  59. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_printer_helpers.py +0 -0
  60. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_printer_products_grouper.py +0 -0
  61. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_ticket_context_builder.py +0 -0
  62. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/tests/unitaries/test_unique_ticket_service.py +0 -0
  63. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/utils/__init__.py +0 -0
  64. {printer_core-0.0.13 → printer_core-1.0.0}/printer_core/utils/printer_helpers.py +0 -0
  65. {printer_core-0.0.13 → printer_core-1.0.0}/scripts/link_backend_env.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: printer-core
3
- Version: 0.0.13
3
+ Version: 1.0.0
4
4
  Summary: Foodeo Printer Core Domain.
5
5
  Project-URL: Homepage, https://github.com/Foodeo/printer-core
6
6
  Project-URL: Repository, https://github.com/Foodeo/printer-core
@@ -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 = product.product_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(product, request.currency or "")
33
+ name += self._formatter.format(displayed_product, request.currency or "")
32
34
  line = KitchenProductLine(
33
35
  name=name,
34
- qty=int(product.qty),
35
- option=product.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=product.details or "",
39
- order=product.order or "",
40
+ details=displayed_product.details or "",
41
+ order=displayed_product.order or "",
40
42
  tpv=printer_payload.tpv,
41
- order_readable=product.order_readable or "",
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": product.importe,
46
- "unitary_price": product.product_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 = product.product_name
21
+ name_with_discount: str = displayed_product.product_name
20
22
  if not request.all_discounted:
21
- name_with_discount += self._formatter.format(product, request.currency or "")
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(product.qty),
25
- option=product.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=product.details or "",
29
- order=product.order or "",
30
+ details=displayed_product.details or "",
31
+ order=displayed_product.order or "",
30
32
  tpv=printer_payload.tpv,
31
- order_readable=product.order_readable or "",
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": product.importe,
37
- "unitary_price": product.product_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(product, request.currency or "")
22
- product_name = product.product_name + with_discount
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(product.qty),
26
- option=product.option,
27
- price=str(product.importe),
28
- unitary_price=str(product.product_price),
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(product, currency_symbol)
75
- product_name = product.product_name + with_discount
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(product.qty),
79
- option=product.option,
80
- price=str(product.importe),
81
- unitary_price=str(product.product_price),
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
- return f" (Dto {product.total_price}{currency_symbol})"
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
- return f" (Dto {product.total_price}{currency_symbol})"
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, "100")
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")
@@ -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 5.00€)")
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 _: "€")
@@ -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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "printer-core"
7
- version = "0.0.13"
7
+ version = "1.0.0"
8
8
  description = "Foodeo Printer Core Domain."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes