Coverage for src/henrri_connect/items/synchro.py: 86%
36 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-05 10:54 +0200
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-05 10:54 +0200
1"""
2Sous-client pour les endpoints /v1/items.
4Classes:
5- ``henrri_connect.items.synchro.SyncItemsClient``
6 Accès synchrone aux endpoints articles.
8Notes:
9- Utiliser de préférence l'objet ``henrri_connect.SyncHenrriClient`` pour acceder aux endpoints.
10"""
12from __future__ import annotations
14from typing import TYPE_CHECKING, overload, Optional
16from ..models import Item, PagedListResponse, ItemsQuery
17from ..utils import clean
19if TYPE_CHECKING:
20 from ..connect import SyncHenrriClient
22ITEMS_ENDPOINT = "/v1/items"
25class SyncItemsClient:
26 """
27 Accès synchrone aux endpoints articles.
29 Arguments
30 - ``client`` : Objet ``henrri_connect.SyncHenrriClient`` pour acceder aux endpoints.
32 Methods
33 - ``list_items`` : Liste les articles avec pagination et filtres optionnels.
34 - ``add`` : Crée un nouvel article.
35 - ``get`` : Récupère un article par son identifiant.
36 - ``modify`` : Modifie un article par son identifiant.
37 - ``delete`` : Supprime un article par son identifiant.
38 - ``get_most_used`` : Récupère les articles les plus utilisés.
39 - ``get_best_sales`` : Récupère les articles les plus vendus.
40 - ``list_with_selected_fields`` : Liste les articles avec sélection de champs.
41 """
43 def __init__(self, client: SyncHenrriClient) -> None:
44 self._c = client
46 @overload
47 def list_items(
48 self,
49 *,
50 request: ItemsQuery,
51 with_selected_fields: bool = True,
52 with_totals: bool = False,
53 only_current_page: bool = True
54 ) -> PagedListResponse[Item]:...
55 @overload
56 def list_items(
57 self,
58 *,
59 request: ItemsQuery,
60 with_selected_fields: bool = False,
61 with_totals: None = None,
62 only_current_page: None = None,
63 ) -> PagedListResponse[Item]:...
64 def list_items(
65 self,
66 *,
67 request: ItemsQuery,
68 with_selected_fields: bool = True,
69 with_totals: Optional[bool] = False,
70 only_current_page: Optional[bool] = True
71 ) -> PagedListResponse[Item]:
72 """
73 Liste les articles avec pagination et filtres optionnels.
75 Arguments
76 - ``request`` (ItemsQuery) : Paramètres de recherche.
77 - ``with_selected_fields`` (bool) : Si True, lance une requête de recherche avancée.
78 - ``with_totals`` (bool) : Si True, renvoie les totaux.
79 - ``only_current_page`` (bool) : Si True, renvoie uniquement les articles de la page
80 actuelle.
82 Returns
83 - ``PagedListResponse[Item]`` : Liste paginée d'articles.
84 """
85 params = clean(request.model_dump(by_alias=True))
86 if with_selected_fields:
87 if with_totals and only_current_page:
88 params["with_totals"] = with_totals
89 params["only_current_page"] = only_current_page
90 resp = self._c.request(
91 "GET",
92 f"{ITEMS_ENDPOINT}/with-selected-fields",
93 params=params
94 )
95 else:
96 raise ValueError(
97 "with_totals and only_current_page must be True if with_selected_fields is True"
98 )
99 else:
100 resp = self._c.request("GET", ITEMS_ENDPOINT, params=params)
101 return PagedListResponse[Item].model_validate(resp.json())
103 def add(self, item: Item) -> Item:
104 """
105 Crée un nouvel article.
107 Arguments
108 - ``item`` (Item) : Article à créer.
110 Returns
111 - ``Item`` : Article créé.
112 """
113 resp = self._c.request(
114 "POST",
115 ITEMS_ENDPOINT,
116 json=item.model_dump(by_alias=True, exclude_unset=True, exclude_none=True),
117 )
118 return Item.model_validate(resp.json())
120 def get(self, item_id: int) -> Item:
121 """
122 Récupère un article par son identifiant.
124 Arguments
125 - ``item_id`` (int) : Identifiant de l'article.
127 Returns
128 - ``Item`` : Article rencontré.
129 """
130 resp = self._c.request("GET", f"{ITEMS_ENDPOINT}/{item_id}")
131 return Item.model_validate(resp.json())
133 def modify(self, item_id: int, item: Item) -> Item:
134 """
135 Met à jour un article existant.
137 Arguments
138 - ``item_id`` (int) : Identifiant de l'article.
139 - ``item`` (Item) : Article à mettre à jour.
141 Returns
142 - ``Item`` : Article mis à jour.
143 """
144 resp = self._c.request(
145 "PUT",
146 f"{ITEMS_ENDPOINT}/{item_id}",
147 json=item.model_dump(by_alias=True, exclude_unset=True, exclude_none=True),
148 )
149 return Item.model_validate(resp.json())
151 def delete(self, item_id: int) -> None:
152 """
153 Supprime un article.
155 Arguments
156 - ``item_id`` (int) : Identifiant de l'article à supprimer.
158 Returns
159 - ``None`` : Article supprimé.
160 """
161 self._c.request("DELETE", f"{ITEMS_ENDPOINT}/{item_id}")
163 def get_most_used(self) -> PagedListResponse[Item]:
164 """
165 Récupère les articles les plus utilisés.
167 Arguments
168 - None
170 Returns
171 - ``PagedListResponse[Item]`` : Liste paginée d'articles.
172 """
173 resp = self._c.request("GET", f"{ITEMS_ENDPOINT}/most-used")
174 return PagedListResponse[Item].model_validate(resp.json())
176 def get_best_sales(self, *, year: int) -> PagedListResponse[Item]:
177 """
178 Récupère les articles les plus vendus.
180 Arguments
181 - ``year`` (int) : Année de recherche.
183 Returns
184 - ``PagedListResponse[Item]`` : Liste paginée d'articles.
185 """
186 params = {
187 "year": year
188 }
189 resp = self._c.request("GET", f"{ITEMS_ENDPOINT}/with-selected-fields", params=params)
190 return PagedListResponse[Item].model_validate(resp.json())