Проблема с Process Delegate после реализации непостоянного DAC - PullRequest
0 голосов
/ 03 января 2019

Я изо всех сил пытаюсь правильно подключить моего Process Delegate после выполнения рекомендаций, указанных в этом билете Реализация DAC без сохраняемых полей .Страница обработки по большей части теперь ведет себя так, как нам нужно.Автозагрузка записей основана на данных, полученных через веб-сервис ReST, и мы не сохраняем какие-либо данные в ERP до тех пор, пока не будут использованы кнопки обработки.У меня сейчас проблема в том, что метод SetProcessDeligate ничего не делает, когда я нажимаю кнопки процесса.Когда я подключаю старый код к месту, которое имеет одно постоянное поле и требует от пользователя нажатия кнопки загрузки, кнопки «Обрабатывать» и «Обрабатывать все» работают должным образом.Я создал этот скринкаст, чтобы пройтись и дать визуальный контекст этой проблеме.https://www.dropbox.com/s/j8vnp8p3556nj1e/issue%20with%20the%20PXProcessing%20page%20not%20wiring%20into%20the%20event%20handler%202019-01-03_12-57-50.mp4?dl=0 Как всегда, я очень благодарен за любую помощь.Спасибо Роберт

//This is how my Graph is defined now. 
public class CtpPaymentProcess : PXGraph<CtpPaymentProcess>
{
    //public PXAction<CtpPayment> checkForC2PPayments;

    public PXSetup<CtpSetup> setup;

    public PXProcessing<CtpPayment> Payments;

    public QueryPaymentsResponseViewModel paymentsFromCtpServer { get; internal set; }

    public IEnumerable payments()
    {
        paymentsFromCtpServer = CtpAcumatica.CheckForAllNewPayments(100);

        PXTrace.WriteInformation("Processing " + (paymentsFromCtpServer.Payments.Count) + " paymentsFromCtpServer");

        if (paymentsFromCtpServer.Payments != null)
        {
            // Loop processing each payment returned from the gateway, storing the 
            // information into non persisted cache.
            foreach (var payment in paymentsFromCtpServer.Payments)
            {
                if (!payment.IsMarkedRetrieved)
                {
                    yield return BuildCtpPayment(payment);
                }
            }
        }
    }

    private CtpPayment BuildCtpPayment(PaymentViewModel payment)
    {
        var customer = (Customer)PXSelect<Customer,
                        Where<Customer.bAccountID, Equal<Required<Customer.bAccountID>>>>
                        .Select(this, payment.CustomerId).FirstOrDefault();

        //Todo: add assertion that will assert payment is made to only matching company payment.CompanyId
        //Todo: find out if we need to handel Bank Account Types differently payment.BankAccountType

        DateTime.TryParse(payment.Date, out var payDate);
        return new CtpPayment
        {
            CustomerID = int.Parse(payment.CustomerId),
            Customer = $"{customer.AcctCD}:{customer.AcctName}",
            Amount = payment.Amount,
            Description = $"Payment:{payment.Id}",
            Id = payment.Id,
            ApsTransactionID = payment.ApsTransactionId,
            Currency = payment.Currency,
            PaymentDate = payDate,
            Invoices = InvoicesAsString(payment)
        };
    }

    private static string InvoicesAsString(PaymentViewModel payment)
    {
        var Invoices = payment.Invoices.Select(x => x.InvoiceId);
        StringBuilder stringBuilder = new StringBuilder();
        foreach (string inv in Invoices)
        {
            stringBuilder.AppendFormat("{0} ", inv);
        }
        string result = stringBuilder.ToString();
        if (result.Length > 100) result = result.Substring(0, 96) + "...";
        return result;
    }

    private CtpAcumatica _ctpAcumatica;


    public CtpAcumatica CtpAcumatica
    {
        get
        {
            if (_ctpAcumatica == null)
            {
                var graph = PXGraph.CreateInstance<PXGraph>();
                _ctpAcumatica = new CtpAcumatica(setup.Current.CtpUrl,
                    setup.Current.CtpApiKey,
                    "NoLongerNeeded", //todo: refactor this out.
                    "NoLongerNeeded", //todo: refactor this out.
                    graph);
            }
            return _ctpAcumatica;
        }
    }

    public CtpPaymentProcess()
    {
        Payments.SetProcessCaption("Process Payments");
        Payments.SetProcessAllCaption("Process All Payments");
        Payments.SetProcessDelegate<CtpPaymentProcess>(
            delegate (CtpPaymentProcess graph, CtpPayment payment)
            {
                graph.Clear();
                graph.ProcessPayment(payment, true);
            }
        );
        //Alternate attempt proved un-successful 
        //Payments.SetProcessDelegate(PaymentGenerationDelegate);

    }

    /* implemented as a test. will remove from production code
    private void PaymentGenerationDelegate(List<CtpPayment> list)
    {
        foreach (var payment in list)
        {
            ProcessPayment(payment, true);
        }
    }
    */

    private void ProcessPayment(CtpPayment payment, bool massProcess)
    {
        PXTrace.WriteInformation($"Processing {payment}");
        //for now we will only write to the trace window. 
        //Stopwatch stopWatch = new Stopwatch();
        //stopWatch.Start();
        //createPayment(payment);
        //stopWatch.Stop();
        //PXTrace.WriteInformation($"Payment {payment.ApsTransactionID} finished in {stopWatch.Elapsed.TotalSeconds} Seconds");
    }

