MambuPy 2.4.0__tar.gz → 2.5.0__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.
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/__init__.py +1 -1
- {mambupy-2.4.0/mambupy → mambupy-2.5.0/MambuPy}/api/__init__.py +1 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/connector/mambuconnector.py +70 -0
- {mambupy-2.4.0/mambupy → mambupy-2.5.0/MambuPy}/api/connector/rest.py +20 -2
- mambupy-2.5.0/MambuPy/api/connector/rest_holidays.py +133 -0
- mambupy-2.5.0/MambuPy/api/mambuholiday.py +272 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/vos.py +9 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/PKG-INFO +1 -1
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/SOURCES.txt +4 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/PKG-INFO +1 -1
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/__init__.py +1 -1
- {mambupy-2.4.0/MambuPy → mambupy-2.5.0/mambupy}/api/__init__.py +1 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/connector/mambuconnector.py +70 -0
- {mambupy-2.4.0/MambuPy → mambupy-2.5.0/mambupy}/api/connector/rest.py +20 -2
- mambupy-2.5.0/mambupy/api/connector/rest_holidays.py +133 -0
- mambupy-2.5.0/mambupy/api/mambuholiday.py +272 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/vos.py +9 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/LICENSE +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/classes.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/connector/__init__.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/connector/rest_helpers.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/entities.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/interfaces.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambubranch.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambucentre.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambuclient.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambucustomfield.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambugroup.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambuloan.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambuproduct.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mamburole.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambustruct.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambutask.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambutransaction.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambuuser.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/mambuconfig.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/mambugeturl.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/mambuutil.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/__init__.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_activities.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_addresses.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_branches.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_centres.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_clients.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_customfields.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_dummies.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_groups.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_loans.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_mambu.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_orm.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_tasks.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_users.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/rest/__init__.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/rest/mambuactivity.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/utils/__init__.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/utils/update_user_roles.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/utils/userdeactivate.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/dependency_links.txt +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/requires.txt +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/top_level.txt +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/README.md +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/classes.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/connector/__init__.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/connector/rest_helpers.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/entities.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/interfaces.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambubranch.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambucentre.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambuclient.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambucustomfield.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambugroup.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambuloan.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambuproduct.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mamburole.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambustruct.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambutask.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambutransaction.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambuuser.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/mambuconfig.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/mambugeturl.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/mambuutil.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/__init__.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_activities.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_addresses.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_branches.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_centres.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_clients.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_customfields.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_dummies.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_groups.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_loans.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_mambu.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_orm.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_tasks.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_users.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/rest/__init__.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/rest/mambuactivity.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/utils/__init__.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/utils/update_user_roles.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/utils/userdeactivate.py +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/pyproject.toml +0 -0
- {mambupy-2.4.0 → mambupy-2.5.0}/setup.cfg +0 -0
|
@@ -138,6 +138,28 @@ class MambuConnectorReader(ABC):
|
|
|
138
138
|
"""
|
|
139
139
|
raise NotImplementedError
|
|
140
140
|
|
|
141
|
+
@abstractmethod
|
|
142
|
+
def mambu_organization_get_holidays(self):
|
|
143
|
+
"""Retrieves the holidays of the organization.
|
|
144
|
+
|
|
145
|
+
Both the general holidays and the non-working days of the week.
|
|
146
|
+
"""
|
|
147
|
+
raise NotImplementedError
|
|
148
|
+
|
|
149
|
+
@abstractmethod
|
|
150
|
+
def mambu_organization_get_non_working_days(self):
|
|
151
|
+
"""Retrieves the non-working days of the week of the organization."""
|
|
152
|
+
raise NotImplementedError
|
|
153
|
+
|
|
154
|
+
@abstractmethod
|
|
155
|
+
def mambu_organization_get_holiday(self, holidayid):
|
|
156
|
+
"""Retrieves a single general holiday of the organization.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
holidayid (str): the id or encoded key of the holiday
|
|
160
|
+
"""
|
|
161
|
+
raise NotImplementedError
|
|
162
|
+
|
|
141
163
|
|
|
142
164
|
class MambuConnectorWriter(ABC):
|
|
143
165
|
"""Interface for Writers.
|
|
@@ -326,3 +348,51 @@ class MambuConnectorWriter(ABC):
|
|
|
326
348
|
notes (str): notes to associate to the transaction adjustment in Mambu
|
|
327
349
|
"""
|
|
328
350
|
raise NotImplementedError
|
|
351
|
+
|
|
352
|
+
@abstractmethod
|
|
353
|
+
def mambu_organization_update_holidays(self, holidays):
|
|
354
|
+
"""Updates the holidays of the organization
|
|
355
|
+
|
|
356
|
+
Mambu replaces the whole configuration with the one given, so the
|
|
357
|
+
complete set of holidays and non-working days must be sent, not just
|
|
358
|
+
the modified ones.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
holidays (dict): holidays of the organization, complying with
|
|
362
|
+
Mambu's schema
|
|
363
|
+
"""
|
|
364
|
+
raise NotImplementedError
|
|
365
|
+
|
|
366
|
+
@abstractmethod
|
|
367
|
+
def mambu_organization_update_non_working_days(self, nonWorkingDays):
|
|
368
|
+
"""Updates the non-working days of the week of the organization
|
|
369
|
+
|
|
370
|
+
Mambu replaces the whole set with the days given.
|
|
371
|
+
|
|
372
|
+
Args:
|
|
373
|
+
nonWorkingDays (list of str): days of the week on which the
|
|
374
|
+
organization does not operate
|
|
375
|
+
"""
|
|
376
|
+
raise NotImplementedError
|
|
377
|
+
|
|
378
|
+
@abstractmethod
|
|
379
|
+
def mambu_organization_create_holidays(self, holidays):
|
|
380
|
+
"""Creates general holidays for the organization
|
|
381
|
+
|
|
382
|
+
Mambu adds them to the ones already configured, all in a single
|
|
383
|
+
request.
|
|
384
|
+
|
|
385
|
+
Args:
|
|
386
|
+
holidays (list of dict): the holidays to create, complying with
|
|
387
|
+
Mambu's schema
|
|
388
|
+
"""
|
|
389
|
+
raise NotImplementedError
|
|
390
|
+
|
|
391
|
+
@abstractmethod
|
|
392
|
+
def mambu_organization_delete_holiday(self, holidayid):
|
|
393
|
+
"""Deletes a general holiday of the organization
|
|
394
|
+
|
|
395
|
+
Args:
|
|
396
|
+
holidayid (str): the id of the holiday to be deleted
|
|
397
|
+
"""
|
|
398
|
+
raise NotImplementedError
|
|
@@ -21,6 +21,7 @@ from requests_toolbelt.multipart.encoder import MultipartEncoder
|
|
|
21
21
|
|
|
22
22
|
from .mambuconnector import MambuConnector, MambuConnectorReader, MambuConnectorWriter
|
|
23
23
|
from .rest_helpers import _MambuJSONEncoder, _configure_retry_strategy
|
|
24
|
+
from .rest_holidays import MambuConnectorRESTHolidays
|
|
24
25
|
from MambuPy.mambuutil import (
|
|
25
26
|
ALLOWED_UPLOAD_MIMETYPES,
|
|
26
27
|
DETAILSLEVEL,
|
|
@@ -85,8 +86,17 @@ class SessionSingleton:
|
|
|
85
86
|
return self.__session
|
|
86
87
|
|
|
87
88
|
|
|
88
|
-
class MambuConnectorREST(
|
|
89
|
-
|
|
89
|
+
class MambuConnectorREST(
|
|
90
|
+
MambuConnectorRESTHolidays,
|
|
91
|
+
MambuConnector,
|
|
92
|
+
MambuConnectorReader,
|
|
93
|
+
MambuConnectorWriter,
|
|
94
|
+
):
|
|
95
|
+
"""A connector for Mambu REST API
|
|
96
|
+
|
|
97
|
+
Endpoint mixins come first: their implementations must win over the
|
|
98
|
+
abstract methods the interfaces declare for them.
|
|
99
|
+
"""
|
|
90
100
|
|
|
91
101
|
_RETRIES = 5
|
|
92
102
|
_tenant = ""
|
|
@@ -240,6 +250,14 @@ url %s, params %s, data %s, headers %s",
|
|
|
240
250
|
|
|
241
251
|
return resp.content
|
|
242
252
|
|
|
253
|
+
_request = __request
|
|
254
|
+
"""protected alias of the private request method
|
|
255
|
+
|
|
256
|
+
Name mangling resolves ``__request`` against the class where it is
|
|
257
|
+
written, so it is out of reach for an endpoint mixin living in another
|
|
258
|
+
module. Those mixins call this alias instead.
|
|
259
|
+
"""
|
|
260
|
+
|
|
243
261
|
def __list_request_args(self, params):
|
|
244
262
|
if not params:
|
|
245
263
|
params = {}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""Holidays endpoints for the REST connector.
|
|
2
|
+
|
|
3
|
+
.. autosummary::
|
|
4
|
+
:nosignatures:
|
|
5
|
+
:toctree: _autosummary
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MambuConnectorRESTHolidays:
|
|
10
|
+
"""Holidays endpoints of the organization.
|
|
11
|
+
|
|
12
|
+
A mixin, not a connector of its own: it builds the URLs and leans on the
|
|
13
|
+
request machinery of
|
|
14
|
+
:py:obj:`MambuPy.api.connector.rest.MambuConnectorREST`, the class that
|
|
15
|
+
mixes it in.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def mambu_organization_get_holidays(self):
|
|
19
|
+
"""Retrieves the holidays of the organization.
|
|
20
|
+
|
|
21
|
+
Both the general holidays and the non-working days of the week.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
response content (str json {})
|
|
25
|
+
"""
|
|
26
|
+
url = "https://{}/api/organization/holidays".format(self._tenant)
|
|
27
|
+
|
|
28
|
+
return self._request("GET", url)
|
|
29
|
+
|
|
30
|
+
def mambu_organization_update_holidays(self, holidays):
|
|
31
|
+
"""Updates the holidays of the organization
|
|
32
|
+
|
|
33
|
+
Mambu replaces the whole configuration with the one given, so the
|
|
34
|
+
complete set of holidays and non-working days must be sent, not just
|
|
35
|
+
the modified ones.
|
|
36
|
+
|
|
37
|
+
Mambu processes holidays asynchronously: this fails with errorCode
|
|
38
|
+
3633, ANOTHER_TASK_IN_PROGRESS, while a previous holidays operation
|
|
39
|
+
is still running. The error is transient and is not retried here.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
holidays (dict): holidays of the organization, complying with
|
|
43
|
+
Mambu's schema
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
response content (str json {})
|
|
47
|
+
"""
|
|
48
|
+
url = "https://{}/api/organization/holidays".format(self._tenant)
|
|
49
|
+
|
|
50
|
+
return self._request("PUT", url, data=holidays)
|
|
51
|
+
|
|
52
|
+
def mambu_organization_get_non_working_days(self):
|
|
53
|
+
"""Retrieves the non-working days of the week of the organization.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
response content (str json {})
|
|
57
|
+
"""
|
|
58
|
+
url = "https://{}/api/organization/holidays/nonworkingdays".format(self._tenant)
|
|
59
|
+
|
|
60
|
+
return self._request("GET", url)
|
|
61
|
+
|
|
62
|
+
def mambu_organization_update_non_working_days(self, nonWorkingDays):
|
|
63
|
+
"""Updates the non-working days of the week of the organization
|
|
64
|
+
|
|
65
|
+
Mambu replaces the whole set with the days given.
|
|
66
|
+
|
|
67
|
+
Mambu processes holidays asynchronously: this fails with errorCode
|
|
68
|
+
3633, ANOTHER_TASK_IN_PROGRESS, while a previous holidays operation
|
|
69
|
+
is still running. The error is transient and is not retried here.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
nonWorkingDays (list of str): days of the week on which the
|
|
73
|
+
organization does not operate
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
response content (str json {})
|
|
77
|
+
"""
|
|
78
|
+
url = "https://{}/api/organization/holidays/nonworkingdays".format(self._tenant)
|
|
79
|
+
data = {"nonWorkingDays": nonWorkingDays}
|
|
80
|
+
|
|
81
|
+
return self._request("PUT", url, data=data)
|
|
82
|
+
|
|
83
|
+
def mambu_organization_create_holidays(self, holidays):
|
|
84
|
+
"""Creates general holidays for the organization
|
|
85
|
+
|
|
86
|
+
Mambu adds them to the ones already configured, all in a single
|
|
87
|
+
request.
|
|
88
|
+
|
|
89
|
+
Mambu processes holidays asynchronously: this fails with errorCode
|
|
90
|
+
3633, ANOTHER_TASK_IN_PROGRESS, while a previous holidays operation
|
|
91
|
+
is still running. The error is transient and is not retried here.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
holidays (list of dict): the holidays to create, complying with
|
|
95
|
+
Mambu's schema
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
response content (str json [])
|
|
99
|
+
"""
|
|
100
|
+
url = "https://{}/api/organization/holidays/general".format(self._tenant)
|
|
101
|
+
|
|
102
|
+
return self._request("POST", url, data=holidays)
|
|
103
|
+
|
|
104
|
+
def mambu_organization_get_holiday(self, holidayid):
|
|
105
|
+
"""Retrieves a single general holiday of the organization.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
holidayid (str): the id or encoded key of the holiday
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
response content (str json {})
|
|
112
|
+
"""
|
|
113
|
+
url = "https://{}/api/organization/holidays/general/{}".format(
|
|
114
|
+
self._tenant, holidayid
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
return self._request("GET", url)
|
|
118
|
+
|
|
119
|
+
def mambu_organization_delete_holiday(self, holidayid):
|
|
120
|
+
"""Deletes a general holiday of the organization
|
|
121
|
+
|
|
122
|
+
Mambu processes holidays asynchronously: this fails with errorCode
|
|
123
|
+
3633, ANOTHER_TASK_IN_PROGRESS, while a previous holidays operation
|
|
124
|
+
is still running. The error is transient and is not retried here.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
holidayid (str): the id of the holiday to be deleted
|
|
128
|
+
"""
|
|
129
|
+
url = "https://{}/api/organization/holidays/general/{}".format(
|
|
130
|
+
self._tenant, holidayid
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
return self._request("DELETE", url)
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"""MambuHolidays: the holidays configuration of the organization.
|
|
2
|
+
|
|
3
|
+
.. autosummary::
|
|
4
|
+
:nosignatures:
|
|
5
|
+
:toctree: _autosummary
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import copy
|
|
9
|
+
|
|
10
|
+
import orjson
|
|
11
|
+
|
|
12
|
+
from .connector.rest import MambuConnectorREST
|
|
13
|
+
from .mambustruct import MambuStruct
|
|
14
|
+
from .vos import MambuHoliday
|
|
15
|
+
from MambuPy.mambuutil import MambuPyError
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class MambuHolidays(MambuStruct):
|
|
19
|
+
"""The holidays of the organization.
|
|
20
|
+
|
|
21
|
+
Holds the general holidays, a list of
|
|
22
|
+
:py:obj:`MambuPy.api.vos.MambuHoliday`, and the non-working days of the
|
|
23
|
+
week: the two halves of Mambu's organization wide holidays configuration.
|
|
24
|
+
|
|
25
|
+
This is not a :py:obj:`MambuPy.api.entities.MambuEntity`, because Mambu
|
|
26
|
+
does not expose the holidays as one: there is a single configuration for
|
|
27
|
+
the whole organization, with no id to get one by, nothing to list and
|
|
28
|
+
nothing to search. What it does offer is adding and removing single
|
|
29
|
+
holidays, given here as methods over the configuration they belong to.
|
|
30
|
+
|
|
31
|
+
Getting the configuration is the usual entry point::
|
|
32
|
+
|
|
33
|
+
holidays = MambuHolidays.get()
|
|
34
|
+
|
|
35
|
+
Operating single holidays doesn't need it, an instance with no data is
|
|
36
|
+
enough to reach Mambu::
|
|
37
|
+
|
|
38
|
+
holiday = MambuHolidays().get_holiday("1")
|
|
39
|
+
|
|
40
|
+
Mambu processes holidays asynchronously: a write answers before the change
|
|
41
|
+
is fully applied, and any holidays operation sent while a previous one is
|
|
42
|
+
still running is rejected with errorCode 3633, ANOTHER_TASK_IN_PROGRESS.
|
|
43
|
+
The error is transient, it only means Mambu is still busy, and MambuPy does
|
|
44
|
+
not retry on its own: whether and when to try again is left to the caller.
|
|
45
|
+
Seen on a sandbox tenant, where a delete issued right after a create needed
|
|
46
|
+
around thirty seconds of waiting before it went through.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
_connector = None
|
|
50
|
+
"""Default connector (REST)"""
|
|
51
|
+
|
|
52
|
+
_vos = [("holidays", "MambuHoliday")]
|
|
53
|
+
"""2-tuples of elements and Value Objects"""
|
|
54
|
+
|
|
55
|
+
_accepted_non_working_days = [
|
|
56
|
+
"MONDAY",
|
|
57
|
+
"TUESDAY",
|
|
58
|
+
"WEDNESDAY",
|
|
59
|
+
"THURSDAY",
|
|
60
|
+
"FRIDAY",
|
|
61
|
+
"SATURDAY",
|
|
62
|
+
"SUNDAY",
|
|
63
|
+
]
|
|
64
|
+
"""days of the week accepted by Mambu as non-working days"""
|
|
65
|
+
|
|
66
|
+
def __init__(self, **kwargs):
|
|
67
|
+
super().__init__(**kwargs)
|
|
68
|
+
if "connector" not in kwargs:
|
|
69
|
+
self._connector = MambuConnectorREST(**kwargs)
|
|
70
|
+
else:
|
|
71
|
+
self._connector = kwargs["connector"]
|
|
72
|
+
|
|
73
|
+
def __repr__(self):
|
|
74
|
+
"""Prints class, number of holidays and the non-working days"""
|
|
75
|
+
try:
|
|
76
|
+
return self.__class__.__name__ + " - holidays: %s, nonWorkingDays: %s" % (
|
|
77
|
+
len(self._attrs["holidays"]),
|
|
78
|
+
self._attrs["nonWorkingDays"],
|
|
79
|
+
)
|
|
80
|
+
except Exception:
|
|
81
|
+
return super().__repr__()
|
|
82
|
+
|
|
83
|
+
@staticmethod
|
|
84
|
+
def _build_holiday(attrs):
|
|
85
|
+
"""Builds a MambuHoliday from the attrs of a Mambu response.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
attrs (dict): the values of a single holiday.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
instance of :py:obj:`MambuPy.api.vos.MambuHoliday`
|
|
92
|
+
"""
|
|
93
|
+
holiday = MambuHoliday(**attrs)
|
|
94
|
+
holiday._tzattrs = copy.deepcopy(attrs)
|
|
95
|
+
holiday._convertDict2Attrs()
|
|
96
|
+
|
|
97
|
+
return holiday
|
|
98
|
+
|
|
99
|
+
def _hydrate(self, resp):
|
|
100
|
+
"""Builds the holidays configuration from a Mambu response.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
resp (bytes): a Mambu response holding a holidays configuration.
|
|
104
|
+
"""
|
|
105
|
+
self._attrs = dict(orjson.loads(resp.decode()))
|
|
106
|
+
self._tzattrs = dict(orjson.loads(resp.decode()))
|
|
107
|
+
self._convertDict2Attrs()
|
|
108
|
+
self._extractVOs()
|
|
109
|
+
|
|
110
|
+
@classmethod
|
|
111
|
+
def get(cls, **kwargs):
|
|
112
|
+
"""get the holidays of the organization.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
kwargs (dict): keyword arguments for this method.
|
|
116
|
+
May include a user, pwd and url to connect to Mambu.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
instance of MambuHolidays with data from Mambu
|
|
120
|
+
"""
|
|
121
|
+
connector = MambuConnectorREST(**kwargs)
|
|
122
|
+
instance = cls(connector=connector)
|
|
123
|
+
instance._hydrate(connector.mambu_organization_get_holidays())
|
|
124
|
+
|
|
125
|
+
return instance
|
|
126
|
+
|
|
127
|
+
def refresh(self, **kwargs):
|
|
128
|
+
"""get again the holidays of the organization.
|
|
129
|
+
|
|
130
|
+
Updates _attrs with responded data, losing any local change.
|
|
131
|
+
"""
|
|
132
|
+
self._hydrate(self._connector.mambu_organization_get_holidays())
|
|
133
|
+
|
|
134
|
+
def update(self, **kwargs):
|
|
135
|
+
"""Request to update the holidays of the organization.
|
|
136
|
+
|
|
137
|
+
Mambu replaces the whole configuration with what is sent, so the
|
|
138
|
+
complete set of holidays and non-working days is written, not just
|
|
139
|
+
the modified ones: dropping a holiday from the list deletes it.
|
|
140
|
+
|
|
141
|
+
kwargs (dict): keyword arguments for this method.
|
|
142
|
+
|
|
143
|
+
Raises:
|
|
144
|
+
`MambuError`: errorCode 3633, ANOTHER_TASK_IN_PROGRESS, if Mambu is
|
|
145
|
+
still processing a previous holidays operation. It is
|
|
146
|
+
transient, retrying is up to the caller.
|
|
147
|
+
"""
|
|
148
|
+
self._updateVOs()
|
|
149
|
+
self._serializeFields()
|
|
150
|
+
try:
|
|
151
|
+
resp = self._connector.mambu_organization_update_holidays(
|
|
152
|
+
copy.deepcopy(self._attrs)
|
|
153
|
+
)
|
|
154
|
+
finally:
|
|
155
|
+
self._convertDict2Attrs()
|
|
156
|
+
self._extractVOs()
|
|
157
|
+
|
|
158
|
+
self._hydrate(resp)
|
|
159
|
+
|
|
160
|
+
def get_non_working_days(self, **kwargs):
|
|
161
|
+
"""get the non-working days of the week of the organization.
|
|
162
|
+
|
|
163
|
+
Updates nonWorkingDays with responded data.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
list of str, the days of the week on which the organization does
|
|
167
|
+
not operate
|
|
168
|
+
"""
|
|
169
|
+
resp = self._connector.mambu_organization_get_non_working_days()
|
|
170
|
+
self._attrs["nonWorkingDays"] = orjson.loads(resp.decode())["nonWorkingDays"]
|
|
171
|
+
|
|
172
|
+
return self._attrs["nonWorkingDays"]
|
|
173
|
+
|
|
174
|
+
def update_non_working_days(self, nonWorkingDays=None, **kwargs):
|
|
175
|
+
"""Request to update the non-working days of the week.
|
|
176
|
+
|
|
177
|
+
Mambu replaces the whole set with the days sent.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
nonWorkingDays (list of str): days of the week on which the
|
|
181
|
+
organization does not operate. Defaults to the days
|
|
182
|
+
currently held by this configuration.
|
|
183
|
+
|
|
184
|
+
Raises:
|
|
185
|
+
`MambuPyError`: if a day is not in _accepted_non_working_days
|
|
186
|
+
`MambuError`: errorCode 3633, ANOTHER_TASK_IN_PROGRESS, if Mambu is
|
|
187
|
+
still processing a previous holidays operation. It is
|
|
188
|
+
transient, retrying is up to the caller.
|
|
189
|
+
"""
|
|
190
|
+
if nonWorkingDays is None:
|
|
191
|
+
nonWorkingDays = self._attrs.get("nonWorkingDays", [])
|
|
192
|
+
|
|
193
|
+
for day in nonWorkingDays:
|
|
194
|
+
if day not in self._accepted_non_working_days:
|
|
195
|
+
raise MambuPyError(
|
|
196
|
+
"day {} not in allowed _accepted_non_working_days: {}".format(
|
|
197
|
+
day, self._accepted_non_working_days
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
resp = self._connector.mambu_organization_update_non_working_days(
|
|
202
|
+
list(nonWorkingDays)
|
|
203
|
+
)
|
|
204
|
+
self._attrs["nonWorkingDays"] = orjson.loads(resp.decode())["nonWorkingDays"]
|
|
205
|
+
|
|
206
|
+
def get_holiday(self, holidayid, **kwargs):
|
|
207
|
+
"""get a single general holiday, identified by its holidayid.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
holidayid (str): the id or encoded key of the holiday
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
instance of :py:obj:`MambuPy.api.vos.MambuHoliday` with data from
|
|
214
|
+
Mambu
|
|
215
|
+
"""
|
|
216
|
+
resp = self._connector.mambu_organization_get_holiday(holidayid)
|
|
217
|
+
|
|
218
|
+
return self._build_holiday(dict(orjson.loads(resp.decode())))
|
|
219
|
+
|
|
220
|
+
def add_holidays(self, holidays, **kwargs):
|
|
221
|
+
"""Request to add general holidays to the organization.
|
|
222
|
+
|
|
223
|
+
Mambu creates them all in a single request, adding them to the ones
|
|
224
|
+
already configured, unlike `update`, which replaces everything.
|
|
225
|
+
|
|
226
|
+
The holidays given are serialized on a copy, so the caller's objects
|
|
227
|
+
keep their datetimes instead of being turned into strings.
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
holidays (list of :py:obj:`MambuPy.api.vos.MambuHoliday`): the
|
|
231
|
+
holidays to create.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
list of :py:obj:`MambuPy.api.vos.MambuHoliday`, the created holidays
|
|
235
|
+
as Mambu returned them
|
|
236
|
+
|
|
237
|
+
Raises:
|
|
238
|
+
`MambuError`: errorCode 3633, ANOTHER_TASK_IN_PROGRESS, if Mambu is
|
|
239
|
+
still processing a previous holidays operation. It is
|
|
240
|
+
transient, retrying is up to the caller.
|
|
241
|
+
"""
|
|
242
|
+
payload = []
|
|
243
|
+
for holiday in holidays:
|
|
244
|
+
serialized = copy.deepcopy(holiday)
|
|
245
|
+
serialized._serializeFields()
|
|
246
|
+
payload.append(serialized._attrs)
|
|
247
|
+
|
|
248
|
+
resp = self._connector.mambu_organization_create_holidays(payload)
|
|
249
|
+
created = [
|
|
250
|
+
self._build_holiday(holiday) for holiday in orjson.loads(resp.decode())
|
|
251
|
+
]
|
|
252
|
+
|
|
253
|
+
self.refresh()
|
|
254
|
+
|
|
255
|
+
return created
|
|
256
|
+
|
|
257
|
+
def delete_holiday(self, holidayid, **kwargs):
|
|
258
|
+
"""Request to delete a general holiday of the organization.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
holidayid (str): the id of the holiday to be deleted. Mambu does not
|
|
262
|
+
accept an encoded key here.
|
|
263
|
+
|
|
264
|
+
Raises:
|
|
265
|
+
`MambuError`: errorCode 3633, ANOTHER_TASK_IN_PROGRESS, if Mambu is
|
|
266
|
+
still processing a previous holidays operation. Right
|
|
267
|
+
after adding a holiday this is the expected answer for
|
|
268
|
+
a while. It is transient, retrying is up to the caller.
|
|
269
|
+
"""
|
|
270
|
+
self._connector.mambu_organization_delete_holiday(holidayid)
|
|
271
|
+
|
|
272
|
+
self.refresh()
|
|
@@ -54,6 +54,15 @@ class MambuGroupRole(MambuValueObject):
|
|
|
54
54
|
"""Group member role"""
|
|
55
55
|
|
|
56
56
|
|
|
57
|
+
class MambuHoliday(MambuValueObject):
|
|
58
|
+
"""Holiday of the organization.
|
|
59
|
+
|
|
60
|
+
A day on which the organization does not operate, part of the holidays
|
|
61
|
+
configuration managed by
|
|
62
|
+
:py:obj:`MambuPy.api.mambuholiday.MambuHolidays`.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
|
|
57
66
|
class MambuDisbursementLoanTransactionInput(MambuValueObject):
|
|
58
67
|
"""Disbursment Loan Transaction body"""
|
|
59
68
|
|
|
@@ -19,6 +19,7 @@ MambuPy/api/mambucentre.py
|
|
|
19
19
|
MambuPy/api/mambuclient.py
|
|
20
20
|
MambuPy/api/mambucustomfield.py
|
|
21
21
|
MambuPy/api/mambugroup.py
|
|
22
|
+
MambuPy/api/mambuholiday.py
|
|
22
23
|
MambuPy/api/mambuloan.py
|
|
23
24
|
MambuPy/api/mambuproduct.py
|
|
24
25
|
MambuPy/api/mamburole.py
|
|
@@ -31,6 +32,7 @@ MambuPy/api/connector/__init__.py
|
|
|
31
32
|
MambuPy/api/connector/mambuconnector.py
|
|
32
33
|
MambuPy/api/connector/rest.py
|
|
33
34
|
MambuPy/api/connector/rest_helpers.py
|
|
35
|
+
MambuPy/api/connector/rest_holidays.py
|
|
34
36
|
MambuPy/orm/__init__.py
|
|
35
37
|
MambuPy/orm/schema_activities.py
|
|
36
38
|
MambuPy/orm/schema_addresses.py
|
|
@@ -63,6 +65,7 @@ mambupy/api/mambucentre.py
|
|
|
63
65
|
mambupy/api/mambuclient.py
|
|
64
66
|
mambupy/api/mambucustomfield.py
|
|
65
67
|
mambupy/api/mambugroup.py
|
|
68
|
+
mambupy/api/mambuholiday.py
|
|
66
69
|
mambupy/api/mambuloan.py
|
|
67
70
|
mambupy/api/mambuproduct.py
|
|
68
71
|
mambupy/api/mamburole.py
|
|
@@ -75,6 +78,7 @@ mambupy/api/connector/__init__.py
|
|
|
75
78
|
mambupy/api/connector/mambuconnector.py
|
|
76
79
|
mambupy/api/connector/rest.py
|
|
77
80
|
mambupy/api/connector/rest_helpers.py
|
|
81
|
+
mambupy/api/connector/rest_holidays.py
|
|
78
82
|
mambupy/orm/__init__.py
|
|
79
83
|
mambupy/orm/schema_activities.py
|
|
80
84
|
mambupy/orm/schema_addresses.py
|