How to throw error from commerce runtime to POS client
How to throw error from commerce runtime to POS client


Song Nghia - Technical Consultant

Hello, 

In this tutorial, I'll show you how to throw error, warning from CRT to POS Client

Step 1. In commerce runtime, use throw exception type: DataVaidationException like:

throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_UnableToOpenShift, "Could not open shift. It could be this terminal did Z-Reading Report in this day");

 "Could not open shift. It could be this terminal did Z-Reading Report in this day" => it will show in event viewer


Step 2. You can get languages text id inside parameter from setup 1. Just f12 type of data validation exception to know id of languages text.

- After, go to languages text in d365, input what string you want to show in client. But you need to know standard alert will change, anyway, you have another choose to show alert to POS client.

Security and permission need to compile AX by cmd

Security and permission need to compile AX by cmd


Song Nghia - Technical Consultant

Sometimes, in new Live enviroment I forgot to check list all security required to upload and full check list in AX 2012.

Let write it to remember. :D

+ AX : system admin
+ SQL : sysadmin
+ SQL server : local admin
+ AX server: local admin
Save all data print in POS - Retail D365

Save all data print in POS - Retail D365

Song Nghia - Technical consultant

This class help you save all data print in POS Retail D365.
namespace LAW
{
    namespace Commerce.Runtime.GetReceiptServiceRequest
    {
        using System;
        using System.Collections.Generic;
        using Microsoft.Dynamics.Commerce.Runtime;
        using Microsoft.Dynamics.Commerce.Runtime.DataModel;
        using Microsoft.Dynamics.Commerce.Runtime.DataServices.Messages;
        using Microsoft.Dynamics.Commerce.Runtime.Messages;
        using Microsoft.Dynamics.Commerce.Runtime.Services.Messages;
        using Microsoft.Dynamics.Commerce.Runtime.Workflow;
        using Microsoft.Dynamics.Commerce.Runtime.RealtimeServices.Messages;
        using System.Text;
        using System.Globalization;
        using System.Linq;
        using System.Collections.ObjectModel;
        using System.Text.RegularExpressions;
        using System.Transactions;
        using Microsoft.Dynamics.Commerce.Runtime.Data;

        public class EJFileLawsonService
        {
            GetReceiptServiceRequest originalReceiptsRequest;
            GetReceiptServiceResponse originalReceiptsResponse;

            public EJFileLawsonService(GetReceiptServiceRequest request, GetReceiptServiceResponse response)
            {
                originalReceiptsRequest = request;
                originalReceiptsResponse = response;
            }

            public void Process()
            {
                string finalReceipt = "";
                string finaleReceiptHTML = "", headerHTML = "", bodyHTML = "", footerHTML = "";
                int lineNum = 0;
                OrgUnit orgUnit = this.GetStoreFromContext(originalReceiptsRequest.RequestContext);
                foreach (Receipt receipt in originalReceiptsResponse.Receipts)
                {
                    lineNum++;
                    if (originalReceiptsRequest.IsCopy == false && originalReceiptsRequest.IsPreview == false)
                    {
                        finalReceipt = receipt.Header + receipt.Body + receipt.Footer;
                        finaleReceiptHTML = this.ConvertToHTML(finalReceipt);
                        headerHTML = this.ConvertToHTML(receipt.Header);
                        bodyHTML = this.ConvertToHTML(receipt.Body);
                        footerHTML = this.ConvertToHTML(receipt.Footer);
                        this.InsertDataIntoExTTable(finaleReceiptHTML, headerHTML, bodyHTML, footerHTML, originalReceiptsRequest, receipt, lineNum);
                    }
                }
            }
            private OrgUnit GetStoreFromContext(RequestContext context)
            {
                SearchOrgUnitDataRequest orgUnitDataRequest = new SearchOrgUnitDataRequest(context.GetPrincipal().ChannelId);
                return context.Execute<EntityDataServiceResponse<OrgUnit>>((Request)orgUnitDataRequest).PagedEntityCollection.SingleOrDefault<OrgUnit>();
            }

            private string ConvertToHTML(string receipt)
            {
                if (string.IsNullOrEmpty(receipt))
                    return receipt;
                string[] strArray = Regex.Split(receipt, "(&#x1B;\\|1C|&#x1B;\\|2C|&#x1B;\\|3C|&#x1B;\\|4C|\\r\\n)", RegexOptions.Multiline);
                StringBuilder stringBuilder = new StringBuilder();
                bool flag = false;
                foreach (string str in strArray)
                {
                    if (!string.IsNullOrEmpty(str))
                    {
                        if (!(str == "&#x1B;|1C") && !(str == "&#x1B;|3C"))
                        {
                            if (!(str == "&#x1B;|2C") && !(str == "&#x1B;|4C"))
                            {
                                if (str == "\r\n")
                                {
                                    stringBuilder.Append("\n");
                                }
                                else
                                {
                                    stringBuilder.Append(str);
                                    if (flag)
                                        stringBuilder.Append(new string(' ', str.Length));
                                }
                            }
                            else
                                flag = true;
                        }
                        else
                            flag = false;
                    }
                }
                receipt = this.RemoveLogo(stringBuilder.ToString());
                return receipt;
            }

            private string RemoveLogo(string receipt)
            {
                foreach (Match match in new Regex("<L(.?|:.+)>").Matches(receipt))
                    receipt = receipt.Replace(match.Value, string.Empty);
                return receipt;
            }

            private void InsertDataIntoExTTable(string _finalReceiptString, string _header, string _body, string _footer, GetReceiptServiceRequest _originalReceiptsRequest, Receipt _receipt, int _lineNum)
            {
                using (TransactionScope transactionScope = new TransactionScope())
                {
                    ParameterSet parameters = new ParameterSet();

                    if (_receipt.ReceiptType == ReceiptType.SalesReceipt || _receipt.ReceiptType == ReceiptType.SalesOrderReceipt || _receipt.ReceiptType == ReceiptType.SuspendedTransaction || _receipt.ReceiptType == ReceiptType.CustomReceipt6 || _receipt.ReceiptType == ReceiptType.CustomReceipt7)
                    {
                        parameters["@TERMINALID"] = _originalReceiptsRequest.SalesOrder.TerminalId;
                        parameters["@SHIFTID"] = _originalReceiptsRequest.SalesOrder.ShiftId;
                        parameters["@RECEIPTTYPES"] = _receipt.ReceiptTypeStrValue;
                        parameters["@CHANNEL"] = _originalReceiptsRequest.SalesOrder.ChannelId;
                        parameters["@TRANSACTIONDATETIME"] = _originalReceiptsRequest.SalesOrder.CreatedDateTime;
                        parameters["@TRANSACTIONDATE"] = _originalReceiptsRequest.SalesOrder.CreatedDateTime;
                        parameters["@TRANSACTIONTYPE"] = _originalReceiptsRequest.SalesOrder.TransactionTypeValue;
                        parameters["@TRANSACTIONID"] = _receipt.TransactionId;
                        parameters["@LINENUM"] = _lineNum;
                    }
                    else if (_receipt.ReceiptType == ReceiptType.SafeDrop || _receipt.ReceiptType == ReceiptType.FloatEntry || _receipt.ReceiptType == ReceiptType.StartingAmount
                        || _receipt.ReceiptType == ReceiptType.RemoveTender)
                    {
                        parameters["@TERMINALID"] = _originalReceiptsRequest.RequestContext.GetPrincipal().ShiftTerminalId;
                        parameters["@SHIFTID"] = _originalReceiptsRequest.RequestContext.GetPrincipal().ShiftId;
                        parameters["@RECEIPTTYPES"] = _receipt.ReceiptTypeStrValue;
                        parameters["@CHANNEL"] = _originalReceiptsRequest.RequestContext.GetPrincipal().ChannelId;
                        parameters["@TRANSACTIONDATETIME"] = DateTime.Now.ToUniversalTime();
                        parameters["@TRANSACTIONDATE"] = DateTime.Now.ToUniversalTime();
                        parameters["@TRANSACTIONTYPE"] = _originalReceiptsRequest.NonSalesTenderTransaction.TransactionTypeValue;
                        parameters["@TRANSACTIONID"] = _receipt.TransactionId;
                        parameters["@LINENUM"] = _lineNum;
                    }
                    else if (_receipt.ReceiptType == ReceiptType.TenderDeclaration)
                    {
                        parameters["@TERMINALID"] = _originalReceiptsRequest.DropAndDeclareTransaction.TerminalId;
                        parameters["@RECEIPTTYPES"] = _receipt.ReceiptTypeStrValue;
                        parameters["@SHIFTID"] = _originalReceiptsRequest.DropAndDeclareTransaction.ShiftId;
                        parameters["@CHANNEL"] = _originalReceiptsRequest.RequestContext.GetPrincipal().ChannelId;
                        parameters["@TRANSACTIONDATETIME"] = DateTime.Now.ToUniversalTime();
                        parameters["@TRANSACTIONDATE"] = DateTime.Now.ToUniversalTime();
                        parameters["@TRANSACTIONTYPE"] = _originalReceiptsRequest.DropAndDeclareTransaction.TransactionTypeValue;
                        parameters["@TRANSACTIONID"] = _receipt.TransactionId;
                        parameters["@LINENUM"] = _lineNum;
                    }
                    else if (_receipt.ReceiptType == ReceiptType.ZReport)
                    {
                        parameters["@TERMINALID"] = _originalReceiptsRequest.ShiftDetails.TerminalId;
                        parameters["@SHIFTID"] = _originalReceiptsRequest.ShiftDetails.ShiftId;
                        parameters["@RECEIPTTYPES"] = "X-Reading Report";
                        parameters["@CHANNEL"] = _originalReceiptsRequest.RequestContext.GetPrincipal().ChannelId;
                        parameters["@TRANSACTIONDATETIME"] = DateTime.Now.ToUniversalTime();
                        parameters["@TRANSACTIONDATE"] = DateTime.Now.ToUniversalTime();
                        parameters["@TRANSACTIONTYPE"] = 24;
                        parameters["@LINENUM"] = _lineNum;

                        /* Get XDOC Number*/
                        var queryRetailXReadingTransactionDetail = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                        {
                            DatabaseSchema = "ext",
                            Select = new ColumnSet("DOCNUM"),
                            From = "LAW_RETAILXREADINGTRANSACTIONDETAIL",
                            Where = "STORE = @STORE AND TERMINALID = @TERMINALID AND DATAAREAID = @DATAAREAID AND SHIFT = @SHIFT"
                        };

                        string storeNum = this.GetStoreNumber(_originalReceiptsRequest);

                        queryRetailXReadingTransactionDetail.Parameters["@TERMINALID"] = _originalReceiptsRequest.ShiftDetails.TerminalId;
                        queryRetailXReadingTransactionDetail.Parameters["@STORE"] = storeNum;
                        queryRetailXReadingTransactionDetail.Parameters["@DATAAREAID"] = _originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                        queryRetailXReadingTransactionDetail.Parameters["@SHIFT"] = _originalReceiptsRequest.ShiftDetails.ShiftId;

                        using (DatabaseContext databaseContextXReadingDetail = new DatabaseContext(_originalReceiptsRequest.RequestContext))
                        {
                            var xReadingEntityDetail = databaseContextXReadingDetail.ReadEntity<ExtensionsEntity>(queryRetailXReadingTransactionDetail).FirstOrDefault();
                            if (xReadingEntityDetail != null)
                            {
                                string XDOC = xReadingEntityDetail.GetProperty("DOCNUM").ToString();
                                parameters["@TRANSACTIONID"] = XDOC;

                            }
                        }
                    }
                    else if (_receipt.ReceiptType == ReceiptType.XReport)
                    {
                        parameters["@TERMINALID"] = _originalReceiptsRequest.ShiftDetails.TerminalId;
                        parameters["@SHIFTID"] = _originalReceiptsRequest.ShiftDetails.ShiftId;
                        parameters["@RECEIPTTYPES"] = "Tender Report";
                        parameters["@CHANNEL"] = _originalReceiptsRequest.RequestContext.GetPrincipal().ChannelId;
                        parameters["@TRANSACTIONDATETIME"] = DateTime.Now.ToUniversalTime();
                        parameters["@TRANSACTIONDATE"] = DateTime.Now.ToUniversalTime();
                        parameters["@TRANSACTIONTYPE"] = 24;
                        parameters["@TRANSACTIONID"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        parameters["@LINENUM"] = _lineNum;
                    }

                    parameters["@DATAAREAID"] = _originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                    parameters["@EVENTCREATEDDATETIME"] = DateTime.Now.ToUniversalTime();
                    parameters["@REPLICATED"] = 0;
                    parameters["@RECEIPTID"] = _receipt.ReceiptId;
                    if(_receipt.ReceiptType == ReceiptType.CustomReceipt7)
                        parameters["@RECEIPTHEADER"] = "DIEP VIEN 007" +  _header;
                    else
                        parameters["@RECEIPTHEADER"] = _header;
                    parameters["@RECEIPTBODY"] = _body;
                    parameters["@RECEIPTFOOTER"] = _footer;
                    parameters["@RECEIPTSTRING"] = _finalReceiptString;

                    if (_receipt.ReceiptType == ReceiptType.CustomReceipt6)
                    {
                        parameters["@LINENUM"] = _lineNum + 1;
                    }

                    int errorCode;
                    using (var databaseContext = new DatabaseContext(_originalReceiptsRequest))
                    {
                        errorCode = databaseContext.ExecuteStoredProcedureNonQuery("[ext].[LAW_RETAILDOCUMENTSPRINTINGHISTORY_Insert]", parameters);
                    }

                    if (errorCode != 0)
                        throw new StorageException(StorageErrors.Microsoft_Dynamics_Commerce_Runtime_CriticalStorageError, errorCode, "Unable to save data");
                    transactionScope.Complete();

                }
            }

            public string GetStoreNumber(Request request)
            {
                long StoreRecId = request.RequestContext.GetPrincipal().ChannelId;
                string StoreNumber = string.Empty;

                var queryRetailStore = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ax",
                    Select = new ColumnSet(new string[] { "STORENUMBER" }),
                    From = "RETAILSTORETABLE",
                    Where = "RECID = @RECID"
                };

                queryRetailStore.Parameters["@RECID"] = StoreRecId;

                using (DatabaseContext databaseContext = new DatabaseContext(request.RequestContext))
                {
                    var extensions = databaseContext.ReadEntity<ExtensionsEntity>(queryRetailStore).FirstOrDefault();
                    StoreNumber = extensions.GetProperty("STORENUMBER").ToString();
                }

                return StoreNumber;
            }
        }
    }
}

