【问题标题】:Acumatica API: Using .ActionConvertToBAccount for converting Lead is failingAcumatica API:使用 .ActionConvertToBAccount 转换潜在客户失败
【发布时间】:2015-12-29 03:11:02
【问题描述】:

我正在尝试使用潜在客户屏幕的 Acumatica API(版本 4.20.2231)将潜在客户转换为企业帐户。甚至在我尝试之前我就有点担心,因为当您在 Acumatica 中使用“转换为企业帐户”操作时,它会弹出一个小对话框。选择“操作”>“转换为企业帐户”后,它在 Acumatica 中的外观如下:

使用 API,我尝试的第一个命令排列是未能转换 Lead 并且没有产生任何类型的错误。最终,我发现了一系列命令,这些命令产生了引用对话框的错误,这让我觉得我走在了正确的轨道上。也许我只是不知道如何使用命令来操作对话框。有谁知道我要去哪里错了?这是我的代码:

Public Function ConvertLeadToCustomer(ByVal leadID As String, ByVal firstName As String, ByVal lastName As String, ByRef companyName As String) As String
    Dim CR301000 As CR301000Content = m_context.CR301000GetSchema()
    m_context.CR301000Clear()

    ' converting a lead requires that there is a value for company, so create one if it is blank
    If companyName = "" Then
        companyName = lastName & ", " & firstName
    End If

    ' create key field
    Dim leadKeyValue As Value = New Value With {.LinkedCommand = CR301000.LeadSummary.LeadID, .Value = leadID}

    ' create company field, since its required
    Dim companyValue As Value = New Value With {.LinkedCommand = CR301000.DetailsSummary.CompanyName, .Value = companyName, .Commit = True}

    Dim updateLeadCommands As Command() = {leadKeyValue, CR301000.Actions.ActionConvertToBAccount, companyValue, CR301000.Actions.Save}
    Dim updateLeadResult As CR301000Content() = m_context.CR301000Submit(updateLeadCommands)

    ' TO DO: search Business Accounts by name to find new Business Account ID
    Dim newBAID As String = ""
    Return newBAID 
End Function

这里是调用 CR301000Submit 时返回的错误:

System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> PX.Data.PXDialogRequiredException
    at PX.Data.DialogManager.a(String A_0, PXGraph A_1, String A_2, Object A_3, String A_4, String A_5, MessageButtons A_6, MessageIcon A_7, Boolean A_8, InitializePanel A_9)
    at PX.Data.DialogManager.AskExt(PXView view, String key, InitializePanel initializeHandler, Boolean repaintControls)
    at PX.Data.PXView.AskExt(InitializePanel initializeHandler, Boolean refreshRequired)
    at PX.Objects.CR.LeadMaint.ConvertToBAccount(PXAdapter adapter)
    at PX.Data.PXAction`1.a(PXAdapter A_0)
    at PX.Data.PXAction`1.<Press>d__c.MoveNext()
    at PX.Data.PXAction`1.<Press>d__c.MoveNext()
    at PX.Data.PXAction`1.<Press>d__c.MoveNext()
    at PX.Data.PXAction`1.<Press>d__c.MoveNext()
    at PX.Api.SyImportProcessor.SyStep.CommitChanges(Object itemToBypass, PXFilterRow[] targetConditions)
    at PX.Api.SyImportProcessor.ExportTableHelper.ExportTable()
    at PX.Api.ScreenUtils.Submit(String screenId, Command[] commands, SchemaMode schemaMode, PXGraph graph)
    at PX.Api.Services.ScreenService.Submit(String id, IEnumerable`1 commands, SchemaMode schemaMode)
    at PX.Api.Soap.Screen.ScreenGate.Submit(Command[] commands)
--- End of inner exception stack trace --- 

【问题讨论】:

  • 我认为您为该对话框设置了错误的链接命令。在您提供的示例中,您正在设置“CR301000.LeadSummary.LeadID”的值,这不是弹出窗口。设置弹出信息并在调用 ActionConvertToBAccount 之前添加创建按钮的命令

标签: acumatica


【解决方案1】:

您当前的问题

出现您的错误是因为操作 ConvertToBAccount 正在调用弹出对话框并期待答案:

if (AccountInfo.AskExt((graph, view) => graph.Views[view].Cache.Clear(), true) != WebDialogResult.OK) return contacts;

告诉 Acumatica 答案的方法是在调用操作之前发送值“OK”。根据您的配置,您可能还希望在此弹出窗口中填充该字段:

