Calculator
parent
d916f638fb
commit
2e2033fec1
|
|
@ -1,49 +0,0 @@
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:logger/logger.dart';
|
|
||||||
import '../logger.dart';
|
|
||||||
|
|
||||||
class BaseViewModel extends ChangeNotifier {
|
|
||||||
String _title;
|
|
||||||
bool _busy;
|
|
||||||
Logger log;
|
|
||||||
bool _isDisposed = false;
|
|
||||||
|
|
||||||
BaseViewModel({
|
|
||||||
bool busy = false,
|
|
||||||
String title,
|
|
||||||
}) : _busy = busy,
|
|
||||||
_title = title {
|
|
||||||
log = getLogger(title ?? this.runtimeType.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get busy => this._busy;
|
|
||||||
bool get isDisposed => this._isDisposed;
|
|
||||||
String get title => _title ?? this.runtimeType.toString();
|
|
||||||
|
|
||||||
set busy(bool busy) {
|
|
||||||
log.i(
|
|
||||||
'busy: '
|
|
||||||
'$title is entering '
|
|
||||||
'${busy ? 'busy' : 'free'} state',
|
|
||||||
);
|
|
||||||
this._busy = busy;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void notifyListeners() {
|
|
||||||
if (!isDisposed) {
|
|
||||||
super.notifyListeners();
|
|
||||||
} else {
|
|
||||||
log.w('notifyListeners: Notify listeners called after '
|
|
||||||
'${title ?? this.runtimeType.toString()} has been disposed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
log.i('dispose');
|
|
||||||
_isDisposed = true;
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,16 +4,19 @@ const String Category_tableName = 'goods_category';
|
||||||
const String Category_columnId = 'id';
|
const String Category_columnId = 'id';
|
||||||
const String Category_columnParentIn = 'parent_id';
|
const String Category_columnParentIn = 'parent_id';
|
||||||
const String Category_columnName = 'name';
|
const String Category_columnName = 'name';
|
||||||
|
const String Category_columnAppCompanyId = 'app_company_id';
|
||||||
|
|
||||||
class Category {
|
class Category {
|
||||||
int id;
|
int id;
|
||||||
int parentIn;
|
int parentIn;
|
||||||
String name;
|
String name;
|
||||||
|
int appCompanyId;
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
var map = <String, dynamic>{
|
var map = <String, dynamic>{
|
||||||
Category_columnParentIn: parentIn,
|
Category_columnParentIn: parentIn,
|
||||||
Category_columnName: name,
|
Category_columnName: name,
|
||||||
|
Category_columnAppCompanyId: appCompanyId
|
||||||
};
|
};
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
map[Category_columnId] = id;
|
map[Category_columnId] = id;
|
||||||
|
|
@ -27,12 +30,14 @@ class Category {
|
||||||
id = map[Category_columnId];
|
id = map[Category_columnId];
|
||||||
parentIn = map[Category_columnParentIn];
|
parentIn = map[Category_columnParentIn];
|
||||||
name = map[Category_columnName];
|
name = map[Category_columnName];
|
||||||
|
appCompanyId = map[Category_columnAppCompanyId];
|
||||||
}
|
}
|
||||||
|
|
||||||
Category.fromJson(Map<String, dynamic> map) {
|
Category.fromJson(Map<String, dynamic> map) {
|
||||||
id = map[Category_columnId];
|
id = map[Category_columnId];
|
||||||
parentIn = map[Category_columnParentIn];
|
parentIn = map[Category_columnParentIn];
|
||||||
name = map[Category_columnName];
|
name = map[Category_columnName];
|
||||||
|
appCompanyId = map[Category_columnAppCompanyId];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,12 @@ const String Goog_columnName = 'name';
|
||||||
const String Goog_columnPrice = 'price';
|
const String Goog_columnPrice = 'price';
|
||||||
const String Goog_columnCategoryId = 'category_id';
|
const String Goog_columnCategoryId = 'category_id';
|
||||||
const String Goog_columnEan = 'ean';
|
const String Goog_columnEan = 'ean';
|
||||||
|
const String Goog_columnAppCompanyId = 'app_company_id';
|
||||||
|
|
||||||
|
const String Goog_columnDescription = 'description';
|
||||||
|
const String Goog_columnShowPrice = 'show_price';
|
||||||
|
const String Goog_columnOkei = 'okei';
|
||||||
|
const String Goog_columnDiscount = 'discount';
|
||||||
|
|
||||||
class Good {
|
class Good {
|
||||||
int id;
|
int id;
|
||||||
|
|
@ -15,6 +21,11 @@ class Good {
|
||||||
double price;
|
double price;
|
||||||
int categoryId;
|
int categoryId;
|
||||||
String ean;
|
String ean;
|
||||||
|
int appCompanyId;
|
||||||
|
String description;
|
||||||
|
double showPrice;
|
||||||
|
int okei;
|
||||||
|
double discount;
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
var map = <String, dynamic>{
|
var map = <String, dynamic>{
|
||||||
|
|
@ -23,6 +34,11 @@ class Good {
|
||||||
Goog_columnPrice: price,
|
Goog_columnPrice: price,
|
||||||
Goog_columnCategoryId: categoryId,
|
Goog_columnCategoryId: categoryId,
|
||||||
Goog_columnEan: ean,
|
Goog_columnEan: ean,
|
||||||
|
Goog_columnAppCompanyId: appCompanyId,
|
||||||
|
Goog_columnDescription: description,
|
||||||
|
Goog_columnShowPrice: showPrice,
|
||||||
|
Goog_columnOkei: okei,
|
||||||
|
Goog_columnDiscount: discount
|
||||||
};
|
};
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
map[Goog_columnId] = id;
|
map[Goog_columnId] = id;
|
||||||
|
|
@ -39,6 +55,11 @@ class Good {
|
||||||
price = map[Goog_columnPrice]?.toDouble();
|
price = map[Goog_columnPrice]?.toDouble();
|
||||||
categoryId = map[Goog_columnCategoryId];
|
categoryId = map[Goog_columnCategoryId];
|
||||||
ean = map[Goog_columnEan];
|
ean = map[Goog_columnEan];
|
||||||
|
appCompanyId= map[Goog_columnAppCompanyId];
|
||||||
|
description = map[Goog_columnDescription];
|
||||||
|
showPrice = map[Goog_columnShowPrice]?.toDouble();
|
||||||
|
okei = map[Goog_columnOkei];
|
||||||
|
discount = map[Goog_columnDiscount]?.toDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
Good.fromJson(Map<String, dynamic> map) {
|
Good.fromJson(Map<String, dynamic> map) {
|
||||||
|
|
@ -48,6 +69,11 @@ class Good {
|
||||||
price = double.parse(map[Goog_columnPrice]);
|
price = double.parse(map[Goog_columnPrice]);
|
||||||
categoryId = map[Goog_columnCategoryId];
|
categoryId = map[Goog_columnCategoryId];
|
||||||
ean = map[Goog_columnEan];
|
ean = map[Goog_columnEan];
|
||||||
|
appCompanyId = map[Goog_columnAppCompanyId];
|
||||||
|
description = map[Goog_columnDescription];
|
||||||
|
showPrice = map[Goog_columnShowPrice]?.toDouble();
|
||||||
|
okei = map[Goog_columnOkei];
|
||||||
|
discount = map[Goog_columnDiscount]?.toDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,18 +7,36 @@ const String Service_columnName = 'name';
|
||||||
const String Service_columnPrice = 'price';
|
const String Service_columnPrice = 'price';
|
||||||
const String Service_columnCategoryId = 'category_id';
|
const String Service_columnCategoryId = 'category_id';
|
||||||
const String Service_columnEan = 'ean';
|
const String Service_columnEan = 'ean';
|
||||||
|
const String Service_columnAppCompanyId = 'app_company_id';
|
||||||
|
|
||||||
|
const String Service_columnDescription = 'description';
|
||||||
|
const String Service_columnShowPrice = 'show_price';
|
||||||
|
const String Service_columnOkei = 'okei';
|
||||||
|
const String Service_columnDiscount = 'discount';
|
||||||
|
|
||||||
|
|
||||||
class Service {
|
class Service {
|
||||||
int id;
|
int id;
|
||||||
int articul;
|
int articul;
|
||||||
String name;
|
String name;
|
||||||
double price;
|
double price;
|
||||||
|
String ean;
|
||||||
|
int appCompanyId;
|
||||||
|
String description;
|
||||||
|
double showPrice;
|
||||||
|
String okei;
|
||||||
|
double discount;
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
var map = <String, dynamic>{
|
var map = <String, dynamic>{
|
||||||
Service_columnArticul: articul,
|
Service_columnArticul: articul,
|
||||||
Service_columnName: name,
|
Service_columnName: name,
|
||||||
Service_columnPrice: price,
|
Service_columnPrice: price,
|
||||||
|
Service_columnAppCompanyId: appCompanyId,
|
||||||
|
Service_columnDescription: description,
|
||||||
|
Service_columnShowPrice: showPrice,
|
||||||
|
Service_columnOkei: okei,
|
||||||
|
Service_columnDiscount: discount
|
||||||
};
|
};
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
map[Service_columnId] = id;
|
map[Service_columnId] = id;
|
||||||
|
|
@ -33,13 +51,24 @@ class Service {
|
||||||
articul = map[Service_columnArticul];
|
articul = map[Service_columnArticul];
|
||||||
name = map[Service_columnName];
|
name = map[Service_columnName];
|
||||||
price = map[Service_columnPrice]?.toDouble();
|
price = map[Service_columnPrice]?.toDouble();
|
||||||
|
appCompanyId = map[Service_columnAppCompanyId];
|
||||||
|
description = map[Service_columnDescription];
|
||||||
|
showPrice = map[Service_columnShowPrice]?.toDouble();
|
||||||
|
okei = map[Service_columnOkei];
|
||||||
|
discount = map[Service_columnDiscount]?.toDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
Service.fromJson(Map<String, dynamic> map) {
|
Service.fromJson(Map<String, dynamic> map) {
|
||||||
id = map[Service_columnId];
|
id = map[Service_columnId];
|
||||||
articul = map[Service_columnArticul];
|
articul = map[Service_columnArticul];
|
||||||
name = map[Service_columnName];
|
name = map[Service_columnName];
|
||||||
price = map[Service_columnPrice]?.toDouble(); }
|
price = map[Service_columnPrice]?.toDouble();
|
||||||
|
appCompanyId = map[Service_columnAppCompanyId];
|
||||||
|
description = map[Service_columnDescription];
|
||||||
|
showPrice = map[Service_columnShowPrice]?.toDouble();
|
||||||
|
okei = map[Service_columnOkei];
|
||||||
|
discount = map[Service_columnDiscount]?.toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,15 +38,25 @@ import 'package:logger/logger.dart';
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
//Logger getLogger(String className) {
|
||||||
|
// //return Logger(printer: SimpleLogPrinter(className));
|
||||||
|
// return Logger(
|
||||||
|
// printer: PrettyPrinter(
|
||||||
|
// methodCount: 1, // number of method calls to be displayed
|
||||||
|
// errorMethodCount: 1, // number of method calls if stacktrace is provided
|
||||||
|
// lineLength: 120, // width of the output
|
||||||
|
// colors: false, // Colorful log messages
|
||||||
|
// printEmojis: false, // Print an emoji for each log message
|
||||||
|
// printTime: false // Should each log print contain a timestamp
|
||||||
|
// ));
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
Logger getLogger(String className) {
|
Logger getLogger(String className) {
|
||||||
//return Logger(printer: SimpleLogPrinter(className));
|
//return Logger(printer: SimpleLogPrinter(className));
|
||||||
return Logger(
|
return Logger(
|
||||||
printer: PrettyPrinter(
|
printer: SimplePrinter(
|
||||||
methodCount: 2, // number of method calls to be displayed
|
|
||||||
errorMethodCount: 8, // number of method calls if stacktrace is provided
|
|
||||||
lineLength: 120, // width of the output
|
|
||||||
colors: true, // Colorful log messages
|
colors: true, // Colorful log messages
|
||||||
printEmojis: true, // Print an emoji for each log message
|
|
||||||
printTime: false // Should each log print contain a timestamp
|
printTime: false // Should each log print contain a timestamp
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
|
||||||
|
|
||||||
class ProductDao {
|
|
||||||
final String name;
|
|
||||||
final num price;
|
|
||||||
num count;
|
|
||||||
final Good good;
|
|
||||||
|
|
||||||
|
|
||||||
ProductDao( {this.name, this.price, this.count, this.good});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import '../utilsParse.dart';
|
||||||
import 'user.dart';
|
import 'user.dart';
|
||||||
|
|
||||||
class AuthResponse {
|
class AuthResponse {
|
||||||
|
|
@ -17,11 +18,6 @@ class AuthResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> parseListString(json){
|
|
||||||
if(json==null) return null;
|
|
||||||
return new List<String>.from(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AuthBody {
|
class AuthBody {
|
||||||
final List<String> email;
|
final List<String> email;
|
||||||
final List<String> password;
|
final List<String> password;
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
class CalcModel {
|
||||||
|
String num1;
|
||||||
|
String num2;
|
||||||
|
bool closed;
|
||||||
|
String operation;
|
||||||
|
CalcModel({this.num1, this.num2, this.operation, this.closed = false});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
// TODO: implement toString
|
||||||
|
|
||||||
|
return 'num1: $num1 num2:$num2 operation:$operation closed:$closed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/models/check_item.dart';
|
||||||
|
|
||||||
|
class CheckData {
|
||||||
|
final String type;
|
||||||
|
num card;
|
||||||
|
final List<CheckItem> items;
|
||||||
|
CheckData({this.type, this.card, this.items});
|
||||||
|
|
||||||
|
static CheckData fromJson(Map<String, dynamic> json) {
|
||||||
|
return CheckData(
|
||||||
|
type: json['type'],
|
||||||
|
card: json['card'],
|
||||||
|
items: json['items'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Map<String, dynamic> toJson() =>
|
||||||
|
{
|
||||||
|
'type': type,
|
||||||
|
'card': card,
|
||||||
|
'items': items.map((e) => e.toJson()).toList()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
class CheckItem {
|
||||||
|
final String name;
|
||||||
|
final num cnt;
|
||||||
|
final num price;
|
||||||
|
final int articul;
|
||||||
|
CheckItem({this.name, this.cnt, this.price, this.articul});
|
||||||
|
|
||||||
|
static CheckItem fromJson(Map<String, dynamic> json) {
|
||||||
|
return CheckItem(
|
||||||
|
name: json['name'],
|
||||||
|
cnt: json['cnt'],
|
||||||
|
price: json['price'],
|
||||||
|
articul: json['articul'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Map<String, dynamic> toJson() =>
|
||||||
|
{
|
||||||
|
'name': name,
|
||||||
|
'cnt': cnt,
|
||||||
|
'price': price,
|
||||||
|
'articul': articul
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -14,13 +14,15 @@ class DialogRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DialogResponse {
|
class DialogResponse {
|
||||||
final String fieldOne;
|
//final String fieldOne;
|
||||||
final String fieldTwo;
|
//final String fieldTwo;
|
||||||
|
final String responseText;
|
||||||
final bool confirmed;
|
final bool confirmed;
|
||||||
|
|
||||||
DialogResponse({
|
DialogResponse({
|
||||||
this.fieldOne,
|
//this.fieldOne,
|
||||||
this.fieldTwo,
|
//this.fieldTwo,
|
||||||
|
this.responseText,
|
||||||
this.confirmed,
|
this.confirmed,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Service.dart';
|
||||||
|
|
||||||
|
class ProductDao {
|
||||||
|
final String name;
|
||||||
|
final num price;
|
||||||
|
num count;
|
||||||
|
num total;
|
||||||
|
final Good good;
|
||||||
|
final Service service;
|
||||||
|
|
||||||
|
|
||||||
|
ProductDao( {this.name, this.price, this.count, this.total, this.good, this.service });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
class Smena {
|
||||||
|
final int id;
|
||||||
|
final DateTime startedAt;
|
||||||
|
final DateTime endedAt;
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
Smena({this.id, this.startedAt, this.endedAt, this.message});
|
||||||
|
|
||||||
|
static Smena fromJson(Map<String, dynamic> data) => Smena(
|
||||||
|
id: data['id'],
|
||||||
|
message: data['message'],
|
||||||
|
startedAt:
|
||||||
|
data['started_at'] != null
|
||||||
|
? DateTime.parse(data['started_at'])
|
||||||
|
: null,
|
||||||
|
endedAt:
|
||||||
|
data['ended_at'] != null
|
||||||
|
? DateTime.parse(data['ended_at'])
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
const String LoginViewRoute = "LoginView";
|
const String LoginViewRoute = "LoginView";
|
||||||
const String HomeViewRoute = "HomeView";
|
const String HomeViewRoute = "HomeView";
|
||||||
|
const String ImageShowRoute = "ImageShowRoute";
|
||||||
|
const String PaymentViewRoute = "PaymentView";
|
||||||
// Generate the views here
|
// Generate the views here
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
|
||||||
|
|
||||||
import './route_names.dart';
|
import './route_names.dart';
|
||||||
import 'package:aman_kassa_flutter/views/home/home_view.dart';
|
import 'package:aman_kassa_flutter/views/home/home_view.dart';
|
||||||
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
||||||
|
|
@ -15,11 +18,15 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: HomeView(),
|
viewToShow: HomeView(),
|
||||||
);
|
);
|
||||||
// case AddAndEditViewRoute:
|
case PaymentViewRoute:
|
||||||
// var documentToEdit = settings.arguments as Document;
|
PaymentModel model = settings.arguments as PaymentModel;
|
||||||
// return SlideRightRoute(widget:AddAndEditView(
|
return _getPageRoute(
|
||||||
// edittingDocument: documentToEdit,
|
routeName: settings.name,
|
||||||
// ));
|
viewToShow: PaymentView(model: model),
|
||||||
|
);
|
||||||
|
case ImageShowRoute:
|
||||||
|
ImageShowModel data = settings.arguments as ImageShowModel;
|
||||||
|
return SlideRightRoute(widget:ImageShowContainer(data));
|
||||||
default:
|
default:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
builder: (_) => Scaffold(
|
builder: (_) => Scaffold(
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/Message.dart';
|
import 'package:aman_kassa_flutter/core/models/message.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/Response.dart';
|
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||||
import '../models/authResponse.dart';
|
import 'package:aman_kassa_flutter/core/models/smena.dart';
|
||||||
|
import '../models/auth_response.dart';
|
||||||
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
|
|
@ -15,32 +16,92 @@ class ApiService extends BaseService {
|
||||||
|
|
||||||
var client = new http.Client();
|
var client = new http.Client();
|
||||||
|
|
||||||
Future<AuthBody> authenticate(String email, String password) async {
|
Future<AuthBody> authenticate(String email, String password, { bool statusCheck = true}) async {
|
||||||
Map<String, String> requestBody = <String, String>{
|
Map<String, String> requestBody = <String, String>{
|
||||||
'email': email,
|
'email': email,
|
||||||
'password': password
|
'password': password
|
||||||
};
|
};
|
||||||
var response = await requestFormData('/authenticate', requestBody);
|
String response = await requestFormData('/authenticate', requestBody, statusCheck: statusCheck );
|
||||||
final respStr = await response.stream.bytesToString();
|
|
||||||
AuthResponse aman = AuthResponse.fromJson(json.decode(respStr));
|
AuthResponse aman = AuthResponse.fromJson(json.decode(response));
|
||||||
return aman.body;
|
return aman.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response<Message>> isActive(String token) async {
|
Future<Response<Message>> isActive(String token) async {
|
||||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
var response = await requestFormData('/test_auth', requestBody);
|
var response = await requestFormData('/test_auth', requestBody);
|
||||||
final respStr = await response.stream.bytesToString();
|
return Response.fromJson(json.decode(response), Message.fromJson);
|
||||||
return Response.fromJson(json.decode(respStr), Message.fromJson);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response<Message>> logout(String token) async {
|
Future<Response<Message>> logout(String token) async {
|
||||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
var response = await requestFormData('/logout', requestBody);
|
var response = await requestFormData('/logout', requestBody);
|
||||||
final respStr = await response.stream.bytesToString();
|
return Response.fromJson(json.decode(response), Message.fromJson);
|
||||||
return Response.fromJson(json.decode(respStr), Message.fromJson);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<http.StreamedResponse> requestFormData(String point, Map<String, String> requestBody) async {
|
Future<Response<dynamic>> money(String token) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
|
var response = await requestFormData('/money', requestBody);
|
||||||
|
return Response.fromJsonDynamic(json.decode(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response<dynamic>> deposit(String token, String sum) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token, 'summ': sum};
|
||||||
|
var response = await requestFormData('/deposit', requestBody);
|
||||||
|
return Response.fromJsonDynamic(json.decode(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response<dynamic>> withdrawal(String token, String sum) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token, 'summ': sum};
|
||||||
|
var response = await requestFormData('/withdrawal', requestBody);
|
||||||
|
return Response.fromJsonDynamic(json.decode(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Future<Response<Smena>> smena(String token) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
|
var response = await requestFormData('/smena', requestBody);
|
||||||
|
|
||||||
|
return Response.fromJson(json.decode(response), Smena.fromJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response<Smena>> closeSmena(String token) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
|
var response = await requestFormData('/close_smena', requestBody);
|
||||||
|
|
||||||
|
return Response.fromJson(json.decode(response), Smena.fromJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response<Smena>> openSmena(String token) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
|
var response = await requestFormData('/open_smena', requestBody);
|
||||||
|
return Response.fromJson(json.decode(response), Smena.fromJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response<dynamic>> xReport(String token) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
|
var response = await requestFormData('/report_x', requestBody);
|
||||||
|
|
||||||
|
return Response.fromJsonDynamic(json.decode(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response<dynamic>> sell(String token, String checkData) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token, 'data': checkData};
|
||||||
|
var response = await requestFormData('/sell', requestBody);
|
||||||
|
print(response);
|
||||||
|
return Response.fromJsonDynamic(json.decode(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response<dynamic>> sellReturn(String token, String checkData) async {
|
||||||
|
Map<String, String> requestBody = <String, String>{'api_token': token, 'data': checkData};
|
||||||
|
var response = await requestFormData('/sell_return', requestBody);
|
||||||
|
print(response);
|
||||||
|
return Response.fromJsonDynamic(json.decode(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<String> requestFormData(String point, Map<String, String> requestBody, { bool statusCheck = true } ) async {
|
||||||
Map<String, String> headers = <String, String>{
|
Map<String, String> headers = <String, String>{
|
||||||
HttpHeaders.contentTypeHeader: "multipart/form-data",
|
HttpHeaders.contentTypeHeader: "multipart/form-data",
|
||||||
HttpHeaders.cacheControlHeader: "no-cache"
|
HttpHeaders.cacheControlHeader: "no-cache"
|
||||||
|
|
@ -48,32 +109,38 @@ class ApiService extends BaseService {
|
||||||
|
|
||||||
var uri = Uri.parse('$endpoint$point');
|
var uri = Uri.parse('$endpoint$point');
|
||||||
var request = http.MultipartRequest('POST', uri)
|
var request = http.MultipartRequest('POST', uri)
|
||||||
..headers.addAll(
|
..headers.addAll(headers)
|
||||||
headers) //if u have headers, basic auth, token bearer... Else remove line
|
|
||||||
..fields.addAll(requestBody);
|
..fields.addAll(requestBody);
|
||||||
return await request.send();
|
|
||||||
|
var response = await request.send();
|
||||||
|
|
||||||
|
String body = await response.stream.bytesToString();
|
||||||
|
if(statusCheck) { //Проверка на авторизованный запрос, необязательный параметр
|
||||||
|
Response check = Response.fromJsonDynamic(json.decode(body));
|
||||||
|
if (!check.operation && check.status == 401) {
|
||||||
|
print('object');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response<dynamic>> getGoodsFromServer(String token) async {
|
Future<Response<dynamic>> getGoodsFromServer(String token) async {
|
||||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
var response = await requestFormData('/goods', requestBody);
|
var response = await requestFormData('/goods', requestBody);
|
||||||
final respStr = await response.stream.bytesToString();
|
print(response);
|
||||||
print(respStr);
|
return Response.fromJsonDynamic(json.decode(response));
|
||||||
return Response.fromJsonDynamic(json.decode(respStr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response<dynamic>> getCategoryFromServer(String token) async {
|
Future<Response<dynamic>> getCategoryFromServer(String token) async {
|
||||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
var response = await requestFormData('/goods_category', requestBody);
|
var response = await requestFormData('/goods_category', requestBody);
|
||||||
final respStr = await response.stream.bytesToString();
|
print(response);
|
||||||
print(respStr);
|
return Response.fromJsonDynamic(json.decode(response));
|
||||||
return Response.fromJsonDynamic(json.decode(respStr));
|
|
||||||
}
|
}
|
||||||
Future<Response<dynamic>> getServiceFromServer(String token) async {
|
Future<Response<dynamic>> getServiceFromServer(String token) async {
|
||||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
var response = await requestFormData('/services', requestBody);
|
var response = await requestFormData('/services', requestBody);
|
||||||
final respStr = await response.stream.bytesToString();
|
print(response);
|
||||||
print(respStr);
|
return Response.fromJsonDynamic(json.decode(response));
|
||||||
return Response.fromJsonDynamic(json.decode(respStr));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,14 @@ 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/Goods.dart';
|
||||||
import 'package:aman_kassa_flutter/core/entity/Service.dart';
|
import 'package:aman_kassa_flutter/core/entity/Service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/Response.dart';
|
import 'package:aman_kassa_flutter/core/models/check_data.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/core/services/DbService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
|
||||||
import 'ApiService.dart';
|
import 'ApiService.dart';
|
||||||
|
|
||||||
|
|
@ -14,19 +20,94 @@ class DataService extends BaseService {
|
||||||
final ApiService _api = locator<ApiService>();
|
final ApiService _api = locator<ApiService>();
|
||||||
final DbService _db = locator<DbService>();
|
final DbService _db = locator<DbService>();
|
||||||
|
|
||||||
Future<List<Category>> getCategoriesByParentId ( {int parentId} ) async {
|
Future<List<Category>> getCategoriesByParentId({int parentId}) async {
|
||||||
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(Category_tableName, '$Category_columnParentIn = ?', [parentId ?? 0 ]);
|
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(
|
||||||
|
Category_tableName, '$Category_columnParentIn = ?', [parentId ?? 0]);
|
||||||
return list.map((e) => Category.fromMap(e)).toList();
|
return list.map((e) => Category.fromMap(e)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Good>> getGoodsByCategoryId ( {int categoryId} ) async {
|
Future<List<Service>> getServices() async {
|
||||||
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(Goog_tableName, '$Goog_columnCategoryId = ?', [categoryId ?? 0]);
|
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();
|
return list.map((e) => Good.fromMap(e)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> getDataFromServer(String token) async {
|
CheckData _transformProductsToCheckData(
|
||||||
try {
|
{String paymentType,
|
||||||
|
String tradeType,
|
||||||
|
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 ?? 'Позиция №$iterator',
|
||||||
|
cnt: el.count,
|
||||||
|
price: el.price,
|
||||||
|
articul: articul));
|
||||||
|
summ += el.total;
|
||||||
|
iterator++;
|
||||||
|
});
|
||||||
|
CheckData checkData = CheckData(type: tradeType, items: itemsList);
|
||||||
|
if ((paymentType ?? 'cash') == 'card') {
|
||||||
|
checkData.card = summ;
|
||||||
|
}
|
||||||
|
print(checkData);
|
||||||
|
return checkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Response<dynamic>> sellOrReturn(
|
||||||
|
{String paymentType,
|
||||||
|
String tradeType,
|
||||||
|
String token,
|
||||||
|
List<ProductDao> items,
|
||||||
|
String operationType}) async {
|
||||||
|
try {
|
||||||
|
CheckData checkData = _transformProductsToCheckData(
|
||||||
|
paymentType: paymentType, tradeType: tradeType, items: items);
|
||||||
|
String 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) {
|
||||||
|
log.i(
|
||||||
|
'save to db appCompanyId: ${Redux.store.state.userState.user.appCompanyId}, kassaId: ${Redux.store.state.userState.user.kassaId}');
|
||||||
|
/* save data to db
|
||||||
|
* data,
|
||||||
|
* dateTime,
|
||||||
|
* check,
|
||||||
|
* appCompanyId,
|
||||||
|
* kassaId,
|
||||||
|
* total,
|
||||||
|
* name,
|
||||||
|
* type
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> getDataFromServer(User user) async {
|
||||||
|
try {
|
||||||
|
String token = user.token;
|
||||||
Response<dynamic> goods = await _api.getGoodsFromServer(token);
|
Response<dynamic> goods = await _api.getGoodsFromServer(token);
|
||||||
Response<dynamic> categories = await _api.getCategoryFromServer(token);
|
Response<dynamic> categories = await _api.getCategoryFromServer(token);
|
||||||
Response<dynamic> services = await _api.getServiceFromServer(token);
|
Response<dynamic> services = await _api.getServiceFromServer(token);
|
||||||
|
|
@ -37,21 +118,21 @@ class DataService extends BaseService {
|
||||||
for (var key in goods.body.keys) {
|
for (var key in goods.body.keys) {
|
||||||
print(goods.body[key]);
|
print(goods.body[key]);
|
||||||
Good row = Good.fromJson(goods.body[key]);
|
Good row = Good.fromJson(goods.body[key]);
|
||||||
_db.insert(Goog_tableName,row.toMap());
|
await _db.insert(Goog_tableName, row.toMap());
|
||||||
}
|
}
|
||||||
log.i('Inserted ${goods.body.length} to table $Goog_tableName');
|
log.i('Inserted ${goods.body.length} to table $Goog_tableName');
|
||||||
|
|
||||||
for (var el in categories.body) {
|
for (var el in categories.body) {
|
||||||
print(el);
|
print(el);
|
||||||
Category row = Category.fromJson(el);
|
Category row = Category.fromJson(el);
|
||||||
_db.insert(Category_tableName,row.toMap());
|
await _db.insert(Category_tableName, row.toMap());
|
||||||
}
|
}
|
||||||
log.i('Inserted ${categories.body.length} to table $Category_tableName');
|
log.i('Inserted ${categories.body.length} to table $Category_tableName');
|
||||||
|
|
||||||
for (var key in services.body.keys) {
|
for (var key in services.body.keys) {
|
||||||
print(services.body[key]);
|
print(services.body[key]);
|
||||||
Service row = Service.fromJson(services.body[key]);
|
Service row = Service.fromJson(services.body[key]);
|
||||||
_db.insert(Service_tableName,row.toMap());
|
await _db.insert(Service_tableName, row.toMap());
|
||||||
}
|
}
|
||||||
log.i('Inserted ${services.body.length} to table $Service_tableName');
|
log.i('Inserted ${services.body.length} to table $Service_tableName');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
class DbService extends BaseService {
|
class DbService extends BaseService {
|
||||||
static final _databaseName = "AmanFlutterDb.db";
|
static final _databaseName = "AmanFlutterDb.db";
|
||||||
static final _databaseVersion = 5;
|
static final _databaseVersion = 15;
|
||||||
|
|
||||||
// make this a singleton class
|
// make this a singleton class
|
||||||
DbService._privateConstructor();
|
DbService._privateConstructor();
|
||||||
|
|
@ -39,18 +39,17 @@ class DbService extends BaseService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Future _onUpdate(Database db, int oldVersion, int newVersion) async {
|
Future _onUpdate(Database db, int oldVersion, int newVersion) async {
|
||||||
print('update from $oldVersion to $newVersion');
|
log.i('update from $oldVersion to $newVersion');
|
||||||
//Goods table
|
//Goods table
|
||||||
await db.execute('''
|
await db.execute('DROP TABLE IF EXISTS $Goog_tableName;');
|
||||||
DROP TABLE IF EXISTS $Goog_tableName;
|
await db.execute('DROP TABLE IF EXISTS $Category_tableName;');
|
||||||
DROP TABLE IF EXISTS $Category_tableName;
|
await db.execute('DROP TABLE IF EXISTS $Service_tableName;');
|
||||||
DROP TABLE IF EXISTS $Service_tableName;
|
log.i('dropped tables');
|
||||||
''');
|
|
||||||
_onCreate(db, newVersion);
|
_onCreate(db, newVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _onCreate(Database db, int version) async {
|
Future _onCreate(Database db, int version) async {
|
||||||
print('create tables');
|
log.i('create tables');
|
||||||
//Goods table
|
//Goods table
|
||||||
await db.execute('''
|
await db.execute('''
|
||||||
CREATE TABLE IF NOT EXISTS $Goog_tableName (
|
CREATE TABLE IF NOT EXISTS $Goog_tableName (
|
||||||
|
|
@ -59,20 +58,35 @@ class DbService extends BaseService {
|
||||||
$Goog_columnName text not null,
|
$Goog_columnName text not null,
|
||||||
$Goog_columnPrice real not null,
|
$Goog_columnPrice real not null,
|
||||||
$Goog_columnCategoryId integer not null,
|
$Goog_columnCategoryId integer not null,
|
||||||
$Goog_columnEan text);
|
$Goog_columnEan text,
|
||||||
|
$Goog_columnAppCompanyId integer,
|
||||||
|
$Goog_columnDescription text,
|
||||||
|
$Goog_columnShowPrice real,
|
||||||
|
$Goog_columnOkei integer,
|
||||||
|
$Goog_columnDiscount real
|
||||||
|
);
|
||||||
''');
|
''');
|
||||||
await db.execute('''
|
await db.execute('''
|
||||||
CREATE TABLE IF NOT EXISTS $Category_tableName (
|
CREATE TABLE IF NOT EXISTS $Category_tableName (
|
||||||
$Category_columnId integer primary key unique,
|
$Category_columnId integer primary key unique,
|
||||||
$Category_columnName text not null,
|
$Category_columnName text not null,
|
||||||
$Category_columnParentIn integer);
|
$Category_columnParentIn integer,
|
||||||
|
$Category_columnAppCompanyId integer
|
||||||
|
);
|
||||||
''');
|
''');
|
||||||
|
//Service
|
||||||
await db.execute('''
|
await db.execute('''
|
||||||
CREATE TABLE IF NOT EXISTS $Service_tableName (
|
CREATE TABLE IF NOT EXISTS $Service_tableName (
|
||||||
$Service_columnId integer primary key unique,
|
$Service_columnId integer primary key unique,
|
||||||
$Service_columnArticul integer not null,
|
$Service_columnArticul integer not null,
|
||||||
$Service_columnName text not null,
|
$Service_columnName text not null,
|
||||||
$Service_columnPrice real not null);
|
$Service_columnPrice real not null,
|
||||||
|
$Service_columnAppCompanyId integer,
|
||||||
|
$Service_columnDescription text,
|
||||||
|
$Service_columnShowPrice real,
|
||||||
|
$Service_columnOkei text,
|
||||||
|
$Service_columnDiscount real
|
||||||
|
);
|
||||||
''');
|
''');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/Message.dart';
|
import 'package:aman_kassa_flutter/core/models/message.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/Response.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/models/user.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/authResponse.dart';
|
import 'package:aman_kassa_flutter/core/models/auth_response.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
import 'ApiService.dart';
|
import 'ApiService.dart';
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,20 @@ import 'package:flutter/cupertino.dart';
|
||||||
class DialogService {
|
class DialogService {
|
||||||
GlobalKey<NavigatorState> _dialogNavigationKey = GlobalKey<NavigatorState>();
|
GlobalKey<NavigatorState> _dialogNavigationKey = GlobalKey<NavigatorState>();
|
||||||
Function(DialogRequest) _showDialogListener;
|
Function(DialogRequest) _showDialogListener;
|
||||||
|
Function(DialogRequest) _showDialogInputListener;
|
||||||
Completer<DialogResponse> _dialogCompleter;
|
Completer<DialogResponse> _dialogCompleter;
|
||||||
|
|
||||||
GlobalKey<NavigatorState> get dialogNavigationKey => _dialogNavigationKey;
|
GlobalKey<NavigatorState> get dialogNavigationKey => _dialogNavigationKey;
|
||||||
|
|
||||||
/// Registers a callback function. Typically to show the dialog
|
/// Registers a callback function. Typically to show the dialog
|
||||||
void registerDialogListener(Function(DialogRequest) showDialogListener) {
|
void registerDialogListener(Function(DialogRequest) showDialogListener, Function(DialogRequest) showDialogInputListener) {
|
||||||
_showDialogListener = showDialogListener;
|
_showDialogListener = showDialogListener;
|
||||||
|
_showDialogInputListener = showDialogInputListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls the dialog listener and returns a Future that will wait for dialogComplete.
|
/// Calls the dialog listener and returns a Future that will wait for dialogComplete.
|
||||||
Future<DialogResponse> showDialog({
|
Future<DialogResponse> showDialog({
|
||||||
String title,
|
String title = 'Aman Касса',
|
||||||
String description,
|
String description,
|
||||||
String buttonTitle = 'Ok',
|
String buttonTitle = 'Ok',
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -45,6 +47,20 @@ class DialogService {
|
||||||
return _dialogCompleter.future;
|
return _dialogCompleter.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<DialogResponse> showConfirmationDialogInput(
|
||||||
|
{String title =' Aman Касса',
|
||||||
|
String description,
|
||||||
|
String confirmationTitle = 'Ok',
|
||||||
|
String cancelTitle = 'Cancel'}) {
|
||||||
|
_dialogCompleter = Completer<DialogResponse>();
|
||||||
|
_showDialogInputListener(DialogRequest(
|
||||||
|
title: title,
|
||||||
|
description: description,
|
||||||
|
buttonTitle: confirmationTitle,
|
||||||
|
cancelTitle: cancelTitle));
|
||||||
|
return _dialogCompleter.future;
|
||||||
|
}
|
||||||
|
|
||||||
/// Completes the _dialogCompleter to resume the Future's execution call
|
/// Completes the _dialogCompleter to resume the Future's execution call
|
||||||
void dialogComplete(DialogResponse response) {
|
void dialogComplete(DialogResponse response) {
|
||||||
_dialogNavigationKey.currentState.pop();
|
_dialogNavigationKey.currentState.pop();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
List<String> parseListString(json){
|
||||||
|
if(json==null) return null;
|
||||||
|
return new List<String>.from(json);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/dict_dao.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/smena.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
|
|
||||||
|
import '../store.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class SetCalcStateAction {
|
||||||
|
final CalcState calcState;
|
||||||
|
SetCalcStateAction(this.calcState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> setEqual(Store<AppState> store) async {
|
||||||
|
store.dispatch(SetCalcStateAction(CalcState(isEqual: true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> onTapAction(String value) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
|
||||||
|
if(value == Calculations.EQUAL){
|
||||||
|
return setEqual(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO create private methods by operations and values
|
||||||
|
List calcItems = Calculator.action(value: value, items: store.state.calcState.calcItems);
|
||||||
|
calcItems.asMap().forEach((index,element ) {
|
||||||
|
print('#$index: ${element.toString()}');
|
||||||
|
});
|
||||||
|
store.dispatch(SetCalcStateAction(CalcState(calcItems: calcItems, isEqual: false)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
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/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/dict_dao.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/smena.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
|
|
||||||
|
import '../store.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class SetKassaStateAction {
|
||||||
|
final KassaState kassaState;
|
||||||
|
SetKassaStateAction(this.kassaState);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ApiService _api = locator<ApiService>();
|
||||||
|
final DataService _dataService = locator<DataService>();
|
||||||
|
final NavigatorService _navigation = locator<NavigatorService>();
|
||||||
|
|
||||||
|
Future<void> backBottomElement(Store<AppState> store) async {
|
||||||
|
List<DictDao> prevCategories = store.state.kassaState.prevCategories;
|
||||||
|
DictDao last = prevCategories.removeLast();
|
||||||
|
if (last != null) {
|
||||||
|
store.dispatch(SetKassaStateAction(KassaState(prevCategories: prevCategories)));
|
||||||
|
store.dispatch(selectBottomElement(last.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> addCustomProductToKassaItems(String name, int count, double price, double total) {
|
||||||
|
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)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ThunkAction<AppState> addProductToKassaItems(Good good) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
List<ProductDao> items = store.state.kassaState.kassaItems;
|
||||||
|
int index = items.indexWhere((element) => element.good?.id == good.id);
|
||||||
|
if (index > -1) {
|
||||||
|
store.dispatch(counterProductFromKassaItems(index, 1));
|
||||||
|
} else {
|
||||||
|
items.add(new ProductDao(
|
||||||
|
name: good.name, good: good, count: 1, price: good.price, total: good.price));
|
||||||
|
store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> addServiceToKassaItems(Service service) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
List<ProductDao> items = store.state.kassaState.kassaItems;
|
||||||
|
int index = items.indexWhere((element) => element.good?.id == service.id);
|
||||||
|
if (index > -1) {
|
||||||
|
store.dispatch(counterProductFromKassaItems(index, 1));
|
||||||
|
} else {
|
||||||
|
items.add(new ProductDao(
|
||||||
|
name: service.name, service: service, count: 1, price: service.price, total: service.price));
|
||||||
|
store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> removeProductFromKassaItems(int index) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
List<ProductDao> items = List.from(store.state.kassaState.kassaItems);
|
||||||
|
items.removeAt(index);
|
||||||
|
store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> counterProductFromKassaItems(int index, int counter) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
List<ProductDao> items = store.state.kassaState.kassaItems;
|
||||||
|
ProductDao product = items.elementAt(index);
|
||||||
|
if (product.count == 1 && counter < 0) {
|
||||||
|
//if count to zero need delete element
|
||||||
|
store.dispatch(removeProductFromKassaItems(index));
|
||||||
|
} else {
|
||||||
|
product.count += counter;
|
||||||
|
product.total = (((product.count * product.price) * 100).roundToDouble()) / 100;
|
||||||
|
store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> selectBottomElement(int parentId) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
store.dispatch(SetKassaStateAction(KassaState(bottomSheetLoading: true)));
|
||||||
|
try {
|
||||||
|
List<DictDao> prevCategories = store.state.kassaState.prevCategories;
|
||||||
|
if (parentId == 0) {
|
||||||
|
prevCategories = [];
|
||||||
|
}
|
||||||
|
store.state.kassaState.bottomSheetElements.forEach((element) {
|
||||||
|
if (element is Category && element.id == parentId) {
|
||||||
|
prevCategories.add(DictDao(id: element.parentIn, name: element.name));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
List _bottomSheetElements = [];
|
||||||
|
|
||||||
|
|
||||||
|
if(store.state.settingState.tradeType == SettingTradeTypeGood) {
|
||||||
|
List<Category> categories = await _dataService.getCategoriesByParentId(parentId: parentId);
|
||||||
|
_bottomSheetElements.addAll(categories);
|
||||||
|
List<Good> goods = await _dataService.getGoodsByCategoryId(categoryId: parentId);
|
||||||
|
_bottomSheetElements.addAll(goods);
|
||||||
|
} else if(store.state.settingState.tradeType == SettingTradeTypeService) {
|
||||||
|
List<Service> services = await _dataService.getServices();
|
||||||
|
_bottomSheetElements.addAll(services);
|
||||||
|
}
|
||||||
|
|
||||||
|
store.dispatch(SetKassaStateAction(KassaState(
|
||||||
|
bottomSheetLoading: false,
|
||||||
|
bottomSheetElements: _bottomSheetElements,
|
||||||
|
prevCategories: prevCategories)));
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
store.dispatch(SetKassaStateAction(KassaState(bottomSheetLoading: false)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/models/DictDao.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/models/ProductDao.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
|
||||||
import 'package:aman_kassa_flutter/redux/state/main_state.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
import 'package:redux/redux.dart';
|
|
||||||
import 'package:redux_thunk/redux_thunk.dart';
|
|
||||||
|
|
||||||
import '../store.dart';
|
|
||||||
|
|
||||||
@immutable
|
|
||||||
class SetMainStateAction {
|
|
||||||
final MainState mainState;
|
|
||||||
|
|
||||||
SetMainStateAction(this.mainState);
|
|
||||||
}
|
|
||||||
|
|
||||||
final ApiService _api = locator<ApiService>();
|
|
||||||
final DataService _dataService = locator<DataService>();
|
|
||||||
final NavigatorService _navigation = locator<NavigatorService>();
|
|
||||||
|
|
||||||
Future<void> backBottomElement(Store<AppState> store) async {
|
|
||||||
List<DictDao> prevCategories = store.state.mainState.prevCategories;
|
|
||||||
DictDao last = prevCategories.removeLast();
|
|
||||||
if (last != null) {
|
|
||||||
store.dispatch(
|
|
||||||
SetMainStateAction(MainState(prevCategories: prevCategories)));
|
|
||||||
store.dispatch(selectBottomElement(last.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ThunkAction<AppState> addCustomProductToKassaItems(String name, int count, double price) {
|
|
||||||
return (Store<AppState> store) async {
|
|
||||||
List<ProductDao> items = store.state.mainState.kassaItems;
|
|
||||||
items.add(new ProductDao(name: name, count: count, price: price));
|
|
||||||
store.dispatch(SetMainStateAction(MainState(kassaItems: items)));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ThunkAction<AppState> addProductToKassaItems(Good good) {
|
|
||||||
return (Store<AppState> store) async {
|
|
||||||
List<ProductDao> items = store.state.mainState.kassaItems;
|
|
||||||
int index = items.indexWhere((element) => element.good?.id == good.id);
|
|
||||||
if (index > -1) {
|
|
||||||
store.dispatch(counterProductFromKassaItems(index, 1));
|
|
||||||
} else {
|
|
||||||
items.add(new ProductDao(
|
|
||||||
name: good.name, good: good, count: 1, price: good.price));
|
|
||||||
store.dispatch(SetMainStateAction(MainState(kassaItems: items)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ThunkAction<AppState> removeProductFromKassaItems(int index) {
|
|
||||||
return (Store<AppState> store) async {
|
|
||||||
List<ProductDao> items = List.from(store.state.mainState.kassaItems);
|
|
||||||
items.removeAt(index);
|
|
||||||
store.dispatch(SetMainStateAction(MainState(kassaItems: items)));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ThunkAction<AppState> counterProductFromKassaItems(int index, int counter) {
|
|
||||||
return (Store<AppState> store) async {
|
|
||||||
List<ProductDao> items = store.state.mainState.kassaItems;
|
|
||||||
if (items.elementAt(index).count == 1 && counter < 0) {
|
|
||||||
//if count to zero need delete element
|
|
||||||
store.dispatch(removeProductFromKassaItems(index));
|
|
||||||
} else {
|
|
||||||
items.elementAt(index).count += counter;
|
|
||||||
store.dispatch(SetMainStateAction(MainState(kassaItems: items)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ThunkAction<AppState> selectBottomElement(int parentId) {
|
|
||||||
return (Store<AppState> store) async {
|
|
||||||
store.dispatch(SetMainStateAction(MainState(bottomSheetLoading: true)));
|
|
||||||
try {
|
|
||||||
List<DictDao> prevCategories = store.state.mainState.prevCategories;
|
|
||||||
if (parentId == 0) {
|
|
||||||
prevCategories = [];
|
|
||||||
}
|
|
||||||
store.state.mainState.bottomSheetElements.forEach((element) {
|
|
||||||
if (element is Category && element.id == parentId) {
|
|
||||||
prevCategories.add(DictDao(id: element.parentIn, name: element.name));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
List<Category> categories =
|
|
||||||
await _dataService.getCategoriesByParentId(parentId: parentId);
|
|
||||||
List<Good> goods =
|
|
||||||
await _dataService.getGoodsByCategoryId(categoryId: parentId);
|
|
||||||
List _bottomSheetElements = [];
|
|
||||||
_bottomSheetElements.addAll(categories);
|
|
||||||
_bottomSheetElements.addAll(goods);
|
|
||||||
store.dispatch(SetMainStateAction(MainState(
|
|
||||||
bottomSheetLoading: false,
|
|
||||||
bottomSheetElements: _bottomSheetElements,
|
|
||||||
prevCategories: prevCategories)));
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
store.dispatch(SetMainStateAction(MainState(bottomSheetLoading: false)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Category.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/dict_dao.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/smena.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
|
|
||||||
|
import '../store.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class SetSettingStateAction {
|
||||||
|
final SettingState settingState;
|
||||||
|
SetSettingStateAction(this.settingState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ThunkAction<AppState> changeModeFromSetting(bool isKassa) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
store.dispatch(SetSettingStateAction(SettingState(mode: isKassa? SettingModeKassa: SettingModeCalc )));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> changeTradeTypeFromSetting(String tradeType) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
store.dispatch(SetSettingStateAction(SettingState(tradeType: tradeType )));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/Message.dart';
|
import 'package:aman_kassa_flutter/core/models/message.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/authResponse.dart';
|
import 'package:aman_kassa_flutter/core/models/auth_response.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/Response.dart';
|
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/smena.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/user.dart';
|
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||||
|
|
@ -53,7 +54,7 @@ ThunkAction<AppState> authenticate(String email, String password) {
|
||||||
return (Store<AppState> store) async {
|
return (Store<AppState> store) async {
|
||||||
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
||||||
try {
|
try {
|
||||||
AuthBody result = await _api.authenticate(email, password);
|
AuthBody result = await _api.authenticate(email, password, statusCheck: false);
|
||||||
store.dispatch(SetUserStateAction(UserState(
|
store.dispatch(SetUserStateAction(UserState(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
loginFormMessage: LoginFormMessage(email: result.email?.join(","), password: result.password?.join(","), message: result.message),
|
loginFormMessage: LoginFormMessage(email: result.email?.join(","), password: result.password?.join(","), message: result.message),
|
||||||
|
|
@ -66,7 +67,29 @@ ThunkAction<AppState> authenticate(String email, String password) {
|
||||||
_navigation.replace(HomeViewRoute);
|
_navigation.replace(HomeViewRoute);
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
print(e);
|
||||||
store.dispatch(SetUserStateAction(UserState(isLoading: false)));
|
store.dispatch(SetUserStateAction(UserState(isLoading: false)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> checkSmena(Store<AppState> store) async {
|
||||||
|
String token = store.state.userState.user.token;
|
||||||
|
Response<Smena> result = await _api.smena(token);
|
||||||
|
store.dispatch(SetUserStateAction(UserState(smena: result.body)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> closeSmena(Store<AppState> store) async {
|
||||||
|
String token = store.state.userState.user.token;
|
||||||
|
Response<Smena> result = await _api.closeSmena(token);
|
||||||
|
store.dispatch(SetUserStateAction(UserState(smena: result.body)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> openSmena(Store<AppState> store) async {
|
||||||
|
String token = store.state.userState.user.token;
|
||||||
|
Response<Smena> result = await _api.openSmena(token);
|
||||||
|
store.dispatch(SetUserStateAction(UserState(smena: result.body)));
|
||||||
|
if(result.operation){
|
||||||
|
store.dispatch(checkSmena);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
const String OperationTypePay = 'OperationTypePay';
|
||||||
|
const String OperationTypeReturn = 'OperationTypeReturn';
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
const String SettingModeKassa = 'kassaMode';
|
||||||
|
const String SettingModeCalc = 'calcMode';
|
||||||
|
|
||||||
|
|
||||||
|
const String SettingTradeTypeGood = 'g';
|
||||||
|
const String SettingTradeTypeService = 's';
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/calc_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
|
||||||
|
|
||||||
|
calcReducer(CalcState prevState, SetCalcStateAction action) {
|
||||||
|
final payload = action.calcState;
|
||||||
|
return prevState.copyWith(
|
||||||
|
calcItems: payload.calcItems,
|
||||||
|
isEqual: payload.isEqual
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/main_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
|
||||||
mainReducer(MainState prevState, SetMainStateAction action) {
|
mainReducer(KassaState prevState, SetKassaStateAction action) {
|
||||||
final payload = action.mainState;
|
final payload = action.kassaState;
|
||||||
return prevState.copyWith(
|
return prevState.copyWith(
|
||||||
bottomSheetElements: payload.bottomSheetElements,
|
bottomSheetElements: payload.bottomSheetElements,
|
||||||
bottomSheetLoading: payload.bottomSheetLoading,
|
bottomSheetLoading: payload.bottomSheetLoading,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
|
|
||||||
|
settingReducer(SettingState prevState, SetSettingStateAction action) {
|
||||||
|
final payload = action.settingState;
|
||||||
|
return prevState.copyWith(
|
||||||
|
mode: payload.mode,
|
||||||
|
tradeType: payload.tradeType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -10,5 +10,6 @@ userReducer(UserState prevState, SetUserStateAction action) {
|
||||||
user: payload.user,
|
user: payload.user,
|
||||||
isAuthenticated: payload.isAuthenticated,
|
isAuthenticated: payload.isAuthenticated,
|
||||||
loginFormMessage: payload.loginFormMessage,
|
loginFormMessage: payload.loginFormMessage,
|
||||||
|
smena: payload.smena,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
|
import 'package:aman_kassa_flutter/core/models/calc_model.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class CalcState {
|
||||||
|
final List<CalcModel> calcItems;
|
||||||
|
final bool isEqual;
|
||||||
|
|
||||||
|
CalcState({this.calcItems, this.isEqual});
|
||||||
|
|
||||||
|
factory CalcState.initial() => CalcState(calcItems: [], isEqual: false);
|
||||||
|
|
||||||
|
CalcState copyWith({
|
||||||
|
@required calcItems,
|
||||||
|
@required isEqual,
|
||||||
|
}) {
|
||||||
|
return CalcState(
|
||||||
|
calcItems: calcItems ?? this.calcItems,
|
||||||
|
isEqual: isEqual ?? this.isEqual,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,35 +1,37 @@
|
||||||
import 'package:aman_kassa_flutter/core/models/DictDao.dart';
|
import 'package:aman_kassa_flutter/core/models/dict_dao.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/ProductDao.dart';
|
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/smena.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
class MainState {
|
class KassaState {
|
||||||
final List bottomSheetElements;
|
final List bottomSheetElements;
|
||||||
final bool bottomSheetLoading;
|
final bool bottomSheetLoading;
|
||||||
final List<DictDao> prevCategories;
|
final List<DictDao> prevCategories;
|
||||||
|
|
||||||
final List<ProductDao> kassaItems;
|
final List<ProductDao> kassaItems;
|
||||||
|
|
||||||
MainState(
|
|
||||||
|
KassaState(
|
||||||
{this.bottomSheetElements,
|
{this.bottomSheetElements,
|
||||||
this.bottomSheetLoading,
|
this.bottomSheetLoading,
|
||||||
this.prevCategories,
|
this.prevCategories,
|
||||||
this.kassaItems});
|
this.kassaItems,
|
||||||
|
});
|
||||||
|
|
||||||
factory MainState.initial() => MainState(
|
factory KassaState.initial() => KassaState(
|
||||||
bottomSheetElements: [],
|
bottomSheetElements: [],
|
||||||
bottomSheetLoading: false,
|
bottomSheetLoading: false,
|
||||||
prevCategories: [],
|
prevCategories: [],
|
||||||
kassaItems: [],
|
kassaItems: [],
|
||||||
);
|
);
|
||||||
|
|
||||||
MainState copyWith({
|
KassaState copyWith({
|
||||||
@required bottomSheetElements,
|
@required bottomSheetElements,
|
||||||
@required bottomSheetLoading,
|
@required bottomSheetLoading,
|
||||||
@required prevCategories,
|
@required prevCategories,
|
||||||
@required kassaItems,
|
@required kassaItems,
|
||||||
}) {
|
}) {
|
||||||
return MainState(
|
return KassaState(
|
||||||
bottomSheetElements: bottomSheetElements ?? this.bottomSheetElements,
|
bottomSheetElements: bottomSheetElements ?? this.bottomSheetElements,
|
||||||
bottomSheetLoading: bottomSheetLoading ?? this.bottomSheetLoading,
|
bottomSheetLoading: bottomSheetLoading ?? this.bottomSheetLoading,
|
||||||
prevCategories: prevCategories ?? this.prevCategories,
|
prevCategories: prevCategories ?? this.prevCategories,
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class SettingState {
|
||||||
|
final String mode;
|
||||||
|
final String tradeType;
|
||||||
|
|
||||||
|
SettingState({this.mode, this.tradeType});
|
||||||
|
|
||||||
|
factory SettingState.initial() => SettingState(mode: SettingModeCalc, tradeType: SettingTradeTypeGood);
|
||||||
|
|
||||||
|
SettingState copyWith({
|
||||||
|
@required mode,
|
||||||
|
@required tradeType,
|
||||||
|
}) {
|
||||||
|
return SettingState(
|
||||||
|
mode: mode ?? this.mode,
|
||||||
|
tradeType: tradeType ?? this.tradeType,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/models/smena.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/user.dart';
|
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
|
@ -8,13 +9,15 @@ class UserState {
|
||||||
final bool isAuthenticated;
|
final bool isAuthenticated;
|
||||||
final LoginFormMessage loginFormMessage;
|
final LoginFormMessage loginFormMessage;
|
||||||
final User user;
|
final User user;
|
||||||
|
final Smena smena;
|
||||||
|
|
||||||
UserState({
|
UserState({
|
||||||
this.isError,
|
this.isError,
|
||||||
this.isLoading,
|
this.isLoading,
|
||||||
this.isAuthenticated,
|
this.isAuthenticated,
|
||||||
this.user,
|
this.user,
|
||||||
this.loginFormMessage
|
this.loginFormMessage,
|
||||||
|
this.smena
|
||||||
});
|
});
|
||||||
|
|
||||||
factory UserState.initial() => UserState(
|
factory UserState.initial() => UserState(
|
||||||
|
|
@ -22,6 +25,7 @@ class UserState {
|
||||||
isError: false,
|
isError: false,
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
loginFormMessage: LoginFormMessage(),
|
loginFormMessage: LoginFormMessage(),
|
||||||
|
smena: Smena(),
|
||||||
);
|
);
|
||||||
|
|
||||||
UserState copyWith({
|
UserState copyWith({
|
||||||
|
|
@ -30,6 +34,7 @@ class UserState {
|
||||||
@required User user,
|
@required User user,
|
||||||
@required bool isAuthenticated,
|
@required bool isAuthenticated,
|
||||||
@required LoginFormMessage loginFormMessage,
|
@required LoginFormMessage loginFormMessage,
|
||||||
|
@required Smena smena,
|
||||||
}) {
|
}) {
|
||||||
return UserState(
|
return UserState(
|
||||||
isError: isError ?? this.isError,
|
isError: isError ?? this.isError,
|
||||||
|
|
@ -37,6 +42,7 @@ class UserState {
|
||||||
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
||||||
user: user ?? this.user,
|
user: user ?? this.user,
|
||||||
loginFormMessage: loginFormMessage ?? this.loginFormMessage,
|
loginFormMessage: loginFormMessage ?? this.loginFormMessage,
|
||||||
|
smena: smena ?? this.smena,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,38 @@
|
||||||
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/reducers/calc_reducer.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/reducers/main_reducer.dart';
|
import 'package:aman_kassa_flutter/redux/reducers/main_reducer.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/reducers/setting_reducer.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/reducers/user_reducer.dart';
|
import 'package:aman_kassa_flutter/redux/reducers/user_reducer.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/main_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:redux/redux.dart';
|
import 'package:redux/redux.dart';
|
||||||
import 'package:redux_thunk/redux_thunk.dart';
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
|
|
||||||
|
import 'actions/calc_actions.dart';
|
||||||
|
|
||||||
//reducer context
|
//reducer context
|
||||||
AppState appReducer(AppState state, dynamic action) {
|
AppState appReducer(AppState state, dynamic action) {
|
||||||
|
if (action is SetUserStateAction) {
|
||||||
if (action is SetUserStateAction) { /** UserAction **/
|
/** UserAction **/
|
||||||
final nextUserState = userReducer(state.userState, action);
|
final nextUserState = userReducer(state.userState, action);
|
||||||
return state.copyWith(userState: nextUserState);
|
return state.copyWith(userState: nextUserState);
|
||||||
} else if(action is SetMainStateAction) { /** MainAction **/
|
} else if (action is SetKassaStateAction) {
|
||||||
final nextMainState = mainReducer(state.mainState, action);
|
/** KassaAction **/
|
||||||
return state.copyWith(mainState: nextMainState);
|
final nextMainState = mainReducer(state.kassaState, action);
|
||||||
|
return state.copyWith(kassaState: nextMainState);
|
||||||
|
} else if (action is SetSettingStateAction) {
|
||||||
|
/** SettingAction **/
|
||||||
|
final nextSettingState = settingReducer(state.settingState, action);
|
||||||
|
return state.copyWith(settingState: nextSettingState);
|
||||||
|
} else if (action is SetCalcStateAction) {
|
||||||
|
/** CalcAction **/
|
||||||
|
final nextCalcState = calcReducer(state.calcState, action);
|
||||||
|
return state.copyWith(calcState: nextCalcState);
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
@ -26,20 +41,29 @@ AppState appReducer(AppState state, dynamic action) {
|
||||||
@immutable
|
@immutable
|
||||||
class AppState {
|
class AppState {
|
||||||
final UserState userState;
|
final UserState userState;
|
||||||
final MainState mainState;
|
final KassaState kassaState;
|
||||||
|
final SettingState settingState;
|
||||||
|
final CalcState calcState;
|
||||||
|
|
||||||
AppState({
|
AppState({
|
||||||
@required this.userState,
|
@required this.userState,
|
||||||
@required this.mainState,
|
@required this.kassaState,
|
||||||
|
@required this.settingState,
|
||||||
|
@required this.calcState,
|
||||||
});
|
});
|
||||||
|
|
||||||
//stable work
|
//stable work
|
||||||
AppState copyWith({
|
AppState copyWith({
|
||||||
UserState userState,
|
UserState userState,
|
||||||
MainState mainState,
|
KassaState kassaState,
|
||||||
|
SettingState settingState,
|
||||||
|
CalcState calcState,
|
||||||
}) {
|
}) {
|
||||||
return AppState(
|
return AppState(
|
||||||
userState: userState ?? this.userState,
|
userState: userState ?? this.userState,
|
||||||
mainState: mainState ?? this.mainState,
|
kassaState: kassaState ?? this.kassaState,
|
||||||
|
settingState: settingState ?? this.settingState,
|
||||||
|
calcState: calcState ?? this.calcState,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -58,12 +82,18 @@ class Redux {
|
||||||
//initial context
|
//initial context
|
||||||
static Future<void> init() async {
|
static Future<void> init() async {
|
||||||
final userStateInitial = UserState.initial();
|
final userStateInitial = UserState.initial();
|
||||||
final mainStateInitial = MainState.initial();
|
final kassaStateInitial = KassaState.initial();
|
||||||
|
final settingStateInitial = SettingState.initial();
|
||||||
|
final calcStateInitial = CalcState.initial();
|
||||||
|
|
||||||
_store = Store<AppState>(
|
_store = Store<AppState>(
|
||||||
appReducer,
|
appReducer,
|
||||||
middleware: [thunkMiddleware],
|
middleware: [thunkMiddleware],
|
||||||
initialState: AppState(userState: userStateInitial, mainState: mainStateInitial),
|
initialState: AppState(
|
||||||
|
userState: userStateInitial,
|
||||||
|
kassaState: kassaStateInitial,
|
||||||
|
settingState: settingStateInitial,
|
||||||
|
calcState: calcStateInitial),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,10 +24,10 @@ const TextStyle productTextStyle = const TextStyle(fontWeight: FontWeight.w400,
|
||||||
const TextStyle buttonTitleTextStyle = const TextStyle(fontWeight: FontWeight.w700, color: whiteColor, fontSize: 15);
|
const TextStyle buttonTitleTextStyle = const TextStyle(fontWeight: FontWeight.w700, color: whiteColor, fontSize: 15);
|
||||||
const TextStyle buttonBigTitleTextStyle = const TextStyle(fontWeight: FontWeight.w700, color: whiteColor, fontSize: 22, );
|
const TextStyle buttonBigTitleTextStyle = const TextStyle(fontWeight: FontWeight.w700, color: whiteColor, fontSize: 22, );
|
||||||
|
|
||||||
const TextStyle stepTitleTextStyle =
|
const TextStyle dropDownTradeTypeTextStyle = TextStyle( color: Colors.black54, fontWeight: FontWeight.bold, fontSize: 24);
|
||||||
const TextStyle(fontWeight: FontWeight.w700, color: textColor, fontSize: 15);
|
|
||||||
const TextStyle stepSubTitleTextStyle = const TextStyle(fontWeight: FontWeight.w400, color: textColor, fontSize: 12);
|
|
||||||
|
|
||||||
// Box Shadow
|
// Box Shadow
|
||||||
const BoxShadow mainShadowBox = BoxShadow(blurRadius: 16, color: shadowColor, offset: Offset(0, 5));
|
const BoxShadow mainShadowBox = BoxShadow(blurRadius: 16, color: shadowColor, offset: Offset(0, 5));
|
||||||
const BoxShadow cardShadowBox = BoxShadow(blurRadius: 23, color: cardShadowColor, offset: Offset(0, 2));
|
const BoxShadow buttonShadowBox = BoxShadow(blurRadius: 5, color: Colors.grey, offset: Offset(0, 1));
|
||||||
|
const BoxShadow cardShadowBox = BoxShadow(blurRadius: 5, color: Colors.black26, offset: Offset(0, 5));
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ImageShowContainer extends StatelessWidget {
|
||||||
|
final ImageShowModel data;
|
||||||
|
ImageShowContainer(this.data);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
//backgroundColor: fillColor,
|
||||||
|
title: Text(data.title),
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
children: <Widget>[
|
||||||
|
imageFromBase64String(data.data)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Padding imageFromBase64String(String base64String) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 8.0),
|
||||||
|
child: Image.memory(base64Decode(base64String)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ImageShowModel {
|
||||||
|
final String data;
|
||||||
|
final String title;
|
||||||
|
ImageShowModel(this.data, this.title);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
|
|
||||||
|
class BottomBar extends StatelessWidget {
|
||||||
|
final PageController pageController;
|
||||||
|
final int selectedTabIndex;
|
||||||
|
|
||||||
|
BottomBar({
|
||||||
|
this.pageController,
|
||||||
|
this.selectedTabIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return StoreConnector<AppState, SettingState>(
|
||||||
|
converter: (store) => store.state.settingState,
|
||||||
|
builder: (context, vm) {
|
||||||
|
return BottomNavigationBar(
|
||||||
|
currentIndex: selectedTabIndex,
|
||||||
|
backgroundColor: menuColor,
|
||||||
|
type: BottomNavigationBarType.shifting,
|
||||||
|
items: [
|
||||||
|
vm.mode == SettingModeKassa
|
||||||
|
? BottomNavigationBarItem(
|
||||||
|
backgroundColor: menuColor,
|
||||||
|
icon: Icon(MdiIcons.cashRegister, color: Colors.white),
|
||||||
|
title: new Text(
|
||||||
|
'Касса',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
))
|
||||||
|
: BottomNavigationBarItem(
|
||||||
|
backgroundColor: menuColor,
|
||||||
|
icon: Icon(MdiIcons.calculator, color: Colors.white),
|
||||||
|
title: new Text(
|
||||||
|
'Калькулятор',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
)),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
backgroundColor: menuColor,
|
||||||
|
icon: Icon(MdiIcons.tune, color: Colors.white),
|
||||||
|
title: new Text(
|
||||||
|
'Опции',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
onTap: (index) {
|
||||||
|
pageController.animateToPage(
|
||||||
|
index,
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
class HeaderTitle extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return StoreConnector<AppState, UserState>(
|
||||||
|
converter: (store) => store.state.userState,
|
||||||
|
builder: (context, vm) {
|
||||||
|
return Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Container(
|
||||||
|
width: 75,
|
||||||
|
child: Image(
|
||||||
|
image: AssetImage('assets/images/logo.png'),
|
||||||
|
fit: BoxFit.fitWidth,
|
||||||
|
),
|
||||||
|
margin: const EdgeInsets.only(right: 15),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Text('Пользователь: ${vm.user.email}' ,style: TextStyle(fontSize: 13, color: Colors.black),),
|
||||||
|
vm.smena.message !=null
|
||||||
|
? Text(vm.smena.message, style: TextStyle(fontSize: 13, color: redColor) )
|
||||||
|
: vm.smena.startedAt !=null
|
||||||
|
? Text('Смена от: ${dateFormat.format(vm.smena.startedAt)}' , style: TextStyle(fontSize: 13, color: Colors.black),)
|
||||||
|
: Text('Смена от:', style: TextStyle(fontSize: 13, color: Colors.black),),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/models/choice.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
const List<Choice> choices = const <Choice>[
|
||||||
|
const Choice(title: 'Обновить номенклатуру', icon: Icons.update, command: 'update'),
|
||||||
|
const Choice(title: 'Помощь', icon: Icons.help, command: 'help'),
|
||||||
|
const Choice(title: 'О Программе', icon: Icons.info_outline, command: 'info'),
|
||||||
|
const Choice(title: 'Язык', icon: Icons.language, command: 'language'),
|
||||||
|
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
||||||
|
];
|
||||||
|
|
||||||
|
class PopupMenu extends StatelessWidget {
|
||||||
|
|
||||||
|
final void Function(Choice value) onSelectChoice;
|
||||||
|
|
||||||
|
PopupMenu({this.onSelectChoice});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return PopupMenuButton<Choice>(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.more_vert,
|
||||||
|
color: menuColor,
|
||||||
|
),
|
||||||
|
onSelected: onSelectChoice,
|
||||||
|
itemBuilder: (BuildContext context) {
|
||||||
|
return choices.map((Choice choice) {
|
||||||
|
return PopupMenuItem<Choice>(
|
||||||
|
value: choice,
|
||||||
|
child: Row(children: <Widget>[
|
||||||
|
Icon(choice.icon, color: primaryColor,),
|
||||||
|
Text(choice.title)
|
||||||
|
], ),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,22 +1,29 @@
|
||||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/Choice.dart';
|
import 'package:aman_kassa_flutter/core/logger.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/choice.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/home/components/header_title.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
import 'package:logger/logger.dart';
|
||||||
|
|
||||||
import './tabs/KassaTab.dart';
|
import './tabs/KassaTab.dart';
|
||||||
import './tabs/AdditionalTab.dart';
|
import './tabs/AdditionalTab.dart';
|
||||||
import './tabs/CalculatorTab.dart';
|
import './tabs/CalculatorTab.dart';
|
||||||
|
|
||||||
|
import './components/popup_menu.dart';
|
||||||
|
import 'components/bottom_bar.dart';
|
||||||
|
|
||||||
const List<Choice> choices = const <Choice>[
|
const List<Choice> choices = const <Choice>[
|
||||||
const Choice(title: 'Обновить номенклатуру', icon: Icons.update, command: 'update'),
|
const Choice(
|
||||||
|
title: 'Обновить номенклатуру', icon: Icons.update, command: 'update'),
|
||||||
const Choice(title: 'Помощь', icon: Icons.help, command: 'help'),
|
const Choice(title: 'Помощь', icon: Icons.help, command: 'help'),
|
||||||
const Choice(title: 'О Программе', icon: Icons.info_outline, command: 'info'),
|
const Choice(title: 'О Программе', icon: Icons.info_outline, command: 'info'),
|
||||||
const Choice(title: 'Язык', icon: Icons.language, command: 'language'),
|
const Choice(title: 'Язык', icon: Icons.language, command: 'language'),
|
||||||
|
|
@ -29,18 +36,18 @@ class HomeView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HomeViewState extends State<HomeView> {
|
class _HomeViewState extends State<HomeView> {
|
||||||
|
Logger log = getLogger('HomeView');
|
||||||
PageController pageController;
|
PageController pageController;
|
||||||
int selectedTabIndex;
|
int selectedTabIndex;
|
||||||
DataService _dataService = locator<DataService>();
|
DataService _dataService = locator<DataService>();
|
||||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
// TODO: implement initState
|
|
||||||
super.initState();
|
super.initState();
|
||||||
selectedTabIndex = 0;
|
selectedTabIndex = 0;
|
||||||
pageController = new PageController(initialPage: selectedTabIndex);
|
pageController = new PageController(initialPage: selectedTabIndex);
|
||||||
|
Redux.store.dispatch(checkSmena);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -50,13 +57,13 @@ class _HomeViewState extends State<HomeView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSelectChoice(Choice choice) async {
|
void _onSelectChoice(Choice choice) async {
|
||||||
if(choice.command == 'exit') {
|
if (choice.command == 'exit') {
|
||||||
|
|
||||||
} else if (choice.command == 'update') {
|
} else if (choice.command == 'update') {
|
||||||
Dialogs.showLoadingDialog(context, _keyLoader);
|
Dialogs.showLoadingDialog(context, _keyLoader);
|
||||||
bool result = await _dataService.getDataFromServer(Redux.store.state.userState.user.token);
|
bool result = await _dataService.getDataFromServer(Redux.store.state.userState.user);
|
||||||
print('result: $result');
|
log.i('result: $result');
|
||||||
Navigator.of(_keyLoader.currentContext,rootNavigator: true).pop();
|
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,37 +71,18 @@ class _HomeViewState extends State<HomeView> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Center(
|
title: HeaderTitle(),
|
||||||
child: Container(
|
|
||||||
width: 100,
|
|
||||||
child: Image(
|
|
||||||
image: AssetImage('assets/images/logo.png'),
|
|
||||||
fit: BoxFit.fitHeight,
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
PopupMenuButton<Choice>(
|
PopupMenu(
|
||||||
icon: Icon(
|
onSelectChoice: _onSelectChoice,
|
||||||
Icons.more_vert,
|
|
||||||
color: menuColor,
|
|
||||||
),
|
|
||||||
onSelected: _onSelectChoice,
|
|
||||||
itemBuilder: (BuildContext context) {
|
|
||||||
return choices.map((Choice choice) {
|
|
||||||
return PopupMenuItem<Choice>(
|
|
||||||
value: choice,
|
|
||||||
child: Row(children: <Widget>[
|
|
||||||
Icon(choice.icon, color: primaryColor,),
|
|
||||||
Text(choice.title)
|
|
||||||
], ),
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
backgroundColor: fillColor,
|
backgroundColor: fillColor,
|
||||||
),
|
),
|
||||||
body: PageView(
|
body:StoreConnector<AppState, SettingState>(
|
||||||
|
converter: (store) => store.state.settingState,
|
||||||
|
builder: (context, vm) {
|
||||||
|
return PageView(
|
||||||
onPageChanged: (index) {
|
onPageChanged: (index) {
|
||||||
setState(() {
|
setState(() {
|
||||||
selectedTabIndex = index;
|
selectedTabIndex = index;
|
||||||
|
|
@ -102,43 +90,15 @@ class _HomeViewState extends State<HomeView> {
|
||||||
},
|
},
|
||||||
controller: pageController,
|
controller: pageController,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
KassaTab(0),
|
vm.mode == SettingModeKassa ? KassaTab(0) : CalculatorTab(0),
|
||||||
CalculatorTab(1),
|
AdditionalTab(1),
|
||||||
AdditionalTab(2),
|
|
||||||
],
|
],
|
||||||
),
|
|
||||||
bottomNavigationBar: BottomNavigationBar(
|
|
||||||
currentIndex: selectedTabIndex,
|
|
||||||
backgroundColor: menuColor,
|
|
||||||
type: BottomNavigationBarType.shifting,
|
|
||||||
items: [
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
backgroundColor: menuColor,
|
|
||||||
icon: Icon(MdiIcons.cashRegister, color: Colors.white),
|
|
||||||
title: new Text(
|
|
||||||
'Касса',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
)),
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: Icon(MdiIcons.calculator, color: Colors.white),
|
|
||||||
title: new Text(
|
|
||||||
'Калькулятор',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
)),
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: Icon(MdiIcons.tune, color: Colors.white),
|
|
||||||
title: new Text(
|
|
||||||
'Опции',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
onTap: (index) {
|
|
||||||
pageController.animateToPage(
|
|
||||||
index,
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
curve: Curves.easeIn,
|
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
|
),
|
||||||
|
bottomNavigationBar: BottomBar(
|
||||||
|
pageController: pageController,
|
||||||
|
selectedTabIndex: selectedTabIndex,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,59 +1,298 @@
|
||||||
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/message.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/dialog_models.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/smena.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||||
|
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/user_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button_horizontal.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
|
|
||||||
class AdditionalTab extends StatelessWidget {
|
class AdditionalTab extends StatefulWidget {
|
||||||
final int index;
|
final int index;
|
||||||
|
|
||||||
AdditionalTab(this.index);
|
AdditionalTab(this.index);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AdditionalTabState createState() => _AdditionalTabState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AdditionalTabState extends State<AdditionalTab> {
|
||||||
|
ApiService _api = locator<ApiService>();
|
||||||
|
NavigatorService _navigator = locator<NavigatorService>();
|
||||||
|
DialogService _dialog = locator<DialogService>();
|
||||||
|
|
||||||
|
bool isMoneyCheckBusy;
|
||||||
|
bool closeSmenaBusy;
|
||||||
|
bool openSmenaBusy;
|
||||||
|
bool depositBusy;
|
||||||
|
bool withdrawalBusy;
|
||||||
|
bool xReportBusy;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
isMoneyCheckBusy = false;
|
||||||
|
closeSmenaBusy = false;
|
||||||
|
openSmenaBusy = false;
|
||||||
|
depositBusy = false;
|
||||||
|
withdrawalBusy = false;
|
||||||
|
xReportBusy = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _closeSmena() async {
|
||||||
|
setState(() {
|
||||||
|
closeSmenaBusy = true;
|
||||||
|
});
|
||||||
|
await Redux.store.dispatch(closeSmena);
|
||||||
|
setState(() {
|
||||||
|
closeSmenaBusy = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _openSmena() async {
|
||||||
|
setState(() {
|
||||||
|
openSmenaBusy = true;
|
||||||
|
});
|
||||||
|
await Redux.store.dispatch(openSmena);
|
||||||
|
setState(() {
|
||||||
|
openSmenaBusy = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _xReport() async {
|
||||||
|
setState(() {
|
||||||
|
xReportBusy = true;
|
||||||
|
});
|
||||||
|
Response response =
|
||||||
|
await _api.xReport(Redux.store.state.userState.user.token);
|
||||||
|
if (response.operation) {
|
||||||
|
_navigator.push(ImageShowRoute,
|
||||||
|
arguments: ImageShowModel(response.body['check'], 'X Отчет'));
|
||||||
|
} else {
|
||||||
|
_dialog.showDialog(description: response.body['message']);
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
xReportBusy = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _deposit() async {
|
||||||
|
setState(() {
|
||||||
|
depositBusy = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
DialogResponse response = await _dialog.showConfirmationDialogInput(
|
||||||
|
description: 'Укажите сумму',
|
||||||
|
cancelTitle: 'Отмена',
|
||||||
|
confirmationTitle: 'Взнос',
|
||||||
|
);
|
||||||
|
if (response.confirmed) {
|
||||||
|
Response<dynamic> result = await _api.deposit(
|
||||||
|
Redux.store.state.userState.user.token, response.responseText);
|
||||||
|
//if(result.operation) {
|
||||||
|
_dialog.showDialog(description: result.body['message']);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
depositBusy = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _withdrawal() async {
|
||||||
|
setState(() {
|
||||||
|
withdrawalBusy = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
DialogResponse response = await _dialog.showConfirmationDialogInput(
|
||||||
|
description: 'Укажите сумму',
|
||||||
|
cancelTitle: 'Отмена',
|
||||||
|
confirmationTitle: 'Снятие',
|
||||||
|
);
|
||||||
|
if (response.confirmed) {
|
||||||
|
Response<dynamic> result = await _api.withdrawal(
|
||||||
|
Redux.store.state.userState.user.token, response.responseText);
|
||||||
|
//if(result.operation) {
|
||||||
|
_dialog.showDialog(description: result.body['message']);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
withdrawalBusy = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _checkMoney() async {
|
||||||
|
setState(() {
|
||||||
|
isMoneyCheckBusy = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
Response<dynamic> result =
|
||||||
|
await _api.money(Redux.store.state.userState.user.token);
|
||||||
|
setState(() {
|
||||||
|
isMoneyCheckBusy = false;
|
||||||
|
});
|
||||||
|
if (result.operation) {
|
||||||
|
_dialog.showDialog(
|
||||||
|
description: 'Денег в кассе: ${result.body['money']}');
|
||||||
|
} else {
|
||||||
|
_dialog.showDialog(description: '${result.body['message']}');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
setState(() {
|
||||||
|
isMoneyCheckBusy = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StoreConnector<AppState, UserState>(
|
|
||||||
converter: (store) => store.state.userState,
|
|
||||||
builder: (context, vm) {
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 15),
|
padding: const EdgeInsets.symmetric(vertical: 15),
|
||||||
|
child: ListView(
|
||||||
|
children: <Widget>[
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
|
child: StoreConnector<AppState, SettingState>(
|
||||||
|
converter: (store) => store.state.settingState,
|
||||||
|
builder: (context, vm) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: AmanIconButtonHorizontal(
|
||||||
|
icon: MdiIcons.calculator,
|
||||||
|
title: 'Калькулятор',
|
||||||
|
selected: vm.mode == SettingModeCalc,
|
||||||
|
onPressed: () => changeMode(false),
|
||||||
|
)),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Center(
|
||||||
|
child: Switch(
|
||||||
|
value: vm.mode == SettingModeKassa,
|
||||||
|
onChanged: changeMode,
|
||||||
|
inactiveThumbColor: primaryColor,
|
||||||
|
activeColor: primaryColor,
|
||||||
|
))),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: AmanIconButtonHorizontal(
|
||||||
|
icon: MdiIcons.cashRegister,
|
||||||
|
title: 'Режим кассы',
|
||||||
|
selected: vm.mode == SettingModeKassa,
|
||||||
|
onPressed: () => changeMode(true))),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
Divider(),
|
||||||
|
verticalSpaceMedium,
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
|
child: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
verticalSpaceLarge,
|
Text(
|
||||||
|
'Денег в кассе:',
|
||||||
|
style: TextStyle(color: primaryColor, fontSize: 15),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'250 024.38 тенге',
|
||||||
|
style: TextStyle(
|
||||||
|
color: primaryColor,
|
||||||
|
fontSize: 25,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
verticalSpaceMedium,
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
BusyButton(title: 'Открыть смену', onPressed: null, mainColor: greenColor,),
|
AmanIconButton(
|
||||||
BusyButton(title: 'Закрыть смену', onPressed: null, mainColor: redColor ,),
|
title: 'Открыть смену',
|
||||||
|
onPressed: _openSmena,
|
||||||
|
mainColor: greenColor,
|
||||||
|
busy: openSmenaBusy,
|
||||||
|
icon: Icons.lock_open,
|
||||||
|
),
|
||||||
|
AmanIconButton(
|
||||||
|
title: 'Закрыть смену',
|
||||||
|
onPressed: _closeSmena,
|
||||||
|
mainColor: redColor,
|
||||||
|
busy: closeSmenaBusy,
|
||||||
|
icon: Icons.lock_outline,
|
||||||
|
),
|
||||||
|
AmanIconButton(
|
||||||
|
title: 'Денег в кассе',
|
||||||
|
onPressed: _checkMoney,
|
||||||
|
busy: isMoneyCheckBusy,
|
||||||
|
icon: Icons.attach_money,
|
||||||
|
mainColor: primaryColor,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
verticalSpaceLarge,
|
verticalSpaceTiny,
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
BusyButton(title: 'Денег в кассе', onPressed: null,),
|
AmanIconButton(
|
||||||
|
title: 'Х Отчет',
|
||||||
|
onPressed: _xReport,
|
||||||
|
busy: xReportBusy,
|
||||||
|
mainColor: primaryColor,
|
||||||
|
icon: Icons.description,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
verticalSpaceLarge,
|
verticalSpaceMedium,
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
BusyButton(title: 'Взнос наличных', onPressed: null,),
|
BusyButton(
|
||||||
BusyButton(title: 'Снятие наличных', onPressed: null, mainColor: redColor ,),
|
title: 'Взнос наличных',
|
||||||
|
onPressed: _deposit,
|
||||||
|
busy: depositBusy,
|
||||||
|
),
|
||||||
|
BusyButton(
|
||||||
|
title: 'Снятие наличных',
|
||||||
|
onPressed: _withdrawal,
|
||||||
|
mainColor: redColor,
|
||||||
|
busy: withdrawalBusy,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
verticalSpaceLarge,
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
BusyButton(title: 'Х Отчет', onPressed: null,),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
|
|
||||||
);
|
void changeMode(el) {
|
||||||
|
Redux.store.dispatch(changeModeFromSetting(el));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,26 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/calc_actions.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/state/calc_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/components/calculator/calculator-buttons.dart';
|
import 'package:aman_kassa_flutter/widgets/components/calculator/calculator-buttons.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/components/calculator/number-display.dart';
|
import 'package:aman_kassa_flutter/widgets/components/calculator/number-display.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CalculatorTab extends StatelessWidget {
|
class CalculatorTab extends StatelessWidget {
|
||||||
|
|
||||||
|
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
|
||||||
final int index;
|
final int index;
|
||||||
|
|
||||||
CalculatorTab(this.index);
|
CalculatorTab(this.index);
|
||||||
|
|
@ -14,10 +30,53 @@ class CalculatorTab extends StatelessWidget {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Column(
|
body: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
NumberDisplay(value: 'values'),
|
StoreConnector<AppState, CalcState>(
|
||||||
CalculatorButtons(onTap: null),
|
converter: (store) => store.state.calcState,
|
||||||
|
builder: (context, vm) {
|
||||||
|
return NumberDisplay(value: Calculator.parseItems(vm.calcItems, vm.isEqual));
|
||||||
|
}
|
||||||
|
),
|
||||||
|
CalculatorButtons(onTap: _onPress),
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
|
||||||
|
child: RaisedButton(
|
||||||
|
padding: EdgeInsets.all(10.0),
|
||||||
|
color: redColor,
|
||||||
|
child: Text(
|
||||||
|
"Возврат",
|
||||||
|
style: buttonBigTitleTextStyle,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeCalc, operationType: OperationTypeReturn) );
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: RaisedButton(
|
||||||
|
padding: EdgeInsets.all(10.0),
|
||||||
|
|
||||||
|
color: greenColor,
|
||||||
|
child: Text(
|
||||||
|
"Оплата",
|
||||||
|
style: buttonBigTitleTextStyle,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeCalc, operationType: OperationTypePay) );
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
],
|
],
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onPress({ String buttonText}) {
|
||||||
|
Redux.store.dispatch(onTapAction(buttonText));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,25 +1,33 @@
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/models/ProductDao.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/main_state.dart';
|
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.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/state/kassa_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
import 'package:aman_kassa_flutter/views/home/tabs/kassaView/CatalogBottomSheet.dart';
|
import 'package:aman_kassa_flutter/views/home/tabs/kassaView/CatalogBottomSheet.dart';
|
||||||
import 'package:aman_kassa_flutter/views/home/tabs/kassaView/ProductAddBottomSheet.dart';
|
import 'package:aman_kassa_flutter/views/home/tabs/kassaView/ProductAddBottomSheet.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/components/ProductListItem.dart';
|
import 'package:aman_kassa_flutter/widgets/components/ProductListItem.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
|
||||||
class KassaTab extends StatelessWidget {
|
class KassaTab extends StatelessWidget {
|
||||||
|
|
||||||
|
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
|
||||||
final int index;
|
final int index;
|
||||||
|
|
||||||
KassaTab(this.index);
|
KassaTab(this.index);
|
||||||
|
|
||||||
Widget buildItem(BuildContext ctxt, int index, ProductDao productDao) {
|
Widget buildItem(BuildContext ctxt, int index, ProductDao productDao) {
|
||||||
return ProductListItem(
|
return ProductListItem(
|
||||||
item: new ProductDao(name: productDao.name, count: productDao.count, price: productDao.price),
|
item: productDao,
|
||||||
index: index,
|
index: index,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -64,8 +72,8 @@ class KassaTab extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: StoreConnector<AppState, MainState>(
|
child: StoreConnector<AppState, KassaState>(
|
||||||
converter: (store) => store.state.mainState,
|
converter: (store) => store.state.kassaState,
|
||||||
builder: (context, vm) {
|
builder: (context, vm) {
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
itemCount: vm.kassaItems.length,
|
itemCount: vm.kassaItems.length,
|
||||||
|
|
@ -75,6 +83,21 @@ class KassaTab extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Divider(),
|
||||||
|
Container(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: <Widget>[
|
||||||
|
StoreConnector<AppState, KassaState>(
|
||||||
|
converter: (store) => store.state.kassaState,
|
||||||
|
builder: (context, vm) {
|
||||||
|
return Text(totalCalc(vm.kassaItems), style: TextStyle(fontSize: 25));
|
||||||
|
}
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
Row(
|
Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
|
|
@ -87,7 +110,9 @@ class KassaTab extends StatelessWidget {
|
||||||
"Возврат",
|
"Возврат",
|
||||||
style: buttonBigTitleTextStyle,
|
style: buttonBigTitleTextStyle,
|
||||||
),
|
),
|
||||||
onPressed: () => null,
|
onPressed: () {
|
||||||
|
_navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeKassa, operationType: OperationTypeReturn) );
|
||||||
|
}
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -101,7 +126,9 @@ class KassaTab extends StatelessWidget {
|
||||||
"Оплата",
|
"Оплата",
|
||||||
style: buttonBigTitleTextStyle,
|
style: buttonBigTitleTextStyle,
|
||||||
),
|
),
|
||||||
onPressed: () => null,
|
onPressed: () {
|
||||||
|
_navigatorService.push(PaymentViewRoute, arguments: PaymentModel(mode: SettingModeKassa, operationType: OperationTypePay) );
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -112,6 +139,14 @@ class KassaTab extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String totalCalc(List<ProductDao> kassaItems) {
|
||||||
|
num total = 0.0;
|
||||||
|
kassaItems.forEach((element) {
|
||||||
|
total+= element.total == null ? 0.0 : element.total.toDouble();
|
||||||
|
});
|
||||||
|
return total.toString();
|
||||||
|
}
|
||||||
|
|
||||||
void showModalBottomSheetCatalog(BuildContext context, String action) {
|
void showModalBottomSheetCatalog(BuildContext context, String action) {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,14 @@
|
||||||
import 'package:aman_kassa_flutter/core/entity/Category.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/Goods.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
import 'package:aman_kassa_flutter/core/entity/Service.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/main_state.dart';
|
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/Choice.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
|
|
@ -15,8 +22,8 @@ class CatalogBottomSheet extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StoreConnector<AppState, MainState>(
|
return StoreConnector<AppState, KassaState>(
|
||||||
converter: (store) => store.state.mainState,
|
converter: (store) => store.state.kassaState,
|
||||||
onInit: (store) => Redux.store.dispatch(selectBottomElement(0)),
|
onInit: (store) => Redux.store.dispatch(selectBottomElement(0)),
|
||||||
builder: (context, vm) {
|
builder: (context, vm) {
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
|
|
@ -36,8 +43,8 @@ class CatalogBottomSheet extends StatelessWidget {
|
||||||
style: TextStyle(color: Colors.black45),
|
style: TextStyle(color: Colors.black45),
|
||||||
),
|
),
|
||||||
iconTheme: IconThemeData(color: Colors.black),
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
backgroundColor: fillColor,
|
backgroundColor: whiteColor,
|
||||||
elevation: 3,
|
elevation: 1,
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: Icon(vm.prevCategories.length > 0
|
icon: Icon(vm.prevCategories.length > 0
|
||||||
? Icons.arrow_back
|
? Icons.arrow_back
|
||||||
|
|
@ -49,6 +56,7 @@ class CatalogBottomSheet extends StatelessWidget {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
actions: <Widget>[buildActionContainer()],
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
|
@ -60,30 +68,49 @@ class CatalogBottomSheet extends StatelessWidget {
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
var el = vm.bottomSheetElements[index];
|
var el = vm.bottomSheetElements[index];
|
||||||
String name;
|
String name;
|
||||||
|
String price;
|
||||||
if (el is Category) {
|
if (el is Category) {
|
||||||
Category category = el;
|
Category category = el;
|
||||||
name = category.name;
|
name = category.name;
|
||||||
} else if (el is Good) {
|
} else if (el is Good) {
|
||||||
Good good = el;
|
Good good = el;
|
||||||
name = good.name;
|
name = good.name;
|
||||||
|
price = good.price.toString();
|
||||||
|
} else if (el is Service) {
|
||||||
|
Service service = el;
|
||||||
|
name = service.name;
|
||||||
|
price = service.price.toString();
|
||||||
}
|
}
|
||||||
return Card(
|
return Card(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: Icon(
|
leading: el is Category
|
||||||
el is Category ? Icons.layers : Icons.move_to_inbox,
|
? Icon(Icons.layers, size: 25)
|
||||||
size: 40,
|
: null,
|
||||||
|
title: Text(
|
||||||
|
name,
|
||||||
|
style: TextStyle(fontSize: 15),
|
||||||
),
|
),
|
||||||
title: Text(name),
|
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (el is Category) {
|
if (el is Category) {
|
||||||
Redux.store.dispatch(selectBottomElement(el.id));
|
Redux.store
|
||||||
|
.dispatch(selectBottomElement(el.id));
|
||||||
} else if (el is Good) {
|
} else if (el is Good) {
|
||||||
await Redux.store.dispatch(addProductToKassaItems(el));
|
await Redux.store
|
||||||
|
.dispatch(addProductToKassaItems(el));
|
||||||
|
Navigator.pop(context);
|
||||||
|
} else if (el is Service) {
|
||||||
|
await Redux.store
|
||||||
|
.dispatch(addServiceToKassaItems(el));
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
trailing:
|
trailing: el is Category
|
||||||
el is Category ? Icon(Icons.chevron_right) : null,
|
? Icon(Icons.chevron_right)
|
||||||
|
: Text(
|
||||||
|
price,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15, color: Colors.black54),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -104,4 +131,68 @@ class CatalogBottomSheet extends StatelessWidget {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Container buildActionContainer() {
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 5.0),
|
||||||
|
child: StoreConnector<AppState, KassaState>(
|
||||||
|
converter: (store) => store.state.kassaState,
|
||||||
|
builder: (_, mainState) {
|
||||||
|
return StoreConnector<AppState, SettingState>(
|
||||||
|
converter: (store) => store.state.settingState,
|
||||||
|
builder: (_, settingState) {
|
||||||
|
if (mainState.kassaItems.isNotEmpty) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
locator<DialogService>().showDialog(
|
||||||
|
description:
|
||||||
|
'Выбрать другой тип продажи, возможно только при пустом списке покупок');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
child: Text(
|
||||||
|
settingState.tradeType == SettingTradeTypeGood
|
||||||
|
? 'Товары'
|
||||||
|
: 'Услуги',
|
||||||
|
style: dropDownTradeTypeTextStyle,
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return DropdownButton<String>(
|
||||||
|
value: settingState.tradeType,
|
||||||
|
icon: Icon(
|
||||||
|
Icons.arrow_drop_down_circle,
|
||||||
|
color: yellowColor,
|
||||||
|
),
|
||||||
|
iconSize: 24,
|
||||||
|
elevation: 6,
|
||||||
|
style: dropDownTradeTypeTextStyle,
|
||||||
|
underline: Container(
|
||||||
|
height: 1,
|
||||||
|
),
|
||||||
|
onChanged: (String newValue) {
|
||||||
|
onChangeTradeType(newValue, settingState.tradeType);
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
DropdownMenuItem<String>(
|
||||||
|
child: Text('Товары'),
|
||||||
|
value: SettingTradeTypeGood,
|
||||||
|
),
|
||||||
|
DropdownMenuItem<String>(
|
||||||
|
child: Text('Услуги'),
|
||||||
|
value: SettingTradeTypeService,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onChangeTradeType(String newValue, String oldValue) async {
|
||||||
|
if (oldValue != newValue) {
|
||||||
|
await Redux.store.dispatch(changeTradeTypeFromSetting(newValue));
|
||||||
|
await Redux.store.dispatch(selectBottomElement(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||||
|
|
@ -155,7 +155,7 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
||||||
_showDialog();
|
_showDialog();
|
||||||
} else {
|
} else {
|
||||||
Redux.store.dispatch(addCustomProductToKassaItems(nameController.text,
|
Redux.store.dispatch(addCustomProductToKassaItems(nameController.text,
|
||||||
int.parse(countController.text), double.parse(priceController.text)));
|
int.parse(countController.text), double.parse(priceController.text), sum));
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ class LoginView extends StatelessWidget {
|
||||||
return StoreConnector<AppState, UserState>(
|
return StoreConnector<AppState, UserState>(
|
||||||
converter: (store) => store.state.userState,
|
converter: (store) => store.state.userState,
|
||||||
builder: (context, vm) {
|
builder: (context, vm) {
|
||||||
print('build');
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
backgroundColor: fillColor,
|
backgroundColor: fillColor,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,179 @@
|
||||||
|
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/product_dao.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/models/response.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/dialog_service.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/navigator_service.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/state/calc_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
||||||
|
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
|
||||||
|
class PaymentView extends StatefulWidget {
|
||||||
|
final PaymentModel model;
|
||||||
|
|
||||||
|
const PaymentView({Key key, this.model}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PaymentViewState createState() => _PaymentViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PaymentViewState extends State<PaymentView> {
|
||||||
|
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||||
|
final DataService _dataService = locator<DataService>();
|
||||||
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
bool isBusy;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
// TODO: implement initState
|
||||||
|
super.initState();
|
||||||
|
isBusy = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return WillPopScope(
|
||||||
|
onWillPop: () {
|
||||||
|
if (!isBusy)
|
||||||
|
Navigator.pop(context);
|
||||||
|
return new Future(() => false);
|
||||||
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: whiteColor,
|
||||||
|
elevation: 0,
|
||||||
|
leading: IconButton(icon: Icon(Icons.arrow_back_ios), color: Colors.black87, onPressed: () => Navigator.pop(context),),
|
||||||
|
title: Text(dataTitle(), style: TextStyle(color: Colors.black87),),
|
||||||
|
),
|
||||||
|
body: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 12.0 ),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(dataText() , style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black26, fontSize: 15 ),),
|
||||||
|
buildStoreConnector(),
|
||||||
|
verticalSpaceLarge,
|
||||||
|
_buildBodyContent(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String dataTitle() => widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат';
|
||||||
|
|
||||||
|
String dataText() => widget.model.operationType == OperationTypePay ? 'К оплате' : 'К возврату';
|
||||||
|
|
||||||
|
StoreConnector buildStoreConnector() {
|
||||||
|
if(widget.model.mode == SettingModeCalc) {
|
||||||
|
return StoreConnector<AppState, CalcState>(
|
||||||
|
converter: (store) => store.state.calcState,
|
||||||
|
builder: (context, vm) {
|
||||||
|
return Text('${totalCalc(vm.calcItems)} тнг', style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black87,
|
||||||
|
fontSize: 35));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return StoreConnector<AppState, KassaState>(
|
||||||
|
converter: (store) => store.state.kassaState,
|
||||||
|
builder: (context, vm) {
|
||||||
|
return Text('${totalKassa(vm.kassaItems)} тнг', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black87, fontSize: 35 ));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Expanded _buildBodyContent() {
|
||||||
|
return Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Container(
|
||||||
|
height: 150,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(child: BusyButton(title: 'Оплатить картой', onPressed:() { pressPayment('card');}, mainColor: greenColor,)),
|
||||||
|
horizontalSpaceSmall,
|
||||||
|
Expanded(child: BusyButton(title: 'Наличными', onPressed:() { pressPayment('cash');}, mainColor: primaryColor,)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
verticalSpaceLarge,
|
||||||
|
Expanded(child: Container(),),
|
||||||
|
Container(child: BusyButton(title: 'Отмена', onPressed:() { Navigator.pop(context);} , mainColor: redColor,)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pressPayment(String type) async {
|
||||||
|
setState(() { isBusy = true; });
|
||||||
|
Dialogs.showLoadingDialog(context, _keyLoader);
|
||||||
|
try {
|
||||||
|
AppState _state = Redux.store.state;
|
||||||
|
String _token = _state.userState.user.token;
|
||||||
|
String _tradeType = _state.settingState.tradeType;
|
||||||
|
List<ProductDao> items = _state.kassaState.kassaItems;
|
||||||
|
Response<dynamic> response = await _dataService.sellOrReturn(token: _token, items: items, paymentType: type, operationType: widget.model.operationType, tradeType: _tradeType );
|
||||||
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
|
setState(() { isBusy = false; });
|
||||||
|
if(response.operation){
|
||||||
|
String message = response.body['message'];
|
||||||
|
String check = response.body['check'];
|
||||||
|
_navigatorService.pop();
|
||||||
|
_navigatorService.push(ImageShowRoute, arguments: ImageShowModel(check, message));
|
||||||
|
} else if(!response.operation && response.status !=500) {
|
||||||
|
_dialogService.showDialog(description: response.body['message']);
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
//Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||||
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
|
setState(() { isBusy = false; });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
String totalKassa(List<ProductDao> kassaItems) {
|
||||||
|
num total = 0.0;
|
||||||
|
kassaItems.forEach((element) {
|
||||||
|
total+= element.total == null ? 0.0 : element.total.toDouble();
|
||||||
|
});
|
||||||
|
return total.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
String totalCalc(List<CalcModel> items) {
|
||||||
|
num total = 0.0;
|
||||||
|
items.forEach((element) {
|
||||||
|
if(element.operation == Calculations.MULTIPLY) {
|
||||||
|
double num1 = element.num1 == null ? 0.0 : double.parse(element.num1);
|
||||||
|
double num2 = element.num2 == null ? 0.0 : double.parse(element.num2);
|
||||||
|
total += num1 * num2;
|
||||||
|
} else {
|
||||||
|
total+= element.num1 == null ? 0.0 : double.parse(element.num1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return total.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PaymentModel {
|
||||||
|
String operationType;
|
||||||
|
String mode;
|
||||||
|
PaymentModel({this.mode, this.operationType});
|
||||||
|
}
|
||||||
|
|
@ -34,8 +34,6 @@ class _StartUpViewState extends State<StartUpView> {
|
||||||
height: 200,
|
height: 200,
|
||||||
child: Image.asset('assets/images/icon_large.png'),
|
child: Image.asset('assets/images/icon_large.png'),
|
||||||
),
|
),
|
||||||
Text('${userState.isLoading}'),
|
|
||||||
Text('${userState.isAuthenticated}'),
|
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
valueColor: AlwaysStoppedAnimation(
|
valueColor: AlwaysStoppedAnimation(
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:aman_kassa_flutter/redux/actions/main_actions.dart';
|
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/ProductDao.dart';
|
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
|
||||||
|
|
||||||
class ProductListItem extends StatelessWidget {
|
class ProductListItem extends StatelessWidget {
|
||||||
final ProductDao item;
|
final ProductDao item;
|
||||||
|
|
@ -28,7 +28,7 @@ class ProductListItem extends StatelessWidget {
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4),
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4),
|
||||||
child: Text(
|
child: Text(
|
||||||
'${item.price?.toString()} x ${item.count?.toString()}',
|
'${item.price?.toString()} x ${item.count?.toString()} = ${item.total?.toString()}',
|
||||||
textAlign: TextAlign.right, style: productTextStyle)),
|
textAlign: TextAlign.right, style: productTextStyle)),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class CalculatorButton extends StatelessWidget {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
width: 1,
|
width: 1.2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: FlatButton(
|
child: FlatButton(
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'package:aman_kassa_flutter/core/models/calc_model.dart';
|
||||||
|
|
||||||
import 'number-formatter.dart';
|
import 'number-formatter.dart';
|
||||||
|
|
||||||
class Calculations {
|
class Calculations {
|
||||||
|
|
@ -5,7 +7,8 @@ class Calculations {
|
||||||
static const MULTIPLY = '*';
|
static const MULTIPLY = '*';
|
||||||
static const SUBTRACT = '-';
|
static const SUBTRACT = '-';
|
||||||
static const ADD = '+';
|
static const ADD = '+';
|
||||||
static const DIVIDE = '/';
|
static const NONE = 'none';
|
||||||
|
|
||||||
static const ERASE = '<<';
|
static const ERASE = '<<';
|
||||||
static const CLEAR = 'C';
|
static const CLEAR = 'C';
|
||||||
static const EQUAL = '=';
|
static const EQUAL = '=';
|
||||||
|
|
@ -13,72 +16,273 @@ class Calculations {
|
||||||
Calculations.ADD,
|
Calculations.ADD,
|
||||||
Calculations.MULTIPLY,
|
Calculations.MULTIPLY,
|
||||||
Calculations.SUBTRACT,
|
Calculations.SUBTRACT,
|
||||||
Calculations.DIVIDE,
|
|
||||||
Calculations.ERASE
|
Calculations.ERASE
|
||||||
];
|
];
|
||||||
|
|
||||||
static double add(double a, double b) => a + b;
|
static double add(double a, double b) => a + b;
|
||||||
|
|
||||||
static double subtract(double a, double b) => a - b;
|
static double subtract(double a, double b) => a - b;
|
||||||
|
|
||||||
static double divide(double a, double b) => a / b;
|
static double divide(double a, double b) => a / b;
|
||||||
|
|
||||||
static double multiply(double a, double b) => a * b;
|
static double multiply(double a, double b) => a * b;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Calculator {
|
class Calculator {
|
||||||
static String parseString(String text) {
|
static String parseItems(List<CalcModel> items, bool isEqual) {
|
||||||
List<String> numbersToAdd;
|
if (isEqual) {
|
||||||
double a, b, result;
|
return _viewResult(items);
|
||||||
if (text.contains(Calculations.ADD)) {
|
|
||||||
numbersToAdd = text.split(Calculations.ADD);
|
|
||||||
a = double.parse(numbersToAdd[0]);
|
|
||||||
b = double.parse(numbersToAdd[1]);
|
|
||||||
|
|
||||||
result = Calculations.add(a, b);
|
|
||||||
} else if (text.contains(Calculations.MULTIPLY)) {
|
|
||||||
numbersToAdd = text.split(Calculations.MULTIPLY);
|
|
||||||
a = double.parse(numbersToAdd[0]);
|
|
||||||
b = double.parse(numbersToAdd[1]);
|
|
||||||
|
|
||||||
result = Calculations.multiply(a, b);
|
|
||||||
} else if (text.contains(Calculations.DIVIDE)) {
|
|
||||||
numbersToAdd = text.split(Calculations.DIVIDE);
|
|
||||||
a = double.parse(numbersToAdd[0]);
|
|
||||||
b = double.parse(numbersToAdd[1]);
|
|
||||||
|
|
||||||
result = Calculations.divide(a, b);
|
|
||||||
} else if (text.contains(Calculations.SUBTRACT)) {
|
|
||||||
numbersToAdd = text.split(Calculations.SUBTRACT);
|
|
||||||
a = double.parse(numbersToAdd[0]);
|
|
||||||
b = double.parse(numbersToAdd[1]);
|
|
||||||
|
|
||||||
result = Calculations.subtract(a, b);
|
|
||||||
} else {
|
} else {
|
||||||
return text;
|
return _viewValues(items);
|
||||||
}
|
|
||||||
|
|
||||||
return NumberFormatter.format(result.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
static String addPeriod(String calculatorString) {
|
|
||||||
if (calculatorString.isEmpty) {
|
|
||||||
return calculatorString = '0${Calculations.PERIOD}';
|
|
||||||
}
|
|
||||||
|
|
||||||
RegExp exp = new RegExp(r"\d\.");
|
|
||||||
Iterable<Match> matches = exp.allMatches(calculatorString);
|
|
||||||
int maxMatches = Calculator.includesOperation(calculatorString) ? 2 : 1;
|
|
||||||
|
|
||||||
return matches.length == maxMatches
|
|
||||||
? calculatorString
|
|
||||||
: calculatorString += Calculations.PERIOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool includesOperation(String calculatorString) {
|
|
||||||
for (var operation in Calculations.OPERATIONS) {
|
|
||||||
if (calculatorString.contains(operation)) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
static String _viewResult(List<CalcModel> items) {
|
||||||
|
String str = '';
|
||||||
|
if (items.isNotEmpty) {
|
||||||
|
CalcModel last = items.removeLast();
|
||||||
|
if (last.operation == Calculations.NONE && last.num1 != '0') {
|
||||||
|
last.operation = Calculations.ADD;
|
||||||
|
} else if (last.operation == Calculations.MULTIPLY) {
|
||||||
|
if (last.num2 == null) {
|
||||||
|
last.num2 = '1';
|
||||||
|
last.operation = Calculations.ADD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last.closed = true;
|
||||||
|
items.add(last);
|
||||||
|
double summ = 0.0;
|
||||||
|
for (var i = 0; i < items.length; i++) {
|
||||||
|
var row = items[i];
|
||||||
|
if (row.operation == Calculations.MULTIPLY) {
|
||||||
|
str += "${row.num1} * ${row.num2}" ;
|
||||||
|
summ += double.parse(row.num1) * double.parse(row.num2);
|
||||||
|
} else {
|
||||||
|
str += row.num1;
|
||||||
|
summ += double.parse(row.num1) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.closed) {
|
||||||
|
if (i < items.length - 1) {
|
||||||
|
str += " + ";
|
||||||
|
} else {
|
||||||
|
str += " = ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str += summ.toStringAsFixed(2);
|
||||||
|
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String _viewValues(List<CalcModel> items) {
|
||||||
|
String str = '';
|
||||||
|
for (var i = 0; i < items.length; i++) {
|
||||||
|
CalcModel row = items[i];
|
||||||
|
if (row.operation == Calculations.ADD) {
|
||||||
|
str += row.num1;
|
||||||
|
} else if (row.operation == Calculations.MULTIPLY) {
|
||||||
|
if (row.num2 == null) {
|
||||||
|
str += row.num1 + " * ";
|
||||||
|
} else {
|
||||||
|
str += row.num1 + " * " + row.num2;
|
||||||
|
}
|
||||||
|
} else if (row.operation == Calculations.NONE) {
|
||||||
|
str += row.num1;
|
||||||
|
} else if (row.operation == Calculations.EQUAL) {
|
||||||
|
str += row.num1;
|
||||||
|
}
|
||||||
|
if (row.closed) {
|
||||||
|
str += " + ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CalcModel> action({String value, List<CalcModel> items}) {
|
||||||
|
switch (value) {
|
||||||
|
case Calculations.ADD:
|
||||||
|
{
|
||||||
|
items = _setPlus(value: value, items: items);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Calculations.MULTIPLY:
|
||||||
|
{
|
||||||
|
items = _setMultiply(value: value, items: items);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Calculations.ERASE:
|
||||||
|
{
|
||||||
|
items = _setBackward(value: value, items: items);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Calculations.CLEAR:
|
||||||
|
{
|
||||||
|
items = _setClean(value: value, items: items);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Calculations.PERIOD:
|
||||||
|
{
|
||||||
|
items = _setDot(value: value, items: items);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Calculations.EQUAL:
|
||||||
|
{
|
||||||
|
items = _setEqual(value: value, items: items);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
items = _setNumber(value: value, items: items);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...items];
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CalcModel> _setNumber({String value, List<CalcModel> items}) {
|
||||||
|
if (items.isEmpty) {
|
||||||
|
items.add(CalcModel(num1: value, operation: Calculations.NONE));
|
||||||
|
} else {
|
||||||
|
CalcModel last = items.removeLast();
|
||||||
|
if (last.closed) {
|
||||||
|
items.add(last);
|
||||||
|
items.add(CalcModel(num1: value, operation: Calculations.NONE));
|
||||||
|
} else {
|
||||||
|
if (value == '0' && last.num1 == '0') {
|
||||||
|
last.operation = Calculations.NONE;
|
||||||
|
items.add(last);
|
||||||
|
} else if (value == '0' && last.num1 == '0.') {
|
||||||
|
last.num1 += value;
|
||||||
|
last.operation = Calculations.NONE;
|
||||||
|
items.add(last);
|
||||||
|
} else {
|
||||||
|
if (last.operation == Calculations.NONE) {
|
||||||
|
if (last.num1 == '0' && value != '0') {
|
||||||
|
last.num1 = value;
|
||||||
|
} else {
|
||||||
|
last.num1 += value;
|
||||||
|
}
|
||||||
|
items.add(last);
|
||||||
|
} else if (last.operation == Calculations.MULTIPLY) {
|
||||||
|
if(last.num2 == null)
|
||||||
|
last.num2 = value;
|
||||||
|
else
|
||||||
|
last.num2 += value;
|
||||||
|
last.operation = Calculations.MULTIPLY;
|
||||||
|
items.add(last);
|
||||||
|
} else if (last.operation == Calculations.ADD) {
|
||||||
|
last.operation = Calculations.ADD;
|
||||||
|
items.add(last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [...items];
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CalcModel> _setPlus({String value, List<CalcModel> items}) {
|
||||||
|
if (items.isNotEmpty) {
|
||||||
|
CalcModel last = items.removeLast();
|
||||||
|
if (last.closed) {
|
||||||
|
items.add(last);
|
||||||
|
} else {
|
||||||
|
if (last.operation == Calculations.NONE) {
|
||||||
|
if (last.num1 != '0') {
|
||||||
|
last.num2 = '1';
|
||||||
|
last.operation = Calculations.ADD;
|
||||||
|
last.closed = true;
|
||||||
|
}
|
||||||
|
items.add(last);
|
||||||
|
} else if (last.operation == Calculations.MULTIPLY) {
|
||||||
|
if (last.num2 == null) {
|
||||||
|
last.num2 = '1';
|
||||||
|
last.operation = Calculations.ADD;
|
||||||
|
}
|
||||||
|
last.closed = true;
|
||||||
|
items.add(last);
|
||||||
|
} else {
|
||||||
|
last.closed = true;
|
||||||
|
items.add(last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [...items];
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CalcModel> _setDot({String value, List<CalcModel> items}) {
|
||||||
|
if (items.isNotEmpty) {
|
||||||
|
CalcModel last = items.removeLast();
|
||||||
|
if (last.operation == Calculations.NONE) {
|
||||||
|
if (last.num1?.contains('.') == false) {
|
||||||
|
last.num1 += '.';
|
||||||
|
}
|
||||||
|
last.operation = Calculations.NONE;
|
||||||
|
items.add(last);
|
||||||
|
} else if (last.operation == Calculations.ADD) {
|
||||||
|
items.add(last);
|
||||||
|
items.add(CalcModel(num1: '0.', operation: Calculations.NONE));
|
||||||
|
} else if (last.operation == Calculations.MULTIPLY) {
|
||||||
|
if (last.num2 == null) {
|
||||||
|
last.num2 += '0.';
|
||||||
|
} else {
|
||||||
|
if (last.num2?.contains('.') == false) {
|
||||||
|
last.num2 += '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last.operation = Calculations.MULTIPLY;
|
||||||
|
items.add(last);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
items.add(CalcModel(num1: '0.', operation: Calculations.NONE));
|
||||||
|
}
|
||||||
|
return [...items];
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CalcModel> _setClean({String value, List<CalcModel> items}) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CalcModel> _setEqual({String value, List<CalcModel> items}) {
|
||||||
|
if (items.isNotEmpty) {
|
||||||
|
CalcModel last = items.removeLast();
|
||||||
|
last.operation = Calculations.EQUAL;
|
||||||
|
items.add(last);
|
||||||
|
}
|
||||||
|
return [...items];
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CalcModel> _setMultiply({String value, List<CalcModel> items}) {
|
||||||
|
if (items.isNotEmpty) {
|
||||||
|
CalcModel last = items.removeLast();
|
||||||
|
if (last.closed) {
|
||||||
|
items.add(last);
|
||||||
|
} else {
|
||||||
|
if (last.operation == Calculations.NONE) {
|
||||||
|
if (last.num1 != '0') {
|
||||||
|
last.operation = Calculations.MULTIPLY;
|
||||||
|
last.num2 = null;
|
||||||
|
}
|
||||||
|
items.add(last);
|
||||||
|
} else if (last.operation == Calculations.MULTIPLY) {
|
||||||
|
if (last.num2 != '0') {
|
||||||
|
last.closed = true;
|
||||||
|
}
|
||||||
|
items.add(last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [...items];
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CalcModel> _setBackward({String value, List<CalcModel> items}) {
|
||||||
|
if (items.isNotEmpty) {
|
||||||
|
CalcModel last = items.removeLast();
|
||||||
|
}
|
||||||
|
return [...items];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class NumberDisplay extends StatelessWidget {
|
class NumberDisplay extends StatelessWidget {
|
||||||
|
|
@ -5,18 +7,44 @@ class NumberDisplay extends StatelessWidget {
|
||||||
|
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
|
GlobalKey stickyKey = GlobalKey();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Expanded(
|
||||||
padding: EdgeInsets.all(20),
|
child: Padding(
|
||||||
child: Row(
|
padding: const EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0 ),
|
||||||
children: <Widget>[
|
child: Container(
|
||||||
Text(
|
key: stickyKey,
|
||||||
value,
|
alignment: Alignment.topLeft,
|
||||||
style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
|
child: AnimatedDefaultTextStyle(
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: fontSizeCalc(value: value),
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
],
|
child: Text(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
value,
|
||||||
));
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
double fontSizeCalc({ String value = " " }) {
|
||||||
|
const double result = 40.0;
|
||||||
|
try {
|
||||||
|
const double global = 100000.0;
|
||||||
|
double scale = (global / value.length);
|
||||||
|
final pixelOfLetter = sqrt(scale);
|
||||||
|
final pixelOfLetterP = pixelOfLetter - (pixelOfLetter * 5) / 100;
|
||||||
|
if(pixelOfLetterP> result){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return pixelOfLetterP;
|
||||||
|
} catch(e) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@ import 'package:aman_kassa_flutter/core/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/dialog_models.dart';
|
import 'package:aman_kassa_flutter/core/models/dialog_models.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class DialogManager extends StatefulWidget {
|
class DialogManager extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
DialogManager({Key key, this.child}) : super(key: key);
|
DialogManager({Key key, this.child}) : super(key: key);
|
||||||
|
|
||||||
_DialogManagerState createState() => _DialogManagerState();
|
_DialogManagerState createState() => _DialogManagerState();
|
||||||
|
|
@ -12,11 +14,19 @@ class DialogManager extends StatefulWidget {
|
||||||
|
|
||||||
class _DialogManagerState extends State<DialogManager> {
|
class _DialogManagerState extends State<DialogManager> {
|
||||||
DialogService _dialogService = locator<DialogService>();
|
DialogService _dialogService = locator<DialogService>();
|
||||||
|
TextEditingController controller;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_dialogService.registerDialogListener(_showDialog);
|
controller = new TextEditingController();
|
||||||
|
_dialogService.registerDialogListener(_showDialog, _showDialogInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
controller.dispose();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -50,4 +60,44 @@ class _DialogManagerState extends State<DialogManager> {
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showDialogInput(DialogRequest request) {
|
||||||
|
var isConfirmationDialog = request.cancelTitle != null;
|
||||||
|
controller.clear();
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: Text(request.title),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(request.description),
|
||||||
|
TextField(
|
||||||
|
controller: controller,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: <TextInputFormatter>[
|
||||||
|
WhitelistingTextInputFormatter(RegExp("^[0-9.]*")),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
if (isConfirmationDialog)
|
||||||
|
FlatButton(
|
||||||
|
child: Text(request.cancelTitle),
|
||||||
|
onPressed: () {
|
||||||
|
_dialogService
|
||||||
|
.dialogComplete(DialogResponse(confirmed: false));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FlatButton(
|
||||||
|
child: Text(request.buttonTitle),
|
||||||
|
onPressed: () {
|
||||||
|
_dialogService
|
||||||
|
.dialogComplete(DialogResponse(confirmed: true, responseText: controller.text));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// A button that shows a busy indicator in place of title
|
||||||
|
class AmanIconButton extends StatefulWidget {
|
||||||
|
final bool busy;
|
||||||
|
final String title;
|
||||||
|
final Function onPressed;
|
||||||
|
final bool enabled;
|
||||||
|
final Color mainColor;
|
||||||
|
final IconData icon;
|
||||||
|
const AmanIconButton(
|
||||||
|
{
|
||||||
|
@required this.title,
|
||||||
|
this.busy = false,
|
||||||
|
@required this.onPressed,
|
||||||
|
this.enabled = true,
|
||||||
|
this.mainColor,
|
||||||
|
@required this.icon
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AmanIconButtonState createState() => _AmanIconButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AmanIconButtonState extends State<AmanIconButton> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
child: InkWell(
|
||||||
|
|
||||||
|
onTap: widget.busy ? () {} : widget.onPressed,
|
||||||
|
child: Container(
|
||||||
|
//height: 75,
|
||||||
|
width: 120,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 25,
|
||||||
|
vertical: 15),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
//color: widget.enabled ? ( whiteColor ) : blueColorLigth,
|
||||||
|
borderRadius: BorderRadius.circular(50),
|
||||||
|
//boxShadow: [buttonShadowBox],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
(!widget.busy
|
||||||
|
? Icon(
|
||||||
|
widget.icon,
|
||||||
|
color: widget.mainColor,
|
||||||
|
size: 36,
|
||||||
|
)
|
||||||
|
: CircularProgressIndicator(
|
||||||
|
strokeWidth: 3,
|
||||||
|
valueColor: AlwaysStoppedAnimation<Color>(widget.mainColor))),
|
||||||
|
Text(widget.title, style: TextStyle(color: widget.mainColor, fontSize: 15, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center,)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
|
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
|
|
||||||
|
/// A button that shows a busy indicator in place of title
|
||||||
|
class AmanIconButtonHorizontal extends StatefulWidget {
|
||||||
|
final String title;
|
||||||
|
final Function onPressed;
|
||||||
|
final Color activeColor;
|
||||||
|
final Color inactiveColor;
|
||||||
|
final bool selected;
|
||||||
|
final IconData icon;
|
||||||
|
const AmanIconButtonHorizontal(
|
||||||
|
{
|
||||||
|
@required this.title,
|
||||||
|
this.onPressed,
|
||||||
|
this.activeColor = primaryColor,
|
||||||
|
this.inactiveColor = Colors.black26,
|
||||||
|
this.selected = false,
|
||||||
|
@required this.icon
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AmanIconButtonHorizontalState createState() => _AmanIconButtonHorizontalState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AmanIconButtonHorizontalState extends State<AmanIconButtonHorizontal> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: widget.onPressed,
|
||||||
|
child: Row( mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ Icon(widget.icon , color: widget.selected ? widget.activeColor : widget.inactiveColor ), Text(widget.title, style: TextStyle( color: widget.selected ? widget.activeColor : widget.inactiveColor, fontWeight: FontWeight.w800 ) )],),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,22 +25,27 @@ class BusyButton extends StatefulWidget {
|
||||||
class _BusyButtonState extends State<BusyButton> {
|
class _BusyButtonState extends State<BusyButton> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return AnimatedContainer(
|
||||||
onTap: widget.onPressed,
|
|
||||||
child: InkWell(
|
|
||||||
child: AnimatedContainer(
|
|
||||||
height: widget.busy ? 40 : null,
|
|
||||||
width: widget.busy ? 40 : null,
|
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
alignment: Alignment.center,
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: widget.busy ? 10 : 25,
|
|
||||||
vertical: widget.busy ? 10 : 15),
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: widget.enabled ? ( widget.mainColor ?? primaryColor) : blueColorLigth,
|
color: widget.enabled ? ( widget.mainColor ?? primaryColor) : blueColorLigth,
|
||||||
borderRadius: BorderRadius.circular(7),
|
borderRadius: BorderRadius.circular(7),
|
||||||
boxShadow: [mainShadowBox]
|
boxShadow: [
|
||||||
|
cardShadowBox
|
||||||
|
]
|
||||||
),
|
),
|
||||||
|
child: Material(
|
||||||
|
type: MaterialType.transparency,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: widget.busy ? () {} : widget.onPressed,
|
||||||
|
child: AnimatedContainer(
|
||||||
|
height: widget.busy ? 40 : 40,
|
||||||
|
//width: widget.busy ? 40 : 40,
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
margin: EdgeInsets.symmetric(
|
||||||
|
horizontal: widget.busy ? 10 : 25,
|
||||||
|
vertical: widget.busy ? 10 : 15),
|
||||||
child: !widget.busy
|
child: !widget.busy
|
||||||
? Text(
|
? Text(
|
||||||
widget.title,
|
widget.title,
|
||||||
|
|
@ -51,6 +56,7 @@ class _BusyButtonState extends State<BusyButton> {
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white)),
|
valueColor: AlwaysStoppedAnimation<Color>(Colors.white)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class Dialogs {
|
class Dialogs {
|
||||||
|
|
@ -17,7 +18,7 @@ class Dialogs {
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
CircularProgressIndicator(),
|
CircularProgressIndicator(),
|
||||||
SizedBox(height: 10,),
|
SizedBox(height: 10,),
|
||||||
Text("Please Wait....",style: TextStyle(color: Colors.blueAccent),)
|
Text("Подождите выполняеться операция с сервером", textAlign: TextAlign.center, style: TextStyle(color: Colors.grey.shade300, fontWeight: FontWeight.bold, fontSize: 15),)
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
]));
|
]));
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.12"
|
version: "2.1.12"
|
||||||
|
intl:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.16.1"
|
||||||
logger:
|
logger:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ dependencies:
|
||||||
flutter_boom_menu: ^1.0.2
|
flutter_boom_menu: ^1.0.2
|
||||||
sliding_up_panel: ^1.0.2
|
sliding_up_panel: ^1.0.2
|
||||||
material_design_icons_flutter: ^4.0.5345
|
material_design_icons_flutter: ^4.0.5345
|
||||||
|
intl: ^0.16.1
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue