Noted code print X Z Report LAWSON - Microsoft Dynamics 365 Vietnam

Microsoft Dynamics 365 Vietnam

Song Nghia - Microsoft Dynamics 365 Vietnam

Breaking

Monday, April 13, 2020

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

        }
    }
}