Spaces:
Build error
Build error
| import datetime | |
| from dateutil.relativedelta import relativedelta | |
| from pydantic import ( | |
| BaseModel, | |
| computed_field, | |
| Field, | |
| ValidationInfo, | |
| model_validator, | |
| ConfigDict | |
| ) | |
| import pandas as pd | |
| class UKPassportSchema(BaseModel): | |
| model_config = ConfigDict(arbitrary_types_allowed=True) | |
| full_name: str | None = Field( | |
| default=None, | |
| description="Applicant's full name. Must consist of at least 2 words, have length gte 2 & lte 61", | |
| examples=["Jodie Pippa"], | |
| ) # , min_length=2, max_length=61) | |
| expiry_date: datetime.date | None = Field( | |
| default=None, | |
| description="The passport's expiry date in YYYY-MM-DD format", | |
| examples=["2028-06-01"], | |
| ) | |
| full_name_err_msgs: str | None = None | |
| expiry_date_err_msgs: str | None = None | |
| validation_policy_status_df: pd.DataFrame = pd.DataFrame( | |
| columns=["Policy", "Value", "Status", "Message"]) | |
| def validate_expiry_date(cls, values): | |
| try: | |
| err_msgs = list() | |
| expiry_date_val = values.expiry_date | |
| if not expiry_date_val: | |
| err_msgs.append("Expiry date must be present") | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = ["Expiry date must be present", values.expiry_date, False, "Expiry date is not present"] | |
| else: | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = ["Expiry date must be present", values.expiry_date, True, "Expiry date is present"] | |
| if expiry_date_val < datetime.date.today() + relativedelta(years=1): | |
| # raise ValueError("Provided passport expires within 1 year") | |
| err_msgs.append("Provided passport expires within 1 year") | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Provided passport expiry should be more than 1 year", | |
| values.expiry_date, | |
| False, | |
| "Provided passport expires within 1 year &/or is expired", | |
| ] | |
| else: | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Provided passport expiry should be more than 1 year", | |
| values.expiry_date, | |
| True, | |
| "Provided passport does not expire within 1 year", | |
| ] | |
| values.expiry_date_err_msgs = ", ".join( | |
| err_msgs) if err_msgs else None | |
| return values | |
| except Exception as e: | |
| raise | |
| # if not values.expiry_date_err_msgs: | |
| # values.expiry_date_err_msgs = "Provided passport expires within 1 year" | |
| # else: | |
| # values.expiry_date_err_msgs = f"{values.expiry_date_err_msgs}, Provided passport expires within 1 year" | |
| # if not values.expiry_date_err_msgs: | |
| # values.expiry_date_err_msgs = None | |
| # return values | |
| def validate_full_name(cls, values, info: ValidationInfo): | |
| """Match applicant's full name against provided name (case-insensitive)""" | |
| try: | |
| err_msgs = [] | |
| expected = ( | |
| info.context.get("application_summary_full_name") | |
| if info.context | |
| else None | |
| ) | |
| full_name_val = values.full_name | |
| if not full_name_val: | |
| err_msgs.append("Applicant's full name not present") | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = ["Applicant's full name should be present", full_name_val, False, "Applicant's full name not present"] | |
| else: | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = ["Applicant's full name should be present", full_name_val, True, "Applicant's full name is 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" | |
| ) | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = [ "Full name must have a length of at least 2 & at most 61", full_name_val_len, False, "Full name does not have a length of at least 2 & at most 61"] | |
| else: | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = [ "Full name must have a length of at least 2 & at most 61", full_name_val_len, True, "Full name has a length of at least 2 & at most 61"] | |
| if ( | |
| not expected | |
| or not full_name_val | |
| or full_name_val.lower() != expected.lower() | |
| ): | |
| err_msgs.append("Name mismatch with provided value") | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = ["Name should match with provided value", full_name_val, False, "Name does not match with provided value"] | |
| else: | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = ["Name should match with provided value", full_name_val, True, "Name matches with provided value"] | |
| 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)" | |
| ) | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = ["Full name must consist of at least 2 words (first name + last name)", len(full_name_val.strip().split(" ")), False, "Full name does not consist of at least 2 words (first name + last name)"] | |
| else: | |
| values.validation_policy_status_df.loc[len( | |
| values.validation_policy_status_df)] = ["Full name must consist of at least 2 words (first name + last name)", len(full_name_val.strip().split(" ")), True, "Full name does consist of at least 2 words (first name + last name)"] | |
| if err_msgs: | |
| values.full_name_err_msgs = ", ".join(err_msgs) | |
| else: | |
| values.full_name_err_msgs = None | |
| return values | |
| except Exception as e: | |
| # logger.exception(e, exc_info=True) | |
| # return None | |
| raise | |
| def is_red_flagged(self) -> bool: | |
| if self.full_name_err_msgs or self.expiry_date_err_msgs: | |
| return True | |
| return False | |
| class UKDrivingLicense(BaseModel): | |
| model_config = ConfigDict(arbitrary_types_allowed=True) | |
| full_name: str | None = Field( | |
| default=None, | |
| description="Applicant's full name. Must consist of at least 2 words, have length gte 2 & lte 61", | |
| examples=["Jodie Pippa"], | |
| ) # , min_length=2, max_length=61) | |
| full_name_err_msgs: str | None = None | |
| expiry_date_err_msgs: str | None = None | |
| validation_policy_status_df: pd.DataFrame = pd.DataFrame( | |
| columns=["Policy", "Value", "Status", "Message"]) | |
| def validate_full_name(cls, values, info: ValidationInfo): | |
| """Match applicant's full name against provided name (case-insensitive)""" | |
| try: | |
| err_msgs = [] | |
| expected = ( | |
| info.context.get("application_summary_full_name") | |
| if info.context | |
| else None | |
| ) | |
| full_name_val = values.full_name | |
| if not full_name_val: | |
| err_msgs.append("Applicant's full name not present") | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Applicant's full name should be present", | |
| full_name_val, | |
| False, | |
| "Applicant's full name not present", | |
| ] | |
| else: | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Applicant's full name should be present", | |
| full_name_val, | |
| True, | |
| "Applicant's full name is 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" | |
| ) | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Full name must have a length of at least 2 & at most 61", | |
| full_name_val_len, | |
| False, | |
| "Full name does not have a length of at least 2 & at most 61", | |
| ] | |
| else: | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Full name must have a length of at least 2 & at most 61", | |
| full_name_val_len, | |
| True, | |
| "Full name has a length of at least 2 & at most 61", | |
| ] | |
| if ( | |
| not expected | |
| or not full_name_val | |
| or full_name_val.lower() != expected.lower() | |
| ): | |
| err_msgs.append("Name mismatch with provided value") | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Name should match with provided value", | |
| full_name_val, | |
| False, | |
| "Name does not match with provided value", | |
| ] | |
| else: | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Name should match with provided value", | |
| full_name_val, | |
| True, | |
| "Name matches with provided value", | |
| ] | |
| 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)" | |
| ) | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Full name must consist of at least 2 words (first name + last name)", | |
| len(full_name_val.strip().split(" ")), | |
| False, | |
| "Full name does not consist of at least 2 words (first name + last name)", | |
| ] | |
| else: | |
| values.validation_policy_status_df.loc[ | |
| len(values.validation_policy_status_df) | |
| ] = [ | |
| "Full name must consist of at least 2 words (first name + last name)", | |
| len(full_name_val.strip().split(" ")), | |
| True, | |
| "Full name does consist of at least 2 words (first name + last name)", | |
| ] | |
| if err_msgs: | |
| values.full_name_err_msgs = ", ".join(err_msgs) | |
| else: | |
| values.full_name_err_msgs = None | |
| return values | |
| except Exception as e: | |
| # logger.exception(e, exc_info=True) | |
| # return None | |
| raise | |
| def is_red_flagged(self) -> bool: | |
| if self.full_name_err_msgs or self.expiry_date_err_msgs: | |
| return True | |
| return False | |