group_list
parent
9486186973
commit
17f730eebd
|
|
@ -15,6 +15,7 @@ class AuthResponse {
|
|||
int? kassaId;
|
||||
String? token;
|
||||
String? authAt;
|
||||
String? username;
|
||||
int? shard;
|
||||
String? message;
|
||||
bool? operation;
|
||||
|
|
@ -29,6 +30,7 @@ class AuthResponse {
|
|||
authResponseBean.shard = cast<int>(map['shard']);
|
||||
authResponseBean.message = cast<String>(map['message']);
|
||||
authResponseBean.operation = map['operation'] as bool;
|
||||
authResponseBean.username = cast<String>(map['username']);
|
||||
return authResponseBean;
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +44,7 @@ class AuthResponse {
|
|||
'shard': shard,
|
||||
'message': message,
|
||||
'operation': operation,
|
||||
'username' : username
|
||||
};
|
||||
return map;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import 'package:satu/core/utils/utils_parse.dart';
|
||||
|
||||
class TransactionDao {
|
||||
TransactionDao();
|
||||
|
||||
int? id;
|
||||
double total = 0;
|
||||
String contragentName = '';
|
||||
String? number;
|
||||
String? date;
|
||||
String? day;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:redux_thunk/redux_thunk.dart';
|
||||
import 'package:satu/core/entity/category_entity.dart';
|
||||
import 'package:satu/core/entity/goods_entity.dart';
|
||||
import 'package:satu/core/entity/transaction_entity.dart';
|
||||
import 'package:satu/core/entity/transaction_rec_entity.dart';
|
||||
import 'package:satu/core/models/entity_data/transaction_data.dart';
|
||||
import 'package:satu/core/models/flow/dao/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/dao/transaction_dao.dart';
|
||||
import 'package:satu/core/models/flow/transaction_state.dart';
|
||||
import 'package:satu/core/redux/state/journal_state.dart';
|
||||
import 'package:satu/core/redux/state/sell_state.dart';
|
||||
import 'package:satu/core/services/db_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
import 'package:satu/core/utils/logger.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../store.dart';
|
||||
|
||||
@immutable
|
||||
class SetJournalStateAction {
|
||||
const SetJournalStateAction(this.journalState);
|
||||
|
||||
final JournalState journalState;
|
||||
}
|
||||
|
||||
final Logger log = getLogger('SetJournalStateAction');
|
||||
|
||||
final DbService _dbService = locator<DbService>();
|
||||
|
||||
ThunkAction<AppState> navigateTab(int index) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetJournalStateAction(JournalState(tabIndex: index)));
|
||||
loadJournalData(store);
|
||||
};
|
||||
}
|
||||
|
||||
Future<void> loadJournalData(Store<AppState> store) async {
|
||||
try {
|
||||
log.i('loadJournalData');
|
||||
final int? appCompanyId = store.state.userState!.auth!.companyId;
|
||||
final int tabIndex = store.state.journalState?.tabIndex ?? 0;
|
||||
final List<Map<String, dynamic>> set = await _dbService.queryRowsWithWhere(
|
||||
transactionTableName,
|
||||
'$transactionColumnAppCompanyId = ?'
|
||||
' and $transactionColumnStatus = ?'
|
||||
' and $transactionColumnType = ?',
|
||||
[appCompanyId, transactionStatusFinish, transactionTypeSell],
|
||||
orderBy: '$transactionColumnCreatedAt desc');
|
||||
log.i(set.length);
|
||||
final List<TransactionDao> list = [];
|
||||
for (final Map<String, dynamic> map in set) {
|
||||
final Transaction transaction = Transaction.fromMap(map);
|
||||
final TransactionData data = TransactionData.fromMap(
|
||||
jsonDecode(transaction.data!));
|
||||
TransactionDao dao = TransactionDao();
|
||||
dao.day = transaction.id.toString();
|
||||
dao.id = transaction.id;
|
||||
dao.contragentName = data.contragentName;
|
||||
list.add(dao);
|
||||
}
|
||||
store.dispatch(SetJournalStateAction(JournalState(
|
||||
items: list,
|
||||
)));
|
||||
} catch (e, stack)
|
||||
{
|
||||
log.e('loadSellData', e, stack);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import 'package:satu/core/entity/goods_entity.dart';
|
|||
import 'package:satu/core/entity/transaction_entity.dart';
|
||||
import 'package:satu/core/entity/transaction_rec_entity.dart';
|
||||
import 'package:satu/core/models/entity_data/transaction_data.dart';
|
||||
import 'package:satu/core/models/flow/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/dao/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/transaction_state.dart';
|
||||
import 'package:satu/core/redux/state/sell_state.dart';
|
||||
import 'package:satu/core/services/db_service.dart';
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import '../store.dart';
|
|||
@immutable
|
||||
class SetUserStateAction {
|
||||
final UserState userState;
|
||||
|
||||
SetUserStateAction(this.userState);
|
||||
}
|
||||
|
||||
|
|
@ -23,19 +24,20 @@ final DialogService _dialogService = locator<DialogService>();
|
|||
|
||||
final DictionaryService _dictionaryService = locator<DictionaryService>();
|
||||
|
||||
|
||||
ThunkAction<AppState> authenticate(String email, String password) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
||||
try {
|
||||
AuthResponse result = await _api.login(email, password);
|
||||
if ( result.operation!) {
|
||||
final AuthResponse result = await _api.login(email, password);
|
||||
if (result.operation!) {
|
||||
_api.token = result.token!;
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: false, auth: result)));
|
||||
store.dispatch(
|
||||
SetUserStateAction(UserState(isLoading: false, auth: result)));
|
||||
_navigation.replace(mainViewRoute);
|
||||
_afterAuth(store);
|
||||
} else {
|
||||
_dialogService.showDialog(title: 'Внимание', buttonTitle: 'Ok', description: result.message!);
|
||||
_dialogService.showDialog(
|
||||
title: 'Внимание', buttonTitle: 'Ok', description: result.message!);
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
|
|
@ -50,13 +52,15 @@ ThunkAction<AppState> authenticateByToken(String token) {
|
|||
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
||||
try {
|
||||
AuthResponse result = await _api.authorization(token);
|
||||
if ( result.operation!) {
|
||||
if (result.operation!) {
|
||||
_api.token = result.token!;
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: false, auth: result)));
|
||||
store.dispatch(
|
||||
SetUserStateAction(UserState(isLoading: false, auth: result)));
|
||||
_navigation.replace(mainViewRoute);
|
||||
_afterAuth(store);
|
||||
} else {
|
||||
_dialogService.showDialog(title: 'Внимание', buttonTitle: 'Ok', description: result.message!);
|
||||
_dialogService.showDialog(
|
||||
title: 'Внимание', buttonTitle: 'Ok', description: result.message!);
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
|
|
@ -69,8 +73,8 @@ ThunkAction<AppState> authenticateByToken(String token) {
|
|||
Future<void> auth(Store<AppState> store) async {
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
||||
try {
|
||||
UserState? state = store.state.userState;
|
||||
if(state != null) {
|
||||
UserState? state = store.state.userState;
|
||||
if (state != null) {
|
||||
if (state.auth?.operation == false) {
|
||||
_navigation.replace(loginViewRoute);
|
||||
} else {
|
||||
|
|
@ -99,10 +103,12 @@ Future<void> logout(Store<AppState> store) async {
|
|||
AuthResponse result = await _api.logout();
|
||||
if (result.operation!) {
|
||||
_api.token = null;
|
||||
store.dispatch(SetUserStateAction(UserState(isLoading: false, auth: AuthResponse())));
|
||||
store.dispatch(SetUserStateAction(
|
||||
UserState(isLoading: false, auth: AuthResponse())));
|
||||
_navigation.replace(loginViewRoute);
|
||||
} else {
|
||||
_dialogService.showDialog(title: 'Внимание', buttonTitle: 'Ok', description: result.message!);
|
||||
_dialogService.showDialog(
|
||||
title: 'Внимание', buttonTitle: 'Ok', description: result.message!);
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
|
|
@ -114,4 +120,3 @@ Future<void> logout(Store<AppState> store) async {
|
|||
Future<void> _afterAuth(Store<AppState> store) async {
|
||||
await _dictionaryService.refreshFull();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import 'package:satu/core/redux/actions/journal_actions.dart';
|
||||
import 'package:satu/core/redux/actions/sell_actions.dart';
|
||||
import 'package:satu/core/redux/actions/user_actions.dart';
|
||||
import 'package:satu/core/redux/state/journal_state.dart';
|
||||
import 'package:satu/core/redux/state/sell_state.dart';
|
||||
import 'package:satu/core/redux/state/user_state.dart';
|
||||
|
||||
JournalState journalReducer(
|
||||
JournalState prevState, SetJournalStateAction action) {
|
||||
final JournalState payload = action.journalState;
|
||||
return prevState.copyWith(items: payload.items, tabIndex: payload.tabIndex);
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:meta/meta.dart';
|
||||
import 'package:satu/core/models/flow/dao/transaction_dao.dart';
|
||||
|
||||
|
||||
@immutable
|
||||
class JournalState {
|
||||
const JournalState({this.items, this.tabIndex});
|
||||
|
||||
factory JournalState.initial() => const JournalState(items: [], tabIndex: 0);
|
||||
|
||||
final List<TransactionDao>? items;
|
||||
final int? tabIndex;
|
||||
|
||||
JournalState copyWith({List<TransactionDao>? items, int? tabIndex}) {
|
||||
return JournalState(
|
||||
items: items ?? this.items, tabIndex: tabIndex ?? this.tabIndex);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:meta/meta.dart';
|
||||
import 'package:satu/core/models/auth/auth_response.dart';
|
||||
import 'package:satu/core/models/flow/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/dao/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/transaction_state.dart';
|
||||
|
||||
@immutable
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:redux_persist_flutter/redux_persist_flutter.dart';
|
||||
import 'package:redux_thunk/redux_thunk.dart';
|
||||
import 'package:redux_persist/redux_persist.dart';
|
||||
import 'package:satu/core/redux/actions/journal_actions.dart';
|
||||
import 'package:satu/core/redux/actions/nav_actions.dart';
|
||||
import 'package:satu/core/redux/actions/sell_actions.dart';
|
||||
import 'package:satu/core/redux/reducers/journal_reducer.dart';
|
||||
import 'package:satu/core/redux/reducers/nav_reducer.dart';
|
||||
import 'package:satu/core/redux/reducers/sell_reducer.dart';
|
||||
import 'package:satu/core/redux/reducers/user_reducer.dart';
|
||||
import 'package:satu/core/redux/state/journal_state.dart';
|
||||
import 'package:satu/core/redux/state/nav_state.dart';
|
||||
import 'package:satu/core/redux/state/sell_state.dart';
|
||||
import 'package:satu/core/redux/state/user_state.dart';
|
||||
|
||||
import 'actions/user_actions.dart';
|
||||
|
||||
|
||||
//reducer context
|
||||
AppState appReducer(AppState state, dynamic action) {
|
||||
if (action is SetUserStateAction) {
|
||||
|
|
@ -26,10 +27,14 @@ AppState appReducer(AppState state, dynamic action) {
|
|||
/** NavAction **/
|
||||
final NavState nextState = navReducer(state.navState!, action);
|
||||
return state.copyWith(navState: nextState);
|
||||
} else if (action is SetSellStateAction) {
|
||||
} else if (action is SetSellStateAction) {
|
||||
/** NavAction **/
|
||||
final SellState nextState = sellReducer(state.sellState!, action);
|
||||
return state.copyWith(sellState: nextState);
|
||||
} else if (action is SetJournalStateAction) {
|
||||
/** NavAction **/
|
||||
final JournalState nextState = journalReducer(state.journalState!, action);
|
||||
return state.copyWith(journalState: nextState);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
|
@ -37,41 +42,44 @@ AppState appReducer(AppState state, dynamic action) {
|
|||
//Main State
|
||||
@immutable
|
||||
class AppState {
|
||||
final UserState? userState;
|
||||
final NavState? navState;
|
||||
final SellState? sellState;
|
||||
|
||||
|
||||
const AppState({
|
||||
this.userState,
|
||||
this.navState,
|
||||
this.sellState
|
||||
this.sellState,
|
||||
this.journalState,
|
||||
});
|
||||
|
||||
final UserState? userState;
|
||||
final NavState? navState;
|
||||
final SellState? sellState;
|
||||
final JournalState? journalState;
|
||||
|
||||
//stable work
|
||||
AppState copyWith({
|
||||
UserState? userState,
|
||||
NavState? navState,
|
||||
SellState? sellState,
|
||||
JournalState? journalState,
|
||||
}) {
|
||||
return AppState(
|
||||
userState: userState ?? this.userState,
|
||||
navState: navState ?? this.navState,
|
||||
sellState: sellState ?? this.sellState
|
||||
sellState: sellState ?? this.sellState,
|
||||
journalState: journalState ?? this.journalState,
|
||||
);
|
||||
}
|
||||
|
||||
static AppState? fromJson(dynamic json){
|
||||
return json !=null
|
||||
static AppState? fromJson(dynamic json) {
|
||||
return json != null
|
||||
? AppState(
|
||||
userState: UserState.fromJson(json['userState']),
|
||||
)
|
||||
userState: UserState.fromJson(json['userState']),
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
dynamic toJson() {
|
||||
return {
|
||||
"userState" : userState!.toJson(),
|
||||
'userState': userState!.toJson(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -81,33 +89,37 @@ class Redux {
|
|||
|
||||
static Store<AppState>? get store {
|
||||
if (_store == null) {
|
||||
throw Exception("store is not initialized");
|
||||
throw Exception('store is not initialized');
|
||||
} else {
|
||||
return _store;
|
||||
}
|
||||
}
|
||||
|
||||
//blank function just for lint context
|
||||
Future<void> blank() async {}
|
||||
|
||||
//initial context
|
||||
static Future<void> init() async {
|
||||
// Create Persistor
|
||||
final persist = Persistor<AppState>(
|
||||
storage: FlutterStorage(), // Or use other engines
|
||||
serializer: JsonSerializer<AppState>(AppState.fromJson), // Or use other serializers
|
||||
serializer: JsonSerializer<AppState>(
|
||||
AppState.fromJson), // Or use other serializers
|
||||
);
|
||||
|
||||
final AppState? initialState = await persist.load();
|
||||
final userStateInitial = UserState.initial(initialState?.userState);
|
||||
final navStateInitial = NavState.initial();
|
||||
final sellStateInitial = SellState.initial();
|
||||
final journalStateInitial = JournalState.initial();
|
||||
|
||||
_store = Store<AppState>(
|
||||
appReducer,
|
||||
middleware: [thunkMiddleware, persist.createMiddleware() ],
|
||||
initialState: AppState(
|
||||
_store = Store<AppState>(appReducer,
|
||||
middleware: [thunkMiddleware, persist.createMiddleware()],
|
||||
initialState: AppState(
|
||||
userState: userStateInitial,
|
||||
navState: navStateInitial,
|
||||
sellState: sellStateInitial,
|
||||
)
|
||||
);
|
||||
journalState: journalStateInitial,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import 'package:satu/core/entity/transaction_entity.dart';
|
|||
import 'package:satu/core/models/entity_data/transaction_data.dart';
|
||||
import 'package:satu/core/models/flow/items_bean.dart';
|
||||
import 'package:satu/core/models/flow/operator_bean.dart';
|
||||
import 'package:satu/core/models/flow/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/dao/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/sell_request.dart';
|
||||
import 'package:satu/core/models/flow/sell_response.dart';
|
||||
import 'package:satu/core/models/flow/transaction_state.dart';
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:satu/core/services/api_service.dart';
|
|||
import 'package:satu/core/services/navigator_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
import 'package:satu/routes/route_names.dart';
|
||||
import 'package:satu/shared/app_colors.dart';
|
||||
|
||||
|
||||
class StartUpView extends StatefulWidget {
|
||||
|
|
@ -33,6 +34,7 @@ class _StartUpViewState extends State<StartUpView> {
|
|||
converter: (store) => store.state.userState!,
|
||||
builder: (context, userState) {
|
||||
return Scaffold(
|
||||
backgroundColor: whiteColor,
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
|
|
|||
|
|
@ -1,219 +1,115 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:grouped_list/grouped_list.dart';
|
||||
import 'package:satu/core/models/flow/dao/transaction_dao.dart';
|
||||
import 'package:satu/core/redux/actions/journal_actions.dart';
|
||||
import 'package:satu/core/redux/state/journal_state.dart';
|
||||
import 'package:satu/core/redux/store.dart';
|
||||
import 'package:satu/shared/app_colors.dart';
|
||||
import 'package:satu/widgets/bar/products_app_bar.dart';
|
||||
import 'package:satu/widgets/buttons/option_pill.dart';
|
||||
import 'component/transaction_item.dart';
|
||||
|
||||
|
||||
class JournalView extends StatefulWidget {
|
||||
@override
|
||||
_JournalViewState createState() => _JournalViewState();
|
||||
}
|
||||
|
||||
class _JournalViewState extends State<JournalView> {
|
||||
|
||||
int tabIndex = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
Redux.store!.dispatch(loadJournalData);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: ProductsAppBar(title: 'Журнал транзакции',),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
OptionPill(
|
||||
text: 'Все',
|
||||
selected: tabIndex == 0,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
tabIndex = 0;
|
||||
});
|
||||
},
|
||||
appBar: const ProductsAppBar(
|
||||
title: 'Журнал транзакции',
|
||||
),
|
||||
body: StoreConnector<AppState, JournalState>(
|
||||
converter: (store) => store.state.journalState!,
|
||||
builder: (context, snapshot) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
OptionPill(
|
||||
text: 'Все',
|
||||
selected: snapshot.tabIndex == 0,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
tabIndex = 0;
|
||||
});
|
||||
},
|
||||
),
|
||||
OptionPill(
|
||||
text: 'Приход',
|
||||
selected: snapshot.tabIndex == 1,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
tabIndex = 1;
|
||||
});
|
||||
},
|
||||
),
|
||||
OptionPill(
|
||||
text: 'Расход',
|
||||
selected: snapshot.tabIndex == 2,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
tabIndex = 2;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
OptionPill(
|
||||
text: 'Приход',
|
||||
selected: tabIndex == 1,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
tabIndex = 1;
|
||||
});
|
||||
},
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
|
||||
OptionPill(
|
||||
text: 'Расход',
|
||||
selected: tabIndex == 2,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
tabIndex = 2;
|
||||
});
|
||||
},
|
||||
Expanded(
|
||||
child: GroupedListView<TransactionDao, String>(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
elements: snapshot.items!,
|
||||
groupBy: (element) => element.day!,
|
||||
groupSeparatorBuilder: (String groupByValue) => Text(
|
||||
groupByValue,
|
||||
style: const TextStyle(
|
||||
color: textColor,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
itemBuilder: (context, TransactionDao element) =>
|
||||
TransactionItem(
|
||||
fullName: 'Чек № ${element.number} 13:03:05',
|
||||
status: element.contragentName,
|
||||
amount: element.total.toString(),
|
||||
received: true,
|
||||
),
|
||||
itemComparator: (item1, item2) =>
|
||||
item1.day!.compareTo(item2.day!),
|
||||
// optional
|
||||
useStickyGroupSeparators: true,
|
||||
// optional
|
||||
floatingHeader: true,
|
||||
// optional
|
||||
order: GroupedListOrder.DESC, // optional
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
physics: BouncingScrollPhysics(),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
|
||||
Text(
|
||||
'03/06/2020',
|
||||
style: TextStyle(
|
||||
//color: kGreyColor,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 52021 13:03:05',
|
||||
status: 'Частное лицо',
|
||||
amount: '2706.00',
|
||||
received: true,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 52020 13:01:05',
|
||||
status: 'ИП Иванов В.И.',
|
||||
amount: '19000.63',
|
||||
received: false,
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
|
||||
Divider(
|
||||
//color: kPrimaryColor,
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 32,
|
||||
),
|
||||
|
||||
Text(
|
||||
'02/06/2020',
|
||||
style: TextStyle(
|
||||
//color: kGreyColor,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 5019 13:03:05',
|
||||
status: 'Частное лицо',
|
||||
amount: '114.00',
|
||||
received: true,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 5019 13:03:05',
|
||||
status: 'Частное лицо',
|
||||
amount: '70.16',
|
||||
received: true,
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
|
||||
Text(
|
||||
'29/05/2020',
|
||||
style: TextStyle(
|
||||
//color: kGreyColor,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 5019 13:03:05',
|
||||
status: 'Частное лицо',
|
||||
amount: '44.50',
|
||||
received: true,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 5019 13:03:05',
|
||||
status: 'ТОО Рога и копыта',
|
||||
amount: '85.50',
|
||||
received: false,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 5019 13:03:05',
|
||||
status: 'Частное лицо',
|
||||
amount: '155.00',
|
||||
received: true,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 5019 13:03:05',
|
||||
status: 'Частное лицо',
|
||||
amount: '23.50',
|
||||
received: true,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 5019 13:03:05',
|
||||
status: 'Частное лицо',
|
||||
amount: '11.50',
|
||||
received: true,
|
||||
),
|
||||
|
||||
TransactionItem(
|
||||
fullName: 'Чек № 5019 13:03:05',
|
||||
status: 'Частное лицо',
|
||||
amount: '36.00',
|
||||
received: true,
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import 'package:flutter_redux/flutter_redux.dart';
|
|||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:redux/src/store.dart';
|
||||
import 'package:satu/core/entity/goods_entity.dart';
|
||||
import 'package:satu/core/models/flow/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/dao/product_dao.dart';
|
||||
import 'package:satu/core/redux/actions/sell_actions.dart';
|
||||
import 'package:satu/core/redux/state/sell_state.dart';
|
||||
import 'package:satu/core/redux/store.dart';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:satu/core/models/flow/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/dao/product_dao.dart';
|
||||
|
||||
double sumProducts(List<ProductDao> list) {
|
||||
double result = 0.0;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class BottomBar extends StatelessWidget {
|
|||
active: selectedIndex == 1,
|
||||
onTap: () => onTap(1),
|
||||
svgFile: 'buy',
|
||||
disable: true,
|
||||
),
|
||||
BottomButton(
|
||||
active: selectedIndex == 2,
|
||||
|
|
@ -43,16 +44,18 @@ class BottomBar extends StatelessWidget {
|
|||
}
|
||||
|
||||
class BottomButton extends StatelessWidget {
|
||||
const BottomButton({
|
||||
required this.svgFile,
|
||||
required this.onTap,
|
||||
required this.active,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
const BottomButton(
|
||||
{required this.svgFile,
|
||||
required this.onTap,
|
||||
required this.active,
|
||||
Key? key,
|
||||
this.disable = false})
|
||||
: super(key: key);
|
||||
|
||||
final String svgFile;
|
||||
final void Function() onTap;
|
||||
final bool active;
|
||||
final bool disable;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -73,14 +76,18 @@ class BottomButton extends StatelessWidget {
|
|||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
onTap: disable == true ? (){} : onTap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SvgPicture.asset(
|
||||
'assets/images/svg/$svgFile.svg',
|
||||
height: 30,
|
||||
width: 30,
|
||||
color: active ? primaryColor : placeholderColor,
|
||||
color: disable
|
||||
? disableColor
|
||||
: active
|
||||
? primaryColor
|
||||
: placeholderColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:satu/core/redux/actions/nav_actions.dart';
|
||||
import 'package:satu/core/redux/actions/user_actions.dart';
|
||||
import 'package:satu/core/redux/state/user_state.dart';
|
||||
import 'package:satu/core/redux/store.dart';
|
||||
|
||||
import 'package:satu/shared/app_colors.dart';
|
||||
|
|
@ -31,7 +33,9 @@ class AppDrawer extends StatelessWidget {
|
|||
Redux.store!.dispatch(navigateDrawer(WorkView));
|
||||
}),
|
||||
_createDrawerItem(
|
||||
svgFile: 'inventarization', text: 'Инвентаризация'),
|
||||
svgFile: 'inventarization',
|
||||
text: 'Инвентаризация',
|
||||
disable: true),
|
||||
_createDrawerSectionTitle(text: 'СПРАВОЧНИКИ'),
|
||||
_createDrawerItem(
|
||||
svgFile: 'categories',
|
||||
|
|
@ -47,13 +51,18 @@ class AppDrawer extends StatelessWidget {
|
|||
Navigator.of(context).pop();
|
||||
Redux.store!.dispatch(navigateDrawer(GoodsDictionaryView));
|
||||
}),
|
||||
_createDrawerItem(svgFile: 'contragents', text: 'Контрагенты'),
|
||||
_createDrawerItem(
|
||||
svgFile: 'contragents', text: 'Контрагенты', disable: true),
|
||||
_createDrawerSectionTitle(text: 'ИНФОРМАЦИЯ'),
|
||||
_createDrawerItem(svgFile: 'question', text: 'Справочник'),
|
||||
_createDrawerItem(
|
||||
svgFile: 'question', text: 'Справочник', disable: true),
|
||||
_createDrawerSectionTitle(text: 'ПРОЧЕЕ'),
|
||||
_createDrawerItem(svgFile: 'settings', text: 'Настройки'),
|
||||
_createDrawerItem(svgFile: 'global', text: 'Перейти на сайт'),
|
||||
_createDrawerItem(svgFile: 'bug', text: 'Сообщить об ошибке'),
|
||||
_createDrawerItem(
|
||||
svgFile: 'settings', text: 'Настройки', disable: true),
|
||||
_createDrawerItem(
|
||||
svgFile: 'global', text: 'Перейти на сайт', disable: true),
|
||||
_createDrawerItem(
|
||||
svgFile: 'bug', text: 'Сообщить об ошибке', disable: true),
|
||||
_createDrawerItem(
|
||||
svgFile: 'logout',
|
||||
text: 'Выйти из аккаунта',
|
||||
|
|
@ -95,13 +104,18 @@ class AppDrawer extends StatelessWidget {
|
|||
'assets/images/drawer/user.png')))),
|
||||
),
|
||||
horizontalSpaceSmall,
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: const [
|
||||
Text('Хайруллин Тимур',
|
||||
style: TextStyle(fontSize: 16.0)),
|
||||
Text('Продавец', style: TextStyle(fontSize: 12)),
|
||||
],
|
||||
StoreConnector<AppState, UserState>(
|
||||
converter: (store) => store.state.userState!,
|
||||
builder: (context, snapshot) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(snapshot.auth?.username ?? '',
|
||||
style: TextStyle(fontSize: 16.0)),
|
||||
Text('Продавец', style: TextStyle(fontSize: 12)),
|
||||
],
|
||||
);
|
||||
}
|
||||
),
|
||||
],
|
||||
)),
|
||||
|
|
@ -114,7 +128,8 @@ class AppDrawer extends StatelessWidget {
|
|||
IconData? icon,
|
||||
String? svgFile,
|
||||
GestureTapCallback? onTap,
|
||||
bool isDanger = false}) {
|
||||
bool isDanger = false,
|
||||
bool disable = false}) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(color: whiteColor),
|
||||
child: Material(
|
||||
|
|
@ -131,13 +146,21 @@ class AppDrawer extends StatelessWidget {
|
|||
'assets/images/svg/$svgFile.svg',
|
||||
height: 20,
|
||||
width: 20,
|
||||
color: isDanger ? dangerColor : textColor,
|
||||
color: disable
|
||||
? disableColor
|
||||
: isDanger
|
||||
? dangerColor
|
||||
: textColor,
|
||||
),
|
||||
if (icon != null)
|
||||
Icon(
|
||||
icon,
|
||||
size: 20.0,
|
||||
color: isDanger ? dangerColor : textColor,
|
||||
color: disable
|
||||
? disableColor
|
||||
: isDanger
|
||||
? dangerColor
|
||||
: textColor,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
|
|
@ -145,7 +168,11 @@ class AppDrawer extends StatelessWidget {
|
|||
text,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: isDanger ? dangerColor : textColor),
|
||||
color: disable
|
||||
? disableColor
|
||||
: isDanger
|
||||
? dangerColor
|
||||
: textColor),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
|
|
|||
21
pubspec.lock
21
pubspec.lock
|
|
@ -184,6 +184,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.2.0"
|
||||
grouped_list:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: grouped_list
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -211,7 +218,7 @@ packages:
|
|||
name: implicitly_animated_reorderable_list
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.0"
|
||||
version: "0.4.1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -239,7 +246,7 @@ packages:
|
|||
name: logger
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "1.1.0"
|
||||
mask_text_input_formatter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -309,7 +316,7 @@ packages:
|
|||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.0.3"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -393,7 +400,7 @@ packages:
|
|||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
version: "6.0.0"
|
||||
qr:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -449,7 +456,7 @@ packages:
|
|||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.6"
|
||||
version: "2.0.7"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -503,14 +510,14 @@ packages:
|
|||
name: sqflite
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0+3"
|
||||
version: "2.0.0+4"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0+2"
|
||||
version: "2.0.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
13
pubspec.yaml
13
pubspec.yaml
|
|
@ -34,13 +34,13 @@ dependencies:
|
|||
redux_persist: ^0.9.0
|
||||
redux_persist_flutter: ^0.9.0
|
||||
responsive_builder: ^0.4.1
|
||||
provider: ^5.0.0
|
||||
logger: ^1.0.0
|
||||
provider: ^6.0.0
|
||||
logger: ^1.1.0
|
||||
get_it: ^7.2.0
|
||||
equatable: ^2.0.3
|
||||
http: ^0.13.3
|
||||
sqflite: ^2.0.0+3
|
||||
path_provider: ^2.0.2
|
||||
sqflite: ^2.0.0+4
|
||||
path_provider: ^2.0.3
|
||||
material_design_icons_flutter: 5.0.5955-rc.1
|
||||
intl: ^0.17.0
|
||||
device_info: ^2.0.2
|
||||
|
|
@ -49,14 +49,15 @@ dependencies:
|
|||
qr_flutter: ^4.0.0
|
||||
mask_text_input_formatter: ^2.0.0
|
||||
flutter_screenutil: ^5.0.0+2
|
||||
shared_preferences: ^2.0.6
|
||||
shared_preferences: ^2.0.7
|
||||
material_floating_search_bar: ^0.3.4
|
||||
implicitly_animated_reorderable_list: ^0.4.0
|
||||
implicitly_animated_reorderable_list: ^0.4.1
|
||||
uuid: ^3.0.4
|
||||
charset_converter: ^2.0.0
|
||||
ai_barcode: ^3.0.1
|
||||
permission_handler: ^8.1.4+2
|
||||
flutter_svg: ^0.22.0
|
||||
grouped_list: ^4.1.0
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
|
|
|||
Loading…
Reference in New Issue