fortenew commit prod
parent
1a39e1eed4
commit
7c7e50b78e
|
|
@ -3,6 +3,7 @@
|
|||
import 'package:aman_kassa_flutter/core/services/BankService.dart' as bank;
|
||||
import 'package:aman_kassa_flutter/core/services/ForteService.dart' as forte;
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/NctService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/blue_print_service.dart';
|
||||
|
||||
import '../core/services/DbService.dart';
|
||||
|
|
@ -35,6 +36,8 @@ class LocatorInjector {
|
|||
// depencies
|
||||
|
||||
|
||||
_log.d('Initializing NctService Service');
|
||||
locator.registerLazySingleton<NctService>(() => NctService());
|
||||
_log.d('Initializing DataService Service');
|
||||
locator.registerLazySingleton<DataService>(() => DataService());
|
||||
_log.d('Initializing BankService Service');
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ class CheckItem {
|
|||
final num price;
|
||||
final int articul;
|
||||
final String? excise;
|
||||
CheckItem({required this.name, required this.cnt, required this.price, required this.articul, this.excise});
|
||||
final String? ntin;
|
||||
|
||||
CheckItem({required this.name, required this.cnt, required this.price, required this.articul, this.excise, this.ntin});
|
||||
|
||||
static CheckItem fromJson(Map<String, dynamic> json) {
|
||||
return CheckItem(
|
||||
|
|
@ -13,14 +15,17 @@ class CheckItem {
|
|||
price: json['price'],
|
||||
articul: json['articul'],
|
||||
excise: json['excise'],
|
||||
ntin: json['ntin'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
'name': name,
|
||||
'cnt': cnt,
|
||||
'price': price,
|
||||
'articul': articul,
|
||||
'excise' : excise
|
||||
'excise': excise,
|
||||
'ntin': ntin ?? '',
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
class NctProduct {
|
||||
final int? id;
|
||||
final String? nameRu;
|
||||
final String? nameKk;
|
||||
final String? gtin;
|
||||
final String? ntinCode;
|
||||
final bool? isSocial;
|
||||
final int? status;
|
||||
final bool? isMarkedEac;
|
||||
final String? measure;
|
||||
final bool? ntinIsDeactivated;
|
||||
final String? ntinDeactivationReason;
|
||||
final String? ntinDuplicateOfProduct;
|
||||
|
||||
NctProduct({
|
||||
this.id,
|
||||
this.nameRu,
|
||||
this.nameKk,
|
||||
this.gtin,
|
||||
this.ntinCode,
|
||||
this.isSocial,
|
||||
this.status,
|
||||
this.isMarkedEac,
|
||||
this.measure,
|
||||
this.ntinIsDeactivated,
|
||||
this.ntinDeactivationReason,
|
||||
this.ntinDuplicateOfProduct,
|
||||
});
|
||||
|
||||
factory NctProduct.fromJson(Map<String, dynamic> json) {
|
||||
return NctProduct(
|
||||
id: json['id'] is int ? json['id'] as int : null,
|
||||
nameRu: json['name_ru'] is String ? json['name_ru'] as String : null,
|
||||
nameKk: json['name_kk'] is String ? json['name_kk'] as String : null,
|
||||
gtin: json['gtin'] is String ? json['gtin'] as String : null,
|
||||
ntinCode: json['ntin_code'] is String ? json['ntin_code'] as String : null,
|
||||
isSocial: json['is_social'] is bool ? json['is_social'] as bool : null,
|
||||
status: json['status'] is int ? json['status'] as int : null,
|
||||
isMarkedEac: json['is_markedeac'] is bool ? json['is_markedeac'] as bool : null,
|
||||
measure: _parseStringOrObject(json['measure']),
|
||||
ntinIsDeactivated: json['ntin_isdeactivated'] is bool ? json['ntin_isdeactivated'] as bool : null,
|
||||
ntinDeactivationReason: _parseStringOrObject(json['ntin_deactivationreason']),
|
||||
ntinDuplicateOfProduct: _parseStringOrObject(json['ntin_duplicateofproduct']),
|
||||
);
|
||||
}
|
||||
|
||||
static String? _parseStringOrObject(dynamic value) {
|
||||
if (value == null) return null;
|
||||
if (value is String) return value;
|
||||
if (value is Map) return value['name_ru']?.toString() ?? value['name']?.toString() ?? value.toString();
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -9,8 +9,7 @@ class ProductDao {
|
|||
final Good? good;
|
||||
final Service? service;
|
||||
final String? excise;
|
||||
final String? ntin;
|
||||
|
||||
|
||||
ProductDao( {required this.name, required this.price, required this.count, required this.total, this.good, this.service, this.excise });
|
||||
|
||||
ProductDao({required this.name, required this.price, required this.count, required this.total, this.good, this.service, this.excise, this.ntin});
|
||||
}
|
||||
|
|
@ -147,8 +147,11 @@ class ApiService extends BaseService {
|
|||
return Response.fromJsonDynamic(json.decode(response));
|
||||
}
|
||||
|
||||
Future<Response<dynamic>> sellReturn(String token, String checkData) async {
|
||||
Future<Response<dynamic>> sellReturn(String token, String checkData, {String? ticketNumber}) async {
|
||||
Map<String, String> requestBody = <String, String>{'api_token': token, 'data': checkData};
|
||||
if (ticketNumber != null && ticketNumber.isNotEmpty) {
|
||||
requestBody['ticketNumber'] = ticketNumber;
|
||||
}
|
||||
var response = await requestFormData('/sell_return', requestBody);
|
||||
return Response.fromJsonDynamic(json.decode(response));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ class DataService extends BaseService {
|
|||
price: el.price,
|
||||
articul: articul,
|
||||
excise: el.excise,
|
||||
ntin: el.ntin,
|
||||
));
|
||||
summ += el.total;
|
||||
iterator++;
|
||||
|
|
@ -191,6 +192,7 @@ class DataService extends BaseService {
|
|||
{String? paymentType,
|
||||
String? tradeType,
|
||||
String? contragent,
|
||||
String? ticketNumber,
|
||||
required String token,
|
||||
required List<ProductDao> kassaItems,
|
||||
required List<CalcModel> calcItems,
|
||||
|
|
@ -217,7 +219,7 @@ class DataService extends BaseService {
|
|||
// log.i('data: $data');
|
||||
Response<dynamic> response = await (operationType == OperationTypePay
|
||||
? _api.sell(token, data)
|
||||
: _api.sellReturn(token, data));
|
||||
: _api.sellReturn(token, data, ticketNumber: ticketNumber));
|
||||
// log.i('response status: ${response.status}');
|
||||
// log.i('response operation: ${response.operation}');
|
||||
if (response.status == 200 && response.operation == true) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/nct_product.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/io_client.dart';
|
||||
|
||||
class NctService extends BaseService {
|
||||
static const String _baseUrl = 'https://nct.gov.kz/api/integration/ofd/search_ofd/';
|
||||
|
||||
Future<List<NctProduct>> searchByNtin(String ntin) async {
|
||||
final uri = Uri.parse(_baseUrl).replace(queryParameters: {'tin': ntin});
|
||||
log.i('NCT request: $uri');
|
||||
|
||||
http.Client client = _buildClient();
|
||||
late http.Response response;
|
||||
try {
|
||||
response = await client.get(uri, headers: {'Accept': 'application/json'});
|
||||
} on TlsException catch (e) {
|
||||
log.e('NCT TLS error', e);
|
||||
throw NctServiceException('Ошибка SSL при подключении к NCT: ${e.message}');
|
||||
} on SocketException catch (e) {
|
||||
log.e('NCT network error', e);
|
||||
throw NctServiceException('Ошибка сети при подключении к NCT: ${e.message}');
|
||||
} catch (e) {
|
||||
log.e('NCT request error', e);
|
||||
throw NctServiceException('Ошибка запроса к NCT: $e');
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
||||
log.i('NCT status: ${response.statusCode}');
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw NctServiceException('NCT вернул статус ${response.statusCode}');
|
||||
}
|
||||
|
||||
try {
|
||||
final bodyString = utf8.decode(response.bodyBytes);
|
||||
log.i('NCT body: ${bodyString.length > 300 ? bodyString.substring(0, 300) : bodyString}');
|
||||
final decoded = json.decode(bodyString);
|
||||
List<dynamic> list;
|
||||
if (decoded is List) {
|
||||
list = decoded;
|
||||
} else if (decoded is Map && decoded.containsKey('results')) {
|
||||
list = decoded['results'] as List<dynamic>;
|
||||
} else {
|
||||
log.w('NCT unexpected response format: ${decoded.runtimeType}');
|
||||
return [];
|
||||
}
|
||||
return list
|
||||
.map((e) => NctProduct.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
} catch (e) {
|
||||
log.e('NCT JSON parse error', e);
|
||||
throw NctServiceException('Ошибка разбора ответа NCT: $e');
|
||||
}
|
||||
}
|
||||
|
||||
http.Client _buildClient() {
|
||||
final httpClient = HttpClient()
|
||||
..badCertificateCallback = (cert, host, port) {
|
||||
log.w('NCT bad certificate for $host:$port — subject: ${cert.subject}');
|
||||
return host == 'nct.gov.kz';
|
||||
};
|
||||
return IOClient(httpClient);
|
||||
}
|
||||
}
|
||||
|
||||
class NctServiceException implements Exception {
|
||||
final String message;
|
||||
NctServiceException(this.message);
|
||||
@override
|
||||
String toString() => message;
|
||||
}
|
||||
|
|
@ -36,12 +36,12 @@ Future<void> cleanKassaItems(Store<AppState> store) async {
|
|||
store.dispatch(SetKassaStateAction(KassaState(kassaItems: [])));
|
||||
}
|
||||
|
||||
ThunkAction<AppState> addCustomProductToKassaItems(String name, double count, double price, double total) {
|
||||
ThunkAction<AppState> addCustomProductToKassaItems(String name, double count, double price, double total, {String? ntin}) {
|
||||
return (Store<AppState> store) async {
|
||||
List<ProductDao> items = store.state.kassaState!.kassaItems!;
|
||||
items.add(new ProductDao(name: name, count: count, price: price, total: total));
|
||||
store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
|
||||
};
|
||||
items.add(new ProductDao(name: name, count: count, price: price, total: total, ntin: ntin));
|
||||
store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/nct_product.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/NctService.dart' show NctService, NctServiceException;
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||
|
|
@ -30,6 +32,7 @@ class KassaTab extends StatelessWidget {
|
|||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
final DataService _dataService = locator<DataService>();
|
||||
final NctService _nctService = locator<NctService>();
|
||||
|
||||
final int index;
|
||||
|
||||
|
|
@ -221,8 +224,20 @@ class KassaTab extends StatelessWidget {
|
|||
if (goods != null && goods.isNotEmpty) {
|
||||
await Redux.store!.dispatch(addProductToKassaItems(goods.first, dataMatrix));
|
||||
} else {
|
||||
_dialogService.showDialog(
|
||||
description: 'Товар не найден: $barcode');
|
||||
try {
|
||||
List<NctProduct> nctResults = await _nctService.searchByNtin(barcode);
|
||||
if (nctResults.isNotEmpty) {
|
||||
final NctProduct nctProduct = nctResults.first;
|
||||
final String? name = nctProduct.nameRu ?? nctProduct.nameKk;
|
||||
_openAddSheetWithName(name, ntinCode: nctProduct.ntinCode);
|
||||
} else {
|
||||
_dialogService.showDialog(description: 'Товар не найден: $barcode');
|
||||
}
|
||||
} on NctServiceException catch (e) {
|
||||
_dialogService.showDialog(description: e.message);
|
||||
} catch (e) {
|
||||
_dialogService.showDialog(description: 'Ошибка поиска NCT: $e');
|
||||
}
|
||||
}
|
||||
} else if (result.type == ResultType.Error) {
|
||||
_dialogService.showDialog(description: 'Не верный формат QR кода');
|
||||
|
|
@ -247,6 +262,12 @@ class KassaTab extends StatelessWidget {
|
|||
|
||||
|
||||
|
||||
void _openAddSheetWithName(String? name, {String? ntinCode}) {
|
||||
_navigatorService.navigateToPage(
|
||||
MaterialPageRoute(builder: (_) => ProductAddBottomSheet(initialName: name, initialNtinCode: ntinCode))
|
||||
);
|
||||
}
|
||||
|
||||
void showModalBottomSheetCatalog(BuildContext context, String action) {
|
||||
|
||||
if (action == 'add') {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/nct_product.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/NctService.dart' show NctService, NctServiceException;
|
||||
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
|
|
@ -7,29 +10,39 @@ import 'package:flutter/services.dart';
|
|||
|
||||
class ProductAddBottomSheet extends StatefulWidget {
|
||||
final ScrollController? scrollController;
|
||||
final String? initialName;
|
||||
final String? initialNtinCode;
|
||||
|
||||
ProductAddBottomSheet({this.scrollController});
|
||||
ProductAddBottomSheet({this.scrollController, this.initialName, this.initialNtinCode});
|
||||
|
||||
@override
|
||||
_ProductAddBottomSheetState createState() => _ProductAddBottomSheetState();
|
||||
}
|
||||
|
||||
class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
||||
final NctService _nctService = locator<NctService>();
|
||||
|
||||
late TextEditingController ntinController;
|
||||
late TextEditingController nameController;
|
||||
late TextEditingController countController;
|
||||
late TextEditingController priceController;
|
||||
double sum = 0.0;
|
||||
bool _isSearching = false;
|
||||
String? _foundNtinCode;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
nameController = new TextEditingController();
|
||||
ntinController = new TextEditingController();
|
||||
nameController = new TextEditingController(text: widget.initialName ?? '');
|
||||
countController = new TextEditingController();
|
||||
priceController = new TextEditingController();
|
||||
_foundNtinCode = widget.initialNtinCode;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
ntinController.dispose();
|
||||
nameController.dispose();
|
||||
countController.dispose();
|
||||
priceController.dispose();
|
||||
|
|
@ -51,10 +64,48 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
|||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.only(top: 15, left: 10, right: 15, bottom: 0 ),
|
||||
padding: EdgeInsets.only(top: 15, left: 10, right: 15, bottom: 0),
|
||||
child: ListView(
|
||||
controller: widget.scrollController,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: new InputDecoration(
|
||||
border: new OutlineInputBorder(
|
||||
borderSide: new BorderSide(color: primaryColor)),
|
||||
hintText: 'Введите NTIN/GTIN',
|
||||
labelText: 'NTIN/GTIN',
|
||||
prefixText: ' ',
|
||||
),
|
||||
keyboardType: TextInputType.text,
|
||||
controller: ntinController,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
SizedBox(
|
||||
height: 56,
|
||||
child: ElevatedButton(
|
||||
onPressed: _isSearching ? null : _searchByNtin,
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: primaryColor,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
),
|
||||
child: _isSearching
|
||||
? SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white, strokeWidth: 2),
|
||||
)
|
||||
: Icon(Icons.search, color: Colors.white),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
verticalSpaceSmall,
|
||||
TextField(
|
||||
decoration: new InputDecoration(
|
||||
border: new OutlineInputBorder(
|
||||
|
|
@ -78,8 +129,6 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
|||
decimal: true,
|
||||
),
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
// WhitelistingTextInputFormatter.digitsOnly
|
||||
// FilteringTextInputFormatter.digitsOnly
|
||||
FilteringTextInputFormatter.allow(RegExp("^[0-9.]*")),
|
||||
],
|
||||
controller: countController,
|
||||
|
|
@ -152,17 +201,52 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> _searchByNtin() async {
|
||||
final ntin = ntinController.text.trim();
|
||||
if (ntin.isEmpty) {
|
||||
_showErrorDialog('Введите NTIN/GTIN для поиска.');
|
||||
return;
|
||||
}
|
||||
setState(() => _isSearching = true);
|
||||
try {
|
||||
List<NctProduct> results = await _nctService.searchByNtin(ntin);
|
||||
if (results.isNotEmpty) {
|
||||
final product = results.first;
|
||||
setState(() {
|
||||
nameController.text = product.nameRu ?? product.nameKk ?? '';
|
||||
_foundNtinCode = product.ntinCode;
|
||||
});
|
||||
if (product.ntinIsDeactivated == true) {
|
||||
String reason = product.ntinDeactivationReason ?? '';
|
||||
String duplicate = product.ntinDuplicateOfProduct != null
|
||||
? '\nДубликат: ${product.ntinDuplicateOfProduct}'
|
||||
: '';
|
||||
_showErrorDialog('Карточка деактивирована.$reason$duplicate');
|
||||
}
|
||||
} else {
|
||||
_showErrorDialog('Товар с NTIN/GTIN "$ntin" не найден.');
|
||||
}
|
||||
} on NctServiceException catch (e) {
|
||||
_showErrorDialog(e.message);
|
||||
} catch (e) {
|
||||
_showErrorDialog('Ошибка поиска NCT: $e');
|
||||
} finally {
|
||||
setState(() => _isSearching = false);
|
||||
}
|
||||
}
|
||||
|
||||
void submit() {
|
||||
if (nameController.text.isEmpty ||
|
||||
countController.text.isEmpty ||
|
||||
priceController.text.isEmpty) {
|
||||
_showDialog();
|
||||
_showErrorDialog('Введите наименование, количество и цену');
|
||||
} else {
|
||||
Redux.store!.dispatch(addCustomProductToKassaItems(
|
||||
nameController.text,
|
||||
double.parse(countController.text),
|
||||
double.parse(priceController.text),
|
||||
sum));
|
||||
sum,
|
||||
ntin: _foundNtinCode));
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
|
|
@ -185,18 +269,17 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
|||
}
|
||||
}
|
||||
|
||||
void _showDialog() {
|
||||
// flutter defined function
|
||||
void _showErrorDialog(String message) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: new Text("Aman Касса"),
|
||||
content: new Text("Введите наименование, количество и цену"),
|
||||
content: new Text(message),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
TextButton(
|
||||
child: Text(
|
||||
"ОK",
|
||||
"ОК",
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
|
||||
),
|
||||
onPressed: () {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
dynamic _bankService;
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final TextEditingController _iinController = new TextEditingController();
|
||||
final TextEditingController _ticketNumberController = new TextEditingController();
|
||||
late bool isBusy;
|
||||
late bool isBankApiAccess;
|
||||
|
||||
|
|
@ -72,6 +73,7 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
@override
|
||||
void dispose() {
|
||||
_iinController.dispose();
|
||||
_ticketNumberController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -177,6 +179,24 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
});
|
||||
}
|
||||
|
||||
bool get _isReturn => widget.model.operationType == OperationTypeReturn;
|
||||
|
||||
bool _canProceed() {
|
||||
if (_isReturn && _ticketNumberController.text.trim().isEmpty) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void _onPaymentPressed(String type, CardData? cardData) {
|
||||
if (!_canProceed()) {
|
||||
_dialogService.showDialog(
|
||||
description: 'Введите фискальный признак для выполнения возврата.');
|
||||
return;
|
||||
}
|
||||
pressPayment(type, cardData);
|
||||
}
|
||||
|
||||
Expanded _buildBodyContent() {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
|
|
@ -188,6 +208,15 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
decoration: InputDecoration(
|
||||
labelText: 'ИИН Покупателя', hintText: "Введите ИИН покупателя"),
|
||||
),
|
||||
if (_isReturn)
|
||||
TextField(
|
||||
keyboardType: TextInputType.text,
|
||||
controller: _ticketNumberController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Фискальный признак *',
|
||||
hintText: 'Введите фискальный признак'),
|
||||
),
|
||||
if (_isReturn) verticalSpaceSmall,
|
||||
Container(
|
||||
height: 150,
|
||||
child: Row(
|
||||
|
|
@ -197,7 +226,7 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
child: BusyButton(
|
||||
title: 'Оплатить картой',
|
||||
onPressed: () {
|
||||
pressPayment('card', null);
|
||||
_onPaymentPressed('card', null);
|
||||
},
|
||||
mainColor: primaryColor,
|
||||
)),
|
||||
|
|
@ -206,7 +235,7 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
child: BusyButton(
|
||||
title: 'Мобильный',
|
||||
onPressed: () {
|
||||
pressPayment('mobile', null);
|
||||
_onPaymentPressed('mobile', null);
|
||||
},
|
||||
mainColor: redColor,
|
||||
)),
|
||||
|
|
@ -215,7 +244,7 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
child: BusyButton(
|
||||
title: 'Наличными',
|
||||
onPressed: () {
|
||||
pressPayment('cash', null);
|
||||
_onPaymentPressed('cash', null);
|
||||
},
|
||||
mainColor: greenColor,
|
||||
)),
|
||||
|
|
@ -360,7 +389,8 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
calcItems: calcItems,
|
||||
mode: _mode,
|
||||
cardData: cardData,
|
||||
contragent: _iinController.text
|
||||
contragent: _iinController.text,
|
||||
ticketNumber: _isReturn ? _ticketNumberController.text.trim() : null,
|
||||
);
|
||||
setState(() {
|
||||
isBusy = false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue