from django.conf import settings from django.db import models from oauth2_provider.settings import oauth2_settings from apps.core.models import BaseModel from apps.pg.constans import StateChoices import uuid from utils.wallet_client import deposit_to_user_wallet_submit, withdraw_from_user_wallet_verify, \ deposit_to_user_wallet_verify class ChargeRequest(BaseModel): application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT, related_name='+', null=True, blank=True) state = models.IntegerField(choices=StateChoices.choices, default=StateChoices.CREATED) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT) amount = models.PositiveBigIntegerField(null=True, blank=True) callback_url = models.URLField(null=True, blank=True) details = models.JSONField(null=True, blank=True, default=dict) # TODO: complete and use this def change_state(self, from_state, to_state, error_message=None, **data): if self.state == from_state: updated = ChargeRequest.objects.filter(pk=self.pk, state=from_state).update( state=to_state, **data ) if updated: # double check in db level self.state = to_state else: raise Exception(error_message) else: raise Exception(error_message) def charge_wallet_balance(self): if self.state in [StateChoices.CREATED]: to_pending = ChargeRequest.objects.filter( pk=self.pk, state=StateChoices.CREATED.value, ).update( state=StateChoices.PENDING.value) if not to_pending: raise Exception('Cannot charge balance because state') data = { "uuid": str(self.pk), "payee_id": str(self.user.uuid), "payee_type": 1, "amount": self.amount, "details": { 'description': "charge via IPG", 'reference_id': str(self.pk), 'application_details_url': '' }, } submit_response = deposit_to_user_wallet_submit(data) if not submit_response.uuid: raise Exception('Failed to submit payment in wallet') verify_response = deposit_to_user_wallet_verify(self.pk) if not verify_response.uuid or verify_response.state != 5: raise Exception('Failed to verify payment in wallet') to_pay_success = ChargeRequest.objects.filter( pk=self.pk, state=StateChoices.PENDING.value ).update( publication_state=StateChoices.SUCCESS.value, ) if not to_pay_success: raise Exception('Failed to update state payment') return bool(to_pay_success)