Acumatica API: использование .ActionConvertToBAccount для преобразования Lead не работает

Я пытаюсь использовать 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 --- 

person Eric Barr    schedule 23.12.2015    source источник
comment
Я думаю, вы устанавливаете неправильную связанную команду для этого диалогового окна. В предоставленном вами примере вы устанавливаете значение CR301000.LeadSummary.LeadID, которое не является всплывающим окном. установите информацию для всплывающего окна, также добавьте команду для кнопки создания перед вызовом ActionConvertToBAccount   -  person Sin    schedule 28.12.2015


Ответы (2)


Ваш текущий вопрос

Ошибка возникает из-за того, что действие ConvertToBAccount вызывает всплывающее диалоговое окно и ожидает ответа:

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

Чтобы сообщить Acumatica о своем ответе, нужно отправить значение «ОК» еще до того, как вызвать действие. В зависимости от вашей конфигурации вы также можете заполнить поле во всплывающем окне:

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, вам не с чем иметь дело.

К сожалению, в этом сценарии это не работает.

Кажется, что PXRedirectRequiredException возникает из PXLongOperation (читайте Thread) и что веб-служба не выбирает грязное состояние 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;
    }
}

Я ищу лучший способ разрешить ситуацию, и я отредактирую свой ответ, когда найду его.

person Philippe    schedule 28.12.2015
comment
Спасибо @Philippe за первый ответ и за то, что предвидели вторую проблему и изучали ее дальше. Да, дайте мне знать, если найдете другое решение. - person Eric Barr; 29.12.2015
comment
Привет, @Philippe, мы еще не сделали настройки, но мы находимся в процессе обновления до сборки 5.20.2067. Исправлена ​​ли эта проблема в сборке 5.20.2067? В противном случае мы внесем изменения после завершения обновления. Будет ли настройка отличаться в сборке 5.20.2067 или останется такой же, как вы предоставили? Спасибо! - person Eric Barr; 08.02.2016

Указанные команды должны быть для диалогового окна, а не для сводки. Обязательные поля и ответ диалога должны быть предоставлены перед вызовом действия.

Ниже приведен образец, используемый для создания действия «Квитанция» на экране квитанций. Примечание: код 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);

Надеюсь это поможет.

person Sin    schedule 28.12.2015