Merge remote-tracking branch 'origin/design_3.0_TM_Module_bug_fixes' into design_3.0_TM_Module_bug_fixes

# Conflicts:
#	lib/controllers/api_routes/urls.dart
design_3.0_task_module_new
Sikander Saleem 5 months ago
commit 4c88dce72c

@ -170,7 +170,7 @@ class ProgressFragment extends StatelessWidget {
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
bool isCurrentUserIsNurse = (_userProvider.user!.type == UsersTypes.normal_user);
bool isCurrentUserIsNurse = (_userProvider.user?.type == UsersTypes.normal_user);
return Consumer<DashBoardProvider>(
builder: (context, snapshot, _) {
int total = 0;

@ -159,10 +159,13 @@ class WorkOrderCostModel {
num? sparePartCost;
num? labourCost;
num? travelCost;
num? qAmount;
String? prNo;
String? poNo;
WorkOrderCostModel({this.workOrderId, this.sparePartCost, this.labourCost, this.travelCost});
WorkOrderCostModel({this.workOrderId, this.sparePartCost, this.labourCost, this.travelCost, this.qAmount, this.poNo, this.prNo});
Map<String, dynamic> toJson() {
return {'workOrderId': workOrderId, 'sparePartCost': sparePartCost, 'laborCost': labourCost, 'travelCost': travelCost};
return {'workOrderId': workOrderId, 'sparePartCost': sparePartCost, 'laborCost': labourCost, 'travelCost': travelCost, 'qAmount': qAmount, 'prNo': prNo, 'poNo': poNo};
}
}

@ -96,10 +96,13 @@ class WorkOrderData {
this.labourCost,
this.sparePartCost,
this.travelCost,
this.qAmount,
this.prNo,
this.poNo,
required this.workOrderHistory,
required this.activities,
required this.activityAssetToBeRetireds,
this.itgFormWorkOrderStatus,
this.itgFormWorkOrderStatus,
});
int? requestId;
@ -157,6 +160,9 @@ class WorkOrderData {
num? sparePartCost;
num? labourCost;
num? travelCost;
num? qAmount;
String? prNo;
String? poNo;
List<WorkOrderHistory> workOrderHistory;
List<Activities> activities;
List<dynamic> activityAssetToBeRetireds;
@ -190,6 +196,9 @@ class WorkOrderData {
travelCost: json['travelCost'],
sparePartCost: json['sparePartCost'],
labourCost: json['laborCost'],
qAmount: json['qAmount'],
prNo: json['prNo'],
poNo: json['poNo'],
assetType: json["assetType"] == null ? null : Lookup.fromJson(json["assetType"]),
assignedEmployee: json["assignedEmployee"] == null ? null : WorkOrderAssignedEmployee.fromJson(json["assignedEmployee"]),
lastActivityStatus: json["lastActivityStatus"] != null ? Lookup.fromJson(json["lastActivityStatus"]) : null,
@ -451,15 +460,19 @@ class ActivitySparePart {
int? id;
PartCatalogItem? partCatalogItem;
double? quantity;
double? installQty;
double? returnQty;
String? comment;
List<SparePartAttachments>? acitiySparePartAttachments;
ActivitySparePart({this.id, this.partCatalogItem, this.quantity, this.comment, this.acitiySparePartAttachments});
ActivitySparePart({this.id, this.partCatalogItem, this.quantity,this.installQty,this.returnQty, this.comment, this.acitiySparePartAttachments});
ActivitySparePart.fromJson(Map<String, dynamic> json) {
id = json['id'];
partCatalogItem = json['partCatalogItem'] != null ? new PartCatalogItem.fromJson(json['partCatalogItem']) : null;
quantity = json['quantity'];
installQty = json['installQty'];
returnQty = json['returnQty'];
comment = json['comment'];
if (json['acitiySparePartAttachments'] != null) {
acitiySparePartAttachments = <SparePartAttachments>[];
@ -476,6 +489,8 @@ class ActivitySparePart {
data['partCatalogItem'] = partCatalogItem!.toJson();
}
data['quantity'] = quantity;
data['installQty'] = installQty;
data['returnQty'] = returnQty;
data['comment'] = comment;
if (acitiySparePartAttachments != null) {
data['acitiySparePartAttachments'] = acitiySparePartAttachments!.map((v) => v.toJson()).toList();

@ -167,32 +167,16 @@ class _ActivitiesListViewState extends State<ActivitiesListView> {
backgroundColor: AppColor.primary10,
),
// "drag_icon".toSvgAsset(height: 12, width: 23, color: AppColor.neutral160),
if (userProvider.user!.type == UsersTypes.engineer && requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)
if (userProvider.user!.userID == requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId &&
userProvider.user!.type == UsersTypes.engineer &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"edit_icon".toSvgAsset(height: 21, width: 21).onPress(() {
requestDetailProvider.sparePartHelperModel = SparePartHelperModel(
id: activity.id,
workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId,
comment: activity.activitySparePart?.comment,
sparePartAttachments: activity.activitySparePart?.acitiySparePartAttachments ?? [],
activityStatus: activity.activityStatus,
sparePart: SparePart(
id: activity.activitySparePart?.partCatalogItem?.id,
partName: activity.activitySparePart?.partCatalogItem?.partName,
partNo: activity.activitySparePart?.partCatalogItem?.partNumber,
oracleCode: activity.activitySparePart?.partCatalogItem?.oracleCode),
quantity: activity.activitySparePart?.quantity,
activityStatusId: activity.activityStatus?.id,
);
requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel);
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => const SparePartRequest(),
));
editSparePartRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity);
}),
24.width,
"delete_icon".toSvgAsset(height: 21, width: 21).onPress(() async {
@ -241,26 +225,13 @@ class _ActivitiesListViewState extends State<ActivitiesListView> {
],
],
).toShadowContainer(context, padding: 12, showShadow: false).onPress(() {
// if(requestDetailProvider.currentWorkOrder?.data?.status?.id ==3498){
// requestDetailProvider.sparePartHelperModel = SparePartHelperModel(
// id: activity.id,
// workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId,
// comment: activity.activitySparePart?.comment,
// sparePartAttachments: activity.activitySparePart?.acitiySparePartAttachments ?? [],
// activityStatus: activity.activityStatus,
// sparePart: SparePart(
// id: activity.activitySparePart?.partCatalogItem?.id,
// partName: activity.activitySparePart?.partCatalogItem?.partName,
// partNo: activity.activitySparePart?.partCatalogItem?.partNumber,
// oracleCode: activity.activitySparePart?.partCatalogItem?.oracleCode),
// quantity: activity.activitySparePart?.quantity,
// activityStatusId: activity.activityStatus?.id,
// );
// requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel);
// Navigator.of(context).push(MaterialPageRoute(
// builder: (_) => const SparePartRequest(),
// ));
// }
if (requestDetailProvider.isReadOnlyRequest) {
editSparePartRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity);
}
else if(userProvider.user!.userID == requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId) {
requestDetailProvider.isReadOnlyRequest = true;
editSparePartRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity);
}
});
}
@ -297,13 +268,16 @@ class _ActivitiesListViewState extends State<ActivitiesListView> {
),
// "drag_icon".toSvgAsset(height: 12, width: 23, color: AppColor.neutral160),
if (userProvider.user!.type == UsersTypes.engineer && requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)
if (userProvider.user!.userID == requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId &&
userProvider.user!.type == UsersTypes.engineer &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"edit_icon".toSvgAsset(height: 21, width: 21).onPress(() {
onEditMaintenanceRequestPress(context: context, requestDetailProvider: requestDetailProvider, activity: activity);
editMaintenanceRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity);
}),
24.width,
"delete_icon".toSvgAsset(height: 21, width: 21).onPress(() async {
@ -365,12 +339,16 @@ class _ActivitiesListViewState extends State<ActivitiesListView> {
],
).toShadowContainer(context, padding: 12, showShadow: false).onPress(() {
if (requestDetailProvider.isReadOnlyRequest) {
onEditMaintenanceRequestPress(context: context, requestDetailProvider: requestDetailProvider, activity: activity);
editMaintenanceRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity);
}
else if(userProvider.user!.userID == requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId) {
requestDetailProvider.isReadOnlyRequest = true;
editMaintenanceRequest(context: context, requestDetailProvider: requestDetailProvider, activity: activity);
}
});
}
void onEditMaintenanceRequestPress({required BuildContext context, required ServiceRequestDetailProvider requestDetailProvider, required Activities activity}) async {
void editMaintenanceRequest({required BuildContext context, required ServiceRequestDetailProvider requestDetailProvider, required Activities activity}) async {
Map<String, dynamic> assistEmpData = {};
try {
if (activity.activityMaintenance?.assistantEmployees != null && activity.activityMaintenance!.assistantEmployees!.isNotEmpty) {
@ -428,6 +406,31 @@ class _ActivitiesListViewState extends State<ActivitiesListView> {
}
Navigator.of(context).push(MaterialPageRoute(builder: (_) => MaintenanceRequestForm()));
}
void editSparePartRequest({required BuildContext context, required ServiceRequestDetailProvider requestDetailProvider, required Activities activity}) async {
requestDetailProvider.sparePartHelperModel = SparePartHelperModel(
id: activity.id,
workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId,
comment: activity.activitySparePart?.comment,
sparePartAttachments: activity.activitySparePart?.acitiySparePartAttachments ?? [],
activityStatus: activity.activityStatus,
sparePart: SparePart(
id: activity.activitySparePart?.partCatalogItem?.id,
partName: activity.activitySparePart?.partCatalogItem?.partName,
partNo: activity.activitySparePart?.partCatalogItem?.partNumber,
oracleCode: activity.activitySparePart?.partCatalogItem?.oracleCode),
quantity: activity.activitySparePart?.quantity,
installQty: activity.activitySparePart?.installQty,
returnQty: activity.activitySparePart?.returnQty,
activityStatusId: activity.activityStatus?.id,
);
requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel);
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => const SparePartRequest(),
));
}
}
class ReorderWidget extends StatelessWidget {

@ -68,7 +68,9 @@ class _ServiceRequestDetailViewState extends State<ServiceRequestDetailView> {
initialVisitCard(requestDetailProvider: requestProvider, userProvider: _userProvider),
assetDetailCard(requestDetailProvider: requestProvider, userProvider: _userProvider),
12.height,
if (context.userProvider.user!.type == UsersTypes.engineer) ...[
if (context.userProvider.user!.type == UsersTypes.engineer &&
!requestProvider.isReadOnlyRequest &&
requestProvider.currentWorkOrder!.data!.nextStep?.workOrderNextStepEnum == WorkOrderNextStepEnum.activity) ...[
costCard(context, requestProvider),
12.height,
],
@ -310,14 +312,13 @@ class _ServiceRequestDetailViewState extends State<ServiceRequestDetailView> {
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
],
if (!requestProvider.isReadOnlyRequest) ...[
//workOrderNextStepStatus == WorkOrderNextStepEnum.assignToMe
if (!requestProvider.isReadOnlyRequest && userProvider.user?.type == UsersTypes.engineer && workOrder.nextStep?.workOrderNextStepEnum == WorkOrderNextStepEnum.activity) ...[
8.height,
const Divider().defaultStyle(context),
MultiFilesPicker(
label: context.translation.attachments,
files: _workOrderAttachments,
// attachment: _workOrderAttachments,
buttonColor: AppColor.primary10,
onlyImages: false,
buttonIcon: 'quotation_icon'.toSvgAsset(color: AppColor.primary10),
@ -484,6 +485,18 @@ class _ServiceRequestDetailViewState extends State<ServiceRequestDetailView> {
'Travel Cost: ${provider.currentWorkOrder!.data?.travelCost ?? '-'}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'Quot Amount: ${provider.currentWorkOrder!.data?.qAmount ?? '-'}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'PR No: ${provider.currentWorkOrder!.data?.prNo ?? '-'}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'PO No: ${provider.currentWorkOrder!.data?.poNo ?? '-'}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
],
),
],

@ -43,6 +43,9 @@ class _CostDetailFormScreenState extends State<CostDetailFormScreen> with Ticker
labourCost: currentWorkOrderData.labourCost,
sparePartCost: currentWorkOrderData.sparePartCost,
travelCost: currentWorkOrderData.travelCost,
qAmount: currentWorkOrderData.qAmount,
prNo: currentWorkOrderData.prNo,
poNo: currentWorkOrderData.poNo,
);
}
@ -107,6 +110,48 @@ class _CostDetailFormScreenState extends State<CostDetailFormScreen> with Ticker
},
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
labelText: "Quot Amount",
backgroundColor: AppColor.neutral100,
initialValue: requestDetailProvider.workOrderCostModel?.qAmount?.toString(),
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
textInputType: TextInputType.number,
showShadow: false,
onChange: (value) {
requestDetailProvider.workOrderCostModel?.qAmount = num.parse(value);
},
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
labelText: "PR No",
backgroundColor: AppColor.neutral100,
initialValue: requestDetailProvider.workOrderCostModel?.prNo,
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
textInputType: TextInputType.text,
showShadow: false,
onChange: (value) {
requestDetailProvider.workOrderCostModel?.prNo = value;
},
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
labelText: "PO No",
backgroundColor: AppColor.neutral100,
initialValue: requestDetailProvider.workOrderCostModel?.poNo,
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
textInputType: TextInputType.text,
showShadow: false,
onChange: (value) {
requestDetailProvider.workOrderCostModel?.poNo = value;
},
style: Theme.of(context).textTheme.titleMedium,
),
],
).toShadowContainer(context).paddingAll(16),
).expanded,

