parent
df06a77b6c
commit
94b1e7a79a
|
|
@ -0,0 +1,41 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'buy_item_response.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class BuyItemResponse {
|
||||
BuyItemResponse({
|
||||
required this.id,
|
||||
required this.eaccBuyInvoiceId,
|
||||
required this.eaccGoodId,
|
||||
required this.cnt,
|
||||
required this.price,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
required this.unitPrice,
|
||||
this.deletedAt,
|
||||
this.refOkeiId,
|
||||
});
|
||||
|
||||
int id;
|
||||
@JsonKey(name: 'eacc_buy_invoice_id')
|
||||
int eaccBuyInvoiceId;
|
||||
@JsonKey(name: 'eacc_good_id')
|
||||
int eaccGoodId;
|
||||
@JsonKey(name: 'ref_okei_id')
|
||||
int? refOkeiId;
|
||||
double cnt;
|
||||
double price;
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime createdAt;
|
||||
@JsonKey(name: 'updated_at')
|
||||
DateTime updatedAt;
|
||||
@JsonKey(name: 'deleted_at')
|
||||
DateTime? deletedAt;
|
||||
@JsonKey(name: 'unit_price')
|
||||
double unitPrice;
|
||||
|
||||
factory BuyItemResponse.fromJson(Map<String, dynamic> json) => _$BuyItemResponseFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$BuyItemResponseToJson(this);
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'buy_item_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
BuyItemResponse _$BuyItemResponseFromJson(Map<String, dynamic> json) =>
|
||||
BuyItemResponse(
|
||||
id: json['id'] as int,
|
||||
eaccBuyInvoiceId: json['eacc_buy_invoice_id'] as int,
|
||||
eaccGoodId: json['eacc_good_id'] as int,
|
||||
cnt: (json['cnt'] as num).toDouble(),
|
||||
price: (json['price'] as num).toDouble(),
|
||||
createdAt: DateTime.parse(json['created_at'] as String),
|
||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||
unitPrice: (json['unit_price'] as num).toDouble(),
|
||||
deletedAt: json['deleted_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['deleted_at'] as String),
|
||||
refOkeiId: json['ref_okei_id'] as int?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$BuyItemResponseToJson(BuyItemResponse instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'eacc_buy_invoice_id': instance.eaccBuyInvoiceId,
|
||||
'eacc_good_id': instance.eaccGoodId,
|
||||
'ref_okei_id': instance.refOkeiId,
|
||||
'cnt': instance.cnt,
|
||||
'price': instance.price,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||
'unit_price': instance.unitPrice,
|
||||
};
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
// "eacc_contract_id": null,
|
||||
// "file_id": null,
|
||||
// "invoice": null,
|
||||
// "invoice_check": null,
|
||||
// "cruser_id": 10,
|
||||
// "invoice_doc_date": null,
|
||||
// "invoice_number": null,
|
||||
// "returned_id": null,
|
||||
// "returned_by_id": null,
|
||||
// not usable fields
|
||||
|
||||
part 'buy_invoice_response.g.dart';
|
||||
@JsonSerializable()
|
||||
class BuyInvoiceResponse {
|
||||
BuyInvoiceResponse({
|
||||
required this.id,
|
||||
required this.appCompanyId,
|
||||
required this.refBuyInvoiceStatusId,
|
||||
required this.invoiceDate,
|
||||
required this.docNumber,
|
||||
required this.eaccContragentId,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
this.deletedAt,
|
||||
this.summ,
|
||||
});
|
||||
int id;
|
||||
double? summ;
|
||||
@JsonKey(name: 'app_company_id')
|
||||
int appCompanyId;
|
||||
@JsonKey(name: 'ref_buy_invoice_status_id')
|
||||
int refBuyInvoiceStatusId;
|
||||
@JsonKey(name: 'invoice_date')
|
||||
DateTime invoiceDate;
|
||||
@JsonKey(name: 'doc_number')
|
||||
int docNumber;
|
||||
@JsonKey(name: 'eacc_contragent_id')
|
||||
int eaccContragentId;
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime createdAt;
|
||||
@JsonKey(name: 'updated_at')
|
||||
DateTime updatedAt;
|
||||
@JsonKey(name: 'deleted_at')
|
||||
DateTime? deletedAt;
|
||||
|
||||
factory BuyInvoiceResponse.fromJson(Map<String, dynamic> json) => _$BuyInvoiceResponseFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$BuyInvoiceResponseToJson(this);
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'buy_invoice_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
BuyInvoiceResponse _$BuyInvoiceResponseFromJson(Map<String, dynamic> json) =>
|
||||
BuyInvoiceResponse(
|
||||
id: json['id'] as int,
|
||||
appCompanyId: json['app_company_id'] as int,
|
||||
refBuyInvoiceStatusId: json['ref_buy_invoice_status_id'] as int,
|
||||
invoiceDate: DateTime.parse(json['invoice_date'] as String),
|
||||
docNumber: json['doc_number'] as int,
|
||||
eaccContragentId: json['eacc_contragent_id'] as int,
|
||||
createdAt: DateTime.parse(json['created_at'] as String),
|
||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||
deletedAt: json['deleted_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['deleted_at'] as String),
|
||||
summ: (json['summ'] as num?)?.toDouble(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$BuyInvoiceResponseToJson(BuyInvoiceResponse instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'summ': instance.summ,
|
||||
'app_company_id': instance.appCompanyId,
|
||||
'ref_buy_invoice_status_id': instance.refBuyInvoiceStatusId,
|
||||
'invoice_date': instance.invoiceDate.toIso8601String(),
|
||||
'doc_number': instance.docNumber,
|
||||
'eacc_contragent_id': instance.eaccContragentId,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||
};
|
||||
|
|
@ -48,6 +48,7 @@ class ResponseOriginal {
|
|||
int? page;
|
||||
int? perpage;
|
||||
List<dynamic>? data;
|
||||
List<dynamic>? items;
|
||||
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>?
|
||||
..items = json['items'] as List<dynamic>?
|
||||
..result = json['result']
|
||||
..errors = (json['errors'] as Map<String, dynamic>?)?.map(
|
||||
(k, e) =>
|
||||
|
|
@ -46,6 +47,7 @@ Map<String, dynamic> _$ResponseOriginalToJson(ResponseOriginal instance) =>
|
|||
'page': instance.page,
|
||||
'perpage': instance.perpage,
|
||||
'data': instance.data,
|
||||
'items': instance.items,
|
||||
'result': instance.result,
|
||||
'errors': instance.errors,
|
||||
'message': instance.message,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
import 'package:satu/core/base/base_service.dart';
|
||||
import 'package:satu/core/models/but_item/buy_item_response.dart';
|
||||
import 'package:satu/core/services/api_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
|
||||
import '../models/buy_invoice/buy_invoice_response.dart';
|
||||
import '../models/response/response_entity.dart';
|
||||
|
||||
class BuyService extends BaseService {
|
||||
final ApiService _api = locator<ApiService>();
|
||||
Future<List<BuyInvoiceResponse>> getList(
|
||||
{required int page, required int perpage, dynamic filter}) async {
|
||||
List<BuyInvoiceResponse> list = [];
|
||||
try {
|
||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||
'page': page,
|
||||
'perpage': perpage,
|
||||
};
|
||||
|
||||
ResponseEntity categories = await _api.postRequest('/general_purchases_get',
|
||||
requestBody: requestBody);
|
||||
if (categories.original.data != null &&
|
||||
categories.original.data!.isNotEmpty) {
|
||||
for (final dynamic map in categories.original.data!) {
|
||||
final BuyInvoiceResponse item =
|
||||
BuyInvoiceResponse.fromJson(map);
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
} catch (e, stack) {
|
||||
log.e('getList', e, stack);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Future<List<BuyItemResponse>> getItemList(int id,
|
||||
{required int page, required int perpage, dynamic filter}) async {
|
||||
List<BuyItemResponse> list = [];
|
||||
try {
|
||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||
'page': page,
|
||||
'perpage': perpage,
|
||||
'id': id
|
||||
};
|
||||
log.i(requestBody);
|
||||
|
||||
ResponseEntity categories = await _api.postRequest('/general_purchases_get_items',
|
||||
requestBody: requestBody);
|
||||
if (categories.original.items != null &&
|
||||
categories.original.items!.isNotEmpty) {
|
||||
for (final dynamic map in categories.original.items!) {
|
||||
final BuyItemResponse item =
|
||||
BuyItemResponse.fromJson(map);
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
} catch (e, stack) {
|
||||
log.e('getList', e, stack);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
@ -198,6 +198,7 @@ class DictionaryService extends BaseService {
|
|||
|
||||
Future<String?> saveGood(GoodResponseEntity good) async {
|
||||
ResponseEntity? status;
|
||||
log.i(good.toJson());
|
||||
if (good.id != null) {
|
||||
status = await _api.dictionarySave('/goods_goods_edit', good.toJson());
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,25 @@ class InventarizationService extends BaseService {
|
|||
return result ;
|
||||
}
|
||||
|
||||
Future<bool> deleteFromList(int inventoryId, int inventory_item_id) async {
|
||||
bool result = false;
|
||||
try {
|
||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||
'page': 1,
|
||||
'perpage': 1,
|
||||
'id': inventoryId,
|
||||
'inventory_item_id' : inventory_item_id
|
||||
};
|
||||
ResponseEntity response = await _api.postRequest(
|
||||
'/goods_inventory_delete_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 {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import 'api_service.dart';
|
|||
import 'db_service.dart';
|
||||
import 'dialog_service.dart';
|
||||
|
||||
class DataService extends BaseService {
|
||||
class SellService extends BaseService {
|
||||
final ApiService _api = locator<ApiService>();
|
||||
final DbService _db = locator<DbService>();
|
||||
|
||||
|
|
@ -3,7 +3,8 @@
|
|||
import 'package:get_it/get_it.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:satu/core/services/api_service.dart';
|
||||
import 'package:satu/core/services/data_service.dart';
|
||||
import 'package:satu/core/services/buy_service.dart';
|
||||
import 'package:satu/core/services/sell_service.dart';
|
||||
import 'package:satu/core/services/db_service.dart';
|
||||
import 'package:satu/core/services/dialog_service.dart';
|
||||
import 'package:satu/core/services/dictionary_service.dart';
|
||||
|
|
@ -30,7 +31,9 @@ class LocatorInjector {
|
|||
// depencies
|
||||
|
||||
_log.d('Initializing DataService Service');
|
||||
locator.registerLazySingleton<DataService>(() => DataService());
|
||||
locator.registerLazySingleton<SellService>(() => SellService());
|
||||
_log.d('Initializing BuyService Service');
|
||||
locator.registerLazySingleton<BuyService>(() => BuyService());
|
||||
_log.d('Initializing DictionaryService Service');
|
||||
locator.registerLazySingleton<DictionaryService>(() => DictionaryService());
|
||||
_log.d('Initializing InventarizationService Service');
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ const String contragentEditRoute = 'contragentEditRoute';
|
|||
// inventarization
|
||||
const String inventarizationEditRoute = 'inventarizationEditRoute';
|
||||
|
||||
//buy
|
||||
const String buyEditRoute = 'buyEditRoute';
|
||||
|
||||
// setting - ble printer
|
||||
const String settingPrinterBluetoothViewRoute = 'SettingPrinterBluetoothView';
|
||||
const String settingPrinterBluetoothSelectViewRoute =
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:satu/core/models/buy_invoice/buy_invoice_response.dart';
|
||||
import 'package:satu/core/models/dictionary/category/category_response.dart';
|
||||
import 'package:satu/core/models/dictionary/contragent/contragent_response_entity.dart';
|
||||
import 'package:satu/core/models/dictionary/good/good_response_entity.dart';
|
||||
|
|
@ -13,6 +14,7 @@ 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_select.dart';
|
||||
import 'package:satu/views/settings/printer_bluetooth/printer_view.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';
|
||||
|
|
@ -127,6 +129,15 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
|||
item: inventarizationResponse,
|
||||
),
|
||||
);
|
||||
case buyEditRoute:
|
||||
final BuyInvoiceResponse invoice = settings.arguments! as BuyInvoiceResponse;
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: BuyEditView(
|
||||
invoice: invoice,
|
||||
),
|
||||
);
|
||||
|
||||
default:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => Scaffold(
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ const TextStyle dropDownTradeTypeTextStyle =
|
|||
const TextStyle textGray11Style =
|
||||
TextStyle(color: placeholderColor, fontWeight: FontWeight.w400, fontSize: 11);
|
||||
|
||||
const TextStyle textBlack12Style =
|
||||
TextStyle(color: textColor, fontWeight: FontWeight.w400, fontSize: 12);
|
||||
|
||||
// Box Shadow
|
||||
BoxShadow buttonShadowBox =
|
||||
const BoxShadow(blurRadius: 10, color: shadowColor, offset: Offset(0, 4));
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ class _GoodEditState extends State<GoodEdit> {
|
|||
good.basePrice = parseNumeric(_controllerBasePrice.text);
|
||||
good.ean13 = _controllerEan.text;
|
||||
good.description = _controllerDescription.text;
|
||||
good.categoryId = parentCategoryId;
|
||||
String? message = await _dictionaryService.saveGood(good);
|
||||
if (message != null) {
|
||||
_dialogService.showDialog(description: message);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class _InventarizationEditViewState extends State<InventarizationEditView> {
|
|||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pagingController.dispose();
|
||||
|
|
@ -122,7 +123,7 @@ class _InventarizationEditViewState extends State<InventarizationEditView> {
|
|||
ean: item.ean13,
|
||||
isOdd: index % 2 == 0,
|
||||
refresh: () {
|
||||
_refreshData(_pageCurrent, _pageSize);
|
||||
_pagingController.refresh();
|
||||
},
|
||||
);
|
||||
},
|
||||
|
|
@ -145,7 +146,7 @@ class _InventarizationEditViewState extends State<InventarizationEditView> {
|
|||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Visibility(
|
||||
visible: true,
|
||||
visible: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: FloatingActionButton(
|
||||
|
|
@ -176,7 +177,10 @@ class _InventarizationEditViewState extends State<InventarizationEditView> {
|
|||
_pagingController.refresh();
|
||||
} else {
|
||||
_dialogService.showDialog(
|
||||
description: 'Товара отсутсвует в остатке');
|
||||
description:
|
||||
'Товара отсутсвует в остатке или ранее не'
|
||||
' использователся в системе',
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -196,9 +200,7 @@ class _InventarizationEditViewState extends State<InventarizationEditView> {
|
|||
if (result != null) {
|
||||
final List<Good> goods = await locator<DictionaryService>()
|
||||
.getGoodsByNameOrEan(result as String);
|
||||
if (goods.isNotEmpty) {
|
||||
|
||||
}
|
||||
if (goods.isNotEmpty) {}
|
||||
}
|
||||
},
|
||||
child: Icon(Icons.qr_code_rounded, size: 30, color: whiteColor),
|
||||
|
|
@ -228,14 +230,13 @@ class _InventarizationEditViewState extends State<InventarizationEditView> {
|
|||
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);
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,12 @@ class _InventarizationViewState extends State<InventarizationView> {
|
|||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pagingController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
|
|
|||
|
|
@ -72,10 +72,15 @@ class _GoodInventarizationListItemState
|
|||
' - ${widget.count} ед. ?',
|
||||
confirmationTitle: 'Удалить',
|
||||
cancelTitle: 'Отмена');
|
||||
|
||||
return response.confirmed;
|
||||
if (response.confirmed) {
|
||||
bool result = await _service.deleteFromList(widget.inventoryId,widget.inventoryItemId);
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
onDismissed: (DismissDirection direction) {
|
||||
widget.refresh();
|
||||
},
|
||||
onDismissed: (direction) {},
|
||||
key: widget.key!,
|
||||
child: ListTile(
|
||||
key: widget.key!,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import 'package:satu/core/models/but_item/buy_item_response.dart';
|
||||
import 'package:satu/views/work/tabs/buy/component/product_buy_tile.dart';
|
||||
|
||||
|
||||
import '../../../../core/models/buy_invoice/buy_invoice_response.dart';
|
||||
import '../../../../core/services/buy_service.dart';
|
||||
import '../../../../core/services/navigator_service.dart';
|
||||
import '../../../../core/utils/locator.dart';
|
||||
import '../../../../shared/app_colors.dart';
|
||||
import '../../../../widgets/bar/products_app_bar.dart';
|
||||
|
||||
class BuyEditView extends StatefulWidget {
|
||||
const BuyEditView({required this.invoice, Key? key}) : super(key: key);
|
||||
|
||||
final BuyInvoiceResponse invoice;
|
||||
|
||||
@override
|
||||
State<BuyEditView> createState() => _BuyEditViewState();
|
||||
}
|
||||
|
||||
class _BuyEditViewState extends State<BuyEditView> {
|
||||
final BuyService _service = locator<BuyService>();
|
||||
|
||||
static const _pageSize = 20;
|
||||
|
||||
final PagingController<int, BuyItemResponse> _pagingController =
|
||||
PagingController(firstPageKey: 1);
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_pagingController.addPageRequestListener((pageKey) {
|
||||
_fetchData(pageKey, _pageSize);
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
||||
_pagingController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: const ProductsAppBar(
|
||||
title: 'Покупка',
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: PagedListView<int, BuyItemResponse>.separated(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1.0,
|
||||
color: disableColor,
|
||||
);
|
||||
},
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<BuyItemResponse>(
|
||||
itemBuilder: (BuildContext context, BuyItemResponse item,
|
||||
int index) {
|
||||
return ProductBuyTile(
|
||||
key: ValueKey(item.id),
|
||||
ean: '1234567890123',
|
||||
name: 'Картофель',
|
||||
price: item.price,
|
||||
count: item.cnt,
|
||||
categoryName: 'Овощи',
|
||||
isOdd: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _fetchData(int pageKey, int perPage) async {
|
||||
final List<BuyItemResponse> newItems = await _service
|
||||
.getItemList(widget.invoice.id, page: pageKey, perpage: perPage);
|
||||
final isLastPage = newItems.length < _pageSize;
|
||||
if (isLastPage) {
|
||||
_pagingController.appendLastPage(newItems);
|
||||
} else {
|
||||
final nextPageKey = pageKey + 1;
|
||||
_pagingController.appendPage(newItems, nextPageKey);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:satu/core/services/buy_service.dart';
|
||||
import 'package:satu/core/utils/utils_parse.dart';
|
||||
|
||||
import '../../../../core/models/buy_invoice/buy_invoice_response.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 '../../../dictionaries/component/dictionary_list_tile.dart';
|
||||
import '../../../inventarization/widget/inventarization_list_tile.dart';
|
||||
|
||||
class BuyView extends StatefulWidget {
|
||||
@override
|
||||
State<BuyView> createState() => _BuyViewState();
|
||||
}
|
||||
|
||||
class _BuyViewState extends State<BuyView> {
|
||||
|
||||
|
||||
final BuyService _service = locator<BuyService>();
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
|
||||
static const _pageSize = 20;
|
||||
|
||||
final PagingController<int, BuyInvoiceResponse> _pagingController =
|
||||
PagingController(firstPageKey: 1);
|
||||
|
||||
final DateFormat formatterDay = DateFormat('dd.MM.yyyy');
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_pagingController.addPageRequestListener((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: true,
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: PagedListView<int, BuyInvoiceResponse>.separated(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1.0,
|
||||
color: disableColor,
|
||||
);
|
||||
},
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<BuyInvoiceResponse>(
|
||||
itemBuilder: (BuildContext context, BuyInvoiceResponse item,
|
||||
int index) {
|
||||
return DictionaryTile(
|
||||
key: Key('category_${item.id}'),
|
||||
onPress: () async {
|
||||
final dynamic result = await _navigatorService
|
||||
.push(buyEditRoute, arguments: item);
|
||||
if (result != null && true == (result as bool)) {
|
||||
_pagingController.refresh();
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${item.eaccContragentId.toString()}',
|
||||
style: textBlack12Style,
|
||||
),
|
||||
SizedBox(
|
||||
height: 5.0,
|
||||
),
|
||||
Text(
|
||||
'Статус: ${item.eaccContragentId.toString()}',
|
||||
style: textGray11Style,
|
||||
),
|
||||
],
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
'${formatterDay.format(item.invoiceDate)}',
|
||||
style: textBlack12Style,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'${formatDecimal(item.summ ?? 0)} т.',
|
||||
style: textGray11Style,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _fetchData(int pageKey, int perPage) async {
|
||||
final List<BuyInvoiceResponse> newItems = await _service
|
||||
.getList(page: pageKey, perpage: perPage);
|
||||
final isLastPage = newItems.length < _pageSize;
|
||||
if (isLastPage) {
|
||||
_pagingController.appendLastPage(newItems);
|
||||
} else {
|
||||
final nextPageKey = pageKey + 1;
|
||||
_pagingController.appendPage(newItems, nextPageKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
|
||||
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/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 ProductBuyTile extends StatefulWidget {
|
||||
const ProductBuyTile(
|
||||
{Key? key,
|
||||
this.name = '',
|
||||
this.ean,
|
||||
this.categoryName,
|
||||
this.price,
|
||||
this.count,
|
||||
this.isOdd,
|
||||
this.transactionId})
|
||||
: super(key: key);
|
||||
|
||||
final String name;
|
||||
final String? ean;
|
||||
final String? categoryName;
|
||||
final num? price;
|
||||
final num? count;
|
||||
final bool? isOdd;
|
||||
final int? transactionId;
|
||||
|
||||
@override
|
||||
_ProductBuyTileState createState() => _ProductBuyTileState();
|
||||
}
|
||||
|
||||
class _ProductBuyTileState extends State<ProductBuyTile> {
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
|
||||
void _onItemTapped(BuildContext context) {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (BuildContext context) => const AddByBarcodeView()));
|
||||
}
|
||||
|
||||
@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) {
|
||||
Redux.store!
|
||||
.dispatch(removeSellItem(transactionId: widget.transactionId!));
|
||||
},
|
||||
key: Key(widget.name),
|
||||
child: ListTile(
|
||||
key: Key(widget.name),
|
||||
onTap: () {
|
||||
editProductModal();
|
||||
},
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 10.0, vertical: 4.0),
|
||||
title: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: ProductTitleWidget(
|
||||
name: widget.name,
|
||||
ean: widget.ean,
|
||||
categoryName: widget.categoryName,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 3.0),
|
||||
child: Text(
|
||||
'${widget.price} ₸',
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: textColor),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Redux.store!.dispatch(counterOrEditSellItem(
|
||||
transactionId: widget.transactionId!,
|
||||
counter: 1.0));
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
//color: whiteColor,
|
||||
borderRadius: BorderRadius.circular(
|
||||
ScreenUtil().radius(5),
|
||||
),
|
||||
border: Border.all(color: successColor),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.add,
|
||||
color: successColor,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 45,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 5.0),
|
||||
decoration: BoxDecoration(
|
||||
color: whiteColor,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
boxShadow: [cardShadowBox]),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
child: SizedBox(
|
||||
width: 45,
|
||||
child: Text(
|
||||
'${widget.count} шт',
|
||||
style: const TextStyle(
|
||||
fontSize: 10, color: placeholderColor),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
if (widget.count! > 1.0) {
|
||||
Redux.store!.dispatch(counterOrEditSellItem(
|
||||
transactionId: widget.transactionId!,
|
||||
counter: -1.0));
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
//color: whiteColor,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(
|
||||
width: 1.0.sp,
|
||||
color: widget.count! <= 1.0
|
||||
? disableColor
|
||||
: dangerColor)),
|
||||
child: Icon(
|
||||
Icons.remove,
|
||||
color: widget.count! <= 1.0
|
||||
? disableColor
|
||||
: dangerColor,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
tileColor: !widget.isOdd! ? whiteColor : whiteColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> editProductModal() async {
|
||||
final DialogResponse response =
|
||||
await _dialogService.showConfirmationDialogInput(
|
||||
title: widget.name,
|
||||
requestCount: formatDecimal(widget.count!.toDouble()),
|
||||
requestPrice: formatDecimal(widget.price!.toDouble()));
|
||||
if (response.confirmed) {
|
||||
if (isNumeric(response.responsePrice) &&
|
||||
isNumeric(response.responseCount)) {
|
||||
Redux.store!.dispatch(counterOrEditSellItem(
|
||||
transactionId: widget.transactionId!,
|
||||
counter: double.parse(response.responseCount!),
|
||||
price: double.parse(response.responsePrice!),
|
||||
));
|
||||
} else {
|
||||
_dialogService.showDialog(description: 'Не верный формат');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../widgets/bar/products_app_bar.dart';
|
||||
|
||||
class BuyView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: ProductsAppBar(title: 'Покупка',),
|
||||
body: Center(
|
||||
child: Text(
|
||||
'Index 2: School',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600, color: Colors.black, fontSize: 15),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ import 'package:satu/routes/route_names.dart';
|
|||
import 'package:satu/shared/app_colors.dart';
|
||||
import 'package:satu/widgets/bar/products_app_bar.dart';
|
||||
import 'package:satu/widgets/buttons/option_pill.dart';
|
||||
import 'component/journal_list_tile.dart';
|
||||
import '../component/journal_list_tile.dart';
|
||||
|
||||
class JournalView extends StatefulWidget {
|
||||
@override
|
||||
|
|
@ -13,8 +13,8 @@ import 'package:satu/views/work/views/add_by_barcode/add_by_barcode_view.dart';
|
|||
import 'package:satu/widgets/ui/product_title_widget.dart';
|
||||
|
||||
|
||||
class ProductListItem extends StatefulWidget {
|
||||
const ProductListItem(
|
||||
class ProductSellTile extends StatefulWidget {
|
||||
const ProductSellTile(
|
||||
{Key? key,
|
||||
this.name = '',
|
||||
this.ean,
|
||||
|
|
@ -34,10 +34,10 @@ class ProductListItem extends StatefulWidget {
|
|||
final int? transactionId;
|
||||
|
||||
@override
|
||||
_ProductListItemState createState() => _ProductListItemState();
|
||||
_ProductSellTileState createState() => _ProductSellTileState();
|
||||
}
|
||||
|
||||
class _ProductListItemState extends State<ProductListItem> {
|
||||
class _ProductSellTileState extends State<ProductSellTile> {
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
|
||||
void _onItemTapped(BuildContext context) {
|
||||
|
|
@ -10,16 +10,16 @@ import 'package:satu/core/utils/locator.dart';
|
|||
import 'package:satu/routes/route_names.dart';
|
||||
import 'package:satu/shared/app_colors.dart';
|
||||
import 'package:satu/shared/ui_helpers.dart';
|
||||
import 'package:satu/views/work/tabs/component/product_list_item.dart';
|
||||
import 'package:satu/views/work/tabs/sell/component/product_sell_tile.dart';
|
||||
import 'package:satu/widgets/bar/products_app_bar.dart';
|
||||
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';
|
||||
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 {
|
||||
@override
|
||||
|
|
@ -62,7 +62,7 @@ class SellView extends StatelessWidget {
|
|||
itemBuilder: (BuildContext context, int index) {
|
||||
final ProductDao product =
|
||||
state.items!.elementAt(index);
|
||||
return ProductListItem(
|
||||
return ProductSellTile(
|
||||
key: UniqueKey(),
|
||||
ean: product.eanCode,
|
||||
isOdd: index % 2 == 0,
|
||||
|
|
@ -7,7 +7,7 @@ import 'package:satu/core/utils/locator.dart';
|
|||
import 'package:satu/core/utils/utils_parse.dart';
|
||||
import 'package:satu/routes/route_names.dart';
|
||||
import 'package:satu/shared/app_colors.dart';
|
||||
import 'package:satu/core/services/data_service.dart';
|
||||
import 'package:satu/core/services/sell_service.dart';
|
||||
import 'package:satu/views/work/views/payment/component/combine_dock.dart';
|
||||
import 'package:satu/widgets/bar/products_app_bar.dart';
|
||||
import 'package:satu/widgets/bar/products_header_bar.dart';
|
||||
|
|
@ -24,7 +24,7 @@ class PaymentView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _PaymentViewState extends State<PaymentView> {
|
||||
final DataService _dataService = locator<DataService>();
|
||||
final SellService _dataService = locator<SellService>();
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
|
||||
bool combine = false;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import 'package:satu/core/models/flow/sell_response.dart';
|
|||
import 'package:satu/core/models/settings/printer_setting.dart';
|
||||
import 'package:satu/core/models/ui_dao/popup_item_dao.dart';
|
||||
import 'package:satu/core/redux/store.dart';
|
||||
import 'package:satu/core/services/data_service.dart';
|
||||
import 'package:satu/core/services/sell_service.dart';
|
||||
import 'package:satu/core/services/dialog_service.dart';
|
||||
import 'package:satu/core/services/navigator_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
|
|
@ -32,7 +32,7 @@ class ReceiptView extends StatefulWidget {
|
|||
|
||||
class _ReceiptViewState extends State<ReceiptView> {
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
final DataService _dataService = locator<DataService>();
|
||||
final SellService _dataService = locator<SellService>();
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
PrinterBluetoothManager printerManager = PrinterBluetoothManager();
|
||||
bool printerLocked = false;
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
|
|||
|
||||
import 'package:satu/core/redux/actions/sell_actions.dart';
|
||||
import 'package:satu/core/redux/store.dart';
|
||||
import 'package:satu/views/work/tabs/buy_view.dart';
|
||||
import 'package:satu/views/work/tabs/journal_view.dart';
|
||||
import 'package:satu/views/work/tabs/sell_view.dart';
|
||||
import 'package:satu/views/work/tabs/buy/buy_view.dart';
|
||||
import 'package:satu/views/work/tabs/journal/journal_view.dart';
|
||||
import 'package:satu/views/work/tabs/sell/sell_view.dart';
|
||||
import 'package:satu/widgets/bar/bottom_bar.dart';
|
||||
|
||||
class WorkView extends StatefulWidget {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ class BottomBar extends StatelessWidget {
|
|||
active: selectedIndex == 1,
|
||||
onTap: () => onTap(1),
|
||||
svgFile: 'buy',
|
||||
disable: true,
|
||||
name: 'Покупка',
|
||||
),
|
||||
BottomButton(
|
||||
|
|
|
|||
Loading…
Reference in New Issue