Skip to content

Commit

Permalink
Refactor CreateMarriageHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
madnoberson committed Dec 25, 2023
1 parent 776affd commit fe04011
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 73 deletions.
125 changes: 55 additions & 70 deletions src/amdb/application/command_handlers/person/create_marriage.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
PERSONS_DO_NOT_EXIST,
PERSON_IS_MARRIED,
MARRIAGE_ALREADY_EXISTS,
PERSONS_HAVE_SAME_SEX,
)
from amdb.application.common.exception import ApplicationError

Expand Down Expand Up @@ -53,19 +52,40 @@ def execute(self, command: CreateMarriageCommand) -> MarriageId:
if not access:
raise ApplicationError(CREATE_MARRIAGE_ACCESS_DENIED)

husband, wife = self._ensure_husband_and_wife(
husband_id=command.husband_id,
wife_id=command.wife_id,
self._ensure_valid_command(
command=command,
)

husband = self._person_gateway.with_id(
person_id=command.husband_id,
)
if husband is None:
raise ApplicationError(
message=PERSON_DOES_NOT_EXIST,
extra={"person_id": command.husband_id},
)

wife = self._person_gateway.with_id(
person_id=command.wife_id,
)
if wife is None:
raise ApplicationError(
message=PERSON_DOES_NOT_EXIST,
extra={"person_id": command.wife_id},
)

self._ensure_can_create_marriage(
husband=husband,
wife=wife,
status=command.status,
)
children = self._ensure_children(
father=husband,
mother=wife,
child_ids=command.child_ids,

children = self._person_gateway.list_with_ids(
*command.child_ids,
)
self._ensure_persons(
requested_person_ids=command.child_ids,
persons=children,
)

marriage = self._create_marriage(
Expand Down Expand Up @@ -95,43 +115,30 @@ def execute(self, command: CreateMarriageCommand) -> MarriageId:

return marriage.id

def _ensure_husband_and_wife(
def _ensure_valid_command(
self,
*,
husband_id: PersonId,
wife_id: PersonId,
) -> tuple[Person, Person]:
husband = self._person_gateway.with_id(
person_id=husband_id,
)
if husband is None:
raise ApplicationError(
message=PERSON_DOES_NOT_EXIST,
extra={"person_id": husband_id},
)

wife = self._person_gateway.with_id(
person_id=wife_id,
)
if wife is None:
command: CreateMarriageCommand,
) -> None:
if command.husband_id in command.child_ids or command.wife_id in command.child_ids:
raise ApplicationError(
message=PERSON_DOES_NOT_EXIST,
extra={"person_id": wife_id},
message=CREATE_MARRIAGE_INVALID_COMMAND,
extra={"details": "Child ids contain id of husband or wife"},
)

if husband.sex == wife.sex:
raise ApplicationError(PERSONS_HAVE_SAME_SEX)

return (husband, wife)

def _ensure_can_create_marriage(
self,
*,
husband: Person,
wife: Person,
status: MarriageStatus,
) -> None:
valid_marriage_statuses = (
valid_marriage_statuses_for_new_marriage_to_have = (
MarriageStatus.MARRIAGE,
MarriageStatus.HE_FILED_FOR_DIVORCE,
MarriageStatus.SHE_FILED_FOR_DIVORCE,
)
valid_marriage_statuses_for_spouses_to_have = (
MarriageStatus.DIVORCE,
MarriageStatus.HIS_DEATH,
MarriageStatus.HER_DEATH,
Expand All @@ -142,13 +149,8 @@ def _ensure_can_create_marriage(
)
for husband_marriage in husband_marriages:
if (
status
in (
MarriageStatus.MARRIAGE,
MarriageStatus.HE_FILED_FOR_DIVORCE,
MarriageStatus.SHE_FILED_FOR_DIVORCE,
)
and husband_marriage.status not in valid_marriage_statuses
status in valid_marriage_statuses_for_new_marriage_to_have
and husband_marriage.status not in valid_marriage_statuses_for_spouses_to_have
):
if husband_marriage.wife_id == wife.id:
raise ApplicationError(MARRIAGE_ALREADY_EXISTS)
Expand All @@ -163,47 +165,30 @@ def _ensure_can_create_marriage(
)
for wife_marriage in wife_marriages:
if (
status
in (
MarriageStatus.MARRIAGE,
MarriageStatus.HE_FILED_FOR_DIVORCE,
MarriageStatus.SHE_FILED_FOR_DIVORCE,
)
and wife_marriage.status not in valid_marriage_statuses
status in valid_marriage_statuses_for_new_marriage_to_have
and wife_marriage.status not in valid_marriage_statuses_for_spouses_to_have
):
raise ApplicationError(
message=PERSON_IS_MARRIED,
extra={"person_id": wife.id},
)

def _ensure_children(
def _ensure_persons(
self,
*,
father: Person,
mother: Person,
child_ids: list[PersonId],
) -> list[Person]:
if father.id in child_ids or mother.id in child_ids:
raise ApplicationError(
message=CREATE_MARRIAGE_INVALID_COMMAND,
extra={"details": "`child_ids` contains `husband_id` or `wife_id`"},
)

children = self._person_gateway.list_with_ids(
*child_ids,
)
if len(children) != len(child_ids):
child_ids_from_gateway = [child.id for child in children]
requested_person_ids: list[PersonId],
persons: list[Person],
) -> None:
if len(requested_person_ids) != len(persons):
person_ids = [person.id for person in persons]

invalid_child_ids = []
for child_id in child_ids:
if child_id in child_ids_from_gateway:
invalid_person_ids = []
for requested_person_id in requested_person_ids:
if requested_person_id in person_ids:
continue
invalid_child_ids.append(child_id)
invalid_person_ids.append(requested_person_id)

raise ApplicationError(
message=PERSONS_DO_NOT_EXIST,
extra={"person_ids": invalid_child_ids},
extra={"person_ids": invalid_person_ids},
)

return children
1 change: 0 additions & 1 deletion src/amdb/application/common/constants/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@
PERSON_DOES_NOT_EXIST = "Person doesn't exist"
PERSONS_DO_NOT_EXIST = "Persons don't exist"
PERSON_IS_MARRIED = "Person is married"
PERSONS_HAVE_SAME_SEX = "Persons have the same sex"
MARRIAGE_DOES_NOT_EXIST = "Marriage doesn't exist"
MARRIAGE_ALREADY_EXISTS = "Marriage already exists"
2 changes: 2 additions & 0 deletions src/amdb/domain/constants/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
PERSONS_HAVE_SAME_SEX = "Persons have the same sex"

CANNOT_REMOVE_GENRE_FROM_SERIES = (
"Cannot delete a genre because it belongs to one of the episodes of the series"
)
Expand Down
5 changes: 5 additions & 0 deletions src/amdb/domain/services/person/create_marriage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from amdb.domain.value_objects import Date
from amdb.domain.entities.person.person import Person
from amdb.domain.entities.person.marriage import MarriageId, MarriageStatus, Marriage
from amdb.domain.constants.exceptions import PERSONS_HAVE_SAME_SEX
from amdb.domain.exception import DomainError


class CreateMarriage(Service):
Expand All @@ -20,6 +22,9 @@ def __call__(
start_date: Optional[Date] = None,
end_date: Optional[Date] = None,
) -> Marriage:
if husband.sex == wife.sex:
raise DomainError(PERSONS_HAVE_SAME_SEX)

husband.updated_at = timestamp
wife.updated_at = timestamp

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from amdb.domain.constants.common import Sex
from amdb.domain.services.user.access_concern import AccessConcern
from amdb.domain.services.person.create_marriage import CreateMarriage
from amdb.domain.constants.exceptions import PERSONS_HAVE_SAME_SEX
from amdb.domain.exception import DomainError
from amdb.application.common.interfaces.gateways.user.access_policy import AccessPolicyGateway
from amdb.application.common.interfaces.gateways.person.marriage import MarriageGateway
from amdb.application.common.interfaces.gateways.person.person import PersonGateway
Expand All @@ -24,7 +26,6 @@
PERSONS_DO_NOT_EXIST,
PERSON_IS_MARRIED,
MARRIAGE_ALREADY_EXISTS,
PERSONS_HAVE_SAME_SEX,
)
from amdb.application.common.exception import ApplicationError
from amdb.application.commands.person.create_marriage import CreateMarriageCommand
Expand Down Expand Up @@ -445,7 +446,7 @@ def when_husband_and_wife_have_same_sex(
unit_of_work=unit_of_work,
)

with pytest.raises(ApplicationError) as error:
with pytest.raises(DomainError) as error:
create_marriage_handler.execute(
command=create_marriage_command,
)
Expand Down

0 comments on commit fe04011

Please sign in to comment.