@ -27,7 +27,6 @@ import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/views/widgets/images/new_multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
class SparePartRequest extends StatefulWidget {
static const String id = "/spare-part-request";
@ -60,18 +59,18 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
super.initState();
_partsProvider = Provider.of<PartsProvider>(context, listen: false);
_requestDetailProvider = Provider.of<ServiceRequestDetailProvider>(context, listen: false);
_requestDetailProvider?.sparePartHelperModel = SparePartHelperModel(
id: _requestDetailProvider?.sparePartHelperModel?.id ?? 0,
workOrderId: _requestDetailProvider?.sparePartHelperModel?.workOrderId ?? _requestDetailProvider?.currentWorkOrder?.data?.requestId,
sparePartAttachments: _requestDetailProvider?.sparePartHelperModel?.sparePartAttachments ?? [],
sparePart: _requestDetailProvider?.sparePartHelperModel?.sparePart ?? SparePart(),
quantity: _requestDetailProvider?.sparePartHelperModel?.quantity,
installQty: _requestDetailProvider?.sparePartHelperModel?.installQty,
returnQty: _requestDetailProvider?.sparePartHelperModel?.returnQty,
activityStatusId: _requestDetailProvider?.sparePartHelperModel?.activityStatusId ?? statusLookup.id,
activityStatus: _requestDetailProvider?.sparePartHelperModel?.activityStatus ?? statusLookup,
comment: _requestDetailProvider?.sparePartHelperModel?.comment ?? '',
);
// _requestDetailProvider?.sparePartHelperModel = SparePartHelperModel(
// id: _requestDetailProvider?.sparePartHelperModel?.id ?? 0,
// workOrderId: _requestDetailProvider?.sparePartHelperModel?.workOrderId ?? _requestDetailProvider?.currentWorkOrder?.data?.requestId,
// sparePartAttachments: _requestDetailProvider?.sparePartHelperModel?.sparePartAttachments ?? [],
// sparePart: _requestDetailProvider?.sparePartHelperModel?.sparePart ?? SparePart(),
// quantity: _requestDetailProvider?.sparePartHelperModel?.quantity,
// installQty: _requestDetailProvider?.sparePartHelperModel?.installQty,
// returnQty: _requestDetailProvider?.sparePartHelperModel?.returnQty,
// activityStatusId: _requestDetailProvider?.sparePartHelperModel?.activityStatusId ?? statusLookup.id,
// activityStatus: _requestDetailProvider?.sparePartHelperModel?.activityStatus ?? statusLookup,
// comment: _requestDetailProvider?.sparePartHelperModel?.comment ?? '',
// );
_partQtyController.text = _requestDetailProvider?.sparePartHelperModel?.quantity != null ? _requestDetailProvider!.sparePartHelperModel!.quantity!.round().toString() : '';
_installQtyController.text = _requestDetailProvider?.sparePartHelperModel?.installQty != null ? _requestDetailProvider!.sparePartHelperModel!.installQty!.round().toString() : '';
_returnQtyController.text = _requestDetailProvider?.sparePartHelperModel?.returnQty != null ? _requestDetailProvider!.sparePartHelperModel!.returnQty!.round().toString() : '';
@ -83,7 +82,6 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
_files = _requestDetailProvider?.sparePartHelperModel?.sparePartAttachments?.map((e) => MultiFilesPickerModel(e.id!, File(e.name!))).toList() ?? [];
setState(() {});
_spareParts = await _partsProvider!.getPartsListByDisplayName(assetId: _requestDetailProvider?.currentWorkOrder?.data?.asset?.id);
_isLoading = false;
setState(() {});
});
@ -127,100 +125,81 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
child: Column(
children: [
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
context.translation.sparePartDetails.heading5(context),
// 12.height,
// SingleItemDropDownMenu<Lookup, ActivityStatusProvider>(
// context: context,
// height: 56.toScreenHeight,
// title: context.translation.activityStatus,
// showShadow: false,
// backgroundColor: AppColor.neutral100,
// initialValue: requestDetailProvider.sparePartHelperModel?.activityStatus,
// onSelect: (status) {
// requestDetailProvider.sparePartHelperModel?.activityStatus = status;
// },
// ),
12.height,
SingleItemDropDownMenu<SparePart, NullableLoadingProvider>(
context: context,
title: context.translation.part,
staticData: _spareParts,
showShadow: false,
showAsBottomSheet: true,
loading: _isLoading,
initialValue: requestDetailProvider.sparePartHelperModel?.sparePart,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
onSelect: (part) async {
if (part != null) {
requestDetailProvider.sparePartHelperModel?.sparePart = part;
_oracleNoController.text = part.oracleCode ?? '';
requestDetailProvider.updateSparePartHelperModel(_requestDetailProvider?.sparePartHelperModel);
}
},
),
if(requestDetailProvider.sparePartHelperModel?.sparePart?.id!=null)...[
child: IgnorePointer(
ignoring: _requestDetailProvider!.isReadOnlyRequest,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
context.translation.sparePartDetails.heading5(context),
// 12.height,
// SingleItemDropDownMenu<Lookup, ActivityStatusProvider>(
// context: context,
// height: 56.toScreenHeight,
// title: context.translation.activityStatus,
// showShadow: false,
// backgroundColor: AppColor.neutral100,
// initialValue: requestDetailProvider.sparePartHelperModel?.activityStatus,
// onSelect: (status) {
// requestDetailProvider.sparePartHelperModel?.activityStatus = status;
// },
// ),
12.height,
SizedBox(
height: 30.toScreenHeight,
child: Text('View Parts Availability',style:TextStyle(
fontSize: 12.toScreenWidth,
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
color:AppColor.primary10 ,
decorationColor: AppColor.primary10,
decoration: TextDecoration.underline,
)).onPress(
() async {
requestDetailProvider.getStoreAvailabilityById(partId: requestDetailProvider.sparePartHelperModel?.sparePart?.id);
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
SingleItemDropDownMenu<SparePart, NullableLoadingProvider>(
context: context,
title: context.translation.part,
staticData: _spareParts,
showShadow: false,
showAsBottomSheet: true,
loading: _isLoading,
initialValue: requestDetailProvider.sparePartHelperModel?.sparePart,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
onSelect: (part) async {
if (part != null) {
requestDetailProvider.sparePartHelperModel?.sparePart = part;
_oracleNoController.text = part.oracleCode ?? '';
requestDetailProvider.updateSparePartHelperModel(_requestDetailProvider?.sparePartHelperModel);
}
},
),
if (requestDetailProvider.sparePartHelperModel?.sparePart?.id != null) ...[
12.height,
SizedBox(
height: 30.toScreenHeight,
child: Text('View Parts Availability',
style: TextStyle(
fontSize: 12.toScreenWidth,
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
color: AppColor.primary10,
decorationColor: AppColor.primary10,
decoration: TextDecoration.underline,
)).onPress(
() async {
requestDetailProvider.getStoreAvailabilityById(partId: requestDetailProvider.sparePartHelperModel?.sparePart?.id);
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
),
clipBehavior: Clip.antiAliasWithSaveLayer,
builder: (BuildContext context) => PartDetailBottomSheetSheet(),
);
},
clipBehavior: Clip.antiAliasWithSaveLayer,
builder: (BuildContext context) => PartDetailBottomSheetSheet(),
);
},
),
),
),
],
12.height,
AppTextFormField(
controller: _partQtyController,
labelText: context.translation.quantity,
textInputType: TextInputType.number,
labelStyle: AppTextStyles.textFieldLabelStyle,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null,
validator: (value) => value == null || value.isEmpty
? context.translation.requiredField
: Validator.isNumeric(value)
? null
: context.translation.onlyNumbers,
onChange: (value) {
requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(value ?? "");
},
onSaved: (text) {
requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(text ?? "");
},
),
12.height,
if(showInstallAndReturnQty) ...[
],
12.height,
AppTextFormField(
controller: _installQtyController,
labelText: context.translation.installedQty,
controller: _partQtyController,
labelText: context.translation.quantity,
textInputType: TextInputType.number,
labelStyle: AppTextStyles.textFieldLabelStyle,
showWithoutDecoration: true,
@ -229,170 +208,186 @@ class _SparePartRequestState extends State<SparePartRequest> with TickerProvider
validator: (value) => value == null || value.isEmpty
? context.translation.requiredField
: Validator.isNumeric(value)
? null
: context.translation.onlyNumbers,
? null
: context.translation.onlyNumbers,
onChange: (value) {
requestDetailProvider.sparePartHelperModel?.installQty = num.tryParse(value ?? "");
requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(value ?? "");
},
onSaved: (text) {
requestDetailProvider.sparePartHelperModel?.installQty = num.tryParse(text ?? "");
requestDetailProvider.sparePartHelperModel?.quantity = num.tryParse(text ?? "");
},
),
12.height,
if (showInstallAndReturnQty) ...[
AppTextFormField(
controller: _installQtyController,
labelText: context.translation.installedQty,
textInputType: TextInputType.number,
labelStyle: AppTextStyles.textFieldLabelStyle,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null,
validator: (value) => value == null || value.isEmpty
? context.translation.requiredField
: Validator.isNumeric(value)
? null
: context.translation.onlyNumbers,
onChange: (value) {
requestDetailProvider.sparePartHelperModel?.installQty = num.tryParse(value ?? "");
},
onSaved: (text) {
requestDetailProvider.sparePartHelperModel?.installQty = num.tryParse(text ?? "");
},
),
12.height,
AppTextFormField(
controller: _returnQtyController,
labelText: context.translation.returnQty,
textInputType: TextInputType.number,
labelStyle: AppTextStyles.textFieldLabelStyle,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null,
validator: (value) => value == null || value.isEmpty
? context.translation.requiredField
: Validator.isNumeric(value)
? null
: context.translation.onlyNumbers,
onChange: (value) {
requestDetailProvider.sparePartHelperModel?.returnQty = num.tryParse(value ?? "");
},
onSaved: (text) {
requestDetailProvider.sparePartHelperModel?.returnQty = num.tryParse(text ?? "");
},
),
12.height,
],
AppTextFormField(
controller: _returnQtyController,
labelText: context.translation.returnQty,
textInputType: TextInputType.number,
labelStyle: AppTextStyles.textFieldLabelStyle,
controller: _oracleNoController,
labelText: context.translation.oracleNo,
textInputType: TextInputType.number,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null,
validator: (value) => value == null || value.isEmpty
? context.translation.requiredField
: Validator.isNumeric(value)
? null
: context.translation.onlyNumbers,
enable: false,
),
12.height,
AppTextFormField(
initialValue: requestDetailProvider.sparePartHelperModel?.comment,
labelStyle: AppTextStyles.textFieldLabelStyle,
controller: _descriptionController,
showSpeechToText: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
labelText: "Engineer Comment",
alignLabelWithHint: true,
showWithoutDecoration: true,
textInputType: TextInputType.multiline,
onChange: (value) {
requestDetailProvider.sparePartHelperModel?.returnQty = num.tryParse(value ?? "");
requestDetailProvider.sparePartHelperModel?.comment = value;
},
onSaved: (text) {
requestDetailProvider.sparePartHelperModel?.returnQty = num.tryParse(text ?? "");
onSaved: (value) {
requestDetailProvider.sparePartHelperModel?.comment = value;
},
),
12.height,
NewMultiFilesPicker(
label: context.translation.attachQuotation,
files: _files,
buttonIcon: 'quotation_icon'.toSvgAsset(),
buttonColor: AppColor.primary10,
),
],
AppTextFormField(
labelStyle: AppTextStyles.textFieldLabelStyle,
controller: _oracleNoController,
labelText: context.translation.oracleNo,
textInputType: TextInputType.number,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
enable: false,
),
12.height,
AppTextFormField(
initialValue: requestDetailProvider.sparePartHelperModel?.comment,
labelStyle: AppTextStyles.textFieldLabelStyle,
controller: _descriptionController,
showSpeechToText: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90,
labelText: "Engineer Comment",
alignLabelWithHint: true,
showWithoutDecoration: true,
textInputType: TextInputType.multiline,
onChange: (value) {
requestDetailProvider.sparePartHelperModel?.comment = value;
},
onSaved: (value) {
requestDetailProvider.sparePartHelperModel?.comment = value;
},
),
12.height,
NewMultiFilesPicker(
label: context.translation.attachQuotation,
files: _files,
buttonIcon: 'quotation_icon'.toSvgAsset(),
buttonColor: AppColor.primary10,
),
],
).paddingAll(16),
),
8.height,
],
).paddingAll(16),
),
8.height,
],
),
),
).paddingAll(12).expanded,
FooterActionButton.footerContainer(
child: AppFilledButton(
label: _requestDetailProvider?.sparePartHelperModel?.id == 0 ? context.translation.addSparePartActivity : context.translation.updateSparePartActivity,
buttonColor: AppColor.green70,
onPressed: () async {
requestDetailProvider.sparePartHelperModel?.sparePartAttachments?.clear();
for (var pickerObject in _files) {
String fileData =
_isLocalUrl(pickerObject.file.path) ? ("${pickerObject.file.path.split("/").last}|${base64Encode(File(pickerObject.file.path).readAsBytesSync())}") : pickerObject.file.path;
requestDetailProvider.sparePartHelperModel?.sparePartAttachments?.add(SparePartAttachments(id: pickerObject.id, name: fileData));
}
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
int status = -1;
if (_requestDetailProvider?.sparePartHelperModel?.id == 0) {
status = await requestDetailProvider.createActivitySparePart();
} else {
status = await requestDetailProvider.updateActivitySparePart();
}
if (status == 200) {
await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
//this is for hide the dialoge...
Navigator.pop(context);
Navigator.pop(context);
//show this only for add form..
if (!requestDetailProvider.isReadOnlyRequest)
FooterActionButton.footerContainer(
child: AppFilledButton(
label: _requestDetailProvider?.sparePartHelperModel?.id == 0 ? context.translation.addSparePartActivity : context.translation.updateSparePartActivity,
buttonColor: AppColor.green70,
onPressed: () async {
requestDetailProvider.sparePartHelperModel?.sparePartAttachments?.clear();
for (var pickerObject in _files) {
String fileData =
_isLocalUrl(pickerObject.file.path) ? ("${pickerObject.file.path.split("/").last}|${base64Encode(File(pickerObject.file.path).readAsBytesSync())}") : pickerObject.file.path;
requestDetailProvider.sparePartHelperModel?.sparePartAttachments?.add(SparePartAttachments(id: pickerObject.id, name: fileData));
}
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
int status = -1;
if (_requestDetailProvider?.sparePartHelperModel?.id == 0) {
ServiceRequestBottomSheet.addAnotherSpareRequestBottomSheet(context: context);
SizedBox().flushBar(context: context, title: context.translation.sparePartActivitySuccess, message: '');
status = await requestDetailProvider.createActivitySparePart();
} else {
status = await requestDetailProvider.updateActivitySparePart();
}
} else {
Navigator.pop(context);
}
},
)),
if (status == 200) {
await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
//this is for hide the dialoge...
Navigator.pop(context);
Navigator.pop(context);
//show this only for add form..
if (_requestDetailProvider?.sparePartHelperModel?.id == 0) {
ServiceRequestBottomSheet.addAnotherSpareRequestBottomSheet(context: context);
SizedBox().flushBar(context: context, title: context.translation.sparePartActivitySuccess, message: '');
}
} else {
Navigator.pop(context);
}
},
)),
],
),
));
}),
);
}
}
class PartDetailBottomSheetSheet extends StatelessWidget {
PartDetailBottomSheetSheet( {Key? key}) : super(key: key);
PartDetailBottomSheetSheet({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
height: SizeConfig.screenHeight!/2.2,
width: SizeConfig.screenWidth,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
8.height,
'Parts Availability'.heading6(context).paddingOnly(top: 12,start: 12),
Consumer<ServiceRequestDetailProvider>(
builder: (context, requestDetailProvider,child) {
return requestDetailProvider.isLoading
? const CircularProgressIndicator(color: AppColor.primary10).center
: requestDetailProvider.storeAvailability.isEmpty
? const NoDataFound().center
: ListView.separated(
padding: const EdgeInsets.all(16),
itemCount: requestDetailProvider.storeAvailability.length,
separatorBuilder: (czt, index) => 12.height,
itemBuilder: (context, index) {
StoreAvailability model = requestDetailProvider.storeAvailability[index];
return partAvailableQuantityCard(context: context,model:model);
},
);
}
).expanded,
],
),
);
return SizedBox(
height: SizeConfig.screenHeight! / 2.2,
width: SizeConfig.screenWidth,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
8.height,
'Parts Availability'.heading6(context).paddingOnly(top: 12, start: 12),
Consumer<ServiceRequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return requestDetailProvider.isLoading
? const CircularProgressIndicator(color: AppColor.primary10).center
: requestDetailProvider.storeAvailability.isEmpty
? const NoDataFound().center
: ListView.separated(
padding: const EdgeInsets.all(16),
itemCount: requestDetailProvider.storeAvailability.length,
separatorBuilder: (czt, index) => 12.height,
itemBuilder: (context, index) {
StoreAvailability model = requestDetailProvider.storeAvailability[index];
return partAvailableQuantityCard(context: context, model: model);
},
);
}).expanded,
],
),
);
}
Widget partAvailableQuantityCard({required StoreAvailability model,required BuildContext context }){
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Site Name: ${model.siteName??''}'.bodyText2(context).custom(color: AppColor.neutral120),
8.height,
'Store Name: ${model.storeName??''}'.bodyText2(context).custom(color: AppColor.neutral120),
8.height,
'Available Quantity: ${model.availablityQty??''}'.bodyText2(context).custom(color: AppColor.neutral120),
8.height,
]
).toShadowContainer(context, padding: 12, showShadow: false,backgroundColor: AppColor.neutral110);
Widget partAvailableQuantityCard({required StoreAvailability model, required BuildContext context}) {
return Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [
'Site Name: ${model.siteName ?? ''}'.bodyText2(context).custom(color: AppColor.neutral120),
8.height,
'Store Name: ${model.storeName ?? ''}'.bodyText2(context).custom(color: AppColor.neutral120),
8.height,
'Available Quantity: ${model.availablityQty ?? ''}'.bodyText2(context).custom(color: AppColor.neutral120),
8.height,
]).toShadowContainer(context, padding: 12, showShadow: false, backgroundColor: AppColor.neutral110);
}
}

Loading…
Cancel
Save