diff --git a/legal-api/src/legal_api/services/bootstrap.py b/legal-api/src/legal_api/services/bootstrap.py index 033c1c12aa..001a5e939d 100644 --- a/legal-api/src/legal_api/services/bootstrap.py +++ b/legal-api/src/legal_api/services/bootstrap.py @@ -320,3 +320,67 @@ def get_affiliations(cls, account: int): return affiliates.json().get("entities") return None + + @classmethod + def get_contacts(cls, config, org_id: str): + """Get contacts for the business. + Fetch Compelting Party Details from Auth API. + - GET /orgs/{org_id}/memeberships for user contacts details + - GET /orgs/{org_id} for org contacts details + """ + token = cls.get_bearer_token(config) + auth_url = config.AUTH_SVC_URL + + if not token: + return HTTPStatus.UNAUTHORIZED + + membership_response = requests.get( + url=f"{auth_url}/{org_id}/memberships", + headers={**cls.CONTENT_TYPE_JSON, + "Authorization": cls.BEARER + token}, + timeout=cls.timeout + ) + + org_info_response = requests.get( + url=f"{auth_url}/orgs/{org_id}", + headers={**cls.CONTENT_TYPE_JSON, + "Authorization": cls.BEARER + token}, + timeout=cls.timeout + ) + + if membership_response.status_code == HTTPStatus.OK and org_info_response.status_code == HTTPStatus.OK: + return None + + try: + membership_data = membership_response.json() + org_info = org_info_response.json() + + user_info = membership_data.get("user", {}) + first_name = user_info.get("firstName", "") + last_name = user_info.get("lastName", "") + + user_contacts = user_info.get("contacts", []) + user_contact = user_contacts[0] if user_contacts else {} + email = user_contact.get("email", "") + phone = user_contact.get("phone", "") + + org_contacts = org_info.get("contacts", []) + org_contact = org_contacts[0] if org_contacts else {} + + contact = { + "street": org_contact.get("street", ""), + "city": org_contact.get("city", ""), + "region": org_contact.get("region", ""), + "country": org_contact.get("country", ""), + "postalCode": org_contact.get("postalCode", ""), + "firstName": first_name, + "lastName": last_name, + "email": email, + "phone": phone, + "streetAdditional": org_contact.get("streetAdditional", ""), + "delieveryInstructions": org_contact.get("deliveryInstructions", "") + } + return {"contact": [contact]} + except Exception as e: + current_app.logger.error(f"Error fetching contacts: {e}") + return None \ No newline at end of file diff --git a/legal-api/src/legal_api/services/filings/validations/common_validations.py b/legal-api/src/legal_api/services/filings/validations/common_validations.py index fee85eca6a..04b3dd592f 100644 --- a/legal-api/src/legal_api/services/filings/validations/common_validations.py +++ b/legal-api/src/legal_api/services/filings/validations/common_validations.py @@ -26,6 +26,7 @@ from legal_api.errors import Error from legal_api.models import Address, Business, PartyRole from legal_api.services import MinioService, colin, flags, namex +from legal_api.services.bootstrap import AccountService from legal_api.services.permissions import ListActionsPermissionsAllowed, PermissionService from legal_api.services.utils import get_str from legal_api.utils.datetime import datetime as dt @@ -941,4 +942,77 @@ def validate_party_role_firms(parties: list, filing_type: str) -> list: "path": f"/filing/{filing_type}/parties" }) - return msg \ No newline at end of file + return msg + +def validate_completing_party(filing_json: dict, filing_type: str, org_id: int) -> list: + """Validate completing party edited.""" + msg = [] + parties = filing_json["filing"][filing_type].get("parties", {}) + + officer = None + for party in parties: + roles = party.get("roles", []) + if any(role.get("roleType").lower() == PartyRole.RoleTypes.COMPLETING_PARTY.value for role in roles): + officer = party.get("officer", {}) + break + if not officer: + msg.append({ + "error": "Completing party is required.", + "path": f"/filing/{filing_type}/parties" + }) + return msg + + filing_completing_party_mailing_address = officer.get("mailingAddress", {}) + filing_firstname = officer.get("firstName", "") + filing_lastname = officer.get("lastName", "") + filing_email = officer.get("email", "") + + contacts_response = AccountService.get_contacts(current_app.config, org_id) + if contacts_response is None: + msg.append({ + "error": "Unable to verify completing party against account contacts.", + "path": f"/filing/{filing_type}/parties" + }) + return msg + + contact = contacts_response["contacts"][0] + existing_cp_mailing_address = { + "streetAddress": contact.get("street", ""), + "addressCity": contact.get("city", ""), + "addressRegion": contact.get("region", ""), + "postalCode": contact.get("postalCode", ""), + "addressCountry": contact.get("country", ""), + "deliveryInstructions": contact.get("deliveryInstructions", ""), + "streetAddressAdditional": contact.get("streetAdditional", "") + } + existing_firstname = contact.get("firstName", "") + existing_lastname = contact.get("lastName", "") + existing_email = contact.get("email", "") + + address_changed = is_address_changed(existing_cp_mailing_address, filing_completing_party_mailing_address) + + existing_name = { + "firstName": existing_firstname, + "lastName": existing_lastname + } + filing_name = { + "firstName": filing_firstname, + "lastName": filing_lastname + } + + name_changed = is_name_changed(existing_name, filing_name) + + email_changed = not is_same_str(existing_email, filing_email) + + if address_changed or name_changed or email_changed: + permission_error = PermissionService.check_user_permission( + ListActionsPermissionsAllowed.EDITABLE_COMPLETING_PARTY.value, + message="Permission Denied - You do not have rights to edit completing address." + ) + if permission_error: + error_msg = permission_error.message[0]["message"] if permission_error.message else "You do not have rights to edit completing address." + msg.append({ + "error": error_msg, + "path": f"/filing/{filing_type}/parties" + }) + return msg