Thứ Tư, 8 tháng 12, 2021

Create Retail Transaction by X++

Create Retail Transaction by X++

Nghia Song - Techincal Lead


 /// <summary>

/// AmicisLotteryPATMachineDeclarationPost

/// </summary>

public class AmicisLotteryPATMachineDeclarationPost

{

    AmicisLotteryDeclarationId   declarationId;

    RetailPosBatchID             shiftId;

    /// <summary>

    /// Post

    /// </summary>

    /// <param name = "_declarationId">_declarationId</param>

    /// <param name = "_shiftId">_shiftId</param>

    public static void Post(AmicisLotteryDeclarationId _declarationId, RetailPosBatchID  _shiftId)

    {

        AmicisLotteryPATMachineDeclarationPost patMachineDeclarationPost = new AmicisLotteryPATMachineDeclarationPost();

        patMachineDeclarationPost.parmDeclarationId(_declarationId);

        patMachineDeclarationPost.parmShiftId(_shiftId);

        patMachineDeclarationPost.createSaleTransaction();


    }


    /// <summary>

    /// parmDeclarationId

    /// </summary>

    /// <param name = "_declarationId">_declarationId</param>

    /// <returns>AmicisLotteryDeclarationId</returns>

    public AmicisLotteryDeclarationId parmDeclarationId(AmicisLotteryDeclarationId _declarationId = declarationId)

    {

        declarationId = _declarationId;


        return declarationId;

    }


    /// <summary>

    /// parmShiftId

    /// </summary>

    /// <param name = "_shiftId">_shiftId</param>

    /// <returns>RetailPosBatchID</returns>

    public RetailPosBatchID parmShiftId(RetailPosBatchID _shiftId = shiftId)

    {

        shiftId = _shiftId;


        return shiftId;

    }


    /// <summary>

    /// createSaleTransaction

    /// </summary>

    public void createSaleTransaction()

    {

        RetailTransactionTable    retailTransactionTableForSale, retailTransactionTableForSafeDrop;

        retailTransactionTableForSale = this.createRetailTransactionTableForSale();

        LineNumber  currentLineNum = 0;

        if(retailTransactionTableForSale)

        {

            currentLineNum = this.createRetailTransactionSalesTransForSale(retailTransactionTableForSale);

            this.createRetailTransactionSalesTransForCashed(retailTransactionTableForSale, currentLineNum);

            this.createRetailTransactionTaxTransForSale(retailTransactionTableForSale);

            this.createRetailTransactionPaymentTransForSales(retailTransactionTableForSale);

            this.updateRetailTransactionTableForSale(retailTransactionTableForSale);

        }

        

        retailTransactionTableForSafeDrop = this.createRetailTransactionTableForSafeDrop();

        if(retailTransactionTableForSafeDrop)

        {

            this.createRetailTransactionSafeTenderTransForSafeDrop();

        }


    }


    /// <summary>

    /// createRetailTransactionTableForSale

    /// </summary>

    /// <returns>RetailTransactionTable</returns>

    public RetailTransactionTable createRetailTransactionTableForSale()

    {

        RetailTransactionTable              retailTransactionTable;

        RetailTransactionId                 retailTransactionId;

        RetailStoreTable                    retailStoreTable;

        RetailChannelTable                  retailChannelTable;

        AmicisLotteryPATDeclarationHeader   patDeclarationHeader    =   AmicisLotteryPATDeclarationHeader::find(declarationId);


        retailStoreTable    =   RetailStoreTable::find(patDeclarationHeader.Store);

        retailChannelTable  =   RetailChannelTable::findByRecId(retailStoreTable.RecId);

        retailTransactionTable.clear();

        //Key and no logic

        retailTransactionTable.terminal         =   patDeclarationHeader.Register;

        retailTransactionTable.BatchID          =   shiftId;

        retailTransactionTable.BatchTerminalId  =   patDeclarationHeader.Register;

        retailTransactionTable.businessDate     =   patDeclarationHeader.DeclarationDate;

        retailTransactionTable.Channel          =   retailStoreTable.RecId;

        retailTransactionTable.CreatedOffline   =   NoYes::No;

        retailTransactionTable.createdOnPosTerminal =   patDeclarationHeader.Register;

        retailTransactionTable.currency         =   retailStoreTable.Currency;

        retailTransactionTable.entryStatus      =   RetailEntryStatus::None;

        retailTransactionTable.exchRate         =   100;

        retailTransactionTable.InventLocationId =   retailStoreTable.inventLocation;

        retailTransactionTable.ReceiptDateRequested =  patDeclarationHeader.DeclarationDate;

        retailTransactionTable.saleIsReturnSale =   NoYes::No;

        retailTransactionTable.ShippingDateRequested =  patDeclarationHeader.DeclarationDate;

        retailTransactionTable.staff            =    HcmWorker::find(patDeclarationHeader.StaffId).PersonnelNumber;

        retailTransactionTable.store            =   patDeclarationHeader.Store;

        retailTransactionTable.transactionId    =   patDeclarationHeader.DeclarationId;

        retailTransactionTable.receiptId        =   patDeclarationHeader.DeclarationId;

        retailTransactionTable.transTime        =   patDeclarationHeader.DeclarationTime;

        retailTransactionTable.transDate        =   patDeclarationHeader.DeclarationDate;

        retailTransactionTable.type             =   RetailTransactionType::Sales;

        retailTransactionTable.IsTaxIncludedInPrice =   RetailChannelTable::findByRecId(retailStoreTable.RecId).PriceIncludesSalesTax;

        retailTransactionTable.TransactionOrderType =   RetailTransactionOrderTypes::SalesOrder;

        retailTransactionTable.BeginDateTime    =   patDeclarationHeader.DeclarationDate;

        

        //Different field POS Integration

        retailTransactionTable.custAccount      = '';

        

        retailTransactionTable.insert();

        return retailTransactionTable;


    }


    /// <summary>

    /// retailTransactionTable

    /// </summary>

    /// <param name = "retailTransactionTable">retailTransactionTable</param>

    public void updateRetailTransactionTableForSale(RetailTransactionTable retailTransactionTable)

    {

        RetailTransactionTable retailTransactionTableUpdate;

        RetailTransactionSalesTrans         retailTransactionSalesTrans, retailTransactionSalestransCount, retailTransactionSalestransNoOfQty;

        retailTransactionTableUpdate = RetailTransactionTable::find(retailTransactionTable.transactionId, retailTransactionTable.store, retailTransactionTable.terminal);


        if(retailTransactionTableUpdate)

        {

            select count(RecId) from retailTransactionSalestransCount

                where retailTransactionSalestransCount.transactionId == retailTransactionTable.transactionId

                   && retailTransactionSalestransCount.store         == retailTransactionTable.store

                   && retailTransactionSalestransCount.terminalId    == retailTransactionTable.terminal;


            select sum(netAmount), sum(netPrice), sum(netAmountInclTax), sum(taxAmount) from retailTransactionSalesTrans

                where retailTransactionSalesTrans.transactionId == retailTransactionTableUpdate.transactionId &&

                retailTransactionSalesTrans.terminalId          == retailTransactionTableUpdate.terminal &&

                retailTransactionSalesTrans.store               == retailTransactionTableUpdate.store;


            retailTransactionTableUpdate.selectForUpdate(true);

            retailTransactionTableUpdate.grossAmount      =   retailTransactionSalesTrans.netAmount + retailTransactionSalesTrans.taxAmount;

            retailTransactionTableUpdate.netAmount        =   retailTransactionSalesTrans.netAmount;

            retailTransactionTableUpdate.netPrice         =   retailTransactionSalesTrans.netPrice;

            retailTransactionTableUpdate.numberOfItemLines    =   retailTransactionSalestransCount.RecId;

            retailTransactionTableUpdate.paymentAmount    =   (-1) *  retailTransactionTableUpdate.grossAmount ;

            //retailTransactionTableUpdate.discAmountWithoutTax =   0;

            

            retailTransactionTableUpdate.TaxCalculationType   =   TaxCalculationType::Regular;


            //Different field POS Integration

            retailTransactionTableUpdate.amountToAccount  =  -1 * retailTransactionTable.grossAmount;

            retailTransactionTableUpdate.numberOfPaymentLines = 0;


            while select qty from retailTransactionSalestransNoOfQty

                where retailTransactionSalestransNoOfQty.transactionId     == retailTransactionTable.transactionId

                   && retailTransactionSalestransNoOfQty.store             == retailTransactionTable.store

                   && retailTransactionSalestransNoOfQty.terminalId        == retailTransactionTable.terminal

                   && retailTransactionSalestransNoOfQty.transactionStatus != RetailEntryStatus::Voided

            {

                retailTransactionTableUpdate.numberOfItems     += abs(retailTransactionSalestransNoOfQty.qty); //validation required abs qty

            }

            retailTransactionTableUpdate.update();

        }

    }


    /// <summary>

    /// createLotterySalesTicketOnlineGame

    /// </summary>

    /// <param name = "PATDeclarationHeader">PATDeclarationHeader</param>

    /// <param name = "PATDeclarationLotterySales">PATDeclarationLotterySales</param>

    /// <param name = "retailStoreTable">retailStoreTable</param>

    /// <param name = "retailTransactionTable">retailTransactionTable</param>

    /// <param name = "lineNumber">lineNumber</param>

    /// <returns></returns>

    public LineNum createLotterySalesTicketOnlineGame(  AmicisLotteryPATDeclarationHeader   PATDeclarationHeader, 

                                                        AmicisLotteryPATDeclarationLotterySales PATDeclarationLotterySales, 

                                                        RetailStoreTable   retailStoreTable, 

                                                        RetailTransactionTable retailTransactionTable, 

                                                        LineNumber lineNumber)

    {

        RetailTransactionSalesTrans             retailTransactionSalesTrans;


        lineNumber++;

        retailTransactionSalesTrans.clear();

        retailTransactionSalesTrans.Channel    = retailStoreTable.RecId;

        retailTransactionSalesTrans.DefaultDimension    =   retailStoreTable.DefaultDimension;

        retailTransactionSalesTrans.terminalId = PATDeclarationHeader.Register;

        retailTransactionSalesTrans.transactionId = retailTransactionTable.TransactionId;

        retailTransactionSalesTrans.lineNum = lineNumber;

        retailTransactionSalesTrans.store = retailTransactionTable.store;

        retailTransactionSalesTrans.businessDate        = retailTransactionTable.businessDate;

        retailTransactionSalesTrans.currency = retailTransactionTable.Currency;

        retailTransactionSalesTrans.itemId              = PATDeclarationLotterySales.Product;

        retailTransactionSalesTrans.price               = PATDeclarationLotterySales.Qty ? PATDeclarationLotterySales.Amount/ PATDeclarationLotterySales.Qty : 0;

        retailTransactionSalesTrans.originalPrice       = retailTransactionSalesTrans.price;

        //Note: Qty, net price, net amount, net amount incl tax is negative

        retailTransactionSalesTrans.qty                 = (-1) * PATDeclarationLotterySales.Qty;

        retailTransactionSalesTrans.unit                = InventTable::find(PATDeclarationLotterySales.Product).salesUnitId();

        retailTransactionSalesTrans.netAmountInclTax    = (-1) * PATDeclarationLotterySales.Amount;

        //Net Amount and net price will calculate after create tax 

        //retailTransactionSalesTrans.netAmount           = RetailTransactionSalesTrans.netAmountInclTax;

        //retailTransactionSalesTrans.netPrice            = (-1) * PATDeclarationLotterySales.Amount;

        retailTransactionSalesTrans.receiptId           = retailTransactionTable.TransactionId;

        retailTransactionSalesTrans.ReceiptDateRequested    =   retailTransactionTable.ReceiptDateRequested;

        retailTransactionSalesTrans.ShippingDateRequested   =   retailTransactionTable.ReceiptDateRequested;

        retailTransactionSalesTrans.transDate           = retailTransactionTable.transDate;

        retailTransactionSalesTrans.transTime           = retailTransactionTable.transTime;

        retailTransactionSalesTrans.TaxItemGroup =  InventTableModule::find(PATDeclarationLotterySales.Product, ModuleInventPurchSales::Sales).TaxItemGroupId;

        retailTransactionSalesTrans.taxGroup =  retailStoreTable.taxGroup;

        retailTransactionSalesTrans.transactionStatus       =   RetailEntryStatus::None;

        retailTransactionSalesTrans.InventLocationId        =   retailStoreTable.inventLocation;

        retailTransactionSalesTrans.InventSiteId            =   InventLocation::find(retailTransactionSalesTrans.InventLocationId).InventSiteId;

        retailTransactionSalesTrans.staffId                 =   HcmWorker::find(PATDeclarationHeader.StaffId).PersonnelNumber;


        //Some fields need to check data

        //retailTransactionSalesTrans.barcode             =  '';

        retailTransactionSalesTrans.keyboardItemEntry   = NoYes::Yes;

        retailTransactionSalesTrans.itemIdScanned       = NoYes::No;

        //retailTransactionSalesTrans.variantId           = '';

        //retailTransactionSalesTrans.WarehouseLocation   =  retailTransactionTable;

        retailTransactionSalesTrans.insert();

        

        return lineNumber;

    }