Dim commandsConvert As Command() =
    {
        New Value With {.Value = leadID, .LinkedCommand = CR301000.LeadSummary.LeadID, .Commit = True},
        New Value With {.Value = "OK", .LinkedCommand = CR301000.NewAccountServicesSettings.ServiceCommands.DialogAnswer, .Commit = True}, 'This is how close the pop-up. We fill the field from the pop-up after this line
        New Value With {.Value = newCompanyCD, .LinkedCommand = CR301000.NewAccountServicesSettings.BAccountID}, 'With autonumbering On, no need for this line.
        New Value With {.Value = newCompanyName, .LinkedCommand = CR301000.NewAccountServicesSettings.AccountName}, 'The default value will be taken from DetailsSummary.CompanyName
        CR301000.Actions.ActionConvertToBAccount
    }

m_context.CR301000Submit(commandsConvert)

你未来的问题

Lead 转换为 BAccount 是一个两步过程,您将被重定向到新创建的 BAccount 和您需要的位置保存它。 只要不保存就不会转换。

这通常是一个非常简单的过程,或者您只需将 Save 提交到您被重定向的页面 (CR303000):

'Once the Process is completed, We want to save the new record.
'If we want to edit some information on the new Business Account
'this is the right place to do it.

Dim newBAID As String = String.Empty
Dim commandsBAccount As Command() =
    {
        CR303000.Actions.Save,
        CR303000.AccountSummary.BusinessAccount
    }
Dim newBAccountContent As CR303000Content() = m_context.CR303000Submit(commandsBAccount)
If newBAccountContent.Length > 0 Then
    newBAID = newBAccountContent(0).AccountSummary.BusinessAccount.Value
End If

只要您保留相同的 cookie 容器,UserState 应该知道您当前处于带有缓存信息的脏 CR303000 上。如果您使用包含 CR301000 和 CR303000 的自定义 Web 服务端点,则无需处理任何事情。

不幸的是,在这种情况下它不起作用。

似乎PXRedirectRequiredException 是从PXLongOperation(阅读线程)中引发的,并且Web 服务没有选择BAccount的脏状态>。我现在能找到的唯一解决方案是自定义操作ConvertToBAccount 以删除线程:

public class LeadMaintExt : PXGraphExtension<LeadMaint>
{
    [PXUIField(DisplayName = Messages.ConvertToBAccount, MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Select)]
    [PXButton(ImageKey = PX.Web.UI.Sprite.Main.Process)]
    public virtual IEnumerable ConvertToBAccount(PXAdapter adapter)
    {
        List<Contact> contacts = new List<Contact>(adapter.Get().Cast<Contact>());
        foreach (Contact lead in contacts)
        {
            if (Base.AccountInfo.AskExt((graph, view) => graph.Views[view].Cache.Clear(), true) != WebDialogResult.OK) return contacts;
            bool empty_required = !Base.AccountInfo.VerifyRequired();
            BAccount existing = PXSelect<BAccount, Where<BAccount.acctCD, Equal<Required<BAccount.acctCD>>>>.SelectSingleBound(Base, null, Base.AccountInfo.Current.BAccountID);
            if (existing != null)
            {
                Base.AccountInfo.Cache.RaiseExceptionHandling<LeadMaint.AccountsFilter.bAccountID>(Base.AccountInfo.Current, Base.AccountInfo.Current.BAccountID, new PXSetPropertyException(Messages.BAccountAlreadyExists, Base.AccountInfo.Current.BAccountID));
                return contacts;
            }
            if (empty_required) return contacts;

            Base.Save.Press();
            //PXLongOperation.StartOperation(this, () => ConvertToAccount(lead, AccountInfo.Current));
            LeadMaint.ConvertToAccount(lead, Base.AccountInfo.Current);
        }
        return contacts;
    }
}

我正在寻找一种更好的方法来解决这种情况,当我找到它时我会编辑我的答案。

【讨论】:

  • 感谢@Philippe 的第一个答案以及对第二个问题的预期并进一步研究。是的,如果您找到其他解决方案,请告诉我。
  • 嗨@Philippe,我们还没有进行自定义,但我们正在升级到 5.20.2067 版本。这个问题在 5.20.2067 版本中修复了吗?如果没有,那么我们将在更新完成后进行更改。 5.20.2067 版本中的定制是否会有所不同,还是与您提供的一样?谢谢!
【解决方案2】:

指定的命令应该用于对话框而不是摘要。 在调用操作之前,应提供必填字段和对话答案。

以下是用于在收据屏幕中创建收据操作的示例。 注意:C#代码

   commands = new Command[]
            {          
                 new Value 
                {

                    Value = CreatedOn.HasValue ? ((DateTime)CreatedOn.Value).ToLongDateString() : "",  
                    LinkedCommand = SOSchema.SpecifyShipmentParameters.ShipmentDate, 
                    Commit = true 
                },
                new Value 
                {

                    Value = "OK", 
                    LinkedCommand = SOSchema.SpecifyShipmentParameters.ServiceCommands.DialogAnswer, 
                    Commit = true 
                },               
                SOSchema.Actions.ActionCreateReceipt
            };
                context.SO301000Submit(commands);

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多