brynq-sdk-allsolutions 1.0.2__tar.gz → 1.0.3__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.
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/PKG-INFO +1 -1
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/brynq_sdk_allsolutions/__init__.py +82 -61
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/brynq_sdk_allsolutions.egg-info/PKG-INFO +1 -1
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/setup.py +1 -1
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/brynq_sdk_allsolutions.egg-info/SOURCES.txt +0 -0
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/brynq_sdk_allsolutions.egg-info/dependency_links.txt +0 -0
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/brynq_sdk_allsolutions.egg-info/not-zip-safe +0 -0
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/brynq_sdk_allsolutions.egg-info/requires.txt +0 -0
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/brynq_sdk_allsolutions.egg-info/top_level.txt +0 -0
- {brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/setup.cfg +0 -0
{brynq_sdk_allsolutions-1.0.2 → brynq_sdk_allsolutions-1.0.3}/brynq_sdk_allsolutions/__init__.py
RENAMED
|
@@ -13,7 +13,7 @@ class AllSolutions(BrynQ):
|
|
|
13
13
|
self.token = None
|
|
14
14
|
self.refresh_token = None
|
|
15
15
|
self.debug = debug
|
|
16
|
-
credentials = self.interfaces.credentials.get(interface_id=
|
|
16
|
+
credentials = self.interfaces.credentials.get(interface_id=interface_id, system='all-solutions', system_type=None)
|
|
17
17
|
self.url = credentials['data']['url']
|
|
18
18
|
self.client_id = credentials['data']['client_id']
|
|
19
19
|
self.secret_id = credentials['data']['secret_id']
|
|
@@ -21,8 +21,9 @@ class AllSolutions(BrynQ):
|
|
|
21
21
|
self.password = credentials['data']['password']
|
|
22
22
|
self.content_type_header = {'Content-Type': 'application/json'}
|
|
23
23
|
self.filter_freeform_string = "$filter-freeform"
|
|
24
|
+
self.timeout = 3600
|
|
24
25
|
|
|
25
|
-
#authentication functions
|
|
26
|
+
# authentication functions
|
|
26
27
|
def _get_refreshtoken(self):
|
|
27
28
|
signature = hashlib.sha1(f"{self.username}{self.client_id}{self.secret_id}".encode()).hexdigest()
|
|
28
29
|
response = requests.post(url=f"{self.url}login",
|
|
@@ -32,7 +33,8 @@ class AllSolutions(BrynQ):
|
|
|
32
33
|
"Signature": signature,
|
|
33
34
|
"Password": self.password,
|
|
34
35
|
"ClientId": self.client_id
|
|
35
|
-
})
|
|
36
|
+
}),
|
|
37
|
+
timeout=self.timeout)
|
|
36
38
|
if self.debug:
|
|
37
39
|
print(response.content)
|
|
38
40
|
response.raise_for_status()
|
|
@@ -46,7 +48,8 @@ class AllSolutions(BrynQ):
|
|
|
46
48
|
data=json.dumps({
|
|
47
49
|
"RefreshToken": self.refresh_token,
|
|
48
50
|
"Signature": signature
|
|
49
|
-
})
|
|
51
|
+
}),
|
|
52
|
+
timeout=self.timeout)
|
|
50
53
|
if self.debug:
|
|
51
54
|
print(response.content)
|
|
52
55
|
response.raise_for_status()
|
|
@@ -72,7 +75,8 @@ class AllSolutions(BrynQ):
|
|
|
72
75
|
while more_results:
|
|
73
76
|
response = requests.get(url=f"{self.url}mperso",
|
|
74
77
|
headers=self._get_headers_allsol(),
|
|
75
|
-
params=params
|
|
78
|
+
params=params,
|
|
79
|
+
timeout=self.timeout)
|
|
76
80
|
if self.debug:
|
|
77
81
|
print(response.content)
|
|
78
82
|
response.raise_for_status()
|
|
@@ -106,7 +110,8 @@ class AllSolutions(BrynQ):
|
|
|
106
110
|
while more_results:
|
|
107
111
|
response = requests.get(url=f"{self.url}mzktml",
|
|
108
112
|
headers=self._get_headers_allsol(),
|
|
109
|
-
params=params
|
|
113
|
+
params=params,
|
|
114
|
+
timeout=self.timeout)
|
|
110
115
|
if self.debug:
|
|
111
116
|
print(response.content)
|
|
112
117
|
response.raise_for_status()
|
|
@@ -121,17 +126,17 @@ class AllSolutions(BrynQ):
|
|
|
121
126
|
if sickleave_id:
|
|
122
127
|
partial_response = requests.get(
|
|
123
128
|
url=f"{self.url}mzktml/{sickleave_id}/partieelverzuim",
|
|
124
|
-
headers=self._get_headers_allsol()
|
|
129
|
+
headers=self._get_headers_allsol(),
|
|
130
|
+
timeout=self.timeout
|
|
125
131
|
)
|
|
126
132
|
partial_response.raise_for_status()
|
|
127
133
|
partial_data = partial_response.json().get('Data', [])
|
|
128
134
|
if partial_data:
|
|
129
135
|
entry['percentage'] = partial_data[0].get('ap47.prc', None)
|
|
130
136
|
|
|
131
|
-
|
|
132
137
|
return total_response
|
|
133
138
|
|
|
134
|
-
def
|
|
139
|
+
def get_detailed_sickleave(self, filter: str = None):
|
|
135
140
|
self._get_headers_allsol()
|
|
136
141
|
total_response = []
|
|
137
142
|
more_results = True
|
|
@@ -163,7 +168,6 @@ class AllSolutions(BrynQ):
|
|
|
163
168
|
sickleave_start_date = entry.get('ap46.ziektedat')
|
|
164
169
|
sickleave_end_date = entry.get('ap46.dat-hervat-arbo')
|
|
165
170
|
|
|
166
|
-
|
|
167
171
|
if sickleave_id:
|
|
168
172
|
partial_response = requests.get(
|
|
169
173
|
url=f"{self.url}mzktml/{sickleave_id}/partieelverzuim",
|
|
@@ -201,7 +205,8 @@ class AllSolutions(BrynQ):
|
|
|
201
205
|
while more_results:
|
|
202
206
|
response = requests.get(url=f"{self.url}mrlprs",
|
|
203
207
|
headers=self._get_headers_allsol(),
|
|
204
|
-
params=params
|
|
208
|
+
params=params,
|
|
209
|
+
timeout=self.timeout)
|
|
205
210
|
if self.debug:
|
|
206
211
|
print(response.content)
|
|
207
212
|
response.raise_for_status()
|
|
@@ -221,7 +226,8 @@ class AllSolutions(BrynQ):
|
|
|
221
226
|
while more_results:
|
|
222
227
|
response = requests.get(url=f"{self.url}/mappar", # Adjusted the endpoint
|
|
223
228
|
headers=self._get_headers_allsol(),
|
|
224
|
-
params=params
|
|
229
|
+
params=params,
|
|
230
|
+
timeout=self.timeout)
|
|
225
231
|
if self.debug:
|
|
226
232
|
print(response.content)
|
|
227
233
|
|
|
@@ -248,7 +254,8 @@ class AllSolutions(BrynQ):
|
|
|
248
254
|
while more_results:
|
|
249
255
|
response = requests.get(url=f"{self.url}mperso/{employee_id}/arbeidsovereenkomsten",
|
|
250
256
|
headers=self._get_headers_allsol(),
|
|
251
|
-
params=params
|
|
257
|
+
params=params,
|
|
258
|
+
timeout=self.timeout)
|
|
252
259
|
if self.debug:
|
|
253
260
|
print(response.content)
|
|
254
261
|
response.raise_for_status()
|
|
@@ -266,7 +273,8 @@ class AllSolutions(BrynQ):
|
|
|
266
273
|
while more_results:
|
|
267
274
|
response = requests.get(url=f"{self.url}mperso/{employee_id}/werktijden2wk",
|
|
268
275
|
headers=self._get_headers_allsol(),
|
|
269
|
-
params=params
|
|
276
|
+
params=params,
|
|
277
|
+
timeout=self.timeout)
|
|
270
278
|
response.raise_for_status()
|
|
271
279
|
more_results = response.json()['Paging']['More']
|
|
272
280
|
params['cursor'] = response.json()['Paging']['NextCursor']
|
|
@@ -282,7 +290,8 @@ class AllSolutions(BrynQ):
|
|
|
282
290
|
while more_results:
|
|
283
291
|
response = requests.get(url=f"{self.url}mperso/{employee_id}/manager",
|
|
284
292
|
headers=self._get_headers_allsol(),
|
|
285
|
-
params=params
|
|
293
|
+
params=params,
|
|
294
|
+
timeout=self.timeout)
|
|
286
295
|
response.raise_for_status()
|
|
287
296
|
more_results = response.json()['Paging']['More']
|
|
288
297
|
params['cursor'] = response.json()['Paging']['NextCursor']
|
|
@@ -298,7 +307,8 @@ class AllSolutions(BrynQ):
|
|
|
298
307
|
while more_results:
|
|
299
308
|
response = requests.get(url=f"{self.url}mperso/{employee_id}/functies",
|
|
300
309
|
headers=self._get_headers_allsol(),
|
|
301
|
-
params=params
|
|
310
|
+
params=params,
|
|
311
|
+
timeout=self.timeout)
|
|
302
312
|
response.raise_for_status()
|
|
303
313
|
more_results = response.json()['Paging']['More']
|
|
304
314
|
params['cursor'] = response.json()['Paging']['NextCursor']
|
|
@@ -315,14 +325,15 @@ class AllSolutions(BrynQ):
|
|
|
315
325
|
headers = self._get_headers_allsol()
|
|
316
326
|
response = requests.get(url=f"{self.url}mperso/{employee_id}/thuisafdelingen",
|
|
317
327
|
headers=headers,
|
|
318
|
-
params=params
|
|
328
|
+
params=params,
|
|
329
|
+
timeout=self.timeout)
|
|
319
330
|
response.raise_for_status()
|
|
320
331
|
more_results = response.json()['Paging']['More']
|
|
321
332
|
params['cursor'] = response.json()['Paging']['NextCursor']
|
|
322
333
|
total_response += response.json()['Data']
|
|
323
334
|
|
|
324
|
-
return total_response\
|
|
325
|
-
|
|
335
|
+
return total_response \
|
|
336
|
+
\
|
|
326
337
|
# Post functions
|
|
327
338
|
def create_employee(self, data: dict) -> json:
|
|
328
339
|
"""
|
|
@@ -359,7 +370,7 @@ class AllSolutions(BrynQ):
|
|
|
359
370
|
"ab02.ba-kd": data['costcenter'],
|
|
360
371
|
"ab02.funktie": data['function'],
|
|
361
372
|
"ab02.srt-mdw": data["employment"],
|
|
362
|
-
"h-aanw":data['hours_week'],
|
|
373
|
+
"h-aanw": data['hours_week'],
|
|
363
374
|
"h-aanw2": data['hours_week'],
|
|
364
375
|
"h-default7": True,
|
|
365
376
|
"ab02.contr-srt-kd": "1",
|
|
@@ -368,7 +379,7 @@ class AllSolutions(BrynQ):
|
|
|
368
379
|
]
|
|
369
380
|
}
|
|
370
381
|
if 'contract_end_date' in data:
|
|
371
|
-
#also add "ab02.einddat-proef" as the same date
|
|
382
|
+
# also add "ab02.einddat-proef" as the same date
|
|
372
383
|
payload['Data'][0].update({"ab02.uitdat": data['contract_end_date']})
|
|
373
384
|
# Add allowed fields to the body
|
|
374
385
|
for field in (allowed_fields.keys() & data.keys()):
|
|
@@ -437,7 +448,8 @@ class AllSolutions(BrynQ):
|
|
|
437
448
|
|
|
438
449
|
response = requests.post(url=f"{self.url}mrlprs",
|
|
439
450
|
headers=self._get_headers_allsol(),
|
|
440
|
-
data=json.dumps(payload)
|
|
451
|
+
data=json.dumps(payload),
|
|
452
|
+
timeout=self.timeout)
|
|
441
453
|
# if self.debug:
|
|
442
454
|
# print("______________________payload______________________")
|
|
443
455
|
# print(payload)
|
|
@@ -445,7 +457,6 @@ class AllSolutions(BrynQ):
|
|
|
445
457
|
# print(response.content)
|
|
446
458
|
response.raise_for_status()
|
|
447
459
|
|
|
448
|
-
|
|
449
460
|
return response
|
|
450
461
|
|
|
451
462
|
def create_timetable(self, data: dict) -> json:
|
|
@@ -481,8 +492,9 @@ class AllSolutions(BrynQ):
|
|
|
481
492
|
print(payload)
|
|
482
493
|
print(data['employee_id_afas'])
|
|
483
494
|
response = requests.post(url=f"{self.url}mperso/{data['employee_id']}/werktijden2wk",
|
|
484
|
-
|
|
485
|
-
|
|
495
|
+
headers=self._get_headers_allsol(),
|
|
496
|
+
data=json.dumps(payload),
|
|
497
|
+
timeout=self.timeout)
|
|
486
498
|
response.raise_for_status()
|
|
487
499
|
return response
|
|
488
500
|
|
|
@@ -515,7 +527,7 @@ class AllSolutions(BrynQ):
|
|
|
515
527
|
}
|
|
516
528
|
]
|
|
517
529
|
}
|
|
518
|
-
#add the uitdat field if it is present in the data
|
|
530
|
+
# add the uitdat field if it is present in the data
|
|
519
531
|
if 'contract_end_date' in data:
|
|
520
532
|
payload['Data'][0].update({"ap11.uitdat": data['contract_end_date']})
|
|
521
533
|
|
|
@@ -524,8 +536,9 @@ class AllSolutions(BrynQ):
|
|
|
524
536
|
payload['Data'][0].update({allowed_fields[field]: data[field]})
|
|
525
537
|
|
|
526
538
|
response = requests.post(url=f"{self.url}mperso/{data['employee_id']}/arbeidsovereenkomsten",
|
|
527
|
-
|
|
528
|
-
|
|
539
|
+
headers=self._get_headers_allsol(),
|
|
540
|
+
data=json.dumps(payload),
|
|
541
|
+
timeout=self.timeout)
|
|
529
542
|
if self.debug:
|
|
530
543
|
print(response.content)
|
|
531
544
|
print(payload)
|
|
@@ -554,7 +567,8 @@ class AllSolutions(BrynQ):
|
|
|
554
567
|
|
|
555
568
|
response = requests.post(url=f"{self.url}mperso/{data['employee_id']}/thuisafdelingen",
|
|
556
569
|
headers=self._get_headers_allsol(),
|
|
557
|
-
data=json.dumps(payload)
|
|
570
|
+
data=json.dumps(payload),
|
|
571
|
+
timeout=self.timeout)
|
|
558
572
|
if self.debug:
|
|
559
573
|
print(response.content)
|
|
560
574
|
print(payload)
|
|
@@ -590,11 +604,10 @@ class AllSolutions(BrynQ):
|
|
|
590
604
|
for field in (allowed_fields.keys() & data.keys()):
|
|
591
605
|
payload['Data'][0].update({allowed_fields[field]: data[field]})
|
|
592
606
|
|
|
593
|
-
|
|
594
|
-
|
|
595
607
|
response = requests.post(url=f"{self.url}mperso/{data['employee_id']}/functies",
|
|
596
608
|
headers=self._get_headers_allsol(),
|
|
597
|
-
data=json.dumps(payload)
|
|
609
|
+
data=json.dumps(payload),
|
|
610
|
+
timeout=self.timeout)
|
|
598
611
|
if self.debug:
|
|
599
612
|
print(response.content)
|
|
600
613
|
print(payload)
|
|
@@ -622,7 +635,6 @@ class AllSolutions(BrynQ):
|
|
|
622
635
|
# "ap46.dat-meld-arbo": data['start_date'],
|
|
623
636
|
"ap46.opm": f"Afas koppeling {data['sickleave_code_afas']}"
|
|
624
637
|
|
|
625
|
-
|
|
626
638
|
}
|
|
627
639
|
]
|
|
628
640
|
}
|
|
@@ -638,7 +650,8 @@ class AllSolutions(BrynQ):
|
|
|
638
650
|
|
|
639
651
|
response = requests.post(url=url,
|
|
640
652
|
headers=self._get_headers_allsol(),
|
|
641
|
-
data=json.dumps(payload)
|
|
653
|
+
data=json.dumps(payload),
|
|
654
|
+
timeout=self.timeout)
|
|
642
655
|
return response
|
|
643
656
|
|
|
644
657
|
def create_partial_sickleave(self, data):
|
|
@@ -724,7 +737,8 @@ class AllSolutions(BrynQ):
|
|
|
724
737
|
response = requests.put(
|
|
725
738
|
url=f"{self.url}{url}",
|
|
726
739
|
headers=self._get_headers_allsol(),
|
|
727
|
-
data=json.dumps(payload)
|
|
740
|
+
data=json.dumps(payload),
|
|
741
|
+
timeout=self.timeout
|
|
728
742
|
)
|
|
729
743
|
# Return the response (JSON)
|
|
730
744
|
return response
|
|
@@ -744,7 +758,7 @@ class AllSolutions(BrynQ):
|
|
|
744
758
|
for field in (allowed_fields.keys() & data.keys()):
|
|
745
759
|
payload['Data'][0].update({allowed_fields[field]: data[field]})
|
|
746
760
|
|
|
747
|
-
response = requests.post(url=f"{self.url}mperso/{data['employee_id']}/manager", headers=self._get_headers_allsol(), data=json.dumps(payload))
|
|
761
|
+
response = requests.post(url=f"{self.url}mperso/{data['employee_id']}/manager", headers=self._get_headers_allsol(), data=json.dumps(payload), timeout=self.timeout)
|
|
748
762
|
if self.debug:
|
|
749
763
|
print(response.content)
|
|
750
764
|
print(payload)
|
|
@@ -783,7 +797,8 @@ class AllSolutions(BrynQ):
|
|
|
783
797
|
print(data['employee_id_afas'])
|
|
784
798
|
response = requests.put(url=f"{self.url}mperso/{data['employee_id']}/werktijden2wk/{data['timetable_id']}",
|
|
785
799
|
headers=self._get_headers_allsol(),
|
|
786
|
-
data=json.dumps(payload)
|
|
800
|
+
data=json.dumps(payload),
|
|
801
|
+
timeout=self.timeout)
|
|
787
802
|
response.raise_for_status()
|
|
788
803
|
return response
|
|
789
804
|
|
|
@@ -814,8 +829,9 @@ class AllSolutions(BrynQ):
|
|
|
814
829
|
payload['Data'][0].update({allowed_fields[field]: data[field]})
|
|
815
830
|
|
|
816
831
|
response = requests.put(url=f"{self.url}mperso/{data['employee_id']}/arbeidsovereenkomsten/{data['contract_id']}",
|
|
817
|
-
|
|
818
|
-
|
|
832
|
+
headers=self._get_headers_allsol(),
|
|
833
|
+
data=json.dumps(payload),
|
|
834
|
+
timeout=self.timeout)
|
|
819
835
|
if self.debug:
|
|
820
836
|
print(response.content)
|
|
821
837
|
print(payload)
|
|
@@ -867,7 +883,8 @@ class AllSolutions(BrynQ):
|
|
|
867
883
|
|
|
868
884
|
response = requests.put(url=f"{self.url}mperso/{data['employee_id']}",
|
|
869
885
|
headers=self._get_headers_allsol(),
|
|
870
|
-
data=json.dumps(payload)
|
|
886
|
+
data=json.dumps(payload),
|
|
887
|
+
timeout=self.timeout)
|
|
871
888
|
if self.debug:
|
|
872
889
|
print(response.content)
|
|
873
890
|
print(payload)
|
|
@@ -921,7 +938,8 @@ class AllSolutions(BrynQ):
|
|
|
921
938
|
|
|
922
939
|
response = requests.put(url=f"{self.url}mrlprs/{data['person_id']}",
|
|
923
940
|
headers=self._get_headers_allsol(),
|
|
924
|
-
data=json.dumps(payload)
|
|
941
|
+
data=json.dumps(payload),
|
|
942
|
+
timeout=self.timeout)
|
|
925
943
|
if self.debug:
|
|
926
944
|
print(response.content)
|
|
927
945
|
print(payload)
|
|
@@ -958,8 +976,9 @@ class AllSolutions(BrynQ):
|
|
|
958
976
|
payload['Data'][0].update({allowed_fields[field]: data[field]})
|
|
959
977
|
|
|
960
978
|
response = requests.put(url=f"{self.url}mperso/{data['employee_id']}/thuisafdelingen/{data['costcenter_id']}",
|
|
961
|
-
|
|
962
|
-
|
|
979
|
+
headers=self._get_headers_allsol(),
|
|
980
|
+
data=json.dumps(payload),
|
|
981
|
+
timeout=self.timeout)
|
|
963
982
|
if self.debug:
|
|
964
983
|
print(response.content)
|
|
965
984
|
print(payload)
|
|
@@ -994,11 +1013,10 @@ class AllSolutions(BrynQ):
|
|
|
994
1013
|
for field in (allowed_fields.keys() & data.keys()):
|
|
995
1014
|
payload['Data'][0].update({allowed_fields[field]: data[field]})
|
|
996
1015
|
|
|
997
|
-
|
|
998
|
-
|
|
999
1016
|
response = requests.put(url=f"{self.url}mperso/{data['employee_id']}/functies/{data['function_id']}",
|
|
1000
|
-
|
|
1001
|
-
|
|
1017
|
+
headers=self._get_headers_allsol(),
|
|
1018
|
+
data=json.dumps(payload),
|
|
1019
|
+
timeout=self.timeout)
|
|
1002
1020
|
if self.debug:
|
|
1003
1021
|
print(response.content)
|
|
1004
1022
|
print(payload)
|
|
@@ -1026,7 +1044,8 @@ class AllSolutions(BrynQ):
|
|
|
1026
1044
|
print(json.dumps(payload))
|
|
1027
1045
|
response = requests.post(url=f"{self.url}mperso/{data['employee_id']}/Tijdelijkewerktijden",
|
|
1028
1046
|
headers=self._get_headers_allsol(),
|
|
1029
|
-
data=json.dumps(payload)
|
|
1047
|
+
data=json.dumps(payload),
|
|
1048
|
+
timeout=self.timeout)
|
|
1030
1049
|
if self.debug:
|
|
1031
1050
|
print(response.content)
|
|
1032
1051
|
response.raise_for_status()
|
|
@@ -1053,7 +1072,8 @@ class AllSolutions(BrynQ):
|
|
|
1053
1072
|
print(json.dumps(payload))
|
|
1054
1073
|
response = requests.post(url=f"{self.url}mperso/{data['employee_id']}/arbeidsovereenkomsten/{data['id']}",
|
|
1055
1074
|
headers=self._get_headers_allsol(),
|
|
1056
|
-
data=json.dumps(payload)
|
|
1075
|
+
data=json.dumps(payload),
|
|
1076
|
+
timeout=self.timeout)
|
|
1057
1077
|
if self.debug:
|
|
1058
1078
|
print(response.content)
|
|
1059
1079
|
response.raise_for_status()
|
|
@@ -1086,7 +1106,8 @@ class AllSolutions(BrynQ):
|
|
|
1086
1106
|
|
|
1087
1107
|
response = requests.put(url=f"{self.url}mzktml/{data['sickleave_id']}",
|
|
1088
1108
|
headers=self._get_headers_allsol(),
|
|
1089
|
-
data=json.dumps(payload)
|
|
1109
|
+
data=json.dumps(payload),
|
|
1110
|
+
timeout=self.timeout)
|
|
1090
1111
|
response.raise_for_status()
|
|
1091
1112
|
return response
|
|
1092
1113
|
|
|
@@ -1115,7 +1136,7 @@ def format_dates(df: pd.DataFrame, date_cols: List[str]) -> pd.DataFrame:
|
|
|
1115
1136
|
|
|
1116
1137
|
|
|
1117
1138
|
def build_unique_key(
|
|
1118
|
-
|
|
1139
|
+
df: pd.DataFrame, *, id_col: str, date_col: str, key_col: str
|
|
1119
1140
|
) -> pd.DataFrame:
|
|
1120
1141
|
"""
|
|
1121
1142
|
Construct a textual unique key of the form <id>_<YYYY‑MM‑DD>.
|
|
@@ -1132,9 +1153,9 @@ def build_unique_key(
|
|
|
1132
1153
|
# OPTIONAL: duplicate‑partial‑rows logger
|
|
1133
1154
|
# ---------------------------------------------------------------------------
|
|
1134
1155
|
def log_duplicate_partials(
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1156
|
+
df_partial: pd.DataFrame,
|
|
1157
|
+
write_log: Callable[[str], None],
|
|
1158
|
+
subset: str | List[str] = "unique_key_partial",
|
|
1138
1159
|
) -> None:
|
|
1139
1160
|
"""
|
|
1140
1161
|
Detect rows that share the same *subset* key(s) and send a readable
|
|
@@ -1152,10 +1173,10 @@ def log_duplicate_partials(
|
|
|
1152
1173
|
dupes = df_partial[df_partial.duplicated(subset=subset, keep=False)]
|
|
1153
1174
|
for _, row in dupes.iterrows():
|
|
1154
1175
|
write_log(message=
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
)
|
|
1176
|
+
(
|
|
1177
|
+
"Duplicate partial sick‑leave record — "
|
|
1178
|
+
f"employee_id_afas={row.get('employee_id_afas')} "
|
|
1179
|
+
f"employee_code={row.get('employee_code')} "
|
|
1180
|
+
f"key={row.get(subset)}"
|
|
1181
|
+
), data=None, loglevel="INFO"
|
|
1182
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|