Я хочу автоматически создать метод оплаты клиента на странице PXProcessing. Я думаю, что близок к решению этого, но я слишком долго ломал голову и надеюсь, что кто-то сможет помочь.
По сути, мне нужно создать этот метод оплаты для эмуляции обычной тестовой карты. Ничто из этого не затронет платежный шлюз, так как платеж уже получен, и основная цель состоит в том, чтобы пометить счет как оплаченный с помощью платежа и записи приложения.
Я испробовал две стратегии.
1) Создать платеж, а затем вставить или обновить настройки, необходимые в подробных записях.
2) (это показано в примере) переберите автоматически созданные подробные записи и установите для каждого из них правильное значение.
Следующий код показывает, что я пробовал с комментариями.
Заранее спасибо за любые советы.
Роберт
/**
<summary>
This method creates a new Customer Payment Method if no ClickToPay Payment Method is present.
This method is primarily a means to an end as to be able to use the CaptureCCPayment
action item to finalize and register a payment captured on the ClickToPayServer.
It uses a standard test card as the Detail of the Payment Method
</summary>
<param name="bankingPaymentMethodKey">
Holds the primary key value of the Bank Payment Method used in setting up this new Payment Method.
</param>
<param name="paymentFromCtp">
Holds data retrieved from the click to pay server needed to create the Customer Payment Method.
</param>
<returns>
It is not currently working. Will likely need to reach out for help.
</returns>
*/
private int? CreateCustomerPaymentMethod(int? bankingPaymentMethodKey, PaymentViewModel paymentFromCtp)
{
PaymentMethod paymentMethod = GetBankingPaymentMethod(bankingPaymentMethodKey);
const bool getDefault = true; //for BQL readability
const bool getActive = true;
CCProcessingCenterPmntMethod proCentPmtMthXref =
PXSelect<CCProcessingCenterPmntMethod,
Where<CCProcessingCenterPmntMethod.paymentMethodID,Equal<Required<CCProcessingCenterPmntMethod.paymentMethodID>>,
And<CCProcessingCenterPmntMethod.isDefault,Equal<Required<CCProcessingCenterPmntMethod.isDefault>>,
And<CCProcessingCenterPmntMethod.isActive,Equal<Required<CCProcessingCenterPmntMethod.isActive>>>>
>>
.Select(this, paymentMethod.PaymentMethodID, getDefault,getActive);
PaymentMethodAccount paymentMethodAccount = (PaymentMethodAccount)PXSelect<PaymentMethodAccount,
Where<PaymentMethodAccount.paymentMethodID,Equal<Required<PaymentMethodAccount.paymentMethodID>>>
>.Select(this, paymentMethod.PaymentMethodID).FirstOrDefault();
var cpmGraph = PXGraph.CreateInstance<CustomerPaymentMethodMaint>();
var customerPaymentMethod = new CustomerPaymentMethod
{
BAccountID = int.Parse(paymentFromCtp.CustomerId),
PaymentMethodID = paymentMethod.PaymentMethodID,
CashAccountID = paymentMethodAccount.CashAccountID,
CCProcessingCenterID = proCentPmtMthXref.ProcessingCenterID
};
//customerPaymentMethod.CustomerCCPID = "12345"; //this is empty on my manual created records but trying this gets the same resutls.
//either of these seem to yield the same result.
//cpmGraph.CustomerPaymentMethod.Current = cpmGraph.CustomerPaymentMethod.Insert(customerPaymentMethod);
cpmGraph.CurrentCPM.Current = cpmGraph.CurrentCPM.Insert(customerPaymentMethod);
/*
I would have assumed I should be able to do so with the DetailsAll or Details view, but this
seems to be empty at the point we reach this.
*/
int detailCountForDebugger = cpmGraph.Details.Select().Count; //returns 0
int detailAllCountForDebugger = cpmGraph.DetailsAll.Select().Count; //returns 0
//but it appears we can find the auto generated detail records in this cache under the inserted collection.
var targetCache = cpmGraph.Caches["CustomerPaymentMethodDetail"];
long insertedCountForDebugger = targetCache.Inserted.Count(); //returns 5
PXTrace.WriteInformation($"Detail.count {detailCountForDebugger} DetailAll.Count {detailAllCountForDebugger} inserted.Count {insertedCountForDebugger}");
foreach (var cpmGraphDetail in targetCache.Inserted)
{
CustomerPaymentMethodDetail detail = (CustomerPaymentMethodDetail) cpmGraphDetail;
switch (detail.DetailID)
{
case "CCDNUM":
detail.Value = "4111111111111111";
break;
case "CCPID":
detail.Value = "12345";
break;
case "CVV":
detail.Value = "555";
break;
case "EXPDATE":
detail.Value = "10/2025";
break;
case "NAMEONCC":
detail.Value = "Blank Card";
break;
}
//these where added to address error that PMIntanceID is missing on previous attempts.
detail.PMInstanceID = cpmGraph.CustomerPaymentMethod.Current.PMInstanceID;
detail.PaymentMethodID = customerPaymentMethod.PaymentMethodID;
/*
using update seems to add or insert a record as I
start this iteration with 5 records in the cache
then end up with 10 at the end.
the original records do seem to have the desired data in them.
not sure if this is related to the error
Another process has added the 'CustomerPaymentMethodDetail' record. Your changes will be lost.
*/
cpmGraph.Details.Update(detail);
//cpmGraph.Details.Insert(detail); //get the same results with insert
//cpmGraph.DetailsAll.Update(detail);
}
detailCountForDebugger = cpmGraph.Details.Select().Count; //returns 4
detailAllCountForDebugger = cpmGraph.DetailsAll.Select().Count; //returns 5
insertedCountForDebugger = targetCache.Inserted.Count(); //returns 10 but note that the original records reflect updated values
PXTrace.WriteInformation($"Detail.count {detailCountForDebugger} DetailAll.Count {detailAllCountForDebugger} inserted.Count {insertedCountForDebugger}");
//Calling Persist generates the following error
//"Error: Another process has added the 'CustomerPaymentMethodDetail' record. Your changes will be lost."
cpmGraph.Persist();
return cpmGraph.CustomerPaymentMethod.Current.PMInstanceID;
}