Added Shipping Management
parent
fb41cd0770
commit
450dfff6e8
@ -0,0 +1,27 @@
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/models/requests_models/request_model.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
|
||||
class ShippingRequestModel {
|
||||
int? id;
|
||||
int? requestID;
|
||||
RequestModel? request;
|
||||
int? shippingStatus;
|
||||
ShippingRequestStatusEnum? shippingStatusEnum;
|
||||
String? deliveredOn;
|
||||
String? comment;
|
||||
String? createdOn;
|
||||
|
||||
ShippingRequestModel({this.id, this.requestID, this.request, this.shippingStatus, this.deliveredOn, this.comment, this.createdOn});
|
||||
|
||||
ShippingRequestModel.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
requestID = json['requestID'];
|
||||
request = json['request'];
|
||||
shippingStatus = json['shippingStatus'];
|
||||
shippingStatusEnum = json['shippingStatus'] != null ? (json['shippingStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.initiated;
|
||||
deliveredOn = json['deliveredOn'];
|
||||
comment = json['comment'];
|
||||
createdOn = json['createdOn'];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:mc_common_app/api/api_client.dart';
|
||||
import 'package:mc_common_app/classes/app_state.dart';
|
||||
import 'package:mc_common_app/classes/consts.dart';
|
||||
import 'package:mc_common_app/config/dependency_injection.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
||||
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
|
||||
import 'package:mc_common_app/models/shipping_models/shipping_status_model.dart';
|
||||
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/utils.dart';
|
||||
|
||||
abstract class ShippingRepo {
|
||||
Future<List<ShippingRequestModel>> getShippingRequestListByStatus({ShippingRequestStatusEnum? shippingStatusEnum, int? requestId});
|
||||
|
||||
Future<GenericRespModel> updateShippingRequestStatus({required ShippingRequestStatusEnum shippingStatusEnum, required int shippingRequestId, String? comment});
|
||||
}
|
||||
|
||||
class ShippingRepoImp extends ShippingRepo {
|
||||
ApiClient apiClient = injector.get<ApiClient>();
|
||||
AppState appState = injector.get<AppState>();
|
||||
|
||||
@override
|
||||
Future<List<ShippingRequestModel>> getShippingRequestListByStatus({ShippingRequestStatusEnum? shippingStatusEnum, int? requestId}) async {
|
||||
String token = appState.getUser.data!.accessToken ?? "";
|
||||
Map<String, String> queryParameters = {
|
||||
"requestID": "${requestId ?? 0}",
|
||||
"shippingStatus": "${shippingStatusEnum != null ? shippingStatusEnum.getIdFromShippingStatusEnum() : 0}",
|
||||
};
|
||||
|
||||
GenericRespModel genericRespModel = await injector.get<ApiClient>().postJsonForObject(
|
||||
(json) => GenericRespModel.fromJson(json),
|
||||
ApiConsts.shippingRequestStatusGet,
|
||||
queryParameters,
|
||||
token: token,
|
||||
);
|
||||
|
||||
if (genericRespModel.messageStatus != 1 || genericRespModel.data == null) {
|
||||
Utils.showToast(genericRespModel.message ?? LocaleKeys.somethingWrong.tr());
|
||||
return [];
|
||||
}
|
||||
|
||||
List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJson(genericRespModel.data[index]));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GenericRespModel> updateShippingRequestStatus({required ShippingRequestStatusEnum shippingStatusEnum, required int shippingRequestId, String? comment}) async {
|
||||
String token = appState.getUser.data!.accessToken ?? "";
|
||||
Map<String, String> queryParameters = {
|
||||
"id": "$shippingRequestId",
|
||||
"shippingStatus": "${shippingStatusEnum.getIdFromShippingStatusEnum()}",
|
||||
"comment": comment ?? "",
|
||||
};
|
||||
|
||||
GenericRespModel genericRespModel = await injector.get<ApiClient>().postJsonForObject(
|
||||
(json) => GenericRespModel.fromJson(json),
|
||||
ApiConsts.shippingRequestStatusUpdate,
|
||||
queryParameters,
|
||||
token: token,
|
||||
);
|
||||
|
||||
if (genericRespModel.messageStatus != 1 || genericRespModel.data == null) {
|
||||
Utils.showToast(genericRespModel.message ?? LocaleKeys.somethingWrong.tr());
|
||||
}
|
||||
|
||||
return genericRespModel;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,110 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/main.dart';
|
||||
import 'package:mc_common_app/models/general_models/enums_model.dart';
|
||||
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
|
||||
import 'package:mc_common_app/models/general_models/widgets_models.dart';
|
||||
import 'package:mc_common_app/models/shipping_models/shipping_status_model.dart';
|
||||
import 'package:mc_common_app/repositories/common_repo.dart';
|
||||
import 'package:mc_common_app/repositories/shipping_repo.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/utils.dart';
|
||||
import 'package:mc_common_app/view_models/base_view_model.dart';
|
||||
|
||||
class ShippingManagementVM extends BaseVM {
|
||||
final ShippingRepo shippingRepo;
|
||||
final CommonRepo commonRepo;
|
||||
|
||||
ShippingManagementVM({required this.shippingRepo, required this.commonRepo});
|
||||
|
||||
List<ShippingRequestModel> shippingRequestsList = [];
|
||||
|
||||
List<EnumsModel> shippingStatusEnums = [];
|
||||
|
||||
List<FilterListModel> shippingRequestFilterOptions = [];
|
||||
List<FilterListModel> shippingRequestStatusesList = [];
|
||||
|
||||
String requestStatusComments = "";
|
||||
|
||||
void updateRequestStatusComments(var value) {
|
||||
requestStatusComments = value;
|
||||
}
|
||||
|
||||
resetFilters() {
|
||||
if (shippingRequestFilterOptions.isEmpty) return;
|
||||
for (var value in shippingRequestFilterOptions) {
|
||||
value.isSelected = false;
|
||||
}
|
||||
shippingRequestFilterOptions[0].isSelected = true;
|
||||
requestStatusComments = "";
|
||||
}
|
||||
|
||||
Future<void> populateShippingRequestFilterList() async {
|
||||
if (shippingRequestFilterOptions.isNotEmpty && shippingRequestStatusesList.isNotEmpty) return;
|
||||
|
||||
shippingStatusEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.shippingStatusEnumId);
|
||||
shippingRequestFilterOptions.clear();
|
||||
shippingRequestStatusesList.clear();
|
||||
for (int i = 0; i < shippingStatusEnums.length; i++) {
|
||||
shippingRequestFilterOptions.add(FilterListModel(title: shippingStatusEnums[i].enumValueStr, isSelected: false, id: shippingStatusEnums[i].enumValue));
|
||||
shippingRequestStatusesList.add(FilterListModel(title: shippingStatusEnums[i].enumValueStr, isSelected: false, id: shippingStatusEnums[i].enumValue));
|
||||
}
|
||||
|
||||
shippingRequestFilterOptions.insert(0, FilterListModel(title: Utils.getNameByShippingRequestStatusEnum(0.toShippingStatusEnum()), isSelected: true, id: 0));
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> applyFiltersOnShippingRequests({required ShippingRequestStatusEnum shippingRequestStatusEnum}) async {
|
||||
for (var value in shippingRequestFilterOptions) {
|
||||
value.isSelected = false;
|
||||
}
|
||||
if (shippingRequestStatusEnum == ShippingRequestStatusEnum.allRequests) {
|
||||
shippingRequestFilterOptions[0].isSelected = true;
|
||||
await getShippingRequestsListByFilters();
|
||||
notifyListeners();
|
||||
return;
|
||||
}
|
||||
shippingRequestFilterOptions[shippingRequestStatusEnum.getIdFromShippingStatusEnum()].isSelected = true; // -1 to match with the index
|
||||
await getShippingRequestsListByFilters(shippingStatusEnum: shippingRequestStatusEnum);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void updateSelectionInShippingRequestStatuses(int index) {
|
||||
for (var value in shippingRequestStatusesList) {
|
||||
value.isSelected = false;
|
||||
}
|
||||
shippingRequestStatusesList[index].isSelected = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> getShippingRequestsListByFilters({ShippingRequestStatusEnum? shippingStatusEnum}) async {
|
||||
setState(ViewState.busy);
|
||||
try {
|
||||
shippingRequestsList = await shippingRepo.getShippingRequestListByStatus(shippingStatusEnum: shippingStatusEnum);
|
||||
setState(ViewState.idle);
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
logger.i(e.toString());
|
||||
Utils.showToast(e.toString());
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> onUpdateShippingStatusTapped({required BuildContext context, required ShippingRequestStatusEnum shippingStatusEnum, required int shippingRequestId}) async {
|
||||
|
||||
Utils.showLoading(context);
|
||||
try {
|
||||
GenericRespModel? genericRespModel = await shippingRepo.updateShippingRequestStatus(shippingStatusEnum: shippingStatusEnum, shippingRequestId: shippingRequestId);
|
||||
Utils.showToast(genericRespModel.message.toString());
|
||||
Utils.hideLoading(context);
|
||||
return genericRespModel.messageStatus == 1;
|
||||
} catch (e) {
|
||||
logger.i(e.toString());
|
||||
Utils.showToast(e.toString());
|
||||
Utils.hideLoading(context);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,199 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
||||
import 'package:mc_common_app/models/general_models/widgets_models.dart';
|
||||
import 'package:mc_common_app/models/shipping_models/shipping_status_model.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/utils/utils.dart';
|
||||
import 'package:mc_common_app/view_models/shipping_management_view_model.dart';
|
||||
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||
import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
import 'package:mc_common_app/widgets/txt_field.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
class ShippingManagementView extends StatefulWidget {
|
||||
const ShippingManagementView({super.key});
|
||||
|
||||
@override
|
||||
State<ShippingManagementView> createState() => _ShippingManagementViewState();
|
||||
}
|
||||
|
||||
class _ShippingManagementViewState extends State<ShippingManagementView> {
|
||||
late ShippingManagementVM shippingViewModel;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
shippingViewModel = context.read<ShippingManagementVM>();
|
||||
scheduleMicrotask(() async {
|
||||
if (shippingViewModel.shippingRequestFilterOptions.isNotEmpty) {
|
||||
await shippingViewModel.populateShippingRequestFilterList();
|
||||
}
|
||||
await shippingViewModel.getShippingRequestsListByFilters();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Future buildUpdateShippingStatusBottomSheet({required int shippingRequestId}) {
|
||||
return showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
enableDrag: true,
|
||||
builder: (BuildContext context) {
|
||||
return Consumer(builder: (BuildContext context, ShippingManagementVM shippingManagementVM, Widget? child) {
|
||||
return InfoBottomSheet(
|
||||
title: LocaleKeys.pleaseSpecify.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
|
||||
description: Padding(
|
||||
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
12.height,
|
||||
ListView.separated(
|
||||
shrinkWrap: true,
|
||||
itemCount: shippingManagementVM.shippingRequestStatusesList.length,
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 3.0),
|
||||
child: Divider(thickness: 0.5),
|
||||
);
|
||||
},
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
List<FilterListModel> list = shippingManagementVM.shippingRequestStatusesList;
|
||||
FilterListModel shippingFilterListModel = list[index];
|
||||
return CircleCheckBoxWithTitle(
|
||||
isChecked: shippingFilterListModel.isSelected,
|
||||
title: shippingFilterListModel.title,
|
||||
onSelected: () {
|
||||
shippingManagementVM.updateSelectionInShippingRequestStatuses(index);
|
||||
},
|
||||
selectedColor: MyColors.darkPrimaryColor,
|
||||
);
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
TxtField(
|
||||
maxLines: 4,
|
||||
value: shippingManagementVM.requestStatusComments,
|
||||
errorValue: "",
|
||||
keyboardType: TextInputType.text,
|
||||
hint: LocaleKeys.comment.tr(),
|
||||
onChanged: (v) => shippingManagementVM.updateRequestStatusComments(v),
|
||||
),
|
||||
],
|
||||
),
|
||||
25.height,
|
||||
ShowFillButton(
|
||||
title: LocaleKeys.submit.tr(),
|
||||
onPressed: () async {
|
||||
FilterListModel value = shippingManagementVM.shippingRequestStatusesList.firstWhere((element) => element.isSelected);
|
||||
ShippingRequestStatusEnum shippingStatusEnum = value.id.toShippingStatusEnum();
|
||||
bool status = await shippingManagementVM.onUpdateShippingStatusTapped(shippingStatusEnum: shippingStatusEnum, shippingRequestId: shippingRequestId, context: context);
|
||||
if (status) {
|
||||
pop(context);
|
||||
await shippingManagementVM.getShippingRequestsListByFilters();
|
||||
}
|
||||
},
|
||||
maxWidth: double.infinity,
|
||||
),
|
||||
19.height,
|
||||
],
|
||||
),
|
||||
));
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
shippingViewModel.resetFilters();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer(builder: (BuildContext context, ShippingManagementVM shippingVm, Widget? child) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(title: LocaleKeys.shippingManagement.tr()),
|
||||
body: Container(
|
||||
color: MyColors.backgroundColor,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
16.height,
|
||||
FiltersList(
|
||||
filterList: shippingVm.shippingRequestFilterOptions,
|
||||
onFilterTapped: (index, selectedFilterId) {
|
||||
shippingVm.applyFiltersOnShippingRequests(shippingRequestStatusEnum: selectedFilterId.toShippingStatusEnum());
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
int index = shippingVm.shippingRequestFilterOptions.indexWhere((element) => element.isSelected);
|
||||
await shippingVm.getShippingRequestsListByFilters(shippingStatusEnum: index.toShippingStatusEnum());
|
||||
},
|
||||
child: (shippingVm.state == ViewState.busy)
|
||||
? const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: shippingVm.shippingRequestsList.isEmpty
|
||||
? Center(child: LocaleKeys.noRequeststoShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor))
|
||||
: ListView.separated(
|
||||
itemCount: shippingVm.shippingRequestsList.length,
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemBuilder: (context, index) {
|
||||
ShippingRequestModel shippingRequest = shippingVm.shippingRequestsList[index];
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Utils.statusContainerChip(
|
||||
text: Utils.getNameByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated),
|
||||
chipColor: Utils.getChipColorByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated),
|
||||
),
|
||||
("Request Name | ${shippingRequest.id.toString()}").toText(fontSize: 16),
|
||||
8.height,
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
"customer name".toText(color: MyColors.lightTextColor, fontSize: 14),
|
||||
if (shippingRequest.createdOn != null && shippingRequest.createdOn!.isNotEmpty) ...[
|
||||
" | ${DateTime.parse(shippingRequest.createdOn!).getTimeAgo()}".toText(color: MyColors.lightTextColor, fontSize: 14),
|
||||
],
|
||||
],
|
||||
),
|
||||
const Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18),
|
||||
],
|
||||
),
|
||||
],
|
||||
).onPress(() {
|
||||
buildUpdateShippingStatusBottomSheet(shippingRequestId: shippingRequest.id!);
|
||||
}).toContainer(isShadowEnabled: true);
|
||||
},
|
||||
separatorBuilder: (context, index) => 16.height,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue