Acumatica 采购收据退货:未清采购订单行默认为 false

时间:2021-07-07 19:57:46

标签: return default acumatica receipt

点击已完成采购收据中选定项目的“退货”操作后,我们尝试将“打开订单行”值设为默认值。有人知道如何自定义吗?

当我们按下“返回”按钮时,默认字段似乎被覆盖了。我们在网格中尝试了几个不同的事件,但似乎都没有奏效。

期望的结果是在退货后将“打开订单行”默认为 false,一旦退货被下达,与退货相关的采购订单行应保持完成。

enter image description here

1 个答案:

答案 0 :(得分:0)

研究

POReceiptLine 上的 AllowOpen 字段是一个 PXBool。这意味着必须通过 PXDBScalar、PXFormula 等或通过图中的某些业务逻辑填充该值。要了解发生了什么,让我们看看 POReceiptLine 的 DAC...

#region AllowOpen
public abstract class allowOpen : PX.Data.BQL.BqlBool.Field<allowOpen> { }
protected Boolean? _AllowOpen;
[PXBool()]
[PXUIField(DisplayName = "Open PO Line", Visibility = PXUIVisibility.Service, Visible = true)]
public virtual Boolean? AllowOpen
{
    get
    {
        return this._AllowOpen;
    }
    set
    {
        this._AllowOpen = value;

    }
}
#endregion

如您所见,DAC 中的该字段没有任何逻辑,因此我们需要转向图表以了解它是如何使用的。 (即使 DAC 中有逻辑,我们也需要查看图形是否执行某些操作。但是,DAC 中的逻辑可能很容易被 CacheAttached 覆盖 - 不幸的是,在这种情况下并非如此。)

让我们转向处理退货的 POReceiptEntry。我们发现在 POReceiptLine_RowSelected 事件中设置了 AllowComplete 和 AllowOpen,正如我们所期望的那样,因为它必须填充在 DAC 中没有逻辑的代码的图形侧。

if ((row.AllowComplete == null || row.AllowOpen == null) && fromPO)
{
    POLineR source = PXSelect<POLineR,
        Where<POLineR.orderType, Equal<Required<POLineR.orderType>>,
        And<POLineR.orderNbr, Equal<Required<POLineR.orderNbr>>,
        And<POLineR.lineNbr, Equal<Required<POLineR.lineNbr>>>>>>
        .Select(this, row.POType, row.PONbr, row.POLineNbr);

// Acuminator disable once PX1047 RowChangesInEventHandlersForbiddenForArgs [Legacy, moved the exception here from PX.Objects.acuminator because the condition was changed]
row.AllowComplete = row.AllowOpen = (row.Released == true) ?
    (row.ReceiptType != POReceiptType.POReturn ? source?.Completed == true : source?.Completed != true) :
    (source?.AllowComplete ?? false);

该字段填充在代码的 row.AllowComplete = row.AllowOpen = (row.Released == true) ?... 部分。

随后,我们看到 CopyFromOrigReceiptLine 方法在正在创建的“destLine”上将此值设置为 false。

destLine.AllowOpen = false;

因为这不是“真的”,所以我们知道这不是我们的位置。继续,我们在 UpdatePOLineCompletedFlag 中看到 AllowComplete 和 AllowOpen 正在被设置。这可能是我们的位置(或其中之一)。

row.AllowComplete = row.AllowOpen = poLineCurrent.AllowComplete;

旁注:值得注意的是,该行在 if then else 中出现了两次。在这两种情况下,它将被执行,因此最好的编码实践是在 if then else 之后放置这个相同的语句,因为 if 和 else 条件都将执行相同的语句,而不管 if 是什么。 >

此特定用途似乎是从正在接收的采购订单行的 AllowComplete 字段中提取值。 此时,您应该考虑是否需要查看采购订单行的上游以查看那里的字段是否也需要进行操作。我无法为您回答这个问题,因为您的商业案例将推动决策。

Copy 方法中还有一行设置 AllowComplete 和 AllowOpen。​​

aDest.AllowComplete = aDest.AllowOpen = (aSrc.CompletePOLine == CompletePOLineTypes.Quantity);

Copy 方法被重载,该方法的另一个签名将值设置为 true。

aDest.AllowComplete = true;
aDest.AllowOpen = true;

这两种情况可能也需要定制,但我认为这不是主要问题。

后续步骤

此时,我们看到该字段要么是在 UpdatePOLineCompletedFlag 中设置的,要么是在似乎与复制记录相关的方法中设置的。如果复制相关方法也需要更改,您将需要进一步调查。但是,我认为最初的重点应该放在 UpdatePOLineCompletedFlag 方法上。

如果我们发现识别出的其他点需要自定义,我们可能会以相同的方式处理它们...覆盖基本方法/事件,在我们的覆盖中调用原始方法/事件,然后强制这些值适合我们的商业案例。需要仔细测试,因为强行更改这些值可能会产生不可预见的负面影响。

尝试一下

我们想要更新(或创建)POReceiptEntry 的图形扩展以覆盖 UpdatePOLineCompleteFlag 方法。这可以编译,但对我而言它完全未经测试。我们需要创建一个委托并指定 PXOverride 属性。然后我们想在覆盖有问题的字段之前执行基本方法。

注意额外的代码(注释掉)作为提醒您需要小心更新我们在缓存中的记录的方法(通常是事件)并且需要定位以便我们不使用陈旧的副本的记录。我认为在这种情况下没有必要,但在我看到的代码示例中似乎有些模糊。当然,那是因为我一直在查看代码库,其中很少有图扩展覆盖事件处理程序!

#region CreateReceiptEntry Override
public delegate void UpdatePOLineCompleteFlagDelegate(POReceiptLine row, bool isDeleted, POLine aOriginLine);
[PXOverride]
public virtual void UpdatePOLineCompleteFlag(POReceiptLine row, bool isDeleted, POLine aOriginLine, UpdatePOLineCompleteFlagDelegate baseMethod)
{
    //Execute original logic
    baseMethod(row, isDeleted, aOriginLine);
    
    /* If the base method has updated the cache, then we would need to locate the updated record in the cache to proceed
     * This tends to be the case more often with event handlers, so it probably isn't needed in this case.
     * This is just for reference as a training reminder
    //If row has been updatd in the baseMethod, let's go get the updated cache values
    POReceiptLine locateRow = Base.transactions.Locate(row);
    if (locateRow != null) row = locateRow;
    */

    //Override the fields to false - need to test to see if this creates any issues with breaking existing business logic
    row.AllowComplete = row.AllowOpen = false;
}
#endregion

如果这不能为您提供所需的具体答案,我希望它至少能让您深入了解如何寻找要改变的“点”。我怀疑您可能需要更新 POLine 以获得如上所述的完整解决方案。 (有关导致我得出该结论的代码,请参阅事件处理程序 POReceiptLine_AllowOpen_FieldUpdated。)

祝您定制好运,编码愉快!