/// <summary> /// Pay the amount of the operation /// Debit seekios free credit or user credit or both /// </summary> /// <param name="seekiosEntities">the database context</param> /// <param name="operationTypeEnum">the operation type</param> /// <param name="idUser">id user</param> /// <param name="idMode">id mode</param> /// <param name="idSeekios">id seekios</param> /// <param name="minUserCreditThreshold">the minimum left on the account</param> /// <returns>return 1 if it's working</returns> public static int PayOperationCost(seekios_dbEntities seekiosEntities , OperationType operationTypeEnum , int idUser , int?idMode , int idSeekios , int minUserCreditThreshold = 0) { //bool alreadyCommit = false; //using (DbContextTransaction dbContextTransaction = seekiosEntities.Database.BeginTransaction(System.Data.IsolationLevel.Snapshot)) //{ try { // Get user var userDb = (from u in seekiosEntities.user where u.iduser == idUser select u).FirstOrDefault(); if (userDb == null) { return(-1); } // Retrieves all seekioses for the current user, order by freecredits... var seekiosAndSeekiosProductionBdd = (from s in seekiosEntities.seekiosAndSeekiosProduction where s.user_iduser == idUser orderby s.freeCredit descending select s).ToArray(); int sumOfseekiosFreeCredits = seekiosAndSeekiosProductionBdd.Sum(s => s.freeCredit); int amountToPay = operationTypeEnum.GetAmount(); int sumOfTotalCredit = (!userDb.remainingRequest.HasValue ? 0 : userDb.remainingRequest.Value) + sumOfseekiosFreeCredits + amountToPay; var uidSeekiosToNotify = string.Empty; // Can not pay the operation, not enough credit if (sumOfTotalCredit < minUserCreditThreshold) { // Delete the mode if (idMode.HasValue) { // WARNING : Hotfix, the mobile app should display the tracking is not available for the seekios because the seekios will receive M01 (wait state) //var result = new System.Data.Entity.Core.Objects.ObjectParameter("Result", 0); //seekiosEntities.DeleteModeById(idMode, result); SeekiosService.PrepareInstructionForNewMode(seekiosEntities , null , (from s in seekiosEntities.seekios where s.idseekios == idSeekios select s).First()); } return(-2); } // Pay the operation with free credit // Take the seekios with the value freeCredit more than the amount requested to pay var now = DateTime.UtcNow; var oneSeekiosToPay = seekiosAndSeekiosProductionBdd.FirstOrDefault(f => f.freeCredit > -amountToPay); if (oneSeekiosToPay != null) { // Pay the operation (decrement the freeCredit value) seekiosEntities.UpdateSeekiosFreeCreditById(oneSeekiosToPay.idseekios, amountToPay); AddOperationInDatabase(seekiosEntities, now, idMode, idSeekios, idUser, operationTypeEnum, amountToPay, true); uidSeekiosToNotify = oneSeekiosToPay.uidSeekios; amountToPay = 0; } else { // Not enought on one seekios but more than one seekios var moreThanOneSeekiosToPay = seekiosAndSeekiosProductionBdd.Where(w => w.freeCredit > 0); foreach (var seekiosToPay in moreThanOneSeekiosToPay) { if (amountToPay + seekiosToPay.freeCredit >= 0) { seekiosEntities.UpdateSeekiosFreeCreditById(seekiosToPay.idseekios, amountToPay); AddOperationInDatabase(seekiosEntities, now, idMode, idSeekios, idUser, operationTypeEnum, amountToPay, true); uidSeekiosToNotify = seekiosToPay.uidSeekios; amountToPay = 0; break; } else { seekiosEntities.UpdateSeekiosFreeCreditById(seekiosToPay.idseekios, -seekiosToPay.freeCredit); AddOperationInDatabase(seekiosEntities, now, idMode, idSeekios, idUser, operationTypeEnum, -seekiosToPay.freeCredit, true); amountToPay += seekiosToPay.freeCredit; } } } int userDebit = 0; int seekiosDebit = operationTypeEnum.GetAmount() - amountToPay; // The operation is not finish to pay, we need to use the user credit if (amountToPay < 0) { userDb.remainingRequest += amountToPay; AddOperationInDatabase(seekiosEntities, now, idMode, idSeekios, idUser, operationTypeEnum, amountToPay, false); userDebit = amountToPay; } // Save changes and commit seekiosEntities.SaveChanges(); //dbContextTransaction.Commit(); //alreadyCommit = true; // Broadcast user devices SignalRHelper.BroadcastUser(HubProxyEnum.CreditsHub , SignalRHelper.METHOD_REFRESH_CREDIT , new object[] { userDb.iduser, uidSeekiosToNotify, userDebit, seekiosDebit, now }); return(1); } catch (Exception ex) { //if (!alreadyCommit) dbContextTransaction.Rollback(); throw ex; } //finally //{ // dbContextTransaction.Dispose(); //} //} }