    /// <summary>

    /// createLotterySalesTicketScratchGame

    /// </summary>

    /// <param name = "PATDeclarationHeader">PATDeclarationHeader</param>

    /// <param name = "PATDeclarationLotterySalesParam">PATDeclarationLotterySalesParam</param>

    /// <param name = "retailStoreTable">retailStoreTable</param>

    /// <param name = "retailTransactionTable">retailTransactionTable</param>

    /// <returns></returns>

    public LineNum createLotterySalesTicketScratchGame( AmicisLotteryPATDeclarationHeader   PATDeclarationHeader, 

                                                        AmicisLotteryPATDeclarationLotterySales PATDeclarationLotterySalesParam, 

                                                        RetailStoreTable   retailStoreTable, 

                                                        RetailTransactionTable retailTransactionTable)

    {

        AmicisLotteryPATInstantTicketSaleEntry  PATInstantTicketSaleEntry;

        RetailTransactionSalesTrans             retailTransactionSalesTrans;

        LineNumber                              lineNumber = 0;

        RetailStaffId                           staffId;


        staffId = HcmWorker::find(patDeclarationHeader.StaffId).PersonnelNumber;


        int loopQty;


        if(PATDeclarationLotterySalesParam.SalesEntryByGame)

        {

            while select PATInstantTicketSaleEntry

                    where PATInstantTicketSaleEntry.LotterySalesLineNum    == PATDeclarationLotterySalesParam.LineNum &&

                    PATInstantTicketSaleEntry.DeclarationId                == PATDeclarationLotterySalesParam.DeclarationId &&

                    PATInstantTicketSaleEntry.GameType                     == PATDeclarationLotterySalesParam.GameType &&

                    PATInstantTicketSaleEntry.SaleQty

            {

                for(loopQty = 1 ; loopQty <= PATInstantTicketSaleEntry.SaleQty; loopQty++)

                {

                    lineNumber++;

                    retailTransactionSalesTrans.clear();

                    retailTransactionSalesTrans.Channel    = retailStoreTable.RecId;

                    retailTransactionSalesTrans.DefaultDimension    =   retailStoreTable.DefaultDimension;

                    retailTransactionSalesTrans.terminalId = PATDeclarationHeader.Register;

                    retailTransactionSalesTrans.transactionId = retailTransactionTable.TransactionId;

                    retailTransactionSalesTrans.lineNum = lineNumber;

                    retailTransactionSalesTrans.store = retailTransactionTable.store;

                    retailTransactionSalesTrans.businessDate        = retailTransactionTable.businessDate;

                    retailTransactionSalesTrans.currency = retailTransactionTable.Currency;

                    retailTransactionSalesTrans.itemId              = PATInstantTicketSaleEntry.GameId;

                    retailTransactionSalesTrans.price               = AmicisLotteryUtility::getTradeAgreementPrice(PATInstantTicketSaleEntry.GameId, PATInstantTicketSaleEntry.UOM,VendTable::find( AmicisLotteryStoreVendors::findByStoreId(retailStoreTable.StoreNumber).VendAccount), ModuleInventPurchSales::Sales);

                    retailTransactionSalesTrans.originalPrice       = retailTransactionSalesTrans.price;

                    //Note: Qty, net price, net amount, net amount incl tax is negative

                    retailTransactionSalesTrans.qty                 = (-1);

                    retailTransactionSalesTrans.unit                = PATInstantTicketSaleEntry.UOM;

                    retailTransactionSalesTrans.netAmountInclTax    = (-1) * PATInstantTicketSaleEntry.TicketPrice;

                    //Net Amount and net price will calculate after create tax

                    //retailTransactionSalesTrans.netAmount           = ;

                    //retailTransactionSalesTrans.netPrice            = (-1) * PATInstantTicketSaleEntry.TicketPrice;

                    retailTransactionSalesTrans.receiptId           = retailTransactionTable.TransactionId;

                    retailTransactionSalesTrans.ReceiptDateRequested    =   retailTransactionTable.ReceiptDateRequested;

                    retailTransactionSalesTrans.ShippingDateRequested   =   retailTransactionTable.ReceiptDateRequested;

                    retailTransactionSalesTrans.transDate           = retailTransactionTable.transDate;

                    retailTransactionSalesTrans.transTime           = retailTransactionTable.transTime;

                    retailTransactionSalesTrans.TaxItemGroup =  InventTableModule::find(PATInstantTicketSaleEntry.GameId, ModuleInventPurchSales::Sales).TaxItemGroupId;

                    retailTransactionSalesTrans.taxGroup =  retailStoreTable.taxGroup;

                    retailTransactionSalesTrans.transactionStatus       =   RetailEntryStatus::None;

                    retailTransactionSalesTrans.InventLocationId        =   retailStoreTable.inventLocation;

                    retailTransactionSalesTrans.InventSiteId            =   InventLocation::find(retailTransactionSalesTrans.InventLocationId).InventSiteId;

                    retailTransactionSalesTrans.staffId                 =   staffId;


                    //Some fields need to check data

                    //retailTransactionSalesTrans.barcode             =  '';

                    retailTransactionSalesTrans.keyboardItemEntry   = NoYes::Yes;

                    retailTransactionSalesTrans.itemIdScanned       = NoYes::No;

                    //retailTransactionSalesTrans.variantId           = '';

                    //retailTransactionSalesTrans.WarehouseLocation   =  retailTransactionTable;

                    retailTransactionSalesTrans.insert();

                }

            }

        }

        else //get from total

        {

            for(loopQty = 1; loopQty <= PATDeclarationLotterySalesParam.Qty; loopQty++)

            {

                lineNumber++;

                retailTransactionSalesTrans.clear();

                retailTransactionSalesTrans.Channel    = retailStoreTable.RecId;

                retailTransactionSalesTrans.DefaultDimension    =   retailStoreTable.DefaultDimension;

                retailTransactionSalesTrans.terminalId = PATDeclarationHeader.Register;

                retailTransactionSalesTrans.transactionId = retailTransactionTable.TransactionId;

                retailTransactionSalesTrans.lineNum = lineNumber;

                retailTransactionSalesTrans.store = retailTransactionTable.store;

                retailTransactionSalesTrans.businessDate        = retailTransactionTable.businessDate;

                retailTransactionSalesTrans.currency = retailTransactionTable.Currency;

                retailTransactionSalesTrans.itemId              = PATDeclarationLotterySalesParam.Product;

                retailTransactionSalesTrans.price               = PATDeclarationLotterySalesParam.Qty ? PATDeclarationLotterySalesParam.Amount/ PATDeclarationLotterySalesParam.Qty : 0;

                retailTransactionSalesTrans.originalPrice       = retailTransactionSalesTrans.price;

                //Note: Qty, net price, net amount, net amount incl tax is negative

                retailTransactionSalesTrans.qty                 = (-1);

                retailTransactionSalesTrans.unit                = InventTable::find(PATDeclarationLotterySalesParam.Product).salesUnitId();

                retailTransactionSalesTrans.netAmountInclTax    = (-1) * retailTransactionSalesTrans.price;

                //Net Amount and net price will calculate after create tax

                //retailTransactionSalesTrans.netAmount           = retailTransactionSalesTrans.netAmountInclTax;

                //retailTransactionSalesTrans.netPrice            = (-1) * retailTransactionSalesTrans.price;

                retailTransactionSalesTrans.receiptId           = retailTransactionTable.TransactionId;

                retailTransactionSalesTrans.ReceiptDateRequested    =   retailTransactionTable.ReceiptDateRequested;

                retailTransactionSalesTrans.ShippingDateRequested   =   retailTransactionTable.ReceiptDateRequested;

                retailTransactionSalesTrans.transDate           = retailTransactionTable.transDate;

                retailTransactionSalesTrans.transTime           = retailTransactionTable.transTime;

                retailTransactionSalesTrans.TaxItemGroup =  InventTableModule::find(PATDeclarationLotterySalesParam.Product, ModuleInventPurchSales::Sales).TaxItemGroupId;

                retailTransactionSalesTrans.taxGroup =  retailStoreTable.taxGroup;

                retailTransactionSalesTrans.transactionStatus       =   RetailEntryStatus::None;

                retailTransactionSalesTrans.InventLocationId        =   retailStoreTable.inventLocation;

                retailTransactionSalesTrans.InventSiteId            =   InventLocation::find(retailTransactionSalesTrans.InventLocationId).InventSiteId;

                retailTransactionSalesTrans.staffId                 =   staffId;


                //Some fields need to check data

                //retailTransactionSalesTrans.barcode             =  '';

                retailTransactionSalesTrans.keyboardItemEntry   = NoYes::Yes;

                retailTransactionSalesTrans.itemIdScanned       = NoYes::No;

                //retailTransactionSalesTrans.variantId           = '';

                //retailTransactionSalesTrans.WarehouseLocation   =  retailTransactionTable;

                retailTransactionSalesTrans.insert();

            }

                

        }

        return lineNumber;

    }