Noted code print X Z Report LAWSON

Noted code print X Z Report LAWSON


Song Nghia - Technical Consultant

namespace LAW
{
    namespace Commerce.Runtime.GetReceiptServiceRequest
    {
        using System;
        using System.Collections.Generic;
        using Microsoft.Dynamics.Commerce.Runtime;
        using Microsoft.Dynamics.Commerce.Runtime.DataModel;
        using Microsoft.Dynamics.Commerce.Runtime.DataServices.Messages;
        using Microsoft.Dynamics.Commerce.Runtime.Messages;
        using Microsoft.Dynamics.Commerce.Runtime.Services.Messages;
        using Microsoft.Dynamics.Commerce.Runtime.Workflow;
        using Microsoft.Dynamics.Commerce.Runtime.RealtimeServices.Messages;
        using System.Text;
        using System.Globalization;
        using System.Linq;
        using System.Collections.ObjectModel;
        using System.Transactions;
        using Microsoft.Dynamics.Commerce.Runtime.Data;

        public class XZReportsLawsonService
        {
            private readonly string SingleLine = string.Empty.PadLeft(55, '-');
            private readonly string DoubleLine = string.Empty.PadLeft(55, '=');
            private Dictionary<string, LocalizedText> localizedTexts = (Dictionary<string, LocalizedText>)null;
            private string localizedTextKeyFormat = "{0}_{1}";


            //Define global variable
            public GetReceiptServiceRequest originalReceiptsRequest;
            public GetReceiptServiceResponse originalReceiptsResponse;
            public Shift shift = new Shift();
            public Terminal terminal = new Terminal();
            public RetailXReadingEntity XReadingData = new RetailXReadingEntity();
            public string header = "";
            public string body = "";
            public string XReadingNumber;
            List<DistcountEntity> listDiscountType = new List<DistcountEntity>();
            List<DistcountEntity> listVATAdjustDiscountGroup = new List<DistcountEntity>();
            decimal globalLastShiftBalance;
            public string hardwareProfileId;
            //End define 
            public XZReportsLawsonService(GetReceiptServiceRequest request, GetReceiptServiceResponse response)
            {
                originalReceiptsRequest = request;
                originalReceiptsResponse = response;
            }

            private SalesOrder GetSalesOrderForTransactionWithId(RequestContext requestContext, string transactionId)
            {
                SalesOrder salesOrder = new SalesOrder();

                var getCartRequest = new GetSalesOrderDetailsByTransactionIdServiceRequest(transactionId, SearchLocation.Local);
                var getCartResponse = requestContext.Execute<GetSalesOrderDetailsServiceResponse>(getCartRequest);
                salesOrder = getCartResponse.SalesOrder;

                return salesOrder;
            }

            public string generateDocNum()
            {
                string DOCNUM = "";
                int numSeq = 0;
                var queryRetailXReport = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet(new string[] { "DOCNUM" }),
                    From = "LAW_RETAILXREADINGTRANSACTIONDETAIL",
                    Where = "STORE = @STORE AND TERMINALID = @TERMINALID AND DATAAREAID = @DATAAREAID",
                    OrderBy = "SHIFT DESC"
                };

                queryRetailXReport.Parameters["@TERMINALID"] = terminal.TerminalId;
                queryRetailXReport.Parameters["@STORE"] = shift.StoreId;
                queryRetailXReport.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    var extensions = databaseContext.ReadEntity<ExtensionsEntity>(queryRetailXReport).FirstOrDefault();
                    if (extensions == null)
                    {
                        globalLastShiftBalance = 0;
                        return DOCNUM = "X-" + shift.TerminalId + "-000001";
                    }
                    else
                    {
                        DOCNUM = extensions.GetProperty("DOCNUM").ToString();

                        var queryOldReport = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                        {
                            DatabaseSchema = "ext",
                            Select = new ColumnSet(new string[] { "DOCNUM", "ENDINGBALANCE" }),
                            From = "LAW_RETAILXREADINGREPORT",
                            Where = "STORE = @STORE AND TERMINALID = @TERMINALID",
                            OrderBy = "SHIFT DESC"
                        };

                        queryOldReport.Parameters["@TERMINALID"] = terminal.TerminalId;
                        queryOldReport.Parameters["@STORE"] = shift.StoreId;

                        using (DatabaseContext databaseOldContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                        {
                            var extensionsOld = databaseOldContext.ReadEntity<ExtensionsEntity>(queryOldReport).FirstOrDefault();

                            if (extensionsOld != null)
                            {
                                globalLastShiftBalance = decimal.Parse(extensionsOld.GetProperty("ENDINGBALANCE").ToString());
                            }
                        }
                    }
                }

                numSeq = int.Parse(DOCNUM.Substring(DOCNUM.Length - 6, 6));
                //numSeq += 1;
                if (numSeq >= 1 && numSeq < 9)
                    DOCNUM = "X-" + shift.TerminalId + "-00000" + numSeq++;
                if (numSeq >= 9 && numSeq < 99)
                    DOCNUM = "X-" + shift.TerminalId + "-0000" + numSeq++;
                if (numSeq >= 99 && numSeq < 999)
                    DOCNUM = "X-" + shift.TerminalId + "-000" + numSeq++;
                if (numSeq >= 999 && numSeq < 9999)
                    DOCNUM = "X-" + shift.TerminalId + "-00" + numSeq++;
                if (numSeq >= 9999 && numSeq < 99999)
                    DOCNUM = "X-" + shift.TerminalId + "-0" + numSeq++;
                if (numSeq >= 99999 && numSeq < 999999)
                    DOCNUM = "X-" + shift.TerminalId + "-" + numSeq++;

                return DOCNUM;
            }


            public void Process()
            {
                RequestContext context = originalReceiptsRequest.RequestContext;
                //Loop all receipt need to print, and only customize X/Z receipt
                shift = originalReceiptsRequest.ShiftDetails;
                //Get Current Hardware profile
                hardwareProfileId = originalReceiptsRequest.HardwareProfileId;
                terminal = context.GetTerminal();
                XReadingNumber = this.generateDocNum();

                for (int i = 0; i < originalReceiptsResponse.Receipts.Count; i++)
                {
                    //Nghia.Song Get all transaction in shift and mark it in table LAW_RETAILXREADINGTRANSACTIONDETAIL
                    if (originalReceiptsResponse.Receipts[i].ReceiptType == ReceiptType.XReport || originalReceiptsResponse.Receipts[i].ReceiptType == ReceiptType.ZReport)
                    {
                        var queryRetailTransactionTable = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                        {
                            DatabaseSchema = "ax",
                            Select = new ColumnSet(new string[] { "TRANSACTIONID, RECEIPTID" }),
                            From = "RETAILTRANSACTIONTABLE",
                            Where = "BATCHID = @BATCHID AND CHANNEL = @CHANNEL AND STORE = @STORE AND TERMINAL = @TERMINAL AND DATAAREAID = @DATAAREAID"
                        };

                        queryRetailTransactionTable.Parameters["@BATCHID"] = shift.ShiftId;
                        queryRetailTransactionTable.Parameters["@TERMINAL"] = terminal.TerminalId;
                        queryRetailTransactionTable.Parameters["@CHANNEL"] = terminal.ChannelId;
                        queryRetailTransactionTable.Parameters["@STORE"] = shift.StoreId;
                        queryRetailTransactionTable.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                        using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                        {
                            var extensions = databaseContext.ReadEntity<ExtensionsEntity>(queryRetailTransactionTable);
                            //LOOP all retail transaction in shift
                            foreach (ExtensionsEntity extension in extensions)
                            {
                                //Get data
                                string transactionId = extension.GetProperty("TRANSACTIONID").ToString();
                                string receiptId = extension.GetProperty("RECEIPTID").ToString();
                                using (TransactionScope transactionScope = new TransactionScope())
                                {
                                    ParameterSet parameters = new ParameterSet();
                                    parameters["@STORE"] = shift.StoreId;
                                    parameters["@TERMINALID"] = terminal.TerminalId;
                                    parameters["@TRANSACTIONID"] = transactionId;
                                    parameters["@TRANSDATE"] = DateTime.Parse(this.FormatDate(shift.StartDateTime, context));
                                    parameters["@SHIFT"] = shift.ShiftId;
                                    parameters["@DOCNUM"] = XReadingNumber;
                                    parameters["@RECCEIPTID"] = receiptId;
                                    parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;


                                    int errorCode;
                                    using (var databaseContextX = new DatabaseContext(originalReceiptsRequest.RequestContext))
                                    {
                                        errorCode = databaseContextX.ExecuteStoredProcedureNonQuery("[ext].[LAW_RETAILXREADINGTRANSACTIONDETAIL_Insert]", parameters);
                                    }
                                    if (errorCode != 0)
                                        throw new StorageException(StorageErrors.Microsoft_Dynamics_Commerce_Runtime_CriticalStorageError, errorCode, "Unable to save data");
                                    transactionScope.Complete();
                                }
                            }
                            //End Loop all retail transaction in shift
                        }

                        Receipt receiptShift = this.CustomizeXZReport(originalReceiptsResponse.Receipts[i], context, shift);

                        originalReceiptsResponse.Receipts[i].Body = receiptShift.Body;
                        originalReceiptsResponse.Receipts[i].Header = receiptShift.Header;

                        #region Insert XZReport
                        if (originalReceiptsResponse.Receipts[i].ReceiptType == ReceiptType.ZReport)
                        {
                            //Nghia.song save data Xreport
                            using (TransactionScope transactionScope = new TransactionScope())
                            {
                                ParameterSet parameters = new ParameterSet();
                                parameters["@STORE"] = shift.StoreId;
                                parameters["@TERMINALID"] = terminal.TerminalId;
                                parameters["@TRANSDATE"] = DateTime.Now; //DateTime.Parse(this.FormatDate(shift.StartDateTime, context));
                                parameters["@SHIFT"] = shift.ShiftId;
                                parameters["@DOCNUM"] = XReadingData.DOCNUM;
                                parameters["@HEADER"] = XReadingData.HEADER;
                                parameters["@BODY"] = XReadingData.BODY;
                                parameters["@FOOTER"] = "";
                                parameters["@COMPANYNAME"] = XReadingData.COMPANYNAME;
                                parameters["@BUSINESSSTYLE"] = XReadingData.BUSINESSSTYLE;
                                parameters["@COMPANYADDRESS"] = XReadingData.COMPANYADDRESS;
                                parameters["@TIN"] = XReadingData.TIN;
                                parameters["@STAFFNAME"] = XReadingData.STAFFNAME;
                                parameters["@REPORTNAME"] = XReadingData.REPORTNAME;
                                parameters["@GROSSSALES"] = XReadingData.GROSSSALES;
                                parameters["@NETSALES"] = XReadingData.NETSALES;
                                parameters["@BEGININGBALANCE"] = XReadingData.BEGININGBALANCE;
                                parameters["@ENDINGBALANCE"] = XReadingData.ENDINGBALANCE;
                                parameters["@XREPORTID"] = XReadingData.XREPORTID;
                                parameters["@BEGINNINGRETURNNO"] = XReadingData.BEGINNINGRETURNNO;
                                parameters["@ENDINGSALESINVOICENO"] = XReadingData.ENDINGSALESINVOICENO;
                                parameters["@BEGINNINGSALESINVOICENO"] = XReadingData.BEGINNINGSALESINVOICENO;
                                parameters["@ENDINGRETURNNO"] = XReadingData.ENDINGRETURNNO;
                                parameters["@ZERORATEDSALESVATAMOUNT"] = XReadingData.ZERORATEDSALESVATAMOUNT;
                                parameters["@VATABLESALES"] = XReadingData.VATABLESALES;
                                parameters["@VATEXEMPTSALES"] = XReadingData.VATEXEMPTSALES;
                                parameters["@ZERORATEDSALES"] = XReadingData.ZERORATEDSALES;
                                parameters["@VATAMOUNT"] = XReadingData.VATAMOUNT;
                                parameters["@NOOFTRAININGTRANS"] = XReadingData.NOOFTRAININGTRANS;
                                parameters["@NOOFPAYINGCUST"] = XReadingData.NOOFPAYINGCUST;
                                parameters["@NOOFRETURN"] = XReadingData.NOOFRETURN;
                                parameters["@NUMBEROFITEMSOLD"] = XReadingData.NUMBEROFITEMSOLD;
                                parameters["@NOOFSUSPENDED"] = XReadingData.NOOFSUSPENDED;
                                parameters["@DATAAREAID"] = XReadingData.DATAAREAID;
                                parameters["@REGULARDISCOUNTS"] = XReadingData.REGULARDISCOUNTS;
                                parameters["@ACTUALDATE"] = XReadingData.ACTUALDATE;
                                parameters["@ACTUALTIME"] = 14400;// DateTime.Now.TimeOfDay;// XReadingData.ACTUALTIME;
                                parameters["@TENDERTYPE"] = XReadingData.TENDERTYPE;//XReadingData.TENDERTYPE;
                                parameters["@TENDERDECLARATION"] = XReadingData.TENDERDECLARATION;
                                parameters["@RETURNAMOUNT"] = XReadingData.RETURNAMOUNT;
                                parameters["@ROUNDING"] = XReadingData.ROUNDING;
                                parameters["@NOOFTRANSACTION"] = XReadingData.NOOFTRANSACTION;
                                parameters["@NOOFABORTED"] = XReadingData.NOOFABORTED;
                                parameters["@NOOFOPENDRAWER"] = XReadingData.NOOFOPENDRAWER;
                                parameters["@OVERBALANCE"] = XReadingData.OVERAMOUNT;
                                parameters["@SHORTBALANCE"] = XReadingData.SHORTAMOUNT;
                                parameters["@MACHINEIDENTIFY"] = XReadingData.MIN;
                                parameters["@SERIALNUMBER"] = XReadingData.SN;
                                parameters["@TOTALDISCOUNT"] = XReadingData.TOTALDISCOUNTS;
                                parameters["@TOTALVATADJUSTMENT"] = XReadingData.TOTALVATADJUSTMENT;
                                parameters["@NOOFLOGON"] = XReadingData.NOOFLOGON;
                                parameters["@ZERORATEDDISCOUNT"] = XReadingData.ZERORATEDDISCOUNT;
                                int errorCode;
                                using (var databaseContextX = new DatabaseContext(originalReceiptsRequest.RequestContext))
                                {
                                    errorCode = databaseContextX.ExecuteStoredProcedureNonQuery("[ext].[LAW_RETAILXREADINGREPORT_Insert]", parameters);
                                }
                                if (errorCode != 0)
                                    throw new StorageException(StorageErrors.Microsoft_Dynamics_Commerce_Runtime_CriticalStorageError, errorCode, "Unable to save data");
                                transactionScope.Complete();
                            }
                        }
                        #endregion
                    }
                }
            }

