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.
Files changed (102) hide show
  1. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/__init__.py +1 -1
  2. {mambupy-2.4.0/mambupy → mambupy-2.5.0/MambuPy}/api/__init__.py +1 -0
  3. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/connector/mambuconnector.py +70 -0
  4. {mambupy-2.4.0/mambupy → mambupy-2.5.0/MambuPy}/api/connector/rest.py +20 -2
  5. mambupy-2.5.0/MambuPy/api/connector/rest_holidays.py +133 -0
  6. mambupy-2.5.0/MambuPy/api/mambuholiday.py +272 -0
  7. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/vos.py +9 -0
  8. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/PKG-INFO +1 -1
  9. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/SOURCES.txt +4 -0
  10. {mambupy-2.4.0 → mambupy-2.5.0}/PKG-INFO +1 -1
  11. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/__init__.py +1 -1
  12. {mambupy-2.4.0/MambuPy → mambupy-2.5.0/mambupy}/api/__init__.py +1 -0
  13. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/connector/mambuconnector.py +70 -0
  14. {mambupy-2.4.0/MambuPy → mambupy-2.5.0/mambupy}/api/connector/rest.py +20 -2
  15. mambupy-2.5.0/mambupy/api/connector/rest_holidays.py +133 -0
  16. mambupy-2.5.0/mambupy/api/mambuholiday.py +272 -0
  17. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/vos.py +9 -0
  18. {mambupy-2.4.0 → mambupy-2.5.0}/LICENSE +0 -0
  19. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/classes.py +0 -0
  20. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/connector/__init__.py +0 -0
  21. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/connector/rest_helpers.py +0 -0
  22. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/entities.py +0 -0
  23. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/interfaces.py +0 -0
  24. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambubranch.py +0 -0
  25. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambucentre.py +0 -0
  26. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambuclient.py +0 -0
  27. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambucustomfield.py +0 -0
  28. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambugroup.py +0 -0
  29. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambuloan.py +0 -0
  30. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambuproduct.py +0 -0
  31. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mamburole.py +0 -0
  32. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambustruct.py +0 -0
  33. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambutask.py +0 -0
  34. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambutransaction.py +0 -0
  35. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/api/mambuuser.py +0 -0
  36. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/mambuconfig.py +0 -0
  37. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/mambugeturl.py +0 -0
  38. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/mambuutil.py +0 -0
  39. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/__init__.py +0 -0
  40. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_activities.py +0 -0
  41. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_addresses.py +0 -0
  42. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_branches.py +0 -0
  43. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_centres.py +0 -0
  44. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_clients.py +0 -0
  45. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_customfields.py +0 -0
  46. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_dummies.py +0 -0
  47. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_groups.py +0 -0
  48. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_loans.py +0 -0
  49. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_mambu.py +0 -0
  50. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_orm.py +0 -0
  51. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_tasks.py +0 -0
  52. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/orm/schema_users.py +0 -0
  53. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/rest/__init__.py +0 -0
  54. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/rest/mambuactivity.py +0 -0
  55. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/utils/__init__.py +0 -0
  56. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/utils/update_user_roles.py +0 -0
  57. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy/utils/userdeactivate.py +0 -0
  58. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/dependency_links.txt +0 -0
  59. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/requires.txt +0 -0
  60. {mambupy-2.4.0 → mambupy-2.5.0}/MambuPy.egg-info/top_level.txt +0 -0
  61. {mambupy-2.4.0 → mambupy-2.5.0}/README.md +0 -0
  62. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/classes.py +0 -0
  63. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/connector/__init__.py +0 -0
  64. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/connector/rest_helpers.py +0 -0
  65. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/entities.py +0 -0
  66. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/interfaces.py +0 -0
  67. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambubranch.py +0 -0
  68. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambucentre.py +0 -0
  69. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambuclient.py +0 -0
  70. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambucustomfield.py +0 -0
  71. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambugroup.py +0 -0
  72. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambuloan.py +0 -0
  73. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambuproduct.py +0 -0
  74. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mamburole.py +0 -0
  75. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambustruct.py +0 -0
  76. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambutask.py +0 -0
  77. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambutransaction.py +0 -0
  78. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/api/mambuuser.py +0 -0
  79. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/mambuconfig.py +0 -0
  80. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/mambugeturl.py +0 -0
  81. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/mambuutil.py +0 -0
  82. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/__init__.py +0 -0
  83. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_activities.py +0 -0
  84. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_addresses.py +0 -0
  85. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_branches.py +0 -0
  86. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_centres.py +0 -0
  87. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_clients.py +0 -0
  88. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_customfields.py +0 -0
  89. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_dummies.py +0 -0
  90. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_groups.py +0 -0
  91. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_loans.py +0 -0
  92. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_mambu.py +0 -0
  93. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_orm.py +0 -0
  94. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_tasks.py +0 -0
  95. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/orm/schema_users.py +0 -0
  96. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/rest/__init__.py +0 -0
  97. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/rest/mambuactivity.py +0 -0
  98. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/utils/__init__.py +0 -0
  99. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/utils/update_user_roles.py +0 -0
  100. {mambupy-2.4.0 → mambupy-2.5.0}/mambupy/utils/userdeactivate.py +0 -0
  101. {mambupy-2.4.0 → mambupy-2.5.0}/pyproject.toml +0 -0
  102. {mambupy-2.4.0 → mambupy-2.5.0}/setup.cfg +0 -0
@@ -37,7 +37,7 @@ import sys
37
37
  from importlib.abc import MetaPathFinder
38
38
  from importlib.util import spec_from_file_location
39
39
 
40
- __version__ = "2.4.0"
40
+ __version__ = "2.5.0"
41
41
  """The version of this module."""
42
42
 
43
43
 
@@ -20,6 +20,7 @@ Objects using `Mambu REST API <https://api.mambu.com/?python>`_
20
20
  MambuPy.api.mambuuser
21
21
  MambuPy.api.mambutask
22
22
  MambuPy.api.mambucustomfield
23
+ MambuPy.api.mambuholiday
23
24
 
24
25
  Entities use the Mixin pattern to acquire functionality.
25
26
  """
@@ -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(MambuConnector, MambuConnectorReader, MambuConnectorWriter):
89
- """A connector for Mambu REST API"""
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MambuPy
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: A python library for using Mambu APIs.
5
5
  Author-email: "Javier Novoa C." <jstitch@gmail.com>
6
6
  License: LICENSE
@@ -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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MambuPy
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: A python library for using Mambu APIs.
5
5
  Author-email: "Javier Novoa C." <jstitch@gmail.com>
6
6
  License: LICENSE
@@ -37,7 +37,7 @@ import sys
37
37
  from importlib.abc import MetaPathFinder
38
38
  from importlib.util import spec_from_file_location
39
39
 
40
- __version__ = "2.4.0"
40
+ __version__ = "2.5.0"
41
41
  """The version of this module."""
42
42
 
43
43
 
@@ -20,6 +20,7 @@ Objects using `Mambu REST API <https://api.mambu.com/?python>`_
20
20
  MambuPy.api.mambuuser
21
21
  MambuPy.api.mambutask
22
22
  MambuPy.api.mambucustomfield
23
+ MambuPy.api.mambuholiday
23
24
 
24
25
  Entities use the Mixin pattern to acquire functionality.
25
26
  """