public int ProcessFirstAccrualInvoices(int branchID, int[] invoiceIDs, DateTime processDate)
    {
        int processedInvoices = 0;

        foreach (var invoiceID in invoiceIDs)
        {
            var     invoiceHeader = ctx.InvoiceHeaders.SingleOrDefault(inv => inv.ID == invoiceID);
            decimal adminFee      = 0;
            if (invoiceHeader != null)
            {
                // invoice
                int duesInMonth = invoiceHeader.Contract.DuesInMonth;
                var iah         = new InvoiceAccrualHeader();
                iah.InvoiceID = invoiceHeader.ID;
                iah.InvoiceNo = autoNumberProvider.Generate(branchID, "OR", processDate.Month, processDate.Year);
                autoNumberProvider.Increment("OR", branchID, processDate.Year);
                iah.TotalAmount = ctx.func_GetTotalInvoice(invoiceHeader.InvoiceNo).GetValueOrDefault();
                iah.AccrualDate = processDate;
                //iah.AccrualAmount = iah.TotalAmount / duesInMonth;
                iah.CreatedWhen        = DateTime.Now;
                iah.CreatedWho         = HttpContext.Current.User.Identity.Name;
                iah.SumAccrualPeriod   = 1;
                iah.TotalAccrualPeriod = duesInMonth;

                var details = invoiceHeader.InvoiceDetails.Where(invd => !invd.Item.Description.Contains("Admin Fee"));
                var total   = 0M;
                foreach (var detail in details)
                {
                    var iad = new InvoiceAccrualDetail
                    {
                        Discount =
                            detail.Discount / (detail.Item.ItemAccountID == ITEM_ACCOUNT_ADMINISTRATION_FEE
                                          ? 1
                                          : duesInMonth),
                        IsTaxable = detail.IsTaxable,
                        ItemID    = detail.ItemID,
                        Quantity  = detail.Quantity,
                        UnitPrice =
                            detail.UnitPrice / (detail.Item.ItemAccountID == ITEM_ACCOUNT_ADMINISTRATION_FEE
                                          ? 1
                                          : duesInMonth)
                    };
                    total += iad.UnitPrice * iad.Quantity - (iad.Discount / 100 * iad.UnitPrice * iad.Quantity) -
                             (invoiceHeader.DiscountValue / duesInMonth);
                    iah.InvoiceAccrualDetails.Add(iad);
                }
                iah.AccrualAmount    = total;
                iah.SumAccrualAmount = iah.AccrualAmount;
                ctx.InvoiceAccrualHeaders.InsertOnSubmit(iah);

                // payment
                var    paymentHeader = invoiceHeader.PaymentHeaders.FirstOrDefault(pay => !pay.VoidDate.HasValue);
                string paymentNo     = String.Empty;
                if (paymentHeader != null)
                {
                    var payAccHeader = new PaymentAccrualHeader();
                    payAccHeader.InvoiceAccrualHeader = iah;
                    paymentNo = autoNumberProvider.Generate(branchID,
                                                            "PM",
                                                            processDate.Month,
                                                            processDate.Year);
                    payAccHeader.PaymentNo = paymentNo;
                    autoNumberProvider.Increment("PM", branchID, processDate.Year);
                    payAccHeader.Date        = processDate;
                    payAccHeader.CreatedWhen = DateTime.Now;
                    payAccHeader.CreatedWho  = HttpContext.Current.User.Identity.Name;

                    var paymentDetails = paymentHeader.PaymentDetails.ToList();
                    foreach (var paymentDetail in paymentDetails)
                    {
                        var payAccDetail = new PaymentAccrualDetail();
                        payAccDetail.Amount           = total / paymentDetails.Count;
                        payAccDetail.ApprovalCode     = paymentDetail.ApprovalCode;
                        payAccDetail.CreditCardTypeID = paymentDetail.CreditCardTypeID;
                        payAccDetail.Notes            = paymentDetail.Notes;
                        payAccDetail.PaymentTypeID    = paymentDetail.PaymentTypeID;

                        payAccHeader.PaymentAccrualDetails.Add(payAccDetail);
                    }
                    ctx.PaymentAccrualHeaders.InsertOnSubmit(payAccHeader);
                }


                // invoice
                var iahAdminFee = new InvoiceAccrualHeader();
                iahAdminFee.InvoiceID = invoiceHeader.ID;
                iahAdminFee.InvoiceNo = iah.InvoiceNo + "AF";
                //iahAdminFee.TotalAmount = ctx.func_GetTotalInvoice(invoiceHeader.InvoiceNo).GetValueOrDefault();
                iahAdminFee.AccrualDate = processDate;
                //iah.AccrualAmount = iah.TotalAmount / duesInMonth;
                iahAdminFee.CreatedWhen        = DateTime.Now;
                iahAdminFee.CreatedWho         = HttpContext.Current.User.Identity.Name;
                iahAdminFee.SumAccrualPeriod   = 0;
                iahAdminFee.TotalAccrualPeriod = 0;

                var detailsAdminFee = invoiceHeader.InvoiceDetails.Where(invd => invd.Item.Description.Contains("Admin Fee"));
                var totalAdminFee   = 0M;
                foreach (var detail in detailsAdminFee)
                {
                    var iadAdminFee = new InvoiceAccrualDetail
                    {
                        Discount =
                            detail.Discount / (detail.Item.ItemAccountID == ITEM_ACCOUNT_ADMINISTRATION_FEE
                                ? 1
                                : duesInMonth),
                        IsTaxable = false,
                        ItemID    = detail.ItemID,
                        Quantity  = detail.Quantity,
                        UnitPrice =
                            detail.UnitPrice / (detail.Item.ItemAccountID == ITEM_ACCOUNT_ADMINISTRATION_FEE
                                ? 1
                                : duesInMonth)
                    };
                    totalAdminFee += iadAdminFee.UnitPrice * iadAdminFee.Quantity - (iadAdminFee.Discount / 100 * iadAdminFee.UnitPrice * iadAdminFee.Quantity) -
                                     (invoiceHeader.DiscountValue / duesInMonth);
                    iahAdminFee.InvoiceAccrualDetails.Add(iadAdminFee);
                }
                iahAdminFee.AccrualAmount    = totalAdminFee;
                iahAdminFee.TotalAmount      = totalAdminFee;
                iahAdminFee.SumAccrualAmount = iahAdminFee.AccrualAmount;
                ctx.InvoiceAccrualHeaders.InsertOnSubmit(iahAdminFee);
                iah.TotalAmount -= iahAdminFee.TotalAmount;
                // payment
                var paymentHeaderAdminFee = invoiceHeader.PaymentHeaders.FirstOrDefault(pay => !pay.VoidDate.HasValue);
                if (paymentHeaderAdminFee != null)
                {
                    var payAccHeader = new PaymentAccrualHeader();
                    payAccHeader.InvoiceAccrualHeader = iahAdminFee;
                    payAccHeader.PaymentNo            = paymentNo + "AF";
                    payAccHeader.Date        = processDate;
                    payAccHeader.CreatedWhen = DateTime.Now;
                    payAccHeader.CreatedWho  = HttpContext.Current.User.Identity.Name;

                    var paymentDetails = paymentHeaderAdminFee.PaymentDetails.ToList();
                    foreach (var paymentDetail in paymentDetails)
                    {
                        var payAccDetail = new PaymentAccrualDetail();
                        payAccDetail.Amount           = totalAdminFee / paymentDetails.Count;
                        payAccDetail.ApprovalCode     = paymentDetail.ApprovalCode;
                        payAccDetail.CreditCardTypeID = paymentDetail.CreditCardTypeID;
                        payAccDetail.Notes            = paymentDetail.Notes;
                        payAccDetail.PaymentTypeID    = paymentDetail.PaymentTypeID;

                        payAccHeader.PaymentAccrualDetails.Add(payAccDetail);
                    }
                    ctx.PaymentAccrualHeaders.InsertOnSubmit(payAccHeader);
                }

                processedInvoices++;
            }
        }
        ctx.SubmitChanges();
        return(processedInvoices);
    }