Какое событие или метод необходим для установки определенного пользователем поля сразу после назначения InvoiceNbr / RefNbr - PullRequest
0 голосов
/ 28 февраля 2019

Я слишком долго ломал голову над этим, поэтому я обращаюсь в надежде получить какую-то помощь.

Основная цель заключается в следующем:

Когдамы сохраняем запись, нам нужно обратиться к веб-сервису, чтобы получить значение и сохранить его в пользовательском поле.Номер счета-фактуры, который присваивается счету-фактуре, требуется для вызова веб-метода, поэтому его необходимо заполнить до вызова веб-метода и, предпочтительно, до окончательного постоянного вызова.

Мой первоначальный подход заключался в использовании поляСобытие уровня в поле RefNbr, но я не получаю желаемого конечного результата, так как большинство из них возвращает значение «NEW» в качестве RefNbr и не может найти событие, которое сработает, когда этому полю будет присвоен окончательный номер счета-фактуры.но до финального сохранения.Это то, что я наблюдал со следующими событиями

ARInvoice_RefNbr_FieldUpdated - это не срабатывает при установке RefNbr.

ARInvoice_RowInserting - это срабатывает до нажатия кнопки сохранения и удерживает NEWзначение

ARInvoice_RowUpdating - при этом срабатывает и значение NEW.

ARInvoice_RowPersisting - срабатывает сразу после нажатия кнопки сохранения, но строка все еще содержит значение NEW.

ARInvoice_RowPersisted - запускается с правильным номером счета.Но запись, похоже, уже сохранена.Мы получаем ключ, но при обновлении он исчезает.

Второй подход, который я выбрал, - установить UDF post-Persist (), а затем восстановить запись после заполнения UDF.

Приведенный мною код демонстрирует то, что я пробовал до сих пор с моими комментариями.

Спасибо за помощь. Роберт

public class CtpARInvoiceEntry_Extension : PXGraphExtension<ARInvoiceEntry>
{
//... unrelated code removed
public delegate void PersistDelegate();
    [PXOverride]
    public void Persist(PersistDelegate baseMethod)
    {
        //Getting the ClickToPay Key does not work if we are attempting to get it before or
        //after the baseMethod call.

        //IF we try to get it before we will be sending in <NEW> as 
        //the invoice number.

        //If we send it after the base Method Call we get the correct Key and it seems things are copacetic.
        //But if we hit the refresh button the end result is the key disapears 

        //My initial thoughts where to look into implementing this at the FieldUpdating event as well as several other event handlers
        //including FieldUpdated, RowInserting, RowUpdating, RowPersisting, FieldVerifying...
        //none of these are leading to a case where we can get the CtpKey between the time we get a valid 
        //Invoice Nbr and the final persisting of the record.
        //We only get a RefNbr of <NEW> in each of the above cases.

        //GetClickToPayKey() Calling this before sends <NEW> as the invoice number
        baseMethod();
        GetClickToPayKey(baseMethod);

    }

    private void GetClickToPayKey(PersistDelegate baseMethod)
    {
        GetClickToPayKey();
        if (SaveAfterCtpKeyIsSet)
        {
            SaveAfterCtpKeyIsSet = false;// prevent any duplicate Calls
            Persist(baseMethod);
        }
    }

    private void GetClickToPayKey()
    {

        ARInvoice invoice = Base.CurrentDocument.Select();
        if (invoice.RefNbr.Contains("<NEW>")) return;
        CtpARInvoiceExt invoiceExt = PXCache<ARInvoice>.GetExtension<CtpARInvoiceExt>(invoice);
        if (!string.IsNullOrEmpty(invoiceExt.UsrCtpKey)) return;

        var ctpAcumatica = CtpAcumatica.Create(Base);
        try
        {
            invoiceExt.UsrCtpKey = ctpAcumatica.GetCtpKey(invoice);
            invoiceExt.UsrCtpUrl = BuildCtpUrl(invoiceExt.UsrCtpKey);
            //Neither the PressSave() nor Update() existed when the first approch was attempted.
            Base.CurrentDocument.Cache.Update(invoiceExt);
            Base.Actions.PressSave(); //does not get the desired results either.
            //the second save will not occur unless this is set to true.
            //If we do not invoke the second save the key will be present 
            //only until the refresh button is clicked where it then disappears. 
            SaveAfterCtpKeyIsSet = true;

        }
        catch
        {
            // ignored Allow saving even if the C2P server cannot be reached.  TODO: Verify that is okay
        }

    }

    private bool SaveAfterCtpKeyIsSet { get; set; }

    private string BuildCtpUrl(string ctpKey)
    {
        return CtpSetupData.Current.CtpPortalUrl + '/' + ctpKey;
    }

    //protected void ARInvoice_RefNbr_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
    //{
    //    //When we save the RefNbr get the actual invoice number but 
    //    //This Event Handler does not appear to be called.
    //    var row = (ARInvoice)e.Row;
    //    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();
    //    //does not yield desired end result
    //}

    //protected void ARInvoice_RowInserting(PXCache cache, PXRowInsertingEventArgs e)
    //{

    //    var row = (ARInvoice)e.Row;
    //    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();
    //    //does not yield desired end result
    //}

    //protected void ARInvoice_RowUpdating(PXCache cache, PXRowUpdatingEventArgs e)
    //{

    //    var row = (ARInvoice)e.Row;
    //    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();
    //    //does not yield desired end result
    //}

    //protected void ARInvoice_RowPersisted(PXCache cache, PXRowPersistedEventArgs e)
    //{

    //    var row = (ARInvoice)e.Row;
    //    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();
    //    //does not yield desired end result
    //}



    //protected void ARInvoice_RowPersisting(PXCache cache, PXRowPersistingEventArgs e)
    //{

    //    var row = (ARInvoice)e.Row;
    //    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();
    //    //does not yield desired end result
    //}



    ////protected void ARInvoice_RefNbr_FieldUpdating(PXCache cache, PXFieldUpdatedEventArgs e)
    ////{

    ////    var row = (ARInvoice)e.Row;
    ////    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();

    ////}



    //protected void ARInvoice_RowInserted(PXCache cache, PXRowInsertedEventArgs e)
    //{

    //    var row = (ARInvoice)e.Row;
    //    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();
    //    //does not yield desired end result
    //}



    //protected void ARInvoice_RefNbr_FieldVerifying(PXCache cache, PXFieldVerifyingEventArgs e)
    //{

    //    var row = (ARInvoice)e.Row;
    //    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();
    //    //does not yield desired end result
    //}



    ////protected void ARInvoice_RefNbr_FieldUpdating(PXCache cache, PXFieldUpdatingEventArgs e)
    ////{

    ////    var row = (ARInvoice)e.Row;
    ////    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();

    ////}



    //protected void ARInvoice_RefNbr_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e)
    //{

    //    var row = (ARInvoice)e.Row;
    //    if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();
    //    //does not yield desired end result
    //}


}

Примечания относительно Первого подхода

private void GetClickToPayKey()
    {

        ARInvoice invoice = Base.CurrentDocument.Select();
        if (invoice.RefNbr.Contains("<NEW>")) return;
        CtpARInvoiceExt invoiceExt = PXCache<ARInvoice>.GetExtension<CtpARInvoiceExt>(invoice);
        if (!string.IsNullOrEmpty(invoiceExt.UsrCtpKey)) return;

        var ctpAcumatica = CtpAcumatica.Create(Base);
        try
        {
            invoiceExt.UsrCtpKey = ctpAcumatica.GetCtpKey(invoice);
            invoiceExt.UsrCtpUrl = BuildCtpUrl(invoiceExt.UsrCtpKey);

            /* this code below was only attempted with the second approach
             and was not used when attempting the first and ideal approach using 
             field row level event handlers.
            Base.CurrentDocument.Cache.Update(invoiceExt);
            Base.Actions.PressSave(); //does not get the desired results either.
            //the second save will not occur unless this is set to true.
            //If we do not invoke the second save the key will be present 
            //only until the refresh button is clicked where it then disappears. 
            SaveAfterCtpKeyIsSet = true;
            */
        }
        catch
        {
            // ignored Allow saving even if the C2P server cannot be reached.  TODO: Verify that is okay
        }

    }

    protected void ARInvoice_RowPersisting(PXCache cache, PXRowPersistingEventArgs e)
    {

        var row = (ARInvoice)e.Row;
        if (row.RefNbr != null && !row.RefNbr.Contains("<NEW>")) GetClickToPayKey();
        //does not yield desired end result
        //the issue with using this event or similar ones is the row.RefNbr is returning <NEW>
        //We need to call the web service only when the Actual invoice is assigned.
    }

1 Ответ

0 голосов
/ 04 марта 2019

Это был, конечно, головокружительный.Так что это конкретное требование было уловкой-22Нам нужно было инициализировать запись с некоторыми значениями UDF в рамках пользователей, сохраняющих запись.Логика определения содержания этих пользовательских функций зависела от наличия Assigned RefNbr или InvoiceNbr, но мы не смогли получить его до завершения метода Persist.Я попробовал несколько вариантов вызова другого персистентного эквивалента после оригинала, но они, похоже, не оказали никакого влияния на сохранение внутренних данных, как когда мы обновляли значения, когда их не было.Поэтому я предполагаю, что Acumatica заблокировала способность к сохранению после первого появления, поскольку это, вероятно, считается сохраняющимся в постоянном анти-паттерне.Чтобы преодолеть это, я использовал обновление PXDatabase, и это дало нам конечный результат, который мы ищем.Особая благодарность HB_Acumatica за руководство в процессе устранения неполадок.Вот код, который дошел до конечного результата.

   //Within the Overridden Persist method of the Graph Extention.
   baseMethod(); //Can not get RefNbr until this is finished.
   //... logic to populate UDFValues    
   PXDatabase.Update<ARInvoice>(
            new PXDataFieldAssign<CtpARInvoiceExt.usrCtpKey>(invoiceExt.UsrYourKey),
            new PXDataFieldAssign<CtpARInvoiceExt.usrCtpUrl>(invoiceExt.UsrYourUrl),
            new PXDataFieldRestrict<ARInvoice.refNbr>(Base.CurrentDocument.Current.RefNbr));
...