stocks
parent
01d6e2d808
commit
b5f9291116
|
|
@ -13,8 +13,11 @@ class BuyItemResponse {
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
required this.unitPrice,
|
required this.unitPrice,
|
||||||
|
required this.name,
|
||||||
this.deletedAt,
|
this.deletedAt,
|
||||||
this.refOkeiId,
|
this.refOkeiId,
|
||||||
|
this.ean13,
|
||||||
|
this.category
|
||||||
});
|
});
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
|
@ -34,6 +37,9 @@ class BuyItemResponse {
|
||||||
DateTime? deletedAt;
|
DateTime? deletedAt;
|
||||||
@JsonKey(name: 'unit_price')
|
@JsonKey(name: 'unit_price')
|
||||||
double unitPrice;
|
double unitPrice;
|
||||||
|
String name;
|
||||||
|
String? ean13;
|
||||||
|
String? category;
|
||||||
|
|
||||||
factory BuyItemResponse.fromJson(Map<String, dynamic> json) => _$BuyItemResponseFromJson(json);
|
factory BuyItemResponse.fromJson(Map<String, dynamic> json) => _$BuyItemResponseFromJson(json);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,13 @@ BuyItemResponse _$BuyItemResponseFromJson(Map<String, dynamic> json) =>
|
||||||
createdAt: DateTime.parse(json['created_at'] as String),
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
unitPrice: (json['unit_price'] as num).toDouble(),
|
unitPrice: (json['unit_price'] as num).toDouble(),
|
||||||
|
name: json['name'] as String,
|
||||||
deletedAt: json['deleted_at'] == null
|
deletedAt: json['deleted_at'] == null
|
||||||
? null
|
? null
|
||||||
: DateTime.parse(json['deleted_at'] as String),
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
refOkeiId: json['ref_okei_id'] as int?,
|
refOkeiId: json['ref_okei_id'] as int?,
|
||||||
|
ean13: json['ean13'] as String?,
|
||||||
|
category: json['category'] as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$BuyItemResponseToJson(BuyItemResponse instance) =>
|
Map<String, dynamic> _$BuyItemResponseToJson(BuyItemResponse instance) =>
|
||||||
|
|
@ -34,4 +37,7 @@ Map<String, dynamic> _$BuyItemResponseToJson(BuyItemResponse instance) =>
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
'unit_price': instance.unitPrice,
|
'unit_price': instance.unitPrice,
|
||||||
|
'name': instance.name,
|
||||||
|
'ean13': instance.ean13,
|
||||||
|
'category': instance.category,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ class BuyInvoiceResponse {
|
||||||
required this.eaccContragentId,
|
required this.eaccContragentId,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
|
required this.name,
|
||||||
this.deletedAt,
|
this.deletedAt,
|
||||||
this.summ,
|
this.summ,
|
||||||
});
|
});
|
||||||
|
|
@ -43,6 +44,7 @@ class BuyInvoiceResponse {
|
||||||
DateTime updatedAt;
|
DateTime updatedAt;
|
||||||
@JsonKey(name: 'deleted_at')
|
@JsonKey(name: 'deleted_at')
|
||||||
DateTime? deletedAt;
|
DateTime? deletedAt;
|
||||||
|
String name;
|
||||||
|
|
||||||
factory BuyInvoiceResponse.fromJson(Map<String, dynamic> json) => _$BuyInvoiceResponseFromJson(json);
|
factory BuyInvoiceResponse.fromJson(Map<String, dynamic> json) => _$BuyInvoiceResponseFromJson(json);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ BuyInvoiceResponse _$BuyInvoiceResponseFromJson(Map<String, dynamic> json) =>
|
||||||
eaccContragentId: json['eacc_contragent_id'] as int,
|
eaccContragentId: json['eacc_contragent_id'] as int,
|
||||||
createdAt: DateTime.parse(json['created_at'] as String),
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
|
name: json['name'] as String,
|
||||||
deletedAt: json['deleted_at'] == null
|
deletedAt: json['deleted_at'] == null
|
||||||
? null
|
? null
|
||||||
: DateTime.parse(json['deleted_at'] as String),
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
|
|
@ -34,4 +35,5 @@ Map<String, dynamic> _$BuyInvoiceResponseToJson(BuyInvoiceResponse instance) =>
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
'name': instance.name,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
part 'stock_response.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class StockResponse {
|
||||||
|
StockResponse({
|
||||||
|
required this.articul,
|
||||||
|
required this.ean13,
|
||||||
|
required this.eaccGoodId,
|
||||||
|
required this.name,
|
||||||
|
required this.price,
|
||||||
|
required this.cnt,
|
||||||
|
required this.katName,
|
||||||
|
});
|
||||||
|
|
||||||
|
int articul;
|
||||||
|
String ean13;
|
||||||
|
@JsonKey(name: 'eacc_good_id')
|
||||||
|
int eaccGoodId;
|
||||||
|
String name;
|
||||||
|
double price;
|
||||||
|
double cnt;
|
||||||
|
String katName;
|
||||||
|
|
||||||
|
factory StockResponse.fromJson(Map<String, dynamic> json) => _$StockResponseFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$StockResponseToJson(this);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'stock_response.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
StockResponse _$StockResponseFromJson(Map<String, dynamic> json) =>
|
||||||
|
StockResponse(
|
||||||
|
articul: json['articul'] as int,
|
||||||
|
ean13: json['ean13'] as String,
|
||||||
|
eaccGoodId: json['eacc_good_id'] as int,
|
||||||
|
name: json['name'] as String,
|
||||||
|
price: (json['price'] as num).toDouble(),
|
||||||
|
cnt: (json['cnt'] as num).toDouble(),
|
||||||
|
katName: json['katName'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$StockResponseToJson(StockResponse instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'articul': instance.articul,
|
||||||
|
'ean13': instance.ean13,
|
||||||
|
'eacc_good_id': instance.eaccGoodId,
|
||||||
|
'name': instance.name,
|
||||||
|
'price': instance.price,
|
||||||
|
'cnt': instance.cnt,
|
||||||
|
'katName': instance.katName,
|
||||||
|
};
|
||||||
|
|
@ -2,6 +2,7 @@ import 'package:redux/redux.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:redux_thunk/redux_thunk.dart';
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
import 'package:satu/core/models/auth/auth_response.dart';
|
import 'package:satu/core/models/auth/auth_response.dart';
|
||||||
|
import 'package:satu/core/models/dictionary/contragent/contragent_response_entity.dart';
|
||||||
import 'package:satu/core/redux/state/user_state.dart';
|
import 'package:satu/core/redux/state/user_state.dart';
|
||||||
import 'package:satu/core/services/api_service.dart';
|
import 'package:satu/core/services/api_service.dart';
|
||||||
import 'package:satu/core/services/dialog_service.dart';
|
import 'package:satu/core/services/dialog_service.dart';
|
||||||
|
|
@ -13,8 +14,8 @@ import '../store.dart';
|
||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
class SetUserStateAction {
|
class SetUserStateAction {
|
||||||
|
|
||||||
SetUserStateAction(this.userState);
|
SetUserStateAction(this.userState);
|
||||||
|
|
||||||
final UserState userState;
|
final UserState userState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,6 +48,12 @@ ThunkAction<AppState> authenticate(String email, String password) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThunkAction<AppState> setDefaultContragent(ContragentResponseEntity? entity) {
|
||||||
|
return (Store<AppState> store) async {
|
||||||
|
store.dispatch(SetUserStateAction(UserState(defaultContragent: entity)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
ThunkAction<AppState> authenticateByToken(String token) {
|
ThunkAction<AppState> authenticateByToken(String token) {
|
||||||
return (Store<AppState> store) async {
|
return (Store<AppState> store) async {
|
||||||
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
store.dispatch(SetUserStateAction(UserState(isLoading: true)));
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,6 @@ UserState userReducer(UserState prevState, SetUserStateAction action) {
|
||||||
isError: payload.isError,
|
isError: payload.isError,
|
||||||
isLoading: payload.isLoading,
|
isLoading: payload.isLoading,
|
||||||
auth: payload.auth,
|
auth: payload.auth,
|
||||||
|
defaultContragent: payload.defaultContragent,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,43 +1,43 @@
|
||||||
|
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:satu/core/models/auth/auth_response.dart';
|
import 'package:satu/core/models/auth/auth_response.dart';
|
||||||
|
import 'package:satu/core/models/dictionary/contragent/contragent_response_entity.dart';
|
||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
class UserState {
|
class UserState {
|
||||||
|
|
||||||
factory UserState.initial(UserState? payload) => UserState(
|
factory UserState.initial(UserState? payload) => UserState(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isError: false,
|
isError: false,
|
||||||
auth: payload?.auth ?? (AuthResponse()..operation=false),
|
auth: payload?.auth ?? (AuthResponse()..operation = false),
|
||||||
|
defaultContragent:
|
||||||
|
payload?.defaultContragent ?? ContragentResponseEntity(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
UserState({this.isError, this.isLoading, this.auth, this.defaultContragent});
|
||||||
|
|
||||||
UserState(
|
|
||||||
{this.isError,
|
|
||||||
this.isLoading,
|
|
||||||
this.auth,
|
|
||||||
});
|
|
||||||
final bool? isError;
|
final bool? isError;
|
||||||
final bool? isLoading;
|
final bool? isLoading;
|
||||||
final AuthResponse? auth;
|
final AuthResponse? auth;
|
||||||
|
final ContragentResponseEntity? defaultContragent;
|
||||||
|
|
||||||
UserState copyWith({
|
UserState copyWith(
|
||||||
required bool? isError,
|
{required bool? isError,
|
||||||
required bool? isLoading,
|
required bool? isLoading,
|
||||||
required AuthResponse? auth
|
required AuthResponse? auth,
|
||||||
}) {
|
required ContragentResponseEntity? defaultContragent}) {
|
||||||
return UserState(
|
return UserState(
|
||||||
isError: isError ?? this.isError,
|
isError: isError ?? this.isError,
|
||||||
isLoading: isLoading ?? this.isLoading,
|
isLoading: isLoading ?? this.isLoading,
|
||||||
auth: auth ?? this.auth,
|
auth: auth ?? this.auth,
|
||||||
);
|
defaultContragent: defaultContragent ?? this.defaultContragent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UserState? fromJson(dynamic json) {
|
static UserState? fromJson(dynamic json) {
|
||||||
return json != null
|
return json != null
|
||||||
? UserState(
|
? UserState(
|
||||||
auth: AuthResponse.fromMap(json['auth']),
|
auth: AuthResponse.fromMap(json['auth']),
|
||||||
|
defaultContragent: json['defaultContragent'] == null
|
||||||
|
? null
|
||||||
|
: ContragentResponseEntity.fromJson(json['defaultContragent']),
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +45,8 @@ class UserState {
|
||||||
dynamic toJson() {
|
dynamic toJson() {
|
||||||
return {
|
return {
|
||||||
'auth': auth != null ? auth!.toJson() : null,
|
'auth': auth != null ? auth!.toJson() : null,
|
||||||
|
'defaultContragent':
|
||||||
|
defaultContragent != null ? defaultContragent!.toJson() : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,6 @@ class ApiService extends BaseService {
|
||||||
|
|
||||||
final response = await http.post(Uri.https(host, url),
|
final response = await http.post(Uri.https(host, url),
|
||||||
body: jsonEncode(requestBody), headers: headers);
|
body: jsonEncode(requestBody), headers: headers);
|
||||||
if (requestBody != null) {
|
|
||||||
// log.i(host);
|
|
||||||
// log.i(url);
|
|
||||||
// log.i(headers);
|
|
||||||
//log.i(jsonEncode(requestBody));
|
|
||||||
//log.i(jsonEncode(response.body));
|
|
||||||
}
|
|
||||||
return response.body;
|
return response.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,6 +136,24 @@ class ApiService extends BaseService {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<ResponseOriginal> postRequestOriginal(String target,
|
||||||
|
{Map<String, dynamic>? requestBody}) async {
|
||||||
|
ResponseOriginal result;
|
||||||
|
try {
|
||||||
|
final Map<String, String> headers = <String, String>{
|
||||||
|
HttpHeaders.authorizationHeader: 'Bearer $token'
|
||||||
|
};
|
||||||
|
|
||||||
|
final String response =
|
||||||
|
await _post(target, header: headers, requestBody: requestBody);
|
||||||
|
result = ResponseOriginal.fromJson(json.decode(response));
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e('postRequest', e, stack);
|
||||||
|
result = ResponseOriginal()..message = e.toString();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Future<ResponseEntity> dictionarySave(
|
Future<ResponseEntity> dictionarySave(
|
||||||
String target, Map<String, dynamic>? body) async {
|
String target, Map<String, dynamic>? body) async {
|
||||||
ResponseEntity response;
|
ResponseEntity response;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:satu/core/base/base_service.dart';
|
import 'package:satu/core/base/base_service.dart';
|
||||||
import 'package:satu/core/models/but_item/buy_item_response.dart';
|
import 'package:satu/core/models/but_item/buy_item_response.dart';
|
||||||
|
import 'package:satu/core/models/dictionary/contragent/contragent_response_entity.dart';
|
||||||
import 'package:satu/core/services/api_service.dart';
|
import 'package:satu/core/services/api_service.dart';
|
||||||
import 'package:satu/core/utils/locator.dart';
|
import 'package:satu/core/utils/locator.dart';
|
||||||
|
|
||||||
|
|
@ -15,6 +17,10 @@ class BuyService extends BaseService {
|
||||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||||
'page': page,
|
'page': page,
|
||||||
'perpage': perpage,
|
'perpage': perpage,
|
||||||
|
'order' : {
|
||||||
|
'col': 'doc_number',
|
||||||
|
'desc': true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ResponseEntity categories = await _api.postRequest('/general_purchases_get',
|
ResponseEntity categories = await _api.postRequest('/general_purchases_get',
|
||||||
|
|
@ -42,8 +48,6 @@ class BuyService extends BaseService {
|
||||||
'perpage': perpage,
|
'perpage': perpage,
|
||||||
'id': id
|
'id': id
|
||||||
};
|
};
|
||||||
log.i(requestBody);
|
|
||||||
|
|
||||||
ResponseEntity categories = await _api.postRequest('/general_purchases_get_items',
|
ResponseEntity categories = await _api.postRequest('/general_purchases_get_items',
|
||||||
requestBody: requestBody);
|
requestBody: requestBody);
|
||||||
if (categories.original.items != null &&
|
if (categories.original.items != null &&
|
||||||
|
|
@ -69,7 +73,6 @@ class BuyService extends BaseService {
|
||||||
'price': price,
|
'price': price,
|
||||||
'cnt': count
|
'cnt': count
|
||||||
};
|
};
|
||||||
log.i(requestBody);
|
|
||||||
|
|
||||||
ResponseEntity response = await _api.postRequest('/general_purchases_edit_item',
|
ResponseEntity response = await _api.postRequest('/general_purchases_edit_item',
|
||||||
requestBody: requestBody);
|
requestBody: requestBody);
|
||||||
|
|
@ -86,7 +89,6 @@ class BuyService extends BaseService {
|
||||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||||
'id': id,
|
'id': id,
|
||||||
};
|
};
|
||||||
log.i(requestBody);
|
|
||||||
|
|
||||||
ResponseEntity response = await _api.postRequest('/general_purchases_delete_item',
|
ResponseEntity response = await _api.postRequest('/general_purchases_delete_item',
|
||||||
requestBody: requestBody);
|
requestBody: requestBody);
|
||||||
|
|
@ -105,7 +107,6 @@ class BuyService extends BaseService {
|
||||||
'eacc_good_id': goodId,
|
'eacc_good_id': goodId,
|
||||||
'id': invoiceId,
|
'id': invoiceId,
|
||||||
};
|
};
|
||||||
log.i(requestBody);
|
|
||||||
|
|
||||||
ResponseEntity response = await _api.postRequest('/general_purchases_add_item',
|
ResponseEntity response = await _api.postRequest('/general_purchases_add_item',
|
||||||
requestBody: requestBody);
|
requestBody: requestBody);
|
||||||
|
|
@ -116,4 +117,40 @@ class BuyService extends BaseService {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> confirmInvoice(int invoiceId) async {
|
||||||
|
bool result = false;
|
||||||
|
try {
|
||||||
|
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||||
|
'id': invoiceId,
|
||||||
|
};
|
||||||
|
|
||||||
|
ResponseEntity response = await _api.postRequest('/general_purchases_confirm',
|
||||||
|
requestBody: requestBody);
|
||||||
|
result = response.original.status == 'success';
|
||||||
|
log.i(response.toJson());
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e('getList', e, stack);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> createBuy(ContragentResponseEntity contragent, DateTime date) async {
|
||||||
|
bool result = false;
|
||||||
|
try {
|
||||||
|
DateFormat formatter = DateFormat('yyyy-MM-dd');
|
||||||
|
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||||
|
'eacc_contragent_id': contragent.id,
|
||||||
|
'invoice_date': formatter.format(date),
|
||||||
|
};
|
||||||
|
log.i('requestBody', requestBody);
|
||||||
|
ResponseEntity response = await _api.postRequest('/general_purchases_add',
|
||||||
|
requestBody: requestBody);
|
||||||
|
log.i('response', response.toJson());
|
||||||
|
result = response.original.status == 'success';
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e('getList', e, stack);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,8 +30,6 @@ class DictionaryService extends BaseService {
|
||||||
final ApiService _api = locator<ApiService>();
|
final ApiService _api = locator<ApiService>();
|
||||||
final DbService _db = locator<DbService>();
|
final DbService _db = locator<DbService>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Category categoryResponseToCategory(CategoryResponse response) {
|
Category categoryResponseToCategory(CategoryResponse response) {
|
||||||
return Category()
|
return Category()
|
||||||
..id = response.id
|
..id = response.id
|
||||||
|
|
@ -84,7 +82,7 @@ class DictionaryService extends BaseService {
|
||||||
'val': categoryId
|
'val': categoryId
|
||||||
};
|
};
|
||||||
List<GoodResponseEntity> responses =
|
List<GoodResponseEntity> responses =
|
||||||
await getGoods(page: 1, perpage: 100, filter: filter);
|
await getGoods(page: 1, perpage: 100, filter: [filter]);
|
||||||
for (final GoodResponseEntity response in responses) {
|
for (final GoodResponseEntity response in responses) {
|
||||||
final Good good = goodResponseToGood(response);
|
final Good good = goodResponseToGood(response);
|
||||||
list.add(good);
|
list.add(good);
|
||||||
|
|
@ -95,24 +93,38 @@ class DictionaryService extends BaseService {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Good>> getGoodsByNameOrEan(String query) async {
|
Future<List<Good>> getGoodsByNameOrEan(String query, { bool onlyEan = false}) async {
|
||||||
final List<Good> list = [];
|
final List<Good> list = [];
|
||||||
try {
|
try {
|
||||||
final int? appCompanyId = Redux.store?.state.userState?.auth?.companyId;
|
dynamic filter = [
|
||||||
String where =
|
{
|
||||||
'( $GoodColumnAppCompanyId = ? and $GoodColumnName like ? ) ';
|
'col': 'name',
|
||||||
final List args = [appCompanyId, '%$query%'];
|
'action': 'like',
|
||||||
if (_isNumericInt(query) && query.length >= 8) {
|
'val': query,
|
||||||
where += ' or $GoodColumnEan like ?';
|
},
|
||||||
args.add('${int.parse(query).toString()}%');
|
{
|
||||||
|
'col': 'ean13',
|
||||||
|
'action': 'like',
|
||||||
|
'val': query,
|
||||||
}
|
}
|
||||||
final List<Map<String, dynamic>> elements =
|
];
|
||||||
await _db.queryRowsWithWhere(goodTableName, where, args);
|
if (onlyEan) {
|
||||||
for (final Map<String, dynamic> element in elements) {
|
filter = [
|
||||||
list.add(Good.fromMap(element));
|
{
|
||||||
|
'col': 'ean13',
|
||||||
|
'action': 'equals',
|
||||||
|
'val': query,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
List<GoodResponseEntity> responses =
|
||||||
|
await getGoods(page: 1, perpage: 100, filter: filter);
|
||||||
|
for (final GoodResponseEntity response in responses) {
|
||||||
|
final Good good = goodResponseToGood(response);
|
||||||
|
list.add(good);
|
||||||
}
|
}
|
||||||
} catch (e, stack) {
|
} catch (e, stack) {
|
||||||
log.e('getGoodsByCategoryId', e, stack);
|
log.e('getGoods', e, stack);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
@ -172,13 +184,14 @@ class DictionaryService extends BaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<GoodResponseEntity>> getGoods(
|
Future<List<GoodResponseEntity>> getGoods(
|
||||||
{required int page, required int perpage, dynamic filter}) async {
|
{required int page, required int perpage, dynamic filter,bool orGate = false}) async {
|
||||||
List<GoodResponseEntity> list = [];
|
List<GoodResponseEntity> list = [];
|
||||||
try {
|
try {
|
||||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||||
'page': page,
|
'page': page,
|
||||||
'perpage': perpage,
|
'perpage': perpage,
|
||||||
'filter': [filter]
|
'filter': filter,
|
||||||
|
'or_gate': orGate
|
||||||
};
|
};
|
||||||
|
|
||||||
ResponseEntity categories =
|
ResponseEntity categories =
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,12 @@ import 'package:satu/core/models/flow/sell_return/sell_return_request.dart';
|
||||||
import 'package:satu/core/models/flow/transaction_state.dart';
|
import 'package:satu/core/models/flow/transaction_state.dart';
|
||||||
import 'package:satu/core/redux/actions/sell_actions.dart';
|
import 'package:satu/core/redux/actions/sell_actions.dart';
|
||||||
import 'package:satu/core/redux/state/sell_state.dart';
|
import 'package:satu/core/redux/state/sell_state.dart';
|
||||||
|
import 'package:satu/core/redux/state/user_state.dart';
|
||||||
import 'package:satu/core/redux/store.dart';
|
import 'package:satu/core/redux/store.dart';
|
||||||
import 'package:satu/core/utils/locator.dart';
|
import 'package:satu/core/utils/locator.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
import '../models/dictionary/contragent/contragent_response_entity.dart';
|
||||||
import 'api_service.dart';
|
import 'api_service.dart';
|
||||||
import 'db_service.dart';
|
import 'db_service.dart';
|
||||||
import 'dialog_service.dart';
|
import 'dialog_service.dart';
|
||||||
|
|
@ -30,6 +32,7 @@ class SellService extends BaseService {
|
||||||
{double card = 0, double nal = 0, double total = 0}) async {
|
{double card = 0, double nal = 0, double total = 0}) async {
|
||||||
final SellRequest request = SellRequest();
|
final SellRequest request = SellRequest();
|
||||||
final SellState sellState = Redux.store!.state.sellState!;
|
final SellState sellState = Redux.store!.state.sellState!;
|
||||||
|
final UserState userState = Redux.store!.state.userState!;
|
||||||
final TransactionState transactionState = sellState.transactionState!;
|
final TransactionState transactionState = sellState.transactionState!;
|
||||||
final List<ProductDao> items = sellState.items!;
|
final List<ProductDao> items = sellState.items!;
|
||||||
for (final ProductDao item in items) {
|
for (final ProductDao item in items) {
|
||||||
|
|
@ -40,10 +43,12 @@ class SellService extends BaseService {
|
||||||
request.invoiceId = transactionState.uuid;
|
request.invoiceId = transactionState.uuid;
|
||||||
request.section = transactionState.sectionName;
|
request.section = transactionState.sectionName;
|
||||||
request.contragent = transactionState.contragentName;
|
request.contragent = transactionState.contragentName;
|
||||||
|
ContragentResponseEntity? contragent = userState.defaultContragent;
|
||||||
final OperatorBean operator = OperatorBean()
|
final OperatorBean operator = OperatorBean()
|
||||||
..name = 'operator'
|
..name = 'operator'
|
||||||
..code = 1;
|
..code = 1;
|
||||||
request.operator = operator;
|
request.operator = operator;
|
||||||
|
request.contragent = contragent?.name;
|
||||||
final SellResponse response = await _api.sell(request);
|
final SellResponse response = await _api.sell(request);
|
||||||
if (response.operation == false) {
|
if (response.operation == false) {
|
||||||
_dialogService.showDialog(description: response.message);
|
_dialogService.showDialog(description: response.message);
|
||||||
|
|
@ -125,7 +130,6 @@ class SellService extends BaseService {
|
||||||
data.nal = nal;
|
data.nal = nal;
|
||||||
data.total = total;
|
data.total = total;
|
||||||
transaction.data = jsonEncode(data.toMap());
|
transaction.data = jsonEncode(data.toMap());
|
||||||
log.i(jsonEncode(data.toMap()));
|
|
||||||
await _db.update(transactionTableName, transaction.toMap());
|
await _db.update(transactionTableName, transaction.toMap());
|
||||||
return transaction.id;
|
return transaction.id;
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +161,6 @@ class SellService extends BaseService {
|
||||||
data.nal = nal;
|
data.nal = nal;
|
||||||
data.total = total;
|
data.total = total;
|
||||||
transaction.data = jsonEncode(data.toMap());
|
transaction.data = jsonEncode(data.toMap());
|
||||||
log.i(jsonEncode(data.toMap()));
|
|
||||||
return await _db.insert(transactionTableName, transaction.toMap());
|
return await _db.insert(transactionTableName, transaction.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import 'package:satu/core/base/base_service.dart';
|
||||||
|
import 'package:satu/core/models/stock/stock_response.dart';
|
||||||
|
|
||||||
|
import '../models/response/response_entity.dart';
|
||||||
|
import '../utils/locator.dart';
|
||||||
|
import 'api_service.dart';
|
||||||
|
|
||||||
|
class StockService extends BaseService {
|
||||||
|
final ApiService _api = locator<ApiService>();
|
||||||
|
|
||||||
|
Future<List<StockResponse>> getList(
|
||||||
|
{required int page, required int perpage, String? query}) async {
|
||||||
|
List<StockResponse> list = [];
|
||||||
|
try {
|
||||||
|
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||||
|
'page': page,
|
||||||
|
'perpage': perpage,
|
||||||
|
'search': query ?? ''
|
||||||
|
};
|
||||||
|
|
||||||
|
ResponseOriginal categories = await _api.postRequestOriginal('/get_stock_balance',
|
||||||
|
requestBody: requestBody);
|
||||||
|
if (categories.data != null &&
|
||||||
|
categories.data!.isNotEmpty) {
|
||||||
|
for (final dynamic map in categories.data!) {
|
||||||
|
final StockResponse item =
|
||||||
|
StockResponse.fromJson(map);
|
||||||
|
list.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e, stack) {
|
||||||
|
log.e('getList', e, stack);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,7 @@ import 'package:satu/core/services/dialog_service.dart';
|
||||||
import 'package:satu/core/services/dictionary_service.dart';
|
import 'package:satu/core/services/dictionary_service.dart';
|
||||||
import 'package:satu/core/services/inventarization_service.dart';
|
import 'package:satu/core/services/inventarization_service.dart';
|
||||||
import 'package:satu/core/services/navigator_service.dart';
|
import 'package:satu/core/services/navigator_service.dart';
|
||||||
|
import 'package:satu/core/services/stocks_service.dart';
|
||||||
|
|
||||||
import 'logger.dart';
|
import 'logger.dart';
|
||||||
|
|
||||||
|
|
@ -39,5 +40,7 @@ class LocatorInjector {
|
||||||
_log.d('Initializing InventarizationService Service');
|
_log.d('Initializing InventarizationService Service');
|
||||||
locator.registerLazySingleton<InventarizationService>(
|
locator.registerLazySingleton<InventarizationService>(
|
||||||
() => InventarizationService());
|
() => InventarizationService());
|
||||||
|
_log.d('Initializing StockService Service');
|
||||||
|
locator.registerLazySingleton<StockService>(() => StockService());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ const String inventarizationEditRoute = 'inventarizationEditRoute';
|
||||||
|
|
||||||
//buy
|
//buy
|
||||||
const String buyEditRoute = 'buyEditRoute';
|
const String buyEditRoute = 'buyEditRoute';
|
||||||
|
const String buyAddRoute = 'buyAddRoute';
|
||||||
|
|
||||||
// setting - ble printer
|
// setting - ble printer
|
||||||
const String settingPrinterBluetoothViewRoute = 'SettingPrinterBluetoothView';
|
const String settingPrinterBluetoothViewRoute = 'SettingPrinterBluetoothView';
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,16 @@ import 'package:satu/views/settings/printer_bluetooth/printer_encoding_select.da
|
||||||
import 'package:satu/views/settings/printer_bluetooth/printer_paper_size_select.dart';
|
import 'package:satu/views/settings/printer_bluetooth/printer_paper_size_select.dart';
|
||||||
import 'package:satu/views/settings/printer_bluetooth/printer_select.dart';
|
import 'package:satu/views/settings/printer_bluetooth/printer_select.dart';
|
||||||
import 'package:satu/views/settings/printer_bluetooth/printer_view.dart';
|
import 'package:satu/views/settings/printer_bluetooth/printer_view.dart';
|
||||||
|
import 'package:satu/views/work/tabs/buy/buy_add.dart';
|
||||||
import 'package:satu/views/work/tabs/buy/buy_edit.dart';
|
import 'package:satu/views/work/tabs/buy/buy_edit.dart';
|
||||||
import 'package:satu/views/work/views/add_by_barcode/add_by_barcode_view.dart';
|
|
||||||
import 'package:satu/views/work/views/add_product/add_product_view.dart';
|
|
||||||
import 'package:satu/views/work/views/contragent/select_contragent_view.dart';
|
|
||||||
import 'package:satu/views/work/views/payment/payment_view.dart';
|
import 'package:satu/views/work/views/payment/payment_view.dart';
|
||||||
import 'package:satu/views/work/views/receipt/receipt_view.dart';
|
import 'package:satu/views/work/views/receipt/receipt_view.dart';
|
||||||
|
import 'package:satu/views/work/views/select_by_scan/add_by_barcode_view.dart';
|
||||||
import 'package:satu/views/work/work_view.dart';
|
import 'package:satu/views/work/work_view.dart';
|
||||||
|
|
||||||
import '../core/models/inventarization/response/inventarization_response.dart';
|
import '../core/models/inventarization/response/inventarization_response.dart';
|
||||||
|
import '../views/work/views/select_contragent/select_contragent_view.dart';
|
||||||
|
import '../views/work/views/select_product/add_product_view.dart';
|
||||||
import './route_names.dart';
|
import './route_names.dart';
|
||||||
|
|
||||||
Route<dynamic> generateRoute(RouteSettings settings) {
|
Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
|
|
@ -46,12 +47,12 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
case addProductViewRoute:
|
case addProductViewRoute:
|
||||||
return _getPageRoute(
|
return _getPageRoute(
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: AddProductView(),
|
viewToShow: SelectProductView(),
|
||||||
);
|
);
|
||||||
case addByBarcodeViewRoute:
|
case addByBarcodeViewRoute:
|
||||||
return _getPageRoute(
|
return _getPageRoute(
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: const AddByBarcodeView(),
|
viewToShow: const SelectByScanView(),
|
||||||
);
|
);
|
||||||
case settingPrinterBluetoothViewRoute:
|
case settingPrinterBluetoothViewRoute:
|
||||||
return _getPageRoute(
|
return _getPageRoute(
|
||||||
|
|
@ -137,6 +138,11 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
invoice: invoice,
|
invoice: invoice,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
case buyAddRoute:
|
||||||
|
return _getPageRoute(
|
||||||
|
routeName: settings.name,
|
||||||
|
viewToShow: BuyAddView(),
|
||||||
|
);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,8 @@ class _GoodsDictionaryViewState extends State<GoodsDictionaryView> {
|
||||||
Future<void> _fetchData(int pageKey, int perPage, String? query) async {
|
Future<void> _fetchData(int pageKey, int perPage, String? query) async {
|
||||||
final List<GoodResponseEntity> newItems = await _dictionaryService.getGoods(
|
final List<GoodResponseEntity> newItems = await _dictionaryService.getGoods(
|
||||||
page: pageKey,
|
page: pageKey,
|
||||||
filter: {'col': 'name', 'action': 'like', 'val': query ?? ''},
|
filter: [{'col': 'name', 'action': 'like', 'val': query ?? ''}],
|
||||||
perpage: perPage);
|
perpage: perPage, orGate: true);
|
||||||
|
|
||||||
final isLastPage = newItems.length < _pageSize;
|
final isLastPage = newItems.length < _pageSize;
|
||||||
if (isLastPage) {
|
if (isLastPage) {
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,14 @@ class _InventarizationEditViewState extends State<InventarizationEditView> {
|
||||||
},
|
},
|
||||||
pagingController: _pagingController,
|
pagingController: _pagingController,
|
||||||
builderDelegate: PagedChildBuilderDelegate<GoodInventarization>(
|
builderDelegate: PagedChildBuilderDelegate<GoodInventarization>(
|
||||||
|
noItemsFoundIndicatorBuilder: (BuildContext context) {
|
||||||
|
return const Center(
|
||||||
|
child: Text(
|
||||||
|
'Необходимо добавить товар',
|
||||||
|
style: textGray11Style,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
itemBuilder: (BuildContext context, GoodInventarization item,
|
itemBuilder: (BuildContext context, GoodInventarization item,
|
||||||
int index) {
|
int index) {
|
||||||
return GoodInventarizationListItem(
|
return GoodInventarizationListItem(
|
||||||
|
|
@ -199,8 +207,25 @@ class _InventarizationEditViewState extends State<InventarizationEditView> {
|
||||||
final dynamic result = await _nav.push(addByBarcodeViewRoute);
|
final dynamic result = await _nav.push(addByBarcodeViewRoute);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
final List<Good> goods = await locator<DictionaryService>()
|
final List<Good> goods = await locator<DictionaryService>()
|
||||||
.getGoodsByNameOrEan(result as String);
|
.getGoodsByNameOrEan(result as String, onlyEan: true);
|
||||||
if (goods.isNotEmpty) {}
|
if (goods.isNotEmpty) {
|
||||||
|
final Good good = goods.first;
|
||||||
|
bool result = await _service
|
||||||
|
.addGoodToList(widget.item.id, good.id);
|
||||||
|
if (result) {
|
||||||
|
_pagingController.refresh();
|
||||||
|
} else {
|
||||||
|
_dialogService.showDialog(
|
||||||
|
description:
|
||||||
|
'Товара отсутсвует в остатке или ранее не'
|
||||||
|
' использователся в системе',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_dialogService.showDialog(
|
||||||
|
description: 'Товар не найден',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Icon(Icons.qr_code_rounded, size: 30, color: whiteColor),
|
child: Icon(Icons.qr_code_rounded, size: 30, color: whiteColor),
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,11 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
import 'package:satu/core/models/dialog_models.dart';
|
import 'package:satu/core/models/dialog_models.dart';
|
||||||
import 'package:satu/core/redux/actions/sell_actions.dart';
|
|
||||||
import 'package:satu/core/redux/store.dart';
|
|
||||||
import 'package:satu/core/services/dialog_service.dart';
|
import 'package:satu/core/services/dialog_service.dart';
|
||||||
import 'package:satu/core/services/inventarization_service.dart';
|
import 'package:satu/core/services/inventarization_service.dart';
|
||||||
import 'package:satu/core/utils/locator.dart';
|
import 'package:satu/core/utils/locator.dart';
|
||||||
import 'package:satu/core/utils/utils_parse.dart';
|
import 'package:satu/core/utils/utils_parse.dart';
|
||||||
import 'package:satu/shared/app_colors.dart';
|
import 'package:satu/shared/app_colors.dart';
|
||||||
import 'package:satu/shared/shared_styles.dart';
|
|
||||||
import 'package:satu/views/work/views/add_by_barcode/add_by_barcode_view.dart';
|
|
||||||
import 'package:satu/widgets/ui/product_title_widget.dart';
|
import 'package:satu/widgets/ui/product_title_widget.dart';
|
||||||
|
|
||||||
class GoodInventarizationListItem extends StatefulWidget {
|
class GoodInventarizationListItem extends StatefulWidget {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import 'package:satu/views/work/work_view.dart';
|
||||||
import 'package:satu/widgets/drawer/app_drawer.dart';
|
import 'package:satu/widgets/drawer/app_drawer.dart';
|
||||||
|
|
||||||
import '../dictionaries/contragents/contragents_view.dart';
|
import '../dictionaries/contragents/contragents_view.dart';
|
||||||
|
import '../stocks/stocks_view.dart';
|
||||||
|
|
||||||
class MainView extends StatefulWidget {
|
class MainView extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
|
@ -30,6 +31,7 @@ class _MainViewState extends State<MainView> {
|
||||||
final _contragentDictView = ContragentsDictionaryView();
|
final _contragentDictView = ContragentsDictionaryView();
|
||||||
final _analyticsView = const AnalyticsView();
|
final _analyticsView = const AnalyticsView();
|
||||||
final _inventarizationView = InventarizationView();
|
final _inventarizationView = InventarizationView();
|
||||||
|
final _stocksView = StocksView();
|
||||||
|
|
||||||
Widget _body(Type viewClass) {
|
Widget _body(Type viewClass) {
|
||||||
if(viewClass == WorkView) {
|
if(viewClass == WorkView) {
|
||||||
|
|
@ -53,6 +55,9 @@ class _MainViewState extends State<MainView> {
|
||||||
if(viewClass == AnalyticsView) {
|
if(viewClass == AnalyticsView) {
|
||||||
return _analyticsView;
|
return _analyticsView;
|
||||||
}
|
}
|
||||||
|
if(viewClass == StocksView) {
|
||||||
|
return _stocksView;
|
||||||
|
}
|
||||||
return _workView;
|
return _workView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,179 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
|
import 'package:satu/core/models/inventarization/response/inventarization_response.dart';
|
||||||
|
import 'package:satu/core/models/stock/stock_response.dart';
|
||||||
|
import 'package:satu/core/services/dialog_service.dart';
|
||||||
|
import 'package:satu/core/services/stocks_service.dart';
|
||||||
|
import 'package:satu/views/inventarization/widget/good_inventarization_list_item.dart';
|
||||||
|
import 'package:satu/views/stocks/widget/stock_tile.dart';
|
||||||
|
|
||||||
|
import '../../../core/entity/goods_entity.dart';
|
||||||
|
import '../../../core/models/inventarization/good_item/good_item.dart';
|
||||||
|
import '../../../core/services/dictionary_service.dart';
|
||||||
|
import '../../../core/services/inventarization_service.dart';
|
||||||
|
import '../../../core/services/navigator_service.dart';
|
||||||
|
import '../../../core/utils/locator.dart';
|
||||||
|
import '../../../routes/route_names.dart';
|
||||||
|
import '../../../shared/app_colors.dart';
|
||||||
|
import '../../../shared/shared_styles.dart';
|
||||||
|
import '../../../shared/ui_helpers.dart';
|
||||||
|
import '../../../widgets/bar/products_app_bar.dart';
|
||||||
|
import '../../widgets/fields/input_field.dart';
|
||||||
|
|
||||||
|
class StocksView extends StatefulWidget {
|
||||||
|
const StocksView({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StocksView> createState() => _StocksViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StocksViewState extends State<StocksView> {
|
||||||
|
final StockService _service = locator<StockService>();
|
||||||
|
late TextEditingController _searchTextController;
|
||||||
|
final FocusNode _searchFocusNode = FocusNode();
|
||||||
|
String query = '';
|
||||||
|
Timer? _debounce;
|
||||||
|
|
||||||
|
static const _pageSize = 20;
|
||||||
|
bool _isLastPage = false;
|
||||||
|
|
||||||
|
final PagingController<int, StockResponse> _pagingController =
|
||||||
|
PagingController(firstPageKey: 1);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_searchTextController = TextEditingController();
|
||||||
|
_searchTextController.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
query = _searchTextController.text;
|
||||||
|
});
|
||||||
|
if (_debounce?.isActive ?? false) _debounce?.cancel();
|
||||||
|
_debounce = Timer(const Duration(milliseconds: 500), () {
|
||||||
|
_pagingController.refresh();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
_pagingController.addPageRequestListener((pageKey) {
|
||||||
|
_fetchData(pageKey, _pageSize, query);
|
||||||
|
});
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
;
|
||||||
|
_debounce?.cancel();
|
||||||
|
_pagingController.dispose();
|
||||||
|
_searchTextController.dispose();
|
||||||
|
_searchFocusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: const ProductsAppBar(
|
||||||
|
title: 'Остатки',
|
||||||
|
drawerShow: true,
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
InputField(
|
||||||
|
placeholder: 'Поиск по наименованию товара или штрих-код',
|
||||||
|
search: true,
|
||||||
|
controller: _searchTextController,
|
||||||
|
fieldFocusNode: _searchFocusNode,
|
||||||
|
),
|
||||||
|
verticalSpaceSmall,
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15.0),
|
||||||
|
child: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 4,
|
||||||
|
child: Text(
|
||||||
|
'Список товара',
|
||||||
|
style: textGray11Style,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text(
|
||||||
|
'Количество',
|
||||||
|
style: textGray11Style,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Text(
|
||||||
|
'Сумма',
|
||||||
|
style: textGray11Style,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
verticalSpaceSmall,
|
||||||
|
Expanded(
|
||||||
|
child: PagedListView<int, StockResponse>.separated(
|
||||||
|
//physics: const BouncingScrollPhysics(),
|
||||||
|
separatorBuilder: (BuildContext context, int index) {
|
||||||
|
return const Divider(
|
||||||
|
height: 1.0,
|
||||||
|
color: disableColor,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
pagingController: _pagingController,
|
||||||
|
builderDelegate: PagedChildBuilderDelegate<StockResponse>(
|
||||||
|
noItemsFoundIndicatorBuilder: (BuildContext context) {
|
||||||
|
return const Center(
|
||||||
|
child: Text(
|
||||||
|
'В данном списке нет товаров',
|
||||||
|
style: textGray11Style,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemBuilder:
|
||||||
|
(BuildContext context, StockResponse item, int index) {
|
||||||
|
return StockTile(
|
||||||
|
key: Key(
|
||||||
|
'good_stock_${item.eaccGoodId}',
|
||||||
|
),
|
||||||
|
name: item.name,
|
||||||
|
categoryName: item.katName,
|
||||||
|
count: item.cnt,
|
||||||
|
price: item.price,
|
||||||
|
ean: item.ean13,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _fetchData(int pageKey, int perPage, String? query) async {
|
||||||
|
final List<StockResponse> newItems = await _service.getList(
|
||||||
|
page: pageKey,
|
||||||
|
perpage: perPage,
|
||||||
|
query: query,
|
||||||
|
);
|
||||||
|
_isLastPage = newItems.length < _pageSize;
|
||||||
|
|
||||||
|
if (_isLastPage) {
|
||||||
|
_pagingController.appendLastPage(newItems);
|
||||||
|
} else {
|
||||||
|
final nextPageKey = pageKey + 1;
|
||||||
|
_pagingController.appendPage(newItems, nextPageKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:satu/core/utils/utils_parse.dart';
|
||||||
|
import 'package:satu/shared/app_colors.dart';
|
||||||
|
|
||||||
|
import 'package:satu/widgets/ui/product_title_widget.dart';
|
||||||
|
|
||||||
|
class StockTile extends StatefulWidget {
|
||||||
|
const StockTile({
|
||||||
|
required Key key,
|
||||||
|
required this.price,
|
||||||
|
required this.count,
|
||||||
|
this.name = '',
|
||||||
|
this.ean,
|
||||||
|
this.categoryName,
|
||||||
|
|
||||||
|
}) : super(key: key);
|
||||||
|
final String name;
|
||||||
|
final String? ean;
|
||||||
|
final String? categoryName;
|
||||||
|
final double price;
|
||||||
|
final double count;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
_StockTileState createState() =>
|
||||||
|
_StockTileState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StockTileState
|
||||||
|
extends State<StockTile> {
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
key: widget.key!,
|
||||||
|
contentPadding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 10.0, vertical: 4.0),
|
||||||
|
title: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 4,
|
||||||
|
child: ProductTitleWidget(
|
||||||
|
name: widget.name,
|
||||||
|
ean: widget.ean,
|
||||||
|
categoryName: widget.categoryName,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text(
|
||||||
|
formatDecimal(widget.count),
|
||||||
|
style: const TextStyle(fontSize: 12, color: textColor),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
)),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Text(
|
||||||
|
formatDecimal(widget.price),
|
||||||
|
style: const TextStyle(fontSize: 12, color: textColor),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
tileColor: whiteColor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:satu/core/models/dictionary/contragent/contragent_response_entity.dart';
|
||||||
|
import 'package:satu/widgets/fields/line_tile.dart';
|
||||||
|
|
||||||
|
import '../../../../core/services/buy_service.dart';
|
||||||
|
import '../../../../core/services/navigator_service.dart';
|
||||||
|
import '../../../../core/utils/locator.dart';
|
||||||
|
import '../../../../routes/route_names.dart';
|
||||||
|
import '../../../../widgets/bar/products_app_bar.dart';
|
||||||
|
import '../../../../widgets/buttons/busy_button.dart';
|
||||||
|
|
||||||
|
class BuyAddView extends StatefulWidget {
|
||||||
|
const BuyAddView({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BuyAddView> createState() => _BuyAddViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BuyAddViewState extends State<BuyAddView> {
|
||||||
|
ContragentResponseEntity? _contragent;
|
||||||
|
DateTime _date = DateTime.now();
|
||||||
|
final BuyService _service = locator<BuyService>();
|
||||||
|
DateFormat _dateFormat = DateFormat('dd.MM.yyyy');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: const ProductsAppBar(
|
||||||
|
title: 'Новая накладная покупки',
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ListView(
|
||||||
|
children: [
|
||||||
|
LineTile(
|
||||||
|
key: const Key('BuyAddView_Contragent'),
|
||||||
|
_contragent?.name ?? 'Выберите контрагента',
|
||||||
|
onTap: () async {
|
||||||
|
ContragentResponseEntity? entity =
|
||||||
|
await locator<NavigatorService>()
|
||||||
|
.push(contragentSelectViewRoute)
|
||||||
|
as ContragentResponseEntity?;
|
||||||
|
if (entity != null) {
|
||||||
|
setState(() {
|
||||||
|
_contragent = entity;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
labelText: 'Контрагент',
|
||||||
|
),
|
||||||
|
LineTile(
|
||||||
|
key: const Key('BuyAddView_Date'),
|
||||||
|
_dateFormat.format(_date),
|
||||||
|
onTap: () async {
|
||||||
|
|
||||||
|
DateTime? pickedDate = await showDatePicker(
|
||||||
|
context: context,
|
||||||
|
initialDate: DateTime.now(), //get today's date
|
||||||
|
firstDate:DateTime(2000), //DateTime.now() - not to allow to choose before today.
|
||||||
|
lastDate: DateTime(2101)
|
||||||
|
);
|
||||||
|
if (pickedDate != null) {
|
||||||
|
setState(() {
|
||||||
|
_date = pickedDate;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
labelText: 'Дата накладной',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 45, vertical: 30),
|
||||||
|
child: BusyButton(
|
||||||
|
title: 'СОЗДАТЬ',
|
||||||
|
busy: false,
|
||||||
|
onPressed: () async {
|
||||||
|
|
||||||
|
if (_contragent == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool result = await _service.createBuy(_contragent!, _date);
|
||||||
|
if (result) {
|
||||||
|
locator<NavigatorService>().pop(result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,10 +3,11 @@ import 'dart:developer';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:satu/core/models/but_item/buy_item_response.dart';
|
import 'package:satu/core/models/but_item/buy_item_response.dart';
|
||||||
|
import 'package:satu/core/models/dialog_models.dart';
|
||||||
import 'package:satu/core/services/dialog_service.dart';
|
import 'package:satu/core/services/dialog_service.dart';
|
||||||
|
import 'package:satu/shared/shared_styles.dart';
|
||||||
import 'package:satu/views/work/tabs/buy/component/product_buy_tile.dart';
|
import 'package:satu/views/work/tabs/buy/component/product_buy_tile.dart';
|
||||||
|
|
||||||
|
|
||||||
import '../../../../core/entity/goods_entity.dart';
|
import '../../../../core/entity/goods_entity.dart';
|
||||||
import '../../../../core/models/buy_invoice/buy_invoice_response.dart';
|
import '../../../../core/models/buy_invoice/buy_invoice_response.dart';
|
||||||
import '../../../../core/services/buy_service.dart';
|
import '../../../../core/services/buy_service.dart';
|
||||||
|
|
@ -38,6 +39,7 @@ class _BuyEditViewState extends State<BuyEditView> {
|
||||||
|
|
||||||
bool editable = false;
|
bool editable = false;
|
||||||
|
|
||||||
|
bool itemsExist = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -46,7 +48,7 @@ class _BuyEditViewState extends State<BuyEditView> {
|
||||||
_fetchData(pageKey, _pageSize);
|
_fetchData(pageKey, _pageSize);
|
||||||
});
|
});
|
||||||
log('refBuyInvoiceStatusId: ${widget.invoice.refBuyInvoiceStatusId}');
|
log('refBuyInvoiceStatusId: ${widget.invoice.refBuyInvoiceStatusId}');
|
||||||
if(widget.invoice.refBuyInvoiceStatusId == 1){
|
if (widget.invoice.refBuyInvoiceStatusId == 1) {
|
||||||
editable = true;
|
editable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,7 +57,6 @@ class _BuyEditViewState extends State<BuyEditView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
|
||||||
_pagingController.dispose();
|
_pagingController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
@ -79,15 +80,23 @@ class _BuyEditViewState extends State<BuyEditView> {
|
||||||
},
|
},
|
||||||
pagingController: _pagingController,
|
pagingController: _pagingController,
|
||||||
builderDelegate: PagedChildBuilderDelegate<BuyItemResponse>(
|
builderDelegate: PagedChildBuilderDelegate<BuyItemResponse>(
|
||||||
itemBuilder: (BuildContext context, BuyItemResponse item,
|
noItemsFoundIndicatorBuilder: (BuildContext context) {
|
||||||
int index) {
|
return const Center(
|
||||||
|
child: Text(
|
||||||
|
'Необходимо добавить товар',
|
||||||
|
style: textGray11Style,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemBuilder:
|
||||||
|
(BuildContext context, BuyItemResponse item, int index) {
|
||||||
return ProductBuyTile(
|
return ProductBuyTile(
|
||||||
key: ValueKey(item.id),
|
key: ValueKey(item.id),
|
||||||
ean: '1234567890123',
|
ean: item.ean13,
|
||||||
name: 'Картофель',
|
name: item.name,
|
||||||
price: item.price,
|
price: item.price,
|
||||||
count: item.cnt,
|
count: item.cnt,
|
||||||
categoryName: 'Овощи',
|
categoryName: item.category,
|
||||||
editable: editable,
|
editable: editable,
|
||||||
invoiceId: widget.invoice.id,
|
invoiceId: widget.invoice.id,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
|
|
@ -115,14 +124,29 @@ class _BuyEditViewState extends State<BuyEditView> {
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: false,
|
visible: itemsExist,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: FloatingActionButton(
|
child: FloatingActionButton(
|
||||||
mini: true,
|
mini: true,
|
||||||
elevation: 2,
|
elevation: 2,
|
||||||
backgroundColor: successColor,
|
backgroundColor: successColor,
|
||||||
onPressed: () {},
|
onPressed: () async {
|
||||||
|
DialogResponse confirm =
|
||||||
|
await _dialogService.showConfirmationDialog(
|
||||||
|
title: 'Подтверждение',
|
||||||
|
description: 'Вы действительно хотите завершить покупку?',
|
||||||
|
confirmationTitle: 'Да',
|
||||||
|
cancelTitle: 'Нет',
|
||||||
|
);
|
||||||
|
if (confirm.confirmed) {
|
||||||
|
bool result =
|
||||||
|
await _service.confirmInvoice(widget.invoice.id);
|
||||||
|
if (result) {
|
||||||
|
locator<NavigatorService>().pop(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.check,
|
Icons.check,
|
||||||
color: whiteColor,
|
color: whiteColor,
|
||||||
|
|
@ -146,8 +170,7 @@ class _BuyEditViewState extends State<BuyEditView> {
|
||||||
_pagingController.refresh();
|
_pagingController.refresh();
|
||||||
} else {
|
} else {
|
||||||
_dialogService.showDialog(
|
_dialogService.showDialog(
|
||||||
description:
|
description: 'Товара отсутсвует в остатке или ранее не'
|
||||||
'Товара отсутсвует в остатке или ранее не'
|
|
||||||
' использователся в системе',
|
' использователся в системе',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -168,8 +191,25 @@ class _BuyEditViewState extends State<BuyEditView> {
|
||||||
final dynamic result = await _nav.push(addByBarcodeViewRoute);
|
final dynamic result = await _nav.push(addByBarcodeViewRoute);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
final List<Good> goods = await locator<DictionaryService>()
|
final List<Good> goods = await locator<DictionaryService>()
|
||||||
.getGoodsByNameOrEan(result as String);
|
.getGoodsByNameOrEan(result as String, onlyEan: true);
|
||||||
if (goods.isNotEmpty) {}
|
if (goods.isNotEmpty) {
|
||||||
|
final Good good = goods.first;
|
||||||
|
bool result = await _service.addItem(
|
||||||
|
widget.invoice.id, good.id!);
|
||||||
|
if (result) {
|
||||||
|
_pagingController.refresh();
|
||||||
|
} else {
|
||||||
|
_dialogService.showDialog(
|
||||||
|
description: 'Товара отсутсвует в остатке или ранее не'
|
||||||
|
' использователся в системе',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_dialogService.showDialog(
|
||||||
|
description: 'Товара отсутсвует в остатке или ранее не'
|
||||||
|
' использователся в системе',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Icon(Icons.qr_code_rounded, size: 30, color: whiteColor),
|
child: Icon(Icons.qr_code_rounded, size: 30, color: whiteColor),
|
||||||
|
|
@ -191,16 +231,21 @@ class _BuyEditViewState extends State<BuyEditView> {
|
||||||
final nextPageKey = pageKey + 1;
|
final nextPageKey = pageKey + 1;
|
||||||
_pagingController.appendPage(newItems, nextPageKey);
|
_pagingController.appendPage(newItems, nextPageKey);
|
||||||
}
|
}
|
||||||
|
if ((_pagingController.value.itemList ?? []).isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
itemsExist = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _editData(int id, double price, double count) {
|
void _editData(int id, double price, double count) {
|
||||||
final List<BuyItemResponse> oldList =
|
final List<BuyItemResponse> oldList =
|
||||||
_pagingController.value.itemList ?? [];
|
_pagingController.value.itemList ?? [];
|
||||||
oldList..firstWhere((element) => element.id == id).price = price
|
oldList
|
||||||
|
..firstWhere((element) => element.id == id).price = price
|
||||||
..firstWhere((element) => element.id == id).cnt = count;
|
..firstWhere((element) => element.id == id).cnt = count;
|
||||||
setState(() {
|
setState(() {
|
||||||
_pagingController.itemList = oldList;
|
_pagingController.itemList = oldList;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,6 @@ class BuyView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BuyViewState extends State<BuyView> {
|
class _BuyViewState extends State<BuyView> {
|
||||||
|
|
||||||
|
|
||||||
final BuyService _service = locator<BuyService>();
|
final BuyService _service = locator<BuyService>();
|
||||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
|
||||||
|
|
@ -43,7 +41,6 @@ class _BuyViewState extends State<BuyView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
|
||||||
_pagingController.dispose();
|
_pagingController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
@ -68,8 +65,8 @@ class _BuyViewState extends State<BuyView> {
|
||||||
},
|
},
|
||||||
pagingController: _pagingController,
|
pagingController: _pagingController,
|
||||||
builderDelegate: PagedChildBuilderDelegate<BuyInvoiceResponse>(
|
builderDelegate: PagedChildBuilderDelegate<BuyInvoiceResponse>(
|
||||||
itemBuilder: (BuildContext context, BuyInvoiceResponse item,
|
itemBuilder:
|
||||||
int index) {
|
(BuildContext context, BuyInvoiceResponse item, int index) {
|
||||||
return DictionaryTile(
|
return DictionaryTile(
|
||||||
key: Key('category_${item.id}'),
|
key: Key('category_${item.id}'),
|
||||||
onPress: () async {
|
onPress: () async {
|
||||||
|
|
@ -88,24 +85,36 @@ class _BuyViewState extends State<BuyView> {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'${item.eaccContragentId.toString()}',
|
'${item.name}',
|
||||||
style: textBlack12Style,
|
style: textBlack12Style,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 5.0,
|
height: 5.0,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'Статус: ${item.refBuyInvoiceStatusId.toString()}',
|
'Номер: ${item.docNumber.toString()}',
|
||||||
style: textGray11Style,
|
style: textGray11Style,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: Text(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
'${formatterDay.format(item.invoiceDate)}',
|
'${formatterDay.format(item.invoiceDate)}',
|
||||||
style: textBlack12Style,
|
style: textBlack12Style,
|
||||||
),
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 5.0,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Статус: ${item.refBuyInvoiceStatusId == 1 ? 'Новая' : 'Обработана'}',
|
||||||
|
style: textGray11Style,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
|
@ -127,12 +136,22 @@ class _BuyViewState extends State<BuyView> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final dynamic result = await _navigatorService.push(buyAddRoute);
|
||||||
|
if (result != null && true == (result as bool)) {
|
||||||
|
_pagingController.refresh();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mini: true,
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _fetchData(int pageKey, int perPage) async {
|
Future<void> _fetchData(int pageKey, int perPage) async {
|
||||||
final List<BuyInvoiceResponse> newItems = await _service
|
final List<BuyInvoiceResponse> newItems =
|
||||||
.getList(page: pageKey, perpage: perPage);
|
await _service.getList(page: pageKey, perpage: perPage);
|
||||||
final isLastPage = newItems.length < _pageSize;
|
final isLastPage = newItems.length < _pageSize;
|
||||||
if (isLastPage) {
|
if (isLastPage) {
|
||||||
_pagingController.appendLastPage(newItems);
|
_pagingController.appendLastPage(newItems);
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
import 'package:satu/core/models/dialog_models.dart';
|
import 'package:satu/core/models/dialog_models.dart';
|
||||||
import 'package:satu/core/redux/actions/sell_actions.dart';
|
|
||||||
import 'package:satu/core/redux/store.dart';
|
|
||||||
import 'package:satu/core/services/buy_service.dart';
|
import 'package:satu/core/services/buy_service.dart';
|
||||||
import 'package:satu/core/services/dialog_service.dart';
|
import 'package:satu/core/services/dialog_service.dart';
|
||||||
import 'package:satu/core/utils/locator.dart';
|
import 'package:satu/core/utils/locator.dart';
|
||||||
import 'package:satu/core/utils/utils_parse.dart';
|
import 'package:satu/core/utils/utils_parse.dart';
|
||||||
import 'package:satu/shared/app_colors.dart';
|
import 'package:satu/shared/app_colors.dart';
|
||||||
import 'package:satu/shared/shared_styles.dart';
|
|
||||||
import 'package:satu/views/work/views/add_by_barcode/add_by_barcode_view.dart';
|
|
||||||
import 'package:satu/widgets/ui/product_title_widget.dart';
|
import 'package:satu/widgets/ui/product_title_widget.dart';
|
||||||
|
|
||||||
class ProductBuyTile extends StatefulWidget {
|
class ProductBuyTile extends StatefulWidget {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:satu/core/models/dictionary/contragent/contragent_response_entity.dart';
|
||||||
|
import 'package:satu/core/redux/actions/user_actions.dart';
|
||||||
|
import 'package:satu/core/redux/store.dart';
|
||||||
import 'package:satu/core/services/navigator_service.dart';
|
import 'package:satu/core/services/navigator_service.dart';
|
||||||
import 'package:satu/core/utils/locator.dart';
|
import 'package:satu/core/utils/locator.dart';
|
||||||
import 'package:satu/routes/route_names.dart';
|
import 'package:satu/routes/route_names.dart';
|
||||||
import 'package:satu/shared/app_colors.dart';
|
import 'package:satu/shared/app_colors.dart';
|
||||||
|
|
||||||
class ContragentSelectBar extends StatelessWidget {
|
class ContragentSelectBar extends StatelessWidget {
|
||||||
|
|
||||||
const ContragentSelectBar({required this.value, Key? key}) : super(key: key);
|
const ContragentSelectBar({required this.value, Key? key}) : super(key: key);
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
|
|
@ -17,11 +19,16 @@ class ContragentSelectBar extends StatelessWidget {
|
||||||
child: Material(
|
child: Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
locator<NavigatorService>().push(contragentSelectViewRoute);
|
ContragentResponseEntity? entity =
|
||||||
|
await locator<NavigatorService>()
|
||||||
|
.push(contragentSelectViewRoute) as ContragentResponseEntity?;
|
||||||
|
if (entity != null) {
|
||||||
|
Redux.store?.dispatch(setDefaultContragent(entity));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.symmetric(vertical:08.w, horizontal: 15.w),
|
padding: EdgeInsets.symmetric(vertical: 08.w, horizontal: 15.w),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,10 @@ import 'package:satu/core/utils/locator.dart';
|
||||||
import 'package:satu/core/utils/utils_parse.dart';
|
import 'package:satu/core/utils/utils_parse.dart';
|
||||||
import 'package:satu/shared/app_colors.dart';
|
import 'package:satu/shared/app_colors.dart';
|
||||||
import 'package:satu/shared/shared_styles.dart';
|
import 'package:satu/shared/shared_styles.dart';
|
||||||
import 'package:satu/views/work/views/add_by_barcode/add_by_barcode_view.dart';
|
|
||||||
import 'package:satu/widgets/ui/product_title_widget.dart';
|
import 'package:satu/widgets/ui/product_title_widget.dart';
|
||||||
|
|
||||||
|
import '../../../views/select_by_scan/add_by_barcode_view.dart';
|
||||||
|
|
||||||
|
|
||||||
class ProductSellTile extends StatefulWidget {
|
class ProductSellTile extends StatefulWidget {
|
||||||
const ProductSellTile(
|
const ProductSellTile(
|
||||||
|
|
@ -42,7 +43,7 @@ class _ProductSellTileState extends State<ProductSellTile> {
|
||||||
|
|
||||||
void _onItemTapped(BuildContext context) {
|
void _onItemTapped(BuildContext context) {
|
||||||
Navigator.of(context).push(MaterialPageRoute(
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
builder: (BuildContext context) => const AddByBarcodeView()));
|
builder: (BuildContext context) => const SelectByScanView()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:redux/src/store.dart';
|
import 'package:redux/src/store.dart';
|
||||||
import 'package:satu/core/models/flow/dao/product_dao.dart';
|
import 'package:satu/core/models/flow/dao/product_dao.dart';
|
||||||
import 'package:satu/core/redux/state/sell_state.dart';
|
import 'package:satu/core/redux/state/sell_state.dart';
|
||||||
|
import 'package:satu/core/redux/state/user_state.dart';
|
||||||
import 'package:satu/core/redux/store.dart';
|
import 'package:satu/core/redux/store.dart';
|
||||||
import 'package:satu/core/services/navigator_service.dart';
|
import 'package:satu/core/services/navigator_service.dart';
|
||||||
import 'package:satu/core/utils/locator.dart';
|
import 'package:satu/core/utils/locator.dart';
|
||||||
|
|
@ -40,9 +41,14 @@ class SellView extends StatelessWidget {
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
const ContragentSelectBar(
|
StoreConnector<AppState, UserState>(
|
||||||
value: 'Частное лицо',
|
converter: (store) => store.state.userState!,
|
||||||
),
|
builder: (_, uState) {
|
||||||
|
return ContragentSelectBar(
|
||||||
|
value: (uState.defaultContragent?.name ??
|
||||||
|
'Выберите контрагента'),
|
||||||
|
);
|
||||||
|
}),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
|
|
@ -120,11 +126,11 @@ class SellView extends StatelessWidget {
|
||||||
elevation: 2,
|
elevation: 2,
|
||||||
mini: true,
|
mini: true,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final Good? good = await locator<NavigatorService>().push(addProductViewRoute) as Good?;
|
final Good? good = await locator<NavigatorService>()
|
||||||
if(good !=null) {
|
.push(addProductViewRoute) as Good?;
|
||||||
|
if (good != null) {
|
||||||
Redux.store!.dispatch(addSellItem(good: good));
|
Redux.store!.dispatch(addSellItem(good: good));
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.add_rounded,
|
Icons.add_rounded,
|
||||||
|
|
@ -144,7 +150,7 @@ class SellView extends StatelessWidget {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
final List<Good> goods =
|
final List<Good> goods =
|
||||||
await locator<DictionaryService>()
|
await locator<DictionaryService>()
|
||||||
.getGoodsByNameOrEan(result as String);
|
.getGoodsByNameOrEan(result as String, onlyEan: true);
|
||||||
if (goods.isNotEmpty) {
|
if (goods.isNotEmpty) {
|
||||||
Redux.store
|
Redux.store
|
||||||
?.dispatch(addSellItem(good: goods.first));
|
?.dispatch(addSellItem(good: goods.first));
|
||||||
|
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:satu/core/entity/category_entity.dart';
|
|
||||||
import 'package:satu/core/entity/goods_entity.dart';
|
|
||||||
import 'package:satu/core/services/dictionary_service.dart';
|
|
||||||
import 'package:satu/core/utils/locator.dart';
|
|
||||||
import 'package:satu/shared/app_colors.dart';
|
|
||||||
import 'package:satu/shared/ui_helpers.dart';
|
|
||||||
import 'package:satu/widgets/bar/products_app_bar.dart';
|
|
||||||
import 'package:satu/widgets/bar/products_title_bar.dart';
|
|
||||||
import 'package:satu/widgets/fields/input_field.dart';
|
|
||||||
|
|
||||||
import 'companent/contragent_list_item.dart';
|
|
||||||
|
|
||||||
class SelectContragentView extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_SelectContragentViewState createState() => _SelectContragentViewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SelectContragentViewState extends State<SelectContragentView> {
|
|
||||||
final DictionaryService _dictionaryService = locator<DictionaryService>();
|
|
||||||
late TextEditingController _searchTextController;
|
|
||||||
final FocusNode _searchFocusNode = new FocusNode();
|
|
||||||
|
|
||||||
final List<Category> _contragents = [];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_searchTextController = TextEditingController();
|
|
||||||
_searchTextController.addListener(() {
|
|
||||||
if (_searchTextController.text.isNotEmpty) {
|
|
||||||
searchByField(_searchTextController.text);
|
|
||||||
} else {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_searchTextController.dispose();
|
|
||||||
_searchFocusNode.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: const ProductsAppBar(
|
|
||||||
title: 'Контрагент',
|
|
||||||
),
|
|
||||||
body: Column(
|
|
||||||
children: [
|
|
||||||
InputField(
|
|
||||||
placeholder: 'Поиск по наименованию или коду товара',
|
|
||||||
search: true,
|
|
||||||
controller: _searchTextController,
|
|
||||||
fieldFocusNode: _searchFocusNode,
|
|
||||||
),
|
|
||||||
verticalSpaceTiny,
|
|
||||||
const ProductsTitleBarBar(
|
|
||||||
title: 'Выберите контрагента',
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: ListView.separated(
|
|
||||||
physics: const BouncingScrollPhysics(),
|
|
||||||
itemCount: _contragents.length,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
final Category category = _contragents[index];
|
|
||||||
return ContragentListItem(
|
|
||||||
name: category.name,
|
|
||||||
key: Key('category_${category.id}'),
|
|
||||||
onPress: () => () {},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
separatorBuilder: (BuildContext context, int index) {
|
|
||||||
return const Divider(
|
|
||||||
height: 1.0,
|
|
||||||
color: disableColor,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
_searchTextController.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void searchByField(String query) async {
|
|
||||||
|
|
||||||
List<Good> goods = await _dictionaryService.getGoodsByNameOrEan(query);
|
|
||||||
setState(() {
|
|
||||||
goods;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,17 +5,17 @@ import 'package:satu/core/utils/locator.dart';
|
||||||
import 'package:satu/widgets/bar/products_app_bar.dart';
|
import 'package:satu/widgets/bar/products_app_bar.dart';
|
||||||
import 'package:satu/widgets/tools/app_barcode_scanner_widget.dart';
|
import 'package:satu/widgets/tools/app_barcode_scanner_widget.dart';
|
||||||
|
|
||||||
class AddByBarcodeView extends StatefulWidget {
|
class SelectByScanView extends StatefulWidget {
|
||||||
|
|
||||||
const AddByBarcodeView({
|
const SelectByScanView({
|
||||||
Key? key
|
Key? key
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_AddByBarcodeViewState createState() => _AddByBarcodeViewState();
|
_SelectByScanViewState createState() => _SelectByScanViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AddByBarcodeViewState extends State<AddByBarcodeView> {
|
class _SelectByScanViewState extends State<SelectByScanView> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
|
import 'package:satu/core/entity/category_entity.dart';
|
||||||
|
import 'package:satu/core/entity/goods_entity.dart';
|
||||||
|
import 'package:satu/core/services/dictionary_service.dart';
|
||||||
|
import 'package:satu/core/utils/locator.dart';
|
||||||
|
import 'package:satu/shared/app_colors.dart';
|
||||||
|
import 'package:satu/shared/ui_helpers.dart';
|
||||||
|
import 'package:satu/widgets/bar/products_app_bar.dart';
|
||||||
|
import 'package:satu/widgets/bar/products_title_bar.dart';
|
||||||
|
import 'package:satu/widgets/fields/input_field.dart';
|
||||||
|
|
||||||
|
import '../../../../core/models/dictionary/contragent/contragent_response_entity.dart';
|
||||||
|
import '../../../../core/services/navigator_service.dart';
|
||||||
|
import '../../../dictionaries/component/dictionary_list_tile.dart';
|
||||||
|
import 'companent/contragent_list_item.dart';
|
||||||
|
|
||||||
|
class SelectContragentView extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_SelectContragentViewState createState() => _SelectContragentViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SelectContragentViewState extends State<SelectContragentView> {
|
||||||
|
final DictionaryService _dictionaryService = locator<DictionaryService>();
|
||||||
|
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
late TextEditingController _searchTextController;
|
||||||
|
final FocusNode _searchFocusNode = FocusNode();
|
||||||
|
|
||||||
|
late List<ContragentResponseEntity> items = [];
|
||||||
|
static const _pageSize = 20;
|
||||||
|
|
||||||
|
final PagingController<int, ContragentResponseEntity> _pagingController =
|
||||||
|
PagingController(firstPageKey: 0);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_searchTextController = TextEditingController();
|
||||||
|
_searchTextController.addListener(() {
|
||||||
|
if (_searchTextController.text.isNotEmpty) {
|
||||||
|
//searchByField(_searchTextController.text);
|
||||||
|
} else {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_pagingController.addPageRequestListener((pageKey) {
|
||||||
|
_fetchData(pageKey, _pageSize, null);
|
||||||
|
});
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> initQuery() async {
|
||||||
|
//searchByField('');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_searchTextController.dispose();
|
||||||
|
_searchFocusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: ProductsAppBar(
|
||||||
|
title: 'Контрагенты',
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
InputField(
|
||||||
|
placeholder: 'Поиск по наименованию',
|
||||||
|
search: true,
|
||||||
|
controller: _searchTextController,
|
||||||
|
fieldFocusNode: _searchFocusNode,
|
||||||
|
),
|
||||||
|
const ProductsTitleBarBar(title: 'Список контрагентов'),
|
||||||
|
Expanded(
|
||||||
|
child: PagedListView<int, ContragentResponseEntity>(
|
||||||
|
pagingController: _pagingController,
|
||||||
|
builderDelegate:
|
||||||
|
PagedChildBuilderDelegate<ContragentResponseEntity>(
|
||||||
|
itemBuilder: (BuildContext context,
|
||||||
|
ContragentResponseEntity entity, int index) {
|
||||||
|
return DictionaryTile(
|
||||||
|
key: Key('contragent_${entity.id}'),
|
||||||
|
onPress: () async {
|
||||||
|
_navigatorService.pop(entity);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
entity.name ?? '',
|
||||||
|
style: const TextStyle(fontSize: 12, color: textColor),
|
||||||
|
),
|
||||||
|
Text('БИН/ИИН: ${entity.biniin}',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 10, color: placeholderColor)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
_searchTextController.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _fetchData(int pageKey, int perPage, String? query) async {
|
||||||
|
final List<ContragentResponseEntity> newItems = await _dictionaryService
|
||||||
|
.getContragents(page: pageKey, query: query, perpage: perPage);
|
||||||
|
|
||||||
|
final isLastPage = newItems.length < _pageSize;
|
||||||
|
if (isLastPage) {
|
||||||
|
_pagingController.appendLastPage(newItems);
|
||||||
|
} else {
|
||||||
|
final nextPageKey = pageKey + newItems.length;
|
||||||
|
_pagingController.appendPage(newItems, nextPageKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,12 +15,12 @@ import 'package:satu/widgets/fields/input_field.dart';
|
||||||
import '../../../../core/models/dictionary/good/good_response_entity.dart';
|
import '../../../../core/models/dictionary/good/good_response_entity.dart';
|
||||||
import 'component/add_product_list_item.dart';
|
import 'component/add_product_list_item.dart';
|
||||||
|
|
||||||
class AddProductView extends StatefulWidget {
|
class SelectProductView extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
_AddProductViewState createState() => _AddProductViewState();
|
_SelectProductViewState createState() => _SelectProductViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AddProductViewState extends State<AddProductView> {
|
class _SelectProductViewState extends State<SelectProductView> {
|
||||||
final DictionaryService _dictionaryService = locator<DictionaryService>();
|
final DictionaryService _dictionaryService = locator<DictionaryService>();
|
||||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
late TextEditingController _searchTextController;
|
late TextEditingController _searchTextController;
|
||||||
|
|
@ -121,8 +121,12 @@ class _AddProductViewState extends State<AddProductView> {
|
||||||
Future<void> _fetchData(int pageKey, int perPage, String? query) async {
|
Future<void> _fetchData(int pageKey, int perPage, String? query) async {
|
||||||
final List<GoodResponseEntity> newItems = await _dictionaryService.getGoods(
|
final List<GoodResponseEntity> newItems = await _dictionaryService.getGoods(
|
||||||
page: pageKey,
|
page: pageKey,
|
||||||
filter: {'col': 'name', 'action': 'like', 'val': query ?? ''},
|
filter: [{'col': 'name', 'action': 'like', 'val': query ?? ''}, {
|
||||||
perpage: perPage);
|
'col': 'ean13',
|
||||||
|
'action': 'like',
|
||||||
|
'val': query ?? ''
|
||||||
|
}],
|
||||||
|
perpage: perPage, orGate: true);
|
||||||
|
|
||||||
List<Good> items = newItems.map((e) => goodResponseToGood(e)).toList();
|
List<Good> items = newItems.map((e) => goodResponseToGood(e)).toList();
|
||||||
final isLastPage = newItems.length < _pageSize;
|
final isLastPage = newItems.length < _pageSize;
|
||||||
|
|
@ -14,6 +14,7 @@ import 'package:satu/views/dictionaries/category/category_view.dart';
|
||||||
import 'package:satu/views/dictionaries/contragents/contragents_view.dart';
|
import 'package:satu/views/dictionaries/contragents/contragents_view.dart';
|
||||||
import 'package:satu/views/dictionaries/goods/goods_view.dart';
|
import 'package:satu/views/dictionaries/goods/goods_view.dart';
|
||||||
import 'package:satu/views/settings/setting_view.dart';
|
import 'package:satu/views/settings/setting_view.dart';
|
||||||
|
import 'package:satu/views/stocks/stocks_view.dart';
|
||||||
import 'package:satu/views/work/work_view.dart';
|
import 'package:satu/views/work/work_view.dart';
|
||||||
|
|
||||||
import '../../views/inventarization/view/inventarization_view.dart';
|
import '../../views/inventarization/view/inventarization_view.dart';
|
||||||
|
|
@ -50,9 +51,8 @@ class AppDrawer extends StatelessWidget {
|
||||||
text: 'Остатки',
|
text: 'Остатки',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Redux.store!.dispatch(navigateDrawer(AnalyticsView));
|
Redux.store!.dispatch(navigateDrawer(StocksView));
|
||||||
},
|
}
|
||||||
disable: true,
|
|
||||||
),
|
),
|
||||||
_createDrawerItem(
|
_createDrawerItem(
|
||||||
svgFile: 'inventarization',
|
svgFile: 'inventarization',
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import 'note_text.dart';
|
||||||
|
|
||||||
class LineTile extends StatelessWidget {
|
class LineTile extends StatelessWidget {
|
||||||
const LineTile(this.text,
|
const LineTile(this.text,
|
||||||
{required this.onTap, this.labelText, this.placeholder = 'Выберите'});
|
{required this.onTap, this.labelText, this.placeholder = 'Выберите', Key? key}) : super(key: key);
|
||||||
|
|
||||||
final String text;
|
final String text;
|
||||||
final String placeholder;
|
final String placeholder;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.0.0+1
|
version: 1.0.1+2
|
||||||
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue