public void CheckAmountLimits(decimal amount, string currencyCode, string path) { IEnumerable <LimitDefinition> list = _dataService.GetDefinitions(path, true); foreach (var item in list) { if (item.Path == path) { continue; } if (item.MaxAmountLimit != -1) { if (item.MaxAmountLimitCurrencyCode == currencyCode) { if (item.MaxAmountLimit < amount) { throw new AmountLimitBiggerThanMaxException(item); } } else { if (_dataHelperService.CurrencyConverter((decimal)item.MaxAmountLimit, item.MaxAmountLimitCurrencyCode, currencyCode) < amount) { throw new AmountLimitBiggerThanMaxException(item); } } } } }
public IEnumerable <ExecuteResponseDefinition> ExecuteTransaction(ExecuteRequestDefinition data) { if (String.IsNullOrEmpty(data.Path)) { throw new NullPathException(); } if (data.Path.Contains("*")) { throw new ParentPathException(); } var definitions = GetDefinitions(data.Path, true).Where(x => x.isActive == true); definitions = _businessHelperService.AddAlsoLookPaths(definitions); if (definitions.Count() == 0) { throw new PathNotDefinedException(); } var notUpdatedDefinitions = _dataService.GetDefinitions(data.Path, true).Where(x => x.isActive = true); var definition = definitions.Where(x => x.Path == data.Path).FirstOrDefault(); if (definition == null && data.isExactPathRequired == true) { throw new PathNotDefinedException(); } if (data.Amount < 0) { throw new InvalidAmountException(); } if (!_businessHelperService.CheckCurrencyCode(data.CurrencyCode)) { throw new InvalidCurrencyCodeException(); } Dictionary <string, decimal> amounts = new Dictionary <string, decimal>(); List <ExecuteResponseDefinition> response = new List <ExecuteResponseDefinition>(); foreach (var def in definitions) { if (def.AmountLimit.CurrencyCode != data.CurrencyCode) { amounts[def.Path + def.Duration.Span] = Decimal.Parse(_dataHelperService.CurrencyConverter(data.Amount, data.CurrencyCode, def.AmountLimit.CurrencyCode).ToString(("0.####"))); } else { amounts[def.Path + def.Duration.Span] = Decimal.Parse(data.Amount.ToString(("0.####"))); } } if (data.Type == ExecutionType.Utilize || data.Type == ExecutionType.Simulation) { foreach (var def in definitions) { var availabilityStatus = _businessHelperService.CheckAvailability(def.Availability); if (availabilityStatus.AvailabilityStatus == AvailabilityStatusType.NotInRange) { throw new AvailabilityException(new AvailabilityRejectDefinition { FirstAvailableDate = _businessHelperService.FirstAvailableTime(def.Availability.Start), Reason = new AvailabilityExceptionDescriptionDefinition[] { new AvailabilityExceptionDescriptionDefinition { Description = "Not inside available time frame.", Language = "EN" }, new AvailabilityExceptionDescriptionDefinition { Description = "Tanımlı işlem yapılabilir zaman dilimi içerisinde değilsiniz.", Language = "TR" } } }); } if (availabilityStatus.AvailabilityStatus == AvailabilityStatusType.Exception) { throw new AvailabilityException(new AvailabilityRejectDefinition { FirstAvailableDate = _businessHelperService.FirstAvailableTime(def.Availability.Start, def.Availability.Exceptions.FirstOrDefault().Finish), Reason = availabilityStatus.Exceptions[0].Descriptions }); } if (amounts[def.Path + def.Duration.Span] > def.AmountLimit.Remaining && def.AmountLimit.Limit != -1) { throw new AmountRemainingLimitException(definitions.Where(x => x.Path == def.Path && x.Duration.Span == def.Duration.Span).FirstOrDefault()); } if (def.TimerLimit.Remaining <= 0 && def.TimerLimit.Limit != -1) { throw new TimerRemainingLimitException(definitions.Where(x => x.Path == def.Path && x.Duration.Span == def.Duration.Span).FirstOrDefault()); } if (amounts[def.Path + def.Duration.Span] > def.TransactionLimit.MaximumLimit && def.TransactionLimit.MaximumLimit != -1) { throw new MaximumLimitException(definitions.Where(x => x.Path == def.Path && x.Duration.Span == def.Duration.Span).FirstOrDefault()); } if (amounts[def.Path + def.Duration.Span] < def.TransactionLimit.MinimumLimit && amounts[def.Path + def.Duration.Span] != 0 && def.TransactionLimit.MinimumLimit != -1) { throw new MinimumLimitException(definitions.Where(x => x.Path == def.Path && x.Duration.Span == def.Duration.Span).FirstOrDefault()); } var amountLimitDef = new AmountLimitDefinition(); amountLimitDef.Remaining = (def.AmountLimit.Limit == -1) ? 0 : def.AmountLimit.Remaining - amounts[def.Path + def.Duration.Span]; amountLimitDef.Utilized = def.AmountLimit.Utilized + amounts[def.Path + def.Duration.Span]; amountLimitDef.CurrencyCode = def.AmountLimit.CurrencyCode; amountLimitDef.Limit = def.AmountLimit.Limit; var timerLimitDef = new TimerLimitDefinition(); timerLimitDef.Limit = def.TimerLimit.Limit; timerLimitDef.Remaining = (def.TimerLimit.Limit == -1) ? 0 : def.TimerLimit.Remaining - 1; timerLimitDef.Utilized = def.TimerLimit.Utilized + 1; timerLimitDef.MaxTimerLimit = def.TimerLimit.MaxTimerLimit; response.Add(new ExecuteResponseDefinition { Path = def.Path, Duration = def.Duration.Span, AmountLimit = amountLimitDef, TransactionLimit = def.TransactionLimit, TimerLimit = timerLimitDef }); } } else if (data.Type == ExecutionType.Reversal) { foreach (var def in definitions) { if (def.AmountLimit.Limit < def.AmountLimit.Remaining + amounts[def.Path + def.Duration.Span] && def.AmountLimit.Limit != -1) { throw new AmountRemainingLimitException(definitions.Where(x => x.Path == def.Path && x.Duration.Span == def.Duration.Span).FirstOrDefault()); } if (def.TimerLimit.Limit < def.TimerLimit.Remaining + 1 && def.TimerLimit.Limit != -1) { throw new TimerRemainingLimitException(definitions.Where(x => x.Path == def.Path && x.Duration.Span == def.Duration.Span).FirstOrDefault()); } var amountLimitDef = new AmountLimitDefinition(); amountLimitDef.Remaining = (def.AmountLimit.Limit == -1) ? 0 : def.AmountLimit.Remaining + amounts[def.Path + def.Duration.Span]; amountLimitDef.Utilized = def.AmountLimit.Utilized - amounts[def.Path + def.Duration.Span]; amountLimitDef.CurrencyCode = def.AmountLimit.CurrencyCode; amountLimitDef.Limit = def.AmountLimit.Limit; var timerLimitDef = new TimerLimitDefinition(); timerLimitDef.Limit = def.TimerLimit.Limit; timerLimitDef.Remaining = (def.TimerLimit.Limit == -1) ? 0 : def.TimerLimit.Remaining + 1; timerLimitDef.Utilized = def.TimerLimit.Utilized - 1; timerLimitDef.MaxTimerLimit = def.TimerLimit.MaxTimerLimit; response.Add(new ExecuteResponseDefinition { Path = def.Path, Duration = def.Duration.Span, AmountLimit = amountLimitDef, TransactionLimit = def.TransactionLimit, TimerLimit = timerLimitDef }); } } int starCount = -1; STATUSERRORCODE status; List <LimitDefinition> limitList = new List <LimitDefinition>(); foreach (var def in definitions) { if (def.Duration.Renewal == RenewalType.elapsed && notUpdatedDefinitions.Where(x => x.Path == def.Path && x.Duration.Span == def.Duration.Span).FirstOrDefault().RenewedAt < CrontabSchedule.Parse(_businessHelperService.GetCron(def.Duration.Span)).GetNextOccurrences(DateTime.Now.AddYears(-1), DateTime.Now).Last()) { _dataService.AutoUpdateLimits(def.Path, def.Duration.Span, def.RenewedAt); } if (def.Path == data.Path) { status = _dataService.ExecuteTransaction(def.Path, def.Duration.Span, amounts[def.Path + def.Duration.Span], data.Type, "fullPath"); } else { status = _dataService.ExecuteTransaction(def.Path, def.Duration.Span, amounts[def.Path + def.Duration.Span], data.Type, "parentPath"); } if (status != STATUSERRORCODE.Success) { foreach (var revereDef in limitList) { if (data.Type == ExecutionType.Reversal) { if (def.Path == data.Path) { _dataService.ExecuteTransaction(def.Path, def.Duration.Span, amounts[def.Path + def.Duration.Span], ExecutionType.Utilize, "fullPath"); } else { _dataService.ExecuteTransaction(def.Path, def.Duration.Span, amounts[def.Path + def.Duration.Span], ExecutionType.Utilize, "parentPath"); } } else if (data.Type == ExecutionType.Utilize) { if (def.Path == data.Path) { _dataService.ExecuteTransaction(def.Path, def.Duration.Span, amounts[def.Path + def.Duration.Span], ExecutionType.Reversal, "fullPath"); } else { _dataService.ExecuteTransaction(def.Path, def.Duration.Span, amounts[def.Path + def.Duration.Span], ExecutionType.Reversal, "parentPath"); } } } } if (status == STATUSERRORCODE.AmountLimitError) { throw new AmountRemainingLimitException(def); } else if (status == STATUSERRORCODE.TimerLimitError) { throw new TimerRemainingLimitException(def); } else if (status == STATUSERRORCODE.DataBaseError) { throw new DatabaseException(); } limitList.Add(def); if (starCount == -1 || starCount > def.Path.Count(x => x == '*')) { starCount = def.Path.Count(x => x == '*'); definition = def; } } return(response); }