如何使用 PXProtectedAccess 覆盖受保护的方法?

How to override a protected method using PXProtectedAccess?

我需要在生成服务订单时覆盖服务合同计划的下次执行日期。这会根据事件设置自动计算。虽然计算不符合我的要求,所以我需要覆盖它。

查看源代码,我找到了需要重写的方法。不幸的是它被保护了。

我找到了这个 但我没有这么幸运。不确定我在这里错过了什么?我的代码如下:

[PXProtectedAccess]
public abstract class ServiceContractInqExt1 : PXGraphExtension<ServiceContractInq>
{
    [PXProtectedAccess]
    protected abstract void UpdateGeneratedSchedule(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow);
}

public class ServiceContractInqExt2: PXGraphExtension<ServiceContractInqExt1,ServiceContractInq>
{
    #region Event Handlers
    public static bool IsActive()
    {
        return true;
    }

    public delegate void UpdateGeneratedScheduleDelegate(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow);
    [PXOverride]
    public virtual void UpdateGeneratedSchedule(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow,UpdateGeneratedScheduleDelegate baseMethod)
    {
      PXTrace.WriteInformation("HIT !");//this is not firing !
      baseMethod(scheduleID, toDate, lastGeneratedElementDate, fsScheduleRow);
    }
    #endregion
}

编辑: 按照下面的答案。

using PX.Data;
using PX.Objects.CR;
using PX.Objects.CS;
using PX.Objects.FS.Scheduler;
using PX.SM;
using System;
using System.Collections;
using System.Collections.Generic;
using PX.Objects.AR;
using PX.Objects;
using PX.Objects.FS;

namespace PX.Objects.FS
{
  [PXProtectedAccess]
  public abstract class AAServiceContractInqExtension : PXGraphExtension<ServiceContractInq>
  {
      [PXProtectedAccess]
      protected void UpdateGeneratedSchedule(int scheduleID, DateTime? toDate, DateTime? lastGeneratedElementDate, FSSchedule fsScheduleRow)
      {
          PXTrace.WriteInformation("HIT");
      }
  }  
}

并且只是加载页面会引发错误。

我的 Acumatica build/version

不幸的是,您将无法覆盖方法 UpdateGeneratedSchedule,因为它没有标记为 virtual,因此即使可以访问 ContractGenerationEnqBase 图,我们也无法修改它功能。

考虑到这一点,我成功实施了以下解决方案

public class ServiceContractInqExtension : PXGraphExtension<ServiceContractInq>
{
    public delegate void ProcessServiceContractDelegate(PXCache cache, FSContractSchedule fsScheduleRow, DateTime? fromDate, DateTime? toDate);

    [PXOverride]
    public virtual void processServiceContract(PXCache cache, FSContractSchedule fsScheduleRow, DateTime? fromDate, DateTime? toDate, ProcessServiceContractDelegate del)
    {
        del?.Invoke(cache, fsScheduleRow, fromDate, toDate);
        UpdateGeneratedSchedule(fsScheduleRow.ScheduleID, new DateTime(2023, 3, 11));
    }

    protected void UpdateGeneratedSchedule(int? scheduleID, DateTime nextExecutionDate)
    {
                PXUpdate<Set<FSSchedule.nextExecutionDate, Required<FSSchedule.nextExecutionDate>>, FSSchedule,
                Where<
                    FSSchedule.scheduleID, Equal<Required<FSSchedule.scheduleID>>>>
                .Update(Base, nextExecutionDate, scheduleID);
    }
}

处理方法完成后,自定义 UpdateGeneratedSchedule 将利用 PXUpdate 设置所需的字段值。 PXUpdate 与您最初想要覆盖的方法使用的调用相同。

在这里我们可以看到其中一个处理前的时间表

调用自定义代码后,我们可以看到 'Next Execution Date' 是提供给自定义方法的值。