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 }); }
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 }); } }