← All posts tagged динамика

*erlang *haskell *ктонановенького

Стандартная банковская задача. Предыстория будет отдельным постом. Интересно как можно решить подобную задачу с использованием стат. типизации. Чтобы был контроль компилятором, не надо было полагаться на 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 запрос на всю сумму. Если хоть один из них не срабатывает, увеличить нельзя.