首页 文章

带参数的Acumatica处理屏幕不刷新

提问于
浏览
1

Issue Summary:

我的新屏幕上的处理逻辑正在运行,但页面未向用户显示任何反馈(例如,计时器未显示,没有红色/绿色复选框,未禁用复选框)

Issue Detail:

我正在创建一个处理屏幕,要求处理代表使用来自用户的单独信息 . 业务逻辑有效,但用户体验与其他处理屏幕不同 . 单击“处理”时,没有向用户显示任何内容 . 通常,页面通过禁用并仅显示正在处理的所选项目来刷新网格,此外还添加了长操作计时器(然后由绿色检查替换,或者根据流程是成功还是失败来替换红色x) . 当我单击进程时,将检查所有整个网格的选定列,但是没有其他任何更改(例如,没有计时器,状态,也没有禁用网格) . 最终,流程和流程都执行业务逻辑,但用户没有看到任何指示所述成功/失败的信息 .

屏幕显示所有客户位置,因为该流程正在根据每个位置的订单更新我们为每个位置保留的一些统计信息 .

My Graph

public class CalculateLocationStatsProcess : PXGraph<CalculateLocationStatsProcess>
{
    public PXCancel<LocationStatsFilter> Cancel;

    public PXFilter<LocationStatsFilter> filterLocStat;
    public PXFilteredProcessingJoin<Location,
        LocationStatsFilter,
        InnerJoin<Customer, On<Customer.bAccountID, Equal<Location.bAccountID>>>,
        Where<True, Equal<True>>,
        OrderBy<Asc<Customer.acctCD, Asc<Location.locationCD>>>> processLocations;

    public CalculateLocationStatsProcess()
    {
    }

    public virtual void LocationStatsFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
    {
        processLocations.SetProcessDelegate(
            delegate (List<Location> list)
            {
                var newList = new List<Location>();
                foreach (Location locLp in list)
                {
                    newList.Add(locLp);
                }
                CalculateLocationStatsProcess.updateLocationStats(newList, filterLocStat.Current);
            }
        );
    }

    public static void updateLocationStats(List<Location> locations, LocationStatsFilter filter)
    {
        var graph = new PXGraph();
        var locStats = new StatsHelper(graph, filter.TargetDate);

        bool erred = false;
        for (int iLp = 0; iLp < locations.Count; iLp++)
        {
            Location locationLp = locations[iLp];
            PXProcessing<Location>.SetCurrentItem(locationLp);
            try
            {
                locStats.setCommStats(locationLp);
            }
            catch (Exception ex)
            {
                erred = true;
                PXProcessing<Location>.SetError(iLp, ex.Message);
            }
        }

        locStats.StatCache.Persist(PXDBOperation.Insert);
        locStats.StatCache.Persist(PXDBOperation.Update);

        if (erred)
        {
            throw new PXException("Location(s) failed during recalculation process. View individual lines to see their specific error.");
        }
    }
}

My Page

<%@ Page Language="C#" MasterPageFile="~/MasterPages/FormDetail.master" AutoEventWireup="true" ValidateRequest="false" CodeFile="SO509503.aspx.cs" Inherits="Page_SO509503" Title="Calculate Location Stats" %>
<%@ MasterType VirtualPath="~/MasterPages/FormDetail.master" %>

<asp:Content ID="cont1" ContentPlaceHolderID="phDS" runat="Server">
    <px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%" PrimaryView="filterLocStat" TypeName="exampleNS.CalculateLocationStatsProcess">
        <CallbackCommands>
        </CallbackCommands>
    </px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" runat="Server">
    <px:PXFormView ID="formFilter" runat="server" DataMember="filterLocStat" DataSourceID="ds" Style="z-index: 100" Width="100%" >
        <Template>
            <px:PXLayoutRule runat="server" ID="PXLayoutRule1" ControlSize="M" LabelsWidth="M" StartRow="true" />
            <px:PXDateTimeEdit runat="server" ID="edTargetDate" DataField="TargetDate" />
        </Template>
    </px:PXFormView>
