Skip to content

Commit a094e4d

Browse files
committed
Improve pickup sites api
1 parent 7879c3b commit a094e4d

10 files changed

+2308
-264
lines changed

roulier/carriers/mondialrelay_fr/carrier.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
from .schema import (
99
MondialRelayLabelInput,
1010
MondialRelayLabelOutput,
11-
MondialRelayPickupSiteInput,
12-
MondialRelayPickupSiteOutput,
11+
MondialRelayPickupSiteGetInput,
12+
MondialRelayPickupSiteSearchInput,
13+
MondialRelayPickupSiteGetOutput,
14+
MondialRelayPickupSiteSearchOutput,
1315
)
1416
from .constants import STATUSES
1517

@@ -18,7 +20,7 @@ class MondialRelay(Carrier):
1820
__key__ = "mondialrelay_fr"
1921

2022
__url__ = "https://api.mondialrelay.com/Web_Services.asmx?WSDL"
21-
__ref__ = "https://www.mondialrelay.fr/media/122867/solution-web-service-v57.pdf"
23+
__ref__ = "https://storage.mondialrelay.fr/web-service-solution-v514-EN.pdf"
2224
__ns_prefix__ = "http://www.mondialrelay.fr/webservice/"
2325

2426
@property
@@ -40,9 +42,17 @@ def get_label(self, input: MondialRelayLabelInput) -> MondialRelayLabelOutput:
4042
return MondialRelayLabelOutput.from_soap(result)
4143

4244
@action
43-
def find_pickup_site(
44-
self, input: MondialRelayPickupSiteInput
45-
) -> MondialRelayPickupSiteOutput:
45+
def search_pickup_sites(
46+
self, input: MondialRelayPickupSiteSearchInput
47+
) -> MondialRelayPickupSiteSearchOutput:
4648
result = self.client.WSI4_PointRelais_Recherche(**input.soap())
4749
self.raise_for_status(result)
48-
return MondialRelayPickupSiteOutput.from_soap(result)
50+
return MondialRelayPickupSiteSearchOutput.from_soap(result)
51+
52+
@action
53+
def get_pickup_site(
54+
self, input: MondialRelayPickupSiteGetInput
55+
) -> MondialRelayPickupSiteGetOutput:
56+
result = self.client.WSI4_PointRelais_Recherche(**input.soap())
57+
self.raise_for_status(result)
58+
return MondialRelayPickupSiteGetOutput.from_soap(result)

roulier/carriers/mondialrelay_fr/schema.py

+102-24
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@
1111
Parcel,
1212
ParcelLabel,
1313
PickupSite,
14-
PickupSiteInput,
15-
PickupSiteOutput,
14+
PickupSiteSearchInput,
1615
PickupSiteSearch,
16+
PickupSiteGetInput,
17+
PickupSiteGet,
18+
PickupSiteOpeningSlot,
19+
PickupSiteOpeningHours,
20+
PickupSiteSearchOutput,
21+
PickupSiteGetOutput,
1722
Service,
1823
)
1924
from .constants import SORTED_KEYS
2025
from hashlib import md5
26+
from datetime import datetime
2127

2228

2329
class MondialRelayAuth(Auth):
@@ -163,43 +169,75 @@ def soap(self):
163169

164170

165171
class MondialRelayPickupSiteSearch(PickupSiteSearch):
166-
id: int | None = None
167-
weight: float | None = None
172+
lat: float | None = None
173+
lng: float | None = None
168174
action: str | None = None
169-
delay: int | None = None
170175
searchRadius: int | None = None
171176
actionType: str | None = None
172177
resultsCount: int | None = None
173178

174179
def soap(self):
175180
return {
176181
"Pays": self.country,
177-
"NumPointRelais": self.id,
178182
"CP": self.zip,
179183
"Latitude": self.lat,
180184
"Longitude": self.lng,
181185
"Poids": self.weight,
182186
"Action": self.action,
183-
"DelaiEnvoi": self.delay,
184187
"RayonRecherche": self.searchRadius,
185188
"TypeActivite": self.actionType,
186189
"NombreResultats": self.resultsCount,
187190
}
188191

189192

190-
class MondialRelayPickupSiteInput(PickupSiteInput):
193+
class MondialRelayPickupSiteService(Service):
194+
def soap(self):
195+
delay = None
196+
if self.shippingDate:
197+
delay = (self.shippingDate - datetime.now()).days
198+
return {
199+
"DelaiEnvoi": delay,
200+
}
201+
202+
203+
class MondialRelayPickupSiteSearchInput(PickupSiteSearchInput):
191204
auth: MondialRelayAuth
205+
service: MondialRelayPickupSiteService | None = None
192206
search: MondialRelayPickupSiteSearch
193207

194208
def soap(self):
195209
return self.auth.sign(
196210
{
197211
**self.auth.soap(),
212+
**(self.service.soap() if self.service else {}),
198213
**self.search.soap(),
199214
}
200215
)
201216

202217