    /// <summary>

    /// createRetailTransactionSalesTransForSale

    /// </summary>

    /// <param name = "retailTransactionTable">retailTransactionTable</param>

    /// <returns></returns>

    public LineNumber createRetailTransactionSalesTransForSale(RetailTransactionTable retailTransactionTable)

    {

        RetailStoreTable                    retailStoreTable;

        AmicisLotteryPATDeclarationLotterySales PATDeclarationLotterySales;

        LineNumber                          lineNumber = 0;


        AmicisLotteryPATDeclarationHeader   PATDeclarationHeader;

        PATDeclarationHeader =   AmicisLotteryPATDeclarationHeader::find(declarationId);

        retailStoreTable     =   RetailStoreTable::find(PATDeclarationHeader.Store);



        while select PATDeclarationLotterySales

            where  PATDeclarationLotterySales.DeclarationId == PATDeclarationHeader.DeclarationId &&

            PATDeclarationLotterySales.GameType             == AmicisLotterySubTypes::ScratchGame &&

            PATDeclarationLotterySales.ProfileId            == PATDeclarationHeader.DeclarationProfile

        {

            lineNumber = this.createLotterySalesTicketScratchGame(PATDeclarationHeader, PATDeclarationLotterySales, retailStoreTable, retailTransactionTable);

        }


        while select PATDeclarationLotterySales

            where  PATDeclarationLotterySales.DeclarationId == PATDeclarationHeader.DeclarationId &&

            PATDeclarationLotterySales.GameType             == AmicisLotterySubTypes::OnlineGame &&

            PATDeclarationLotterySales.ProfileId            == PATDeclarationHeader.DeclarationProfile &&

            PATDeclarationLotterySales.Qty

        {

            lineNumber++;

            lineNumber = this.createLotterySalesTicketOnlineGame(PATDeclarationHeader, PATDeclarationLotterySales, retailStoreTable, retailTransactionTable, lineNumber);

        }

        return lineNumber;

    }


    /// <summary>

    /// createRetailTransactionSalesTransForCashed