</asp:Content>
<asp:Content ID="cont3" ContentPlaceHolderID="phG" runat="Server">
    <px:PXGrid ID="gridLocations" runat="server" 
        AdjustPageSize="Auto" AllowPaging="True" AllowSearch="true" DataSourceID="ds" FilesIndicator="false" 
        Height="400px" NoteIndicator="false" SkinID="Inquire" Style="z-index: 100" SyncPosition="true" Width="100%" >
        <AutoSize Container="Window" Enabled="True" MinHeight="200" />
        <Levels>
            <px:PXGridLevel DataMember="processLocations">
                <Columns>
                    <px:PXGridColumn DataField="Selected" Type="CheckBox" AllowCheckAll="true" Width="40px" />
                    <px:PXGridColumn DataField="Customer__AcctCD" Width="125px" />
                    <px:PXGridColumn DataField="LocationCD" Width="75px" />
                    <px:PXGridColumn DataField="Descr" Width="175px" />
                </Columns>
            </px:PXGridLevel>
        </Levels>
    </px:PXGrid>
</asp:Content>

My Filter DAC

public class LocationStatsFilter : IBqlTable
{
    #region TargetDate
    public abstract class targetDate : IBqlField { }
    [PXDate()]
    [PXUIField(DisplayName = "Target Month and Year")]
    public virtual DateTime? TargetDate { get; set; }
    #endregion
}

My Location Extension DAC

[PXTable(typeof(Location.locationID), typeof(Location.bAccountID), IsOptional = false)]
public class LocationExt : PXCacheExtension<Location>
{
    #region Selected
    public abstract class selected : IBqlField { }
    [PXBool()]
    [PXDefault(false)]
    [PXUIField(DisplayName = "Selected")]
    public virtual bool? Selected { get; set; }
    #endregion
    #region DateFirstService
    public abstract class dateFirstService : IBqlField { }
    [PXDBDate()]
    [PXUIField(DisplayName = "Date of First Service")]
    public virtual DateTime? DateFirstService { get; set; }
    #endregion
}

在我找到的几个处理屏幕之后,我对我的解决方案进行了建模,但是我看了很多,我不知道我用哪些作为例子 . 我已经在RowSelected事件和构造函数之间移动了SetProcessDelegate调用而没有运气 . 我试图将updateLocationStats函数设置为静态而非静态(使用现有图形),但没有成功 .

更新:

  • 直接调用updateLocationStats方法而不是创建List的副本不会更改结果 .

  • 将PXFilterable添加到PXFilteredProcessingJoin并未更改结果

  • 删除对locStats的调用(creation,setCommStats(locationLp),Persist)没有改变结果

  • 添加了缺少的位置DAC

  • 尝试将选定的LocationExt DAC移动到新的LocationAlt:位置DAC,结果没有变化 .

  • 将DataType = "Boolean"添加到页面中的选定字段 . 行为没有变化

  • 将BatchUpdate = "True"添加到PXGrid标记 . 行为没有变化 .

  • 添加了PXProcessing.SetProcessed();在locStats.setCommStats(locationLp)之后;没有改变行为 .

Alternate Test

public class LocationAlt : Location
{
    #region Selected
    public abstract class selected : IBqlField { }
    [PXBool()]
    [PXDefault(false)]
    [PXUIField(DisplayName = "Selected")]
    public virtual bool? Selected { get; set; }
    #endregion
}

public class CalculateLocationStatsProcess : PXGraph<CalculateLocationStatsProcess>
{
    public PXCancel<LocationStatsFilter> Cancel;

    public PXFilter<LocationStatsFilter> filterLocStat;
    [PXFilterable()]
    public PXFilteredProcessingJoin<LocationAlt,
        LocationStatsFilter,
        InnerJoin<Customer, On<Customer.bAccountID, Equal<LocationAlt.bAccountID>>>,
        Where<True, Equal<True>>,
        OrderBy<Asc<Customer.acctCD, Asc<LocationAlt.locationCD>>>> processLocations;

