Skip to content

Commit

Permalink
Merge branch 'main' into services-flake
Browse files Browse the repository at this point in the history
  • Loading branch information
shivaraj-bh committed Dec 31, 2023
2 parents 9fb1649 + bcfdb14 commit 4ce77dc
Show file tree
Hide file tree
Showing 25 changed files with 187 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ data OnboardingDocumentConfigItem = OnboardingDocumentConfigItem
vehicleClassCheckType :: VehicleClassCheckType,
rcNumberPrefix :: Text,
rcNumberPrefixList :: Maybe [Text],
maxRetryCount :: Int,
createdAt :: UTCTime,
updatedAt :: UTCTime
}
Expand Down Expand Up @@ -557,6 +558,7 @@ data OnboardingDocumentConfigUpdateReq = OnboardingDocumentConfigUpdateReq
supportedVehicleClasses :: Maybe SupportedVehicleClasses, -- value wrapper make no sense for lists and objects
rcNumberPrefix :: Maybe (MandatoryValue Text),
rcNumberPrefixList :: Maybe (MandatoryValue [Text]),
maxRetryCount :: Maybe (MandatoryValue Int),
vehicleClassCheckType :: Maybe (MandatoryValue VehicleClassCheckType)
}
deriving stock (Show, Generic)
Expand All @@ -582,6 +584,7 @@ data OnboardingDocumentConfigCreateReq = OnboardingDocumentConfigCreateReq
supportedVehicleClasses :: SupportedVehicleClasses,
rcNumberPrefix :: Text,
rcNumberPrefixList :: Maybe [Text],
maxRetryCount :: Int,
vehicleClassCheckType :: VehicleClassCheckType
}
deriving stock (Show, Generic)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ data AllFees = AllFees
{ status :: DriverFeeStatus,
numRides :: Int,
numDrivers :: Int,
totalAmount :: Centesimal
totalAmount :: Int
}
deriving (Generic, Show, FromJSON, ToJSON, ToSchema)

data CollectionListElem = CollectionListElem
{ totalAmount :: Centesimal,
{ totalAmount :: Int,
totalRides :: Int,
numDrivers :: Int,
date :: Day,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Kernel.Utils.Servant.SignatureAuth
import Lib.Scheduler
import qualified Lib.Scheduler.JobStorageType.SchedulerType as QAllJ
import SharedLogic.Allocator
import SharedLogic.Allocator.Jobs.Document.VerificationRetry
import SharedLogic.Allocator.Jobs.DriverFeeUpdates.BadDebtCalculationScheduler
import SharedLogic.Allocator.Jobs.DriverFeeUpdates.DriverFee
import SharedLogic.Allocator.Jobs.Mandate.Execution (startMandateExecutionForDriver)
Expand Down Expand Up @@ -71,6 +72,7 @@ allocatorHandle flowRt env =
& putJobHandlerInList (liftIO . runFlowR flowRt env . notificationAndOrderStatusUpdate)
& putJobHandlerInList (liftIO . runFlowR flowRt env . sendOverlayToDriver)
& putJobHandlerInList (liftIO . runFlowR flowRt env . badDebtCalculation)
& putJobHandlerInList (liftIO . runFlowR flowRt env . retryDocumentVerificationJob)
}

runDriverOfferAllocator ::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ library
Lib.Mesh
Lib.Schema
SharedLogic.Allocator
SharedLogic.Allocator.Jobs.Document.VerificationRetry
SharedLogic.Allocator.Jobs.DriverFeeUpdates.BadDebtCalculationScheduler
SharedLogic.Allocator.Jobs.DriverFeeUpdates.DriverFee
SharedLogic.Allocator.Jobs.Mandate.Execution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,8 @@ onboardingDocumentConfigUpdate merchantShortId opCity reqDocumentType req = do
supportedVehicleClasses = maybe config.supportedVehicleClasses castSupportedVehicleClasses req.supportedVehicleClasses,
vehicleClassCheckType = maybe config.vehicleClassCheckType (castVehicleClassCheckType . (.value)) req.vehicleClassCheckType,
rcNumberPrefix = maybe config.rcNumberPrefix (.value) req.rcNumberPrefix,
rcNumberPrefixList = maybe config.rcNumberPrefixList (.value) req.rcNumberPrefixList
rcNumberPrefixList = maybe config.rcNumberPrefixList (.value) req.rcNumberPrefixList,
maxRetryCount = maybe config.maxRetryCount (.value) req.maxRetryCount
}
_ <- CQODC.update updConfig
CQODC.clearCache merchantOpCityId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ getAllFeeFromDriverFee Common.DriverFee {..} = do
status' <- readMaybe status_ & fromMaybeM (InvalidRequest "Couldn't find fee's status")
numRides' <- readMaybe numRides_ & fromMaybeM (InvalidRequest "Couldn't find fee's ride count")
numDrivers' <- readMaybe numDrivers_ & fromMaybeM (InvalidRequest "Couldn't find fee's driver count")
pure $ Common.AllFees status' numRides' numDrivers' totalAmount_
pure $ Common.AllFees status' numRides' numDrivers' (round totalAmount_)
_ -> throwError $ InvalidRequest "Couldn't find driver fee"