    /// </summary>

    /// <param name = "retailTransactionTable">retailTransactionTable</param>

    /// <param name = "lineNumber">lineNumber</param>

    public void createRetailTransactionSalesTransForCashed(RetailTransactionTable retailTransactionTable, LineNumber lineNumber)

    {

        RetailTransactionSalesTrans         retailTransactionSalesTrans;

        RecordInsertList                    retailTransactionSalesTransList = new RecordInsertList(tableNum(RetailTransactionSalesTrans));

        RetailStoreTable                    retailStoreTable;

        AmicisLotteryPATDeclarationLotteryPayouts PATDeclarationLotteryPayouts;

        AmicisLotteryPATDeclarationHeader   PATDeclarationHeader    =   AmicisLotteryPATDeclarationHeader::find(declarationId);

        retailStoreTable    =   RetailStoreTable::find(PATDeclarationHeader.Store);



       

        while select PATDeclarationLotteryPayouts

            where  PATDeclarationLotteryPayouts.DeclarationId == PATDeclarationHeader.DeclarationId &&

            PATDeclarationLotteryPayouts.GameType             == AmicisLotterySubTypes::Payout &&

            PATDeclarationLotteryPayouts.ProfileId            == PATDeclarationHeader.DeclarationProfile &&

            PATDeclarationLotteryPayouts.Qty

        {

            lineNumber++;

            lineNumber = this.createLotteryCashedTicketPayoutGame(PATDeclarationHeader, PATDeclarationLotteryPayouts, retailStoreTable, retailTransactionTable, lineNumber);

        }

    }


    /// <summary>

    /// createLotteryCashedTicketPayoutGame

    /// </summary>

    /// <param name = "PATDeclarationHeader">PATDeclarationHeader</param>

    /// <param name = "PATDeclarationLotteryPayouts">PATDeclarationLotteryPayouts</param>

    /// <param name = "retailStoreTable">retailStoreTable</param>

    /// <param name = "retailTransactionTable">retailTransactionTable</param>

    /// <param name = "lineNumber">lineNumber</param>

    /// <returns></returns>

    public LineNum createLotteryCashedTicketPayoutGame( AmicisLotteryPATDeclarationHeader   PATDeclarationHeader,

                                                        AmicisLotteryPATDeclarationLotteryPayouts  PATDeclarationLotteryPayouts,

                                                        RetailStoreTable   retailStoreTable,

                                                        RetailTransactionTable retailTransactionTable,

                                                        LineNumber lineNumber)

    {

        RetailTransactionSalesTrans             retailTransactionSalesTrans;


        lineNumber++;

        retailTransactionSalesTrans.clear();

        retailTransactionSalesTrans.Channel    = retailStoreTable.RecId;

        retailTransactionSalesTrans.DefaultDimension    =   retailStoreTable.DefaultDimension;

        retailTransactionSalesTrans.terminalId = PATDeclarationHeader.Register;

        retailTransactionSalesTrans.transactionId = retailTransactionTable.TransactionId;

        retailTransactionSalesTrans.lineNum = lineNumber;

        retailTransactionSalesTrans.store = retailTransactionTable.store;

        retailTransactionSalesTrans.businessDate        = retailTransactionTable.businessDate;

        retailTransactionSalesTrans.currency = retailTransactionTable.Currency;

        retailTransactionSalesTrans.itemId              = PATDeclarationLotteryPayouts.Product;

        retailTransactionSalesTrans.price               = PATDeclarationLotteryPayouts.Qty ? PATDeclarationLotteryPayouts.Amount / PATDeclarationLotteryPayouts.Qty : 0;

        retailTransactionSalesTrans.originalPrice       = retailTransactionSalesTrans.price;

        //Note: Qty, net price, net amount, net amount incl tax is negative

        retailTransactionSalesTrans.qty                 = PATDeclarationLotteryPayouts.Qty;

        retailTransactionSalesTrans.unit                = InventTable::find(PATDeclarationLotteryPayouts.Product).salesUnitId(); 

        retailTransactionSalesTrans.netAmountInclTax    = PATDeclarationLotteryPayouts.Amount;

        //Net Amount and net price will calculate after create tax

        //retailTransactionSalesTrans.netAmount           = retailTransactionSalesTrans.netAmountInclTax;

        //retailTransactionSalesTrans.netPrice            = PATDeclarationLotteryPayouts.Amount;

        retailTransactionSalesTrans.receiptId           = retailTransactionTable.TransactionId;

        retailTransactionSalesTrans.ReceiptDateRequested    =   retailTransactionTable.ReceiptDateRequested;

        retailTransactionSalesTrans.ShippingDateRequested   =   retailTransactionTable.ReceiptDateRequested;

        retailTransactionSalesTrans.transDate           = retailTransactionTable.transDate;

        retailTransactionSalesTrans.transTime           = retailTransactionTable.transTime;

        retailTransactionSalesTrans.TaxItemGroup =  InventTableModule::find(PATDeclarationLotteryPayouts.Product, ModuleInventPurchSales::Sales).TaxItemGroupId;

        retailTransactionSalesTrans.taxGroup =  retailStoreTable.taxGroup;

        retailTransactionSalesTrans.transactionStatus       =   RetailEntryStatus::None;

        retailTransactionSalesTrans.InventLocationId        =   retailStoreTable.inventLocation;

        retailTransactionSalesTrans.InventSiteId            =   InventLocation::find(retailTransactionSalesTrans.InventLocationId).InventSiteId;

        retailTransactionSalesTrans.staffId                 =   HcmWorker::find(PATDeclarationHeader.StaffId).PersonnelNumber;


        //Some fields need to check data

        //retailTransactionSalesTrans.barcode             =  '';

        retailTransactionSalesTrans.keyboardItemEntry   = NoYes::Yes;

        retailTransactionSalesTrans.itemIdScanned       = NoYes::No;

        //retailTransactionSalesTrans.variantId           = '';

        //retailTransactionSalesTrans.WarehouseLocation   =  retailTransactionTable;

        retailTransactionSalesTrans.insert();

        

        return lineNumber;

    }


    /// <summary>

