public FSProfitability(FSAppointmentDetPart fsAppointmentDetPartRow)
 {
     this.LineRef         = fsAppointmentDetPartRow.LineRef;
     this.LineType        = fsAppointmentDetPartRow.LineType;
     this.ItemID          = fsAppointmentDetPartRow.InventoryID;
     this.Descr           = fsAppointmentDetPartRow.TranDesc;
     this.UnitPrice       = fsAppointmentDetPartRow.CuryUnitPrice;
     this.EstimatedQty    = fsAppointmentDetPartRow.EstimatedQty;
     this.EstimatedAmount = fsAppointmentDetPartRow.CuryEstimatedTranAmt;
     this.ActualDuration  = 0;
     this.ActualQty       = fsAppointmentDetPartRow.Qty;
     this.ActualAmount    = fsAppointmentDetPartRow.CuryTranAmt;
     this.BillableQty     = fsAppointmentDetPartRow.BillableQty;
     this.BillableAmount  = fsAppointmentDetPartRow.CuryBillableTranAmt;
     this.UnitCost        = fsAppointmentDetPartRow.CuryUnitCost;
     this.CostTotal       = this.BillableQty * this.UnitCost;
     this.Profit          = this.BillableAmount - this.CostTotal;
     this.ProfitPercent   = this.CostTotal == 0.0m ? 0.0m : (this.Profit / this.CostTotal) * 100;
 }
        private void CloneParts(AppointmentEntry sourceAppointmentGraph, AppointmentEntry newAppointmentGraph, FSAppointment newAppointmentRow)
        {
            foreach (FSAppointmentDetPart sourceRow in sourceAppointmentGraph.AppointmentDetParts.Select())
            {
                FSSODet fsSODetRow = ServiceOrderCore.GetSODetFromAppointmentDet(sourceAppointmentGraph, sourceRow);

                if (fsSODetRow != null &&
                    (fsSODetRow.Status == ID.Status_AppointmentDet.CANCELED ||
                     fsSODetRow.Status == ID.Status_AppointmentDet.COMPLETED))
                {
                    continue;
                }

                FSAppointmentDet sumFSAppointmentDetPartBillable =
                    PXSelectJoinGroupBy <FSAppointmentDet,
                                         InnerJoin <FSAppointment, On <FSAppointment.srvOrdType, Equal <FSAppointmentDet.srvOrdType>,
                                                                       And <FSAppointment.refNbr, Equal <FSAppointmentDetPart.refNbr> > > >,
                                         Where <FSAppointmentDet.sODetID, Equal <Required <FSAppointmentDet.sODetID> >,
                                                And <FSAppointment.status, NotEqual <FSAppointment.status.Canceled>,
                                                     And <FSAppointmentDet.status, NotEqual <FSAppointmentDet.status.Canceled> > > >,
                                         Aggregate <GroupBy <FSAppointmentDet.sODetID, Sum <FSAppointmentDet.billableQty> > > >
                    .Select(dummyGraph, sourceRow.SODetID);

                decimal?openQty    = fsSODetRow.BillableQty - sumFSAppointmentDetPartBillable.BillableQty;
                bool?   lineCloned = false;

                FSAppointmentDetPart newRow = PXCache <FSAppointmentDetPart> .CreateCopy(sourceRow);

                if (openQty >= sourceRow.BillableQty)
                {
                    newRow = AppointmentEntry.InsertServicePartLine <FSAppointmentDetPart, FSAppointmentDetPart>(
                        newAppointmentGraph.AppointmentDetParts.Cache,
                        newRow,
                        sourceAppointmentGraph.AppointmentDetParts.Cache,
                        sourceRow,
                        null,
                        sourceRow.SODetID,
                        copyTranDate: false,
                        tranDate: sourceRow.TranDate,
                        SetValuesAfterAssigningSODetID: true,
                        copyingFromQuote: false);
                    lineCloned = true;
                }
                else
                {
                    if (openQty > 0)
                    {
                        decimal?remainingQty = sourceRow.BillableQty - openQty;

                        newRow.Qty             = 0;
                        sourceRow.EstimatedQty = openQty;
                        sourceRow.BillableQty  = openQty;
                        newRow = AppointmentEntry.InsertServicePartLine <FSAppointmentDetPart, FSAppointmentDetPart>(
                            newAppointmentGraph.AppointmentDetParts.Cache,
                            newRow,
                            sourceAppointmentGraph.AppointmentDetParts.Cache,
                            sourceRow,
                            null,
                            sourceRow.SODetID,
                            copyTranDate: false,
                            tranDate: sourceRow.TranDate,
                            SetValuesAfterAssigningSODetID: true,
                            copyingFromQuote: false);
                        lineCloned = true;

                        FSAppointmentDetPart secondNewRow = PXCache <FSAppointmentDetPart> .CreateCopy(sourceRow);

                        secondNewRow.Qty       = 0;
                        sourceRow.EstimatedQty = remainingQty;
                        sourceRow.BillableQty  = remainingQty;
                        secondNewRow.SODetID   = null;
                        secondNewRow           = AppointmentEntry.InsertServicePartLine <FSAppointmentDetPart, FSAppointmentDetPart>(
                            newAppointmentGraph.AppointmentDetParts.Cache,
                            secondNewRow,
                            sourceAppointmentGraph.AppointmentDetParts.Cache,
                            sourceRow,
                            null,
                            null,
                            copyTranDate: false,
                            tranDate: sourceRow.TranDate,
                            SetValuesAfterAssigningSODetID: false,
                            copyingFromQuote: false);
                    }
                    else
                    {
                        newRow.SODetID = null;
                        newRow.Qty     = 0;
                        newRow         = AppointmentEntry.InsertServicePartLine <FSAppointmentDetPart, FSAppointmentDetPart>(
                            newAppointmentGraph.AppointmentDetParts.Cache,
                            newRow,
                            sourceAppointmentGraph.AppointmentDetParts.Cache,
                            sourceRow,
                            null,
                            null,
                            copyTranDate: false,
                            tranDate: sourceRow.TranDate,
                            SetValuesAfterAssigningSODetID: false,
                            copyingFromQuote: false);
                    }
                }


                if (lineCloned == true)
                {
                    PXNoteAttribute.CopyNoteAndFiles(
                        sourceAppointmentGraph.AppointmentDetParts.Cache,
                        sourceRow,
                        newAppointmentGraph.AppointmentDetParts.Cache,
                        newRow,
                        copyNotes: true,
                        copyFiles: false);

                    AppointmentCore.UpdateAppointmentsInfoInServiceOrder(newAppointmentGraph.AppointmentDetParts.Cache, newRow, ServiceOrderRelated);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Create an Appointment from a TimeSlot.
        /// </summary>
        protected void createAppointment(
            FSServiceOrder fsServiceOrderRow,
            TimeSlot timeSlotAppointment,
            FSSchedule fsScheduleRow,
            bool insertingFromServiceOrder,
            bool isARouteAppointment,
            bool isPrepaidContract)
        {
            if (graphAppointmentEntry != null)
            {
                graphAppointmentEntry.Clear(PXClearOption.ClearAll);
            }
            else
            {
                graphAppointmentEntry = PXGraph.CreateInstance <AppointmentEntry>();
                graphAppointmentEntry.CalculateGoogleStats                = false;
                graphAppointmentEntry.AvoidCalculateRouteStats            = true;
                graphAppointmentEntry.IsGeneratingAppointment             = true;
                graphAppointmentEntry.DisableServiceOrderUnboundFieldCalc = true;
            }

            graphAppointmentEntry.SkipManualTimeFlagUpdate = true;

            FSScheduleRoute fsScheduleRouteRow = null;

            if (isARouteAppointment == true)
            {
                fsScheduleRouteRow =
                    PXSelect <FSScheduleRoute,
                              Where <
                                  FSScheduleRoute.scheduleID, Equal <Required <FSScheduleRoute.scheduleID> > > >
                    .Select(this, fsServiceOrderRow.ScheduleID);
            }

            FSAppointment fsAppointmentRow = new FSAppointment();

            fsAppointmentRow.SrvOrdType = fsServiceOrderRow.SrvOrdType;

            #region Setting flags for recurring appointments
            fsAppointmentRow.ValidatedByDispatcher = false;
            fsAppointmentRow.GeneratedBySystem     = true;
            fsAppointmentRow.Status = ID.Status_Appointment.AUTOMATIC_SCHEDULED;

            fsAppointmentRow = graphAppointmentEntry.AppointmentRecords.Insert(fsAppointmentRow);

            graphAppointmentEntry.AppointmentRecords.SetValueExt <FSAppointment.soRefNbr>(graphAppointmentEntry.AppointmentRecords.Current, fsServiceOrderRow.RefNbr);
            graphAppointmentEntry.AppointmentRecords.Cache.SetValueExt <FSAppointment.docDesc>(fsAppointmentRow, fsServiceOrderRow.DocDesc);

            if (isARouteAppointment)
            {
                graphAppointmentEntry.AppointmentRecords.Cache.SetValueExt <FSAppointment.scheduledDateTimeBegin>(fsAppointmentRow, timeSlotAppointment.DateTimeBegin);
                graphAppointmentEntry.AppointmentRecords.Cache.SetValueExt <FSAppointment.scheduledDateTimeEnd>(fsAppointmentRow, timeSlotAppointment.DateTimeEnd);
            }
            else
            {
                DateTime?scheduledDateTimeBegin = SharedFunctions.GetCustomDateTime(timeSlotAppointment.DateTimeBegin, fsScheduleRow.ScheduleStartTime);
                graphAppointmentEntry.AppointmentRecords.Cache.SetValueExt <FSAppointment.scheduledDateTimeBegin>(fsAppointmentRow, scheduledDateTimeBegin);
            }

            graphAppointmentEntry.AppointmentRecords.Cache.SetValueExt <FSAppointment.serviceContractID>(fsAppointmentRow, fsServiceOrderRow.ServiceContractID);

            if (isPrepaidContract == true &&
                graphAppointmentEntry.BillingCycleRelated.Current != null &&
                graphAppointmentEntry.BillingCycleRelated.Current.BillingBy == ID.Billing_By.APPOINTMENT)
            {
                graphAppointmentEntry.AppointmentRecords.Cache.SetValueExt <FSAppointment.billServiceContractID>(fsAppointmentRow, fsServiceOrderRow.ServiceContractID);
            }

            fsAppointmentRow = graphAppointmentEntry.AppointmentRecords.Current;

            //Total times get initialized
            fsAppointmentRow.EstimatedDurationTotal = 0;
            fsAppointmentRow.ActualDurationTotal    = 0;

            fsAppointmentRow.ScheduleID        = fsServiceOrderRow.ScheduleID;
            fsAppointmentRow.ServiceContractID = fsServiceOrderRow.ServiceContractID;
            fsAppointmentRow.GenerationID      = fsServiceOrderRow.GenerationID;

            fsAppointmentRow.SalesPersonID  = fsServiceOrderRow.SalesPersonID;
            fsAppointmentRow.Commissionable = fsServiceOrderRow.Commissionable;
            #endregion

            #region Setting route
            if (fsScheduleRouteRow != null)
            {
                switch (timeSlotAppointment.DateTimeBegin.DayOfWeek)
                {
                case DayOfWeek.Sunday:
                    if (fsScheduleRouteRow.RouteIDSunday != null)
                    {
                        fsAppointmentRow.RouteID = fsScheduleRouteRow.RouteIDSunday;
                    }

                    break;

                case DayOfWeek.Monday:
                    if (fsScheduleRouteRow.RouteIDMonday != null)
                    {
                        fsAppointmentRow.RouteID = fsScheduleRouteRow.RouteIDMonday;
                    }

                    break;

                case DayOfWeek.Tuesday:
                    if (fsScheduleRouteRow.RouteIDTuesday != null)
                    {
                        fsAppointmentRow.RouteID = fsScheduleRouteRow.RouteIDTuesday;
                    }

                    break;

                case DayOfWeek.Wednesday:
                    if (fsScheduleRouteRow.RouteIDWednesday != null)
                    {
                        fsAppointmentRow.RouteID = fsScheduleRouteRow.RouteIDWednesday;
                    }

                    break;

                case DayOfWeek.Thursday:
                    if (fsScheduleRouteRow.RouteIDThursday != null)
                    {
                        fsAppointmentRow.RouteID = fsScheduleRouteRow.RouteIDThursday;
                    }

                    break;

                case DayOfWeek.Friday:
                    if (fsScheduleRouteRow.RouteIDFriday != null)
                    {
                        fsAppointmentRow.RouteID = fsScheduleRouteRow.RouteIDFriday;
                    }

                    break;

                case DayOfWeek.Saturday:
                    if (fsScheduleRouteRow.RouteIDSaturday != null)
                    {
                        fsAppointmentRow.RouteID = fsScheduleRouteRow.RouteIDSaturday;
                    }

                    break;
                }

                if (fsAppointmentRow.RouteID == null)
                {
                    fsAppointmentRow.RouteID = fsScheduleRouteRow.DfltRouteID;
                }

                fsAppointmentRow.RoutePosition = int.Parse(fsScheduleRouteRow.GlobalSequence);

                if (fsAppointmentRow.DeliveryNotes == null)
                {
                    fsAppointmentRow.DeliveryNotes = fsScheduleRouteRow.DeliveryNotes;
                }
            }
            #endregion

            #region Setting Appointment Details

            foreach (FSSODetService fsSODetRow in graphServiceOrderEntry.ServiceOrderDetServices.Select())
            {
                var fsAppointmentDetRow = new FSAppointmentDetService();

                fsAppointmentDetRow.ScheduleID    = fsSODetRow.ScheduleID;
                fsAppointmentDetRow.ScheduleDetID = fsSODetRow.ScheduleDetID;

                AppointmentEntry.InsertServicePartLine <FSAppointmentDetService, FSSODetService>(
                    graphAppointmentEntry.AppointmentDetServices.Cache,
                    fsAppointmentDetRow,
                    graphServiceOrderEntry.ServiceOrderDetServices.Cache,
                    fsSODetRow,
                    fsSODetRow.NoteID,
                    fsSODetRow.SODetID,
                    copyTranDate: false,
                    tranDate: fsSODetRow.TranDate,
                    SetValuesAfterAssigningSODetID: false,
                    copyingFromQuote: false);
            }

            foreach (FSSODetPart fsSODetRow in graphServiceOrderEntry.ServiceOrderDetParts.Select())
            {
                var fsAppointmentDetRow = new FSAppointmentDetPart();

                fsAppointmentDetRow.ScheduleID    = fsSODetRow.ScheduleID;
                fsAppointmentDetRow.ScheduleDetID = fsSODetRow.ScheduleDetID;

                AppointmentEntry.InsertServicePartLine <FSAppointmentDetPart, FSSODetPart>(
                    graphAppointmentEntry.AppointmentDetParts.Cache,
                    fsAppointmentDetRow,
                    graphServiceOrderEntry.ServiceOrderDetParts.Cache,
                    fsSODetRow,
                    fsSODetRow.NoteID,
                    fsSODetRow.SODetID,
                    copyTranDate: false,
                    tranDate: fsSODetRow.TranDate,
                    SetValuesAfterAssigningSODetID: false,
                    copyingFromQuote: false);
            }

            foreach (FSSOEmployee fsSOEmployeeRow in graphServiceOrderEntry.ServiceOrderEmployees.Select())
            {
                FSAppointmentEmployee fsAppointmentEmployeeRow = new FSAppointmentEmployee();
                fsAppointmentEmployeeRow.EmployeeID = fsSOEmployeeRow.EmployeeID;
                graphAppointmentEntry.AppointmentEmployees.Insert(fsAppointmentEmployeeRow);
            }
            #endregion

            if (fsScheduleRow.VendorID != null)
            {
                FSAppointmentEmployee fsAppointmentEmployeeRow = new FSAppointmentEmployee();
                fsAppointmentEmployeeRow.EmployeeID = fsScheduleRow.VendorID;
                graphAppointmentEntry.AppointmentEmployees.Insert(fsAppointmentEmployeeRow);
            }

            if (insertingFromServiceOrder == true)
            {
                graphAppointmentEntry.SkipServiceOrderUpdate = true;
            }

            try
            {
                graphAppointmentEntry.Save.Press();
            }
            finally
            {
                graphAppointmentEntry.SkipServiceOrderUpdate = false;
            }
        }
        private static void X_RowSelected <DAC>(
            PXCache cache,
            object eRow,
            EventType eventType,
            FSServiceOrder fsServiceOrderRow,
            FSSrvOrdType fsSrvOrdTypeRow,
            bool disableSODetReferenceFields,
            bool docAllowsActualFieldEdition)
            where DAC : class, IBqlTable, IFSSODetBase, new()
        {
            if (eRow == null)
            {
                return;
            }

            var row = (DAC)eRow;

            Type                 dacType              = typeof(DAC);
            FSSODet              fsSODetRow           = null;
            bool                 calledFromSO         = false;
            bool                 calledFromAPP        = false;
            FSAppointmentDet     fsAppointmentDetRow  = null;
            FSAppointmentDetPart fsAppointmentDetPart = null;

            if (dacType == typeof(FSAppointmentDet) ||
                dacType == typeof(FSAppointmentDetService) ||
                dacType == typeof(FSAppointmentDetPart) ||
                dacType == typeof(FSAppointmentInventoryItem))
            {
                fsAppointmentDetRow = (FSAppointmentDet)eRow;
                if (dacType == typeof(FSAppointmentDetPart))
                {
                    fsAppointmentDetPart = (FSAppointmentDetPart)eRow;
                }
                calledFromAPP = true;
            }
            else
            {
                fsSODetRow   = (FSSODet)eRow;
                calledFromSO = true;
            }


            bool isEnabled;
            PXPersistingCheck persistingCheck;
            bool isInventoryLine = IsInventoryLine(row.LineType);
            bool isStockItem;

            if (isInventoryLine == false)
            {
                isStockItem = false;
            }
            else
            {
                if (row.LineType != ID.LineType_All.SERVICE &&
                    row.LineType != ID.LineType_All.NONSTOCKITEM)
                {
                    isStockItem = true;
                }
                else
                {
                    isStockItem = false;
                }
            }


            // Enable/Disable SODetID
            SetEnabledAndPersistingCheck <FSSODet.sODetID>(cache, eRow, eventType,
                                                           isEnabled: !disableSODetReferenceFields, persistingCheck: null);


            // Enable/Disable LineType
            SetEnabledAndPersistingCheck <FSSODet.lineType>(cache, eRow, eventType,
                                                            isEnabled: !disableSODetReferenceFields, persistingCheck: null);


            // Set InventoryID properties (SetEnabled and SetPersistingCheck)
            isEnabled       = true;
            persistingCheck = PXPersistingCheck.NullOrBlank;
            if (isInventoryLine == false)
            {
                isEnabled       = false;
                persistingCheck = PXPersistingCheck.Nothing;
            }
            else if (row.IsPrepaid == true ||
                     disableSODetReferenceFields == true ||
                     (calledFromSO == true && fsServiceOrderRow.AllowInvoice == true))
            {
                isEnabled = false;
            }

            SetEnabledAndPersistingCheck <FSSODet.inventoryID>(cache, eRow, eventType,
                                                               isEnabled, persistingCheck);


            if (PXAccess.FeatureInstalled <FeaturesSet.subItem>())
            {
                // Set SubItemID properties BASED ON InventoryID and LineType
                SetEnabledAndPersistingCheck <FSSODet.subItemID>(cache, eRow, eventType,
                                                                 isEnabled: isEnabled && isStockItem,
                                                                 persistingCheck: isStockItem == true ? persistingCheck : PXPersistingCheck.Nothing);
            }


            // Set UOM properties SAME AS InventoryID
            SetEnabledAndPersistingCheck <FSSODet.uOM>(cache, eRow, eventType,
                                                       isEnabled, persistingCheck);


            // Enable/Disable billingRule
            isEnabled = false;
            if ((row.LineType == ID.LineType_All.SERVICE || row.LineType == ID.LineType_All.NONSTOCKITEM) &&
                row.IsPrepaid == false &&
                (fsSODetRow == null || fsSODetRow.Mem_LastReferencedBy == null) &&
                (calledFromAPP == true || (calledFromSO == true && fsServiceOrderRow?.AllowInvoice == false)))
            {
                isEnabled = true;
            }

            SetEnabledAndPersistingCheck <FSSODet.billingRule>(cache, eRow, eventType,
                                                               isEnabled, persistingCheck: null);


            // Enable/Disable ManualPrice
            isEnabled = true;
            if (row.IsPrepaid == true ||
                isInventoryLine == false ||
                row.InventoryID == null ||
                (calledFromSO && fsServiceOrderRow?.AllowInvoice == true))
            {
                isEnabled = false;
            }

            SetEnabledAndPersistingCheck <FSSODet.manualPrice>(cache, eRow, eventType,
                                                               isEnabled, persistingCheck: null);


            // Enable/Disable IsBillable Same as ManualPrice

            SetEnabledAndPersistingCheck <FSSODet.isBillable>(cache, eRow, eventType,
                                                              isEnabled, persistingCheck: null);


            // Enable/Disable CuryUnitPrice
            isEnabled = false;
            if (row.BillingRule != ID.BillingRule.NONE &&
                row.IsPrepaid == false &&
                row.InventoryID != null &&
                (calledFromAPP == true || (calledFromSO == true && fsServiceOrderRow?.AllowInvoice == false)))
            {
                isEnabled = true;
            }

            SetEnabledAndPersistingCheck <FSSODet.curyUnitPrice>(cache, eRow, eventType,
                                                                 isEnabled, persistingCheck: null);



            // Enable/Disable EstimatedDuration and ActualDuration
            isEnabled = false;
            if (row.LineType == ID.LineType_All.SERVICE &&
                row.InventoryID != null &&
                (calledFromAPP == true || (calledFromSO == true && fsServiceOrderRow?.AllowInvoice == false)))
            {
                isEnabled = true;
            }

            SetEnabledAndPersistingCheck <FSSODet.estimatedDuration>(cache, eRow, eventType,
                                                                     isEnabled, persistingCheck: null);
            if (fsAppointmentDetRow != null)
            {
                //Enable when there is only 1 or 0 staff related to the service
                bool enableByStaffRelated = fsAppointmentDetRow.StaffRelatedCount < 2;
                SetEnabledAndPersistingCheck <FSAppointmentDet.actualDuration>(cache, eRow, eventType,
                                                                               isEnabled: isEnabled && docAllowsActualFieldEdition && enableByStaffRelated, persistingCheck: null);
            }


            // Enable/Disable EstimatedQty and ActualQty
            isEnabled = false;
            if (isInventoryLine == true &&
                row.BillingRule != ID.BillingRule.TIME &&
                row.IsPrepaid == false &&
                row.InventoryID != null &&
                (fsAppointmentDetPart == null || (string.IsNullOrEmpty(fsAppointmentDetPart.LotSerialNbr) == true ||
                                                  (string.IsNullOrEmpty(fsAppointmentDetPart.LotSerialNbr) == false &&
                                                   fsAppointmentDetPart.LotSerTrack != INLotSerTrack.SerialNumbered))) &&
                (calledFromAPP == true || (calledFromSO == true && fsServiceOrderRow?.AllowInvoice == false)))
            {
                isEnabled = true;
            }

            SetEnabledAndPersistingCheck <FSSODet.estimatedQty>(cache, eRow, eventType,
                                                                isEnabled, persistingCheck: null);
            if (fsAppointmentDetRow != null)
            {
                SetEnabledAndPersistingCheck <FSAppointmentDet.qty>(cache, eRow, eventType,
                                                                    isEnabled: isEnabled && docAllowsActualFieldEdition, persistingCheck: null);
            }


            // Set SiteID properties (SetEnabled and SetPersistingCheck)
            isEnabled       = false;
            persistingCheck = PXPersistingCheck.Nothing;
            if (isInventoryLine == true && row.InventoryID != null)
            {
                if (row.IsPrepaid == false)
                {
                    if (fsAppointmentDetPart != null)
                    {
                        isEnabled = fsAppointmentDetPart.SODetID == null;
                    }
                    else
                    {
                        isEnabled = true;
                    }
                }

                persistingCheck = PXPersistingCheck.NullOrBlank;
            }

            SetEnabledAndPersistingCheck <FSSODet.siteID>(cache, eRow, eventType,
                                                          isEnabled, persistingCheck);


            // Set SiteLocationID properties SAME AS SiteID
            SetEnabledAndPersistingCheck <FSSODet.siteLocationID>(cache, eRow, eventType,
                                                                  isEnabled, persistingCheck);


            // Set ProjectID properties (SetEnabled and SetPersistingCheck)
            isEnabled       = false;
            persistingCheck = PXPersistingCheck.Nothing;
            if (isInventoryLine == true && row.InventoryID != null)
            {
                isEnabled       = true;
                persistingCheck = PXPersistingCheck.NullOrBlank;
            }

            SetEnabledAndPersistingCheck <FSSODet.projectID>(cache, eRow, eventType,
                                                             isEnabled, persistingCheck);


            // Set ProjectTaskID properties (SetEnabled and SetPersistingCheck)
            isEnabled       = true;
            persistingCheck = PXPersistingCheck.Nothing;
            if (isInventoryLine == false || row.InventoryID == null)
            {
                isEnabled = false;
            }
            else if (ProjectDefaultAttribute.IsProject(cache.Graph, row.ProjectID) == true)
            {
                persistingCheck = PXPersistingCheck.NullOrBlank;
            }

            SetEnabledAndPersistingCheck <FSSODet.projectTaskID>(cache, eRow, eventType,
                                                                 isEnabled, persistingCheck);


            // Set CostCodeID properties (SetEnabled and SetPersistingCheck)
            isEnabled       = true;
            persistingCheck = PXPersistingCheck.Nothing;
            if (isInventoryLine == false || row.InventoryID == null)
            {
                isEnabled = false;
            }
            else if (ProjectDefaultAttribute.IsProject(cache.Graph, row.ProjectID) == true)
            {
                persistingCheck = PXPersistingCheck.NullOrBlank;
            }

            SetEnabledAndPersistingCheck <FSSODet.costCodeID>(cache, eRow, eventType,
                                                              isEnabled, persistingCheck);


            // Set AcctID properties (SetEnabled and SetPersistingCheck)
            isEnabled       = false;
            persistingCheck = PXPersistingCheck.Nothing;
            if (isInventoryLine == true &&
                row.InventoryID != null &&
                fsServiceOrderRow?.Quote == false &&
                fsSrvOrdTypeRow?.Behavior != ID.Behavior_SrvOrderType.INTERNAL_APPOINTMENT)
            {
                isEnabled       = true;
                persistingCheck = PXPersistingCheck.NullOrBlank;
            }

            SetEnabledAndPersistingCheck <FSSODet.acctID>(cache, eRow, eventType,
                                                          isEnabled, persistingCheck);


            // Set SubID properties SAME AS AcctID
            SetEnabledAndPersistingCheck <FSSODet.subID>(cache, eRow, eventType,
                                                         isEnabled, persistingCheck);


            // Set PickupDeliveryServiceID properties (SetEnabled and SetPersistingCheck)
            if (fsAppointmentDetRow != null && dacType == typeof(FSAppointmentInventoryItem))
            {
                isEnabled       = false;
                persistingCheck = PXPersistingCheck.Nothing;
                if (row.LineType == ID.LineType_All.PICKUP_DELIVERY)
                {
                    isEnabled       = true;
                    persistingCheck = PXPersistingCheck.NullOrBlank;
                }

                SetEnabledAndPersistingCheck <FSAppointmentInventoryItem.pickupDeliveryServiceID>(cache, eRow, eventType,
                                                                                                  isEnabled, persistingCheck);
            }


            // Set IsBillable properties (SetEnabled and SetPersistingCheck)

            isEnabled = true;
            if (row.ContractRelated == true || row.IsPrepaid == true)
            {
                isEnabled = false;
            }

            SetEnabledAndPersistingCheck <FSSODet.isBillable>(cache, eRow, eventType,
                                                              isEnabled, persistingCheck: null);

            // Set TranDesc properties (SetEnabled and SetPersistingCheck)
            isEnabled       = true;
            persistingCheck = PXPersistingCheck.Nothing;
            if (isInventoryLine == false)
            {
                persistingCheck = PXPersistingCheck.NullOrBlank;
            }

            SetEnabledAndPersistingCheck <FSSODet.tranDesc>(cache, eRow, eventType,
                                                            isEnabled, persistingCheck);

            isEnabled       = false;
            persistingCheck = PXPersistingCheck.Nothing;
            if (fsSODetRow != null && fsSODetRow.EnablePO == true)
            {
                persistingCheck = PXPersistingCheck.NullOrBlank;
                isEnabled       = true;
            }

            SetEnabledAndPersistingCheck <FSSODet.curyUnitCost>(cache, eRow, eventType,
                                                                isEnabled, persistingCheck);


            SharedFunctions.UpdateEquipmentAction(cache, eRow);
            // Additional Enable/Disable for Equipment fields
            if ((calledFromSO == true && fsServiceOrderRow?.AllowInvoice == true))
            {
                isEnabled = false;
                SetEnabledAndPersistingCheck <FSSODet.SMequipmentID>(cache, eRow, eventType,
                                                                     isEnabled, persistingCheck: null);
            }
        }