/// <summary> /// Purchase gift card /// </summary> /// <param name="giftCard">Gift card</param> /// <returns>Purchased gift card</returns> public PurchasedGiftCard PurchaseGiftCardRequest(int giftCardId) { var giftCard = Repository.Table <GiftCard>().FirstOrDefault(m => m.CardId == giftCardId); if (giftCard == null) { throw new InvalidParameterException("Gift card not found!"); } var canTransact = _earningsService.CanTransact(EarningsBucketType.Spend, giftCard.Amount); if (giftCard.Amount == 0 || !canTransact) { throw new InvalidParameterException("Insufficient balance in spend bucket!"); } var familyMember = _familyService.GetMember(); var adminMember = _familyService.GetAdmin(); var purchasedGiftCard = new PurchasedGiftCard { FamilyMemberID = familyMember.Id, CardId = giftCard.CardId, Name = giftCard.GiftCardName ?? giftCard.MerchantName, Amount = giftCard.Amount, CoverImageUrl = giftCard.MerchantIconImageUrl, PurchasedOn = DateTime.UtcNow, Status = ApprovalStatus.PendingApproval }; AddPurchasedGiftCard(purchasedGiftCard); // deduct spend amount of corresponding child from child earnings var childEarnings = _earningsService.GetByMemberId(familyMember.Id); childEarnings.Spend -= giftCard.Amount; _earningsService.Update(childEarnings); // Send spent info to parent through SMS var message = $"{familyMember.Firstname.FirstCharToUpper()} wants to purchase a ${purchasedGiftCard.Amount:N2} {purchasedGiftCard.Name} gift card. Do you approve? Reply YES or NO."; _smsApprovalHistory.Add(adminMember.Id, ApprovalType.GiftPurchase, message, purchasedGiftCard.Id); if (adminMember != null && !string.IsNullOrEmpty(adminMember.PhoneNumber)) { _textMessageService.Send(adminMember.PhoneNumber, message); } return(purchasedGiftCard); }
/// <summary> /// Make a donation approval request to the parent /// </summary> /// <param name="donation">The donation</param> /// <returns>The donation</returns> public Donation Donate(Donation donation) { var canAllowTransaction = _earningsService.CanTransact(EarningsBucketType.Share, donation.Amount); if (donation.Amount == 0 || !canAllowTransaction) { throw new InvalidOperationException($"Insufficient balance in share bucket!"); } donation.FamilyMemberID = _currentUserService.MemberID; donation.Date = DateTime.UtcNow; Repository.Insert(donation); // Updates child earnings var childEarnings = _earningsService.GetByMemberId(_currentUserService.MemberID); childEarnings.Share -= donation.Amount; Repository.Update(childEarnings); var child = _familyService.GetMemberById(donation.FamilyMemberID); var admin = _familyService.GetAdmin(); var charity = Repository.Table <Charity>().SingleOrDefault(p => p.Id == donation.CharityID); var message = $"{child.Firstname.FirstCharToUpper()} has decided to donate ${donation.Amount:N2} to {charity.Name}." + $" Are you OK with transfering ${donation.Amount:N2} back into your account so you can make the donation? Reply YES or NO."; _smsApprovalHistory.Add(admin.Id, ApprovalType.CharityDonation, message, donation.Id); if (admin != null && !string.IsNullOrEmpty(admin.PhoneNumber)) { _textMessageService.Send(admin.PhoneNumber, message); } return(donation); }
/// <summary> /// initiates the stock purchase. /// </summary> /// <param name="stockPurchaseRequest">The stock purchase request.</param> /// <returns>The stock purchase request.</returns> public StockPurchaseRequest InitiateStockPurchase(StockPurchaseRequest stockPurchaseRequest) { stockPurchaseRequest.Fee = StockFee; var canAllowTransaction = _earningsService.CanTransact(EarningsBucketType.Save, (stockPurchaseRequest.Amount + stockPurchaseRequest.Fee)); if (stockPurchaseRequest.Amount == 0 || !canAllowTransaction) { throw new InvalidOperationException("Insufficient balance in save bucket!"); } stockPurchaseRequest.LineItemID = Guid.NewGuid(); stockPurchaseRequest.TransactionID = Guid.NewGuid(); stockPurchaseRequest.DateCreated = DateTime.UtcNow; stockPurchaseRequest.ChildID = _currentUserService.MemberID; Repository.Insert(stockPurchaseRequest); // deduct save amount of corresponding child from child earnings var childEarnings = _earningsService.GetByMemberId(_currentUserService.MemberID); childEarnings.Save -= (stockPurchaseRequest.Amount + stockPurchaseRequest.Fee); // Deducting stock amount including Fee Repository.Update(childEarnings); var admin = _familyService.GetAdmin(); var child = _familyService.GetMember(); var stock = GetById(stockPurchaseRequest.StockItemID); var stockName = string.IsNullOrEmpty(stock.BrandName) ? stock.CompanyPopularName : stock.BrandName; var message = $"{child.Firstname.FirstCharToUpper()} would like to buy ${stockPurchaseRequest.Amount:N2} of {stockName} stock. Are you OK with this? Reply YES or NO."; _smsApprovalHistory.Add(admin.Id, ApprovalType.StockPurchase, message, stockPurchaseRequest.Id); if (admin != null && !string.IsNullOrEmpty(admin.PhoneNumber)) { _textMessageService.Send(admin.PhoneNumber, message); } return(stockPurchaseRequest); }
/// <summary> /// Send pay day notification. /// </summary> public void SendPayDayMessage() { var dtTodayUtc = DateTime.UtcNow; var timeZoneCST = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); var utcOffset = new DateTimeOffset(dtTodayUtc, TimeSpan.Zero); DateTime cstTimeZoneTime = utcOffset.ToOffset(timeZoneCST.GetUtcOffset(utcOffset)).DateTime; var nextPayDate = cstTimeZoneTime.GetNextPayDay().Date.AddHours(15); decimal amountdeduction = decimal.Zero; var startDate = nextPayDate.AddDays(-7); decimal memberPrevAmount = decimal.Zero; var completedChoresByFamily = _choreService.GetCompletedChoresByFamily(startDate, nextPayDate); foreach (var familyChores in completedChoresByFamily) { //Update Include flag for perticular family foreach (var choreDetail in familyChores) { var includedChore = Repository.Table <Chore>().SingleOrDefault(p => p.Id.Equals(choreDetail.Id)); includedChore.IncludedFlag = true; Repository.Update(includedChore); } var amountToBePaid = familyChores.Sum(m => m.Value); var childMembers = familyChores.Select(p => p.FamilyMember).Distinct().ToList(); //Check for previous Week childs amount foreach (var child in childMembers) { //memberPrevAmount = _earningServices.CalculateChildChoreStatusAmount(child.Id); if (memberPrevAmount != decimal.Zero) { amountToBePaid = amountToBePaid - memberPrevAmount; } } var childCount = Repository.Table <FamilyMember>().Count(m => m.User.FamilyID == familyChores.Key && m.MemberType == MemberType.Child && !m.IsDeleted); if (childCount == 0) { continue; } var admin1 = Repository.Table <FamilyMember>().FirstOrDefault(m => m.User.FamilyID == familyChores.Key); var admin = Repository.Table <FamilyMember>().FirstOrDefault(m => m.User.FamilyID == familyChores.Key && m.MemberType == MemberType.Admin && m.User.Family.FamilySubscription.Status == SubscriptionStatus.Active); if (admin == null) { continue; } ////Check Financial Account Verification var hasFinancialAccount = Repository.Table <FinancialAccount>().Where(p => p.FamilyMemberID == admin.Id).FirstOrDefault().Status; if (hasFinancialAccount != FinancialAccountStatus.Verified) { continue; } //Check The amount less than $1 if (amountToBePaid < 1) { var lessAmountMessage = "Your family total for the week is less than $1.00. BusyKid cannot process transactions less than $1.00."; _smsApprovalHistory.AddLessAmount(admin.Id, ApprovalType.ChorePayment, lessAmountMessage); if (!string.IsNullOrEmpty(admin.PhoneNumber)) { _textMessageService.Send(admin.PhoneNumber, lessAmountMessage); } continue; } if (admin.PayDayAutoApproval) { foreach (var chore in familyChores) { chore.ChoreStatus = ChoreStatus.CompletedAndApproved; Repository.Update(chore); } continue; } decimal totalAmountToBePaid = 0; var meesagesum = "Total"; var childPaymentDetails = string.Empty; foreach (var child in childMembers) { var amountToBePaidToChild = familyChores.Where(m => m.FamilyMemberID == child.Id).Sum(m => m.Value); if (amountToBePaidToChild == 0) { continue; } var separator = "\n"; //amountdeduction = _earningServices.CalculateChildChoreStatusAmount(child.Id); amountToBePaidToChild = amountToBePaidToChild - amountdeduction; if (amountToBePaidToChild <= 0) { continue; } totalAmountToBePaid = totalAmountToBePaid + amountToBePaidToChild; childPaymentDetails += $"{ child.Firstname }: ${amountToBePaidToChild:N2}{separator}"; } childPaymentDetails += $"{ meesagesum }: ${totalAmountToBePaid:N2}"; var message = $"Tomorrow is payday! Here is a summary of earnings: \n{childPaymentDetails}" + " \n\nReply YES or NO.\nRespond within 2 hours to ensure Friday payday."; _smsApprovalHistory.Add(admin.Id, ApprovalType.ChorePayment, message); if (!string.IsNullOrEmpty(admin.PhoneNumber)) { _textMessageService.Send(admin.PhoneNumber, message); } //SendMessagePaydayNotProceedService(startDate, nextPayDate, admin.Id); } }