Инвентаризация ++
parent
94db86ee66
commit
e461fb5662
|
|
@ -0,0 +1,38 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'good_item.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GoodInventarization {
|
||||
GoodInventarization({
|
||||
required this.id,
|
||||
required this.eaccGoodId,
|
||||
required this.name,
|
||||
required this.cnt,
|
||||
required this.price,
|
||||
required this.cntBuh,
|
||||
required this.priceBuh,
|
||||
this.articul,
|
||||
this.category,
|
||||
this.ean13,
|
||||
});
|
||||
|
||||
int id;
|
||||
@JsonKey(name: 'eacc_good_id')
|
||||
int eaccGoodId;
|
||||
double cnt;
|
||||
double price;
|
||||
@JsonKey(name: 'cnt_buh')
|
||||
double cntBuh;
|
||||
@JsonKey(name: 'price_buh')
|
||||
double priceBuh;
|
||||
String name;
|
||||
int? articul;
|
||||
String? ean13;
|
||||
String? category;
|
||||
|
||||
factory GoodInventarization.fromJson(Map<String, dynamic> json) =>
|
||||
_$GoodInventarizationFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$GoodInventarizationToJson(this);
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'good_item.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GoodInventarization _$GoodInventarizationFromJson(Map<String, dynamic> json) =>
|
||||
GoodInventarization(
|
||||
id: json['id'] as int,
|
||||
eaccGoodId: json['eacc_good_id'] as int,
|
||||
name: json['name'] as String,
|
||||
cnt: (json['cnt'] as num).toDouble(),
|
||||
price: (json['price'] as num).toDouble(),
|
||||
cntBuh: (json['cnt_buh'] as num).toDouble(),
|
||||
priceBuh: (json['price_buh'] as num).toDouble(),
|
||||
articul: json['articul'] as int?,
|
||||
category: json['category'] as String?,
|
||||
ean13: json['ean13'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GoodInventarizationToJson(
|
||||
GoodInventarization instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'eacc_good_id': instance.eaccGoodId,
|
||||
'cnt': instance.cnt,
|
||||
'price': instance.price,
|
||||
'cnt_buh': instance.cntBuh,
|
||||
'price_buh': instance.priceBuh,
|
||||
'name': instance.name,
|
||||
'articul': instance.articul,
|
||||
'ean13': instance.ean13,
|
||||
'category': instance.category,
|
||||
};
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:satu/core/models/inventarization/good_item/good_item.dart';
|
||||
|
||||
part 'invetarization_good_list.g.dart';
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class InventarizationGoodList {
|
||||
InventarizationGoodList({
|
||||
required this.goodsList
|
||||
});
|
||||
|
||||
@JsonKey(name: 'goods_list')
|
||||
List<GoodInventarization> goodsList;
|
||||
|
||||
factory InventarizationGoodList.fromJson(Map<String, dynamic> json) => _$InventarizationGoodListFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$InventarizationGoodListToJson(this);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'invetarization_good_list.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
InventarizationGoodList _$InventarizationGoodListFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
InventarizationGoodList(
|
||||
goodsList: (json['goods_list'] as List<dynamic>)
|
||||
.map((e) => GoodInventarization.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$InventarizationGoodListToJson(
|
||||
InventarizationGoodList instance) =>
|
||||
<String, dynamic>{
|
||||
'goods_list': instance.goodsList.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
|
|
@ -48,6 +48,7 @@ class ResponseOriginal {
|
|||
int? page;
|
||||
int? perpage;
|
||||
List<dynamic>? data;
|
||||
dynamic result;
|
||||
Map<String, List<String>>? errors;
|
||||
String? message;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ ResponseOriginal _$ResponseOriginalFromJson(Map<String, dynamic> json) =>
|
|||
..page = json['page'] as int?
|
||||
..perpage = json['perpage'] as int?
|
||||
..data = json['data'] as List<dynamic>?
|
||||
..result = json['result']
|
||||
..errors = (json['errors'] as Map<String, dynamic>?)?.map(
|
||||
(k, e) =>
|
||||
MapEntry(k, (e as List<dynamic>).map((e) => e as String).toList()),
|
||||
|
|
@ -45,6 +46,7 @@ Map<String, dynamic> _$ResponseOriginalToJson(ResponseOriginal instance) =>
|
|||
'page': instance.page,
|
||||
'perpage': instance.perpage,
|
||||
'data': instance.data,
|
||||
'result': instance.result,
|
||||
'errors': instance.errors,
|
||||
'message': instance.message,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ class ApiService extends BaseService {
|
|||
// log.i(host);
|
||||
// log.i(url);
|
||||
// log.i(headers);
|
||||
log.i(jsonEncode(requestBody));
|
||||
log.i(jsonEncode(response.body));
|
||||
//log.i(jsonEncode(requestBody));
|
||||
//log.i(jsonEncode(response.body));
|
||||
}
|
||||
return response.body;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ class DialogService {
|
|||
|
||||
Future<DialogResponse> showConfirmationDialogInput({
|
||||
required String title,
|
||||
required String requestPrice,
|
||||
required String requestCount,
|
||||
String? requestPrice,
|
||||
String? description,
|
||||
String confirmationTitle = 'ПОДТВЕРДИТЬ',
|
||||
String cancelTitle = 'Отмена',
|
||||
|
|
|
|||
|
|
@ -11,11 +11,7 @@ import 'package:satu/core/utils/locator.dart';
|
|||
import 'api_service.dart';
|
||||
import 'db_service.dart';
|
||||
|
||||
class DictionaryService extends BaseService {
|
||||
final ApiService _api = locator<ApiService>();
|
||||
final DbService _db = locator<DbService>();
|
||||
|
||||
Good goodResponseToGood(GoodResponseEntity response) {
|
||||
Good goodResponseToGood(GoodResponseEntity response) {
|
||||
return Good()
|
||||
..id = response.id
|
||||
..name = response.name
|
||||
|
|
@ -28,7 +24,13 @@ class DictionaryService extends BaseService {
|
|||
..divisible = response.divisible
|
||||
..ean = response.ean13
|
||||
..appCompanyId = response.appCompanyId;
|
||||
}
|
||||
}
|
||||
|
||||
class DictionaryService extends BaseService {
|
||||
final ApiService _api = locator<ApiService>();
|
||||
final DbService _db = locator<DbService>();
|
||||
|
||||
|
||||
|
||||
Category categoryResponseToCategory(CategoryResponse response) {
|
||||
return Category()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import 'package:satu/core/base/base_service.dart';
|
||||
import 'package:satu/core/models/inventarization/inventarization_response.dart';
|
||||
import 'package:satu/core/models/inventarization/invetarization_good_list/invetarization_good_list.dart';
|
||||
import 'package:satu/core/models/inventarization/response/inventarization_response.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
|
||||
import '../models/inventarization/good_item/good_item.dart';
|
||||
import '../models/response/response_entity.dart';
|
||||
import 'api_service.dart';
|
||||
|
||||
|
|
@ -17,12 +19,13 @@ class InventarizationService extends BaseService {
|
|||
'perpage': perpage
|
||||
};
|
||||
|
||||
ResponseEntity categories = await _api
|
||||
.postRequest('/goods_inventory_get', requestBody: requestBody);
|
||||
ResponseEntity categories = await _api.postRequest('/goods_inventory_get',
|
||||
requestBody: requestBody);
|
||||
if (categories.original.data != null &&
|
||||
categories.original.data!.isNotEmpty) {
|
||||
for (final dynamic map in categories.original.data!) {
|
||||
final InventarizationResponse item = InventarizationResponse.fromJson(map);
|
||||
final InventarizationResponse item =
|
||||
InventarizationResponse.fromJson(map);
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -32,4 +35,63 @@ class InventarizationService extends BaseService {
|
|||
return list;
|
||||
}
|
||||
|
||||
Future<List<GoodInventarization>> getGoodByInventarizationId(
|
||||
{required int page, required int perpage, required int id}) async {
|
||||
List<GoodInventarization> list = [];
|
||||
try {
|
||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||
'page': page,
|
||||
'perpage': perpage,
|
||||
'id': id
|
||||
};
|
||||
|
||||
ResponseEntity categories = await _api.postRequest(
|
||||
'/goods_inventory_get_edit_form_data',
|
||||
requestBody: requestBody);
|
||||
if (categories.original.result != null) {
|
||||
InventarizationGoodList listResponse = InventarizationGoodList.fromJson(categories.original.result);
|
||||
list.addAll(listResponse.goodsList);
|
||||
}
|
||||
} catch (e, stack) {
|
||||
log.e('getList', e, stack);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Future<bool> addGoodToList(int inventoryId, int? goodId) async {
|
||||
bool result = false;
|
||||
try {
|
||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||
'page': 1,
|
||||
'perpage': 1,
|
||||
'id': inventoryId,
|
||||
'good_id' : goodId
|
||||
};
|
||||
ResponseEntity response = await _api.postRequest(
|
||||
'/goods_inventory_select_item',
|
||||
requestBody: requestBody);
|
||||
result = response.original.result != null;
|
||||
} catch (e, stack) {
|
||||
log.e('getList', e, stack);
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
|
||||
Future<bool> setCountToItem(int inventoryId, int inventoryItemId, double value) async {
|
||||
bool result = false;
|
||||
try {
|
||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||
'id': inventoryId,
|
||||
'inventory_item_id' : inventoryItemId,
|
||||
'cnt_buh': value
|
||||
};
|
||||
ResponseEntity response = await _api.postRequest(
|
||||
'/goods_inventory_set_cnt_item',
|
||||
requestBody: requestBody);
|
||||
result = response.original.result != null;
|
||||
} catch (e, stack) {
|
||||
log.e('getList', e, stack);
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,9 @@ const String goodsDictionaryViewRoute = 'goodsDictionaryViewRoute';
|
|||
const String contragentSelectViewRoute = 'ContragentSelectViewRoute';
|
||||
const String contragentEditRoute = 'contragentEditRoute';
|
||||
|
||||
// inventarization
|
||||
const String inventarizationEditRoute = 'inventarizationEditRoute';
|
||||
|
||||
// setting - ble printer
|
||||
const String settingPrinterBluetoothViewRoute = 'SettingPrinterBluetoothView';
|
||||
const String settingPrinterBluetoothSelectViewRoute =
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import 'package:satu/views/dictionaries/category/category_edit.dart';
|
|||
import 'package:satu/views/dictionaries/category/category_select_view.dart';
|
||||
import 'package:satu/views/dictionaries/contragents/contragents_edit.dart';
|
||||
import 'package:satu/views/dictionaries/goods/goods_edit.dart';
|
||||
import 'package:satu/views/inventarization/view/inventarization_edit_view.dart';
|
||||
import 'package:satu/views/login/login_view.dart';
|
||||
import 'package:satu/views/main/main_view.dart';
|
||||
import 'package:satu/views/settings/printer_bluetooth/printer_encoding_select.dart';
|
||||
|
|
@ -19,6 +20,7 @@ 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/work_view.dart';
|
||||
|
||||
import '../core/models/inventarization/response/inventarization_response.dart';
|
||||
import './route_names.dart';
|
||||
|
||||
Route<dynamic> generateRoute(RouteSettings settings) {
|
||||
|
|
@ -117,6 +119,14 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
|||
transactionId: data,
|
||||
),
|
||||
);
|
||||
case inventarizationEditRoute:
|
||||
final InventarizationResponse inventarizationResponse = settings.arguments! as InventarizationResponse;
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: InventarizationEditView(
|
||||
item: inventarizationResponse,
|
||||
),
|
||||
);
|
||||
default:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => Scaffold(
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ class _GoodsDictionaryViewState extends State<GoodsDictionaryView> {
|
|||
itemBuilder:
|
||||
(BuildContext context, GoodResponseEntity good, int index) {
|
||||
return DictionaryTile(
|
||||
key: Key('good_${good.id}'),
|
||||
onPress: () async {
|
||||
final dynamic result = await _navigatorService
|
||||
.push(goodsEditRoute, arguments: good);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,241 @@
|
|||
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/services/dialog_service.dart';
|
||||
import 'package:satu/views/inventarization/widget/good_inventarization_list_item.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';
|
||||
|
||||
class InventarizationEditView extends StatefulWidget {
|
||||
const InventarizationEditView({
|
||||
required this.item,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
final InventarizationResponse item;
|
||||
|
||||
@override
|
||||
State<InventarizationEditView> createState() =>
|
||||
_InventarizationEditViewState();
|
||||
}
|
||||
|
||||
class _InventarizationEditViewState extends State<InventarizationEditView> {
|
||||
final InventarizationService _service = locator<InventarizationService>();
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
|
||||
static const _pageSize = 20;
|
||||
int _pageCurrent = 1;
|
||||
bool _isLastPage = false;
|
||||
|
||||
final PagingController<int, GoodInventarization> _pagingController =
|
||||
PagingController(firstPageKey: 1);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_pagingController.addPageRequestListener((pageKey) {
|
||||
_pageCurrent = pageKey;
|
||||
_fetchData(pageKey, _pageSize);
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
@override
|
||||
void dispose() {
|
||||
_pagingController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: const ProductsAppBar(
|
||||
title: 'Создание инвентаризации',
|
||||
drawerShow: false,
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
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, GoodInventarization>.separated(
|
||||
//physics: const BouncingScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1.0,
|
||||
color: disableColor,
|
||||
);
|
||||
},
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<GoodInventarization>(
|
||||
itemBuilder: (BuildContext context, GoodInventarization item,
|
||||
int index) {
|
||||
return GoodInventarizationListItem(
|
||||
key: Key(
|
||||
'good_inv_${item.id}',
|
||||
),
|
||||
inventoryId: widget.item.id,
|
||||
inventoryItemId: item.id,
|
||||
name: item.name,
|
||||
categoryName: item.category,
|
||||
count: item.cntBuh,
|
||||
price: item.priceBuh,
|
||||
ean: item.ean13,
|
||||
isOdd: index % 2 == 0,
|
||||
refresh: () {
|
||||
_refreshData(_pageCurrent, _pageSize);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||
floatingActionButton: floatingActionButtonRender(),
|
||||
);
|
||||
}
|
||||
|
||||
/// render floating buttons
|
||||
Widget floatingActionButtonRender() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.all(15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Visibility(
|
||||
visible: true,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: FloatingActionButton(
|
||||
mini: true,
|
||||
elevation: 2,
|
||||
backgroundColor: successColor,
|
||||
onPressed: () {},
|
||||
child: Icon(
|
||||
Icons.check,
|
||||
color: whiteColor,
|
||||
size: 35,
|
||||
),
|
||||
),
|
||||
)),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
FloatingActionButton(
|
||||
elevation: 2,
|
||||
mini: true,
|
||||
onPressed: () async {
|
||||
final Good? good = await locator<NavigatorService>()
|
||||
.push(addProductViewRoute) as Good?;
|
||||
if (good != null) {
|
||||
bool result =
|
||||
await _service.addGoodToList(widget.item.id, good.id);
|
||||
if (result) {
|
||||
_pagingController.refresh();
|
||||
} else {
|
||||
_dialogService.showDialog(
|
||||
description: 'Товара отсутсвует в остатке');
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Icon(
|
||||
Icons.add_rounded,
|
||||
size: 40,
|
||||
color: whiteColor,
|
||||
),
|
||||
),
|
||||
verticalSpaceSmall,
|
||||
FloatingActionButton(
|
||||
elevation: 2,
|
||||
mini: true,
|
||||
onPressed: () async {
|
||||
final NavigatorService _nav = locator<NavigatorService>();
|
||||
final dynamic result = await _nav.push(addByBarcodeViewRoute);
|
||||
if (result != null) {
|
||||
final List<Good> goods = await locator<DictionaryService>()
|
||||
.getGoodsByNameOrEan(result as String);
|
||||
if (goods.isNotEmpty) {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Icon(Icons.qr_code_rounded, size: 30, color: whiteColor),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _fetchData(int pageKey, int perPage) async {
|
||||
final List<GoodInventarization> newItems =
|
||||
await _service.getGoodByInventarizationId(
|
||||
page: pageKey, perpage: perPage, id: widget.item.id);
|
||||
_isLastPage = newItems.length < _pageSize;
|
||||
_pageCurrent = pageKey;
|
||||
if (_isLastPage) {
|
||||
_pagingController.appendLastPage(newItems);
|
||||
} else {
|
||||
final nextPageKey = pageKey + 1;
|
||||
_pageCurrent = nextPageKey;
|
||||
_pagingController.appendPage(newItems, nextPageKey);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _refreshData(int pageKey, int perPage) async {
|
||||
print('${pageKey} - ${perPage}');
|
||||
final List<GoodInventarization> newItems =
|
||||
await _service.getGoodByInventarizationId(
|
||||
page: pageKey, perpage: perPage, id: widget.item.id);
|
||||
final List<GoodInventarization> oldList = _pagingController.value.itemList ?? [];
|
||||
oldList.setAll((pageKey - 1) * perPage , newItems);
|
||||
setState(() {
|
||||
_pagingController.itemList = oldList;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,14 +1,18 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import 'package:satu/core/models/inventarization/inventarization_response.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:satu/core/models/inventarization/response/inventarization_response.dart';
|
||||
import 'package:satu/core/services/inventarization_service.dart';
|
||||
import 'package:satu/core/services/navigator_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
import 'package:satu/shared/app_colors.dart';
|
||||
import 'package:satu/shared/shared_styles.dart';
|
||||
import 'package:satu/shared/ui_helpers.dart';
|
||||
import 'package:satu/views/inventarization/widget/inventarization_list_tile.dart';
|
||||
|
||||
import '../../../routes/route_names.dart';
|
||||
import '../../../widgets/bar/products_app_bar.dart';
|
||||
import '../../dictionaries/component/dictionary_list_tile.dart';
|
||||
|
||||
class InventarizationView extends StatefulWidget {
|
||||
const InventarizationView({Key? key}) : super(key: key);
|
||||
|
|
@ -20,12 +24,15 @@ class InventarizationView extends StatefulWidget {
|
|||
class _InventarizationViewState extends State<InventarizationView> {
|
||||
|
||||
final InventarizationService _service = locator<InventarizationService>();
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
|
||||
static const _pageSize = 20;
|
||||
|
||||
final PagingController<int, InventarizationResponse> _pagingController =
|
||||
PagingController(firstPageKey: 1);
|
||||
|
||||
final DateFormat formatterDay = DateFormat('dd.MM.yyyy');
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_pagingController.addPageRequestListener((pageKey) {
|
||||
|
|
@ -89,16 +96,37 @@ class _InventarizationViewState extends State<InventarizationView> {
|
|||
builderDelegate: PagedChildBuilderDelegate<InventarizationResponse>(
|
||||
itemBuilder: (BuildContext context, InventarizationResponse item,
|
||||
int index) {
|
||||
return InventarizationListTile(
|
||||
return DictionaryTile(
|
||||
key: Key('category_${item.id}'),
|
||||
// onPress: () async {
|
||||
// final dynamic result = await _navigatorService
|
||||
// .push(categoryEditRoute, arguments: item);
|
||||
// if (result != null && true == (result as bool)) {
|
||||
// _pagingController.refresh();
|
||||
// }
|
||||
// },
|
||||
item: item,
|
||||
onPress: () async {
|
||||
final dynamic result = await _navigatorService
|
||||
.push(inventarizationEditRoute, arguments: item);
|
||||
if (result != null && true == (result as bool)) {
|
||||
_pagingController.refresh();
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: InventarizationCellTile(
|
||||
value: item.docNumber.toString()),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: InventarizationCellTile(
|
||||
value: formatterDay.format(item.createdAt),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: InventarizationCellButton(
|
||||
value: item.act,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,140 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.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/inventarization_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
import 'package:satu/core/utils/utils_parse.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';
|
||||
|
||||
class GoodInventarizationListItem extends StatefulWidget {
|
||||
const GoodInventarizationListItem({
|
||||
required Key key,
|
||||
required this.price,
|
||||
required this.count,
|
||||
required this.inventoryItemId,
|
||||
required this.inventoryId,
|
||||
required this.refresh,
|
||||
this.name = '',
|
||||
this.ean,
|
||||
this.categoryName,
|
||||
this.isOdd = true,
|
||||
this.transactionId,
|
||||
|
||||
}) : super(key: key);
|
||||
final int inventoryItemId;
|
||||
final int inventoryId;
|
||||
final String name;
|
||||
final String? ean;
|
||||
final String? categoryName;
|
||||
final double price;
|
||||
final double count;
|
||||
final bool isOdd;
|
||||
final int? transactionId;
|
||||
|
||||
final void Function() refresh;
|
||||
|
||||
@override
|
||||
_GoodInventarizationListItemState createState() =>
|
||||
_GoodInventarizationListItemState();
|
||||
}
|
||||
|
||||
class _GoodInventarizationListItemState
|
||||
extends State<GoodInventarizationListItem> {
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
final InventarizationService _service = locator<InventarizationService>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dismissible(
|
||||
background: Container(
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
color: dangerColor,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
'Удалить',
|
||||
style: TextStyle(color: whiteColor, fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
),
|
||||
direction: DismissDirection.endToStart,
|
||||
confirmDismiss: (DismissDirection direction) async {
|
||||
final DialogResponse response =
|
||||
await _dialogService.showConfirmationDialog(
|
||||
title: 'Внимание',
|
||||
description: 'Удалить из списка товар '
|
||||
'"${widget.name}"'
|
||||
' - ${widget.count} ед. ?',
|
||||
confirmationTitle: 'Удалить',
|
||||
cancelTitle: 'Отмена');
|
||||
|
||||
return response.confirmed;
|
||||
},
|
||||
onDismissed: (direction) {},
|
||||
key: widget.key!,
|
||||
child: ListTile(
|
||||
key: widget.key!,
|
||||
onTap: () {
|
||||
editProductModal();
|
||||
},
|
||||
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: !widget.isOdd ? whiteColor : whiteColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> editProductModal() async {
|
||||
final DialogResponse response =
|
||||
await _dialogService.showConfirmationDialogInput(
|
||||
title: widget.name,
|
||||
requestCount: formatDecimal(widget.count),
|
||||
);
|
||||
if (response.confirmed) {
|
||||
if (isNumeric(response.responseCount)) {
|
||||
bool result = await _service.setCountToItem(widget.inventoryId, widget.inventoryItemId, double.parse(response.responseCount!));
|
||||
if(result) {
|
||||
widget.refresh();
|
||||
} else {
|
||||
_dialogService.showDialog(description: 'Что то пошло не так!');
|
||||
}
|
||||
} else {
|
||||
_dialogService.showDialog(description: 'Не верный формат');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:satu/core/models/inventarization/inventarization_response.dart';
|
||||
import 'package:satu/core/models/inventarization/response/inventarization_response.dart';
|
||||
import 'package:satu/shared/app_colors.dart';
|
||||
|
||||
class InventarizationListTile extends StatefulWidget {
|
||||
const InventarizationListTile({required this.item, Key? key})
|
||||
: super(key: key);
|
||||
|
||||
final InventarizationResponse item;
|
||||
|
||||
@override
|
||||
State<InventarizationListTile> createState() =>
|
||||
_InventarizationListTileState();
|
||||
}
|
||||
|
||||
class _InventarizationListTileState extends State<InventarizationListTile> {
|
||||
final DateFormat formatterDay = DateFormat('dd.MM.yyyy');
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(color: whiteColor),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: InventarizationCellTile(
|
||||
value: widget.item.docNumber.toString()),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: InventarizationCellTile(
|
||||
value: formatterDay.format(widget.item.createdAt),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: InventarizationCellButton(
|
||||
value: formatterDay.format(widget.item.createdAt),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class InventarizationCellTile extends StatelessWidget {
|
||||
const InventarizationCellTile({
|
||||
required this.value,
|
||||
|
|
@ -58,7 +14,6 @@ class InventarizationCellTile extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(15.0),
|
||||
child: Text(
|
||||
value,
|
||||
style: TextStyle(fontSize: 12),
|
||||
|
|
@ -73,20 +28,24 @@ class InventarizationCellButton extends StatelessWidget {
|
|||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
final String value;
|
||||
final int? value;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only( right: 15.0),
|
||||
child: OutlinedButton(
|
||||
onPressed: () {},
|
||||
child: ElevatedButton(
|
||||
onPressed: value == null ? () {} : () {},
|
||||
|
||||
child: Text(
|
||||
'Акт',
|
||||
style: TextStyle(fontSize: 12, color: whiteColor),
|
||||
),
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor: blueColor,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: value == null ? disableColor : blueColor
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class _ProductListItemState extends State<ProductListItem> {
|
|||
},
|
||||
key: Key(widget.name),
|
||||
child: ListTile(
|
||||
//onTap: () => _onItemTapped(context),
|
||||
key: Key(widget.name),
|
||||
onTap: () {
|
||||
editProductModal();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ import 'package:satu/widgets/bar/products_header_bar.dart';
|
|||
import 'package:satu/widgets/bar/products_title_bar.dart';
|
||||
import 'package:satu/views/work/tabs/utils/product_utils.dart';
|
||||
|
||||
import '../../../core/entity/goods_entity.dart';
|
||||
import '../../../core/redux/actions/sell_actions.dart';
|
||||
import '../../../core/services/dictionary_service.dart';
|
||||
import 'component/contagent_select_bar.dart';
|
||||
|
||||
class SellView extends StatelessWidget {
|
||||
|
|
@ -95,7 +98,7 @@ class SellView extends StatelessWidget {
|
|||
converter: (Store<AppState> store) => store.state.sellState!,
|
||||
builder: (_, SellState snapshot) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.all(15.w),
|
||||
padding: EdgeInsets.all(15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
|
|
@ -108,7 +111,7 @@ class SellView extends StatelessWidget {
|
|||
backgroundColor: successColor,
|
||||
onPressed: () =>
|
||||
locator<NavigatorService>().push(paymentViewRoute),
|
||||
child: Icon(Icons.check, color: whiteColor, size: 35.sp),
|
||||
child: Icon(Icons.check, color: whiteColor, size: 35),
|
||||
)),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
|
|
@ -116,11 +119,16 @@ class SellView extends StatelessWidget {
|
|||
FloatingActionButton(
|
||||
elevation: 2,
|
||||
mini: true,
|
||||
onPressed: () =>
|
||||
locator<NavigatorService>().push(addProductViewRoute),
|
||||
onPressed: () async {
|
||||
final Good? good = await locator<NavigatorService>().push(addProductViewRoute) as Good?;
|
||||
if(good !=null) {
|
||||
Redux.store!.dispatch(addSellItem(good: good));
|
||||
}
|
||||
|
||||
},
|
||||
child: Icon(
|
||||
Icons.add_rounded,
|
||||
size: 40.sp,
|
||||
size: 40,
|
||||
color: whiteColor,
|
||||
),
|
||||
),
|
||||
|
|
@ -134,17 +142,17 @@ class SellView extends StatelessWidget {
|
|||
final dynamic result =
|
||||
await _nav.push(addByBarcodeViewRoute);
|
||||
if (result != null) {
|
||||
// final List<Good> goods =
|
||||
// await locator<DictionaryService>()
|
||||
// .getGoodsByEan(result as String);
|
||||
// if (goods.isNotEmpty) {
|
||||
// Redux.store
|
||||
// ?.dispatch(addSellItem(good: goods.first));
|
||||
// }
|
||||
final List<Good> goods =
|
||||
await locator<DictionaryService>()
|
||||
.getGoodsByNameOrEan(result as String);
|
||||
if (goods.isNotEmpty) {
|
||||
Redux.store
|
||||
?.dispatch(addSellItem(good: goods.first));
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Icon(Icons.qr_code_rounded,
|
||||
size: 30.sp, color: whiteColor),
|
||||
size: 30, color: whiteColor),
|
||||
),
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ class AddByBarcodeView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _AddByBarcodeViewState extends State<AddByBarcodeView> {
|
||||
String _code = '';
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
|
@ -30,11 +29,6 @@ class _AddByBarcodeViewState extends State<AddByBarcodeView> {
|
|||
resultCallback: (String code) {
|
||||
final NavigatorService _nav = locator<NavigatorService>();
|
||||
_nav.pop(code);
|
||||
//Navigator.pop(context, code);
|
||||
|
||||
// setState(() {
|
||||
// _code = code;
|
||||
// });
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:satu/core/entity/category_entity.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import 'package:satu/core/entity/goods_entity.dart';
|
||||
import 'package:satu/core/redux/actions/sell_actions.dart';
|
||||
import 'package:satu/core/redux/store.dart';
|
||||
import 'package:satu/core/services/dictionary_service.dart';
|
||||
import 'package:satu/core/services/navigator_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/views/work/views/add_product/component/add_category_list_item.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/good/good_response_entity.dart';
|
||||
import 'component/add_product_list_item.dart';
|
||||
|
||||
class AddProductView extends StatefulWidget {
|
||||
|
|
@ -24,27 +24,30 @@ class _AddProductViewState extends State<AddProductView> {
|
|||
final DictionaryService _dictionaryService = locator<DictionaryService>();
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
late TextEditingController _searchTextController;
|
||||
final FocusNode _searchFocusNode = new FocusNode();
|
||||
final FocusNode _searchFocusNode = FocusNode();
|
||||
static const _pageSize = 20;
|
||||
String query = '';
|
||||
Timer? _debounce;
|
||||
|
||||
List<Category>? _history;
|
||||
List<Category>? _categories;
|
||||
List<Good>? _goods;
|
||||
final PagingController<int, Good> _pagingController =
|
||||
PagingController(firstPageKey: 1);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_searchTextController = TextEditingController();
|
||||
_searchTextController.addListener(() {
|
||||
if (_searchTextController.text.isNotEmpty) {
|
||||
searchByField(_searchTextController.text);
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
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);
|
||||
});
|
||||
_history = [Category()..id = null];
|
||||
_categories = [];
|
||||
_goods = [];
|
||||
super.initState();
|
||||
navigateCategory(null);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -56,8 +59,7 @@ class _AddProductViewState extends State<AddProductView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
int catSize = _categories?.length ?? 0;
|
||||
int goodSize = _goods?.length ?? 0;
|
||||
|
||||
return Scaffold(
|
||||
appBar: ProductsAppBar(
|
||||
title: 'Категория',
|
||||
|
|
@ -72,39 +74,33 @@ class _AddProductViewState extends State<AddProductView> {
|
|||
),
|
||||
verticalSpaceTiny,
|
||||
ProductsTitleBarBar(
|
||||
title: goodSize > 0 ? 'Выберите товар' : 'Выберите категорию',
|
||||
title: 'Выберите товар',
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemCount: catSize + goodSize,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
if (index < catSize) {
|
||||
Category category = _categories![index];
|
||||
return AddCategoryListItem(
|
||||
name: category.name,
|
||||
key: Key('category_${category.id}'),
|
||||
onPress: () => onCategoryPress(category),
|
||||
child: PagedListView<int, Good>.separated(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1.0,
|
||||
color: disableColor,
|
||||
);
|
||||
}
|
||||
Good good = _goods![index - catSize];
|
||||
},
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<Good>(
|
||||
itemBuilder:
|
||||
(BuildContext context, Good good, int index) {
|
||||
return AddProductListItem(
|
||||
key: Key('product_${good.id}'),
|
||||
ean: good.ean,
|
||||
name: good.name,
|
||||
price: good.price,
|
||||
categoryName: _history?.last.name,
|
||||
categoryName: good.categoryName,
|
||||
onPress: () {
|
||||
onGoodPress(good);
|
||||
},
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return Divider(
|
||||
height: 1.0,
|
||||
color: disableColor,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -112,39 +108,29 @@ class _AddProductViewState extends State<AddProductView> {
|
|||
);
|
||||
}
|
||||
|
||||
void onCategoryPress(Category category) {
|
||||
_history!.add(category);
|
||||
navigateCategory(category.id!);
|
||||
}
|
||||
|
||||
|
||||
void onGoodPress(Good good) {
|
||||
Redux.store!.dispatch(addSellItem(good: good));
|
||||
_navigatorService.pop<String>();
|
||||
_navigatorService.pop<Good>(good);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_history = [Category()..id = 0];
|
||||
navigateCategory(0);
|
||||
_searchTextController.clear();
|
||||
}
|
||||
|
||||
void navigateCategory(int? categoryId) async {
|
||||
List<Category> categories =
|
||||
await _dictionaryService.getCategoryByParentId(categoryId);
|
||||
List<Good> goods =
|
||||
await _dictionaryService.getGoodsByCategoryId(categoryId);
|
||||
setState(() {
|
||||
_categories = categories;
|
||||
_goods = goods;
|
||||
});
|
||||
}
|
||||
Future<void> _fetchData(int pageKey, int perPage, String? query) async {
|
||||
final List<GoodResponseEntity> newItems = await _dictionaryService.getGoods(
|
||||
page: pageKey,
|
||||
filter: {'col': 'name', 'action': 'like', 'val': query ?? ''},
|
||||
perpage: perPage);
|
||||
|
||||
void searchByField(String query) async {
|
||||
List<Category> categories = [];
|
||||
List<Good> goods = await _dictionaryService.getGoodsByNameOrEan(query);
|
||||
setState(() {
|
||||
_categories = categories;
|
||||
_goods = goods;
|
||||
});
|
||||
List<Good> items = newItems.map((e) => goodResponseToGood(e)).toList();
|
||||
final isLastPage = newItems.length < _pageSize;
|
||||
if (isLastPage) {
|
||||
_pagingController.appendLastPage(items);
|
||||
} else {
|
||||
final nextPageKey = pageKey + 1;
|
||||
_pagingController.appendPage(items, nextPageKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class AddProductListItem extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
key: key,
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => onPress!(),
|
||||
|
|
@ -51,7 +52,7 @@ class AddProductListItem extends StatelessWidget {
|
|||
Text(
|
||||
'$price ₸',
|
||||
style: TextStyle(
|
||||
fontSize: ScreenUtil().setSp(20.0),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -132,7 +132,9 @@ class _DialogManagerState extends State<DialogManager> {
|
|||
verticalSpaceSmall,
|
||||
const Divider(),
|
||||
verticalSpaceSmall,
|
||||
InputFieldRounded(
|
||||
Visibility(
|
||||
visible: request.requestPrice != null,
|
||||
child: InputFieldRounded(
|
||||
controller: _controllerPrice,
|
||||
placeholder: '',
|
||||
suffixText: '₸',
|
||||
|
|
@ -140,6 +142,7 @@ class _DialogManagerState extends State<DialogManager> {
|
|||
textInputType:
|
||||
const TextInputType.numberWithOptions(decimal: true),
|
||||
),
|
||||
),
|
||||
InputFieldRounded(
|
||||
textInputType:
|
||||
const TextInputType.numberWithOptions(decimal: true),
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ class ProductTitleWidget extends StatelessWidget {
|
|||
children: [
|
||||
Text(
|
||||
name,
|
||||
style: const TextStyle(fontSize: 14, color: textColor),
|
||||
style: const TextStyle(fontSize: 12, color: textColor),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
maxLines: 1,
|
||||
),
|
||||
verticalSpaceTiny,
|
||||
if (ean != null)
|
||||
|
|
|
|||
Loading…
Reference in New Issue