218+
class MondialRelayPickupSiteGet(PickupSiteGet):
219+
def soap(self):
220+
return {
221+
"Pays": self.zone,
222+
"NumPointRelais": self.id,
223+
}
224+
225+
226+
class MondialRelayPickupSiteGetInput(PickupSiteGetInput):
227+
auth: MondialRelayAuth
228+
service: MondialRelayPickupSiteService | None = None
229+
get: MondialRelayPickupSiteGet
230+
231+
def soap(self):
232+
return self.auth.sign(
233+
{
234+
**self.auth.soap(),
235+
**(self.service.soap() if self.service else {}),
236+
**self.get.soap(),
237+
}
238+
)
239+
240+
203241
class MondialRelayLabel(Label):
204242
@classmethod
205243
def from_soap(cls, result):
@@ -229,9 +267,43 @@ def from_soap(cls, result):
229267
return cls.model_construct(parcels=[MondialRelayParcelLabel.from_soap(result)])
230268

231269

270+
class MondialRelayPickupSiteOpeningSlot(PickupSiteOpeningSlot):
271+
@classmethod
272+
def from_soap(cls, start, end):
273+
return cls.model_construct(
274+
start=datetime.strptime(start, "%H%M").time(),
275+
end=datetime.strptime(end, "%H%M").time(),
276+
)
277+
278+
279+
class MondialRelayPickupSiteOpeningHours(PickupSiteOpeningHours):
280+
@classmethod
281+
def from_soap(cls, result):
282+
return cls.model_construct(
283+
**{
284+
day: [
285+
MondialRelayPickupSiteOpeningSlot.from_soap(slot_start, slot_end)
286+
for slot_start, slot_end in zip(
287+
result[f"Horaires_{day_label}"]["string"][::2],
288+
result[f"Horaires_{day_label}"]["string"][1::2],
289+
)
290+
if slot_start != "0000" and slot_end != "0000"
291+
]
292+
for day, day_label in [
293+
("monday", "Lundi"),
294+
("tuesday", "Mardi"),
295+
("wednesday", "Mercredi"),
296+
("thursday", "Jeudi"),
297+
("friday", "Vendredi"),
298+
("saturday", "Samedi"),
299+
("sunday", "Dimanche"),
300+
]
301+
}
302+
)
303+
304+
232305
class MondialRelayPickupSite(PickupSite):
233306
actionType: str
234-
hours: dict
235307
url_pic: str
236308
url_map: str
237309

@@ -240,32 +312,24 @@ def from_soap(cls, result):
240312
return cls.model_construct(
241313
id=result["Num"],
242314
name="\n".join(
243-
[part for part in [result["LgAdr1"], result["LgAdr2"]] if part]
315+
[part.strip() for part in [result["LgAdr1"], result["LgAdr2"]] if part]
244316
),
245317
street="\n".join(
246-
[part for part in [result["LgAdr3"], result["LgAdr4"]] if part]
318+
[part.strip() for part in [result["LgAdr3"], result["LgAdr4"]] if part]
247319
),
248320
zip=result["CP"],
249-
city=result["Ville"],
321+
city=result["Ville"].strip() if result["Ville"] else None,
250322
country=result["Pays"],
251-
lat=result["Latitude"],
252-
lng=result["Longitude"],
323+
lat=result["Latitude"].replace(",", "."),
324+
lng=result["Longitude"].replace(",", "."),
253325
actionType=result["TypeActivite"],
254-
hours={
255-
"monday": result["Horaires_Lundi"],
256-
"tuesday": result["Horaires_Mardi"],
257-
"wednesday": result["Horaires_Mercredi"],
258-
"thursday": result["Horaires_Jeudi"],
259-
"friday": result["Horaires_Vendredi"],
260-
"saturday": result["Horaires_Samedi"],
261-
"sunday": result["Horaires_Dimanche"],
262-
},
326+
hours=MondialRelayPickupSiteOpeningHours.from_soap(result),
263327
url_pic=result["URL_Photo"],
264328
url_map=result["URL_Plan"],
265329
)
266330

267331

268-
class MondialRelayPickupSiteOutput(PickupSiteOutput):
332+
class MondialRelayPickupSiteSearchOutput(PickupSiteSearchOutput):
269333
sites: list[MondialRelayPickupSite]
270334

271335
@classmethod
@@ -276,3 +340,17 @@ def from_soap(cls, result):
276340
for site in result["PointsRelais"]["PointRelais_Details"]
277341
]
278342
)
343+
344+
345+
class MondialRelayPickupSiteGetOutput(PickupSiteGetOutput):
346+
site: MondialRelayPickupSite
347+
348+
@classmethod
349+
def from_soap(cls, result):
350+
return cls.model_construct(
351+
site=MondialRelayPickupSite.from_soap(
352+
result["PointsRelais"]["PointRelais_Details"][0]
353+
)
354+
if result["PointsRelais"]["PointRelais_Details"]
355+
else None
356+
)

0 commit comments

Comments
 (0)