Esempio n. 1
0
        public async Task <Result <Card> > RegisterAsync(RegisterCardOptions options)
        {
            if (string.IsNullOrWhiteSpace(options.CardNumber))
            {
                return(new Result <Card>()
                {
                    Code = ResultCodes.BadRequest,
                    Message = "Card Number cannot be empty !"
                });
            }

            if (options.CardNumber.Length != 16)
            {
                return(new Result <Card>()
                {
                    Code = ResultCodes.BadRequest,
                    Message = "Card Number cannot be empty !"
                });
            }

            var card = new Card()
            {
                CardNumber       = options.CardNumber,
                AvailableBalance = options.AvailableBalance,
            };

            try
            {
                await _dbContext.AddAsync <Card>(card);

                await _dbContext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                return(new Result <Card>()
                {
                    Code = ResultCodes.InternalServerError,
                    Message = $"Failed to save card. Details: {ex.Message} - {((ex.InnerException != null) ? ex.InnerException.Message : "")}",
                });
            }

            return(new Result <Card>()
            {
                Code = ResultCodes.Success,
                Message = "Card saved.",
                Data = card
            });
        }
Esempio n. 2
0
        public async Task <Result <List <CardLimit> > > RegisterAsync(RegisterCardLimitOptions options)
        {
            if (string.IsNullOrWhiteSpace(options.CardNumber))
            {
                return(new Result <List <CardLimit> >
                {
                    Code = ResultCodes.BadRequest,
                    Message = "Card Number cannot be empty !"
                });
            }

            if (options.CardNumber.Length != 16)
            {
                return(new Result <List <CardLimit> >
                {
                    Code = ResultCodes.BadRequest,
                    Message = "Card Number must be 16 digits long !"
                });
            }

            // Find the card
            var result = await _card.GetCardbyNumberAsync(options.CardNumber);

            if (result.Code != ResultCodes.Success)
            {
                return(new Result <List <CardLimit> >()
                {
                    Code = result.Code,
                    Message = result.Message
                });
            }

            // Transaction amount must not exceed MAX_CARDPRESENT or MAX_ECOMMERCE
            if (options.TransAmount > MAX_CARDPRESENT && options.TransactionType == TransactionTypes.CardPresent)
            {
                return(new Result <List <CardLimit> >()
                {
                    Code = ResultCodes.BadRequest,
                    Message = $"Transaction amount {options.TransAmount} exceeds maximun amount {MAX_CARDPRESENT}"
                });
            }
            if (options.TransAmount > MAX_ECOMMERCE && options.TransactionType == TransactionTypes.eCommerce)
            {
                return(new Result <List <CardLimit> >()
                {
                    Code = ResultCodes.BadRequest,
                    Message = $"Transaction amount {options.TransAmount} exceeds maximun amount {MAX_ECOMMERCE}"
                });
            }


            // Check whether the card has an availiable amount
            var card = result.Data;

            if (card.AvailableBalance < options.TransAmount)
            {
                return(new Result <List <CardLimit> >()
                {
                    Code = ResultCodes.BadRequest,
                    Message = $"Not enough balance. Card availiable balance is {card.AvailableBalance}"
                });
            }

            // Check if limits are there for card number and current date
            if (card.Limits.Count == 0)
            {
                // If not create the two limits for the card
                // One for the requested trans type
                var cardLimit = new CardLimit()
                {
                    TransactionType = options.TransactionType,
                    AggrAmount      = options.TransAmount,
                    ApplyDate       = DateTime.Today.Date
                };
                card.Limits.Add(cardLimit);

                cardLimit = new CardLimit()
                {
                    TransactionType = (options.TransactionType == TransactionTypes.CardPresent) ? TransactionTypes.eCommerce : TransactionTypes.CardPresent,
                    AggrAmount      = 0.0m,
                    ApplyDate       = DateTime.Today.Date
                };

                card.Limits.Add(cardLimit);

                try
                {
                    await _dbContext.SaveChangesAsync();

                    return(new Result <List <CardLimit> >()
                    {
                        Code = ResultCodes.Success,
                        Message = $"New limits added for Card Number {card.CardNumber}",
                        Data = card.Limits
                    });
                }
                catch (Exception ex)
                {
                    return(new Result <List <CardLimit> >()
                    {
                        Code = ResultCodes.InternalServerError,
                        Message = $"Unable to update Card Limits information for Card Number {card.CardNumber}. Details: {ex.Message}"
                    });
                }
            }
            else
            {
                // otherwise update the limits
                var carLimit = card.Limits
                               .Where(l => l.TransactionType == options.TransactionType)
                               .SingleOrDefault();

                if (carLimit.AggrAmount + options.TransAmount > MAX_CARDPRESENT && options.TransactionType == TransactionTypes.CardPresent)
                {
                    return(new Result <List <CardLimit> >()
                    {
                        Code = ResultCodes.BadRequest,
                        Message = $"Maximun card allowance exceeded for Card Number {card.CardNumber} and Transaction Type {options.TransactionType}"
                    });
                }
                if (carLimit.AggrAmount + options.TransAmount > MAX_ECOMMERCE && options.TransactionType == TransactionTypes.eCommerce)
                {
                    return(new Result <List <CardLimit> >()
                    {
                        Code = ResultCodes.BadRequest,
                        Message = $"Maximun card allowance exceeded for Card Number {card.CardNumber} and Transaction Type {options.TransactionType}"
                    });
                }
                var sumOfLimits = card.Limits
                                  .Sum(l => l.AggrAmount);

                if (sumOfLimits + options.TransAmount > card.AvailableBalance)
                {
                    return(new Result <List <CardLimit> >()
                    {
                        Code = ResultCodes.BadRequest,
                        Message = $"Card availiable balance <<{card.AvailableBalance}>> exceeded"
                    });
                }

                carLimit.AggrAmount += options.TransAmount;

                await _dbContext.SaveChangesAsync();

                return(new Result <List <CardLimit> >()
                {
                    Code = ResultCodes.Success,
                    Message = $"Transaction completed. Availiable card balance is {card.AvailableBalance - (sumOfLimits + options.TransAmount)}",
                    Data = card.Limits
                });
            }
        }