    /// createRetailTransactionTaxTrans

    /// </summary>

    /// <param name = "retailTransactionSalesTrans"></param>

    public void createRetailTransactionTaxTransForSale(RetailTransactionTable retailTransactionTable)

    {

        RetailTransactionTaxTrans   retailTransactionTaxTrans;

        RetailTransactionSalesTrans retailTransactionSalesTrans;

        TaxGroupData                taxGroupData;

        TaxOnItem                   taxOnItem;

        real                        totalPercentTax;

        RetailStoreTable            retailStoreTable;

        AmicisLotteryPATDeclarationHeader   patDeclarationHeader;

        Amount                      totalTaxSaleLine;


        patDeclarationHeader    =   AmicisLotteryPATDeclarationHeader::find(declarationId);

        retailStoreTable        =   RetailStoreTable::find(patDeclarationHeader.Store);


        while select retailTransactionSalesTrans

            where retailTransactionSalesTrans.store == retailTransactionTable.store &&

            retailTransactionSalesTrans.terminalId  == retailTransactionTable.terminal &&

            retailTransactionSalesTrans.transactionId == retailTransactionTable.transactionId

        {

            totalPercentTax = 0;

            totalTaxSaleLine = 0;


            while select taxOnItem

            join TaxCode from taxGroupData

                where taxOnItem.TaxCode == taxGroupData.TaxCode &&

                    TaxOnItem.TaxItemGroup == InventTableModule::find(retailTransactionSalesTrans.itemId, ModuleInventPurchSales::Sales).TaxItemGroupId

                    join TaxGroup from retailStoreTable

                        where retailStoreTable.taxGroup == taxGroupData.TaxGroup &&

                                retailStoreTable.StoreNumber ==   retailTransactionSalesTrans.store

            {

                totalPercentTax += TaxTable::find(taxOnItem.TaxCode).showTaxValue();

            }


            //Update Net Amount


            retailTransactionSalesTrans.selectForUpdate(true);

            retailTransactionSalesTrans.netAmount = (retailTransactionSalesTrans.netAmountInclTax) / (1 + (totalPercentTax/100));

            


            //update data after create tax trans

            if(!RetailChannelTable::findByRecId(RetailStoreTable::find(retailTransactionSalesTrans.store).RecId).PriceIncludesSalesTax)

            {

               

            }

            retailTransactionSalesTrans.update();


            while select taxOnItem

            join TaxCode from taxGroupData

                where taxOnItem.TaxCode == taxGroupData.TaxCode &&

                    TaxOnItem.TaxItemGroup == InventTableModule::find(retailTransactionSalesTrans.itemId, ModuleInventPurchSales::Sales).TaxItemGroupId

                    join TaxGroup from retailStoreTable

                        where retailStoreTable.taxGroup == taxGroupData.TaxGroup &&

                                retailStoreTable.StoreNumber ==   retailTransactionSalesTrans.store

            {

                retailTransactionTaxTrans.clear();

                retailTransactionTaxTrans.Channel       =   retailStoreTable.RecId;

                retailTransactionTaxTrans.TerminalId    =   retailTransactionSalesTrans.terminalId;

                retailTransactionTaxTrans.StoreId       =   retailTransactionSalesTrans.store;

                retailTransactionTaxTrans.TransactionId =   retailTransactionSalesTrans.transactionId;

                retailTransactionTaxTrans.SaleLineNum   =   retailTransactionSalesTrans.lineNum;

                retailTransactionTaxTrans.TaxCode       =   taxOnItem.TaxCode;

                retailTransactionTaxTrans.TaxPercentage =   TaxTable::find(taxOnItem.TaxCode).showTaxValue();

                retailTransactionTaxTrans.Amount        =   (-1) * Tax::calcTaxAmount(taxGroupData.TaxGroup, TaxOnItem.TaxItemGroup, retailTransactionSalesTrans.transDate, retailTransactionSalesTrans.currency, retailTransactionSalesTrans.netAmount, TaxModuleType::Retail);

                retailTransactionTaxTrans.insert();

                totalTaxSaleLine += retailTransactionTaxTrans.Amount;

            }


            retailTransactionSalesTrans.selectForUpdate(true);

            //update data after create tax trans and rounding

            if(RetailChannelTable::findByRecId(RetailStoreTable::find(retailTransactionSalesTrans.store).RecId).PriceIncludesSalesTax)

            {

                if(retailTransactionSalesTrans.qty < 0)

                {

                    retailTransactionSalesTrans.taxAmount = (-1) * totalTaxSaleLine;

                    //Get net amount incl tax from user input 

                    retailTransactionSalesTrans.netAmount = retailTransactionSalesTrans.netAmountInclTax + totalTaxSaleLine;

                    retailTransactionSalesTrans.netPrice  = retailTransactionSalesTrans.netAmount;

                }

                else

                {

                    retailTransactionSalesTrans.taxAmount = totalTaxSaleLine;

                    //Get net amount incl tax from user input

                    retailTransactionSalesTrans.netAmount = retailTransactionSalesTrans.netAmountInclTax + totalTaxSaleLine;

                    retailTransactionSalesTrans.netPrice  = retailTransactionSalesTrans.netAmount;

                }

            }

            else

            {

                if(retailTransactionSalesTrans.qty < 0)

                {

                    retailTransactionSalesTrans.taxAmount = (-1) * totalTaxSaleLine;

                    //Get net amount incl tax from user input

                    retailTransactionSalesTrans.netAmount = retailTransactionSalesTrans.netAmountInclTax  + totalTaxSaleLine;

                    retailTransactionSalesTrans.netPrice  = retailTransactionSalesTrans.netAmount;

                    retailTransactionSalesTrans.netAmountInclTax = retailTransactionSalesTrans.netAmount;

                }

                else

                {

                    retailTransactionSalesTrans.taxAmount = totalTaxSaleLine;

                    //Get net amount incl tax from user input

                    retailTransactionSalesTrans.netAmount = retailTransactionSalesTrans.netAmountInclTax + totalTaxSaleLine;

                    retailTransactionSalesTrans.netPrice  = retailTransactionSalesTrans.netAmount;

                    //Re calcuualte net amount incl tax

                    retailTransactionSalesTrans.netAmountInclTax = retailTransactionSalesTrans.netAmount;

                }

            }

            retailTransactionSalesTrans.update();

        }

    }


