Стандартная банковская задача. Предыстория будет отдельным постом. Интересно как можно решить подобную задачу с использованием стат. типизации. Чтобы был контроль компилятором, не надо было полагаться на 100500 тестов, чтобы проверить, что определенные ветки не выполняются и т.п.
Есть модуль X, реализующий API-вызов «изменить сумму заказа».
Заказ
— может быть отправлен или неотправлен
— может быть предоплачен или не предоплачен
— может быть помечен, как несущий риск, или не помечен
(и т.п., см. по ходу пьесы)
Заказ — это сущность, получаемая из базы данных c уже готовыми свойствами. То есть нет последовательности вызовово create_order->risk_check->....->change_sum. Когда-то кем-то где-то был создан заказ. Через две недели мы получили API-вызов, который требует изменить сумму в этом заказе.
Изменение суммы может происходить только по определенным условиям и по определенным правилам, описанных в каждом шаге.
Конечно, в конце концов интересут решение Шага 3. Но интересно увидеть и весь процесс Шаг 1 -> Шаг 2 -> Шаг 3
Шаг 1
— если заказ неотправлен и непредоплачен, сумму можно увеличивать и уменьшать
— если заказ отправлен, сумму нельзя увеличивать, можно уменьшать
— если сумма увеличивается, мы должны провести risk check. если risk check не проходит, товар никак не помечается, но изменение суммы не проходит
— если товар помечен, как risk, то изменять сумму нельзя
Шаг 2
Потом оказалось, что не, так нельзя, поэтому внеслись изменения.
Изменение суммы:
Все то же самое, что и в первой задаче, только:
— увеличивать можно на max(фиксированная сумма1, процент1 от оригинальной суммы заказа)
— уменьшать можно на max(фиксированная сумма2, процент2 от оригинальной суммы заказа),
где сумма1, сумма2, процент1, процент2 — это конфигурация, считываемая из базы данных
Если изменение не попадает в эти рамки, то увеличить/уменьшить нельзя
Шаг 3
И этого оказалось недостаточно
Все то же самое, что и в шаге 2. Дополнительно:
— если заказ предоплачен (неважно, отправлен или нет), можно увеличивать сумму, если это разрешено конфигурацией магазина. Сумма, на которую можно увеличивать высчитывается, как в шаге 2
— если заказ предоплачен, неотправлен, и сумма увеличивается, надо сделать auth-запрос в банк. если он не срабатывает, увеличить нельзя.
— если заказ предоплачен, отправлен, и сумма увеличивается, надо сделать auth-запрос в банк на разницу в сумме, а потом сделать capture запрос на всю сумму. Если хоть один из них не срабатывает, увеличить нельзя.