315 lines
11 KiB
Dart
315 lines
11 KiB
Dart
import 'dart:convert';
|
|
import 'dart:ffi';
|
|
|
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
|
import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
|
import 'package:aman_kassa_flutter/core/entity/Service.dart';
|
|
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
|
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
|
import 'package:aman_kassa_flutter/core/models/calc_model.dart';
|
|
import 'package:aman_kassa_flutter/core/models/card_data.dart';
|
|
import 'package:aman_kassa_flutter/core/models/check_data.dart';
|
|
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
|
import 'package:aman_kassa_flutter/core/models/check_item.dart';
|
|
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
|
|
import 'package:aman_kassa_flutter/core/models/response.dart';
|
|
import 'package:aman_kassa_flutter/core/models/user.dart';
|
|
import 'package:aman_kassa_flutter/core/services/DbService.dart';
|
|
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
|
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'ApiService.dart';
|
|
|
|
class DataService extends BaseService {
|
|
final ApiService _api = locator<ApiService>();
|
|
final DbService _db = locator<DbService>();
|
|
|
|
Future<List<Category>> getCategoriesByParentId(
|
|
{int? parentId}) async {
|
|
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(
|
|
Category_tableName, '$Category_columnParentIn = ?', [parentId ?? 0]);
|
|
return list.map((e) => Category.fromMap(e)).toList();
|
|
}
|
|
|
|
Future<List<Service>> getServices() async {
|
|
List<Map<String, dynamic>> list = await _db.queryAllRows(Service_tableName);
|
|
return list.map((e) => Service.fromMap(e)).toList();
|
|
}
|
|
|
|
Future<List<Good>> getGoodsByCategoryId({int? categoryId}) async {
|
|
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(
|
|
Goog_tableName, '$Goog_columnCategoryId = ?', [categoryId ?? 0]);
|
|
return list.map((e) => Good.fromMap(e)).toList();
|
|
}
|
|
|
|
Future<List<Good>> getGoodsByBarcode({required String barcode}) async {
|
|
List<Map<String, dynamic>> list = await _db
|
|
.queryRowsWithWhere(Goog_tableName, ' $Goog_columnEan = ?', [barcode]);
|
|
return list.map((e) => Good.fromMap(e)).toList();
|
|
}
|
|
|
|
CheckData _transformProductsToCheckData(
|
|
{String? paymentType,
|
|
String? tradeType,
|
|
required List<ProductDao> items}) {
|
|
List<CheckItem> itemsList = [];
|
|
int iterator = 1;
|
|
num summ = 0.0;
|
|
items.forEach((el) {
|
|
int articul = iterator;
|
|
if (el.service != null) {
|
|
articul = el.service!.articul;
|
|
} else if (el.good != null) {
|
|
articul = el.good!.articul;
|
|
}
|
|
itemsList.add(CheckItem(
|
|
name: el.name,
|
|
cnt: el.count,
|
|
price: el.price,
|
|
articul: articul,
|
|
excise: el.excise,
|
|
));
|
|
summ += el.total;
|
|
iterator++;
|
|
});
|
|
CheckData checkData = CheckData(type: tradeType, items: itemsList);
|
|
if ((paymentType ?? 'cash') == 'card') {
|
|
checkData.card = summ;
|
|
}
|
|
return checkData;
|
|
}
|
|
|
|
CheckData _transformCalcModelToCheckData(
|
|
{String? paymentType,
|
|
String? tradeType,
|
|
required List<CalcModel> items}) {
|
|
List<CheckItem> itemsList = [];
|
|
int iterator = 1;
|
|
num summ = 0.0;
|
|
items.forEach((el) {
|
|
int articul = iterator;
|
|
CheckItem item = CheckItem(
|
|
name: 'Позиция $iterator',
|
|
cnt: el.num2 != null ? double.parse(el.num2!) : 1.0,
|
|
price: double.parse(el.num1),
|
|
articul: articul);
|
|
|
|
summ += item.cnt * item.price;
|
|
itemsList.add(item);
|
|
iterator++;
|
|
});
|
|
CheckData checkData = CheckData(type: tradeType, items: itemsList);
|
|
if ((paymentType ?? 'cash') == 'card') {
|
|
checkData.card = summ;
|
|
}
|
|
return checkData;
|
|
}
|
|
|
|
/* save data to db
|
|
* data,
|
|
* dateTime,
|
|
* check,
|
|
* appCompanyId,
|
|
* kassaId,
|
|
* total,
|
|
* name,
|
|
* type
|
|
*/
|
|
Future<void> insertVoucher(
|
|
{required User user,
|
|
String? data,
|
|
String? base64Data,
|
|
required String name,
|
|
double total = 0.0,
|
|
String type = VoucherTypePayment,
|
|
String? url}) async {
|
|
assert(user != null);
|
|
assert(name != null);
|
|
Voucher voucher = Voucher()
|
|
..name = name
|
|
..url = url
|
|
..total = total
|
|
..appCompanyId = user.appCompanyId
|
|
..kassaId = user.kassaId
|
|
..data = data
|
|
..base64Data = base64Data
|
|
..dateTime = DateTime.now()
|
|
..type = type;
|
|
log.i(
|
|
'save to db appCompanyId: ${user.appCompanyId}, kassaId: ${user.kassaId}');
|
|
_db.insert(Voucher_tableName, voucher.toMap());
|
|
}
|
|
|
|
Future<Response<dynamic>?> refundM4Bank(
|
|
{
|
|
required String token,
|
|
required CheckData checkData,
|
|
required CardData cardData}) async {
|
|
try {
|
|
var json = cardData.toJson();
|
|
json['transactionType'] = VoucherTypeReturnPay;
|
|
checkData.cardData = CardData.fromJson(json);
|
|
String data = jsonEncode(checkData.toJson());
|
|
|
|
log.i('token: $token');
|
|
log.i('data: $data');
|
|
Response<dynamic> response = await _api.sellReturn(token, data);
|
|
log.i('response status: ${response.status}');
|
|
log.i('response operation: ${response.operation}');
|
|
if (response.status == 200 && response.operation == true) {
|
|
User user = Redux.store!.state.userState!.user!;
|
|
String check = response.body['check'];
|
|
dynamic journal = response.body['journal'];
|
|
String url = response.body['link'];
|
|
int checkNum = journal['check_num'];
|
|
var summ = journal['summ'];
|
|
double total = summ != null ? double.parse(summ.toString()) : 0.0;
|
|
this.insertVoucher(
|
|
user: user,
|
|
name: 'Чек №$checkNum',
|
|
data: data,
|
|
base64Data: check,
|
|
total: total,
|
|
url: url,
|
|
type: VoucherTypeReturnPay);
|
|
}
|
|
return response;
|
|
} catch (e, stack) {
|
|
log.e("sellOrReturn", e, stack);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<Response<dynamic>?> sellOrReturn(
|
|
{String? paymentType,
|
|
String? tradeType,
|
|
required String token,
|
|
required List<ProductDao> kassaItems,
|
|
required List<CalcModel> calcItems,
|
|
required String operationType,
|
|
required String mode,
|
|
required CardData? cardData}) async {
|
|
try {
|
|
String data = "";
|
|
if (mode == SettingModeKassa) {
|
|
CheckData checkData = _transformProductsToCheckData(
|
|
paymentType: paymentType, tradeType: tradeType, items: kassaItems);
|
|
checkData.cardData = cardData;
|
|
data = jsonEncode(checkData.toJson());
|
|
} else if (mode == SettingModeCalc) {
|
|
CheckData checkData = _transformCalcModelToCheckData(
|
|
paymentType: paymentType, tradeType: tradeType, items: calcItems);
|
|
checkData.cardData = cardData;
|
|
data = jsonEncode(checkData.toJson());
|
|
}
|
|
|
|
// log.i('token: $token');
|
|
// log.i('data: $data');
|
|
Response<dynamic> response = await (operationType == OperationTypePay
|
|
? _api.sell(token, data)
|
|
: _api.sellReturn(token, data));
|
|
// log.i('response status: ${response.status}');
|
|
// log.i('response operation: ${response.operation}');
|
|
if (response.status == 200 && response.operation == true) {
|
|
User user = Redux.store!.state.userState!.user!;
|
|
//check compare
|
|
|
|
String check = response.body['check'];
|
|
var checkText = response.body['check_text'];
|
|
CheckImageModal imageModal = new CheckImageModal(
|
|
base64Data: check,
|
|
textData: checkText != null ? jsonEncode(checkText) : null);
|
|
// journal analyze
|
|
dynamic journal = response.body['journal'];
|
|
int checkNum = journal['check_num'];
|
|
var summ = journal['summ'];
|
|
// short url
|
|
String url = response.body['link'];
|
|
// total
|
|
double total = summ != null ? double.parse(summ.toString()) : 0.0;
|
|
|
|
//insert data to db
|
|
this.insertVoucher(
|
|
user: user,
|
|
name: 'Чек №$checkNum',
|
|
data: data,
|
|
base64Data: jsonEncode(imageModal.toJson()),
|
|
total: total,
|
|
url: url,
|
|
type: operationType == OperationTypeReturn
|
|
? VoucherTypeReturnPay
|
|
: VoucherTypePayment);
|
|
}
|
|
return response;
|
|
} catch (e, stack) {
|
|
log.e("sellOrReturn", e, stack);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<void> checkDbFill(User user) async {
|
|
int serviceCount = await _db.queryRowCount(Service_tableName) ?? 0;
|
|
if (serviceCount == 0) {
|
|
int goodCount = await _db.queryRowCount(Goog_tableName) ?? 0;
|
|
if (goodCount == 0) {
|
|
await getDataFromServer(user);
|
|
} else {
|
|
log.i('$Goog_tableName is Fill');
|
|
}
|
|
} else {
|
|
log.i('$Service_tableName is Fill');
|
|
}
|
|
}
|
|
|
|
Future<bool> getDataFromServer(User user) async {
|
|
log.i('Get Data from server');
|
|
try {
|
|
String token = user.token!;
|
|
Response<dynamic> goods = await _api.getGoodsFromServer(token);
|
|
if (goods.operation == false &&
|
|
[401, 402, 403, 412].contains(goods.status)) {
|
|
log.i('session is closed');
|
|
return false;
|
|
}
|
|
Response<dynamic> categories = await _api.getCategoryFromServer(token);
|
|
Response<dynamic> services = await _api.getServiceFromServer(token);
|
|
await _db.deleteAll(Goog_tableName);
|
|
await _db.deleteAll(Category_tableName);
|
|
await _db.deleteAll(Service_tableName);
|
|
log.i('All tables cleaned');
|
|
|
|
if (goods.body.isNotEmpty) {
|
|
for (var key in goods.body.keys) {
|
|
Good row = Good.fromJson(goods.body[key]);
|
|
//log.i(row.toMap());
|
|
await _db.insert(Goog_tableName, row.toMap());
|
|
}
|
|
log.i('Inserted ${goods.body.length} to table $Goog_tableName');
|
|
}
|
|
if (categories.body.isNotEmpty) {
|
|
for (var el in categories.body) {
|
|
Category row = Category.fromJson(el);
|
|
await _db.insert(Category_tableName, row.toMap());
|
|
}
|
|
log.i(
|
|
'Inserted ${categories.body.length} to table $Category_tableName');
|
|
}
|
|
|
|
if (services.body.isNotEmpty) {
|
|
for (var key in services.body.keys) {
|
|
Service row = Service.fromJson(services.body[key]);
|
|
await _db.insert(Service_tableName, row.toMap());
|
|
}
|
|
log.i('Inserted ${services.body?.length} to table $Service_tableName');
|
|
}
|
|
return true;
|
|
} catch (e, stack) {
|
|
log.e("load from server", e, stack);
|
|
return false;
|
|
}
|
|
}
|
|
}
|