示例#1
0
        static string HandleRequest(string request)
        {
            Message requestMessage = null;

            try
            {
                requestMessage = HL7Utility.Deserialize(request);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception: " + ex.Message);

                Logger.logException(ex);
            }
            if (requestMessage != null)
            {
                // Check if incoming request is in valid format.
                if (requestMessage.Segments != null &&
                    requestMessage.Segments.Count == 4 &&          // DRC, SRV, ARG, ARG = 4
                    requestMessage.Segments[0].Elements != null && // DRC|EXEC-SERVICE|<team name>|<teamID>|
                    requestMessage.Segments[0].Elements.Count == 4 &&
                    requestMessage.Segments[0].Elements[0] == CommandDirectiveElement &&
                    requestMessage.Segments[0].Elements[1] == ExecuteServiceElement &&
                    requestMessage.Segments[1].Elements != null && // SRV||<service name>||<num args>|||
                    requestMessage.Segments[1].Elements.Count == 7 &&
                    requestMessage.Segments[1].Elements[0] == ServiceDirectiveElement &&
                    requestMessage.Segments[1].Elements[1] == "" &&
                    requestMessage.Segments[1].Elements[3] == "" &&
                    requestMessage.Segments[1].Elements[5] == "" &&
                    requestMessage.Segments[1].Elements[6] == "" &&
                    requestMessage.Segments[2].Elements != null && // ARG|<arg position>|<arg name>|<arg data type>||<arg value>|
                    requestMessage.Segments[2].Elements.Count == 6 &&
                    requestMessage.Segments[2].Elements[0] == ArgumentDirectiveElement &&
                    requestMessage.Segments[2].Elements[2] == "province" &&
                    requestMessage.Segments[2].Elements[3] == "string" &&
                    requestMessage.Segments[3].Elements != null && // ARG|<arg position>|<arg name>|<arg data type>||<arg value>|
                    requestMessage.Segments[3].Elements.Count == 6 &&
                    requestMessage.Segments[3].Elements[0] == ArgumentDirectiveElement &&
                    requestMessage.Segments[3].Elements[2] == "amount" &&
                    requestMessage.Segments[3].Elements[3] == "double")
                {
                    // Now we parse out the team requesting to execute.
                    var teamName = requestMessage.Segments[0].Elements[2];
                    var teamId   = requestMessage.Segments[0].Elements[3];

                    if (ValidateTeam(teamName, teamId))
                    {
                        // Now we parse out the arguments province and amount
                        string provinceArg = requestMessage.Segments[2].Elements[5];
                        double amountArg   = 0;
                        if (double.TryParse(requestMessage.Segments[3].Elements[5], out amountArg))
                        {
                            Models.TaxSummary taxSummary = null;
                            try
                            {
                                taxSummary = _taxCalculator.CalculateTax(provinceArg, amountArg);
                            }
                            catch (ArgumentException ae)
                            {
                                Logger.logException(ae);

                                var errorResponseMessage = new Message();
                                errorResponseMessage.AddSegment(PublishedServiceDirectiveElement, SOANotOkElement, "Arguments not valid.", ae.Message);
                                return(HL7Utility.Serialize(errorResponseMessage));
                            }
                            catch (Exception ex)
                            {
                                Logger.logException(ex);

                                var errorResponseMessage = new Message();
                                errorResponseMessage.AddSegment(PublishedServiceDirectiveElement, SOANotOkElement, "There was a problem with calculating the tax summary.", "");
                                return(HL7Utility.Serialize(errorResponseMessage));
                            }
                            if (taxSummary != null)
                            {
                                // SUCCESS //
                                var responseMessage = new Message();
                                // PUB|OK|||<num segments>|
                                responseMessage.AddSegment(PublishedServiceDirectiveElement, SOAOkElement, "", "", "5");
                                // RSP|<resp position>|<resp name>|<resp data type>|<resp value>|
                                responseMessage.AddSegment(ResponseDirectiveElement, "1", "NetAmount", "double", taxSummary.NetAmount.ToString());
                                // RSP|<resp position>|<resp name>|<resp data type>|<resp value>|
                                responseMessage.AddSegment(ResponseDirectiveElement, "2", "PstAmount", "double", taxSummary.PstAmount.ToString());
                                // RSP|<resp position>|<resp name>|<resp data type>|<resp value>|
                                responseMessage.AddSegment(ResponseDirectiveElement, "3", "HstAmount", "double", taxSummary.HstAmount.ToString());
                                // RSP|<resp position>|<resp name>|<resp data type>|<resp value>|
                                responseMessage.AddSegment(ResponseDirectiveElement, "4", "GstAmount", "double", taxSummary.GstAmount.ToString());
                                // RSP|<resp position>|<resp name>|<resp data type>|<resp value>|
                                responseMessage.AddSegment(ResponseDirectiveElement, "5", "TotalAmount", "double", taxSummary.TotalAmount.ToString());
                                return(HL7Utility.Serialize(responseMessage));
                            }
                            else
                            {
                                var errorResponseMessage = new Message();
                                errorResponseMessage.AddSegment(PublishedServiceDirectiveElement, SOANotOkElement, "There was a problem with calculating the tax summary.", "");
                                return(HL7Utility.Serialize(errorResponseMessage));
                            }
                        }
                        else
                        {
                            var errorResponseMessage = new Message();
                            errorResponseMessage.AddSegment(PublishedServiceDirectiveElement, SOANotOkElement, "Could not parse amount argument.", "Make sure that amount argument is of type double.");
                            return(HL7Utility.Serialize(errorResponseMessage));
                        }
                    }
                    else
                    {
                        var errorResponseMessage = new Message();
                        errorResponseMessage.AddSegment(PublishedServiceDirectiveElement, SOANotOkElement, "Assess denied.", string.Format("Team {0} with ID {1} is not allowed to execute the service.", teamName, teamId));
                        return(HL7Utility.Serialize(errorResponseMessage));
                    }
                }
                else
                {
                    var errorResponseMessage = new Message();
                    errorResponseMessage.AddSegment(PublishedServiceDirectiveElement, SOANotOkElement, "Request not in valid format.", "Make sure that you comply to SOA Registry message format.");
                    return(HL7Utility.Serialize(errorResponseMessage));
                }
            }
            else
            {
                var errorResponseMessage = new Message();
                errorResponseMessage.AddSegment(PublishedServiceDirectiveElement, SOANotOkElement, "There was a problem with calculating the tax summary.", "");
                return(HL7Utility.Serialize(errorResponseMessage));
            }
        }
        /// <summary>
        /// This method calculates all taxes for each region 
        /// </summary>
        /// <param name="region">code of the province in the format of "ON"</param>
        /// <param name="amount">the value to calculate taxes on</param>
        /// <returns>an TaxSummary objec, which contains the NetAmount, PST, HST, GST and total after taxes</returns>
        private Models.TaxSummary CalculateTaxByRegion(string region, double amount)
        {
            string codePattern = @"^(NL|NS|NB|PE|QC|ON|MB|SK|AB|BC|YT|NT|NU)$";
            Regex rg = new Regex(codePattern, RegexOptions.IgnoreCase);
            Match mch = rg.Match(region);
            if(!mch.Success)
            {
                throw new ArgumentException("The region code is not in a valid format, Format should be NL|NS|NB|PE|QC|ON|MB|SK|AB|BC|YT|NT|NU");
            }
            if (amount < 0)
            {
                throw new ArgumentException("The amount cannot be negative.");
            }
            #region method Initializers
            TaxSummary ts = new TaxSummary();
            ts.NetAmount = amount;
            string getRegionName = ChooseRegion(region);
            string taxType = GetSaleTaxByRegion(region);
            string pst = string.Empty;
            string gst = string.Empty;
            const double qcPstTaxRate = 9.5d;

            //get tax type pst and gst to be applied where available
            if (taxType.Contains('-'))
            {
                pst = GetPst(taxType);
                gst = GetGst(taxType);
            }
            #endregion
            #region Hst
            //calculates HST tax for regions that have this tax
            if (taxType.Equals("HST"))
            {
                switch (region.ToUpper())
                {
                    case "NL":
                        ts.HstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.HSTRates.HSTMedium));
                        ts.TotalAmount = CalculateTax(ConvertToPercent((double)Enums.HSTRates.HSTMedium), amount);
                        break;
                    case "NS":
                        ts.HstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.HSTRates.HSTHigh));
                        ts.TotalAmount = CalculateTax(ConvertToPercent((double)Enums.HSTRates.HSTHigh), amount);
                        break;
                    case "NB":
                        ts.HstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.HSTRates.HSTMedium));
                        ts.TotalAmount = CalculateTax(ConvertToPercent((double)Enums.HSTRates.HSTMedium), amount);
                        break;
                    case "ON":
                        ts.HstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.HSTRates.HSTMedium));
                        ts.TotalAmount = CalculateTax(ConvertToPercent((double)Enums.HSTRates.HSTMedium), amount);
                        break;
                    case "BC":
                        ts.HstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.HSTRates.HSTLow));
                        ts.TotalAmount = CalculateTax(ConvertToPercent((double)Enums.HSTRates.HSTLow), amount);
                        break;
                    default:
                        break;
                }
            }
            #endregion
            #region Pst-Gst
            //calculates the PST and GST for the regions that have these types of taxes
            if (taxType.Equals("PST-GST"))
            {
                switch (region.ToUpper())
                {
                    case "PE":
                        ts.GstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.GSTRate.GSTRate));
                        ts.PstAmount = CalculateTaxAmount(CalculateTax(ConvertToPercent((double)Enums.GSTRate.GSTRate), amount), ConvertToPercent((double)Enums.PSTRates.PSTHigh));
                        ts.TotalAmount = CalculateTax(ConvertToPercent((double)Enums.PSTRates.PSTHigh), CalculateTax(ConvertToPercent((double)Enums.GSTRate.GSTRate), amount));
                        break;
                    case "QC":
                        ts.GstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.GSTRate.GSTRate));
                        ts.PstAmount = CalculateTaxAmount(CalculateTax(ConvertToPercent((double)Enums.GSTRate.GSTRate), amount), ConvertToPercent(qcPstTaxRate));
                        ts.TotalAmount = CalculateTax(ConvertToPercent(qcPstTaxRate), CalculateTax(ConvertToPercent((double)Enums.GSTRate.GSTRate), amount));
                        break;
                    case "MB":
                        ts.GstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.GSTRate.GSTRate));
                        ts.PstAmount = Math.Round(CalculateTaxAmount(amount, ConvertToPercent((double)Enums.PSTRates.PSTMedium)), 2);
                        ts.TotalAmount = CalculateTax((ConvertToPercent((double)Enums.GSTRate.GSTRate) + ConvertToPercent((double)Enums.PSTRates.PSTMedium)), amount);
                        break;
                    case "SK":
                        ts.GstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.GSTRate.GSTRate));
                        ts.PstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.PSTRates.PSTLow));
                        ts.TotalAmount = CalculateTax((ConvertToPercent((double)Enums.GSTRate.GSTRate) + ConvertToPercent((double)Enums.PSTRates.PSTLow)), amount);
                        break;
                    case "AB":
                        ts.GstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.GSTRate.GSTRate));
                        ts.PstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.PSTRates.PSTZero));
                        ts.TotalAmount = CalculateTax((ConvertToPercent((double)Enums.GSTRate.GSTRate) + ConvertToPercent((double)Enums.PSTRates.PSTZero)), amount);
                        break;
                    case "YT":
                        ts.GstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.GSTRate.GSTRate));
                        ts.PstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.PSTRates.PSTZero));
                        ts.TotalAmount = CalculateTax((ConvertToPercent((double)Enums.GSTRate.GSTRate) + ConvertToPercent((double)Enums.PSTRates.PSTZero)), amount);
                        break;
                    case "NT":
                        ts.GstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.GSTRate.GSTRate));
                        ts.PstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.PSTRates.PSTZero));
                        ts.TotalAmount = CalculateTax((ConvertToPercent((double)Enums.GSTRate.GSTRate) + ConvertToPercent((double)Enums.PSTRates.PSTZero)), amount);
                        break;
                    case "NU":
                        ts.GstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.GSTRate.GSTRate));
                        ts.PstAmount = CalculateTaxAmount(amount, ConvertToPercent((double)Enums.PSTRates.PSTZero));
                        ts.TotalAmount = CalculateTax((ConvertToPercent((double)Enums.GSTRate.GSTRate) + ConvertToPercent((double)Enums.PSTRates.PSTZero)), amount);
                        break;
                    default:
                        break;
                }
            }
            return ts;
            #endregion
        }
        private static TaxSummary MessageToTaxSummary(Message msg)
        {
            TaxSummary ts = new TaxSummary();
            double temp = 0.0;

            //For sanity...
            //If its ok to parse...
            if (msg != null)
            {
                if (msg.Segments[0].Elements[1] == SOAOkElement)
                {
                    if (msg.Segments[1].Elements[2].Equals("NetAmount") &&
                        msg.Segments[2].Elements[2].Equals("PstAmount") &&
                        msg.Segments[3].Elements[2].Equals("HstAmount") &&
                        msg.Segments[4].Elements[2].Equals("GstAmount") &&
                        msg.Segments[5].Elements[2].Equals("TotalAmount"))
                    {
                        double.TryParse(msg.Segments[1].Elements[4], out temp);
                        ts.NetAmount = temp;

                        double.TryParse(msg.Segments[2].Elements[4], out temp);
                        ts.PstAmount = temp;

                        double.TryParse(msg.Segments[3].Elements[4], out temp);
                        ts.HstAmount = temp;

                        double.TryParse(msg.Segments[4].Elements[4], out temp);
                        ts.GstAmount = temp;

                        double.TryParse(msg.Segments[5].Elements[4], out temp);
                        ts.TotalAmount = temp;
                    }
                }
            }

            return ts;
        }
        protected void submitButton_Click(object sender, EventArgs e)
        {
            string province;
            double amount = 0;
            string request = "";
            string response = "";
            TaxSummary taxes = new GIORP_TOTAL.Models.TaxSummary();
            Message msg = new Message();

            province = provinceList.SelectedValue;
            double.TryParse(priceBox.Text, out amount);

            try
            {
                Regex priceRegex = new Regex(amountPattern);

                if (!priceRegex.IsMatch(amount.ToString()))
                {
                    throw new Exception("The amount value was invalid");
                }

                //  DRC|EXEC-SERVICE|PhantomPower|0|
                msg.AddSegment(CommandDirectiveElement, ExecuteServiceElement, teamName, teamID);
                //  SRV||PP-GIORP-TOTAL||2|||
                msg.AddSegment(ServiceDirectiveElement, "", serviceName, "", numArgs, "", "");
                //  ARG|1|province|string||PROVINCE CODE|
                if (argDataType1.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
                {
                    msg.AddSegment(ArgumentDirectiveElement, "1", argName1, argDataType1, "", province);
                }
                else
                {
                    msg.AddSegment(ArgumentDirectiveElement, "1", argName1, argDataType1, "", amount.ToString());
                }
                //  ARG|2|amount|double||AMOUNT|
                if (argDataType2.IndexOf("double", 0, StringComparison.CurrentCultureIgnoreCase) != -1 ||
                    argDataType2.IndexOf("float", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
                {
                    msg.AddSegment(ArgumentDirectiveElement, "2", argName2, argDataType2, "", amount.ToString());
                }
                else
                {
                    msg.AddSegment(ArgumentDirectiveElement, "2", argName2, argDataType2, "", province);
                }

                //Serialize the message
                request = HL7Utility.Serialize(msg);
                //Send the request
                response = ServiceClient.SendRequest(request, IP, port);
                //Deserialize the response
                msg = HL7Utility.Deserialize(response);

                if (msg.Segments[0].Elements[1] == SOAOkElement)
                {
                    taxes = null; //MessageToTaxSummary(msg);
                    response1.Text = msg.Segments[1].Elements[2] + ": " + msg.Segments[1].Elements[4];
                    response2.Text = msg.Segments[2].Elements[2] + ": " + msg.Segments[2].Elements[4];
                    response3.Text = msg.Segments[3].Elements[2] + ": " + msg.Segments[3].Elements[4];
                    response4.Text = msg.Segments[4].Elements[2] + ": " + msg.Segments[4].Elements[4];
                    response5.Text = msg.Segments[5].Elements[2] + ": " + msg.Segments[5].Elements[4];

                    // show the results div with the results
                    results.Visible = true;
                    alertDiv.Visible = false;
                }
                else if(msg.Segments[0].Elements[1] == SOANotOkElement)
                {
                    taxes = null;
                    alert.Text = msg.Segments[0].Elements[3];
                    alertDiv.Visible = true;
                    results.Visible = false;
                }
            }
            catch (Exception ex)
            {
                alert.Text = ex.Message;
                Logger.logException(ex);
            }

            //if (taxes != null)
            //{
            //    // fill in the labels with the responses
            //    try
            //    {
            //        // go through each segment and get the second element (name of field) and forth element (value)
            //        response1.Text = msg.Segments[1].Elements[2] + ": " + msg.Segments[1].Elements[4];
            //        response2.Text = msg.Segments[2].Elements[2] + ": " + msg.Segments[2].Elements[4];
            //        response3.Text = msg.Segments[3].Elements[2] + ": " + msg.Segments[3].Elements[4];
            //        response4.Text = msg.Segments[4].Elements[2] + ": " + msg.Segments[4].Elements[4];
            //        response5.Text = msg.Segments[5].Elements[2] + ": " + msg.Segments[5].Elements[4];
            //    }
            //    catch (Exception ex)
            //    {
            //        alert.Text = ex.Message;
            //        Logger.logException(ex);
            //    }

            //    // format the table
            //    //subtotalAmount.Text = taxes.NetAmount.ToString("C2");
            //    //pstAmount.Text = taxes.PstAmount.ToString("C2");
            //    //hstAmount.Text = taxes.HstAmount.ToString("C2");
            //    //gstAmount.Text = taxes.GstAmount.ToString("C2");
            //    //totalPurchaseAmount.Text = taxes.TotalAmount.ToString("C2");

            //    // show the results div with the results
            //    results.Visible = true;
            //    alertDiv.Visible = false;
            //}
            //else
            //{
            //    alertDiv.Visible = true;
            //    results.Visible = false;
            //}
        }
        protected void submitButton_Click(object sender, EventArgs e)
        {
            string     province;
            double     amount   = 0;
            string     request  = "";
            string     response = "";
            TaxSummary taxes    = new GIORP_TOTAL.Models.TaxSummary();
            Message    msg      = new Message();

            province = provinceList.SelectedValue;
            double.TryParse(priceBox.Text, out amount);

            try
            {
                Regex priceRegex = new Regex(amountPattern);

                if (!priceRegex.IsMatch(amount.ToString()))
                {
                    throw new Exception("The amount value was invalid");
                }

                //  DRC|EXEC-SERVICE|PhantomPower|0|
                msg.AddSegment(CommandDirectiveElement, ExecuteServiceElement, teamName, teamID);
                //  SRV||PP-GIORP-TOTAL||2|||
                msg.AddSegment(ServiceDirectiveElement, "", serviceName, "", numArgs, "", "");
                //  ARG|1|province|string||PROVINCE CODE|
                if (argDataType1.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
                {
                    msg.AddSegment(ArgumentDirectiveElement, "1", argName1, argDataType1, "", province);
                }
                else
                {
                    msg.AddSegment(ArgumentDirectiveElement, "1", argName1, argDataType1, "", amount.ToString());
                }
                //  ARG|2|amount|double||AMOUNT|
                if (argDataType2.IndexOf("double", 0, StringComparison.CurrentCultureIgnoreCase) != -1 ||
                    argDataType2.IndexOf("float", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
                {
                    msg.AddSegment(ArgumentDirectiveElement, "2", argName2, argDataType2, "", amount.ToString());
                }
                else
                {
                    msg.AddSegment(ArgumentDirectiveElement, "2", argName2, argDataType2, "", province);
                }

                //Serialize the message
                request = HL7Utility.Serialize(msg);
                //Send the request
                response = ServiceClient.SendRequest(request, IP, port);
                //Deserialize the response
                msg = HL7Utility.Deserialize(response);

                if (msg.Segments[0].Elements[1] == SOAOkElement)
                {
                    taxes          = null; //MessageToTaxSummary(msg);
                    response1.Text = msg.Segments[1].Elements[2] + ": " + msg.Segments[1].Elements[4];
                    response2.Text = msg.Segments[2].Elements[2] + ": " + msg.Segments[2].Elements[4];
                    response3.Text = msg.Segments[3].Elements[2] + ": " + msg.Segments[3].Elements[4];
                    response4.Text = msg.Segments[4].Elements[2] + ": " + msg.Segments[4].Elements[4];
                    response5.Text = msg.Segments[5].Elements[2] + ": " + msg.Segments[5].Elements[4];

                    // show the results div with the results
                    results.Visible  = true;
                    alertDiv.Visible = false;
                }
                else if (msg.Segments[0].Elements[1] == SOANotOkElement)
                {
                    taxes            = null;
                    alert.Text       = msg.Segments[0].Elements[3];
                    alertDiv.Visible = true;
                    results.Visible  = false;
                }
            }
            catch (Exception ex)
            {
                alert.Text = ex.Message;
                Logger.logException(ex);
            }

            //if (taxes != null)
            //{
            //    // fill in the labels with the responses
            //    try
            //    {
            //        // go through each segment and get the second element (name of field) and forth element (value)
            //        response1.Text = msg.Segments[1].Elements[2] + ": " + msg.Segments[1].Elements[4];
            //        response2.Text = msg.Segments[2].Elements[2] + ": " + msg.Segments[2].Elements[4];
            //        response3.Text = msg.Segments[3].Elements[2] + ": " + msg.Segments[3].Elements[4];
            //        response4.Text = msg.Segments[4].Elements[2] + ": " + msg.Segments[4].Elements[4];
            //        response5.Text = msg.Segments[5].Elements[2] + ": " + msg.Segments[5].Elements[4];
            //    }
            //    catch (Exception ex)
            //    {
            //        alert.Text = ex.Message;
            //        Logger.logException(ex);
            //    }

            //    // format the table
            //    //subtotalAmount.Text = taxes.NetAmount.ToString("C2");
            //    //pstAmount.Text = taxes.PstAmount.ToString("C2");
            //    //hstAmount.Text = taxes.HstAmount.ToString("C2");
            //    //gstAmount.Text = taxes.GstAmount.ToString("C2");
            //    //totalPurchaseAmount.Text = taxes.TotalAmount.ToString("C2");

            //    // show the results div with the results
            //    results.Visible = true;
            //    alertDiv.Visible = false;
            //}
            //else
            //{
            //    alertDiv.Visible = true;
            //    results.Visible = false;
            //}
        }