refund fix

backend_nfc
suvaissov 2021-06-08 13:45:18 +06:00
parent 9cea8b445b
commit f4ce7b85b9
4 changed files with 124 additions and 69 deletions

View File

@ -88,7 +88,9 @@ class MainActivity : FlutterActivity() {
val operDay = call.argument<String>("operDay").toString() val operDay = call.argument<String>("operDay").toString()
val transNum = call.argument<String>("transNum").toString() val transNum = call.argument<String>("transNum").toString()
val operationParameters = createOperationParameters(token) val operationParameters = createOperationParameters(token)
startOperation(OperationType.REVERSAL, JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum)) val body = JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum);
println(body)
startOperation(OperationType.REVERSAL, body)
} }
private fun operationCloseDay(call: MethodCall) { private fun operationCloseDay(call: MethodCall) {

View File

@ -83,6 +83,20 @@ class BankService extends BaseService {
} }
} }
Future<HalykResponse> reversal({ String token, int terminalId, int operDay, int transNum }) async {
try {
String response = await _channel.invokeMethod("reversal", <String, dynamic>{
'token': token , 'terminalId': terminalId, 'operDay': operDay, 'transNum': transNum
});
log.i(response);
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
return dao;
} catch (e, stack) {
log.e("BankService", e, stack);
return new HalykResponse(result: ResultBean(description: 'Ошибка при возврате', code: -1));
}
}
CloseDayData closeDayDataConvert(Cd.TransactionsBean transactions) { CloseDayData closeDayDataConvert(Cd.TransactionsBean transactions) {
final DateFormat formatter = DateFormat('dd.MM.yyyy'); final DateFormat formatter = DateFormat('dd.MM.yyyy');

View File

@ -45,7 +45,6 @@ class ImageShowContainer extends StatefulWidget {
} }
class _ImageShowContainerState extends State<ImageShowContainer> { class _ImageShowContainerState extends State<ImageShowContainer> {
final PrinterBluetoothManager printerManager = PrinterBluetoothManager(); final PrinterBluetoothManager printerManager = PrinterBluetoothManager();
final DialogService _dialogService = locator<DialogService>(); final DialogService _dialogService = locator<DialogService>();
@ -64,11 +63,9 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
if (val == 12) { if (val == 12) {
print('on'); print('on');
_print(); _print();
} else if (val == 10) { } else if (val == 10) {
print('off'); print('off');
_dialogService.showDialog( _dialogService.showDialog(description: 'Отсутвует соеденение Bluetooth или он отключен', title: 'Bluetooth');
description: 'Отсутвует соеденение Bluetooth или он отключен' , title: 'Bluetooth');
} }
print('state is $val'); print('state is $val');
}); });
@ -77,7 +74,7 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
void _print() async { void _print() async {
final SettingState state = Redux.store.state.settingState; final SettingState state = Redux.store.state.settingState;
if(state.printerBT == null) { if (state.printerBT == null) {
_dialogService.showDialog(description: 'Укажите в настройках принтер для печати чеков'); _dialogService.showDialog(description: 'Укажите в настройках принтер для печати чеков');
return; return;
} }
@ -86,7 +83,7 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
int chunkSizeBytes = 3096; int chunkSizeBytes = 3096;
int queueSleepTimeMs = 100; int queueSleepTimeMs = 100;
if(isIos){ if (isIos) {
chunkSizeBytes = 75; chunkSizeBytes = 75;
queueSleepTimeMs = 10; queueSleepTimeMs = 10;
} }
@ -96,9 +93,7 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
}); });
try { try {
printerManager.selectPrinter(PrinterBluetooth(state.printerBT)); printerManager.selectPrinter(PrinterBluetooth(state.printerBT));
PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58;
? PaperSize.mm80
: PaperSize.mm58;
if (SettingPrinterEncodingImage == state.printerEncoding) { if (SettingPrinterEncodingImage == state.printerEncoding) {
final PosPrintResult res = await printerManager.printTicket( final PosPrintResult res = await printerManager.printTicket(
await printImageCheck(paper, widget.showModel.data.base64Data), await printImageCheck(paper, widget.showModel.data.base64Data),
@ -109,9 +104,7 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
} }
} else { } else {
final PosPrintResult res = await printerManager.printTicket( final PosPrintResult res = await printerManager.printTicket(
await printTextCheck( await printTextCheck(paper, state.printerEncoding, jsonDecode(widget.showModel.data.textData)),
paper, state.printerEncoding,
jsonDecode(widget.showModel.data.textData)),
chunkSizeBytes: chunkSizeBytes, chunkSizeBytes: chunkSizeBytes,
queueSleepTimeMs: queueSleepTimeMs); queueSleepTimeMs: queueSleepTimeMs);
if (res.value != 1) { if (res.value != 1) {
@ -134,7 +127,7 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
//backgroundColor: fillColor, //backgroundColor: fillColor,
title: Text(widget.showModel.title), title: Text(widget.showModel.title),
actions: [ actions: [
if(_printing) if (_printing)
Padding( Padding(
padding: const EdgeInsets.only(right: 8.0), padding: const EdgeInsets.only(right: 8.0),
child: SizedBox( child: SizedBox(
@ -142,8 +135,7 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
child: Center( child: Center(
child: CircularProgressIndicator( child: CircularProgressIndicator(
strokeWidth: 2, strokeWidth: 2,
valueColor: new AlwaysStoppedAnimation<Color>( valueColor: new AlwaysStoppedAnimation<Color>(whiteColor),
whiteColor),
), ),
), ),
), ),
@ -179,7 +171,9 @@ class ImageShowModel {
class MyFloatingActionButton extends StatefulWidget { class MyFloatingActionButton extends StatefulWidget {
final ImageShowModel data; final ImageShowModel data;
MyFloatingActionButton(this.data); MyFloatingActionButton(this.data);
@override @override
_MyFloatingActionButtonState createState() => _MyFloatingActionButtonState(); _MyFloatingActionButtonState createState() => _MyFloatingActionButtonState();
} }
@ -191,44 +185,74 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
final GlobalKey<State> _keyLoader = new GlobalKey<State>(); final GlobalKey<State> _keyLoader = new GlobalKey<State>();
final DataService _dataService = locator<DataService>(); final DataService _dataService = locator<DataService>();
double sheetHeight = 260; double sheetHeight = 260;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (showFab) { if (showFab) {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment") FloatingActionButton( if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment")
backgroundColor: redColor, FloatingActionButton(
child: Icon( backgroundColor: redColor,
Icons.settings_backup_restore, tooltip: 'Отмена',
color: whiteColor, child: Icon(
), Icons.cancel,
onPressed: () async { color: whiteColor,
_navigatorService.replace(HomeViewRoute); ),
try { onPressed: () async {
await Redux.store.dispatch(changePinSkipFromSetting(true));
AmanDao<CardData> response = await refundHalykPos(widget.data.cardData, widget.data.voucher.total);
if (response.success) {
pressRefund();
} else {
_dialog.showDialog(description: response.msg);
}
} finally {
await Redux.store.dispatch(changePinSkipFromSetting(false));
}
}, try {
heroTag: null, await Redux.store.dispatch(changePinSkipFromSetting(true));
) else SizedBox( AmanDao<CardData> response = await reversalHalykPos(widget.data.cardData, widget.data.voucher.total);
height: 0, if (response.success) {
pressRefund();
} else {
_dialog.showDialog(description: response.msg);
}
} finally {
await Redux.store.dispatch(changePinSkipFromSetting(false));
}
_navigatorService.replace(HomeViewRoute);
},
heroTag: null,
)
else
SizedBox(
height: 0,
),
SizedBox(
height: 10,
), ),
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment")
FloatingActionButton(
backgroundColor: redColor,
tooltip: 'Возврат',
child: Icon(
Icons.settings_backup_restore,
color: whiteColor,
),
onPressed: () async {
try {
await Redux.store.dispatch(changePinSkipFromSetting(true));
AmanDao<CardData> response = await refundHalykPos(widget.data.cardData, widget.data.voucher.total);
if (response.success) {
pressRefund();
} else {
_dialog.showDialog(description: response.msg);
}
} finally {
await Redux.store.dispatch(changePinSkipFromSetting(false));
}
},
heroTag: null,
)
else
SizedBox(
height: 0,
),
SizedBox( SizedBox(
height: 10, height: 10,
), ),
@ -242,12 +266,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(15)), borderRadius: BorderRadius.all(Radius.circular(15)),
boxShadow: [ boxShadow: [BoxShadow(blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)]),
BoxShadow(
blurRadius: 10,
color: Colors.grey[300],
spreadRadius: 5)
]),
height: 260, height: 260,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -296,11 +315,8 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
String _token = _state.userState.user.token; String _token = _state.userState.user.token;
CardData _cardData = widget.data.cardData; CardData _cardData = widget.data.cardData;
CheckData _checkData = CheckData.fromJson(json.decode(widget.data.voucher.data)); CheckData _checkData = CheckData.fromJson(json.decode(widget.data.voucher.data));
Response<dynamic> response = await _dataService.refundM4Bank( Response<dynamic> response =
token: _token, await _dataService.refundM4Bank(token: _token, cardData: _cardData, checkData: _checkData);
cardData: _cardData,
checkData: _checkData
);
if (response != null) { if (response != null) {
if (response.operation) { if (response.operation) {
String message = response.body['message']; String message = response.body['message'];
@ -313,9 +329,12 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_navigatorService.replace(HomeViewRoute); _navigatorService.replace(HomeViewRoute);
_navigatorService.push(ImageShowRoute, _navigatorService.push(ImageShowRoute,
arguments: ImageShowModel(data: new CheckImageModal(base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null ), title: message, url: url)); arguments: ImageShowModel(
} else if (!response.operation && data: new CheckImageModal(
![401, 402, 403, 412, 500].contains(response.status)) { base64Data: check, textData: checkText != null ? jsonEncode(checkText) : null),
title: message,
url: url));
} else if (!response.operation && ![401, 402, 403, 412, 500].contains(response.status)) {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_dialog.showDialog(description: response.body['message']); _dialog.showDialog(description: response.body['message']);
} else { } else {
@ -332,25 +351,19 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
void shareFile() async { void shareFile() async {
try { try {
await Share.file('Aman Kassa', 'aman_kassa_check.png', await Share.file('Aman Kassa', 'aman_kassa_check.png', base64Decode(widget.data.data.base64Data), 'image/png');
base64Decode(widget.data.data.base64Data), 'image/png');
} catch (e) { } catch (e) {
print('error: $e'); print('error: $e');
} }
} }
void qrGenerate() async { void qrGenerate() async {
_navigatorService.push(QrViewRoute, _navigatorService.push(QrViewRoute, arguments: ImageShowModel(url: widget.data.url, title: 'Спасибо за покупку'));
arguments:
ImageShowModel(url: widget.data.url, title: 'Спасибо за покупку'));
} }
void callWhatsApp() async { void callWhatsApp() async {
DialogResponse response = await _dialog.showConfirmationDialogInput( DialogResponse response = await _dialog.showConfirmationDialogInput(
description: 'Номер телефона', description: 'Номер телефона', cancelTitle: 'Отмена', confirmationTitle: 'Отправить', formatType: 'phone');
cancelTitle: 'Отмена',
confirmationTitle: 'Отправить',
formatType: 'phone');
if (response.confirmed) { if (response.confirmed) {
String phoneNumber = response.responseText; String phoneNumber = response.responseText;
String msg = "Спасибо за покупку! \r\n ${widget.data.url} "; String msg = "Спасибо за покупку! \r\n ${widget.data.url} ";
@ -382,5 +395,4 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
showFab = value; showFab = value;
}); });
} }
} }

View File

@ -66,7 +66,34 @@ Future<AmanDao<CardData>> refundHalykPos(CardData refundData, double total) asyn
operationDay: response.transaction.operationDay, operationDay: response.transaction.operationDay,
transactionNumber: response.transaction.transactionNumber, transactionNumber: response.transaction.transactionNumber,
terminalId: response.transaction.terminalId, terminalId: response.transaction.terminalId,
transactionType: 'payment' transactionType: 'refund'
);
return AmanDao<CardData>(msg: response.result.description, success: true, data: cardData);
}
return AmanDao<CardData>(msg: response.result.errorData !=null ? response.result.errorData.description : response.result.description, success: false);
}
Future<AmanDao<CardData>> reversalHalykPos(CardData refundData, double total) async {
//Авторизация
String token = Redux.store.state.userState.user.token;
BankState bankState = Redux.store.state.bankState;
//права доступа
HalykPosSession session =
await _bankService.renewToken(token: token, login: bankState.login, password: bankState.password);
if (session.token == null) {
return AmanDao<CardData>(success: false, msg: 'Отказано в доступе к API банка');
}
log.i(refundData.toJson());
HalykResponse response = await _bankService.reversal(token: session.token, operDay: refundData.operationDay, terminalId: refundData.terminalId, transNum: refundData.transactionNumber );
if (response.result.code == 0) {
CardData cardData = new CardData(
authorizationCode: response.transaction.instrumentSpecificData.authorizationCode,
cardholderName: response.transaction.instrumentSpecificData.cardholderName,
cardNumber: response.transaction.instrumentSpecificData.maskedPan,
operationDay: response.transaction.operationDay,
transactionNumber: response.transaction.transactionNumber,
terminalId: response.transaction.terminalId,
transactionType: 'reversal'
); );
return AmanDao<CardData>(msg: response.result.description, success: true, data: cardData); return AmanDao<CardData>(msg: response.result.description, success: true, data: cardData);
} }