Coverage for packages/clopos/src/integrify/clopos/schemas/products/request.py: 97%
67 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-10-19 02:39 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-10-19 02:39 +0000
1from typing import Literal
3from integrify.api import PayloadBaseModel
4from integrify.clopos.helpers import BoolInt
5from integrify.clopos.schemas.common.request import ByIDRequest, PaginatedDataRequest
6from integrify.clopos.schemas.enums import ProductType
7from integrify.utils import UnsetField
8from pydantic import Field, field_serializer, model_serializer
9from typing_extensions import NotRequired, TypedDict
12class GetProducstRequestFilter(TypedDict):
13 type: NotRequired[list[ProductType]]
14 """Filters by product type. Possible values: GOODS, DISH, TIMER, PREPARATION, INGREDIENT"""
16 category_id: NotRequired[list[int]]
17 """Lists products belonging to the specified category IDs"""
19 station_id: NotRequired[list[int]]
20 """Retrieves products assigned to the specified station IDs"""
22 tags: NotRequired[list[int]]
23 """Filters for products with the specified tag IDs"""
25 giftable: NotRequired[BoolInt]
26 """Filters for products that are ("1") or are not giftable"""
28 discountable: NotRequired[BoolInt]
29 """Filters for products that are ("1") or are not discountable"""
31 inventory_behavior: NotRequired[int]
32 """Filters by inventory behavior mode (e.g., "3")"""
34 have_ingredients: NotRequired[BoolInt]
35 """Retrieves products that have a recipe/ingredients ("1")"""
37 sold_by_portion: NotRequired[BoolInt]
38 """Lists products sold by portion ("1")"""
40 has_variants: NotRequired[BoolInt]
41 """Lists products that have variants (`modifications`) ("1")"""
43 has_modifiers: NotRequired[BoolInt]
44 """Lists products that have modifier group (`modificator_groups`) ("1")"""
46 has_barcode: NotRequired[BoolInt]
47 """Retrieves products that have a barcode ("1")"""
49 has_service_charge: NotRequired[BoolInt]
50 """Lists products to which a service charge applies ("1")"""
53class GetProductsRequest(PaginatedDataRequest):
54 selects: UnsetField[list[str] | str] = Field(serialization_alias='selects[]')
55 filters: UnsetField[GetProducstRequestFilter]
57 @field_serializer('selects')
58 def serialize_selects(self, value):
59 """Transform to comma-separated string"""
60 if isinstance(value, str):
61 return value
62 return ','.join(value)
64 @field_serializer('filters')
65 def serialize_filters(self, filters):
66 """Transform to [field_name, value] format"""
67 result = {}
68 for key, value in filters.items():
69 if value is not None: # Only include non-None values 69 ↛ 68line 69 didn't jump to line 68 because the condition on line 69 was always true
70 result[key] = [key, value]
72 return result
75class GetProductByIDRequest(ByIDRequest):
76 with_: UnsetField[
77 list[
78 Literal[
79 'taxes',
80 'unit',
81 'modifications',
82 'modificator_groups',
83 'recipe',
84 'packages',
85 'media',
86 'tags',
87 'setting',
88 ]
89 ]
90 ] = Field(serialization_alias='with[]')
93class StopListFilter(TypedDict):
94 by: Literal['id', 'limit', 'timestamp']
95 from_: int
96 to: NotRequired[int]
99class GetStopListRequest(PayloadBaseModel):
100 filters: UnsetField[list[StopListFilter]]
102 @model_serializer
103 def serialize_model(self) -> dict:
104 """Model serializer"""
105 data = {}
107 for i, filter_ in enumerate(self.filters or []):
108 data[f'filters[{i}][0]'] = filter_['by']
109 data[f'filters[{i}][1][0]'] = filter_['from_']
111 if 'to' in filter_: 111 ↛ 107line 111 didn't jump to line 107 because the condition on line 111 was always true
112 data[f'filters[{i}][1][1]'] = filter_['to']
114 return data