Покупка ++
parent
69c98ca7c8
commit
01d6e2d808
|
|
@ -52,6 +52,7 @@ class ResponseOriginal {
|
|||
dynamic result;
|
||||
Map<String, List<String>>? errors;
|
||||
String? message;
|
||||
String? status;
|
||||
|
||||
Map<String, dynamic> toJson() => _$ResponseOriginalToJson(this);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ ResponseOriginal _$ResponseOriginalFromJson(Map<String, dynamic> json) =>
|
|||
(k, e) =>
|
||||
MapEntry(k, (e as List<dynamic>).map((e) => e as String).toList()),
|
||||
)
|
||||
..message = json['message'] as String?;
|
||||
..message = json['message'] as String?
|
||||
..status = json['status'] as String?;
|
||||
|
||||
Map<String, dynamic> _$ResponseOriginalToJson(ResponseOriginal instance) =>
|
||||
<String, dynamic>{
|
||||
|
|
@ -51,4 +52,5 @@ Map<String, dynamic> _$ResponseOriginalToJson(ResponseOriginal instance) =>
|
|||
'result': instance.result,
|
||||
'errors': instance.errors,
|
||||
'message': instance.message,
|
||||
'status': instance.status,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -59,4 +59,61 @@ class BuyService extends BaseService {
|
|||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Future<bool> editItem({required int invoiceId, required int id, required double price, required double count}) async {
|
||||
bool result = false;
|
||||
try {
|
||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||
'eacc_buy_invoice_item_id': id,
|
||||
'id': invoiceId,
|
||||
'price': price,
|
||||
'cnt': count
|
||||
};
|
||||
log.i(requestBody);
|
||||
|
||||
ResponseEntity response = await _api.postRequest('/general_purchases_edit_item',
|
||||
requestBody: requestBody);
|
||||
result = response.original.status == 'success';
|
||||
} catch (e, stack) {
|
||||
log.e('getList', e, stack);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<bool> deleteItem(int id) async {
|
||||
bool result = false;
|
||||
try {
|
||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||
'id': id,
|
||||
};
|
||||
log.i(requestBody);
|
||||
|
||||
ResponseEntity response = await _api.postRequest('/general_purchases_delete_item',
|
||||
requestBody: requestBody);
|
||||
result = response.original.status == 'success';
|
||||
log.i(response.toJson());
|
||||
} catch (e, stack) {
|
||||
log.e('getList', e, stack);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<bool> addItem(int invoiceId, int goodId) async {
|
||||
bool result = false;
|
||||
try {
|
||||
final Map<String, dynamic> requestBody = <String, dynamic>{
|
||||
'eacc_good_id': goodId,
|
||||
'id': invoiceId,
|
||||
};
|
||||
log.i(requestBody);
|
||||
|
||||
ResponseEntity response = await _api.postRequest('/general_purchases_add_item',
|
||||
requestBody: requestBody);
|
||||
result = response.original.status == 'success';
|
||||
log.i(response.toJson());
|
||||
} catch (e, stack) {
|
||||
log.e('getList', e, stack);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,21 @@
|
|||
import 'dart:developer';
|
||||
|
||||
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/core/services/dialog_service.dart';
|
||||
import 'package:satu/views/work/tabs/buy/component/product_buy_tile.dart';
|
||||
|
||||
|
||||
import '../../../../core/entity/goods_entity.dart';
|
||||
import '../../../../core/models/buy_invoice/buy_invoice_response.dart';
|
||||
import '../../../../core/services/buy_service.dart';
|
||||
import '../../../../core/services/dictionary_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/ui_helpers.dart';
|
||||
import '../../../../widgets/bar/products_app_bar.dart';
|
||||
|
||||
class BuyEditView extends StatefulWidget {
|
||||
|
|
@ -22,18 +29,27 @@ class BuyEditView extends StatefulWidget {
|
|||
|
||||
class _BuyEditViewState extends State<BuyEditView> {
|
||||
final BuyService _service = locator<BuyService>();
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
|
||||
static const _pageSize = 20;
|
||||
|
||||
final PagingController<int, BuyItemResponse> _pagingController =
|
||||
PagingController(firstPageKey: 1);
|
||||
|
||||
bool editable = false;
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
log('initState');
|
||||
_pagingController.addPageRequestListener((pageKey) {
|
||||
_fetchData(pageKey, _pageSize);
|
||||
});
|
||||
log('refBuyInvoiceStatusId: ${widget.invoice.refBuyInvoiceStatusId}');
|
||||
if(widget.invoice.refBuyInvoiceStatusId == 1){
|
||||
editable = true;
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +88,12 @@ class _BuyEditViewState extends State<BuyEditView> {
|
|||
price: item.price,
|
||||
count: item.cnt,
|
||||
categoryName: 'Овощи',
|
||||
isOdd: true,
|
||||
editable: editable,
|
||||
invoiceId: widget.invoice.id,
|
||||
id: item.id,
|
||||
editData: (id, price, count) {
|
||||
_editData(id, price, count);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
@ -80,6 +101,83 @@ class _BuyEditViewState extends State<BuyEditView> {
|
|||
)
|
||||
],
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||
floatingActionButton: editable ? floatingActionButtonRender() : null,
|
||||
);
|
||||
}
|
||||
|
||||
/// render floating buttons
|
||||
Widget floatingActionButtonRender() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.all(15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Visibility(
|
||||
visible: false,
|
||||
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 && good.id != null) {
|
||||
bool result =
|
||||
await _service.addItem(widget.invoice.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),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -95,4 +193,14 @@ class _BuyEditViewState extends State<BuyEditView> {
|
|||
}
|
||||
}
|
||||
|
||||
void _editData(int id, double price, double count) {
|
||||
final List<BuyItemResponse> oldList =
|
||||
_pagingController.value.itemList ?? [];
|
||||
oldList..firstWhere((element) => element.id == id).price = price
|
||||
..firstWhere((element) => element.id == id).cnt = count;
|
||||
setState(() {
|
||||
_pagingController.itemList = oldList;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ class _BuyViewState extends State<BuyView> {
|
|||
height: 5.0,
|
||||
),
|
||||
Text(
|
||||
'Статус: ${item.eaccContragentId.toString()}',
|
||||
'Статус: ${item.refBuyInvoiceStatusId.toString()}',
|
||||
style: textGray11Style,
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
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/buy_service.dart';
|
||||
import 'package:satu/core/services/dialog_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
import 'package:satu/core/utils/utils_parse.dart';
|
||||
|
|
@ -12,39 +12,38 @@ 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);
|
||||
|
||||
const ProductBuyTile({
|
||||
required this.invoiceId,
|
||||
required this.id,
|
||||
Key? key,
|
||||
this.name = '',
|
||||
this.ean,
|
||||
this.categoryName,
|
||||
this.price,
|
||||
this.count,
|
||||
this.editable = false,
|
||||
this.editData,
|
||||
}) : super(key: key);
|
||||
final int id;
|
||||
final int invoiceId;
|
||||
final String name;
|
||||
final String? ean;
|
||||
final String? categoryName;
|
||||
final num? price;
|
||||
final num? count;
|
||||
final bool? isOdd;
|
||||
final int? transactionId;
|
||||
final bool editable;
|
||||
|
||||
@override
|
||||
_ProductBuyTileState createState() => _ProductBuyTileState();
|
||||
|
||||
final void Function(int id, double price, double count)? editData;
|
||||
}
|
||||
|
||||
class _ProductBuyTileState extends State<ProductBuyTile> {
|
||||
final BuyService _service = locator<BuyService>();
|
||||
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(
|
||||
|
|
@ -59,31 +58,36 @@ class _ProductBuyTileState extends State<ProductBuyTile> {
|
|||
),
|
||||
),
|
||||
),
|
||||
direction: DismissDirection.endToStart,
|
||||
direction:
|
||||
widget.editable ? DismissDirection.endToStart : DismissDirection.none,
|
||||
confirmDismiss: (DismissDirection direction) async {
|
||||
final DialogResponse response =
|
||||
await _dialogService.showConfirmationDialog(
|
||||
title: 'Внимание',
|
||||
description: 'Удалить из списка товар '
|
||||
'"${widget.name}"'
|
||||
' - ${widget.count} ед. ?',
|
||||
confirmationTitle: 'Удалить',
|
||||
cancelTitle: 'Отмена');
|
||||
await _dialogService.showConfirmationDialog(
|
||||
title: 'Внимание',
|
||||
description: 'Удалить из списка товар '
|
||||
'"${widget.name}"'
|
||||
' - ${widget.count} ед. ?',
|
||||
confirmationTitle: 'Удалить',
|
||||
cancelTitle: 'Отмена');
|
||||
|
||||
return response.confirmed;
|
||||
},
|
||||
onDismissed: (direction) {
|
||||
Redux.store!
|
||||
.dispatch(removeSellItem(transactionId: widget.transactionId!));
|
||||
if (response.confirmed) {
|
||||
bool result = await _service.deleteItem(widget.id);
|
||||
return result;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
onDismissed: (direction) {},
|
||||
key: Key(widget.name),
|
||||
child: ListTile(
|
||||
key: Key(widget.name),
|
||||
onTap: () {
|
||||
editProductModal();
|
||||
},
|
||||
onTap: widget.editable
|
||||
? () {
|
||||
editProductModal();
|
||||
}
|
||||
: null,
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 10.0, vertical: 4.0),
|
||||
const EdgeInsets.symmetric(horizontal: 10.0, vertical: 4.0),
|
||||
title: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
|
|
@ -113,79 +117,13 @@ class _ProductBuyTileState extends State<ProductBuyTile> {
|
|||
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,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
child: Text(
|
||||
'${widget.count} шт',
|
||||
style: const TextStyle(
|
||||
fontSize: 12, color: placeholderColor),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -195,25 +133,29 @@ class _ProductBuyTileState extends State<ProductBuyTile> {
|
|||
),
|
||||
],
|
||||
),
|
||||
tileColor: !widget.isOdd! ? whiteColor : whiteColor,
|
||||
tileColor: whiteColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> editProductModal() async {
|
||||
final DialogResponse response =
|
||||
await _dialogService.showConfirmationDialogInput(
|
||||
title: widget.name,
|
||||
requestCount: formatDecimal(widget.count!.toDouble()),
|
||||
requestPrice: formatDecimal(widget.price!.toDouble()));
|
||||
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!),
|
||||
));
|
||||
bool result = await _service.editItem(
|
||||
invoiceId: widget.invoiceId,
|
||||
id: widget.id,
|
||||
price: double.parse(response.responsePrice!),
|
||||
count: double.parse(response.responseCount!));
|
||||
if (result && widget.editData != null) {
|
||||
widget.editData!(widget.id, double.parse(response.responsePrice!),
|
||||
double.parse(response.responseCount!));
|
||||
}
|
||||
} else {
|
||||
_dialogService.showDialog(description: 'Не верный формат');
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue