Acumatica API:使用.ActionConvertToBAccount转换Lead失败

时间:2015-12-23 22:18:23

标签: acumatica

我尝试使用Acumatica API(版本4.20.2231)将潜在客户屏幕转换为业务帐户。我甚至在尝试之前就对此感到有点担心,因为当你使用"转换为商业帐户时#34;在Acumatica中的动作,它会弹出一个小对话框。选择操作>后,这里是Acumatica的样子。转换为企业帐户: Lead Dialog Screen Shot

使用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 --- 

2 个答案:

答案 0 :(得分:2)

您当前的问题

您的错误发生是因为操作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)

您未来的问题

潜在客户转换为 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;
    }
}

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

答案 1 :(得分:0)

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

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

>>> for row in board:
...     print(*row)
...
O O O O O
O O O O O
O O O O O
O O O O O
O O O O O

希望这有帮助。