fix: test command

This commit is contained in:
2026-05-09 00:14:12 +03:00
parent 22f27fa524
commit be8aee7b73
8 changed files with 126 additions and 44 deletions

View File

@@ -14,6 +14,11 @@ class IOrderRepository(ABC):
raise NotImplementedError
@abstractmethod
async def get_by_id(self,order_id: str) -> OrderEntity | None:
raise NotImplementedError
@abstractmethod
async def update_after_itpay_payment_created(self,order: OrderEntity) -> OrderEntity:
raise NotImplementedError

View File

@@ -8,6 +8,15 @@ from src.infrastructure.database.decorators import transactional
from src.presentation.schemas.itpay_payment_models import ItpayPaymentData
def _parse_money(val: object | None) -> Decimal | None:
if val is None:
return None
s = str(val).strip()
if not s:
return None
return Decimal(s).quantize(Decimal('0.01'))
class CreatePaymentCloudkassirCommand:
def __init__(self, *, unit_of_work: IUnitOfWork, receipt: IReceipt):
self._unit_of_work = unit_of_work
@@ -37,27 +46,62 @@ class CreatePaymentCloudkassirCommand:
user = await self._unit_of_work.user_repository.get(user_id)
if user is None:
raise ApplicationException(status_code=404, message='User not found')
email = str(user.email or '').strip()
email_meta = metadata.get('customer_email')
if email_meta is None:
email_meta = metadata.get('email')
email = str(email_meta or user.email or '').strip()
if not email:
raise ApplicationException(status_code=400, message='User email missing')
phone_raw = (user.phone or '').strip()
phone_raw = str(metadata.get('phone') or '').strip()
if not phone_raw:
phone_raw = str(user.phone or '').strip()
phone = phone_raw if phone_raw else None
total_amount: Decimal | None = None
if payment.amount is not None:
total_amount = Decimal(str(payment.amount)).quantize(Decimal('0.01'))
if total_amount is None:
raw_amt = metadata.get('amount')
if raw_amt is not None:
total_amount = Decimal(str(raw_amt)).quantize(Decimal('0.01'))
if total_amount is None:
raise ApplicationException(status_code=400, message='Itpay webhook payment amount missing for receipt')
raw_sf = metadata.get('service_fee')
if raw_sf is None:
raise ApplicationException(status_code=400, message='Itpay webhook metadata missing service_fee for receipt')
service_fee = Decimal(str(raw_sf)).quantize(Decimal('0.01'))
principal_amount = (total_amount - service_fee).quantize(Decimal('0.01'))
customer_inn_meta = metadata.get('customer_inn')
if customer_inn_meta is None:
customer_inn_meta = metadata.get('customerInn')
customer_inn = str(customer_inn_meta or user.inn or '').strip()
paid_total = _parse_money(payment.amount)
if paid_total is None:
paid_total = _parse_money(metadata.get('amount'))
meta_principal = _parse_money(metadata.get('principal_amount'))
meta_agent = _parse_money(metadata.get('agent_fee'))
if meta_agent is None:
meta_agent = _parse_money(metadata.get('service_fee'))
principal_amount: Decimal
service_fee: Decimal
total_amount: Decimal
if meta_principal is not None and meta_agent is not None:
principal_amount = meta_principal
service_fee = meta_agent
total_amount = (principal_amount + service_fee).quantize(Decimal('0.01'))
else:
order = await self._unit_of_work.order_repository.get_by_id(order_id)
if order is not None and order.total_price is not None and order.service_fee is not None:
total_amount = Decimal(str(order.total_price)).quantize(Decimal('0.01'))
service_fee = Decimal(str(order.service_fee)).quantize(Decimal('0.01'))
principal_amount = (total_amount - service_fee).quantize(Decimal('0.01'))
else:
if paid_total is None:
raise ApplicationException(status_code=400, message='Payment amount missing for receipt')
raw_sf = metadata.get('service_fee')
if raw_sf is None:
raise ApplicationException(
status_code=400,
message='Receipt amounts: need principal_amount+agent_fee in metadata, order in DB, or service_fee with paid amount',
)
service_fee = Decimal(str(raw_sf)).quantize(Decimal('0.01'))
total_amount = paid_total
principal_amount = (total_amount - service_fee).quantize(Decimal('0.01'))
if principal_amount < 0:
raise ApplicationException(status_code=400, message='Invalid receipt amounts: principal negative')
if paid_total is not None and abs(total_amount - paid_total) > Decimal('0.02'):
raise ApplicationException(status_code=400, message='Receipt total does not match paid amount')
await self._receipt.create_receipt(
order_id=order_id,
user_id=user_id,
@@ -66,5 +110,6 @@ class CreatePaymentCloudkassirCommand:
principal_amount=principal_amount,
service_fee=service_fee,
phone=phone,
customer_inn=customer_inn,
request_id=str(ULID()),
)