            private Receipt CustomizeXZReport(Receipt receipt, RequestContext context, Shift shift)
            {
                Receipt customizedReceipt = new Receipt();
                GetDeviceConfigurationDataRequest getDeviceConfigurationDataRequest = new GetDeviceConfigurationDataRequest();
                SingleEntityDataServiceResponse<DeviceConfiguration> deviceConfiguration = originalReceiptsRequest.RequestContext.Execute<SingleEntityDataServiceResponse<DeviceConfiguration>>(getDeviceConfigurationDataRequest);
                this.getDateTimeShiftAndReportName(receipt, context, shift);
                this.getTerminalDetail(receipt, context, shift);
                this.getBeginingSalesInvoice(receipt, context, shift);
                this.getEndingSalesInvoice(receipt, context, shift);
                this.getBeginingSalesReturn(receipt, context, shift);
                this.getEndingSalesReturn(receipt, context, shift);
                this.getAllItemSoldAndReturn(receipt, context, shift);
                this.getRegulerDataInShift(receipt, context, shift, deviceConfiguration);
                customizedReceipt = this.GetDesignReceiptForXZReport(shift, receipt.ReceiptType, context);
                return customizedReceipt;
            }

            public void getRegulerDataInShift(Receipt receipt, RequestContext context, Shift shift, SingleEntityDataServiceResponse<DeviceConfiguration> deviceConfiguration)
            {
                XReadingData.STORE = shift.StoreId;
                XReadingData.TERMINALID = terminal.TerminalId;
                XReadingData.SHIFT = shift.ShiftId.ToString();
                XReadingData.BEGININGBALANCE = globalLastShiftBalance;
                XReadingData.XREPORTID = XReadingNumber;
                XReadingData.NOOFTRANSACTION = shift.SaleTransactionCount;
                XReadingData.ROUNDING = shift.RoundedAmountTotal;
                XReadingData.NOOFABORTED = shift.VoidedSalesTotal;
                XReadingData.DOCNUM = XReadingNumber;
                XReadingData.TIN = deviceConfiguration.Entity.TaxIdNumber;
                XReadingData.STAFFNAME = this.GetEmployeeByStaffId(shift).Entity.Name;
                XReadingData.DATAAREAID = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                bool flag1 = shift.OverShortTotal < Decimal.Zero;
                if (flag1)
                    XReadingData.SHORTAMOUNT = shift.OverShortTotal;
                else
                    XReadingData.OVERAMOUNT = shift.OverShortTotal;
                //nghia.song change code get company and device name
                XReadingData.COMPANYADDRESS = originalReceiptsRequest.RequestContext.GetOrgUnit()?.OrgUnitFullAddress ?? string.Empty;
                XReadingData.COMPANYNAME = originalReceiptsRequest.RequestContext.GetChannel().Name ?? string.Empty;
                //nghia.song --end
                XReadingData.NOOFPAYINGCUST = shift.SaleTransactionCount + shift.CustomerCount;
                XReadingData.NETSALES = XReadingData.NETSALES + XReadingData.VATAMOUNT;
                XReadingData.ENDINGBALANCE = globalLastShiftBalance + XReadingData.NETSALES;//NS
                XReadingData.NOOFLOGON = shift.LogOnTransactionCount;
                XReadingData.GROSSSALES += XReadingData.RETURNAMOUNT;
            }
            public void getAllItemSoldAndReturn(Receipt receipt, RequestContext context, Shift shift)
            {
                var queryRetailTransactionTable = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ax",
                    Select = new ColumnSet(new string[] { "TRANSACTIONID", "NETAMOUNT", "TYPE", "ENTRYSTATUS", "RECEIPTID", "NUMBEROFITEMS" }),
                    From = "RETAILTRANSACTIONTABLE",
                    Where = "BATCHID = @BATCHID AND CHANNEL = @CHANNEL AND STORE = @STORE AND TERMINAL = @TERMINAL AND DATAAREAID = @DATAAREAID"
                };

