MambuPy 1.10.1__tar.gz → 2.0.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-1.10.1 → mambupy-2.0.0}/MambuPy/__init__.py +21 -5
- mambupy-2.0.0/MambuPy/api/__init__.py +25 -0
- mambupy-2.0.0/MambuPy/api/classes.py +220 -0
- mambupy-2.0.0/MambuPy/api/connector/__init__.py +8 -0
- mambupy-2.0.0/MambuPy/api/connector/mambuconnector.py +297 -0
- mambupy-2.0.0/MambuPy/api/connector/rest.py +862 -0
- mambupy-2.0.0/MambuPy/api/entities.py +955 -0
- mambupy-2.0.0/MambuPy/api/interfaces.py +159 -0
- mambupy-2.0.0/MambuPy/api/mambubranch.py +33 -0
- mambupy-2.0.0/MambuPy/api/mambucentre.py +40 -0
- mambupy-2.0.0/MambuPy/api/mambuclient.py +82 -0
- mambupy-2.0.0/MambuPy/api/mambucustomfield.py +72 -0
- mambupy-2.0.0/MambuPy/api/mambugroup.py +61 -0
- mambupy-2.0.0/MambuPy/api/mambuloan.py +330 -0
- mambupy-2.0.0/MambuPy/api/mambuproduct.py +92 -0
- mambupy-2.0.0/MambuPy/api/mamburole.py +22 -0
- mambupy-2.0.0/MambuPy/api/mambustruct.py +785 -0
- mambupy-2.0.0/MambuPy/api/mambutask.py +95 -0
- mambupy-2.0.0/MambuPy/api/mambutransaction.py +63 -0
- mambupy-2.0.0/MambuPy/api/mambuuser.py +114 -0
- mambupy-2.0.0/MambuPy/api/vos.py +113 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/mambuconfig.py +8 -0
- {MambuPy-1.10.1/mambupy → mambupy-2.0.0/MambuPy}/mambugeturl.py +2 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/mambuutil.py +69 -92
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_centres.py +1 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_loans.py +3 -1
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/__init__.py +2 -1
- {MambuPy-1.10.1/mambupy → mambupy-2.0.0/MambuPy}/rest/mambubranch.py +9 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambuloan.py +9 -2
- {MambuPy-1.10.1/mambupy → mambupy-2.0.0/MambuPy}/rest/mambustruct.py +12 -9
- mambupy-2.0.0/MambuPy/utils/__init__.py +9 -0
- mambupy-2.0.0/MambuPy/utils/userdeactivate.py +115 -0
- mambupy-2.0.0/MambuPy.egg-info/PKG-INFO +759 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy.egg-info/SOURCES.txt +46 -2
- mambupy-2.0.0/MambuPy.egg-info/requires.txt +30 -0
- mambupy-2.0.0/MambuPy.egg-info/top_level.txt +3 -0
- mambupy-2.0.0/PKG-INFO +759 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/__init__.py +21 -5
- mambupy-2.0.0/mambupy/api/__init__.py +25 -0
- mambupy-2.0.0/mambupy/api/classes.py +220 -0
- mambupy-2.0.0/mambupy/api/connector/__init__.py +8 -0
- mambupy-2.0.0/mambupy/api/connector/mambuconnector.py +297 -0
- mambupy-2.0.0/mambupy/api/connector/rest.py +862 -0
- mambupy-2.0.0/mambupy/api/entities.py +955 -0
- mambupy-2.0.0/mambupy/api/interfaces.py +159 -0
- mambupy-2.0.0/mambupy/api/mambubranch.py +33 -0
- mambupy-2.0.0/mambupy/api/mambucentre.py +40 -0
- mambupy-2.0.0/mambupy/api/mambuclient.py +82 -0
- mambupy-2.0.0/mambupy/api/mambucustomfield.py +72 -0
- mambupy-2.0.0/mambupy/api/mambugroup.py +61 -0
- mambupy-2.0.0/mambupy/api/mambuloan.py +330 -0
- mambupy-2.0.0/mambupy/api/mambuproduct.py +92 -0
- mambupy-2.0.0/mambupy/api/mamburole.py +22 -0
- mambupy-2.0.0/mambupy/api/mambustruct.py +785 -0
- mambupy-2.0.0/mambupy/api/mambutask.py +95 -0
- mambupy-2.0.0/mambupy/api/mambutransaction.py +63 -0
- mambupy-2.0.0/mambupy/api/mambuuser.py +114 -0
- mambupy-2.0.0/mambupy/api/vos.py +113 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/mambuconfig.py +8 -0
- {MambuPy-1.10.1/MambuPy → mambupy-2.0.0/mambupy}/mambugeturl.py +2 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/mambuutil.py +69 -92
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_centres.py +1 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_loans.py +3 -1
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/__init__.py +2 -1
- {MambuPy-1.10.1/MambuPy → mambupy-2.0.0/mambupy}/rest/mambubranch.py +9 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambuloan.py +9 -2
- {MambuPy-1.10.1/MambuPy → mambupy-2.0.0/mambupy}/rest/mambustruct.py +12 -9
- mambupy-2.0.0/mambupy/utils/__init__.py +9 -0
- mambupy-2.0.0/mambupy/utils/userdeactivate.py +115 -0
- mambupy-2.0.0/pyproject.toml +44 -0
- MambuPy-1.10.1/MambuPy.egg-info/PKG-INFO +0 -53
- MambuPy-1.10.1/MambuPy.egg-info/requires.txt +0 -4
- MambuPy-1.10.1/MambuPy.egg-info/top_level.txt +0 -4
- MambuPy-1.10.1/PKG-INFO +0 -53
- MambuPy-1.10.1/setup.py +0 -127
- {MambuPy-1.10.1 → mambupy-2.0.0}/LICENSE +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/__init__.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_activities.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_addresses.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_branches.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_clients.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_customfields.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_dummies.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_groups.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_mambu.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_orm.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_tasks.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/orm/schema_users.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambuactivity.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambucentre.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambuclient.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambugroup.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambuproduct.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mamburepayment.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mamburestutils.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mamburoles.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambusaving.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambusavingfundingrepayment.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambusavingtransaction.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambutask.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambutransaction.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambutransactionchannel.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy/rest/mambuuser.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/MambuPy.egg-info/dependency_links.txt +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/README.md +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/__init__.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_activities.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_addresses.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_branches.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_clients.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_customfields.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_dummies.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_groups.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_mambu.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_orm.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_tasks.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/orm/schema_users.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambuactivity.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambucentre.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambuclient.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambugroup.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambuproduct.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mamburepayment.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mamburestutils.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mamburoles.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambusaving.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambusavingfundingrepayment.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambusavingtransaction.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambutask.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambutransaction.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambutransactionchannel.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/mambupy/rest/mambuuser.py +0 -0
- {MambuPy-1.10.1 → mambupy-2.0.0}/setup.cfg +0 -0
|
@@ -5,18 +5,18 @@
|
|
|
5
5
|
|
|
6
6
|
MambuPy.mambuconfig
|
|
7
7
|
MambuPy.mambuutil
|
|
8
|
-
MambuPy.rest
|
|
9
|
-
MambuPy.orm
|
|
10
8
|
MambuPy.api
|
|
11
9
|
MambuPy.api.connector
|
|
12
|
-
MambuPy.
|
|
10
|
+
MambuPy.orm
|
|
11
|
+
MambuPy.rest
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
Currently, there are two different ways to access Mambu objects:
|
|
16
15
|
|
|
17
16
|
1) Objects using `Mambu REST API
|
|
18
17
|
<https://developer.mambu.com/customer/en/portal/articles/1162276-rest-apis-overview/>`_
|
|
19
|
-
, they live at the :any:`MambuPy.
|
|
18
|
+
, they live at the :any:`MambuPy.api` package (the old-and-soon-to-be-deprecated,
|
|
19
|
+
V1-compatible code lives at :any:`MambuPy.rest`
|
|
20
20
|
|
|
21
21
|
2) An ORM using a `DB backup retrieved from Mambu
|
|
22
22
|
<https://support.mambu.com/docs/mambu-data-dictionary>`_
|
|
@@ -35,5 +35,21 @@ TODOS
|
|
|
35
35
|
to achive TDD when implementing features or correcting bugs.
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
import sys
|
|
39
|
+
from importlib.abc import MetaPathFinder
|
|
40
|
+
from importlib.util import spec_from_file_location
|
|
41
|
+
|
|
42
|
+
__version__ = "2.0.0"
|
|
39
43
|
"""The version of this module."""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class CaseInsensitiveFinder(MetaPathFinder):
|
|
47
|
+
def find_spec(self, fullname, path, target=None):
|
|
48
|
+
if fullname.lower() == "mambupy":
|
|
49
|
+
# Get the actual module file location
|
|
50
|
+
return spec_from_file_location(fullname, __file__)
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# Register the finder
|
|
55
|
+
sys.meta_path.insert(0, CaseInsensitiveFinder())
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
""" MambuPy's Mambu REST API v2 package.
|
|
2
|
+
|
|
3
|
+
Objects using `Mambu REST API <https://api.mambu.com/?python>`_
|
|
4
|
+
|
|
5
|
+
.. autosummary::
|
|
6
|
+
:toctree: _autosummary
|
|
7
|
+
|
|
8
|
+
MambuPy.api.classes
|
|
9
|
+
MambuPy.api.entities
|
|
10
|
+
MambuPy.api.interfaces
|
|
11
|
+
MambuPy.api.vos
|
|
12
|
+
MambuPy.api.mambustruct
|
|
13
|
+
MambuPy.api.mambuproduct
|
|
14
|
+
MambuPy.api.mambuloan
|
|
15
|
+
MambuPy.api.mambutransaction
|
|
16
|
+
MambuPy.api.mambugroup
|
|
17
|
+
MambuPy.api.mambuclient
|
|
18
|
+
MambuPy.api.mambubranch
|
|
19
|
+
MambuPy.api.mambucentre
|
|
20
|
+
MambuPy.api.mambuuser
|
|
21
|
+
MambuPy.api.mambutask
|
|
22
|
+
MambuPy.api.mambucustomfield
|
|
23
|
+
|
|
24
|
+
Entities use the Mixin pattern to acquire functionality.
|
|
25
|
+
"""
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""Base and utility Classes for Mambu Objects.
|
|
2
|
+
|
|
3
|
+
.. autosummary::
|
|
4
|
+
:nosignatures:
|
|
5
|
+
:toctree: _autosummary
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import copy
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GenericClass: # pragma: no coverage
|
|
12
|
+
"""Generic class for init of MambuMapObj"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, *args, **kwargs):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class MambuMapObj:
|
|
19
|
+
"""An object with dictionary-like behaviour for key-value data"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, cf_class=GenericClass, **kwargs):
|
|
22
|
+
self._attrs = {}
|
|
23
|
+
self._cf_class = cf_class
|
|
24
|
+
if hasattr(self, "_default_tzattrs"):
|
|
25
|
+
self._tzattrs = copy.deepcopy(self._default_tzattrs)
|
|
26
|
+
else:
|
|
27
|
+
self._tzattrs = {}
|
|
28
|
+
if "tzattrs" in kwargs:
|
|
29
|
+
self._tzattrs.update(copy.deepcopy(kwargs.pop("tzattrs")))
|
|
30
|
+
if kwargs:
|
|
31
|
+
for key, val in kwargs.items():
|
|
32
|
+
self._attrs[key] = val
|
|
33
|
+
|
|
34
|
+
def __getattribute__(self, name):
|
|
35
|
+
"""Object-like get attribute
|
|
36
|
+
|
|
37
|
+
When accessing an attribute, tries to find it in the _attrs
|
|
38
|
+
dictionary, so now MambuMapObj may act not only as a dict-like
|
|
39
|
+
structure, but as a full object-like too (this is the getter
|
|
40
|
+
side).
|
|
41
|
+
"""
|
|
42
|
+
try:
|
|
43
|
+
# first, try to read 'name' as if it's a property of the object
|
|
44
|
+
# if it doesn't exists as property, AttributeError raises
|
|
45
|
+
return object.__getattribute__(self, name)
|
|
46
|
+
except AttributeError:
|
|
47
|
+
# try to read the _attrs property
|
|
48
|
+
_attrs = object.__getattribute__(self, "_attrs")
|
|
49
|
+
if isinstance(_attrs, list) or name not in _attrs:
|
|
50
|
+
# magic won't happen when not a dict-like MambuMapObj or
|
|
51
|
+
# when _attrs has not the 'name' key (this last one means
|
|
52
|
+
# that if 'name' is not a property of the object too,
|
|
53
|
+
# AttributeError will raise by default)
|
|
54
|
+
return object.__getattribute__(self, name)
|
|
55
|
+
# all else, read the property from the _attrs dict, but with a . syntax
|
|
56
|
+
# if a cf_class, just return its value
|
|
57
|
+
if _attrs[name].__class__.__name__ == self._cf_class.__name__:
|
|
58
|
+
return _attrs[name]["value"]
|
|
59
|
+
return _attrs[name]
|
|
60
|
+
|
|
61
|
+
def __setattr__(self, name, value):
|
|
62
|
+
"""Object-like set attribute
|
|
63
|
+
|
|
64
|
+
When setting an attribute, tries to set it in the _attrs
|
|
65
|
+
dictionary, so now MambuMapObj acts not only as a dict-like
|
|
66
|
+
structure, but as a full object-like too (this is the setter
|
|
67
|
+
side).
|
|
68
|
+
"""
|
|
69
|
+
# if name beginning with _, assign it as a property of the object
|
|
70
|
+
if name[0] == "_":
|
|
71
|
+
object.__setattr__(self, name, value)
|
|
72
|
+
else:
|
|
73
|
+
try:
|
|
74
|
+
# _attrs needs to exist to make the magic happen!
|
|
75
|
+
# ... if not, AttributeError raises
|
|
76
|
+
_attrs = object.__getattribute__(self, "_attrs")
|
|
77
|
+
if isinstance(_attrs, list):
|
|
78
|
+
# when not treating with a dict-like MambuMapObj...
|
|
79
|
+
raise AttributeError
|
|
80
|
+
try:
|
|
81
|
+
# see if 'name' is currently a property of the object
|
|
82
|
+
object.__getattribute__(self, name)
|
|
83
|
+
except AttributeError:
|
|
84
|
+
# if not, then assign it as a new key in the dict
|
|
85
|
+
if (
|
|
86
|
+
name in _attrs
|
|
87
|
+
and _attrs[name].__class__.__name__ == self._cf_class.__name__
|
|
88
|
+
):
|
|
89
|
+
path = _attrs[name]["path"]
|
|
90
|
+
typecf = _attrs[name]["type"]
|
|
91
|
+
_attrs[name] = self._cf_class(value, path, typecf)
|
|
92
|
+
else:
|
|
93
|
+
_attrs[name] = value
|
|
94
|
+
else: # pragma: no cover
|
|
95
|
+
raise AttributeError
|
|
96
|
+
except AttributeError:
|
|
97
|
+
# all else assign it as a property of the object
|
|
98
|
+
object.__setattr__(self, name, value)
|
|
99
|
+
|
|
100
|
+
def __getitem__(self, key):
|
|
101
|
+
"""Dict-like key query"""
|
|
102
|
+
# if a cf_class, just return its value
|
|
103
|
+
if self._attrs[key].__class__.__name__ == self._cf_class.__name__:
|
|
104
|
+
return self._attrs[key]["value"]
|
|
105
|
+
return self._attrs[key]
|
|
106
|
+
|
|
107
|
+
def __setitem__(self, key, value):
|
|
108
|
+
"""Dict-like set"""
|
|
109
|
+
# if no _attrs attribute, should be automatically created?
|
|
110
|
+
if (
|
|
111
|
+
key in self._attrs
|
|
112
|
+
and self._attrs[key].__class__.__name__ == self._cf_class.__name__
|
|
113
|
+
):
|
|
114
|
+
path = self._attrs[key]["path"]
|
|
115
|
+
typecf = self._attrs[key]["type"]
|
|
116
|
+
self._attrs[key] = self._cf_class(value, path, typecf)
|
|
117
|
+
else:
|
|
118
|
+
self._attrs[key] = value
|
|
119
|
+
|
|
120
|
+
def __delitem__(self, key):
|
|
121
|
+
"""Dict-like del key"""
|
|
122
|
+
del self._attrs[key]
|
|
123
|
+
|
|
124
|
+
def __str__(self):
|
|
125
|
+
"""Mambu object str gives a string representation of the _attrs attribute."""
|
|
126
|
+
try:
|
|
127
|
+
return self.__class__.__name__ + " - " + str(self._attrs)
|
|
128
|
+
except AttributeError:
|
|
129
|
+
return repr(self)
|
|
130
|
+
|
|
131
|
+
def __repr__(self):
|
|
132
|
+
"""Mambu object repr tells the class name and the usual 'id' for it.
|
|
133
|
+
|
|
134
|
+
If an iterable, it instead gives its length.
|
|
135
|
+
"""
|
|
136
|
+
try:
|
|
137
|
+
return self.__class__.__name__ + " - id: %s" % self._attrs["id"]
|
|
138
|
+
except KeyError:
|
|
139
|
+
return self.__class__.__name__ + " - " + str(self._attrs)
|
|
140
|
+
except AttributeError:
|
|
141
|
+
return (
|
|
142
|
+
self.__class__.__name__
|
|
143
|
+
+ " - id: '%s' (not synced with Mambu)" % self.entid
|
|
144
|
+
)
|
|
145
|
+
except TypeError:
|
|
146
|
+
return self.__class__.__name__ + " - len: %s" % len(self._attrs)
|
|
147
|
+
|
|
148
|
+
def __eq__(self, other):
|
|
149
|
+
"""Very basic way to compare to Mambu objects.
|
|
150
|
+
|
|
151
|
+
Only looking at their EncodedKey field (its primary key on the
|
|
152
|
+
Mambu DB).
|
|
153
|
+
|
|
154
|
+
.. todo:: a lot of improvements may be done here.
|
|
155
|
+
"""
|
|
156
|
+
if isinstance(other, MambuMapObj):
|
|
157
|
+
try:
|
|
158
|
+
if "encodedKey" not in other._attrs or "encodedKey" not in self._attrs:
|
|
159
|
+
return NotImplemented
|
|
160
|
+
except AttributeError:
|
|
161
|
+
return NotImplemented
|
|
162
|
+
return other["encodedKey"] == self["encodedKey"]
|
|
163
|
+
|
|
164
|
+
def __hash__(self):
|
|
165
|
+
"""Hash of the object"""
|
|
166
|
+
try:
|
|
167
|
+
return hash(self.encodedKey)
|
|
168
|
+
except AttributeError:
|
|
169
|
+
try:
|
|
170
|
+
return hash(self.__class__.__name__ + self.id)
|
|
171
|
+
except Exception:
|
|
172
|
+
return hash(self.__repr__())
|
|
173
|
+
|
|
174
|
+
def __len__(self):
|
|
175
|
+
"""Length of the _attrs attribute.
|
|
176
|
+
|
|
177
|
+
If dict-like (not iterable), it's the number of keys holded on the _attrs dictionary.
|
|
178
|
+
If list-like (iterable), it's the number of elements of the _attrs list.
|
|
179
|
+
"""
|
|
180
|
+
return len(self._attrs)
|
|
181
|
+
|
|
182
|
+
def __contains__(self, item):
|
|
183
|
+
"""Dict-like and List-like behaviour"""
|
|
184
|
+
return item in self._attrs
|
|
185
|
+
|
|
186
|
+
def get(self, key, default=None):
|
|
187
|
+
"""Dict-like behaviour"""
|
|
188
|
+
if isinstance(self._attrs, dict):
|
|
189
|
+
return self._attrs.get(key, default)
|
|
190
|
+
raise NotImplementedError # if _attrs is not a dict
|
|
191
|
+
|
|
192
|
+
def keys(self):
|
|
193
|
+
"""Dict-like behaviour"""
|
|
194
|
+
try:
|
|
195
|
+
return self._attrs.keys()
|
|
196
|
+
except AttributeError:
|
|
197
|
+
raise NotImplementedError
|
|
198
|
+
|
|
199
|
+
def items(self):
|
|
200
|
+
"""Dict-like behaviour"""
|
|
201
|
+
try:
|
|
202
|
+
return self._attrs.items()
|
|
203
|
+
except AttributeError:
|
|
204
|
+
raise NotImplementedError
|
|
205
|
+
|
|
206
|
+
def values(self):
|
|
207
|
+
"""Dict-like behaviour"""
|
|
208
|
+
try:
|
|
209
|
+
return self._attrs.values()
|
|
210
|
+
except AttributeError:
|
|
211
|
+
raise NotImplementedError
|
|
212
|
+
|
|
213
|
+
def has_key(self, key):
|
|
214
|
+
"""Dict-like behaviour"""
|
|
215
|
+
try:
|
|
216
|
+
if isinstance(self._attrs, dict):
|
|
217
|
+
return key in self._attrs
|
|
218
|
+
raise AttributeError # if _attrs is not a dict
|
|
219
|
+
except AttributeError: # if _attrs doesnt exist
|
|
220
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"""Connectors to Mambu.
|
|
2
|
+
|
|
3
|
+
Currently supports REST.
|
|
4
|
+
|
|
5
|
+
.. autosummary::
|
|
6
|
+
:nosignatures:
|
|
7
|
+
:toctree: _autosummary
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from abc import ABC, abstractmethod
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MambuConnector(ABC):
|
|
14
|
+
"""Interface for Connectors"""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MambuConnectorReader(ABC):
|
|
18
|
+
"""Interface for Readers.
|
|
19
|
+
|
|
20
|
+
A Reader supports the followint operations:
|
|
21
|
+
|
|
22
|
+
- get (gets a single entity)
|
|
23
|
+
- get_all (gets several entities, filtering allowed)
|
|
24
|
+
- search (gets several entities, advanced filtering)
|
|
25
|
+
- get_documents_metadata (gets the metadata of documents attached to some
|
|
26
|
+
entity)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
@abstractmethod
|
|
30
|
+
def mambu_get(self, entid, prefix, detailsLevel="BASIC"):
|
|
31
|
+
"""get, a single entity, identified by its entid.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
entid (str): ID for the entity
|
|
35
|
+
prefix (str): entity's URL prefix
|
|
36
|
+
detailsLevel (str BASIC/FULL): ask for extra details or not
|
|
37
|
+
"""
|
|
38
|
+
raise NotImplementedError
|
|
39
|
+
|
|
40
|
+
@abstractmethod
|
|
41
|
+
def mambu_get_all(
|
|
42
|
+
self,
|
|
43
|
+
prefix,
|
|
44
|
+
filters=None,
|
|
45
|
+
offset=None,
|
|
46
|
+
limit=None,
|
|
47
|
+
paginationDetails="OFF",
|
|
48
|
+
detailsLevel="BASIC",
|
|
49
|
+
sortBy=None,
|
|
50
|
+
**kwargs
|
|
51
|
+
):
|
|
52
|
+
"""get_all, several entities, filtering allowed
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
prefix (str): entity's URL prefix
|
|
56
|
+
filters (dict): key-value filters (depends on each entity)
|
|
57
|
+
offset (int): pagination, index to start searching
|
|
58
|
+
limit (int): pagination, number of elements to retrieve
|
|
59
|
+
paginationDetails (str ON/OFF): ask for details on pagination
|
|
60
|
+
detailsLevel (str BASIC/FULL): ask for extra details or not
|
|
61
|
+
sortBy (str): ``field1:ASC,field2:DESC``, sorting criteria for
|
|
62
|
+
results
|
|
63
|
+
kwargs (dict): extra parameters that a specific entity may receive in
|
|
64
|
+
its get_all method
|
|
65
|
+
"""
|
|
66
|
+
raise NotImplementedError
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def mambu_search(
|
|
70
|
+
self,
|
|
71
|
+
prefix,
|
|
72
|
+
filterCriteria=None,
|
|
73
|
+
sortingCriteria=None,
|
|
74
|
+
offset=None,
|
|
75
|
+
limit=None,
|
|
76
|
+
paginationDetails="OFF",
|
|
77
|
+
detailsLevel="BASIC",
|
|
78
|
+
):
|
|
79
|
+
"""search, several entities, filtering criteria allowed
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
filterCriteria (list of dicts): fields according to
|
|
83
|
+
LoanAccountFilterCriteria schema
|
|
84
|
+
sortingCriteria (dict): fields according to
|
|
85
|
+
LoanAccountSortingCriteria
|
|
86
|
+
offset (int): pagination, index to start searching
|
|
87
|
+
limit (int): pagination, number of elements to retrieve
|
|
88
|
+
paginationDetails (str ON/OFF): ask for details on pagination
|
|
89
|
+
detailsLevel (str BASIC/FULL): ask for extra details or not
|
|
90
|
+
"""
|
|
91
|
+
raise NotImplementedError
|
|
92
|
+
|
|
93
|
+
@abstractmethod
|
|
94
|
+
def mambu_get_documents_metadata(
|
|
95
|
+
self,
|
|
96
|
+
entid,
|
|
97
|
+
owner_type,
|
|
98
|
+
offset=None,
|
|
99
|
+
limit=None,
|
|
100
|
+
paginationDetails="OFF",
|
|
101
|
+
):
|
|
102
|
+
"""Gets metadata for all the documents attached to an entity
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
entid (str): the id or encoded key of the entity owning the document
|
|
106
|
+
owner_type (str): the type of the owner of the document
|
|
107
|
+
offset (int): pagination, index to start searching
|
|
108
|
+
limit (int): pagination, number of elements to retrieve
|
|
109
|
+
paginationDetails (str ON/OFF): ask for details on pagination
|
|
110
|
+
"""
|
|
111
|
+
raise NotImplementedError
|
|
112
|
+
|
|
113
|
+
@abstractmethod
|
|
114
|
+
def mambu_loanaccount_getSchedule(self, loanid):
|
|
115
|
+
"""Retrieves the installments schedule
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
loanid (str): the id or encoded key of the loan account
|
|
119
|
+
"""
|
|
120
|
+
raise NotImplementedError
|
|
121
|
+
|
|
122
|
+
@abstractmethod
|
|
123
|
+
def mambu_get_customfield(self, customfieldid):
|
|
124
|
+
"""Retrieves a Custom Field.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
customfieldid (str): the id or encoded key of the custom field
|
|
128
|
+
"""
|
|
129
|
+
raise NotImplementedError
|
|
130
|
+
|
|
131
|
+
@abstractmethod
|
|
132
|
+
def mambu_get_comments(self, owner_id, owner_type):
|
|
133
|
+
"""Retrieves the comments of entity with owner_id.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
owner_id (str): the id or encoded key of the owner
|
|
137
|
+
owner_type (str): the type of the entity owning the comments
|
|
138
|
+
"""
|
|
139
|
+
raise NotImplementedError
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class MambuConnectorWriter(ABC):
|
|
143
|
+
"""Interface for Writers.
|
|
144
|
+
|
|
145
|
+
A Reader supports the followint operations:
|
|
146
|
+
|
|
147
|
+
- update (updates an entity)
|
|
148
|
+
- create (creates an entity)
|
|
149
|
+
- patch (patches an entity)
|
|
150
|
+
- upload_document (gets a single entity)
|
|
151
|
+
- delete_document (gets several entities, filtering allowed)
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
@abstractmethod
|
|
155
|
+
def mambu_update(self, entid, prefix, attrs):
|
|
156
|
+
"""updates a mambu entity
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
entid (str): the id or encoded key of the entity owning the document
|
|
160
|
+
prefix (str): entity's URL prefix
|
|
161
|
+
attrs (dict): entity to be updated, complying with Mambu's schemas
|
|
162
|
+
"""
|
|
163
|
+
raise NotImplementedError
|
|
164
|
+
|
|
165
|
+
@abstractmethod
|
|
166
|
+
def mambu_create(self, prefix, attrs):
|
|
167
|
+
"""creates a mambu entity
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
prefix (str): entity's URL prefix
|
|
171
|
+
attrs (dict): entity to be created, complying with Mambu's schemas
|
|
172
|
+
"""
|
|
173
|
+
raise NotImplementedError
|
|
174
|
+
|
|
175
|
+
@abstractmethod
|
|
176
|
+
def mambu_patch(self, entid, prefix, fields):
|
|
177
|
+
"""patches certain parts of a mambu entity"""
|
|
178
|
+
raise NotImplementedError
|
|
179
|
+
|
|
180
|
+
@abstractmethod
|
|
181
|
+
def mambu_delete(self, entid, prefix):
|
|
182
|
+
"""deletes a mambu entity"""
|
|
183
|
+
raise NotImplementedError
|
|
184
|
+
|
|
185
|
+
@abstractmethod
|
|
186
|
+
def mambu_upload_document(self, owner_type, entid, filename, name, notes):
|
|
187
|
+
"""uploads an attachment to this entity
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
owner_type (str): the type of the owner of the document
|
|
191
|
+
entid (str): the id or encoded key of the entity owning the document
|
|
192
|
+
filename (str): path and filename of file to upload as attachment
|
|
193
|
+
name (str): name to assign to the attached file in Mambu
|
|
194
|
+
notes (str): notes to associate to the attached file in Mambu
|
|
195
|
+
"""
|
|
196
|
+
raise NotImplementedError
|
|
197
|
+
|
|
198
|
+
@abstractmethod
|
|
199
|
+
def mambu_delete_document(self, documentId):
|
|
200
|
+
"""deletes an attachment by its documentId
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
documentId (str): the id or encodedkey of the document to be deleted
|
|
204
|
+
"""
|
|
205
|
+
raise NotImplementedError
|
|
206
|
+
|
|
207
|
+
@abstractmethod
|
|
208
|
+
def mambu_change_state(self, entid, prefix, action, notes):
|
|
209
|
+
"""change state of mambu entity
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
entid (str): the id or encoded key of the entity owning the document
|
|
213
|
+
prefix (str): entity's URL prefix
|
|
214
|
+
action (str): specify the action state
|
|
215
|
+
notes (str): notes to associate to the change of status
|
|
216
|
+
"""
|
|
217
|
+
raise NotImplementedError
|
|
218
|
+
|
|
219
|
+
@abstractmethod
|
|
220
|
+
def mambu_comment(self, owner_id, owner_type, text):
|
|
221
|
+
"""Comments an entity with owner_id.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
owner_id (str): the id or encoded key of the owner
|
|
225
|
+
owner_type (str): the type of the entity owning the comments
|
|
226
|
+
text (str): the text of the comment
|
|
227
|
+
"""
|
|
228
|
+
raise NotImplementedError
|
|
229
|
+
|
|
230
|
+
@abstractmethod
|
|
231
|
+
def mambu_make_disbursement(
|
|
232
|
+
self, loan_id, firstRepaymentDate, notes, valueDate, allowed_fields, **kwargs
|
|
233
|
+
):
|
|
234
|
+
"""Make a disbursement transacton on a loan account.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
loan_id (str): loan account id to disburse
|
|
238
|
+
firstRepaymentDate (str): first repayment date in ISO format
|
|
239
|
+
notes (str): notes for the disbursement transaction
|
|
240
|
+
valueDate (str): entry date for the disbursement transaction
|
|
241
|
+
allowed_fields (list): extra fields allowed for the transaction
|
|
242
|
+
kwargs (dict): key-values of extra fields for the transaction
|
|
243
|
+
"""
|
|
244
|
+
raise NotImplementedError
|
|
245
|
+
|
|
246
|
+
@abstractmethod
|
|
247
|
+
def mambu_make_repayment(
|
|
248
|
+
self, loan_id, amount, notes, valueDate, allowed_fields, **kwargs
|
|
249
|
+
):
|
|
250
|
+
"""Make a repayment transaction on a loan account.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
loan_id (str): loan account id to make a repayment
|
|
254
|
+
amount (float): the amount of the repayment
|
|
255
|
+
notes (str): notes for the repayment transaction
|
|
256
|
+
valueDate (str): entry date for the repayment transaction
|
|
257
|
+
allowed_fields (list): extra fields allowed for the transaction
|
|
258
|
+
kwargs (dict): key-values of extra fields for the transaction
|
|
259
|
+
"""
|
|
260
|
+
raise NotImplementedError
|
|
261
|
+
|
|
262
|
+
@abstractmethod
|
|
263
|
+
def mambu_make_fee(
|
|
264
|
+
self, loan_id, amount, installmentNumber, notes, valueDate, allowed_fields, **kwargs
|
|
265
|
+
):
|
|
266
|
+
"""Make a fee transaction on a loan account.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
loan_id (str): loan account id to apply a fee
|
|
270
|
+
amount (float): the amount of the fee
|
|
271
|
+
installmentNumber (int): the installment number to apply the fee
|
|
272
|
+
notes (str): notes for the fee transaction
|
|
273
|
+
valueDate (str): entry date for the fee transaction
|
|
274
|
+
allowed_fields (list): extra fields allowed for the transaction
|
|
275
|
+
kwargs (dict): key-values of extra fields for the transaction
|
|
276
|
+
"""
|
|
277
|
+
raise NotImplementedError
|
|
278
|
+
|
|
279
|
+
@abstractmethod
|
|
280
|
+
def mambu_loanaccount_writeoff(self, loanid, notes):
|
|
281
|
+
"""Writesoff a loan account
|
|
282
|
+
|
|
283
|
+
Args:
|
|
284
|
+
loanid (str): the id or encoded key of the loan account
|
|
285
|
+
notes (str): notes to associate to the writeoff operation in Mambu
|
|
286
|
+
"""
|
|
287
|
+
raise NotImplementedError
|
|
288
|
+
|
|
289
|
+
@abstractmethod
|
|
290
|
+
def mambu_loantransaction_adjust(self, transactionid, notes):
|
|
291
|
+
"""Adjust a loan transaction
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
transactionid (str): the id or encoded key of the loan transaction
|
|
295
|
+
notes (str): notes to associate to the transaction adjustment in Mambu
|
|
296
|
+
"""
|
|
297
|
+
raise NotImplementedError
|