/// <summary>
        /// Gets the information of the Appointment and AppointmentInventoryItem using as reference the [appointmentID] and [appointmentInventoryItemID].
        /// </summary>
        ///

        // AC-143262 Review this method
        public virtual SharedClasses.AppointmentInventoryItemInfo GetAppointmentInventoryItemInfo(int?appointmentID, int?appDetID, int index)
        {
            //PXResult<FSAppointment, FSServiceOrder, FSSrvOrdType, FSAppointmentDet, FSAppointmentDet> bqlResult =
            //                                                                            (PXResult<FSAppointment, FSServiceOrder, FSSrvOrdType, FSAppointmentDet, FSAppointmentDet>)
            //                                                                            PXSelectReadonly2<FSAppointment,
            //                                                                            InnerJoin<FSServiceOrder,
            //                                                                                On<FSServiceOrder.sOID, Equal<FSAppointment.sOID>,
            //                                                                                    And<FSAppointment.appointmentID, Equal<Required<FSAppointment.appointmentID>>>>,
            //                                                                            InnerJoin<FSSrvOrdType,
            //                                                                                On<FSSrvOrdType.srvOrdType, Equal<FSAppointment.srvOrdType>>,
            //                                                                            InnerJoin<FSAppointmentDet,
            //                                                                                On<FSAppointmentDet.appointmentID, Equal<FSAppointment.appointmentID>,
            //                                                                                    And<FSAppointmentDet.appDetID, Equal<Required<FSAppointmentDet.appDetID>>>>,
            //                                                                            InnerJoin<FSAppointmentDet,
            //                                                                                On<FSAppointmentDet.sODetID, Equal<FSAppointmentDet.sODetID>>>>>>>
            //                                                                            .Select(this, appointmentID, appDetID);

            SharedClasses.AppointmentInventoryItemInfo appointmentInfoToReturn = new SharedClasses.AppointmentInventoryItemInfo();

            //if (bqlResult != null)
            //{
            //    FSAppointment fsAppointmentRow                              = (FSAppointment)bqlResult;
            //    FSServiceOrder fsServiceOrderRow                            = (FSServiceOrder)bqlResult;
            //    FSSrvOrdType fsSrvOrdTypeRow                                = (FSSrvOrdType)bqlResult;
            //    FSAppointmentDet fsAppointmentInventoryItemRow    = (FSAppointmentDet)bqlResult;
            //    FSAppointmentDet fsAppointmentDetRow                        = (FSAppointmentDet)bqlResult;

            //    appointmentInfoToReturn = new SharedClasses.AppointmentInventoryItemInfo(fsAppointmentRow, fsServiceOrderRow, fsSrvOrdTypeRow, fsAppointmentDetRow, fsAppointmentInventoryItemRow, index);
            //}

            return(appointmentInfoToReturn);
        }
        /// <summary>
        /// Gets the information of the Appointment and AppointmentInventoryItem using as reference the [appointmentID] and [appointmentInventoryItemID].
        /// </summary>
        private SharedClasses.AppointmentInventoryItemInfo GetAppointmentInventoryItemInfo(int?appointmentID, int?appDetID, int index)
        {
            PXResult <FSAppointment, FSServiceOrder, FSSrvOrdType, FSAppointmentInventoryItem, FSAppointmentDet> bqlResult =
                (PXResult <FSAppointment, FSServiceOrder, FSSrvOrdType, FSAppointmentInventoryItem, FSAppointmentDet>)
                PXSelectReadonly2 <FSAppointment,
                                   InnerJoin <FSServiceOrder,
                                              On <FSServiceOrder.sOID, Equal <FSAppointment.sOID>,
                                                  And <FSAppointment.appointmentID, Equal <Required <FSAppointment.appointmentID> > > >,
                                              InnerJoin <FSSrvOrdType,
                                                         On <FSSrvOrdType.srvOrdType, Equal <FSAppointment.srvOrdType> >,
                                                         InnerJoin <FSAppointmentInventoryItem,
                                                                    On <FSAppointmentInventoryItem.appointmentID, Equal <FSAppointment.appointmentID>,
                                                                        And <FSAppointmentInventoryItem.appDetID, Equal <Required <FSAppointmentInventoryItem.appDetID> > > >,
                                                                    InnerJoin <FSAppointmentDet,
                                                                               On <FSAppointmentDet.sODetID, Equal <FSAppointmentInventoryItem.sODetID> > > > > > >
                .Select(this, appointmentID, appDetID);

            SharedClasses.AppointmentInventoryItemInfo appointmentInfoToReturn = new SharedClasses.AppointmentInventoryItemInfo();

            if (bqlResult != null)
            {
                FSAppointment              fsAppointmentRow              = (FSAppointment)bqlResult;
                FSServiceOrder             fsServiceOrderRow             = (FSServiceOrder)bqlResult;
                FSSrvOrdType               fsSrvOrdTypeRow               = (FSSrvOrdType)bqlResult;
                FSAppointmentInventoryItem fsAppointmentInventoryItemRow = (FSAppointmentInventoryItem)bqlResult;
                FSAppointmentDet           fsAppointmentDetRow           = (FSAppointmentDet)bqlResult;

                appointmentInfoToReturn = new SharedClasses.AppointmentInventoryItemInfo(fsAppointmentRow, fsServiceOrderRow, fsSrvOrdTypeRow, fsAppointmentDetRow, fsAppointmentInventoryItemRow, index);
            }

            return(appointmentInfoToReturn);
        }
        /// <summary>
        /// Update the references in <c>FSPostInfo</c> and <c>FSPostDet</c> when the posting process of every AppointmentInventoryItem is complete in IN.
        /// </summary>
        public virtual void UpdateIssuePostInfo(INIssueEntry graphINIssueEntry, InventoryPostBatchMaint graphInventoryPostBatchMaint, PostInfoEntry graphPostInfoEntry, FSAppointmentDet fsAppointmentInventoryItemRow, SharedClasses.AppointmentInventoryItemInfo appointmentInventoryItemInfoRow, FSPostBatch fsPostBatchRow)
        {
            //Create | Update Post info
            FSPostInfo fsPostInfoRow;
            FSPostDet  fsPostDet;

            fsPostBatchRow = graphInventoryPostBatchMaint.BatchRecords.Current = graphInventoryPostBatchMaint.BatchRecords.Search <FSPostBatch.batchID>(fsPostBatchRow.BatchID);

            fsPostInfoRow = PXSelect <FSPostInfo,
                                      Where <
                                          FSPostInfo.postID, Equal <Required <FSPostInfo.postID> > > >
                            .Select(this, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.PostID);

            if (fsPostInfoRow == null || fsPostInfoRow.PostID == null)
            {
                fsPostInfoRow = new FSPostInfo();
                fsPostInfoRow = graphPostInfoEntry.PostInfoRecords.Current = graphPostInfoEntry.PostInfoRecords.Insert(fsPostInfoRow);
            }
            else
            {
                fsPostInfoRow = graphPostInfoEntry.PostInfoRecords.Current = graphPostInfoEntry.PostInfoRecords.Search <FSPostInfo.postID>(fsPostInfoRow.PostID);
            }

            fsPostInfoRow.INPosted  = true;
            fsPostInfoRow.INDocType = graphINIssueEntry.issue.Current.DocType;
            fsPostInfoRow.INRefNbr  = graphINIssueEntry.issue.Current.RefNbr;

            foreach (INTran inTranRowLocal in graphINIssueEntry.transactions.Select())
            {
                FSxINTran fsxINTranRow = graphINIssueEntry.transactions.Cache.GetExtension <FSxINTran>(inTranRowLocal);

                if (fsxINTranRow != null && appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.AppDetID == fsxINTranRow.AppDetID)
                {
                    fsPostInfoRow.INLineNbr = inTranRowLocal.LineNbr;
                    break;
                }
            }

            fsPostInfoRow.AppointmentID = appointmentInventoryItemInfoRow.FSAppointmentRow.AppointmentID;
            fsPostInfoRow.SOID          = appointmentInventoryItemInfoRow.FSAppointmentRow.SOID;

            fsPostInfoRow = graphPostInfoEntry.PostInfoRecords.Update(fsPostInfoRow);

            graphPostInfoEntry.Save.Press();
            fsPostInfoRow = graphPostInfoEntry.PostInfoRecords.Current;

            fsPostDet = new FSPostDet();

            fsPostDet.PostID    = fsPostInfoRow.PostID;
            fsPostDet.INPosted  = fsPostInfoRow.INPosted;
            fsPostDet.INDocType = fsPostInfoRow.INDocType;
            fsPostDet.INRefNbr  = fsPostInfoRow.INRefNbr;
            fsPostDet.INLineNbr = fsPostInfoRow.INLineNbr;

            graphInventoryPostBatchMaint.BatchDetails.Insert(fsPostDet);
            graphInventoryPostBatchMaint.Save.Press();

            fsAppointmentInventoryItemRow.Mem_BatchNbr = fsPostBatchRow.BatchNbr;

            fsPostInfoRow = graphPostInfoEntry.PostInfoRecords.Current;

            PXUpdate <
                Set <FSAppointmentDet.postID, Required <FSAppointmentDet.postID> >,
                FSAppointmentDet,
                Where <
                    FSAppointmentDet.appDetID, Equal <Required <FSAppointmentDet.appDetID> > > >
            .Update(this, fsPostInfoRow.PostID, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.AppDetID);
        }
        /// <summary>
        /// Creates an Issue document using the parameters <c>fsAppointmentRow</c>, <c>fsServiceOrderRow</c>, <c>fsServiceOrderTypeRow</c> and its posting information.
        /// </summary>
        protected virtual void CreateDocumentIssue(INIssueEntry graphINIssueEntry, SharedClasses.AppointmentInventoryItemInfo appointmentInventoryItemInfoRow, FSAppointmentDet fsAppointmentInventoryItemRow, DateTime?documentDate, string documentPeriod, FSPostBatch fsPostBatchRow, ref string inRefNbr, ref string inDocType)
        {
            if (appointmentInventoryItemInfoRow != null)
            {
                INRegister inRegisterRow;
                #region IN Issue Header
                if (string.IsNullOrEmpty(inRefNbr))
                {
                    inRegisterRow = new INRegister();

                    inRegisterRow.DocType     = INDocType.Issue;
                    inRegisterRow.TranDate    = documentDate;
                    inRegisterRow.FinPeriodID = documentPeriod;
                    inRegisterRow.TranDesc    = appointmentInventoryItemInfoRow.FSAppointmentRow.DocDesc;
                    inRegisterRow.Hold        = false;
                    inRegisterRow             = graphINIssueEntry.issue.Current = graphINIssueEntry.issue.Insert(inRegisterRow);

                    inRegisterRow = graphINIssueEntry.issue.Update(inRegisterRow);
                }
                else
                {
                    inRegisterRow = graphINIssueEntry.issue.Current = graphINIssueEntry.issue.Search <INRegister.refNbr>(inRefNbr);
                }
                #endregion
                INTran inTranRow;

                inTranRow          = new INTran();
                inTranRow.TranType = INTranType.Issue;

                inTranRow = graphINIssueEntry.transactions.Current = graphINIssueEntry.transactions.Insert(inTranRow);

                graphINIssueEntry.transactions.Cache.SetValueExt <INTran.inventoryID>(inTranRow, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.InventoryID);

                if (PXAccess.FeatureInstalled <FeaturesSet.subItem>())
                {
                    graphINIssueEntry.transactions.Cache.SetValueExt <INTran.subItemID>(inTranRow, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.SubItemID);
                }

                graphINIssueEntry.transactions.Cache.SetValueExt <INTran.siteID>(inTranRow, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.SiteID);
                graphINIssueEntry.transactions.Cache.SetValueExt <INTran.qty>(inTranRow, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.Qty);
                graphINIssueEntry.transactions.Cache.SetValueExt <INTran.unitPrice>(inTranRow, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.UnitPrice);
                graphINIssueEntry.transactions.Cache.SetValueExt <INTran.tranAmt>(inTranRow, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.TranAmt);
                graphINIssueEntry.transactions.Cache.SetValueExt <INTran.projectID>(inTranRow, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.ProjectID);
                graphINIssueEntry.transactions.Cache.SetValueExt <INTran.taskID>(inTranRow, appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.ProjectTaskID);

                FSxINTran fsxINTranRow = graphINIssueEntry.transactions.Cache.GetExtension <FSxINTran>(graphINIssueEntry.transactions.Current);

                fsxINTranRow.Source             = ID.Billing_By.APPOINTMENT;
                fsxINTranRow.SOID               = appointmentInventoryItemInfoRow.FSAppointmentRow.SOID;
                fsxINTranRow.BillCustomerID     = appointmentInventoryItemInfoRow.FSServiceOrderRow.BillCustomerID;
                fsxINTranRow.CustomerLocationID = appointmentInventoryItemInfoRow.FSServiceOrderRow.BillLocationID;
                fsxINTranRow.AppointmentID      = appointmentInventoryItemInfoRow.FSAppointmentRow.AppointmentID;
                fsxINTranRow.AppointmentDate    = new DateTime(appointmentInventoryItemInfoRow.FSAppointmentRow.ActualDateTimeBegin.Value.Year,
                                                               appointmentInventoryItemInfoRow.FSAppointmentRow.ActualDateTimeBegin.Value.Month,
                                                               appointmentInventoryItemInfoRow.FSAppointmentRow.ActualDateTimeBegin.Value.Day,
                                                               0,
                                                               0,
                                                               0);

                fsxINTranRow.AppDetID = (int)appointmentInventoryItemInfoRow.FSAppointmentInventoryItem.AppDetID;

                inTranRow = graphINIssueEntry.transactions.Update(inTranRow);

                graphINIssueEntry.Save.Press();

                if (string.IsNullOrEmpty(inRefNbr))
                {
                    inRefNbr  = graphINIssueEntry.issue.Current.RefNbr;
                    inDocType = graphINIssueEntry.issue.Current.DocType;
                }

                UpdateIssuePostInfo(graphINIssueEntry, graphUpdatePostBatchMaint, graphPostInfoEntry, fsAppointmentInventoryItemRow, appointmentInventoryItemInfoRow, fsPostBatchRow);
            }
            else
            {
                throw new PXException(TX.Error.NOTHING_TO_BE_POSTED);
            }
        }