getCollectionHistory :: ShortId DM.Merchant -> Context.City -> Maybe Text -> Maybe Text -> Maybe UTCTime -> Maybe UTCTime -> Flow Common.CollectionList
Expand Down Expand Up @@ -102,7 +102,7 @@ getCollectionListElem Common.DriverFee {..} = do
numRides' <- readMaybe numRides_ & fromMaybeM (InvalidRequest "Couldn't find fee's ride count")
numDrivers' <- readMaybe numDrivers_ & fromMaybeM (InvalidRequest "Couldn't find fee's driver count")
date' <- readMaybe date_ & fromMaybeM (InvalidRequest "Couldn't find fee's date")
pure $ Common.CollectionListElem totalAmount_ numRides' numDrivers' date' hour_
pure $ Common.CollectionListElem (round totalAmount_) numRides' numDrivers' date' hour_
_ -> throwError $ InvalidRequest "Couldn't find driver fee"

fetchDatetime :: Text -> String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ verifyDLFlow person merchantOpCityId onboardingDocumentConfig dlNumber driverDat
idfyResponse = Nothing,
multipleRC = Nothing, -- added for backward compatibility
dashboardPassedVehicleVariant = Nothing,
retryCount = 0,
createdAt = now,
updatedAt = now
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ module Domain.Action.UI.DriverOnboarding.IdfyWebhook
)
where

import Control.Applicative ((<|>))
import qualified Domain.Action.UI.DriverOnboarding.DriverLicense as DL
import qualified Domain.Action.UI.DriverOnboarding.Status as Status
import qualified Domain.Action.UI.DriverOnboarding.VehicleRegistrationCertificate as RC
import qualified Domain.Types.DriverOnboarding.IdfyVerification as IV
import qualified Domain.Types.Merchant as DM
import qualified Domain.Types.Merchant.MerchantServiceConfig as DMSC
import Environment
Expand All @@ -36,6 +38,8 @@ import Kernel.Types.Beckn.Context as Context
import Kernel.Types.Error
import Kernel.Types.Id
import Kernel.Utils.Common
import Lib.Scheduler.JobStorageType.SchedulerType (createJobIn)
import SharedLogic.Allocator
import SharedLogic.Merchant (findMerchantByShortId)
import qualified Storage.CachedQueries.Merchant.MerchantOperatingCity as CQMOC
import qualified Storage.CachedQueries.Merchant.MerchantServiceConfig as CQMSC
Expand Down Expand Up @@ -111,18 +115,37 @@ idfyWebhookV2Handler merchantShortId opCity secret val = do
onVerify :: Idfy.VerificationResponse -> Text -> Flow AckResponse
onVerify resp respDump = do
verificationReq <- IVQuery.findByRequestId resp.request_id >>= fromMaybeM (InternalError "Verification request not found")
_ <- IVQuery.updateResponse resp.request_id resp.status respDump

ack_ <- maybe (pure Ack) (verifyDocument verificationReq) resp.result
person <- runInReplica $ QP.findById verificationReq.driverId >>= fromMaybeM (PersonDoesNotExist verificationReq.driverId.getId)
-- running statusHandler to enable Driver
_ <- Status.statusHandler (verificationReq.driverId, person.merchantId, person.merchantOperatingCityId) verificationReq.multipleRC

