/// <summary> /// This is to be called by monthly agent and manual payment. /// </summary> public static bool ProcessInvoicesAndPayments(int companyId, DateTime dateToConsider, bool shouldCreateInvoices, int userId) { using (StageBitzDB dataContext = new StageBitzDB()) { FinanceSupport.InitializePaymentSettings(); bool isPaymentSuccess = false; bool isManualPayment = (companyId == 0) ? false : true; List <Invoice> invoiceList = new List <Invoice>(); if (shouldCreateInvoices) { List <CompanyPaymentSummary> unProcessedPaymentSummaries = GetUnProcessedCompanyPaymentSummaries(0, dataContext, dateToConsider); //Only consider companies which has payment packages List <Data.Company> companies = (from c in dataContext.Companies join cpp in dataContext.CompanyPaymentPackages on c.CompanyId equals cpp.CompanyId select c).Distinct().ToList(); if (unProcessedPaymentSummaries.Count > 0) { CompanyBL companyBL = new CompanyBL(dataContext); foreach (Data.Company company in companies) { try { List <CompanyPaymentSummary> unProcessedCompanyPaymentSummaries = unProcessedCompanyPaymentSummaries = unProcessedPaymentSummaries.Where(upcs => upcs.CompanyId == company.CompanyId).OrderBy(ups => ups.CompanyPaymentSummaryId).ToList(); //*******Consider payment summaries for the company********* if (unProcessedCompanyPaymentSummaries != null && unProcessedCompanyPaymentSummaries.Count() > 0) { if (!companyBL.IsFreeTrialCompany(company.CompanyId, dateToConsider)) { decimal totalAmount = unProcessedCompanyPaymentSummaries.Sum(ups => ups.Amount); DateTime fromDate = unProcessedCompanyPaymentSummaries.First().FromDate; DateTime toDate = unProcessedCompanyPaymentSummaries.Last().ToDate; Invoice invoice = null; if (totalAmount > 0) //generate the invoice only if there is a due amount to pay { invoice = FinanceSupport.CreateInvoice(company.CompanyId, "Company", "PACKAGEFEE", string.Format("Payment for Company {0}", company.CompanyName), decimal.Round(totalAmount, 2), fromDate, toDate, dataContext); } foreach (CompanyPaymentSummary companyPackagePaymentSummary in unProcessedCompanyPaymentSummaries) { companyPackagePaymentSummary.IsMonthlyAgentProcessed = true; if (invoice != null) { companyPackagePaymentSummary.Invoice = invoice; } companyPackagePaymentSummary.LastUpdatedDate = Utils.Today; companyPackagePaymentSummary.LastUpdatedBy = 0; } } } } catch (Exception ex) { AgentErrorLog.WriteToErrorLog("Failed to create Invoice for projectId" + company.CompanyId); AgentErrorLog.HandleException(ex); isPaymentSuccess = false; } } //Complete upto now. dataContext.SaveChanges(); } //Get all the Unprocessed Invoices to send to the payment gateway. invoiceList = FinanceSupport.GetUnProcessedInvoicesByRelatedTable("Company", companyId, "PACKAGEFEE", dataContext); } else { int companyStatusCodeID = 0; if (!isManualPayment) { //Not Manual means, Payment Retry. companyStatusCodeID = Utils.GetCodeByValue("CompanyStatus", "GRACEPERIOD").CodeId; } //Get all the Unprocessed Invoices to send to the payment gateway. //For Grace period payment Retry process projectId is 0. invoiceList = FinanceSupport.GetPaymentFailedInvoices("PACKAGEFEE", companyStatusCodeID, companyId, "Company", dataContext); } //Because we need Payment Log records before process Invoices. foreach (Invoice invoice in invoiceList) { FinanceSupport.CreatePaymentLog(invoice.InvoiceID, dataContext); } dataContext.SaveChanges(); //Get distinct company Ids within the unprocessed invoice list var companyIds = invoiceList.Select(inv => inv.RelatedID).Distinct(); foreach (int distinctCompanyId in companyIds) { isPaymentSuccess = ProcessInvoicesByCompany(invoiceList, distinctCompanyId, isManualPayment, dataContext); if (isPaymentSuccess) { CompanyBL companyBL = new CompanyBL(dataContext); companyBL.ActivateUnProcessedSummaries(distinctCompanyId, userId); } } dataContext.SaveChanges(); //For the Monthly Agent Runner the return value is not important but for the manual payment. return(isPaymentSuccess); } }