Пример #1
0
        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);
                        }
                    }
                }
            }
        }
Пример #2
0
        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);
        }