File size: 5,835 Bytes
52c1998
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import datetime
import re

from dateutil.relativedelta import relativedelta
from pydantic import (
    BaseModel,
    computed_field,
    Field,
    ValidationInfo,
    model_validator,
    ConfigDict
)
import pandas as pd


class CustomAppFormUpload(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    # application_summary_full_name: str | None = Field(None, alias="full_name")
    # application_summary_bank_name: str | None = Field(None, alias="bank_name")
    # application_summary_employer_name: str | None = Field(None, alias="employer_name")
    # application_summary_complete_address: str | None = Field(None, alias="complete_address")
    application_summary_full_name: str = Field(alias="full_name")
    application_summary_bank_name: str = Field(alias="bank_name")
    application_summary_employer_name: str = Field(alias="employer_name")
    application_summary_complete_address: str = Field(alias="complete_address")

    full_name_err_msgs: str | None = None
    bank_name_err_msgs: str | None = None
    employer_name_err_msgs: str | None = None
    complete_employee_address_err_msgs: str | None = None
    validation_policy_status_df: pd.DataFrame = pd.DataFrame(
        columns=["Policy", "Value", "Status", "Message"])
    # is_incomplete: bool = False

    @model_validator(mode="after")
    def validate_full_name(self, info: ValidationInfo):
        """Validate provided applicant's full name"""
        try:
            err_msgs = []

            full_name_val = self.application_summary_full_name
            if not full_name_val:
                err_msgs.append("Applicant's full name not present")

            full_name_val_len = 0
            if full_name_val:
                full_name_val_len = len(full_name_val)
            if not full_name_val and not (
                full_name_val_len >= 2 and full_name_val_len <= 61
            ):
                err_msgs.append(
                    "Full name must have a length of at least 2 & at most 61"
                )

            if not full_name_val or len(full_name_val.strip().split(" ")) < 2:
                err_msgs.append(
                    "Full name must consist of at least 2 words (first name + last name)"
                )

            if err_msgs:
                self.full_name_err_msgs = ", ".join(err_msgs)
            else:
                self.full_name_err_msgs = None

            return self
        except Exception as e:
            # logger.exception(e, exc_info=True)
            # return None
            raise

    @model_validator(mode="after")
    def validate_bank_name(self, info: ValidationInfo):
        """Validate provided bank name"""
        try:
            err_msgs = []
            bank_name_val = self.application_summary_bank_name
            if not bank_name_val:
                err_msgs.append("Bank name not present")

            bank_name_val_len = 0
            if bank_name_val:
                bank_name_val_len = len(bank_name_val)
            if not bank_name_val and not (
                bank_name_val_len >= 4 and bank_name_val_len <= 50
            ):
                err_msgs.append(
                    "Bank name must have a length of at least 4 & at most 50"
                )

            if err_msgs:
                self.bank_name_err_msgs = ", ".join(err_msgs)
            else:
                self.bank_name_err_msgs = None

            return self
        except Exception as e:
            # logger.exception(e, exc_info=True)
            # return None
            raise

    @model_validator(mode="after")
    def validate_employer_name(self, info: ValidationInfo):
        """Validate provided employer name"""
        try:
            err_msgs = []
            employer_name_val = self.application_summary_employer_name

            if not employer_name_val:
                err_msgs.append("Employer name not present")

            # # Allowed: letters, numbers, spaces, and common name punctuation
            # pattern = r"^[A-Za-z0-9&\-,.()'/@ ]{2,100}$"
            # if not re.match(pattern, employer_name_val):
            #     err_msgs.append("Employer name contains invalid characters")
            if not re.search(r"[A-Za-z]", employer_name_val):
                err_msgs.append(
                    "Employer name must contain at least one letter")
            if employer_name_val.strip() == "":
                err_msgs.append("Employer name cannot be only whitespace")

            self.employer_name_err_msgs = ", ".join(
                err_msgs) if err_msgs else None
            return self
        except Exception as e:
            # logger.exception(e, exc_info=True)
            # return None
            raise

    @model_validator(mode="after")
    def validate_complete_address(self, info: ValidationInfo):
        try:
            err_msgs = []
            val = self.application_summary_complete_address

            if not val:
                err_msgs.append("Applicant's address not present")

            length = len(val) if val else 0
            if not (10 <= length <= 300):
                err_msgs.append(
                    "Applicant's complete address must have a length of at least 10 & at most 300"
                )

            self.complete_employee_address_err_msgs = (
                ", ".join(err_msgs) if err_msgs else None
            )
            return self
        except Exception as e:
            # logger.exception(e, exc_info=True)
            # return None
            raise

    @computed_field
    @property
    def is_incomplete(self) -> bool:
        if any([
            self.full_name_err_msgs,
            self.bank_name_err_msgs,
            self.employer_name_err_msgs,
            self.complete_employee_address_err_msgs,
        ]):
            return True
        return False