async Task Stage1CertFee(IList <BillLineItem> container, TransactionCode code, BillRequestLineItem item) { var duration = item.SubScheme == SubScheme.ShortTerm ? (item.ExpiresOn - item.StartsFrom).Days + 1 : BillingUtils.CalculateNoOfMonths(item.StartsFrom.Date, item.ExpiresOn.Date); var factor = await _context.Stage1Factor(); // Full payment for stage 1 if (item.Scheme == Scheme.Endorsement || item.SubScheme == SubScheme.Canteen || item.SubScheme == SubScheme.ShortTerm) { factor = 1M; } // Short term billed per 7 days else if (item.SubScheme == SubScheme.ShortTerm) { factor = Math.Ceiling(duration / 7M); } else { factor = Math.Min(factor, duration / 12M); } // For case where the pro-rated value is less than stage 1 expected factor. factor = Math.Min(duration / 12, factor); var unitPrice = code.GetLatestPriceAmount(); var gst = await _context.GST(); var qty = factor; var fee = qty * unitPrice; var gstAmount = fee * gst; var section = BillingUtils.LineItemSection(BillType.Stage1); var yearPrefix = duration > 12 ? " - Year 1" : ""; string prorateText = duration < 12 ? $" ({duration} of 12 months)" : ""; container.Add(new BillLineItem { SectionIndex = section.Item1, Section = section.Item2, Qty = qty, CodeID = code.ID, Code = code.Code, Descr = $"{code.Text}{yearPrefix}{prorateText}", UnitPrice = code.GetLatestPriceAmount(), Amount = decimal.Round(fee, 2), GSTAmount = decimal.Round(gstAmount, 2), GST = gst, WillRecord = true }); }
public async Task <IList <BillLineItem> > Generate(BillRequest request) { var result = new List <BillLineItem>(); if (request.LineItems?.Any() ?? false) { foreach (var item in request.LineItems) { if (item.NoOfProducts > 0 && (item.Scheme == Scheme.Endorsement || item.SubScheme == SubScheme.Product || item.SubScheme == SubScheme.WholePlant)) { var duration = BillingUtils.CalculateNoOfMonths( item.StartsFrom.Date, item.ExpiresOn.Date); var code = await GetTransactionCode(item.StartsFrom, item.Scheme, item.SubScheme); var unitPrice = code.GetLatestPriceAmount(); var gst = await _context.GST(); var qty = Math.Round(duration / 12M, 2); var fee = item.NoOfProducts * unitPrice * qty; var gstAmount = fee * gst; var section = BillingUtils.LineItemSection(request.Type); result.Add(new BillLineItem { SectionIndex = section.Item1, Section = section.Item2, Qty = qty, CodeID = code.ID, Code = code.Code, Descr = $"{code.Text} x {item.NoOfProducts} prd. ({duration} months)", UnitPrice = code.GetLatestPriceAmount(), Amount = decimal.Round(fee, 2), GSTAmount = decimal.Round(gstAmount, 2), GST = gst, WillRecord = true }); } } } return(result); }
async Task Stage2CertFee(BillRequestType requestType, IList <BillLineItem> container, TransactionCode code, BillRequestLineItem item) { var totalDuration = BillingUtils.CalculateNoOfMonths(item.StartsFrom.Date, item.ExpiresOn.Date); var stage1Factor = await _context.Stage1Factor(); var prorate = Math.Round(totalDuration / 12M, 2); // No stage 2 payment for prorated application whose factor is less than stage 1 payment. if (prorate < stage1Factor && requestType != BillRequestType.Renewal) { return; } var section = BillingUtils.LineItemSection(BillType.Stage2); decimal factor; int i = 0; var duration = (decimal)totalDuration; do { prorate = Math.Min(Math.Round(duration / 12M, 2), 1M); // First year factor. Renewal will only have stage 2 payment. if (i == 0 && requestType != BillRequestType.Renewal) { factor = Math.Max(Math.Min( 1M - stage1Factor, prorate - stage1Factor), 0); } else { factor = Math.Min(1M, prorate); } if (factor == 0M) { break; } var unitPrice = code.GetLatestPriceAmount(); var gst = await _context.GST(); var qty = factor; var fee = qty * unitPrice; var gstAmount = fee * gst; var yearPrefix = totalDuration > 12 ? $" - Year {i + 1}" : ""; var prorateText = duration < 12 ? $" ({(int)duration} of 12 months)" : ""; container.Add(new BillLineItem { SectionIndex = section.Item1, Section = section.Item2, Qty = qty, CodeID = code.ID, Code = code.Code, Descr = $"{code.Text}{yearPrefix}{prorateText}", UnitPrice = code.GetLatestPriceAmount(), Amount = decimal.Round(fee, 2), GSTAmount = decimal.Round(gstAmount, 2), GST = gst, WillRecord = true }); duration -= 12; i++; } while (duration > 0); }