protected void Save(SaveType saveType)
    {
        if (Request.QueryString["debug"] != null && Request.QueryString["debug"] == "1")
        {
            lblXML.Text = "<pre>" + hiddenResponse.Value.Replace("<", "&lt;").Replace(">", "&gt;").Replace(Environment.NewLine, "<br />") + "</pre>";
        }

        Invoice invoice = InvoiceDB.GetByID(Convert.ToInt32(Request.QueryString["invoice"]));

        InvoiceLine[] invLines = InvoiceLineDB.GetByInvoiceID(invoice.InvoiceID);


        using (XmlReader reader = XmlReader.Create(new StringReader(hiddenResponse.Value)))
        {
            reader.ReadToFollowing("detail");

            string tyro_transaction_id = reader.GetAttribute("tyro_transaction_id");

            string result = reader.GetAttribute("result");
            string healthpointErrorCode                  = reader.GetAttribute("healthpointErrorCode");
            string healthpointErrorDescription           = reader.GetAttribute("healthpointErrorDescription");
            string healthpointRefTag                     = reader.GetAttribute("healthpointRefTag");
            string healthpointTotalBenefitAmount         = reader.GetAttribute("healthpointTotalBenefitAmount");
            string healthpointSettlementDateTime         = reader.GetAttribute("healthpointSettlementDateTime");
            string healthpointTerminalDateTime           = reader.GetAttribute("healthpointTerminalDateTime");
            string healthpointMemberNumber               = reader.GetAttribute("healthpointMemberNumber");
            string healthpointProviderId                 = reader.GetAttribute("healthpointProviderId");
            string healthpointServiceType                = reader.GetAttribute("healthpointServiceType");
            string healthpointGapAmount                  = reader.GetAttribute("healthpointGapAmount");
            string healthpointPhfResponseCode            = reader.GetAttribute("healthpointPhfResponseCode");
            string healthpointPhfResponseCodeDescription = reader.GetAttribute("healthpointPhfResponseCodeDescription");



            if (result != "APPROVED")
            {
                var errMsg = "<br />Result: <b>" + result + "</b>";

                if (healthpointErrorCode != "" && healthpointErrorDescription != "")
                {
                    errMsg += "<br />" + healthpointErrorDescription + " (Error Code " + healthpointErrorCode + ")";
                }
                else if (healthpointErrorCode != "")
                {
                    errMsg += "<br />Error Code: " + healthpointErrorCode;
                }
                else if (healthpointErrorDescription != "")
                {
                    errMsg += "<br />Error: " + healthpointErrorDescription;
                }

                lblErrorMessage.Text = errMsg;

                // Email alert this

                return;
            }



            if (saveType == SaveType.Claim)
            {
                DateTime _healthpointSettlementDateTime;
                if (healthpointSettlementDateTime == "undefined")
                {
                    _healthpointSettlementDateTime = DateTime.MinValue;
                }
                else if (!DateTime.TryParseExact(healthpointSettlementDateTime, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out _healthpointSettlementDateTime))
                {
                    throw new Exception("healthpointSettlementDateTime not in correct format: " + healthpointSettlementDateTime);
                }

                DateTime _healthpointTerminalDateTime;
                if (healthpointTerminalDateTime == "undefined")
                {
                    _healthpointTerminalDateTime = DateTime.MinValue;
                }
                else if (!DateTime.TryParseExact(healthpointTerminalDateTime, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out _healthpointTerminalDateTime))
                {
                    throw new Exception("healthpointTerminalDateTime not in correct format: " + healthpointTerminalDateTime);
                }

                decimal paymentAmount = Convert.ToDecimal(healthpointTotalBenefitAmount) / 100;
                decimal gapAmount     = saveType == SaveType.Claim ? Convert.ToDecimal(healthpointGapAmount) / 100 : 0;

                TyroHealthClaimDB.UpdateByTyroTransactionID(
                    tyro_transaction_id,
                    result,
                    healthpointRefTag,
                    paymentAmount,
                    _healthpointSettlementDateTime,
                    _healthpointTerminalDateTime,
                    healthpointMemberNumber,
                    healthpointProviderId,
                    healthpointServiceType,
                    gapAmount,
                    healthpointPhfResponseCode,
                    healthpointPhfResponseCodeDescription);

                TyroHealthClaim tyroHealthClaim = TyroHealthClaimDB.GetByByTyroTransactionID(tyro_transaction_id);

                while (reader.ReadToFollowing("claimItem"))
                {
                    string claimAmount      = reader.GetAttribute("claimAmount");
                    string rebateAmount     = reader.GetAttribute("rebateAmount");
                    string serviceCode      = reader.GetAttribute("serviceCode");
                    string description      = reader.GetAttribute("description");
                    string serviceReference = reader.GetAttribute("serviceReference");
                    string patientId        = reader.GetAttribute("patientId");
                    string serviceDate      = reader.GetAttribute("serviceDate");
                    string responseCode     = reader.GetAttribute("responseCode");

                    DateTime _serviceDate;
                    if (serviceDate == "undefined")
                    {
                        _serviceDate = DateTime.MinValue;
                    }
                    else if (!DateTime.TryParseExact(serviceDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out _serviceDate))
                    {
                        throw new Exception("serviceDate not in correct format: " + serviceDate);
                    }

                    TyroHealthClaimItemDB.Insert(
                        tyroHealthClaim.TyroHealthClaimID,
                        Convert.ToDecimal(claimAmount) / 100,
                        Convert.ToDecimal(rebateAmount) / 100,
                        serviceCode,
                        description,
                        serviceReference,
                        patientId,
                        _serviceDate,
                        responseCode);
                }


                if (result == "APPROVED")
                {
                    decimal totalOwed  = invoice.TotalDue - paymentAmount;
                    bool    isOverPaid = totalOwed < 0;
                    bool    isPaid     = totalOwed <= 0;

                    ReceiptDB.Insert(null, 365, tyroHealthClaim.InvoiceID, paymentAmount, 0, false, isOverPaid, DateTime.MaxValue, -8);

                    if (isPaid)
                    {
                        InvoiceDB.UpdateIsPaid(null, invoice.InvoiceID, true);
                    }

                    if (isOverPaid)
                    {
                        // send email to someone .. to fix up the overpayment....
                        Emailer.SimpleAlertEmail(
                            "Tyro healthpoint invoice late payment added and is overpaid.<br />tyro_health_claim_id: " + tyroHealthClaim.TyroHealthClaimID + "<br />Invoice: " + invoice.InvoiceID + "<br />DB: " + Session["DB"],
                            "Tyro Healthpoint Invoice OverPaid: " + invoice.InvoiceID,
                            true);
                    }
                }

                string cancelLink = "<a href='TyroHealthPointClaimV2.aspx?invoice=" + invoice.InvoiceID + "&reftag=" + healthpointRefTag + "'>Click Here</a>";
                lblResult.Text = "Result: " + result + (result == "APPROVED" ? "<br />Updated Paid Amounts Shown Above<br />To Cancel This Claim " + cancelLink : "") + "<br /><br />";
            }
            else
            {
                if (result == "APPROVED")
                {
                    TyroHealthClaimDB.UpdateCancelled(healthpointRefTag);

                    // set receipt as reversed
                    TyroHealthClaim tyroHealthClaim = TyroHealthClaimDB.GetByRefTag(healthpointRefTag);

                    Receipt[] receipts = ReceiptDB.GetByInvoice(tyroHealthClaim.InvoiceID, false);
                    if (receipts.Length != 1 || receipts[0].ReceiptPaymentType.ID != 365)
                    {
                        Emailer.SimpleAlertEmail(
                            "Tyro claim reversed (by Tyro) but multiple receipts or receipt not of type 'Tyro HC Claim'.<br />healthpointRefTag = " + healthpointRefTag + "<br />DB: " + Session["DB"],
                            "Tyro claim reversed (by Tyro) but multiple receipts or receipt not of type 'Tyro HC Claim'",
                            true
                            );
                    }

                    ReceiptDB.Reverse(receipts[0].ReceiptID, Convert.ToInt32(Session["StaffID"]));
                }

                lblResult.Text = "Cancellation Result: " + result + (result == "APPROVED" ? "<br />Updated Paid Amounts Shown Above" : "") + "<br /><br />";
            }
        }

        SetInvoiceInfo(InvoiceDB.GetByID(invoice.InvoiceID));
    }