Initial commit
This commit is contained in:
+459
@@ -0,0 +1,459 @@
|
||||
"""
|
||||
Data models for request and response validation.
|
||||
"""
|
||||
from dataclasses import dataclass, field, asdict
|
||||
from typing import List, Dict, Any, Optional, TypeVar, Type, cast
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
T = TypeVar('T', bound='BaseModel')
|
||||
|
||||
class BaseModel:
|
||||
"""Base model with serialization capabilities."""
|
||||
|
||||
def __init__(self):
|
||||
self.type_field = None
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert model to dictionary."""
|
||||
result = {k: v for k, v in asdict(self).items() if v is not None}
|
||||
# Handle special case for type_field
|
||||
if hasattr(self, 'type_field') and self.type_field is not None:
|
||||
result['$type'] = self.type_field
|
||||
del result['type_field']
|
||||
return result
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Convert model to JSON string."""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls: Type[T], data: Dict[str, Any]) -> T:
|
||||
"""Create model instance from dictionary."""
|
||||
# Handle special case for $type field
|
||||
if '$type' in data:
|
||||
data_copy = data.copy()
|
||||
data_copy['type_field'] = data_copy.pop('$type')
|
||||
data = data_copy
|
||||
|
||||
return cls(**{k: v for k, v in data.items() if k in cls.__annotations__})
|
||||
|
||||
@dataclass
|
||||
class EligibilityCheckRequest(BaseModel):
|
||||
"""Model for eligibility check request."""
|
||||
type_field: str # This will be mapped to $type in JSON
|
||||
transactionId: str
|
||||
countryCode: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
lienAmount: float
|
||||
channel: str
|
||||
msisdn: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class EligibleOffer(BaseModel):
|
||||
"""Model for eligible offer."""
|
||||
minamount: float
|
||||
maxamount: float
|
||||
productId: int
|
||||
offerid: int
|
||||
Tenor: int
|
||||
|
||||
@dataclass
|
||||
class EligibilityCheckResponse(BaseModel):
|
||||
"""Model for eligibility check response."""
|
||||
customerId: str
|
||||
transactionId: str
|
||||
eligibleOffers: List[Dict[str, Any]]
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
msisdn: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class SelectOffersRequest(BaseModel):
|
||||
"""Model for select offers request."""
|
||||
requestId: str
|
||||
transactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
msisdn: str
|
||||
requestedAmount: float
|
||||
productid: str
|
||||
channel: str
|
||||
|
||||
@dataclass
|
||||
class Offer(BaseModel):
|
||||
"""Model for offer details."""
|
||||
offerId: str
|
||||
productId: str
|
||||
amount: float
|
||||
upfrontPayment: float
|
||||
interestRate: float
|
||||
Interest: float
|
||||
ManagementRate: float
|
||||
ManagementFee: float
|
||||
InsuranceRate: float
|
||||
InsuranceFee: float
|
||||
VATRate: float
|
||||
VATamount: float
|
||||
recommendedRepaymentDates: List[str]
|
||||
installmentAmount: float
|
||||
totalRepaymentAmount: float
|
||||
|
||||
@dataclass
|
||||
class SelectOffersResponse(BaseModel):
|
||||
"""Model for select offers response."""
|
||||
requestId: str
|
||||
transactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
offers: List[Dict[str, Any]]
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
outstandingDebtAmount: Optional[float] = 0
|
||||
|
||||
@dataclass
|
||||
class ProvideLoanRequest(BaseModel):
|
||||
"""Model for provide loan request."""
|
||||
type_field: str # This will be mapped to $type in JSON
|
||||
requestId: str
|
||||
transactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
productId: str
|
||||
lienAmount: float
|
||||
requestedAmount: float
|
||||
collectionType: int
|
||||
loanType: int
|
||||
channel: str
|
||||
msisdn: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class ProvideLoanResponse(BaseModel):
|
||||
"""Model for provide loan response."""
|
||||
requestId: str
|
||||
transactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
msisdn: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class LoanInformationRequest(BaseModel):
|
||||
"""Model for loan information request."""
|
||||
type_field: str # This will be mapped to $type in JSON
|
||||
transactionId: str
|
||||
customerId: str
|
||||
channel: str
|
||||
msisdn: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class Loan(BaseModel):
|
||||
"""Model for loan details."""
|
||||
debtId: str
|
||||
loanDate: str
|
||||
dueDate: str
|
||||
currentLoanAmount: float
|
||||
initialLoanAmount: float
|
||||
defaultFee: float
|
||||
continiousFee: float
|
||||
productId: str
|
||||
|
||||
@dataclass
|
||||
class LoanInformationResponse(BaseModel):
|
||||
"""Model for loan information response."""
|
||||
customerId: str
|
||||
loans: List[Dict[str, Any]]
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
totalDebtAmount: Optional[float] = None
|
||||
|
||||
@dataclass
|
||||
class RepaymentRequest(BaseModel):
|
||||
"""Model for repayment request."""
|
||||
type_field: str # This will be mapped to $type in JSON
|
||||
transactionId: str
|
||||
customerId: str
|
||||
debtId: str
|
||||
productId: str
|
||||
channel: str
|
||||
msisdn: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class RepaymentResponse(BaseModel):
|
||||
"""Model for repayment response."""
|
||||
customerId: str
|
||||
productId: str
|
||||
debtId: str
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class CustomerConsentRequest(BaseModel):
|
||||
"""Model for customer consent request."""
|
||||
type_field: str # This will be mapped to $type in JSON
|
||||
transactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
requestTime: str
|
||||
consentType: str
|
||||
channel: str
|
||||
|
||||
@dataclass
|
||||
class CustomerConsentResponse(BaseModel):
|
||||
"""Model for customer consent response."""
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class NotificationCallbackRequest(BaseModel):
|
||||
"""Model for notification callback request."""
|
||||
fbnTransactionId: str
|
||||
transactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
debtId: str
|
||||
transactionType: str
|
||||
amountProvided: float
|
||||
amountCollected: float
|
||||
responseCode: str
|
||||
responseDescription: str
|
||||
|
||||
@dataclass
|
||||
class NotificationCallbackResponse(BaseModel):
|
||||
"""Model for notification callback response."""
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class RACCheckRequest(BaseModel):
|
||||
"""Model for RAC check request."""
|
||||
transactionId: str
|
||||
fbnTransactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
RAC_Array: List[str]
|
||||
|
||||
@dataclass
|
||||
class RACResponse(BaseModel):
|
||||
"""Model for RAC response details."""
|
||||
SalaryAccount: Optional[str] = None
|
||||
BVN: Optional[str] = None
|
||||
BVNAttachedtoAccount: Optional[str] = None
|
||||
CRMS: Optional[str] = None
|
||||
CRC: Optional[str] = None
|
||||
AccountStatus: Optional[str] = None
|
||||
Lien: Optional[str] = None
|
||||
NoBounchedCheck: Optional[str] = None
|
||||
Whitelist: Optional[str] = None
|
||||
NoPastDueSalaryLoan: Optional[str] = None
|
||||
NoPastDueOtherLoan: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class RACCheckResponse(BaseModel):
|
||||
"""Model for RAC check response."""
|
||||
RACResponse: Dict[str, Any]
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class DisbursementRequest(BaseModel):
|
||||
"""Model for disbursement request."""
|
||||
requestId: str
|
||||
debtId: str
|
||||
transactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
productId: str
|
||||
provideAmount: float
|
||||
countryId: str
|
||||
collectAmountInterest: Optional[float] = None
|
||||
collectAmountMgtFee: Optional[float] = None
|
||||
collectAmountInsurance: Optional[float] = None
|
||||
collectAmountVAT: Optional[float] = None
|
||||
comment: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class DisbursementResponse(BaseModel):
|
||||
"""Model for disbursement response."""
|
||||
requestId: str
|
||||
debtId: str
|
||||
transactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
productId: str
|
||||
provideAmount: float
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
collectAmountInterest: Optional[float] = None
|
||||
collectAmountMgtFee: Optional[float] = None
|
||||
collectAmountInsurance: Optional[float] = None
|
||||
collectAmountVAT: Optional[float] = None
|
||||
|
||||
@dataclass
|
||||
class CollectLoanRequest(BaseModel):
|
||||
"""Model for collect loan request."""
|
||||
transactionId: str
|
||||
fbnTransactionId: str
|
||||
debtId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
productId: str
|
||||
collectAmount: float
|
||||
collectionMethod: int
|
||||
lienAmount: float
|
||||
countryId: str
|
||||
penalCharge: Optional[float] = 0.0
|
||||
comment: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class CollectLoanResponse(BaseModel):
|
||||
"""Model for collect loan response."""
|
||||
transactionId: str
|
||||
debtId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
productId: str
|
||||
collectAmount: float
|
||||
lienAmount: float
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
penalCharge: Optional[float] = 0.0
|
||||
|
||||
@dataclass
|
||||
class TransactionCheckRequest(BaseModel):
|
||||
"""Model for transaction check request."""
|
||||
counter: str
|
||||
TransactionId: str
|
||||
requestID: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
countryId: str
|
||||
transactionType: str
|
||||
|
||||
@dataclass
|
||||
class TransactionCheckResponse(BaseModel):
|
||||
"""Model for transaction check response."""
|
||||
type_field: str # This will be mapped to $type in JSON
|
||||
nativeId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
providedAmount: float
|
||||
collectedAmount: float
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class PenalChargeRequest(BaseModel):
|
||||
"""Model for penal charge request."""
|
||||
transactionId: str
|
||||
fbnTransactionId: str
|
||||
debtId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
penalCharge: float
|
||||
lienAmount: float
|
||||
countryId: str
|
||||
comment: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class PenalChargeResponse(BaseModel):
|
||||
"""Model for penal charge response."""
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class RevokeEnableConsentRequest(BaseModel):
|
||||
"""Model for revoke/enable consent request."""
|
||||
transactionId: str
|
||||
fbnTransactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
processTime: str
|
||||
consentType: str
|
||||
countryId: str
|
||||
comment: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class RevokeEnableConsentResponse(BaseModel):
|
||||
"""Model for revoke/enable consent response."""
|
||||
type_field: str # This will be mapped to $type in JSON
|
||||
customerId: str
|
||||
accountId: str
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class ValidateTokenRequest(BaseModel):
|
||||
"""Model for validate token request."""
|
||||
RequestId: str
|
||||
UserId: str
|
||||
CountryId: str
|
||||
TokenCode: str
|
||||
|
||||
@dataclass
|
||||
class ValidateTokenResponse(BaseModel):
|
||||
"""Model for validate token response."""
|
||||
Authenticated: bool
|
||||
AuthenticatedMessage: str
|
||||
ResponseCode: str
|
||||
ResponseMessage: str
|
||||
RequestId: str
|
||||
|
||||
@dataclass
|
||||
class LienCheckRequest(BaseModel):
|
||||
"""Model for lien check request."""
|
||||
transactionId: str
|
||||
customerId: str
|
||||
accountId: str
|
||||
countryId: str
|
||||
|
||||
@dataclass
|
||||
class LienCheckResponse(BaseModel):
|
||||
"""Model for lien check response."""
|
||||
lienAmount: float
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class NewTransactionCheckRequest(BaseModel):
|
||||
"""Model for new transaction check request."""
|
||||
transactionId: str
|
||||
debtId: str
|
||||
transactionType: str
|
||||
fbnTransactionId: str
|
||||
origTransactionId: str
|
||||
customerId: str
|
||||
|
||||
@dataclass
|
||||
class TransactionData(BaseModel):
|
||||
"""Model for transaction data."""
|
||||
transactionId: str
|
||||
providedAmount: float
|
||||
collectedAmount: float
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class NewTransactionCheckResponse(BaseModel):
|
||||
"""Model for new transaction check response."""
|
||||
transactionId: str
|
||||
data: Dict[str, Any]
|
||||
resultCode: str
|
||||
resultDescription: str
|
||||
|
||||
@dataclass
|
||||
class SMSRequest(BaseModel):
|
||||
"""Model for SMS request."""
|
||||
text: str
|
||||
dest: str
|
||||
unicode: bool
|
||||
|
||||
@dataclass
|
||||
class SMSResponse(BaseModel):
|
||||
"""Model for SMS response."""
|
||||
data: str
|
||||
statusCode: int
|
||||
IsSuccessful: bool
|
||||
errorMessage: Optional[str] = None
|
||||
Reference in New Issue
Block a user