Я слишком долго ломал голову над этим, поэтому я обращаюсь в надежде получить какую-то помощь.
Основная цель заключается в следующем:
Когдамы сохраняем запись, нам нужно обратиться к веб-сервису, чтобы получить значение и сохранить его в пользовательском поле.Номер счета-фактуры, который присваивается счету-фактуре, требуется для вызова веб-метода, поэтому его необходимо заполнить до вызова веб-метода и, предпочтительно, до окончательного постоянного вызова.
Мой первоначальный подход заключался в использовании поляСобытие уровня в поле 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.
}