    //todo: unfinished
    private void createPayment(CtpPayment paymentData)
    {
        var paymentFromCtp = CtpAcumatica.GetPaymentRecord(long.Parse(paymentData.Id));

        ARPaymentEntry arPaymentEntry = PXGraph.CreateInstance<ARPaymentEntry>();

        ARPayment payment = new ARPayment
        {
            CustomerID = int.Parse(paymentFromCtp.CustomerId),
            CuryOrigDocAmt = paymentData.Amount
        };

        arPaymentEntry.CurrentDocument.Insert(payment);

        foreach (var invoice in paymentFromCtp.Invoices)
        {

            ARAdjust adj = new ARAdjust
            {
                AdjdRefNbr = invoice.InvoiceId,
                CuryAdjgAmt = invoice.Amount
            };
            arPaymentEntry.Adjustments.Insert(adj);
        }
        arPaymentEntry.Persist();
        PXTrace.WriteInformation(arPaymentEntry.ToString());
    }
}

//This is the DAC definition.
[Serializable]
[PXPrimaryGraph(typeof(CtpPaymentProcess))]
//[PXNonInstantiatedExtension] this looked close
//to what we are looking for but experimenting 
//with it did not yield desired results.
public class CtpPayment : IBqlTable
{

    #region Selected
    public abstract class selected : IBqlField{ }
    [PXBool]
    [PXUIField(DisplayName = "Selected")]
    public virtual bool? Selected { get; set; }
    #endregion

    public abstract class id : IBqlField { }
    //todo: find out what size we need 50 is just a guess.
    //[PXString(50, IsKey = true)] //We are able to get this to work only if 
                                    //we have at least one persisting field.
                                    //we can live with this but would prefer to 
                                    //have the whole class as non-persistent
    [PXString(50,IsKey = true)] //having only non persisting attributes will result in a 
                    //Incorrect syntax near the keyword 'FROM'. error.
    [PXUIField(DisplayName = "Click To Pay Id")]
    public virtual string Id { get; set; }

    public abstract class customer : IBqlField { }

    [PXString(100)]
    [PXUIField(DisplayName = "Customer")]
    public virtual string Customer { get; set; }

    public abstract  class description : IBqlField {}
    [PXString(200)]
    [PXUIField(DisplayName = "Payment Description")]
    public virtual string Description { get; set; }

    public abstract  class amount : IBqlField { }
    [PXDecimal(2)]
    [PXUIField(DisplayName = "Payment Amount")]
    public  virtual decimal? Amount { get; set; }

    public abstract class customerId : IBqlField { }

    [PXInt]
    [PXUIField(DisplayName = "Customer ID")]
    //todo: decorate this with the needed attributes to display friendly key instead of int.

    public virtual int? CustomerID { get; set; }

    public abstract class apsTransactionID : IBqlField { }

    [PXString]
    [PXUIField(DisplayName = "Transaction ID")]
    public virtual string ApsTransactionID { get; set; }

    public abstract class currency : IBqlField { }
    [PXString(10)]//todo: determine best size. 10 is a guess.
    [PXUIField(DisplayName = "Currency")]
    public  virtual  string Currency { get; set; }

    public abstract class paymentDate : IBqlField { }
    [PXDate]
    [PXUIField(DisplayName = "Payment Date")]
    public virtual DateTime? PaymentDate { get; set; }

    public abstract class invoices : IBqlField { }

    [PXString(100)]
    [PXUIField(DisplayName = "Invoices")]
    public virtual string Invoices { get; set; }




}

1 Ответ

0 голосов
/ 04 января 2019

Спасибо, HB_Acumatica за указание на это.

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

    //old implementation that would not render any result when the process buttons where clicked.
    //public IEnumerable payments()
    //{
    //    paymentsFromCtpServer = CtpAcumatica.CheckForAllNewPayments(100);

    //    PXTrace.WriteInformation("Processing " + (paymentsFromCtpServer.Payments.Count) + " paymentsFromCtpServer");

    //    if (paymentsFromCtpServer.Payments != null)
    //    {
    //        // Loop processing each payment returned from the gateway, storing the 
    //        // information into non persisted cache.
    //        foreach (var payment in paymentsFromCtpServer.Payments)
    //        {
    //            if (!payment.IsMarkedRetrieved)
    //            {
    //                yield return BuildCtpPayment(payment);
    //            }
    //        }
    //    }
    //}

    public IEnumerable payments()
    {
        paymentsFromCtpServer = CtpAcumatica.CheckForAllNewPayments(100);

        PXCache cache = Caches[typeof(CtpPayment)];
        cache.AllowInsert = false;
        cache.AllowUpdate = false;

        if (cache.Current == null)
        {
            foreach (var payment in paymentsFromCtpServer.Payments)
            {
                if (!payment.IsMarkedRetrieved)
                {
                    cache.SetStatus(BuildCtpPayment(payment), PXEntryStatus.Held);
                }
            }
        }
        return Payments.Cache.Cached;
    }
...