Source code for MambuPy.api.mambuloan

"""MambuLoan entity: a MambuEntity struct for credit Loans.

.. autosummary::
   :nosignatures:
   :toctree: _autosummary
"""

import copy
import datetime
import json

from .entities import (
    MambuEntity,
    MambuEntityWritable,
    MambuEntityAttachable,
    MambuEntitySearchable,
    MambuEntityCommentable,
    MambuEntityOwnable,
    MambuInstallment,
)

from MambuPy.api.vos import (
    MambuDisbursementLoanTransactionInput,
    MambuFeeLoanTransactionInput,
    MambuRepaymentLoanTransactionInput,
    MambuLoanTransactionDetailsInput,
)
from MambuPy.mambuutil import MambuPyError
from .mambutransaction import MambuTransaction

[docs]class MambuLoan( MambuEntity, MambuEntityWritable, MambuEntityAttachable, MambuEntityCommentable, MambuEntityOwnable, MambuEntitySearchable, ): """MambuLoan entity""" _prefix = "loans" """prefix constant for connections to Mambu""" _filter_keys = [ "branchId", "centreId", "accountState", "accountHolderType", "accountHolderId", "creditOfficerUsername", ] """allowed filters for get_all filtering""" _default_tzattrs = { "disbursementDetails": { "expectedDisbursementDate": None, "disbursementDate": None, "firstRepaymentDate": None, }, } _sortBy_fields = [ "creationDate", "lastModifiedDate", "id", "loanName", ] """allowed fields for get_all sorting""" _ownerType = "LOAN_ACCOUNT" """owner type of this entity""" _vos = [("disbursementDetails", "MambuDisbursementDetails")] """2-tuples of elements and Value Objects""" _entities = [ ("assignedUserKey", "mambuuser.MambuUser", "assignedUser"), ("assignedBranchKey", "mambubranch.MambuBranch", "assignedBranch"), ("assignedCentreKey", "mambucentre.MambuCentre", "assignedCentre"), ("productTypeKey", "mambuproduct.MambuProduct", "productType"), ("originalAccountKey", "mambuloan.MambuLoan", "originalAccount"), ("accountHolderKey", "", "accountHolder"), ] """3-tuples of elements and Mambu Entities""" _accepted_actions = [ "REQUEST_APPROVAL", "SET_INCOMPLETE", "APPROVE", "UNDO_APPROVE", "REJECT", "WITHDRAW", "CLOSE", "UNDO_REJECT", "UNDO_WITHDRAW", "UNDO_CLOSE", ] """accepted actions to change"""
[docs] def __init__(self, **kwargs): self._entities = copy.deepcopy(MambuLoan._entities) super().__init__(**kwargs) self._attachments = {}
[docs] def _delete_for_creation(self): """Deletes extra fields from Mambu unusable for entity creation.""" try: del self._attrs["currency"] del self._attrs["accountState"] del self._attrs["scheduleSettings"]["hasCustomSchedule"] del self._attrs["interestSettings"]["accrueLateInterest"] except KeyError: pass
[docs] def get_schedule(self, **kwargs): """Retrieves the installments schedule.""" resp = self._connector.mambu_loanaccount_getSchedule(self.id) installments = json.loads(resp.decode())["installments"] self.schedule = [] for installment in installments: installment_entity = MambuInstallment(**installment) installment_entity._tzattrs = copy.deepcopy(installment) installment_entity._convertDict2Attrs() self.schedule.append(installment_entity)
[docs] def get_transactions(self, **kwargs): """Retrieves the transactions of the loan""" self.transactions = MambuTransaction.get_all(self.id)
[docs] def set_state(self, action, notes, **kwargs): """Request to change status of a MambuLoan Args: action (str): specify the action state notes (str): notes to associate to the change of status Raises: `MambuPyError`: if action not in _accepted_actions """ if action in self._accepted_actions: resp = self._connector.mambu_change_state( entid=self.id, prefix=self._prefix, action=action, notes=notes, ) resp = json.loads(resp) self.accountState = resp["accountState"] else: raise MambuPyError( "field {} not in allowed _accepted_actions: {}".format( action, self._accepted_actions ) )
[docs] def approve(self, notes, **kwargs): """Request to approve a loan account. Args: notes (str): notes to attach to the approval operation. """ self.set_state("APPROVE", notes, **kwargs)
[docs] def disburse(self, notes, firstRepaymentDate=None, disbursementDate=None, **kwargs): """Request to disburse a loan account. Args: notes (str): notes to attach to the disbursement transaction. firstRepaymentDate (:py:obj:`datetime`): first repayment date for the loan account. If None, value is fetched from disbursement details. If naive datetime, use TZ info from tzattrs disbursementDate (:py:obj:`datetime`): disbursement date for the loan account. If None, value is fetched from disbursement details, expected disbursement date. If naive datetime, use TZ info from tzattrs kwargs (dict): allowed extra params for the disbursement transaction request. :py:obj:`MambuPy.api.vos.MambuDisbursementLoanTransactionInput._schema_fields` has the allowed fields permitted for this operation """ self._serializeFields() if firstRepaymentDate: if not firstRepaymentDate.tzinfo: tzname = self.disbursementDetails._tzattrs["firstRepaymentDate"] offset_str = tzname[3:] or "+00:00" tz_info = datetime.datetime.fromisoformat( "2000-01-01T00:00:00" + offset_str ).tzinfo firstRepaymentDate = firstRepaymentDate.astimezone(tz_info) firstRepaymentDate = firstRepaymentDate.isoformat() else: firstRepaymentDate = self.disbursementDetails.firstRepaymentDate if disbursementDate: if not disbursementDate.tzinfo: tzname = self.disbursementDetails._tzattrs["expectedDisbursementDate"] offset_str = tzname[3:] or "+00:00" tz_info = datetime.datetime.fromisoformat( "2000-01-01T00:00:00" + offset_str ).tzinfo disbursementDate = disbursementDate.astimezone(tz_info) disbursementDate = disbursementDate.isoformat() else: disbursementDate = self.disbursementDetails.expectedDisbursementDate self.disbursement_tr_resp = self._connector.mambu_make_disbursement( self.id, notes, firstRepaymentDate, disbursementDate, MambuDisbursementLoanTransactionInput._schema_fields, **kwargs ) self.refresh()
[docs] def reject(self, notes, **kwargs): """Request to reject a loan account. Args: notes (str): notes to attach to the reject operation. """ self.set_state("REJECT", notes, **kwargs)
[docs] def close(self, notes, **kwargs): """Request to close a loan account. Args: notes (str): notes to attach to the closing operation. """ self.set_state("CLOSE", notes, **kwargs)
[docs] def writeoff(self, notes, **kwargs): """Request to writeoff a loan account. Args: notes (str): notes to attach to the writting off operation. """ self._connector.mambu_loanaccount_writeoff(self.id, notes) self.refresh()
[docs] def repay(self, amount, notes, valueDate, **kwargs): """Request to repay a loan account. Args: amount (float): the amount of the repayment notes (str): notes to attach to the repayment transaction. valueDate (:py:obj:`datetime`): value date for the repayment operation. If naive datetime, use TZ info from tzattrs. kwargs (dict): allowed extra params for the repayment transaction request. :py:obj:`MambuPy.api.vos.MambuRepaymentLoanTransactionInput._schema_fields` has the allowed fields permitted for this operation. If transactionDetails is provided, it needs to have the structure defined at :py:obj:`MambuPy.api.vos.MambuLoanTransactionDetailsInput._schema_fields`. """ if not valueDate.tzinfo: tzname = self.disbursementDetails._tzattrs["firstRepaymentDate"] offset_str = tzname[3:] or "+00:00" tz_info = datetime.datetime.fromisoformat( "2000-01-01T00:00:00" + offset_str ).tzinfo valueDate = valueDate.astimezone(tz_info) valueDate = valueDate.isoformat() self._connector.mambu_make_repayment( self.id, amount, notes, valueDate, MambuRepaymentLoanTransactionInput._schema_fields, MambuLoanTransactionDetailsInput._schema_fields, **kwargs ) self.refresh()
[docs] def adjust_transaction(self, transactionId, notes, **kwargs): """Request to adjust a loan transaction. Args: transactionId (str): the id of the transaction to adjust notes (str): notes to attach to the adjusting transaction. """ if hasattr(self, "transactions"): if transactionId not in [t.id for t in self.transactions]: raise MambuPyError( "transactionId '{}' not found in loan transactions".format( transactionId ) ) self._connector.mambu_loantransaction_adjust(transactionId, notes) self.refresh()
[docs] def apply_fee(self, amount, installmentNumber, notes, valueDate, **kwargs): """Request to apply a fee to a loan account. Args: amount (float): the amount of the fee installmentNumber (int): the installment number to apply the fee notes (str): notes to attach to the fee transaction. valueDate (:py:obj:`datetime`): value date for the fee transaction. If naive datetime, use TZ info from tzattrs. kwargs (dict): allowed extra params for the fee transaction request. :py:obj:`MambuPy.api.vos.MambuFeeLoanTransactionInput._schema_fields` has the allowed fields permitted for this operation """ if not valueDate.tzinfo: tzname = self.disbursementDetails._tzattrs["firstRepaymentDate"] offset_str = tzname[3:] or "+00:00" tz_info = datetime.datetime.fromisoformat( "2000-01-01T00:00:00" + offset_str ).tzinfo valueDate = valueDate.astimezone(tz_info) valueDate = valueDate.isoformat() self._connector.mambu_make_fee( self.id, amount, installmentNumber, notes, valueDate, MambuFeeLoanTransactionInput._schema_fields, **kwargs ) self.refresh()