return ack_
IVQuery.updateResponse resp.request_id resp.status respDump
let resultStatus = getResultStatus resp.result
if resultStatus == (Just "source_down")
then do
scheduleRetryVerificationJob verificationReq
return Ack
else do
ack_ <- maybe (pure Ack) (verifyDocument verificationReq) resp.result
person <- runInReplica $ QP.findById verificationReq.driverId >>= fromMaybeM (PersonDoesNotExist verificationReq.driverId.getId)
-- running statusHandler to enable Driver
void $ Status.statusHandler (verificationReq.driverId, person.merchantId, person.merchantOperatingCityId) verificationReq.multipleRC
return ack_
where
getResultStatus mbResult = mbResult >>= (\rslt -> (rslt.extraction_output >>= (.status)) <|> (rslt.source_output >>= (.status)))
verifyDocument verificationReq rslt
| isJust rslt.extraction_output =
maybe (pure Ack) (RC.onVerifyRC verificationReq) rslt.extraction_output
| isJust rslt.source_output =
maybe (pure Ack) (DL.onVerifyDL verificationReq) rslt.source_output
| otherwise = pure Ack

scheduleRetryVerificationJob :: IV.IdfyVerification -> Flow ()
scheduleRetryVerificationJob verificationReq = do
maxShards <- asks (.maxShards)
let scheduleTime = calculateScheduleTime verificationReq.retryCount
createJobIn @_ @'RetryDocumentVerification scheduleTime maxShards $
RetryDocumentVerificationJobData
{ requestId = verificationReq.requestId
}
where
calculateScheduleTime retryCount = do
let retryInterval = 60 * 60 * 1000 -- 1 hour
let retryTime = retryInterval * (3 ^ retryCount)
retryTime
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ verifyRCFlow person merchantOpCityId imageExtraction rcNumber imageId dateOfRegi
idfyResponse = Nothing,
multipleRC,
dashboardPassedVehicleVariant = mbVariant,
retryCount = 0,
createdAt = now,
updatedAt = now
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ data IdfyVerificationE e = IdfyVerification
idfyResponse :: Maybe Text,
multipleRC :: Maybe Bool,
dashboardPassedVehicleVariant :: Maybe Vehicle.Variant,
retryCount :: Int,
createdAt :: UTCTime,
updatedAt :: UTCTime
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ data OnboardingDocumentConfig = OnboardingDocumentConfig
vehicleClassCheckType :: VehicleClassCheckType,
rcNumberPrefix :: Text,
rcNumberPrefixList :: [Text],
maxRetryCount :: Int,
createdAt :: UTCTime,
updatedAt :: UTCTime
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ data AllocatorJobType
| OrderAndNotificationStatusUpdate
| SendOverlay
| BadDebtCalculation
| RetryDocumentVerification
deriving (Generic, FromDhall, Eq, Ord, Show, Read, FromJSON, ToJSON)

genSingletons [''AllocatorJobType]
Expand All @@ -59,6 +60,7 @@ instance JobProcessor AllocatorJobType where
restoreAnyJobInfo SOrderAndNotificationStatusUpdate jobData = AnyJobInfo <$> restoreJobInfo SOrderAndNotificationStatusUpdate jobData
restoreAnyJobInfo SSendOverlay jobData = AnyJobInfo <$> restoreJobInfo SSendOverlay jobData
restoreAnyJobInfo SBadDebtCalculation jobData = AnyJobInfo <$> restoreJobInfo SBadDebtCalculation jobData
restoreAnyJobInfo SRetryDocumentVerification jobData = AnyJobInfo <$> restoreJobInfo SRetryDocumentVerification jobData

