Acumatica API:使用.ActionConvertToBAccount转换Lead失败 [英] Acumatica API: Using .ActionConvertToBAccount for converting Lead is failing

查看:45
本文介绍了Acumatica API:使用.ActionConvertToBAccount转换Lead失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use the Acumatica API (Version 4.20.2231) for the Lead screen to convert a Lead to a Business Account. I was a bit worried about this even before I tried it because when you use the "Convert to Business Account" Action in Acumatica, it pops up a small dialog box. Here's what it looks like in Acumatica after choosing Actions > Convert to Business Account:

使用API ,我尝试的第一种命令安排是无法转换Lead且未产生任何类型的错误。最终,我发现了一系列命令,这些命令产生了一个错误消息,该错误消息引用了对话框,因此让我觉得自己处在正确的轨道上。也许我只是不知道如何使用命令来操作对话框。有人知道我要去哪里了吗?这是我的代码:

With the API, the first arrangement of commands I tried was failing to convert the Lead and not producing any kind of error. Eventually, I found a sequence of commands that produced an error that references dialog boxes, so that makes me think I'm on the right track. Maybe I just don't know how to manipulate the dialog box using the Commands. Does anyone know where I'm going wrong? Here is my code:

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时返回的错误:

And here is the error returned when CR301000Submit is called:

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


推荐答案

您当前的问题

发生错误是因为动作 ConvertToBAccount 调用了一个弹出对话框,并期待一个答案:

Your error occurs because the action ConvertToBAccount is calling a Pop-Up Dialog and is expecting an answer:

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

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

The way to tell Acumatica of it answer is to send the value "OK" before even calling the action. Depending on your configuration you might also want populate the field in this pop-up:

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 以及您需要保存的位置。 只要您不保存它,它将不会转换。

Converting from a Lead to a BAccount is a 2-step process where you are redirected to your newly created BAccount and where you need to save it. It will not be converted as long as you don't save it.

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

This is generally a pretty straight forward process or you simply submit Save to the page where you were redirected (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服务终结点,则没有任何处理。

As long as you keep the same cookie container, the UserState should be aware that you are currently on a dirty CR303000 with cached information. If you use a custom web service endpoint that included both CR301000 and CR303000 there is nothing to deal with.


不幸的是,在这种情况下,它不会

Unfortunatly, in this scenario it doesn't work.

似乎 PXRedirectRequiredException 是从 PXLongOperation (读取 Thread ),并且Web服务未选择 BAccount 的脏状态。我现在可以找到的唯一解决方案是自定义操作 ConvertToBAccount 以删除线程:

It seems that the PXRedirectRequiredException is raised from within a PXLongOperation (read Thread) and that the Web-Service doesn't pick the dirty state of BAccount. The only solution I can find right now is to customize the action ConvertToBAccount to remove threading:

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;
    }
}

我正在寻找解决这一问题的更好方法并在找到答案后对其进行编辑。

I am looking for a better way to address the situation and I'll edit my answer when I find it.

这篇关于Acumatica API:使用.ActionConvertToBAccount转换Lead失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