import abc from enums.enums import Questions, DetailsType class SavedDetails(abc.ABC): excluded_fields = ["type_"] def __init__(self, type_: DetailsType, key: str = None): self.type_ = type_ self.key = key @classmethod def load(cls, data: dict): type_ = data.get("type_") if not type_ or type_ != cls.type_: raise ValueError(f"the expected type is {cls.type_} but is actually {type_}") return cls.__init__(**{k: v for k, v in data if k != "type"}) def to_json(self): self.key = self.key.replace(" ", "_") return {k: v for k, v in self.__dict__.items() if k not in self.excluded_fields} def to_answers(self): pass def short_description(self): return ", ".join([v for k, v in self.__dict__.items() if k not in self.excluded_fields]) def widget_labels(self) -> dict[str, str]: fields = {k: " ".join(k.title().split("_")) for k in self.__dict__ if k not in self.excluded_fields and k != "key"} fields["key"] = "Save as" return fields class PersonalDetails(SavedDetails): def __init__(self, key: str = None, full_name: str = None, email: str = None, contact_number: str = None, *_): super().__init__(DetailsType.PERSONAL_DETAILS, key) self.full_name = full_name self.email = email self.contact_number = contact_number def to_answers(self) -> dict[Questions, str]: answers = {} if self.full_name is not None: answers[Questions.FULL_NAME] = self.full_name if self.email is not None: answers[Questions.YOUR_EMAIL] = self.email if self.contact_number is not None: answers[Questions.CONTACT_NUMBER] = self.contact_number return answers class LocationDetails(SavedDetails): type_ = DetailsType.LOCATION_DETAILS def __init__(self, owner_or_tenant: str = None, community: str = None, building: str = None, unit_number: str = None, key: str = None, *_): super().__init__(self.type_, key) self.owner_or_tenant = owner_or_tenant self.community = community self.building = building self.unit_number = unit_number def to_answers(self) -> dict[Questions, str]: answers = {} if self.owner_or_tenant is not None: answers[Questions.OWNER_OR_TENANT] = self.owner_or_tenant if self.building is not None: answers[Questions.BUILDING] = self.building if self.community is not None: answers[Questions.COMMUNITY] = self.community if self.unit_number is not None: answers[Questions.UNIT_APT_NUMBER] = self.unit_number return answers class ContractorDetails(SavedDetails): type_ = DetailsType.CONTRACTOR_DETAILS def __init__(self, contractor_name: str = None, contractor_contact_number: str = None, contractor_email: str = None, key: str = None, *_): super().__init__(self.type_, key) self.contractor_name = contractor_name self.contractor_contact_number = contractor_contact_number self.contractor_email = contractor_email def to_answers(self) -> dict[Questions, str]: answers = {} if self.contractor_email is not None: answers[Questions.COMPANY_EMAIL] = self.contractor_email if self.contractor_contact_number is not None: answers[Questions.COMPANY_NUMBER] = self.contractor_contact_number if self.contractor_name is not None: answers[Questions.COMPANY_NAME] = self.contractor_name return answers detail_classes = { DetailsType.LOCATION_DETAILS: LocationDetails, DetailsType.PERSONAL_DETAILS: PersonalDetails, DetailsType.CONTRACTOR_DETAILS: ContractorDetails }