                queryRetailTransactionTable.Parameters["@BATCHID"] = shift.ShiftId;
                queryRetailTransactionTable.Parameters["@TERMINAL"] = terminal.TerminalId;
                queryRetailTransactionTable.Parameters["@STORE"] = shift.StoreId;
                queryRetailTransactionTable.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryRetailTransactionTable.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                this.defineDataIn2List();
                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    var extensions = databaseContext.ReadEntity<ExtensionsEntity>(queryRetailTransactionTable);
                    //LOOP all retail transaction in shift
                    foreach (ExtensionsEntity extension in extensions)
                    {
                        //Get data in transaction
                        string transactionId = extension.GetProperty("TRANSACTIONID").ToString();
                        this.sumDiscountAmountWithDiscountType(transactionId);
                        this.sumVatAdjustByGroupName(transactionId);
                        this.GetSalesTypeBreakDownAndAmountTotal(transactionId);
                        this.specialDiscountZeroRated(transactionId);
                        #region RECEIPTID
                        if (decimal.Parse(extension.GetProperty("ENTRYSTATUS").ToString()) == 0 && decimal.Parse(extension.GetProperty("TYPE").ToString()) == 2)
                        {
                            var queryTotalItemSold = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                            {
                                DatabaseSchema = "ax",
                                Select = new ColumnSet("QTY"),
                                From = "RETAILTRANSACTIONSALESTRANS",
                                Where = "QTY < 0 AND TRANSACTIONSTATUS = 0  AND CHANNEL = @CHANNEL AND STORE = @STORE AND TERMINALID = @TERMINALID AND TRANSACTIONID = @TRANSACTIONID AND DATAAREAID = @DATAAREAID"
                            };

                            queryTotalItemSold.Parameters["@CHANNEL"] = terminal.ChannelId; ;
                            queryTotalItemSold.Parameters["@STORE"] = shift.StoreId;
                            queryTotalItemSold.Parameters["@TERMINALID"] = shift.TerminalId;
                            queryTotalItemSold.Parameters["@TRANSACTIONID"] = transactionId;
                            queryTotalItemSold.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                            using (DatabaseContext databaseContextD = new DatabaseContext(originalReceiptsRequest.RequestContext))
                            {
                                foreach (ExtensionsEntity totalItemSold in databaseContextD.ReadEntity<ExtensionsEntity>(queryTotalItemSold))
                                {
                                    XReadingData.NUMBEROFITEMSOLD += (-1) * decimal.Parse(totalItemSold.GetProperty("QTY").ToString());
                                }
                            }
                        }


                        if (decimal.Parse(extension.GetProperty("NETAMOUNT").ToString()) > 0)
                        {
                            XReadingData.NOOFRETURN++;
                        }
                        #endregion
                    }
                }
            }
            public void getEndingSalesInvoice(Receipt receipt, RequestContext context, Shift shift)
            {
                var queryReatailTransactionDESC = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ax",
                    Select = new ColumnSet("TRANSACTIONID", "TRANSDATE", "RECEIPTID"),
                    From = "RETAILTRANSACTIONTABLE",
                    OrderBy = "TRANSDATE DESC, TRANSTIME DESC",
                    Where = "ENTRYSTATUS = 0  AND TYPE = 2 AND CHANNEL = @CHANNEL AND BATCHID = @BATCHID AND STORE = @STORE AND TERMINAL = @TERMINAL  AND  NETAMOUNT < 0 AND DATAAREAID = @DATAAREAID"
                };

                queryReatailTransactionDESC.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryReatailTransactionDESC.Parameters["@BATCHID"] = shift.ShiftId;
                queryReatailTransactionDESC.Parameters["@STORE"] = shift.StoreId;
                queryReatailTransactionDESC.Parameters["@TERMINAL"] = terminal.TerminalId;
                queryReatailTransactionDESC.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    ExtensionsEntity extensionsField = databaseContext.ReadEntity<ExtensionsEntity>(queryReatailTransactionDESC).FirstOrDefault();
                    if (extensionsField != null)
                    {
                        XReadingData.ENDINGSALESINVOICENO = extensionsField.GetProperty("RECEIPTID").ToString();
                    }
                }

            }
            public void getBeginingSalesReturn(Receipt receipt, RequestContext context, Shift shift)
            {
                var queryReatailTransactionReturnASC = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ax",
                    Select = new ColumnSet("TRANSACTIONID", "TRANSDATE", "RECEIPTID"),
                    From = "RETAILTRANSACTIONTABLE",
                    OrderBy = "TRANSDATE ASC, TRANSTIME ASC",
                    Where = "TYPE = 2 AND CHANNEL = @CHANNEL AND BATCHID = @BATCHID AND STORE = @STORE AND TERMINAL = @TERMINAL AND NETAMOUNT >= 0  AND DATAAREAID = @DATAAREAID"
                };

                queryReatailTransactionReturnASC.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryReatailTransactionReturnASC.Parameters["@BATCHID"] = shift.ShiftId;
                queryReatailTransactionReturnASC.Parameters["@STORE"] = shift.StoreId;
                queryReatailTransactionReturnASC.Parameters["@TERMINAL"] = terminal.TerminalId;
                queryReatailTransactionReturnASC.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    ExtensionsEntity extensionsField = databaseContext.ReadEntity<ExtensionsEntity>(queryReatailTransactionReturnASC).FirstOrDefault();
                    if (extensionsField != null)
                    {
                        XReadingData.BEGINNINGRETURNNO = extensionsField.GetProperty("RECEIPTID").ToString();
                    }
                }
            }
            public void getEndingSalesReturn(Receipt receipt, RequestContext context, Shift shift)
            {
                var queryReatailTransactionReturnDESC = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ax",
                    Select = new ColumnSet("TRANSACTIONID", "TRANSDATE", "RECEIPTID"),
                    From = "RETAILTRANSACTIONTABLE",
                    OrderBy = "TRANSDATE DESC, TRANSTIME DESC",
                    Where = "TYPE = 2 AND CHANNEL = @CHANNEL AND BATCHID = @BATCHID AND STORE = @STORE AND TERMINAL = @TERMINAL AND NETAMOUNT >= 0  AND DATAAREAID = @DATAAREAID"
                };

                queryReatailTransactionReturnDESC.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryReatailTransactionReturnDESC.Parameters["@BATCHID"] = shift.ShiftId;
                queryReatailTransactionReturnDESC.Parameters["@STORE"] = shift.StoreId;
                queryReatailTransactionReturnDESC.Parameters["@TERMINAL"] = terminal.TerminalId;
                queryReatailTransactionReturnDESC.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    ExtensionsEntity extensionsField = databaseContext.ReadEntity<ExtensionsEntity>(queryReatailTransactionReturnDESC).FirstOrDefault();
                    if (extensionsField != null)
                    {
                        XReadingData.ENDINGRETURNNO = extensionsField.GetProperty("RECEIPTID").ToString();
                    }
                }
            }
            public void getBeginingSalesInvoice(Receipt receipt, RequestContext context, Shift shift)
            {
                var queryReatailTransactionASC = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ax",
                    Select = new ColumnSet("TRANSACTIONID", "TRANSDATE", "RECEIPTID"),
                    From = "RETAILTRANSACTIONTABLE",
                    OrderBy = "TRANSDATE ASC, TRANSTIME ASC",
                    Where = "ENTRYSTATUS = 0 AND  TYPE = 2 AND CHANNEL = @CHANNEL AND BATCHID = @BATCHID AND STORE = @STORE AND TERMINAL = @TERMINAL AND  NETAMOUNT <0 AND  DATAAREAID = @DATAAREAID"
                };

                queryReatailTransactionASC.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryReatailTransactionASC.Parameters["@BATCHID"] = shift.ShiftId;
                queryReatailTransactionASC.Parameters["@STORE"] = shift.StoreId;
                queryReatailTransactionASC.Parameters["@TERMINAL"] = terminal.TerminalId;
                queryReatailTransactionASC.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    ExtensionsEntity extensionsField = databaseContext.ReadEntity<ExtensionsEntity>(queryReatailTransactionASC).FirstOrDefault();
                    if (extensionsField != null)
                    {
                        XReadingData.BEGINNINGSALESINVOICENO = extensionsField.GetProperty("RECEIPTID").ToString();
                    }
                }
            }
            public void getTerminalDetail(Receipt receipt, RequestContext context, Shift shift)
            {
                var queryRetailTerminal = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet(new string[] {
                    "LAW_MACHINEIDENTIFICATIONNUMBER",
                    "LAW_MACHINESERIALNUMBER",
                    "LAW_PERMITTOUSENUMBER",
                    "LAW_PTUDATEISSUED",
                    "LAW_PTUVALIDTO",
                    "LAW_ACCREDITATIONNUMBER",
                    "LAW_ACCDTNDATEISSUED",
                    "LAW_ACCDTNVALIDTO",
                    "TERMINALID" }),
                    From = "LAW_RETAILTERMINALTABLE",
                    Where = "TERMINALID = @TERMINALID"
                };

                queryRetailTerminal.Parameters["@TERMINALID"] = originalReceiptsRequest.RequestContext.GetTerminal().TerminalId;
                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    ExtensionsEntity extensions = databaseContext.ReadEntity<ExtensionsEntity>(queryRetailTerminal).FirstOrDefault();

                    if (extensions != null)
                    {
                        //Header 1.5 
                        XReadingData.MIN = extensions.GetProperty("LAW_MACHINESERIALNUMBER").ToString();
                        //Header 1.6
                        XReadingData.SN = extensions.GetProperty("LAW_MACHINESERIALNUMBER").ToString();

                    }
                }
            }
            public void getDateTimeShiftAndReportName(Receipt receipt, RequestContext context, Shift shift)
            {
                string str1 = string.Empty;
                string str2 = string.Empty;
                string str3 = string.Empty;
                string str4 = string.Empty;

                if (shift.StartDateTime.HasValue)
                {
                    if (receipt.ReceiptType == ReceiptType.ZReport)
                    {
                        str1 = this.FormatDate(shift.StartDateTime, context);
                        str2 = this.FormatTime(shift.StartDateTime, TimeFormattingType.SystemLongTime, context);
                    }
                    else
                    {
                        str1 = this.FormatDate(shift.StartDateTime, context);
                        str2 = this.FormatTime(shift.StartDateTime, TimeFormattingType.SystemLongTime, context);
                    }
                }
                XReadingData.ACTUALDATE = DateTime.Parse(str1);

                DateTime t = DateTime.ParseExact(str2, "h:mm:ss tt", CultureInfo.InvariantCulture);
                //if you really need a TimeSpan this will get the time elapsed since midnight:
                TimeSpan ts = t.TimeOfDay;

                XReadingData.ACTUALTIME = ts;
                if (shift.CloseDateTime.HasValue)
                {
                    str3 = this.FormatDate(shift.CloseDateTime, context);
                    str4 = this.FormatTime(shift.CloseDateTime, TimeFormattingType.SystemLongTime, context);
                }
                string empty = string.Empty;

                string str5;
                if (receipt.ReceiptType != ReceiptType.XReport)
                {
                    if (receipt.ReceiptType != ReceiptType.ZReport)
                        throw new NotSupportedException(string.Format("Unsupported Report Type '{0}'.", (object)receipt.ReceiptType));
                    str5 = shift.StaffId;
                    XReadingData.REPORTNAME = "X-Reading Report";
                }
                else
                {
                    str5 = context.GetPrincipal().UserId;
                    XReadingData.REPORTNAME = "Tender Report";
                }
            }
            public class DistcountEntity
            {
                public string DiscountStr { get; set; }
                public decimal DiscountDecimal { get; set; }
                public decimal PrintingOrder { get; set; }

                public DistcountEntity(string _discountType, decimal _discountAmount, decimal _printingOrder)
                {
                    DiscountStr = _discountType;
                    DiscountDecimal = _discountAmount;
                    PrintingOrder = _printingOrder;
                }
            }
            public void sumVatAdjustByGroupName(string transactionId)
            {
                var queryReatailTransDiscountGroupName = new SqlPagedQuery(QueryResultSettings.AllRecords)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet("DISCOUNTGROUPNAME", "TRANSACTIONID", "SALELINENUM"),
                    From = "LAW_RETAILTRANSDISCOUNTGROUPBYGROUPNAMEVIEW",
                    Where = "DATAAREAID = @DATAAREAID AND TRANSACTIONID = @TRANSACTIONID AND TERMINALID = @TERMINALID AND STOREID = @STOREID AND CHANNEL = @CHANNEL"
                };
                queryReatailTransDiscountGroupName.Parameters["@TERMINALID"] = shift.TerminalId;
                queryReatailTransDiscountGroupName.Parameters["@STOREID"] = shift.StoreId;
                queryReatailTransDiscountGroupName.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryReatailTransDiscountGroupName.Parameters["@TRANSACTIONID"] = transactionId;
                queryReatailTransDiscountGroupName.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    var extensions = databaseContext.ReadEntity<ExtensionsEntity>(queryReatailTransDiscountGroupName);

                    //LOOP all record on RETAILTRANSACTIONDISCOUNTTRANSEXTEND
                    foreach (ExtensionsEntity extension in extensions)
                    {
                        decimal SALELINENUM = decimal.Parse(extension.GetProperty("SALELINENUM").ToString());
                        string discountGroupName = extension.GetProperty("DISCOUNTGROUPNAME").ToString();
                        decimal DiscountValue = this.sumDataInRetailTransactionTableExt(transactionId, SALELINENUM);

                        int printingOrder = 0;
                        var queryLPIDISCOUNTTYPE = new SqlPagedQuery(QueryResultSettings.AllRecords)
                        {
                            DatabaseSchema = "ext",
                            Select = new ColumnSet("DISCOUNTGROUPNAME", "PRINTINGORDER"),
                            From = "LAW_LPIDISCOUNTTYPE",
                            Where = "DATAAREAID = @DATAAREAID AND DISCOUNTGROUPNAME = @DISCOUNTGROUPNAME"
                        };
                        queryLPIDISCOUNTTYPE.Parameters["@DISCOUNTGROUPNAME"] = discountGroupName;
                        queryLPIDISCOUNTTYPE.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                        using (DatabaseContext databaseContextOrder = new DatabaseContext(originalReceiptsRequest.RequestContext))
                        {
                            var extensionsOrder = databaseContextOrder.ReadEntity<ExtensionsEntity>(queryLPIDISCOUNTTYPE).FirstOrDefault();

                            if (extensionsOrder != null)
                            {
                                printingOrder = int.Parse(extensionsOrder.GetProperty("PRINTINGORDER").ToString());
                            }

                        }

                        listVATAdjustDiscountGroup.Add(new DistcountEntity(discountGroupName, (-1) * DiscountValue, printingOrder));
                    }
                }

                //TH ca bi thieu loai VAT
                var queryLPIDISCOUNTTYPEINCLUDE = new SqlPagedQuery(QueryResultSettings.AllRecords)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet("DISCOUNTGROUPNAME", "PRINTINGORDER"),
                    From = "LAW_LPIDISCOUNTTYPE",
                    Where = "DATAAREAID = @DATAAREAID"
                };
                queryLPIDISCOUNTTYPEINCLUDE.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContextOrder = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    var extensionsOrders = databaseContextOrder.ReadEntity<ExtensionsEntity>(queryLPIDISCOUNTTYPEINCLUDE);
                    foreach (ExtensionsEntity extensionsOrder in extensionsOrders)
                    {
                        string discountType = extensionsOrder.GetProperty("DISCOUNTGROUPNAME").ToString();
                        int printingOrder = 0;
                        if (!listDiscountType.Exists(x => x.DiscountStr == discountType))
                        {
                            listVATAdjustDiscountGroup.Add(new DistcountEntity(discountType, 0, printingOrder));
                        }
                    }
                    //End
                }

            }
            public void specialDiscountZeroRated(string transactionId)
            {
                decimal zeroDiscount = 0;
                var queryReatailTableTrans = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet("LAW_VATADJUSTMENT"),
                    From = "LAW_RETAILTRANSACTIONSALESLINEEXTEND",
                    Where = "LAW_ZERORATEDSALESAMOUNT != 0  AND DATAAREAID = @DATAAREAID AND CHANNEL = @CHANNEL AND TERMINALID = @TERMINALID AND TRANSACTIONID = @TRANSACTIONID AND STOREID = @STOREID"
                };

                queryReatailTableTrans.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryReatailTableTrans.Parameters["@STOREID"] = shift.StoreId;
                queryReatailTableTrans.Parameters["@TERMINALID"] = terminal.TerminalId;
                queryReatailTableTrans.Parameters["@TRANSACTIONID"] = transactionId;
                queryReatailTableTrans.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContextField = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    var extensionsFields = databaseContextField.ReadEntity<ExtensionsEntity>(queryReatailTableTrans);
                    foreach (ExtensionsEntity extensionsField in extensionsFields)
                        zeroDiscount += decimal.Parse(extensionsField.GetProperty("LAW_VATADJUSTMENT").ToString());
                }
                XReadingData.ZERORATEDDISCOUNT += (-1) * zeroDiscount;


            }

            public void defineDataIn2List()
            {
                //TH ca bi thieu loai VAT
                var queryLPIDISCOUNTTYPEINCLUDE = new SqlPagedQuery(QueryResultSettings.AllRecords)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet("DISCOUNTTYPENAME", "PRINTINGORDER", "DISCOUNTGROUPNAME"),
                    From = "LAW_LPIDISCOUNTTYPE",
                    Where = "DATAAREAID = @DATAAREAID",
                    OrderBy = "PRINTINGORDER ASC"
                };
                queryLPIDISCOUNTTYPEINCLUDE.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContextOrder = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    var extensionsOrders = databaseContextOrder.ReadEntity<ExtensionsEntity>(queryLPIDISCOUNTTYPEINCLUDE);
                    foreach (ExtensionsEntity extensionsOrder in extensionsOrders)
                    {
                        string discountType = extensionsOrder.GetProperty("DISCOUNTTYPENAME").ToString();
                        string discountGroup = extensionsOrder.GetProperty("DISCOUNTGROUPNAME").ToString();
                        int printingOrder = int.Parse(extensionsOrder.GetProperty("PRINTINGORDER").ToString());
                        listDiscountType.Add(new DistcountEntity(discountType, 0, printingOrder));
                        listVATAdjustDiscountGroup.Add(new DistcountEntity(discountGroup, 0, printingOrder));
                    }
                    //End
                }
            }
            public decimal sumDataInRetailTransactionTableExt(string transactionId, decimal salesLineNum)
            {
                decimal VATAdjust = 0;
                var queryReatailTableTrans = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet("LAW_VATADJUSTMENT"),
                    From = "LAW_RETAILTRANSACTIONSALESLINEEXTEND",
                    Where = "SALESLINENUM = @SALESLINENUM  AND DATAAREAID = @DATAAREAID AND CHANNEL = @CHANNEL AND TERMINALID = @TERMINALID AND TRANSACTIONID = @TRANSACTIONID AND STOREID = @STOREID"
                };

                queryReatailTableTrans.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryReatailTableTrans.Parameters["@STOREID"] = shift.StoreId;
                queryReatailTableTrans.Parameters["@TERMINALID"] = terminal.TerminalId;
                queryReatailTableTrans.Parameters["@TRANSACTIONID"] = transactionId;
                queryReatailTableTrans.Parameters["@SALESLINENUM"] = salesLineNum;
                queryReatailTableTrans.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContextField = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    ExtensionsEntity extensionsFields = databaseContextField.ReadEntity<ExtensionsEntity>(queryReatailTableTrans).FirstOrDefault();

                    VATAdjust = decimal.Parse(extensionsFields.GetProperty("LAW_VATADJUSTMENT").ToString());
                }
                return VATAdjust;
            }
            public void sumDiscountAmountWithDiscountType(string transactionId)
            {
                var queryReatailTransDiscountTransExtend = new SqlPagedQuery(QueryResultSettings.AllRecords)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet("DISCOUNTTYPE", "TRANSACTIONID", "SALELINENUM"),
                    From = "LAW_RETAILTRANSDISCOUNTGROUPBYDISCOUNTTYPEVIEW",
                    Where = "DATAAREAID = @DATAAREAID AND TRANSACTIONID = @TRANSACTIONID AND TERMINALID = @TERMINALID AND STOREID = @STOREID AND CHANNEL = @CHANNEL"
                };
                queryReatailTransDiscountTransExtend.Parameters["@TERMINALID"] = shift.TerminalId;
                queryReatailTransDiscountTransExtend.Parameters["@STOREID"] = shift.StoreId;
                queryReatailTransDiscountTransExtend.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryReatailTransDiscountTransExtend.Parameters["@TRANSACTIONID"] = transactionId;
                queryReatailTransDiscountTransExtend.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    var extensions = databaseContext.ReadEntity<ExtensionsEntity>(queryReatailTransDiscountTransExtend);

                    //LOOP all record on RETAILTRANSACTIONDISCOUNTTRANSEXTEND
                    foreach (ExtensionsEntity extension in extensions)
                    {
                        decimal SALELINENUM = decimal.Parse(extension.GetProperty("SALELINENUM").ToString());
                        string discountType = extension.GetProperty("DISCOUNTTYPE").ToString();
                        decimal DiscountValue = this.getDiscountAmountBaseOnDiscountType(transactionId, SALELINENUM);

                        int printingOrder = 0;
                        var queryLPIDISCOUNTTYPE = new SqlPagedQuery(QueryResultSettings.AllRecords)
                        {
                            DatabaseSchema = "ext",
                            Select = new ColumnSet("DISCOUNTTYPENAME", "PRINTINGORDER"),
                            From = "LAW_LPIDISCOUNTTYPE",
                            Where = "DATAAREAID = @DATAAREAID AND DISCOUNTTYPENAME = @DISCOUNTTYPENAME"
                        };
                        queryLPIDISCOUNTTYPE.Parameters["@DISCOUNTTYPENAME"] = discountType;
                        queryLPIDISCOUNTTYPE.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                        using (DatabaseContext databaseContextOrder = new DatabaseContext(originalReceiptsRequest.RequestContext))
                        {
                            var extensionsOrder = databaseContextOrder.ReadEntity<ExtensionsEntity>(queryLPIDISCOUNTTYPE).FirstOrDefault();

                            if (extensionsOrder != null)
                            {
                                printingOrder = int.Parse(extensionsOrder.GetProperty("PRINTINGORDER").ToString());
                            }

                        }

                        listDiscountType.Add(new DistcountEntity(discountType, (-1) * DiscountValue, printingOrder));
                    }
                }
            }
            public decimal getDiscountAmountBaseOnDiscountType(string transactionId, decimal salesLineNum)
            {
                decimal discountAmt = 0;

                var queryReatailTransSalesTransExt = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ax",
                    Select = new ColumnSet("TERMINALID", "TRANSACTIONID", "STORE", "LINENUM", "CHANNEL", "DISCAMOUNTWITHOUTTAX"),
                    From = "RETAILTRANSACTIONSALESTRANS",
                    Where = "LINENUM = @SALESLINENUM AND DATAAREAID = @DATAAREAID AND CHANNEL = @CHANNEL AND TERMINALID = @TERMINALID AND TRANSACTIONID = @TRANSACTIONID AND STORE = @STORE"
                };

                queryReatailTransSalesTransExt.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryReatailTransSalesTransExt.Parameters["@STORE"] = shift.StoreId;
                queryReatailTransSalesTransExt.Parameters["@TERMINALID"] = terminal.TerminalId;
                queryReatailTransSalesTransExt.Parameters["@TRANSACTIONID"] = transactionId;
                queryReatailTransSalesTransExt.Parameters["@SALESLINENUM"] = salesLineNum;
                queryReatailTransSalesTransExt.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;

                using (DatabaseContext databaseContextField = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    ExtensionsEntity extensionsField = databaseContextField.ReadEntity<ExtensionsEntity>(queryReatailTransSalesTransExt).FirstOrDefault();
                    if (extensionsField != null)
                    {
                        //Get discount amount
                        discountAmt = decimal.Parse(extensionsField.GetProperty("DISCAMOUNTWITHOUTTAX").ToString());
                    }
                }
                return discountAmt;
            }
            public void GetSalesTypeBreakDownAndAmountTotal(string transactionId)
            {
                decimal ZeroRatedSalesAmount = 0;
                decimal VATableSalesAmount = 0;
                decimal VATExemptSalesAmount = 0;

                decimal ZeroRatedSalesVATAmount = 0;
                decimal VATableSales = 0;
                decimal VATExemptSales = 0;

                decimal NetSales = 0;
                decimal Grosssales = 0;
                decimal ReturnAmount = 0;

                var queryRetailTransactionTable = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet(new string[] { "LAW_VATEXEMPTSALESVATAMOUNT", "LAW_ZERORATEDSALESVATAMOUNT", "LAW_VATABLESSALESAMOUNT", "LAW_VATABLESSALESVATAMOUNT", "TRANSACTIONID", "LAW_VATEXEMPTSALESAMOUNT", "LAW_ZERORATEDSALESAMOUNT", "LAW_NETSALES", "LAW_LPITOTAL" }),
                    From = "LAW_RETAILTRANSACTIONTABLEEXTEND",
                    Where = "TRANSACTIONID = @TRANSACTIONID AND CHANNEL = @CHANNEL AND STOREID = @STOREID  AND DATAAREAID = @DATAAREAID"
                };

                queryRetailTransactionTable.Parameters["@STOREID"] = shift.StoreId;
                queryRetailTransactionTable.Parameters["@TRANSACTIONID"] = transactionId;
                queryRetailTransactionTable.Parameters["@CHANNEL"] = terminal.ChannelId;
                queryRetailTransactionTable.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                using (DatabaseContext databaseContextField = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    var extensionsField = databaseContextField.ReadEntity<ExtensionsEntity>(queryRetailTransactionTable);
                    foreach (ExtensionsEntity extension in extensionsField)
                    {
                        //Get discount amount
                        VATableSalesAmount += decimal.Parse(extension.GetProperty("LAW_VATABLESSALESAMOUNT").ToString());
                        VATableSales += decimal.Parse(extension.GetProperty("LAW_VATABLESSALESVATAMOUNT").ToString());
                        VATExemptSalesAmount += decimal.Parse(extension.GetProperty("LAW_VATEXEMPTSALESAMOUNT").ToString());
                        VATExemptSales += decimal.Parse(extension.GetProperty("LAW_VATEXEMPTSALESVATAMOUNT").ToString());
                        ZeroRatedSalesAmount += decimal.Parse(extension.GetProperty("LAW_ZERORATEDSALESAMOUNT").ToString());
                        ZeroRatedSalesVATAmount += decimal.Parse(extension.GetProperty("LAW_ZERORATEDSALESVATAMOUNT").ToString());
                        NetSales += decimal.Parse(extension.GetProperty("LAW_NETSALES").ToString());
                        Grosssales += decimal.Parse(extension.GetProperty("LAW_LPITOTAL").ToString());

                        if (decimal.Parse(extension.GetProperty("LAW_LPITOTAL").ToString()) > 0)
                        {
                            ReturnAmount += decimal.Parse(extension.GetProperty("LAW_LPITOTAL").ToString());
                        }


                    }

                }
                XReadingData.VATAMOUNT += (-1) * (VATableSales + VATExemptSales + ZeroRatedSalesVATAmount);

                //XReadingData.ZERORATEDSALESVATAMOUNT += (-1) * ZeroRatedSalesAmount;
                XReadingData.ZERORATEDSALES += (-1) * ZeroRatedSalesAmount;
                XReadingData.VATABLESALES += (-1) * VATableSalesAmount;
                XReadingData.VATEXEMPTSALES += (-1) * VATExemptSalesAmount;
                //nghia.song can remove code nay sao
                XReadingData.NETSALES += NetSales;
                XReadingData.GROSSSALES += (-1) * Grosssales;
                XReadingData.RETURNAMOUNT += ReturnAmount;




            }
            private SingleEntityDataServiceResponse<Employee> GetEmployeeByStaffId(Shift shift)
            {
                SqlPagedQuery sqlPagedQuery = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    From = "GetEmployeeByStaffId(@nvc_StaffId, @nvc_DataAreaId)"
                };
                sqlPagedQuery.Parameters["@nvc_StaffId"] = shift.StaffId;
                sqlPagedQuery.Parameters["@nvc_DataAreaId"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                Employee entity1;
                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                    entity1 = databaseContext.ReadEntity<Employee>((IDatabaseQuery)sqlPagedQuery).SingleOrDefault<Employee>();
                if (entity1 != null)
                {
                    ChannelConfiguration channelConfiguration = originalReceiptsRequest.RequestContext.GetChannelConfiguration();
                    if (channelConfiguration != null)
                        entity1.Images = RichMediaHelper.PopulateEmployeeMediaInformation(entity1.StaffId, entity1.ImageUri, channelConfiguration.EmployeeDefaultImageTemplate);
                    else if (originalReceiptsRequest.RequestContext.GetPrincipal().ChannelId != 0L)
                    {
                        GetChannelConfigurationDataRequest configurationDataRequest = new GetChannelConfigurationDataRequest(originalReceiptsRequest.RequestContext.GetPrincipal().ChannelId);
                        ChannelConfiguration entity2 = originalReceiptsRequest.RequestContext.Execute<SingleEntityDataServiceResponse<ChannelConfiguration>>((Request)configurationDataRequest).Entity;
                        entity1.Images = RichMediaHelper.PopulateEmployeeMediaInformation(entity1.StaffId, entity1.ImageUri, entity2.EmployeeDefaultImageTemplate);
                    }
                }
                return new SingleEntityDataServiceResponse<Employee>(entity1);
            }

            public string getOwnedBy(RequestContext context)
            {
                string OwnerName = "";
                var querystoreView = new SqlPagedQuery(QueryResultSettings.SingleRecord)
                {
                    DatabaseSchema = "ext",
                    Select = new ColumnSet("NAMEALIAS"),
                    From = "LAW_STOREVIEW",
                    Where = "CHANNELID = @CHANNELID AND DATAAREAID = @DATAAREAID"
                };

                querystoreView.Parameters["@CHANNELID"] = terminal.ChannelId;
                querystoreView.Parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                using (DatabaseContext databaseContext = new DatabaseContext(originalReceiptsRequest.RequestContext))
                {
                    ExtensionsEntity extensionsField = databaseContext.ReadEntity<ExtensionsEntity>(querystoreView).FirstOrDefault();
                    if (extensionsField != null)
                    {
                        OwnerName =  extensionsField.GetProperty("NAMEALIAS").ToString();
                    }
                }
                return OwnerName;
            }
            private void PrepareXZReportHeader(StringBuilder reportLayout, Shift shift, ReceiptType receiptType, RequestContext context)
            {
                ThrowIf.Null<RequestContext>(context, "requestContext");
                ThrowIf.Null<Shift>(shift, nameof(shift));
                ChannelConfiguration channelConfiguration = context.GetChannelConfiguration();
                ThrowIf.Null<ChannelConfiguration>(channelConfiguration, "context.GetChannelConfiguration()");
                string str1 = string.Empty;
                string str2 = string.Empty;
                string str3 = string.Empty;
                string str4 = string.Empty;
                if (shift.StartDateTime.HasValue)
                {
                    if (receiptType == ReceiptType.ZReport)
                    {
                        str1 = this.FormatDate(shift.StartDateTime, context);
                        str2 = this.FormatTime(shift.StartDateTime, TimeFormattingType.SystemLongTime, context);
                    }
                    else
                    {
                        str1 = this.FormatDate(shift.StartDateTime, context);
                        str2 = this.FormatTime(shift.StartDateTime, TimeFormattingType.SystemLongTime, context);
                    }
                }
                if (shift.CloseDateTime.HasValue)
                {
                    str3 = this.FormatDate(shift.CloseDateTime, context);
                    str4 = this.FormatTime(shift.CloseDateTime, TimeFormattingType.SystemLongTime, context);
                }
                string empty = string.Empty;
                //Nghia.song customize X report
                reportLayout.AppendLine(originalReceiptsRequest.RequestContext.GetChannel().Name ?? string.Empty);
                reportLayout.AppendLine(originalReceiptsRequest.RequestContext.GetOrgUnit()?.OrgUnitFullAddress ?? string.Empty);
                this.AppendReportLine(context, reportLayout, "Owned by: ", this.getOwnedBy(originalReceiptsRequest.RequestContext));
                this.AppendReportLine(context, reportLayout, "VAT Reg TIN:    ", XReadingData.TIN);
                this.AppendReportLine(context, reportLayout, "MIN:    ", XReadingData.MIN);
                this.AppendReportLine(context, reportLayout, "SN:    ", XReadingData.SN);
                //this.AppendReportLine(context, reportLayout, "Contact:    ", "1234-5678");
                //this.AppendReportLine(context, reportLayout, "www.lawson.jp");

                //nghia.song --end
                //reportLayout.AppendLine(this.SingleLine);
                string str5;
                if (receiptType != ReceiptType.XReport)
                {
                    if (receiptType != ReceiptType.ZReport)
                        throw new NotSupportedException(string.Format("Unsupported Report Type '{0}'.", (object)receiptType));
                    str5 = shift.StaffId;
                    //this.AppendReportLine(context, reportLayout, "zReport");
                }
                else
                {
                    str5 = context.GetPrincipal().UserId;
                }
                this.AppendReportLine(context, reportLayout, XReadingData.REPORTNAME);
                if (receiptType == ReceiptType.ZReport)
                    this.AppendReportLine(context, reportLayout, "ReportId:", XReadingData.XREPORTID);
                DateTimeOffset now = DateTimeOffset.Now;
                string str6 = this.FormatDate(new DateTimeOffset?(now), context);
                string str7 = this.FormatTime(new DateTimeOffset?(now), TimeFormattingType.SystemLongTime, context);
                if (channelConfiguration.CountryRegionISOCode == CountryRegionISOCode.SE)
                {
                    reportLayout.AppendLine(this.FormatHeaderLineWithWrapping(context, "OrgUnitName", context.GetOrgUnit().OrgUnitName, true));
                    reportLayout.AppendLine(this.FormatHeaderLine(context, "OrgNumber", context.GetDeviceConfiguration().TaxIdNumber, true));
                }
                reportLayout.Append(this.FormatHeaderLine(context, "StoreId", shift.StoreId, true));
                reportLayout.AppendLine(this.FormatHeaderLine(context, "Date", str6, false));

                reportLayout.Append(this.FormatHeaderLine(context, "Employee", str5, true));
                // nghiasong customize x report
                reportLayout.AppendLine(this.FormatHeaderLine(context, "Operator name", XReadingData.STAFFNAME, false));
                //nghia.song --end
                reportLayout.AppendLine(this.FormatHeaderLine(context, "Time", str7, false));
                reportLayout.AppendLine(this.FormatHeaderLine(context, "RegisterNumber", shift.TerminalId, true));
                reportLayout.AppendLine(this.SingleLine);
                reportLayout.AppendLine(this.FormatHeaderLine(context, "ShiftNumber", string.Format("{0}:{1}", (object)shift.TerminalId, (object)shift.ShiftId), true));
                reportLayout.Append(this.FormatHeaderLine(context, "StartDate", str1, true));
                if (receiptType == ReceiptType.ZReport)
                    reportLayout.AppendLine(this.FormatHeaderLine(context, "EndDate", str3, false));
                else
                    reportLayout.AppendLine();
                reportLayout.Append(this.FormatHeaderLine(context, "StartTime", str2, true));
                if (receiptType == ReceiptType.ZReport)
                    reportLayout.AppendLine(this.FormatHeaderLine(context, "EndTime", str4, false));
                else
                    reportLayout.AppendLine();
                reportLayout.AppendLine();
            }

            private Receipt GetDesignReceiptForXZReport(Shift shift, ReceiptType receiptType, RequestContext context)
            {
                DeviceConfiguration deviceConfiguration = context.GetDeviceConfiguration();
                CountryRegionISOCode countryRegionIsoCode = context.GetChannelConfiguration().CountryRegionISOCode;
                if (deviceConfiguration != null && !deviceConfiguration.PrintXZReportsOnTerminal)
                    throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_PrintXZReportNotConfigured, "The current terminal is not configured to print X or Z report.");
                StringBuilder stringBuilder = new StringBuilder(2500);
                Receipt receipt = new Receipt();
                this.PrepareXZReportHeader(stringBuilder, shift, receiptType, context);
                receipt.Header = stringBuilder.ToString().TrimEnd();
                header = receipt.Header;
                stringBuilder.Clear();
                string currency = context.GetOrgUnit().Currency;
                stringBuilder.AppendLine(this.SingleLine);
                this.AppendReportLine(context, stringBuilder, "Gross Sales", (object)this.FormatNumber((Decimal)XReadingData.GROSSSALES, context));
                stringBuilder.AppendLine(this.SingleLine);

                List<DistcountEntity> results = listDiscountType.GroupBy(l => l.DiscountStr).Select(cl => new DistcountEntity(
                                                                                                          cl.First().DiscountStr.ToString(),
                                                                                                          cl.Sum(c => c.DiscountDecimal),
                                                                                                          cl.First().PrintingOrder
                                                                                                         )).OrderBy(l => l.PrintingOrder).ToList();

                decimal sumTotalDiscount = listDiscountType.Sum(x => x.DiscountDecimal);

                this.AppendReportLine(context, stringBuilder, "Discount:");

                {
                    foreach (var discount in results)
                    {
                        ParameterSet parameters = new ParameterSet();
                        parameters["@TERMINALID"] = shift.TerminalId;
                        parameters["@SHIFTID"] = shift.ShiftId;
                        parameters["@STORE"] = shift.StoreId;
                        parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                        parameters["@DISCOUNTTYPE"] = discount.DiscountStr;
                        parameters["@AMOUNT"] = discount.DiscountDecimal;
                        parameters["@PRINTINGORDER"] = discount.PrintingOrder;
                        //TRANSDATE
                        parameters["@TRANSDATE"] = DateTime.Now;
                        using (TransactionScope transactionScope = new TransactionScope())
                        {
                            if (receiptType == ReceiptType.ZReport)
                            {
                                int errorCode;
                                using (var databaseContext = new DatabaseContext(originalReceiptsRequest))
                                {
                                    errorCode = databaseContext.ExecuteStoredProcedureNonQuery("[ext].[LAW_DISCOUNTGROUPINSHIFT_Insert]", parameters);
                                }

                                if (errorCode != 0)
                                    throw new StorageException(StorageErrors.Microsoft_Dynamics_Commerce_Runtime_CriticalStorageError, errorCode, "Unable to save data");

                            }
                            transactionScope.Complete();
                        }
                        this.AppendReportLine(context, stringBuilder, "     " + discount.DiscountStr, (object)this.FormatNumber((Decimal)discount.DiscountDecimal, context));

                    }
                }


                stringBuilder.AppendLine(this.SingleLine);
                List<DistcountEntity> VATAdjustresults = listVATAdjustDiscountGroup.GroupBy(l => l.DiscountStr).Select(cl => new DistcountEntity(
                                                                                          cl.First().DiscountStr.ToString(),
                                                                                          cl.Sum(c => c.DiscountDecimal),
                                                                                           cl.First().PrintingOrder
                                                                                         )).OrderBy(l => l.PrintingOrder).ToList();

                decimal sumVATAdjust = listVATAdjustDiscountGroup.Sum(x => x.DiscountDecimal);
                this.AppendReportLine(context, stringBuilder, "VAT Adjustment:");

                {
                    foreach (var discount in VATAdjustresults)
                    {
                        ParameterSet parameters = new ParameterSet();
                        parameters["@TERMINALID"] = shift.TerminalId;
                        parameters["@SHIFTID"] = shift.ShiftId;
                        parameters["@STORE"] = shift.StoreId;
                        parameters["@DATAAREAID"] = originalReceiptsRequest.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                        parameters["@DISCOUNTGROUPNAME"] = discount.DiscountStr;
                        parameters["@AMOUNT"] = discount.DiscountDecimal;
                        parameters["@PRINTINGORDER"] = discount.PrintingOrder;
                        parameters["@TRANSDATE"] = DateTime.Now;
                        using (TransactionScope transactionScope = new TransactionScope())
                        {
                            if (receiptType == ReceiptType.ZReport)
                            {
                                int errorCode;
                                using (var databaseContext = new DatabaseContext(originalReceiptsRequest))
                                {
                                    errorCode = databaseContext.ExecuteStoredProcedureNonQuery("[ext].[LAW_VATADJUSTMENTINSHIFT_Insert]", parameters);
                                }

                                if (errorCode != 0)
                                    throw new StorageException(StorageErrors.Microsoft_Dynamics_Commerce_Runtime_CriticalStorageError, errorCode, "Unable to save data");

                            }
                            transactionScope.Complete();
                        }

                        this.AppendReportLine(context, stringBuilder, "     " + discount.DiscountStr, (object)this.FormatNumber((Decimal)discount.DiscountDecimal, context));

                    }

                }


                this.AppendReportLine(context, stringBuilder, "     Zero-Rated sales", (object)this.FormatNumber((Decimal)XReadingData.ZERORATEDDISCOUNT, context));//XReadingData.ZERORATEDDISCOUNT);
                this.AppendReportLine(context, stringBuilder, "     Returns", (object)this.FormatNumber((-1) * XReadingData.RETURNAMOUNT, context));//(object)this.FormatCurrency((-1) * XReadingData.RETURNAMOUNT, currency, context, (string)null).Result);
                stringBuilder.AppendLine(this.SingleLine);
                this.AppendReportLine(context, stringBuilder, "NET Sales", (object)this.FormatNumber((Decimal)XReadingData.NETSALES, context));
                stringBuilder.AppendLine(this.SingleLine);

                this.AppendReportLine(context, stringBuilder, "Tax code                                 Amount");
                this.AppendReportLine(context, stringBuilder, "    VATable Sales", (object)this.FormatNumber((Decimal)XReadingData.VATABLESALES, context));
                this.AppendReportLine(context, stringBuilder, "    VAT Exempt Sales", (object)this.FormatNumber((Decimal)XReadingData.VATEXEMPTSALES, context));
                this.AppendReportLine(context, stringBuilder, "    Zero Rated Sales", (object)this.FormatNumber((Decimal)XReadingData.ZERORATEDSALES, context));
                this.AppendReportLine(context, stringBuilder, "    VAT Amount", (object)this.FormatNumber((Decimal)(XReadingData.VATAMOUNT), context)); //(XReadingData.VATABLESALES + XReadingData.VATEXEMPTSALES + XReadingData.ZERORATEDSALES);
                this.AppendReportLine(context, stringBuilder, "Statistics");
                this.AppendReportLine(context, stringBuilder, "Sales", (object)this.FormatNumber((Decimal)shift.SaleTransactionCount, context));
                this.AppendReportLine(context, stringBuilder, "CustomerSales", (object)this.FormatNumber((Decimal)shift.CustomerCount, context));
                this.AppendReportLine(context, stringBuilder, "VoidedSales", (object)this.FormatNumber((Decimal)shift.VoidTransactionCount, context));
                this.AppendReportLine(context, stringBuilder, "OpenDrawer", (object)this.FormatNumber((Decimal)shift.NoSaleTransactionCount, context));
                //3. Customize to add statistics data: add some new rows in ‘Statistics’ part
                this.AppendReportLine(context, stringBuilder, "Item sold", (object)this.FormatNumber((Decimal)XReadingData.NUMBEROFITEMSOLD, context));
                this.AppendReportLine(context, stringBuilder, "No . of paying customer", (object)this.FormatNumber((Decimal)XReadingData.NOOFPAYINGCUST, context)); //XReadingData.NOOFPAYINGCUST);
                this.AppendReportLine(context, stringBuilder, "No . of Suspended Trans", (object)this.FormatNumber((Decimal)XReadingData.NOOFSUSPENDED, context)); //XReadingData.NOOFSUSPENDED);
                this.AppendReportLine(context, stringBuilder, "No . of Returns", (object)this.FormatNumber((Decimal)XReadingData.NOOFRETURN, context)); //XReadingData.NOOFRETURN);
                this.AppendReportLine(context, stringBuilder, "No . of Suspended Trans", (object)this.FormatNumber((Decimal)XReadingData.NOOFSUSPENDED, context)); //XReadingData.NOOFSUSPENDED);
                this.AppendReportLine(context, stringBuilder, "No . of Logon", (object)this.FormatNumber((Decimal)shift.LogOnTransactionCount, context)); //XReadingData.NOOFSUSPENDED);
                //4. Customize to add new part at the bottom of report to display general information of the Shift
                stringBuilder.AppendLine(this.SingleLine);
                this.AppendReportLine(context, stringBuilder, "Beginging Balance", (object)this.FormatNumber((Decimal)XReadingData.BEGININGBALANCE, context)); //XReadingData.BEGININGBALANCE);
                this.AppendReportLine(context, stringBuilder, "Ending Balance", (object)this.FormatNumber((Decimal)XReadingData.ENDINGBALANCE, context)); //XReadingData.ENDINGBALANCE);
                this.AppendReportLine(context, stringBuilder, "Beginging SI", XReadingData.BEGINNINGSALESINVOICENO);
                this.AppendReportLine(context, stringBuilder, "Ending SI", XReadingData.ENDINGSALESINVOICENO);
                this.AppendReportLine(context, stringBuilder, "Beginging Return No.", XReadingData.BEGINNINGRETURNNO);
                this.AppendReportLine(context, stringBuilder, "Ending Return No.", XReadingData.ENDINGRETURNNO);
                stringBuilder.AppendLine(this.SingleLine);
                this.AppendReportLine(context, stringBuilder, "TenderTotals");
                this.AppendReportLine(context, stringBuilder, "Tendered", (object)this.FormatCurrency(shift.TenderedTotal, currency, context, (string)null).Result);
                this.AppendReportLine(context, stringBuilder, "Change", (object)this.FormatCurrency(shift.ChangeTotal, currency, context, (string)null).Result);
                this.AppendReportLine(context, stringBuilder, "StartingAmount", (object)this.FormatCurrency(shift.StartingAmountTotal, currency, context, (string)null).Result);
                this.AppendReportLine(context, stringBuilder, "Added", (object)this.FormatCurrency(shift.FloatingEntryAmountTotal, currency, context, (string)null).Result);
                this.AppendReportLine(context, stringBuilder, "Removed", (object)this.FormatCurrency(shift.RemoveTenderAmountTotal, currency, context, (string)null).Result);
                this.AppendReportLine(context, stringBuilder, "BankDrop", (object)this.FormatCurrency(shift.BankDropTotal, currency, context, (string)null).Result);
                this.AppendReportLine(context, stringBuilder, "SafeDrop", (object)this.FormatCurrency(shift.SafeDropTotal, currency, context, (string)null).Result);
                this.AppendReportLine(context, stringBuilder, "Counted", (object)this.FormatCurrency(shift.DeclareTenderAmountTotal, currency, context, (string)null).Result);
                bool flag1 = shift.OverShortTotal < Decimal.Zero;
                this.AppendReportLine(context, stringBuilder, flag1 ? "Short" : "Over", (object)this.FormatCurrency(flag1 ? Decimal.Negate(shift.OverShortTotal) : shift.OverShortTotal, currency, context, (string)null).Result);
                stringBuilder.AppendLine(this.SingleLine);

                if (shift.AccountLines.Count > 0)
                {
                    this.AppendReportLine(context, stringBuilder, "IncomeExpense");
                    foreach (ShiftAccountLine shiftAccountLine in (IEnumerable<ShiftAccountLine>)shift.AccountLines.OrderBy<ShiftAccountLine, IncomeExpenseAccountType>((Func<ShiftAccountLine, IncomeExpenseAccountType>)(a => a.AccountType)))
                    {
                        string empty = string.Empty;
                        string textId;
                        switch (shiftAccountLine.AccountType)
                        {
                            case IncomeExpenseAccountType.Income:
                                textId = "Income";
                                break;
                            case IncomeExpenseAccountType.Expense:
                                textId = "Expense";
                                break;
                            default:
                                throw new NotSupportedException(string.Format("Unsupported account Type '{0}'.", (object)shiftAccountLine.AccountType));
                        }
                        string localizedString = this.GetLocalizedString(textId, context);
                        this.AppendReportLine(context, stringBuilder, string.Format("{0} [{1}]", (object)shiftAccountLine.AccountNumber, (object)localizedString), (object)this.FormatCurrency(shiftAccountLine.Amount, currency, context, (string)null).Result);
                    }
                    stringBuilder.AppendLine();
                }
                switch (receiptType)
                {
                    case ReceiptType.XReport:
                        if (!deviceConfiguration.PrintTenderDetailsOnXReport)
                            break;
                        goto case ReceiptType.ZReport;
                    case ReceiptType.ZReport:
                        if (shift.TenderLines.Count > 0)
                        {
                            this.AppendReportLine(context, stringBuilder, "Tenders");
                            using (IEnumerator<ShiftTenderLine> enumerator = shift.TenderLines.OrderBy<ShiftTenderLine, string>((Func<ShiftTenderLine, string>)(t => t.TenderTypeName)).GetEnumerator())
                            {
                                while (enumerator.MoveNext())
                                {
                                    ShiftTenderLine current = enumerator.Current;
                                    if (current.AddToTenderAmountOfTenderCurrency != Decimal.Zero || current.ShiftAmountOfTenderCurrency != Decimal.Zero || (current.TotalRemovedFromTenderAmountOfTenderCurrency != Decimal.Zero || current.DeclareTenderAmountOfTenderCurrency != Decimal.Zero) || (current.OverShortAmountOfTenderCurrency != Decimal.Zero || current.Count != 0))
                                    {
                                        string str = current.TenderTypeName;
                                        if (currency != current.TenderCurrency)
                                            str = string.Format("{0} ({1})", (object)current.TenderTypeName, (object)current.TenderCurrency);
                                        string localizedString1 = this.GetLocalizedString("Added", context);
                                        string localizedString2 = this.GetLocalizedString("Collected", context);
                                        string localizedString3 = this.GetLocalizedString("Removed", context);
                                        this.AppendReportLine(context, stringBuilder, string.Format("{0} [{1}]", (object)str, (object)localizedString1), (object)this.FormatCurrency(current.AddToTenderAmountOfTenderCurrency, current.TenderCurrency, context, (string)null).Result);
                                        this.AppendReportLine(context, stringBuilder, string.Format("{0} [{1}]", (object)str, (object)localizedString2), (object)this.FormatCurrency(current.ShiftAmountOfTenderCurrency, current.TenderCurrency, context, (string)null).Result);
                                        this.AppendReportLine(context, stringBuilder, string.Format("{0} [{1}]", (object)str, (object)localizedString3), (object)this.FormatCurrency(current.TotalRemovedFromTenderAmountOfTenderCurrency, current.TenderCurrency, context, (string)null).Result);
                                        if (current.CountingRequired)
                                        {
                                            string localizedString4 = this.GetLocalizedString("Counted", context);
                                            string localizedString5 = this.GetLocalizedString("Short", context);
                                            string localizedString6 = this.GetLocalizedString("Over", context);
                                            this.AppendReportLine(context, stringBuilder, string.Format("{0} [{1}]", (object)str, (object)localizedString4), (object)this.FormatCurrency(current.DeclareTenderAmountOfTenderCurrency, current.TenderCurrency, context, (string)null).Result);
                                            bool flag2 = current.OverShortAmountOfTenderCurrency < Decimal.Zero;
                                            this.AppendReportLine(context, stringBuilder, string.Format("{0} [{1}]", (object)str, flag2 ? (object)localizedString5 : (object)localizedString6), (object)this.FormatCurrency(flag2 ? Decimal.Negate(current.OverShortAmountOfTenderCurrency) : current.OverShortAmountOfTenderCurrency, current.TenderCurrency, context, (string)null).Result);
                                        }
                                        string localizedString7 = this.GetLocalizedString("Transactions", context);
                                        this.AppendReportLine(context, stringBuilder, string.Format("{0} [{1}]", (object)str, (object)localizedString7), (object)current.Count);
                                        stringBuilder.AppendLine();
                                    }
                                }
                                break;
                            }
                        }
                        else
                            break;
                }
                stringBuilder.AppendLine();
                stringBuilder.AppendLine();
                stringBuilder.AppendLine();
                receipt.Body = stringBuilder.ToString();
                body = receipt.Body;
                receipt.Width = 55;
                this.PopulateHardCodedReceiptData(receipt, receiptType, string.Empty, string.Empty, hardwareProfileId, context);
                XReadingData.HEADER = receipt.Header;
                XReadingData.BODY = receipt.Body;
                return receipt;
            }

            #region Formatter Helper
            struct ParseResult
            {
                public string ReceiptFieldName;
                public string Result;
                public bool IsValueZeroCurrency;
                public bool OmitFromReceipt;

                public ParseResult(
                  string result,
                  bool isValueZeroCurrency,
                  string receiptFieldName = null,
                  bool omitFromReceipt = false)
                {
                    this.Result = result;
                    this.IsValueZeroCurrency = isValueZeroCurrency;
                    this.ReceiptFieldName = receiptFieldName;
                    this.OmitFromReceipt = omitFromReceipt;
                }
            }

            private ParseResult FormatCurrency(Decimal value, string currencyCode, RequestContext context, string receiptFieldName = null)
            {
                string currencySymbol = string.Empty;
                int currencyDecimals = 0;
                if (!string.IsNullOrWhiteSpace(currencyCode))
                {
                    GetCurrenciesDataRequest currenciesDataRequest = new GetCurrenciesDataRequest(currencyCode, QueryResultSettings.SingleRecord);
                    Currency currency = context.Runtime.Execute<EntityDataServiceResponse<Currency>>((Request)currenciesDataRequest, context).PagedEntityCollection.FirstOrDefault<Currency>();
                    currencySymbol = currency.CurrencySymbol;
                    currencyDecimals = (int)currency.NumberOfDecimals;
                }
                GetFormattedCurrencyServiceRequest currencyServiceRequest = new GetFormattedCurrencyServiceRequest(value, currencySymbol, currencyDecimals);
                return new ParseResult(context.Execute<GetFormattedContentServiceResponse>((Request)currencyServiceRequest).FormattedValue, value == Decimal.Zero, receiptFieldName, false);
            }

            private bool IsValidDateTime(DateTimeOffset? dateTime)
            {
                return dateTime.HasValue && dateTime.Value.UtcDateTime.Year > 1900;
            }

            private string GetLanguage(ChannelConfiguration channelConfig)
            {
                ThrowIf.Null<ChannelConfiguration>(channelConfig, nameof(channelConfig));
                return !string.IsNullOrEmpty(channelConfig.DefaultLanguageId) ? channelConfig.DefaultLanguageId : channelConfig.CompanyLanguageId;
            }

            private string GetLocalizedString(string textId, RequestContext context)
            {
                if (string.IsNullOrEmpty(textId))
                    return string.Empty;
                string textId1 = "Microsoft_Dynamics_Commerce_Runtime_Receipt_" + textId;
                string language = this.GetLanguage(context.GetChannelConfiguration());
                string localizedString = this.GetLocalizedString(language, textId1, context);
                return string.IsNullOrEmpty(localizedString) ? textId : localizedString;
            }

            private string GetLocalizedString(string cultureName, string textId, RequestContext requestContext)
            {
                return this.GetLocalizedString(cultureName, textId, requestContext, (object[])null);
            }

            public string GetLocalizedString(string cultureName, string textId, params object[] args)
            {
                return this.GetLocalizedString(cultureName, textId, (RequestContext)null, args);
            }

            public string GetLocalizedString(string cultureName, string textId, RequestContext requestContext, params object[] args)
            {
                string str = (string)null;
                if (requestContext != null)
                {
                    try
                    {
                        str = this.GetOverriddenLocalizedString(cultureName, textId, requestContext);
                    }
                    catch
                    {
                    }
                }
                if (str == null)
                {
                    try
                    {
                        str = this.StringLocalizerTranslate(cultureName, textId, args);
                    }
                    catch
                    {
                    }
                }
                return str ?? string.Empty;
            }

            public string StringLocalizerTranslate(string cultureName, string textId, params object[] args)
            {
                if (string.IsNullOrWhiteSpace(textId))
                    return string.Empty;
                string empty = string.Empty;
                try
                {
                    CultureInfo culture;
                    try
                    {
                        culture = string.IsNullOrWhiteSpace(cultureName) ? CultureInfo.CurrentCulture : new CultureInfo(cultureName);
                    }
                    catch (CultureNotFoundException ex)
                    {
                        culture = CultureInfo.CurrentCulture;
                    }
                    string format = "";// string.emthis.resourceManager.GetString(textId, culture); //Need review
                    return args == null ? format : string.Format((IFormatProvider)culture, format, args);
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
            private string GetOverriddenLocalizedString(string cultureName, string textId, RequestContext requestContext)
            {
                if (this.localizedTexts == null)
                    this.InitializeLocalizedTextDictionary(cultureName, requestContext);
                string key = string.Format(this.localizedTextKeyFormat, (object)cultureName.ToLower(CultureInfo.InvariantCulture), (object)textId.ToLower(CultureInfo.InvariantCulture));
                LocalizedText localizedText1 = (LocalizedText)null;
                if (this.localizedTexts.TryGetValue(key, out localizedText1))
                    return localizedText1.Text;
                GetLocalizedTextsDataRequest textsDataRequest = new GetLocalizedTextsDataRequest(cultureName, textId, QueryResultSettings.SingleRecord);
                PagedResult<LocalizedText> entityCollection = requestContext.Execute<EntityDataServiceResponse<LocalizedText>>((Request)textsDataRequest).PagedEntityCollection;
                if (entityCollection.IsNullOrEmpty<LocalizedText>())
                    return (string)null;
                LocalizedText localizedText2 = entityCollection.FirstOrDefault<LocalizedText>();
                this.localizedTexts[key] = localizedText2;
                return localizedText2.Text;
            }

            private string FormatDate(DateTimeOffset? date, RequestContext context)
            {
                string str;
                if (!this.IsValidDateTime(date))
                {
                    str = this.GetLocalizedString("NotApplicable", context);
                }
                else
                {
                    GetFormattedDateServiceRequest dateServiceRequest = new GetFormattedDateServiceRequest(date.Value);
                    str = context.Execute<GetFormattedContentServiceResponse>((Request)dateServiceRequest).FormattedValue;
                }
                return str;
            }

            private string FormatTime(
              DateTimeOffset? time,
              TimeFormattingType timeFormattingType,
              RequestContext context)
            {
                if (!this.IsValidDateTime(time))
                    return this.GetLocalizedString("NotApplicable", context);
                GetFormattedTimeServiceRequest timeServiceRequest = new GetFormattedTimeServiceRequest(time.Value, timeFormattingType);
                return context.Execute<GetFormattedContentServiceResponse>((Request)timeServiceRequest).FormattedValue;
            }

            private void AppendReportLine(RequestContext context, StringBuilder receiptString, string titleResourceId)
            {
                titleResourceId = this.GetLocalizedString(titleResourceId, context);
                receiptString.AppendLine(titleResourceId);
                receiptString.AppendLine(this.SingleLine);
            }

            private string FormatHeaderLineWithWrapping(RequestContext context, string titleResourceId, string value, bool firstPart)
            {
                value = this.WrapHeaderValueString(value, firstPart);
                return this.FormatHeaderLine(context, titleResourceId, value, firstPart);
            }

            private string WrapHeaderValueString(string headerValue, bool firstPart)
            {
                int titleLength = firstPart ? 15 : 11;
                int num = 55 - titleLength - 2;
                string str1 = headerValue ?? string.Empty;
                string empty = string.Empty;
                int lineNumber = 0;
                while (str1.Length > num)
                {
                    string str2 = str1.Substring(0, num) + Environment.NewLine;
                    empty += this.FormatWrappedFieldValue(str2, titleLength, lineNumber);
                    str1 = str1.Substring(num);
                    ++lineNumber;
                }
                return empty + this.FormatWrappedFieldValue(str1, titleLength, lineNumber);
            }

            private string FormatWrappedFieldValue(string value, int titleLength, int lineNumber)
            {
                return (lineNumber > 0 ? string.Empty.PadLeft(titleLength + 2) : " ") + value;
            }

            private string FormatHeaderLine(RequestContext context, string titleResourceId, string value, bool firstPart)
            {
                string localizedString = this.GetLocalizedString(titleResourceId, context);
                int fullWidthCharsCount = this.GetFullWidthCharsCount(localizedString);
                return firstPart ? string.Format((IFormatProvider)this.GetCultureInfo(context.GetChannelConfiguration()), "{0}:{1}", (object)localizedString.PadRight(15 - fullWidthCharsCount, '.'), (object)value.PadLeft(13)) + "  " : string.Format((IFormatProvider)this.GetCultureInfo(context.GetChannelConfiguration()), "{0}:{1}", (object)localizedString.PadRight(11 - fullWidthCharsCount, '.'), (object)value.PadLeft(12));
            }

            private CultureInfo GetCultureInfo(ChannelConfiguration channelConfig)
            {
                return new CultureInfo(this.GetLanguage(channelConfig));
            }
            private int GetFullWidthCharsCount(string item)
            {
                int num = 0;
                foreach (char ch in item)
                {
                    if (ch >= '一' && ch <= '鿌')
                        ++num;
                }
                return num;
            }

            private void AppendReportLine(RequestContext context, StringBuilder receiptString, string titleResourceId, object value)
            {
                titleResourceId = this.GetLocalizedString(titleResourceId, context);
                int fullWidthCharsCount = this.GetFullWidthCharsCount(titleResourceId);
                char paddingChar = fullWidthCharsCount > 0 ? 'ᅠ' : ' ';
                receiptString.AppendLine(string.Format((IFormatProvider)this.GetCultureInfo(context.GetChannelConfiguration()), "{0}:{1}", (object)titleResourceId, (object)value.ToString().PadLeft(55 - titleResourceId.Length - 2 - fullWidthCharsCount, paddingChar)));
            }

            private string FormatNumber(Decimal number, RequestContext context)
            {
                GetFormattedNumberServiceRequest numberServiceRequest = new GetFormattedNumberServiceRequest(number);
                return context.Execute<GetFormattedContentServiceResponse>((Request)numberServiceRequest).FormattedValue;
            }

            private string FormatPercentage(Decimal percentage, RequestContext context)
            {
                GetFormattedPercentageServiceRequest percentageServiceRequest = new GetFormattedPercentageServiceRequest(percentage);
                return context.Execute<GetFormattedContentServiceResponse>((Request)percentageServiceRequest).FormattedValue;
            }

            private TaxCodeInterval GetTaxCodeInterval(RequestContext context, string taxCode, DateTimeOffset transactionDate)
            {
                GetTaxCodeIntervalDataRequest intervalDataRequest = new GetTaxCodeIntervalDataRequest(taxCode, transactionDate);
                return context.Execute<SingleEntityDataServiceResponse<TaxCodeInterval>>((Request)intervalDataRequest).Entity;
            }

            private void PopulateHardCodedReceiptData(Receipt receipt, ReceiptType receiptType, string transactionId, string receiptId, string hardwareProfileId, RequestContext context)
            {
                receipt.ReceiptTitle = receiptType.ToString();
                receipt.TransactionId = transactionId;
                receipt.ReceiptId = receiptId;
                receipt.ReceiptType = receiptType;
                ReadOnlyCollection<Printer> forHardcodeReceipt = this.GetPrinterForHardcodeReceipt(context, hardwareProfileId, receiptType);
                if (!forHardcodeReceipt.IsNullOrEmpty<Printer>())
                    receipt.Printers = (ICollection<Printer>)new Printer[1]
                    {
                        forHardcodeReceipt.First<Printer>()
                    };
                else
                    receipt.Printers = (ICollection<Printer>)forHardcodeReceipt;
                this.ChangePrinterBehavior(receipt.Printers, receiptType);
            }

            private ReadOnlyCollection<Printer> GetPrinterForHardcodeReceipt(RequestContext context, string hardwareProfileId, ReceiptType receiptType)
            {
                Terminal terminal = context.GetTerminal();
                if (string.IsNullOrEmpty(hardwareProfileId))
                    hardwareProfileId = terminal.HardwareProfile;
                GetHardwareProfileDataRequest profileDataRequest = new GetHardwareProfileDataRequest(hardwareProfileId, QueryResultSettings.SingleRecord);
                HardwareProfile entity = context.Runtime.Execute<SingleEntityDataServiceResponse<HardwareProfile>>((Request)profileDataRequest, context).Entity;
                if (entity != null && entity.Printers != null && entity.Printers.Any<HardwareProfilePrinter>())
                {
                    HardwareProfilePrinter hardwareProfilePrinter = entity.Printers.FirstOrDefault<HardwareProfilePrinter>((Func<HardwareProfilePrinter, bool>)(printer => (uint)printer.DeviceType > 0U));
                    if (hardwareProfilePrinter != null)
                        return new List<Printer>()
                {
                    new Printer()
                    {
                      ReceiptType = receiptType,
                      PrintBehavior = PrintBehavior.Always,
                      Terminal = terminal == null ? 0L : terminal.RecordId,
                      HardwareProfileId = hardwareProfileId,
                      Name = hardwareProfilePrinter.DeviceName,
                      PrinterType = (int) hardwareProfilePrinter.DeviceType
                    }
                }.AsReadOnly();
                }
                return new List<Printer>().AsReadOnly();
            }

            private void ChangePrinterBehavior(ICollection<Printer> printers, ReceiptType receiptType)
            {
                foreach (Printer printer in (IEnumerable<Printer>)printers)
                {
                    printer.PrintBehavior = PrintBehavior.Always;
                    printer.ReceiptLayoutId = (string)null;
                    printer.ReceiptType = receiptType;
                }
            }

            private void InitializeLocalizedTextDictionary(string cultureName, RequestContext requestContext)
            {
                GetLocalizedTextsDataRequest textsDataRequest = new GetLocalizedTextsDataRequest(cultureName, (string)null, QueryResultSettings.AllRecords);
                PagedResult<LocalizedText> entityCollection = requestContext.Execute<EntityDataServiceResponse<LocalizedText>>((Request)textsDataRequest).PagedEntityCollection;
                if (!entityCollection.IsNullOrEmpty<LocalizedText>() && !entityCollection.Results.IsNullOrEmpty<LocalizedText>())
                {
                    this.localizedTexts = new Dictionary<string, LocalizedText>(entityCollection.Results.Count);
                    foreach (LocalizedText localizedText in entityCollection)
                    {
                        string index = string.Format(this.localizedTextKeyFormat, (object)localizedText.LanguageId.ToLower(CultureInfo.InvariantCulture), (object)localizedText.TextId.ToLower(CultureInfo.InvariantCulture));
                        this.localizedTexts[index] = localizedText;
                    }
                }
                else
                    this.localizedTexts = new Dictionary<string, LocalizedText>();
            }
            #endregion

        }
    }
}