    /// <summary>

    /// createRetailTransactionTableForSafeDrop

    /// </summary>

    /// <returns>RetailTransactionTable</returns>

    public RetailTransactionTable createRetailTransactionTableForSafeDrop()

    {

        RetailTransactionTable              retailTransactionTable;

        RetailTransactionId                 retailTransactionId;

        RetailStoreTable                    retailStoreTable;

        RetailTransactionType               retailTransactionType;

        AmicisLotteryPATDeclarationHeader   PATDeclarationHeader    =   AmicisLotteryPATDeclarationHeader::find(declarationId);


        retailStoreTable    =   RetailStoreTable::find(PATDeclarationHeader.Store);

        retailTransactionType   = RetailTransactionType::SafeDrop;

        retailTransactionTable.clear();

        //Key and no logic

        retailTransactionTable.terminal             =   PATDeclarationHeader.Register;

        retailTransactionTable.BatchID              =   shiftId;

        retailTransactionTable.BatchTerminalId      =   PATDeclarationHeader.Register;

        retailTransactionTable.businessDate         =   PATDeclarationHeader.DeclarationDate;

        retailTransactionTable.Channel              =   retailStoreTable.RecId;

        retailTransactionTable.CreatedOffline       =   NoYes::No;

        retailTransactionTable.createdOnPosTerminal =   PATDeclarationHeader.Register;

        retailTransactionTable.currency         =   retailStoreTable.Currency;

        retailTransactionTable.entryStatus      =   RetailEntryStatus::Posted;

        retailTransactionTable.exchRate         =   100;

        retailTransactionTable.InventLocationId =   retailStoreTable.inventLocation;

        retailTransactionTable.ReceiptDateRequested =   str2Date(strFmt("%1%2", PATDeclarationHeader.DeclarationDate, PATDeclarationHeader.DeclarationTime),321);

        //retailTransactionTable.receiptId          =   retailTransactionTable.transactionId;

        retailTransactionTable.saleIsReturnSale     =   NoYes::No;

        retailTransactionTable.timeWhenTransClosed  =   0;

        //retailTransactionTable.ShippingDateRequested =  str2Date(strFmt("%1%2", patDeclarationHeader.DeclarationDate, patDeclarationHeader.DeclarationTime),321);

        retailTransactionTable.staff            =    HcmWorker::find(PATDeclarationHeader.StaffId).PersonnelNumber;

        retailTransactionTable.store            =   PATDeclarationHeader.Store;

        retailTransactionTable.transactionId    =   strFmt("%1-%2", PATDeclarationHeader.DeclarationId, enum2int(retailTransactionType));

        retailTransactionTable.transTime        =   PATDeclarationHeader.DeclarationTime;

        retailTransactionTable.transDate        =   patDeclarationHeader.DeclarationDate;

        retailTransactionTable.type             =   RetailTransactionType::SafeDrop;

        //retailTransactionTable.IsTaxIncludedInPrice =   RetailChannelTable::findByRecId(retailStoreTable.RecId).PriceIncludesSalesTax;

        retailTransactionTable.TransactionOrderType =   RetailTransactionOrderTypes::SalesOrder;

        //retailTransactionTable.BeginDateTime    =     patDeclarationHeader.DeclarationTime;

        //Different field POS Integration

        retailTransactionTable.custAccount      = '';

        retailTransactionTable.insert();

        return retailTransactionTable;

    }


    public void createRetailTransactionSafeTenderTransForSafeDrop()

