feat: billing guest access
This commit is contained in:
118
services/billing.py
Normal file
118
services/billing.py
Normal file
@@ -0,0 +1,118 @@
|
||||
import datetime
|
||||
from typing import List
|
||||
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy import select
|
||||
from starlette import status
|
||||
|
||||
import backend.config
|
||||
from external.billing import BillingClient, CreateBillingRequestValue, CreateBillRequestSchema, CreateBillRequestItems, \
|
||||
BillStatusUpdateRequest, NotificationChannel, NotifyReceivedBillRequestSchema, BillPaymentInfo
|
||||
from models import DealBillRequest, Deal
|
||||
from schemas.billing import *
|
||||
from services.base import BaseService
|
||||
from services.deal import DealService
|
||||
|
||||
|
||||
class BillingService(BaseService):
|
||||
async def _process_update_details(
|
||||
self,
|
||||
request: BillStatusUpdateRequest
|
||||
):
|
||||
billing_client = BillingClient(backend.config.BILLING_API_KEY)
|
||||
notify_received_request = NotifyReceivedBillRequestSchema(
|
||||
listener_transaction_id=request.listener_transaction_id,
|
||||
channel=NotificationChannel.PAYMENT_DETAILS,
|
||||
received=True
|
||||
)
|
||||
response = await billing_client.notify_received(notify_received_request)
|
||||
deal_bill_request = await self._get_deal_bill_by_id(request.listener_transaction_id)
|
||||
if not response.ok:
|
||||
return
|
||||
deal_bill_request.pdf_url = request.info.pdf_url
|
||||
deal_bill_request.invoice_number = request.info.invoice_number
|
||||
await self.session.commit()
|
||||
|
||||
async def _process_update_verification(
|
||||
self,
|
||||
request: BillStatusUpdateRequest
|
||||
):
|
||||
billing_client = BillingClient(backend.config.BILLING_API_KEY)
|
||||
notify_received_request = NotifyReceivedBillRequestSchema(
|
||||
listener_transaction_id=request.listener_transaction_id,
|
||||
channel=NotificationChannel.PAYMENT_VERIFICATION,
|
||||
received=True
|
||||
)
|
||||
response = await billing_client.notify_received(notify_received_request)
|
||||
if not response.ok:
|
||||
return
|
||||
deal_bill_request = await self._get_deal_bill_by_id(request.listener_transaction_id)
|
||||
if not deal_bill_request:
|
||||
return
|
||||
deal_bill_request.paid = request.info.payed
|
||||
await self.session.commit()
|
||||
|
||||
async def process_update(
|
||||
self,
|
||||
request: BillStatusUpdateRequest
|
||||
):
|
||||
if request.channel == NotificationChannel.PAYMENT_DETAILS:
|
||||
await self._process_update_details(request)
|
||||
elif request.channel == NotificationChannel.PAYMENT_VERIFICATION:
|
||||
await self._process_update_verification(request)
|
||||
|
||||
async def create_deal_billing(self, user, request: CreateDealBillRequest) -> CreateDealBillResponse:
|
||||
try:
|
||||
deal_service = DealService(self.session)
|
||||
billing_client = BillingClient(backend.config.BILLING_API_KEY)
|
||||
|
||||
deal: Deal = await deal_service.get_by_id(user, request.deal_id)
|
||||
billing_request_values: List[CreateBillingRequestValue] = []
|
||||
for product in deal.products:
|
||||
for service in product.services:
|
||||
billing_request_values.append(
|
||||
CreateBillingRequestValue(
|
||||
name=f'[{product.product.name}] - {service.service.name}',
|
||||
price=service.price,
|
||||
amount=product.quantity
|
||||
)
|
||||
)
|
||||
for service in deal.services:
|
||||
billing_request_values.append(
|
||||
CreateBillingRequestValue(
|
||||
name=f'{service.service.name}',
|
||||
price=service.price,
|
||||
amount=service.quantity
|
||||
)
|
||||
)
|
||||
create_bill_request = CreateBillRequestSchema(
|
||||
listener_transaction_id=deal.id,
|
||||
payer_name=deal.client.name,
|
||||
payer_inn=deal.client.details.inn,
|
||||
payer_phone=deal.client.details.phone_number,
|
||||
items=CreateBillRequestItems(
|
||||
values=billing_request_values
|
||||
)
|
||||
)
|
||||
create_bill_response = await billing_client.create(create_bill_request)
|
||||
if not create_bill_response.ok:
|
||||
return CreateDealBillResponse(ok=create_bill_response.ok, message='Ошибка!')
|
||||
deal_bill_request = DealBillRequest(
|
||||
deal_id=request.deal_id,
|
||||
created_at=datetime.datetime.now()
|
||||
)
|
||||
self.session.add(deal_bill_request)
|
||||
deal.is_locked = True
|
||||
await self.session.commit()
|
||||
return CreateDealBillResponse(ok=create_bill_response.ok, message='Заявка успешно создана!')
|
||||
except Exception as e:
|
||||
return CreateDealBillResponse(ok=False, message=str(e))
|
||||
|
||||
async def _get_deal_bill_by_id(self, deal_id: int) -> Optional[DealBillRequest]:
|
||||
return await self.session.scalar(select(DealBillRequest).where(DealBillRequest.deal_id == deal_id))
|
||||
|
||||
async def get_deal_bill_by_id(self, deal_id: int) -> GetDealBillById:
|
||||
deal_bill = await self._get_deal_bill_by_id(deal_id)
|
||||
if not deal_bill:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Deal bill was not found')
|
||||
return GetDealBillById(deal_bill=DealBillRequestSchema.model_validate(deal_bill))
|
||||
Reference in New Issue
Block a user