private void GenerateInvoice(Application application, EInvoicePurpose invoicePurpose)
        {
            var feeName         = application.PaymentSchedule.ToString();
            var feeScheduleItem = _context.FeeSchedule.First(x => x.ApplicationTypeName == feeName);
            int numberOfUnits   = (application.ProjectInfo is IUnitCount)
                ? ((IUnitCount)application.ProjectInfo).UnitCount
                : 0;
            float fee = feeScheduleItem.CalculateProcessingFee(numberOfUnits);

            if (invoicePurpose == EInvoicePurpose.IncompleteFee)
            {
                fee = EFeeSchedule.INCOMPLETE_FEE;
            }
            else if (invoicePurpose == EInvoicePurpose.MapReviewFee)
            {
                fee = feeScheduleItem.CalculateMapReviewFee(numberOfUnits);
            }

            // We forgive fees less than a nickle I guess. CCSF can bill James Ryan the damages ^_^
            if (Math.Abs(fee) < .05f)
            {
                return; // Don't generate an invoice.
            }
            var invoiceEnvelope = ApplicationToInvoice(fee, application);
            var invoice         = new CreateInvoiceXml(PaymentGatewaySoapHelper.CallWebService(invoiceEnvelope));
            var invoiceRead     =
                new ReadInvoiceXml(PaymentGatewaySoapHelper.CallWebService(new ReadInvoiceEnvelope(invoice.Id)));

            InvoiceInfo finalInvoice = new InvoiceInfo()
            {
                InvoiceNo      = invoice.Id,
                PayUrl         = invoice.Payurl,
                PrintUrl       = invoice.Printurl,
                Created        = invoiceRead.Created,
                Paid           = invoiceRead.IsPaid,
                Void           = invoiceRead.Voided,
                Amount         = fee.ToString("c2"),
                InvoicePurpose = invoicePurpose
            };

            var paymentForm = new PaymentForm();

            application.Forms.Add(paymentForm);
            _context.SaveChanges();
            finalInvoice.PaymentForm   = paymentForm;
            finalInvoice.PaymentFormId = paymentForm.Id;
            _context.Invoices.Add(finalInvoice);
            _context.SaveChanges();

            paymentForm.InvoiceId = finalInvoice.Id;
            paymentForm.Invoice   = finalInvoice;
        }
        public ActionResult VoidInvoice(VoidViewModel vm)
        {
            var invoice = _context.Invoices.Where(x => x.Id == vm.InvoiceId).Include(x => x.PaymentForm).FirstOrDefault();

            if (invoice == null)
            {
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }
            // Verify Payment
            var voidTry =
                new VoidInvoiceXml(PaymentGatewaySoapHelper.CallWebService(new VoidInvoiceEnvelope(invoice.InvoiceNo, vm.UserName, vm.Reason)));

            var invoiceRead =
                new ReadInvoiceXml(PaymentGatewaySoapHelper.CallWebService(new ReadInvoiceEnvelope(invoice.InvoiceNo)));

            invoice.Void = invoiceRead.Voided;
            _context.SaveChanges();

            return(Json(new { result = voidTry.Result, success = invoice.Void }));
        }
        public ActionResult CheckInvoice(int id)
        {
            var invoice = _context.Invoices.Where(x => x.Id == id).Include(x => x.PaymentForm).FirstOrDefault();

            if (invoice == null)
            {
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }

            if (!invoice.Paid)
            {
                var aid         = invoice.PaymentForm.ApplicationId;
                var application = _context.Applications.Where(x => x.Id == aid)
                                  .Include(x => x.StatusHistory)
                                  .Include(x => x.Applicants)
                                  .Include(x => x.ProjectInfo)
                                  .FirstOrDefault();
                var applicant = GetCurrentApplicant();
                if (application == null)
                {
                    throw new HttpResponseException(HttpStatusCode.BadRequest);
                }
                if (!User.IsInRole(EUserRoles.Admin) && !User.IsInRole(EUserRoles.Bsm))
                {
                    // Ensure that an applicant is looking at their invoice & not somebody else's
                    if (application.Applicants.All(x => x.Id != applicant.Id))
                    {
                        throw new HttpResponseException(HttpStatusCode.BadRequest);
                    }
                }
                // Verify Payment
                var invoiceRead =
                    new ReadInvoiceXml(PaymentGatewaySoapHelper.CallWebService(new ReadInvoiceEnvelope(invoice.InvoiceNo)));

                invoice.Paid = invoiceRead.IsPaid && !invoiceRead.Voided;
                invoice.Void = invoiceRead.Voided;

                if (invoice.Paid)
                {
                    EApplicationStatus status;
                    if (invoice.InvoicePurpose == EInvoicePurpose.InitialPayment)
                    {
                        status = EApplicationStatus.InitialPaymentReceived;
                    }
                    else if (invoice.InvoicePurpose == EInvoicePurpose.IncompleteFee)
                    {
                        status = EApplicationStatus.IncompleteFeeReceived;
                    }
                    else if (invoice.InvoicePurpose == EInvoicePurpose.MapReviewFee)
                    {
                        status = EApplicationStatus.MapReviewFeeReceived;
                    }
                    else
                    {
                        throw new NotSupportedException(EnumHelper <EInvoicePurpose> .GetDisplayValue(invoice.InvoicePurpose));
                    }
                    application.StatusHistory.Add(ApplicationStatusLogItem.FactoryCreate(status));
                }
                _context.SaveChanges();
            }
            return(Json(new { paid = invoice.Paid, voided = invoice.Void, success = invoice.Paid || invoice.Void }));
        }