    {

        RetailTransactionType                                       retailTransactionType;

        RetailPosBatchTenderTrans                                   retailPosBatchTenderTrans;

        RetailTransactionSafeTenderTrans                            retailTransactionSafeTenderTrans;

        RetailStoreTable                                            storeTable;

        RetailChannelTable                                          channelTable;

        RetailStaffId                                               staffId;

        RetailStoreTenderTypeTable                                  retailStoreTenderTypeTable;

        RetailPosBatchID                                            batchId;

        RetailTerminalId                                            terminalId;

        AmicisLotteryPATDeclarationHeader                           patDeclarationHeader;

        RetailTransactionId                                         safeDropTransactionId;

        AmicisLotteryPATDeclarationProfilePayment                   PATDeclarationProfilePayment;

        ;

        //Common setup:

        retailTransactionType   = RetailTransactionType::SafeDrop;

        patDeclarationHeader    = AmicisLotteryPATDeclarationHeader::find(declarationId);

        terminalId              = patDeclarationHeader.Register;

        storeTable              = RetailStoreTable::find(patDeclarationHeader.Store);

        channelTable            = RetailChannelTable::findByOperatingUnitId(storeTable.OMOperatingUnitID);

        staffId                 = HcmWorker::find(patDeclarationHeader.StaffId).PersonnelNumber;

        batchId                 = shiftId;

        safeDropTransactionId   = strFmt('%1-%2',declarationId, enum2int(retailTransactionType));

        

        select firstonly PATDeclarationProfilePayment

            where   PATDeclarationProfilePayment.ProfileId                  == patDeclarationHeader.DeclarationProfile &&

                    PATDeclarationProfilePayment.DefaultPaymentSafeTender   == NoYes::Yes;


        //Start - Create RetailTransactionSafeTenderTrans

        retailTransactionSafeTenderTrans.clear();

        retailTransactionSafeTenderTrans.Channel            = channelTable.RecId;

        retailTransactionSafeTenderTrans.Store              = storeTable.StoreNumber;

        retailTransactionSafeTenderTrans.Terminal           = terminalId;

        retailTransactionSafeTenderTrans.TransactionId      = safeDropTransactionId;

        retailTransactionSafeTenderTrans.TransactionStatus  = RetailEntryStatus::None;

        retailTransactionSafeTenderTrans.TransDate          = patDeclarationHeader.DeclarationDate;

        retailTransactionSafeTenderTrans.TransTime          = patDeclarationHeader.DeclarationTime;

        retailTransactionSafeTenderTrans.TenderType         = PATDeclarationProfilePayment.RetailTenderTypeId;

        retailTransactionSafeTenderTrans.statusType         = RetailSafeStatusTypeBase::RetailEx3;

        retailTransactionSafeTenderTrans.staff              = staffId;

        retailTransactionSafeTenderTrans.ShiftDate          = retailTransactionSafeTenderTrans.TransDate;

        retailTransactionSafeTenderTrans.Qty                = 1;

        retailTransactionSafeTenderTrans.LineNum            = 1;

        retailTransactionSafeTenderTrans.currency           = storeTable.Currency;

        retailTransactionSafeTenderTrans.ExchRate           = 1; //Because currency code is always a default store currency, so exchange rate = 1

        retailTransactionSafeTenderTrans.exchRateMST        = 1; //Because currency code is always a default store currency, so exchange rate = 1

        retailTransactionSafeTenderTrans.AmountCur          = patDeclarationHeader.CashCounted;

        retailTransactionSafeTenderTrans.amountCurPOS       = patDeclarationHeader.CashCounted;

        retailTransactionSafeTenderTrans.amountMST          = patDeclarationHeader.CashCounted;

        retailTransactionSafeTenderTrans.amountMSTPOS       = patDeclarationHeader.CashCounted;

        retailTransactionSafeTenderTrans.AmountTendered     = patDeclarationHeader.CashCounted;

        retailTransactionSafeTenderTrans.amountTenderedPOS  = patDeclarationHeader.CashCounted;

        retailTransactionSafeTenderTrans.insert();

        

        //Start - Create RetailPosBatchTenderTrans

        retailPosBatchTenderTrans.clear();

        retailPosBatchTenderTrans.initValue();

        retailPosBatchTenderTrans.BatchID                   = shiftId;

        retailPosBatchTenderTrans.Currency                  = storeTable.Currency;

        retailPosBatchTenderTrans.StoreId                   = storeTable.StoreNumber;

        retailPosBatchTenderTrans.Channel                   = channelTable.RecId;

        retailPosBatchTenderTrans.TenderTypeId              = PATDeclarationProfilePayment.RetailTenderTypeId;

        retailPosBatchTenderTrans.TerminalId                = terminalId;

        retailPosBatchTenderTrans.StartingAmount            = 0;

        retailPosBatchTenderTrans.StartingAmountCur         = 0;

        retailPosBatchTenderTrans.DeclareTenderAmount       = 0;

        retailPosBatchTenderTrans.DeclareTenderAmountCur    = 0;

        retailPosBatchTenderTrans.SafeDropAmount            = patDeclarationHeader.CashCounted;

        retailPosBatchTenderTrans.SafeDropAmountCur         = patDeclarationHeader.CashCounted;

        retailPosBatchTenderTrans.RemoveTenderAmount        = 0;

        retailPosBatchTenderTrans.RemoveTenderAmountCur     = 0;

        retailPosBatchTenderTrans.insert();

    }


    /// <summary>

    /// createRetailTransactionPaymentTransForSales

    /// </summary>

    /// <param name = "retailTransactionTable">retailTransactionTable</param>

    public void createRetailTransactionPaymentTransForSales(RetailTransactionTable retailTransactionTable)

    {

        

        RetailTransactionPaymentTrans       paymentTrans;

        AmicisLotteryPATDeclarationPayment  PATDeclarationPayment;

        RetailStoreTable                    retailStoreTable;

        RetailTerminalId                    terminalId;

        LineNumber                          lineNum = 0;

        RetailStaffId                       staffId;

        AmicisLotteryPATDeclarationHeader   PATDeclarationHeader;


        PATDeclarationHeader                =   AmicisLotteryPATDeclarationHeader::find(declarationId);

        retailStoreTable                    =   RetailStoreTable::find(PATDeclarationHeader.Store);

        terminalId                          = patDeclarationHeader.Register;

        staffId                             = HcmWorker::find(patDeclarationHeader.StaffId).PersonnelNumber;


        while select PATDeclarationPayment

            where  PATDeclarationPayment.DeclarationId == PATDeclarationHeader.DeclarationId &&

            PATDeclarationPayment.ProfileId            == PATDeclarationHeader.DeclarationProfile

        {

            lineNum++;

            paymentTrans.clear();

            paymentTrans.initValue();

            paymentTrans.terminal       = terminalId;

            paymentTrans.transactionId  = retailTransactionTable.transactionId;

            paymentTrans.lineNum        = lineNum;

            paymentTrans.store          = retailStoreTable.StoreNumber;

            paymentTrans.Channel        = retailStoreTable.RecId;

            paymentTrans.amountTendered = PATDeclarationPayment.Amount;

            paymentTrans.amountCur      = PATDeclarationPayment.Amount;

            paymentTrans.amountMST      = PATDeclarationPayment.Amount;


            paymentTrans.cardTypeId     = PATDeclarationPayment.RetailTenderTypeId;

            paymentTrans.currency       = retailTransactionTable.Currency;

            paymentTrans.exchRate       = 100;

            paymentTrans.exchRateMST    = 100;


            paymentTrans.tenderType     = PATDeclarationPayment.RetailTenderTypeId;


            paymentTrans.changeLine = NoYes::No;


            //paymentTrans.loyaltyCardId = trackingPaymentTrans.LoyaltyCardId;

            paymentTrans.qty = 1;

            paymentTrans.receiptId = retailTransactionTable.transactionId;

            //paymentTrans.RefundableAmount = trackingPaymentTrans.RefundAbleAmount;

            paymentTrans.staff = staffId;

            paymentTrans.transactionStatus = RetailEntryStatus::None;

            paymentTrans.VoidStatus = RetailTenderVoidStatus::None;


            paymentTrans.transDate = PATDeclarationHeader.DeclarationDate;

            //paymentTrans.authenticationCode = trackingPaymentTrans.ReferenceNumber;

            paymentTrans.transactionStatus = RetailEntryStatus::None;

            paymentTrans.VoidStatus = RetailTenderVoidStatus::None;


            paymentTrans.insert();


        }

    }


}