data SendSearchRequestToDriverJobData = SendSearchRequestToDriverJobData
{ searchTryId :: Id DST.SearchTry,
Expand Down Expand Up @@ -142,6 +144,15 @@ instance JobInfoProcessor 'CalculateDriverFees

type instance JobContent 'CalculateDriverFees = CalculateDriverFeesJobData

data RetryDocumentVerificationJobData = RetryDocumentVerificationJobData
{ requestId :: Text
}
deriving (Generic, Show, Eq, FromJSON, ToJSON)

instance JobInfoProcessor 'RetryDocumentVerification

type instance JobContent 'RetryDocumentVerification = RetryDocumentVerificationJobData

data OrderAndNotificationStatusUpdateJobData = OrderAndNotificationStatusUpdateJobData
{ merchantId :: Id DM.Merchant,
merchantOperatingCityId :: Maybe (Id DMOC.MerchantOperatingCity)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{-
Copyright 2022-23, Juspay India Pvt Ltd
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program
is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of
the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
-}

module SharedLogic.Allocator.Jobs.Document.VerificationRetry
( retryDocumentVerificationJob,
)
where

import Domain.Types.DriverOnboarding.IdfyVerification
import qualified Domain.Types.DriverOnboarding.Image as Image
import qualified Domain.Types.Merchant.OnboardingDocumentConfig as DTO
import Kernel.Beam.Functions as B
import Kernel.External.Encryption (decrypt)
import Kernel.Prelude
import Kernel.Storage.Esqueleto.Config
import Kernel.Types.Error
import Kernel.Utils.Common
import Lib.Scheduler
import SharedLogic.Allocator (AllocatorJobType (..))
import SharedLogic.GoogleTranslate (TranslateFlow)
import qualified Storage.CachedQueries.Merchant.OnboardingDocumentConfig as QODC
import qualified Storage.Queries.DriverOnboarding.IdfyVerification as IVQuery
import qualified Storage.Queries.Person as QP
import Tools.Error
import qualified Tools.Verification as Verification

retryDocumentVerificationJob ::
( TranslateFlow m r,
EsqDBReplicaFlow m r,
CacheFlow m r,
EsqDBFlow m r
) =>
Job 'RetryDocumentVerification ->
m ExecutionResult
retryDocumentVerificationJob Job {id, jobInfo} = withLogTag ("JobId-" <> id.getId) do
let jobData = jobInfo.jobData
verificationReq <- IVQuery.findByRequestId jobData.requestId >>= fromMaybeM (InternalError "Verification request not found")
person <- runInReplica $ QP.findById verificationReq.driverId >>= fromMaybeM (PersonDoesNotExist verificationReq.driverId.getId)
onboardingDocumentConfig <- QODC.findByMerchantOpCityIdAndDocumentType person.merchantOperatingCityId (castDoctype verificationReq.docType) >>= fromMaybeM (OnboardingDocumentConfigNotFound person.merchantOperatingCityId.getId (show verificationReq.docType))
let maxRetryCount = onboardingDocumentConfig.maxRetryCount
if verificationReq.retryCount <= maxRetryCount
then do
documentNumber <- decrypt verificationReq.documentNumber
IVQuery.updateStatus verificationReq.requestId "source_down_retried"
case verificationReq.docType of
Image.VehicleRegistrationCertificate -> do
verifyRes <-
Verification.verifyRCAsync person.merchantId person.merchantOperatingCityId $
Verification.VerifyRCAsyncReq {rcNumber = documentNumber, driverId = person.id.getId}
mkNewVerificationEntity verificationReq verifyRes.requestId
Image.DriverLicense -> do
whenJust verificationReq.driverDateOfBirth $ \dob -> do
verifyRes <-
Verification.verifyDLAsync person.merchantId person.merchantOperatingCityId $
Verification.VerifyDLAsyncReq {dlNumber = documentNumber, dateOfBirth = dob, driverId = person.id.getId}
mkNewVerificationEntity verificationReq verifyRes.requestId
else do
IVQuery.updateStatus verificationReq.requestId "source_down_failed"
return Complete
where
castDoctype :: Image.ImageType -> DTO.DocumentType
castDoctype docType =
case docType of
Image.VehicleRegistrationCertificate -> DTO.RC
Image.DriverLicense -> DTO.DL

mkNewVerificationEntity verificationReq requestId = do
now <- getCurrentTime
newId <- generateGUID
let newVerificationReq =
verificationReq
{ id = newId,
retryCount = verificationReq.retryCount + 1,
status = "source_down_retrying",
requestId,
createdAt = now,
updatedAt = now
}
IVQuery.create newVerificationReq
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,7 @@ getBatchedDriverIds merchantId jobId condition freeTrialDays timeDiffFromUtc dri
startTime = addUTCTime (-1 * driverPaymentCycleDuration) potentialStartToday
endTime = addUTCTime 120 potentialStartToday
driverFees <- QDF.findWindowsWithFeeTypeAndLimit merchantId startTime endTime (getFeeType paymentMode) overlayBatchSize
let filteredDriverFees = filter (\dueInvoice -> SLDriverFee.roundToHalf (fromIntegral dueInvoice.govtCharges + dueInvoice.platformFee.fee + dueInvoice.platformFee.cgst + dueInvoice.platformFee.sgst) > 0) driverFees
let driverIds = filteredDriverFees <&> (.driverId)
let driverIds = driverFees <&> (.driverId)
void $ QDF.updateDriverFeeOverlayScheduled driverIds True startTime endTime
return driverIds
_ -> do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ data IdfyVerificationT f = IdfyVerificationT
idfyResponse :: B.C f (Maybe Text),
multipleRC :: B.C f (Maybe Bool),
dashboardPassedVehicleVariant :: B.C f (Maybe Vehicle.Variant),
retryCount :: B.C f (Maybe Int),
createdAt :: B.C f UTCTime,
updatedAt :: B.C f UTCTime
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ data OnboardingDocumentConfigT f = OnboardingDocumentConfigT
supportedVehicleClassesJSON :: B.C f A.Value,
rcNumberPrefix :: B.C f Text,
rcNumberPrefixList :: B.C f [Text],
maxRetryCount :: B.C f Int,
vehicleClassCheckType :: B.C f Domain.VehicleClassCheckType,
createdAt :: B.C f UTCTime,
updatedAt :: B.C f UTCTime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,10 @@ findWindowsWithFeeTypeAndLimit merchantId from to feeType limit =
Se.Is BeamDF.endTime $ Se.LessThanOrEq to,
Se.Is BeamDF.feeType $ Se.Eq feeType,
Se.Is BeamDF.merchantId $ Se.Eq merchantId.getId,
Se.Is BeamDF.overlaySent $ Se.Eq False
Se.Is BeamDF.overlaySent $ Se.Eq False,
Se.Is BeamDF.platformFee $ Se.Not (Se.Eq 0.0),
Se.Is BeamDF.cgst $ Se.Not (Se.Eq 0.0),
Se.Is BeamDF.sgst $ Se.Not (Se.Eq 0.0)
]
]
(Se.Asc BeamDF.createdAt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ updateResponse requestId status resp = do
[Se.Set BeamIV.status status, Se.Set BeamIV.idfyResponse $ Just resp, Se.Set BeamIV.updatedAt now]
[Se.Is BeamIV.requestId (Se.Eq requestId)]

updateStatus :: (MonadFlow m, EsqDBFlow m r, CacheFlow m r) => Text -> Text -> m ()
updateStatus requestId status = do
now <- getCurrentTime
updateWithKV
[Se.Set BeamIV.status status, Se.Set BeamIV.updatedAt now]
[Se.Is BeamIV.requestId (Se.Eq requestId)]

updateExtractValidationStatus :: (MonadFlow m, EsqDBFlow m r, CacheFlow m r) => Text -> ImageExtractionValidation -> m ()
updateExtractValidationStatus requestId status = do
now <- getCurrentTime
Expand All @@ -70,6 +77,7 @@ instance FromTType' BeamIV.IdfyVerification IdfyVerification where
documentImageId1 = Id documentImageId1,
documentImageId2 = Id <$> documentImageId2,
dashboardPassedVehicleVariant = dashboardPassedVehicleVariant,
retryCount = fromMaybe 0 retryCount,
driverId = Id driverId,
requestId = requestId,
docType = docType,
Expand All @@ -91,6 +99,7 @@ instance ToTType' BeamIV.IdfyVerification IdfyVerification where
BeamIV.documentImageId1 = getId documentImageId1,
BeamIV.documentImageId2 = getId <$> documentImageId2,
BeamIV.dashboardPassedVehicleVariant = dashboardPassedVehicleVariant,
BeamIV.retryCount = Just retryCount,
BeamIV.driverId = getId driverId,
BeamIV.requestId = requestId,
BeamIV.docType = docType,
Expand Down
Loading

0 comments on commit 4ce77dc

Please sign in to comment.