Coverage for src/henrri_connect/customers/asynchro.py: 80%
55 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/customers.
4Classes:
5- ``henrri_connect.customers.asynchro.AsyncCustomersClient``
6 Accès asynchrone aux endpoints clients.
8Notes:
9- Utiliser de préférence l'objet ``henrri_connect.AsyncHenrriClient`` pour acceder
10aux endpoints.
11"""
13from __future__ import annotations
15from typing import TYPE_CHECKING, overload, Optional
17from ..models import Address, Contact, Customer, CustomerRequest, PagedListResponse
18from ..models.base import CustomerType
19from ..utils import clean
21if TYPE_CHECKING:
22 from ..connect import AsyncHenrriClient
24BASE_CUSTOMERS = "/v1/customers"
26class AsyncCustomersClient:
27 """
28 Accès asynchrone aux endpoints clients.
30 Arguments
31 - ``client`` (AsyncHenrriClient) : Client HTTP.
33 Methods
34 - ``delete`` : Supprime un client.
35 - ``delete_contact`` : Supprime un contact.
36 - ``list_customers`` : Liste les clients avec pagination et filtres optionnels.
37 - ``get_best_sales`` : Récupère les meilleurs clients.
38 - ``get_last_used`` : Récupère le dernier client utilisé.
39 - ``add`` : Crée un nouveau client.
40 - ``get`` : Récupère un client par son identifiant.
41 - ``modify`` : Met à jour un client.
42 - ``get_address`` : Récupère l'adresse d'un client.
43 - ``list_contacts`` : Liste les contacts d'un client.
44 - ``add_contact`` : Crée un nouveau contact.
45 - ``get_contact`` : Récupère un contact d'un client.
46 - ``modify_contact`` : Met à jour un contact.
47 """
49 def __init__(self, client: AsyncHenrriClient) -> None:
50 self._c = client
52 @overload
53 async def list_customers(
54 self,
55 *,
56 request: CustomerRequest,
57 with_selected_fields: bool = True,
58 with_totals: bool = False,
59 only_current_page: bool = True
60 ) -> PagedListResponse[Customer]:...
61 @overload
62 async def list_customers(
63 self,
64 *,
65 request: CustomerRequest,
66 with_selected_fields: bool = False,
67 with_totals: None = None,
68 only_current_page: None = None,
69 ):...
70 async def list_customers(
71 self,
72 *,
73 request: CustomerRequest,
74 with_selected_fields: bool = True,
75 with_totals: Optional[bool] = False,
76 only_current_page: Optional[bool] = True
77 ):
78 """
79 Liste les clients avec pagination et filtres optionnels.
81 Arguments
82 - ``request`` (CustomerRequest) : Paramètres de recherche.
83 - ``with_selected_fields`` (bool) : Si True, lance une requête de recherche avancée.
84 - ``with_totals`` (bool) : Si True, renvoie les totaux.
85 - ``only_current_page`` (bool) : Si True, renvoie uniquement les clients de la page
86 actuelle.
88 Returns
89 - ``PagedListResponse[Customer]`` : Liste paginée de clients.
90 """
91 params = clean(request.model_dump(by_alias=True))
92 if with_selected_fields:
93 if with_totals and only_current_page:
94 params["with_totals"] = with_totals
95 params["only_current_page"] = only_current_page
96 resp = await self._c.request(
97 "GET",
98 f"{BASE_CUSTOMERS}/with-selected-fields",
99 params=params
100 )
101 else:
102 raise ValueError(
103 "with_totals and only_current_page must be True if with_selected_fields is True"
104 )
105 else:
106 resp = await self._c.request("GET", BASE_CUSTOMERS, params=params)
107 return PagedListResponse[Customer].model_validate(resp.json())
109 async def add(self, customer: Customer) -> Customer:
110 """
111 Crée un nouveau client.
113 Arguments
114 - ``customer`` (Customer) : Client à créer.
116 Returns
117 - ``Customer`` : Client créé.
118 """
119 resp = await self._c.request(
120 "POST",
121 BASE_CUSTOMERS,
122 json=customer.model_dump(by_alias=True, exclude_unset=True, exclude_none=True),
123 )
124 return Customer.model_validate(resp.json())
126 async def get_best_sales(
127 self,
128 *,
129 year: int,
130 ) -> PagedListResponse[Customer]:
131 """
132 Récupère les meilleurs clients.
134 Arguments
135 - ``year`` (int) : Année concerne (minimum 2000, maximum 2100).
137 Returns
138 - ``PagedListResponse[Customer]`` : Liste paginée de clients.
139 """
140 params = {
141 "year": year
142 }
143 resp = await self._c.request("GET", f"{BASE_CUSTOMERS}/best-sales", params=params)
144 return PagedListResponse[Customer].model_validate(resp.json())
146 async def get_last_used(self, customer_type: CustomerType, limit: int) -> Customer:
147 """
148 Récupère les derniers clients utilisés.
150 Arguments
151 - ``customer_type`` (CustomerType) : Type de client.
152 - ``limit`` (int) : Nombre de clients maximum.
154 Returns
155 - ``Customer`` : Derniers clients utilisés.
156 """
157 params = {
158 "Types": customer_type,
159 "Limit": limit,
160 }
161 resp = await self._c.request("GET", f"{BASE_CUSTOMERS}/last-used", params=params)
162 return Customer.model_validate(resp.json())
164 async def get(self, customer_id: int) -> Customer:
165 """
166 Récupère un client par son identifiant.
168 Arguments
169 - ``customer_id`` (int) : Identifiant du client.
171 Returns
172 - ``Customer`` : Client.
173 """
174 resp = await self._c.request("GET", f"{BASE_CUSTOMERS}/{customer_id}")
175 return Customer.model_validate(resp.json())
177 async def modify(self, customer_id: int, customer: Customer) -> Customer:
178 """
179 Met à jour un client existant.
181 Arguments
182 - ``customer_id`` (int) : Identifiant du client.
183 - ``customer`` (Customer) : Client à mettre à jour.
185 Returns
186 - ``Customer`` : Client mis à jour.
187 """
188 resp = await self._c.request(
189 "PUT",
190 f"{BASE_CUSTOMERS}/{customer_id}",
191 json=customer.model_dump(by_alias=True, exclude_unset=True, exclude_none=True),
192 )
193 return Customer.model_validate(resp.json())
195 async def delete(self, customer_id: int) -> None:
196 """
197 Supprime un client.
199 Arguments
200 - ``customer_id`` (int) : Identifiant du client.
202 Returns
203 - ``None``.
204 """
205 await self._c.request("DELETE", f"{BASE_CUSTOMERS}/{customer_id}")
207 async def get_address(self, customer_id: int) -> Address:
208 """
209 Récupère l'adresse d'un client.
211 Arguments
212 - ``customer_id`` (int) : Identifiant du client.
214 Returns
215 - ``henrri_connect.models.Address`` : Adresse du client.
216 """
217 resp = await self._c.request("GET", f"{BASE_CUSTOMERS}/{customer_id}/address")
218 return Address.model_validate(resp.json())
220 async def list_contacts(self, customer_id: int) -> list[Contact]:
221 """
222 Liste les contacts d'un client.
224 Arguments
225 - ``customer_id`` (int) : Identifiant du client.
227 Returns
228 - ``list[Contact]`` : Liste de contacts.
229 """
230 resp = await self._c.request("GET", f"{BASE_CUSTOMERS}/{customer_id}/contacts")
231 return [Contact.model_validate(c) for c in resp.json()]
233 async def add_contact(self, customer_id: int, contact: Contact) -> Contact:
234 """
235 Ajoute un contact à un client.
237 Arguments
238 - ``customer_id`` (int) : Identifiant du client.
239 - ``contact`` (Contact) : Contact à ajouter.
241 Returns
242 - ``Contact`` : Contact ajouté.
243 """
244 resp = await self._c.request(
245 "POST",
246 f"{BASE_CUSTOMERS}/{customer_id}/contacts",
247 json=contact.model_dump(by_alias=True, exclude_unset=True, exclude_none=True),
248 )
249 return Contact.model_validate(resp.json())
251 async def get_contact(self, customer_id: int, contact_id: int) -> Contact:
252 """
253 Récupère un contact d'un client.
255 Arguments
256 - ``customer_id`` (int) : Identifiant du client.
257 - ``contact_id`` (int) : Identifiant du contact.
259 Returns
260 - ``Contact`` : Contact.
261 """
262 resp = await self._c.request("GET", f"{BASE_CUSTOMERS}/{customer_id}/contacts/{contact_id}")
263 return Contact.model_validate(resp.json())
265 async def modify_contact(self, customer_id: int, contact_id: int, contact: Contact) -> Contact:
266 """
267 Met à jour un contact d'un client.
269 Arguments
270 - ``customer_id`` (int) : Identifiant du client.
271 - ``contact_id`` (int) : Identifiant du contact.
272 - ``contact`` (Contact) : Contact à mettre à jour.
274 Returns
275 - ``Contact`` : Contact mis à jour.
276 """
277 resp = await self._c.request(
278 "PUT",
279 f"{BASE_CUSTOMERS}/{customer_id}/contacts/{contact_id}",
280 json=contact.model_dump(by_alias=True, exclude_unset=True, exclude_none=True),
281 )
282 return Contact.model_validate(resp.json())
284 async def delete_contact(self, customer_id: int, contact_id: int) -> None:
285 """
286 Supprime un contact d'un client.
288 Arguments
289 - ``customer_id`` (int) : Identifiant du client.
290 - ``contact_id`` (int) : Identifiant du contact.
292 Returns
293 - ``None``.
294 """
295 await self._c.request("DELETE", f"{BASE_CUSTOMERS}/{customer_id}/contacts/{contact_id}")