Open noncommunicado opened 2 years ago
Какую версию iikoFront API вы используете? Предполагаю, что V6 или выше.
Pay(...) { var credits = PluginContext.Operations.AuthenticateByPin(_config.DefaultSettings.Pincode); PluginContext.Operations.AddOrderExternalData("data", data, order, credits);
Почему вы используете глобальный экземпляр IOperationService
обращаясь к нему через PluginContext.Operations
?
Когда вы находитесь на экране кассы на заказ имеется блокировка и он будет недоступен для редактирования через API с помощью глобального экземпляра IOperationService
, по возможности нужно пользоваться "локальным" экземпляром IOperationService
переданным в метод.
Посмотрите на сигнатуру метода IPaymentProcessor.Pay
:
void Pay(decimal sum, [NotNull] IOrder order, Guid paymentTypeId, Guid transactionId, [NotNull] IPointOfSale pointOfSale, [NotNull] IUser cashier, [NotNull] IOperationService operationService, IReceiptPrinter printer, [NotNull] IViewManager viewManager, IPaymentDataContext context);
здесь есть аргумент IOperationService operationService
.
по возможности нужно пользоваться "локальным" экземпляром
IOperationService
переданным в метод.
В вашем случае так:
Pay(..., operationService, ...) {
var credits = operationService.AuthenticateByPin(_config.DefaultSettings.Pincode);
operationService.AddOrderExternalData("data", data, order, credits);
}
Все дело в том, что появляется ошибка и не важно какой IOperationService
я использую.
Версия пакета: v7Preview7
Pay(...)
{
// ...
var credits = operationService.AuthenticateByPin(_config.DefaultSettings.Pincode);
operationService.AddOrderExternalData("data", data, order, credits); // <--- throw Exception
// ...
}
Exception:
System.InvalidOperationException
HResult=0x80131509
Message=Method “CreateEditSession” cannot be called using operation service of ProcessPayment event handler.
Source=mscorlib
StackTrace:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Resto.Front.Api.IOperationServiceInternal.CreateEditSession()
at Resto.Front.Api.OperationServiceFacade.Resto.Front.Api.IOperationService.CreateEditSession()
at Resto.Front.Api.Extensions.OperationServiceExtensions.AddOrderExternalData(IOperationService operationService, String key, String value, IOrder order, ICredentials credentials)
at Nm.Momentum.PluginIiko.MomentumPaymentProcessor.Pay(Decimal sum, IOrder order, IPaymentItem paymentItem, Guid transactionId, IPointOfSale pointOfSale, IUser cashier, IOperationService os, IReceiptPrinter printer, IViewManager vm, IPaymentDataContext context) in D:\Local Projects\Nm.Momentum.Plugin\Nm.Momentum.PluginIiko\Nm.Momentum.PluginIiko\MomentumPaymentProcessor.cs:line 262
at Resto.Front.Api.RemotingHelpers.RemotablePaymentProcessor.Resto.Front.Api.IPaymentProcessor.Pay(Decimal sum, IOrder order, IPaymentItem paymentItem, Guid transactionId, IPointOfSale pointOfSale, IUser cashier, IOperationService operationService, IReceiptPrinter printer, IViewManager viewManager, IPaymentDataContext context)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)
This exception was originally thrown at this call stack:
[External Code]
Nm.Momentum.PluginIiko.MomentumPaymentProcessor.Pay(decimal, Resto.Front.Api.Data.Orders.IOrder, Resto.Front.Api.Data.Payments.IPaymentItem, System.Guid, Resto.Front.Api.Data.Organization.IPointOfSale, Resto.Front.Api.Data.Security.IUser, Resto.Front.Api.IOperationService, Resto.Front.Api.IReceiptPrinter, Resto.Front.Api.UI.IViewManager, Resto.Front.Api.IPaymentDataContext) in MomentumPaymentProcessor.cs
[External Code]
Method “CreateEditSession” cannot be called using operation service of ProcessPayment event handler
Увы, все действия с заказом, выполняемые пакетно в рамках сессии редактирования, во время проведения оплаты не поддерживаются. Это грубое ограничение, просто потому что пока не было возможности точечно запрещать одни действия и разрешать другие. Очевидно, что AddOrderExternalData
— совершенно безопасное действие, никак не мешающее оплате, и его стоило бы разрешить. Если поправим это в V8, достаточно будет? Теоретически можно и в V7 протащить, это не должно сломать обратную совместимость.
@vcpp Спасибо за ответ. Данную проблему пришлось решить иначе. Думаю, что скоропостижных правок она не требует. Ждем V8 (в котором, надеемся, не будут меняться имена интерфейсов, классов и методов на похожие, переставляя слова местами, как в случае с v6 -> v7) 😃
@vcpp если вы такое протащите - будет прекрасно, т.к. есть несколько сценариев, когда addexternaldata надо выполнить именно при выполнении операции Pay.
Здравствуйте!
Есть небольшая задача:
Установить некоторые клиентские данные (например строку в формате json) связные с объектом заказа при успешной оплате заказа. Затем, иметь возможность обратиться к заказу через
PluginContext.Operations.GetOrders()
и поменять эти данные.Это нужно для отправки статистики при отмене; повторной отправки статистики в случае, если интернет соединение было недоступно; хранения логов и т.п.
Идея:
В методе
Pay
имплементацииIPaymentProcessor
записывать в объект данные, например флаги, используяIPaymentDataContext.SetCustomData
илиPluginContext.OperationsAddOrderExternalData
при успешной оплате заказа (обращаясь к внешним сервисам), а затем по таймеру грузить последние несколько заказов (в контексте плагина вцелом) и по флагам производить операции, попутно меняя флаг (данные) используяChangePaymentItemCustomData
илиPluginContext.Operations.AddOrderExternalData
. (Или как-то иначе?)Проблема:
Если в методе Pay пользовать
AddOrderExternalData
:То будет исключение, что Entity занята - что вполне понятно.
Ок, пойдем другим путем:
Но тогда мы не сможем изменить данные Payment'a (платежа) после, по таймеру:
Вопрос:
Не очень хочется городить что-то вне системы, тем более, что кажется есть возможность этого не делать. Подскажите пожалуйста, может, я что-либо упустил? Или вышеизложенной возможности пока нет? Спасибо!