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
            });
        }
Exemple #2
0
        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);
        }