    public CalculateLocationStatsProcess()
    {
    }

    public virtual void LocationStatsFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
    {
        processLocations.SetProcessDelegate(
            delegate (List<LocationAlt> list)
            {
                CalculateLocationStatsProcess.updateLocationStats(list, filterLocStat.Current);
            }
        );
    }

    public static void updateLocationStats(List<LocationAlt> locations, LocationStatsFilter filter)
    {
        var graph = new PXGraph();
        var locStats = new CommStatsHelper(graph, filter.TargetDate);

        bool erred = false;
        for (int iLp = 0; iLp < locations.Count; iLp++)
        {
            LocationAlt locationLp = locations[iLp];
            PXProcessing<LocationAlt>.SetCurrentItem(locationLp);
            try
            {
                locStats.setCommStats(locationLp);
            }
            catch (Exception ex)
            {
                erred = true;
                PXProcessing<LocationAlt>.SetError(iLp, ex.Message);
            }
        }

        locStats.StatCache.Persist(PXDBOperation.Insert);
        locStats.StatCache.Persist(PXDBOperation.Update);

        if (erred)
        {
            throw new PXException("Location(s) failed during recalculation process. View individual lines to see their specific error.");
        }
    }
}

请注意,备用测试也不起作用 .

2 回答

  • 0

    遇到的问题是因为原始图形实例(即您第一次进入屏幕时所处的图形实例)不能保持执行图形实例的范围(即图形的实例)做逻辑) .

    为了让Acumatica放置处理状态逻辑(例如,计时器,绿色/红色状态圆圈),原始图形需要链接到执行操作的图形 . 当您将SetProcessDelegate指向方法委托时,这似乎可以为您处理 .

    在此处的问题中,您正在创建一个ad-hoc委托(通过在构造函数/ rowselected事件中使用delegate关键字) . 变量声明(不是实例化)需要在委托之外 .

    Corrected Setting of Delegate

    CalculateLocationStatsProcess graph = null;
    processLocations.SetProcessDelegate((List<Location> list) => 
        {
            graph = PXGraph.CreateInstance<CalculateLocationStatsProcess>();
            CalculateLocationStatsProcess.updateLocationStats(list, filterLocStat.Current);
        }
    );
    

    注意第一行是在SetProcessDelegate调用之前 . 即使图形未在委托外部实例化,也会创建图形指针 . 因此,当分配了链接并且UI根据需要更新时,它就会出现 .

    补充说明

    • 所选字段仍作为扩展名的一部分存在

    • 我把函数保留为静态,但如果转换为非静态,它确实可以正常工作,只需将 CalculateLocationStatsProcess.updateLocationStats(list, filterLocStat.Current); 更改为 graph.updateLocationStats(list, filterLocStat.Current);

    • 委托声明可以在构造函数 public CalculateLocationStatsProcess() 中发生,也可以在Filter的行选择事件处理程序_1878459中发生,两者都适用于我 .

    • BatchUpdate="true" 没有必要 .

    • DataType="Boolean" 没有必要 .

    最后,链接的 Customer__AcctCD 在进程完成时清除(连接似乎不会保持字段填充),因此在图表上显示 AcctCD 的某些代码将需要更改 . 由于这不是所提出问题的焦点,我不打算在此处包含该代码 .

  • 1

    我相信你错过了DAC中的Selected数据字段:

    #region Selected
    public abstract class selected : IBqlField
    {
    }
    protected bool? _Selected = false;
    [PXBool]
    [PXDefault(false)]
    [PXUIField(DisplayName = "Selected")]
    public bool? Selected
    {
        get
        {
            return _Selected;
        }
        set
        {
            _Selected = value;
        }
    }
    #endregion
    

    而不是直接使用Location,为Location(LocationStat?)创建一个DAC扩展您将添加“选定”字段 . 不要在处理屏幕中使用“位置”,请使用包含所选字段的扩展名 .

相关问题