/// <summary> /// Returns the warning status of the project based on it's current status and expiration details. /// </summary> public static CompanyWarningInfo GetCompanyWarningStatus(int companyId, int companyStatusCodeId, DateTime?expirationDate) { using (StageBitzDB dataContext = new StageBitzDB()) { CompanyBL companyBL = new CompanyBL(dataContext); FinanceBL financeBL = new FinanceBL(dataContext); string statusCode = Utils.GetCodeByCodeId(companyStatusCodeId).Value; double remainingDays = (statusCode == "ACTIVE" || expirationDate == null) ? -1 : (expirationDate.Value.Date - Utils.Today).TotalDays; CompanyWarningStatus warningStatus = CompanyWarningStatus.NoWarning; if (companyBL.HasCompanySuspendedbySBAdmin(companyId)) { warningStatus = CompanyWarningStatus.SBAdminSuspended; } else if (statusCode == "GRACEPERIOD" && ProjectFinanceHandler.IsPaymentFailedInvoicesExistForCompany(companyId)) { warningStatus = CompanyWarningStatus.PaymentFailedGracePeriod; } else if (statusCode == "SUSPENDEDFORPAYMENTFAILED") { warningStatus = CompanyWarningStatus.PaymentFailed; } else if (!financeBL.HasPackageSelectedForFreeTrailEndedCompany(companyId)) { warningStatus = CompanyWarningStatus.FreeTrailEndNoPaymentPackage; } else if (statusCode == "SUSPENDEDFORNOPAYMENTOPTIONS") { warningStatus = CompanyWarningStatus.SuspendedForNoPaymentOptions; } return(new CompanyWarningInfo(warningStatus, (int)Math.Round(remainingDays, 0))); } }
/// <summary> /// Creates the payment summaries. /// This will create payment summaries/Invoice Requests for the repeat payments to be charged at the end of the cycle /// </summary> /// <param name="dateToConsider">The date to consider.</param> public static void CreatePaymentSummaries(DateTime dateToConsider) { using (StageBitzDB dataContext = new StageBitzDB()) { FinanceBL financeBL = new FinanceBL(dataContext); CompanyBL companyBL = new CompanyBL(dataContext); //This will get all the CompanyPaymentPackages that needs to be Charged for considering cycle List <CompanyPaymentPackage> companyPaymentPackages = (from cpp in dataContext.CompanyPaymentPackages join cps in dataContext.CompanyPaymentSummaries on cpp.CompanyId equals cps.CompanyId where cps.IsImmidiateFutureRecordCreated == false && cpp.StartDate <= dateToConsider && (cpp.EndDate > dateToConsider || cpp.EndDate == null) && cps.NextPaymentCycleStartingDate <= dateToConsider select cpp).Distinct().ToList(); foreach (CompanyPaymentPackage companyPaymentPackage in companyPaymentPackages) { Data.Company company = companyPaymentPackage.Company; PaymentSummaryDetails paymentSummaryDetails = new PaymentSummaryDetails() { CompanyPaymentPackage = companyPaymentPackage, CompanyId = companyPaymentPackage.CompanyId, ShouldProcess = !(companyBL.IsCompanySuspended(companyPaymentPackage.CompanyId) || companyBL.HasCompanySuspendedbySBAdmin(companyPaymentPackage.CompanyId)), UserId = 0, PackageStartDate = companyPaymentPackage.StartDate, PaymentMethodCodeId = companyPaymentPackage.PaymentMethodCodeId, HasPackageChanged = false, ProjectPaymentPackageTypeId = companyPaymentPackage.ProjectPaymentPackageTypeId, InventoryPaymentPackageTypeId = companyPaymentPackage.InventoryPaymentPackageTypeId, IsEducationPackage = companyPaymentPackage.IsEducationalPackage, PaymentDurationTypeCodeId = companyPaymentPackage.PaymentDurationCodeId, DiscountCodeUsageToApply = financeBL.GetLatestDiscountCodeUsage(companyPaymentPackage.CompanyId) }; //Get IsImmidiateFutureRecordCreated "False" Future Anual Summary records and make them as "True".(To commit as Processed) var unprocessedFutureSummaries = (from cps in dataContext.CompanyPaymentSummaries where cps.IsImmidiateFutureRecordCreated == false && cps.CompanyId == companyPaymentPackage.CompanyId && cps.ToDate <= dateToConsider select cps).ToList(); foreach (CompanyPaymentSummary cps in unprocessedFutureSummaries) { cps.IsImmidiateFutureRecordCreated = true; cps.LastUpdatedDate = Utils.Today; cps.LastUpdatedBy = 0; } CreateCompanyPaymentSummaries(paymentSummaryDetails, dateToConsider, dataContext); } dataContext.SaveChanges(); } }
/// <summary> /// Processes the invoices by company. /// </summary> /// <param name="invoiceList">The invoice list.</param> /// <param name="companyId">The company identifier.</param> /// <param name="isManualPayment">if set to <c>true</c> [is manual payment].</param> /// <param name="dataContext">The data context.</param> /// <returns></returns> private static bool ProcessInvoicesByCompany(List <Invoice> invoiceList, int companyId, bool isManualPayment, StageBitzDB dataContext) { CompanyBL companyBL = new CompanyBL(dataContext); List <Invoice> companyInvoices = invoiceList.Where(inv => inv.RelatedID == companyId).ToList(); Data.Company company = dataContext.Companies.Where(c => c.CompanyId == companyId).FirstOrDefault(); bool isAllPaymentsSuccess = true; foreach (Invoice invoice in companyInvoices) { bool isPaymentSuccess = ProcessInvoice(invoice, company, dataContext); if (!isPaymentSuccess) { isAllPaymentsSuccess = false; } } List <Code> projectStatusCodes = Utils.GetCodesByCodeHeader("ProjectStatus"); int suspendStateCodeId = projectStatusCodes.Where(c => c.Value == "SUSPENDED").SingleOrDefault().CodeId; int activeStateCodeId = projectStatusCodes.Where(c => c.Value == "ACTIVE").SingleOrDefault().CodeId; int graceperiodStateCodeId = projectStatusCodes.Where(c => c.Value == "GRACEPERIOD").SingleOrDefault().CodeId; int paymentfailedStateCodeId = projectStatusCodes.Where(c => c.Value == "PAYMENTFAILED").SingleOrDefault().CodeId; List <Code> companyStatusCodes = Utils.GetCodesByCodeHeader("CompanyStatus"); int activeCompanyStateCodeId = companyStatusCodes.Where(c => c.Value == "ACTIVE").SingleOrDefault().CodeId; int gracePeriodCompanyStateCodeId = companyStatusCodes.Where(c => c.Value == "GRACEPERIOD").SingleOrDefault().CodeId; int paymentFailedCompanyStateCodeId = companyStatusCodes.Where(c => c.Value == "SUSPENDEDFORPAYMENTFAILED").SingleOrDefault().CodeId; List <Data.Project> projectList = dataContext.Projects.Where(p => p.CompanyId == companyId).ToList(); if (!isAllPaymentsSuccess) { int previousCompanyStatusCodeId = company.CompanyStatusCodeId; // For active project, change it to grace period. if (company.CompanyStatusCodeId == activeCompanyStateCodeId) { company.CompanyStatusCodeId = gracePeriodCompanyStateCodeId; //Next expiration date is 7 days from today company.ExpirationDate = Utils.Today.AddDays(7); company.LastUpdatedByUserId = 0; company.LastUpdatedDate = Utils.Now; } // For grace period project, if it exceeded the grace period change it to Payment Failed. else if (company.CompanyStatusCodeId == gracePeriodCompanyStateCodeId && company.ExpirationDate <= Utils.Today) { company.CompanyStatusCodeId = paymentFailedCompanyStateCodeId; company.LastUpdatedByUserId = 0; company.LastUpdatedDate = Utils.Now; company.ExpirationDate = null; } // Send email notice on payment failure. (Only for monthly process). exclude email if company is suspended by SB admin if (!isManualPayment && !companyBL.HasCompanySuspendedbySBAdmin(companyId)) { int companyPrimaryAdminCodeID = Utils.GetCodeByValue("CompanyUserTypeCode", "ADMIN").CodeId; string userWebUrl = Utils.GetSystemValue("SBUserWebURL"); string supportEmail = Utils.GetSystemValue("FeedbackEmail"); Data.User companyPrimaryAdmin = // project.Company.CompanyUsers.Where(cu => cu.IsActive == true && cu.CompanyUserTypeCodeId == companyPrimaryAdminCodeID).FirstOrDefault().User; (from cu in company.CompanyUsers join cur in dataContext.CompanyUserRoles on cu.CompanyUserId equals cur.CompanyUserId where cu.IsActive && cur.CompanyUserTypeCodeId == companyPrimaryAdminCodeID && cur.IsActive select cu).FirstOrDefault().User; string companyBillingUrl = string.Format("{0}/Company/CompanyFinancialDetails.aspx?companyid={1}", userWebUrl, companyId); // This sends only when the company status change to payment failed grace period. if (previousCompanyStatusCodeId == activeCompanyStateCodeId && company.CompanyStatusCodeId == gracePeriodCompanyStateCodeId) { EmailSender.SendCompanyExpirationNoticeToCompanyAdmin("COMPANYGRACEPERIOD", companyId, companyPrimaryAdmin.Email1, companyPrimaryAdmin.FirstName, company.CompanyName, companyBillingUrl, supportEmail); } // This sends only when the company status change to Payment failed. else if (previousCompanyStatusCodeId == gracePeriodCompanyStateCodeId && company.CompanyStatusCodeId == paymentFailedCompanyStateCodeId) { EmailSender.SendCompanyExpirationNoticeToCompanyAdmin("COMPANYPAYMENTFAILED", companyId, companyPrimaryAdmin.Email1, companyPrimaryAdmin.FirstName, company.CompanyName, companyBillingUrl, supportEmail); } } } else { if (company.CompanyStatusCodeId == Utils.GetCodeIdByCodeValue("CompanyStatus", "GRACEPERIOD") || company.CompanyStatusCodeId == Utils.GetCodeIdByCodeValue("CompanyStatus", "SUSPENDEDFORPAYMENTFAILED")) { company.CompanyStatusCodeId = Utils.GetCodeIdByCodeValue("CompanyStatus", "ACTIVE"); company.LastUpdatedByUserId = 0; company.LastUpdatedDate = Utils.Now; company.ExpirationDate = null; } } foreach (Data.Project project in projectList) { int currentProjectStatusCodeId = project.ProjectStatusCodeId; if (isAllPaymentsSuccess) { int previousStatusCodeId = ProjectStatusHandler.GetPreviuosProjectStatusFromHistory(project.ProjectId); // We need to consier whether current project status. // If it is "Suspended", we are not going to make any change. Because when user tries to reactivate only, we are going to check for pending invoices. // If it is "Active", we do nothing. if (currentProjectStatusCodeId == paymentfailedStateCodeId || currentProjectStatusCodeId == graceperiodStateCodeId) { project.ProjectStatusCodeId = activeStateCodeId; project.ExpirationDate = null; project.LastUpdatedByUserId = 0; project.LastUpdatedDate = Utils.Now; } else if (currentProjectStatusCodeId == suspendStateCodeId && previousStatusCodeId == graceperiodStateCodeId) { project.ExpirationDate = null; project.LastUpdatedByUserId = 0; project.LastUpdatedDate = Utils.Now; } } else { //Do not update if the Project status is Suspended or Payment Failed if (currentProjectStatusCodeId == activeStateCodeId || currentProjectStatusCodeId == graceperiodStateCodeId) { if (project.ProjectStatusCodeId == activeStateCodeId) { project.ProjectStatusCodeId = graceperiodStateCodeId; //Next expiration date is 7 days from today project.ExpirationDate = Utils.Today.AddDays(7); project.LastUpdatedByUserId = 0; project.LastUpdatedDate = Utils.Now; } else if (project.ExpirationDate <= Utils.Today) //This handles payment retry. For Grace period project, if it exceeded the grace period change it to Payment Failed. { project.ProjectStatusCodeId = paymentfailedStateCodeId; project.LastUpdatedByUserId = 0; project.LastUpdatedDate = Utils.Now; } } } } return(isAllPaymentsSuccess); }