Merge branch 'design_3.0_loan_module' into design_3.0_asset_delivery_module

# Conflicts:
#	lib/controllers/api_routes/urls.dart
design_3.0_asset_delivery_module
Sikander Saleem 19 hours ago
commit ce873d99a5

@ -7,13 +7,12 @@ class URLs {
// static const host1 = "https://atomsmdev.hmg.com"; // local DEV url
static const host1 = "https://atomsmuat.hmg.com"; // local UAT url
// static String _baseUrl = "$_host/mobile";
// static final String _baseUrl = "$_host/mobile"; // host local UAT
static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis
// static final String _baseUrl = "$_host/v6/mobile"; // for asset delivery module
// static final String _baseUrl = "$_host/mobile"; // host local UAT and for internal audit dev
// static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM
// static final String _baseUrl = "$_host/v5/mobile"; // v5 for data segregation
// static final String _baseUrl = "$_host/v6/mobile"; // for asset delivery module
static const String chatHubUrl = "https://apiderichat.hmg.com/chathub";
@ -394,6 +393,7 @@ class URLs {
static get getMedDepartmentBasedOnSite => "$_baseUrl/TRAFDataSource/GetDepartmentBasedOnSite";
static get getLoanById => '$_baseUrl/Loan/GetLoanById';
static get getLoanByWorkOrderId => '$_baseUrl/Loan/GetLoanByWorkOrderId';
static get addLoan => '$_baseUrl/Loan/AddLoan';

@ -1,3 +1,5 @@
import 'dart:typed_data';
import 'package:test_sa/models/base.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/assistant_employee.dart';
@ -83,6 +85,7 @@ class TaskData {
String? estimationDeliveryDate;
String? reasonOfFSCA;
String? correctiveActionDescription;
String? signature;
TaskContactUser? evaluatorUser;
List<TaskJobActivityEngineerTimer>? taskJobActivityEngineerTimers = [];
TimerModel? taskTimerModel = TimerModel();
@ -126,6 +129,7 @@ class TaskData {
this.alertNo,
this.estimationDeliveryDate,
this.reasonOfFSCA,
this.signature,
this.correctiveActionDescription,
this.evaluatorUser,
this.taskTimePicker});
@ -193,6 +197,7 @@ class TaskData {
alertNo = json['alertNo'];
estimationDeliveryDate = json['estimationDeliveryDate'];
reasonOfFSCA = json['reasonOfFSCA'];
signature = json['signature'];
correctiveActionDescription = json['correctiveActionDescription'];
evaluatorUser = json['evaluatorUser'] != null ? TaskContactUser.fromJson(json['evaluatorUser']) : null;
site = json["site"] == null ? null : Site.fromJson(json["site"]);
@ -239,7 +244,7 @@ class TaskData {
floor = taskData.floor;
department = taskData.department;
room = taskData.room;
signature = taskData.signature;
taskTimerModel = taskData.taskTimerModel;
totalWorkingHours = taskData.totalWorkingHours;
timerModelList = taskData.timerModelList;
@ -350,79 +355,6 @@ class TaskData {
return data;
}
// Map<String, dynamic> toJson() {
// final Map<String, dynamic> data = <String, dynamic>{};
//
// data['id'] = id;
// data['statusValue'] = statusValue;
// data['taskJobNo'] = taskJobNo;
//
// if (userCreated != null) {
// data['userCreated'] = userCreated!.toJson();
// }
//
// if (taskJobContactPersons != null) {
// data['taskJobContactPersons'] = taskJobContactPersons!.map((e) => e.toJson()).toList();
// }
//
// if (taskType != null) {
// data['taskType'] = taskType!.toJson();
// }
//
// if (taskJobStatus != null) {
// data['taskJobStatus'] = taskJobStatus!.toJson();
// }
//
// data['asset'] = asset?.toJson();
// data['site'] = site;
// data['building'] = building;
// data['floor'] = floor;
// data['department'] = department;
// data['room'] = room;
// data['callComment'] = callComment;
//
// if (assignedEngineer != null) {
// data['assignedEngineer'] = assignedEngineer!.toJson();
// }
//
// if (taskJobAssistantEmployees != null) {
// data['taskJobAssistantEmployees'] = taskJobAssistantEmployees!.map((v) => v.toJson()).toList();
// }
// if (taskJobHistories != null) {
// data['taskJobHistories'] = taskJobHistories!.map((e) => e.toJson()).toList();
// }
// if (installationBuilding != null) {
// data['installationBuilding'] = installationBuilding!.toJson();
// }
// data['installationFloor'] = installationFloor;
// data['installationDepartment'] = installationDepartment;
// data['serialNo'] = serialNo;
// data['installationDate'] = installationDate;
// data['completedAction'] = completedAction;
// data['impactStatus'] = impactStatus;
// data['isUserAcknowledge'] = isUserAcknowledge;
// data['typeOfAlert'] = typeOfAlert;
// data['riskLevel'] = riskLevel;
// data['resource'] = resource;
// data['actionNeeded'] = actionNeeded;
// data['alertNo'] = alertNo;
// data['estimationDeliveryDate'] = estimationDeliveryDate;
// data['reasonOfFSCA'] = reasonOfFSCA;
// data['correctiveActionDescription'] = correctiveActionDescription;
//
// if (evaluatorUser != null) {
// data['evaluatorUser'] = evaluatorUser!.toJson();
// }
// if (taskJobActivityEngineerTimers != null) {
// data['taskJobActivityEngineerTimers'] = taskJobActivityEngineerTimers!.map((e) => e.toJson()).toList();
// }
// if (taskJobAttachments != null) {
// data['taskJobAttachments'] = taskJobAttachments?.map((e) => e.toJson()).toList();
// }
//
// return data;
// }
Map<String, dynamic> toEngineerUpdateJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
@ -449,6 +381,9 @@ class TaskData {
}
data['impactStatusId'] = impactStatus?.id;
data['isUserAcknowledge'] = isUserAcknowledge;
if (signature != null) {
data['signature'] = signature;
}
return data;
}
}

@ -6,6 +6,7 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/helper/utils.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/enums/work_order_next_step.dart';
import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart';
@ -16,6 +17,8 @@ import 'package:test_sa/modules/cx_module/chat/chat_provider.dart';
import 'package:test_sa/modules/cx_module/chat/chat_widget.dart';
import 'package:test_sa/modules/cx_module/survey/survey_page.dart';
import 'package:test_sa/modules/loan_module/pages/create_loan_request_page.dart';
import 'package:test_sa/modules/loan_module/pages/loan_equipment_detail_page.dart';
import 'package:test_sa/modules/loan_module/provider/loan_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
@ -104,7 +107,9 @@ class _CMDetailPageState extends State<CMDetailPage> {
(provider.currentWorkOrder?.data?.workOrderContactPerson?.isNotEmpty ?? false)) {
return ChatWidget(
moduleId: widget.moduleId,
isShow: context.settingProvider.isUserFlowMedical && (context.userProvider.isEngineer || context.userProvider.isNurse) && provider.currentWorkOrder?.data?.assignedEmployee != null,
isShow: context.settingProvider.isUserFlowMedical &&
(context.userProvider.isEngineer || context.userProvider.isNurse) &&
provider.currentWorkOrder?.data?.assignedEmployee != null,
isReadOnly: _requestProvider.isReadOnlyRequest,
requestId: widget.requestId.toInt(),
assigneeEmployeeNumber: provider.currentWorkOrder?.data?.assignedEmployee!.employeeId!,
@ -115,23 +120,64 @@ class _CMDetailPageState extends State<CMDetailPage> {
return const SizedBox();
}
}),
isNurse
? IconButton(
icon: 'qr'.toSvgAsset(
height: 24,
width: 24,
),
onPressed: () {
ServiceRequestBottomSheet.getQRCodeBottomSheet(context: context);
},
)
: IconButton(
icon: const Icon(Icons.home),
onPressed: () {
// stopTimer();
Navigator.pop(context);
},
),
if (isNurse)
IconButton(
icon: 'qr'.toSvgAsset(height: 24, width: 24),
onPressed: () {
ServiceRequestBottomSheet.getQRCodeBottomSheet(context: context);
},
)
else ...[
Selector<CMDetailProvider, bool>(
selector: (_, myModel) => myModel.isLoading, // Selects only the userName
builder: (_, isLoading, __) {
if (isLoading) {
return const SizedBox();
} else {
CMDetailProvider provider = Provider.of<CMDetailProvider>(context, listen: false);
//TODO need to verify the check with backend workOrderNextStepEnum
int? statusValue = provider.currentWorkOrder?.data?.status?.value;
WorkOrderNextStepEnum? workOrderNextStepEnum = provider.currentWorkOrder?.data?.nextStep?.workOrderNextStepEnum;
if (statusValue == 2 && workOrderNextStepEnum == WorkOrderNextStepEnum.activity) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
margin: const EdgeInsets.only(left: 2),
decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.neutral30, borderRadius: BorderRadius.circular(16)),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.add, size: 20, color: AppColor.black1E),
Text(
"Loan",
style: AppTextStyles.bodyText2.copyWith(color: AppColor.black1E),
),
4.width,
],
),
).onPress(() async {
LoanProvider loanProvider = Provider.of<LoanProvider>(context, listen: false);
Utils.showLoading(context);
var data = await loanProvider.getLoanByWorkOrderId(widget.requestId);
Utils.hideLoading(context);
if (data == null) {
CMDetailProvider cmProvider = Provider.of<CMDetailProvider>(context, listen: false);
Navigator.push(context, MaterialPageRoute(builder: (context) => CreateLoanRequestPage(workOrderId: widget.requestId, workOrder: cmProvider.currentWorkOrder!.data)));
} else {
Navigator.push(context, MaterialPageRoute(builder: (context) => LoanEquipmentDetailPage(loanId: data.id!)));
}
});
}
return const SizedBox();
}
}),
IconButton(
icon: const Icon(Icons.home),
onPressed: () {
// stopTimer();
Navigator.pop(context);
},
)
],
],
),
body: DefaultTabController(

@ -2,6 +2,8 @@ import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/mapped_sites.dart';
import 'package:test_sa/models/new_models/site.dart';
import 'package:test_sa/models/new_models/traf_department.dart';
import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart';
import 'package:test_sa/models/service_request/supplier_details.dart';
import 'package:test_sa/modules/loan_module/models/medical_department_model.dart';
class LoanFormModel {
@ -12,12 +14,15 @@ class LoanFormModel {
String? requestDescription;
String? model;
String? manufacturer;
bool isNewVendor;
Lookup? loanProvided;
String? vendorName;
String? vendorRepresentativeName;
String? vendorNumber;
String? vendorEmail;
Site? site;
SupplierDetails? supplier;
SuppEngineerWorkOrders? supEngineer;
MedicalDepartmentModel? department;
List<LoanAttachments>? loanAttachment;
MappedSite? mappedSite;
@ -25,6 +30,7 @@ class LoanFormModel {
LoanFormModel({
this.docName,
this.isNewVendor=false,
this.docNumber,
this.docEmail,
this.itemDescription,
@ -38,6 +44,8 @@ class LoanFormModel {
this.vendorEmail,
this.loanAttachment,
this.site,
this.supplier,
this.supEngineer,
this.department,
this.mappedSite,
this.mappedDepartment,
@ -94,6 +102,7 @@ class LoanFormModel {
"vendorNumber": vendorNumber,
"vendorContact": vendorNumber,
"vendorEmail": vendorEmail,
"isNewVendor": isNewVendor,
// 'siteId': site?.id,
'siteId': mappedSite?.id,
// 'departmentId': department?.id,
@ -109,9 +118,7 @@ class LoanAttachments {
num? loanId;
String? attachmentName;
String? attachmentDescription;
LoanAttachments({this.id, this.loanAttachmentTypeId, this.attachmentName, this.loanId, this.attachmentDescription});
LoanAttachments.fromJson(dynamic json) {
id = json['id'];
loanAttachmentTypeId = json['loanAttachmentTypeId'];

@ -0,0 +1,40 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/modules/loan_module/models/loan_form_model.dart';
class LoanInstallationPullOutFormModel {
String? snNo;
DateTime? date;
Uint8List? signature;
List<LoanAttachments>? loanAttachment;
TimerModel? timerModel = TimerModel();
DateTime? startTime;
DateTime? endTime;
double? totalHours;
LoanInstallationPullOutFormModel({
this.loanAttachment,
this.timerModel,
this.snNo,
this.signature,
this.date,
this.startTime,
this.endTime,
this.totalHours,
});
Map<String, dynamic> toJson() {
//Need to check payload parm they need
return {
'snNo': snNo,
'InstallationDate': date?.toIso8601String(),
"loanAttachments": loanAttachment != null ? loanAttachment!.map((v) => v.toJson()).toList() : [],
"signature": signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature!)}" : null,
'startTime': startTime?.toIso8601String(),
'endTime': endTime?.toIso8601String(),
'totalHours': totalHours,
};
}
}

@ -15,6 +15,8 @@ import 'package:test_sa/models/new_models/mapped_sites.dart';
import 'package:test_sa/models/new_models/task_request/task_type_model.dart';
import 'package:test_sa/models/new_models/traf_department.dart';
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart';
import 'package:test_sa/models/service_request/supplier_details.dart';
import 'package:test_sa/modules/cm_module/cm_request_utils.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/loan_module/models/loan_form_model.dart';
@ -28,6 +30,7 @@ import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart
import 'package:test_sa/providers/gas_request_providers/site_provider.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/lookups/department_lookup_provider.dart';
import 'package:test_sa/providers/work_order/vendor_provider.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import '../../../../../../new_views/common_widgets/default_app_bar.dart';
@ -47,9 +50,11 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TaskType? selectedType;
final LoanFormModel _loanFormModel = LoanFormModel();
final LoanFormModel _loanFormModel = LoanFormModel(isNewVendor: false);
TextEditingController commentController = TextEditingController();
TextEditingController vendorPhoneController = TextEditingController();
TextEditingController vendorEmailController = TextEditingController();
bool get isBackUpRequest => widget.workOrderId != null;
@ -61,6 +66,22 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
Provider.of<MedicalDepartmentProvider>(context, listen: false).reset();
Provider.of<LoanPeriodProvider>(context, listen: false).reset();
loanTypes = [Lookup(id: 0, name: "Standard", value: 1), Lookup(id: 1, name: "Backup", value: 2)];
if (isBackUpRequest) {
fillSiteDeptInfo();
}
}
@override
void dispose() {
vendorPhoneController.dispose();
vendorEmailController.dispose();
super.dispose();
}
void fillSiteDeptInfo() {
_loanFormModel.mappedSite = MappedSite.fromJson(widget.workOrder!.site!.toJson());
_loanFormModel.mappedDepartment = TrafDepartment.fromJson(widget.workOrder!.department!.toJson());
}
@override
@ -94,7 +115,7 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
'Asset Information'.addTranslation.bodyText(context).custom(color: AppColor.black10),
8.height,
Text(
'${context.translation.assetName}: ${widget.workOrder!.assetNdModel!.name?.cleanupWhitespace?.capitalizeFirstOfEach}',
'${context.translation.assetName}: ${widget.workOrder!.assetNdModel!.name?.cleanupWhitespace.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
@ -106,11 +127,11 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.model}: ${widget.workOrder!.model?.name!.cleanupWhitespace?.capitalizeFirstOfEach}',
'${context.translation.model}: ${widget.workOrder!.model?.name!.cleanupWhitespace.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.manufacture}: ${widget.workOrder!.manufacturer?.name?.cleanupWhitespace?.capitalizeFirstOfEach}',
'${context.translation.manufacture}: ${widget.workOrder!.manufacturer?.name?.cleanupWhitespace.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
16.height,
@ -274,6 +295,7 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
title: context.translation.site,
initialValue: _loanFormModel.mappedSite,
showShadow: false,
enabled: !isBackUpRequest,
validator: (value) {
if (value == null) return "Please select a site";
return null;
@ -281,13 +303,12 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
backgroundColor: AppColor.fieldBgColor(context),
showAsBottomSheet: true,
onSelect: (value) {
if(value!=null){
if (value != null) {
_loanFormModel.mappedSite = value;
_loanFormModel.mappedDepartment = null;
Provider.of<DepartmentLookupProvider>(context,listen:false).getData(id:_loanFormModel.mappedSite?.id);
Provider.of<DepartmentLookupProvider>(context, listen: false).getData(id: _loanFormModel.mappedSite?.id);
setState(() {});
}
},
),
8.height,
@ -295,6 +316,7 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
context: context,
title: context.translation.department,
showShadow: false,
enabled: !isBackUpRequest,
validator: (value) {
if (value == null) return "Please select a department";
return null;
@ -417,46 +439,136 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
List<Widget> vendorDetailsSection() {
return [
'Vendor Details'.addTranslation.bodyText(context).custom(color: AppColor.black10),
8.height,
AppTextFormField(
initialValue: "",
labelText: "Vendor Name",
validator: (value) {
if ((value ?? "").isEmpty) return "Mandatory";
return null;
},
style: Theme.of(context).textTheme.titleMedium,
backgroundColor: AppColor.fieldBgColor(context),
labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)),
showShadow: false,
textInputType: TextInputType.name,
textInputAction: TextInputAction.next,
onChange: (value) {
_loanFormModel.vendorName = value;
},
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
'Vendor Details'.addTranslation.bodyText(context).custom(color: AppColor.black10),
Row(
children: [
Container(
height: 24,
width: 24,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: AppColor.primary10, // or AppColor.blueStatus(context)
),
alignment: Alignment.center,
child: Icon(
!_loanFormModel.isNewVendor ? Icons.add : Icons.search,
color: Colors.white,
size: 16,
),
),
4.width,
Text(
!_loanFormModel.isNewVendor ? "Add new vendor" : "Select existing vendor",
style: AppTextStyles.bodyText.copyWith(
color: context.isDark ? AppColor.neutral30 : AppColor.neutral50,
// decoration: TextDecoration.underline,
),
),
],
).onPress(() async {
_loanFormModel.supplier = null;
_loanFormModel.vendorName = null;
_loanFormModel.supEngineer = null;
_loanFormModel.vendorRepresentativeName = null;
setState(() {
_loanFormModel.isNewVendor = !_loanFormModel.isNewVendor;
});
}),
],
),
8.height,
AppTextFormField(
initialValue: "",
labelText: "Vendor Representative Name",
validator: (value) {
if ((value ?? "").isEmpty) return "Mandatory";
return null;
},
style: Theme.of(context).textTheme.titleMedium,
backgroundColor: AppColor.fieldBgColor(context),
labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)),
showShadow: false,
textInputType: TextInputType.name,
textInputAction: TextInputAction.next,
onChange: (value) {
_loanFormModel.vendorRepresentativeName = value;
},
),
if (!_loanFormModel.isNewVendor) ...[
SingleItemDropDownMenu<SupplierDetails, VendorProvider>(
context: context,
title: 'Vendor Name'.addTranslation,
backgroundColor: AppColor.fieldBgColor(context),
initialValue: _loanFormModel.supplier,
showAsBottomSheet: true,
validator: (value) {
if (value == null) return "Please select vendor name";
return null;
},
showShadow: false,
showCancel: true,
onSelect: (person) {
_loanFormModel.supplier = person;
_loanFormModel.vendorName = person?.name;
_loanFormModel.supEngineer = null;
_loanFormModel.vendorRepresentativeName = null;
vendorPhoneController.text = person?.contact ?? '';
vendorEmailController.text = person?.email ?? '';
setState(() {});
},
),
8.height,
SingleItemDropDownMenu<SuppPersons, NullableLoadingProvider>(
context: context,
backgroundColor: _loanFormModel.supplier?.suppliername == null
? context.isDark
? AppColor.neutral20
: AppColor.neutral40
: AppColor.fieldBgColor(context),
title: "Representative Name".addTranslation,
showShadow: false,
validator: (value) {
if (value == null) return "Please select representative name";
return null;
},
enabled: _loanFormModel.supplier?.suppPersons?.isNotEmpty ?? false,
staticData: _loanFormModel.supplier?.suppPersons,
showAsBottomSheet: true,
initialValue: _loanFormModel.supEngineer == null ? null : SuppPersons.fromJson(_loanFormModel.supEngineer?.toJson()),
onSelect: (suppPerson) {
if (suppPerson != null) {
_loanFormModel.vendorRepresentativeName = suppPerson.name;
_loanFormModel.supEngineer = SuppEngineerWorkOrders.fromJson(suppPerson.toJson());
setState(() {});
}
},
),
] else ...[
AppTextFormField(
initialValue: "",
labelText: "Vendor Name",
validator: (value) {
if ((value ?? "").isEmpty) return "Mandatory";
return null;
},
style: Theme.of(context).textTheme.titleMedium,
backgroundColor: AppColor.fieldBgColor(context),
labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)),
showShadow: false,
textInputType: TextInputType.name,
textInputAction: TextInputAction.next,
onChange: (value) {
_loanFormModel.vendorName = value;
},
),
8.height,
AppTextFormField(
initialValue: "",
labelText: "Vendor Representative Name",
validator: (value) {
if ((value ?? "").isEmpty) return "Mandatory";
return null;
},
style: Theme.of(context).textTheme.titleMedium,
backgroundColor: AppColor.fieldBgColor(context),
labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)),
showShadow: false,
textInputType: TextInputType.name,
textInputAction: TextInputAction.next,
onChange: (value) {
_loanFormModel.vendorRepresentativeName = value;
},
),
],
8.height,
AppTextFormField(
initialValue: "",
controller: vendorPhoneController,
labelText: "Vendor Number",
validator: (value) {
if ((value ?? "").isEmpty) return "Mandatory";
@ -474,7 +586,7 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
),
8.height,
AppTextFormField(
initialValue: "",
controller: vendorEmailController,
labelText: "Vendor Email",
validator: (value) {
if ((value ?? "").isEmpty) {

@ -0,0 +1,187 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/loan_module/models/loan_installation_pullout_form_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
class InstallationPullOutFormView extends StatefulWidget {
final bool isPullout;
final String? createdDate;
const InstallationPullOutFormView({super.key, required this.isPullout, this.createdDate});
@override
State<InstallationPullOutFormView> createState() => _InstallationPullOutFormViewState();
}
class _InstallationPullOutFormViewState extends State<InstallationPullOutFormView> {
final _formKey = GlobalKey<FormState>();
final _snController = TextEditingController();
List<GenericAttachmentModel> _attachments = [];
final _formData = LoanInstallationPullOutFormModel();
@override
void dispose() {
_snController.dispose();
super.dispose();
}
void _pickInstallationDate(DateTime date) async {
final time = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
if (time == null) return;
setState(() {
_formData.date = DateTime(
date.year,
date.month,
date.day,
time.hour,
time.minute,
);
});
}
void _onSignatureChanged(Uint8List signature) {
if (signature.isEmpty) return;
setState(() {
_formData.signature = signature;
});
}
void _submitForm() {
if (!_formKey.currentState!.validate()) return;
//Validation if required .
// if (_formData.date == null) {
// context.showSnackBar('Please select installation date');
// return;
// }
//
// if (_formData.signature == null || _formData.signature!.isEmpty) {
// context.showSnackBar('Signature is required');
// return;
// }
_formData.snNo = _snController.text;
}
void updateTimer({TimerModel? timer}) {
if (timer?.startAt != null && timer?.endAt != null) {
final start = timer!.startAt!;
final end = timer.endAt!;
final difference = end.difference(start);
final totalHours = difference.inSeconds / 3600.0;
_formData.startTime = start;
_formData.endTime = end;
_formData.totalHours = totalHours;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: widget.isPullout ? null : DefaultAppBar(title: 'Installation Report'.addTranslation),
body: SafeArea(
child: Form(
key: _formKey,
child: Column(
children: [
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (!widget.isPullout) ...[
AppTextFormField(
controller: _snController,
labelText: context.translation.snNo,
backgroundColor: AppColor.fieldBgColor(context),
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
hintStyle: AppTextStyles.textFieldLabelStyle,
textInputType: TextInputType.text,
textInputAction: TextInputAction.next,
showShadow: false,
validator: (v) => (v == null || v.isEmpty) ? 'Required' : null,
),
8.height,
],
ADatePicker(
label: !widget.isPullout ? "Installation Date".addTranslation : "Validation Date".addTranslation,
hideShadow: true,
backgroundColor: AppColor.fieldBgColor(context),
to: DateTime.now().add(const Duration(days: 365)),
formatDateWithTime: true,
onDatePicker: _pickInstallationDate,
),
8.height,
AppTimer(
label: context.translation.workingHours,
timer: _formData.timerModel,
// pickerFromDate: DateTime.tryParse(widget.createdDate ?? ''),
pickerFromDate: DateTime(DateTime.now().year, DateTime.now().month, 1),
pickerTimer: _formData.timerModel,
showTimer: false,
onPick: (timer) {
updateTimer(timer: timer);
},
width: double.infinity,
decoration: BoxDecoration(
color: AppColor.fieldBgColor(context),
borderRadius: BorderRadius.circular(10),
),
timerProgress: (isRunning) {},
onChange: (timer) async {
updateTimer(timer: timer);
return true;
},
),
ESignature(
title: 'End-user signature'.addTranslation,
backgroundColor: AppColor.fieldBgColor(context),
showShadow: false,
oldSignature: '',
newSignature: _formData.signature,
onChange: _onSignatureChanged,
),
24.height,
AttachmentPicker(
label: context.translation.attachments,
attachment: _attachments,
),
],
).toShadowContainer(context, borderRadius: 20),
).expanded,
FooterActionButton.footerContainer(
context: context,
child: AppFilledButton(
buttonColor: AppColor.primary10,
label: context.translation.submitRequest,
onPressed: _submitForm,
),
),
],
),
),
),
);
}
}

@ -0,0 +1,87 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/modules/loan_module/models/loan_request_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/widgets/images/files_list.dart';
class InstallationDetailsView extends StatelessWidget {
final LoanRequestModel loanData;
const InstallationDetailsView({super.key, required this.loanData});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
detailContent(
context: context,
heading: 'Updates SN:',
label: loanData.installationDate??'-'
),
detailContent(
context: context,
heading: 'Installation Date',
label: loanData.installationDate??'-'
),
],
),
12.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
detailContent(
context: context,
heading: 'Start Time',
label: loanData.installationDate??'-'
),
detailContent(
context: context,
heading: 'End Time',
label: loanData.installationDate??'-'
),
],
),
12.height,
detailContent(
context: context,
heading: 'Total Time',
label: loanData.installationDate??'-'
),
if (loanData.loanAttachments!.isNotEmpty) ...[
12.height,
Text(
"Uploads Phase 2 docs".addTranslation,
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
8.height,
FilesList(images: loanData.loanAttachments?.map((e) => URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList() ?? []),
],
],
).toShadowContainer(context, borderRadius: 20),
);
}
Widget detailContent({required BuildContext context, required String label, required String heading}) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
heading.bodyText(context).custom(color: AppColor.neutral120),
6.height,
//TODO Need to check which value need to show here
label.bodyText(context).custom(color: AppColor.neutral120),
],
);
}
}

@ -1,5 +1,3 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
@ -9,23 +7,18 @@ import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/system_internal_audit_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/update_equipment_internal_audit_page.dart';
import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/update_system_internal_audit_page.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart';
import 'package:test_sa/modules/loan_module/models/loan_attachment_model.dart';
import 'package:test_sa/modules/loan_module/pages/pullout_detail_page.dart';
import 'package:test_sa/modules/loan_module/provider/loan_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
import '../models/loan_request_model.dart';
import 'installation_pullout_form_view.dart';
class LoanEquipmentDetailPage extends StatelessWidget {
static const String id = "/loan-equipment-detail-page";
@ -46,50 +39,73 @@ class LoanEquipmentDetailPage extends StatelessWidget {
List<LoanAttachmentModel> allAttachments = snapshot.data!.loanAttachments!;
return ListView(
padding: const EdgeInsets.all(16),
return Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
ListView(
padding: const EdgeInsets.all(16),
children: [
Row(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
StatusLabel(
label: snapshot.data!.loanStatusName!,
textColor: AppColor.getRequestStatusTextColorByName(context, snapshot.data!.loanStatusName!),
backgroundColor: AppColor.getRequestStatusColorByName(context, snapshot.data!.loanStatusName!),
),
1.width.expanded,
Text(
snapshot.data!.createdDate?.toServiceRequestCardFormat ?? "-",
textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
StatusLabel(
label: snapshot.data!.loanStatusName!,
textColor: AppColor.getRequestStatusTextColorByName(context, snapshot.data!.loanStatusName!),
backgroundColor: AppColor.getRequestStatusColorByName(context, snapshot.data!.loanStatusName!),
),
1.width.expanded,
Text(
snapshot.data!.createdDate?.toServiceRequestCardFormat ?? "-",
textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
),
],
),
12.height,
...requesterDetails(context, snapshot.data!),
12.height,
...requestDetails(context, snapshot.data!),
12.height,
...assetDetails(context, snapshot.data!),
12.height,
...installationDetails(context, snapshot.data!),
12.height,
...doctorDetails(context, snapshot.data!),
12.height,
...vendorDetails(context, snapshot.data!),
if (allAttachments.isNotEmpty) ...[
const Divider().defaultStyle(context),
Text(
"Attachments".addTranslation,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
FilesList(images: allAttachments.map((e) => URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList() ?? []),
],
],
),
12.height,
...requesterDetails(context, snapshot.data!),
12.height,
...requestDetails(context, snapshot.data!),
12.height,
...assetDetails(context, snapshot.data!),
12.height,
...installationDetails(context, snapshot.data!),
12.height,
...doctorDetails(context, snapshot.data!),
12.height,
...vendorDetails(context, snapshot.data!),
if (allAttachments.isNotEmpty) ...[
const Divider().defaultStyle(context),
Text(
"Attachments".addTranslation,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
FilesList(images: allAttachments.map((e) => URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList() ?? []),
],
).toShadowContainer(context, padding: 12),
],
).toShadowContainer(context, padding: 12),
).expanded,
// if (context.userProvider.isEngineer && (snapshot.data?.loanStatusValue == 5 || snapshot.data?.loanStatusValue == 8))
// FooterActionButton.footerContainer(
// context: context,
// child: AppFilledButton(
// onPressed: () async {
// if (snapshot.data?.loanStatusValue == 5) {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => PullOutDetailsPage(
// loanData: snapshot.data,
// )));
// return;
// }
// Navigator.push(context, MaterialPageRoute(builder: (context) => const InstallationPullOutFormView(isPullout: false)));
// },
// label: snapshot.data?.loanStatusValue == 5 ? 'Installation Report' : 'PullOut Report',
// ),
// )
],
);
}),

@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/modules/loan_module/models/loan_request_model.dart';
import 'package:test_sa/modules/loan_module/pages/installation_pullout_form_view.dart';
import 'package:test_sa/modules/loan_module/pages/intallation_details_view.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
class PullOutDetailsPage extends StatefulWidget {
final LoanRequestModel? loanData;
PullOutDetailsPage({Key? key, required this.loanData}) : super(key: key);
@override
_PullOutDetailsPageState createState() {
return _PullOutDetailsPageState();
}
}
class _PullOutDetailsPageState extends State<PullOutDetailsPage> {
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: DefaultAppBar(
title: 'Loan Request'.addTranslation,
),
body: DefaultTabController(
length: 2,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight),
decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10)),
child: TabBar(
padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth),
labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelStyle: AppTextStyles.bodyText,
labelStyle: AppTextStyles.bodyText,
indicatorPadding: EdgeInsets.zero,
indicatorSize: TabBarIndicatorSize.tab,
dividerColor: Colors.transparent,
indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7)),
onTap: (index) {
// setState(() {});
},
tabs: [
Tab(text: 'Installation'.addTranslation, height: 57.toScreenHeight),
Tab(text: 'Pull Out'.addTranslation, height: 57.toScreenHeight),
],
),
),
12.height,
TabBarView(
children: [
Align(
alignment: Alignment.topCenter,
child: InstallationDetailsView(
loanData: widget.loanData!,
),
),
const InstallationPullOutFormView(isPullout: true),
],
).expanded,
],
),
));
}
}

@ -35,4 +35,17 @@ class LoanProvider extends ChangeNotifier {
}
return loanData;
}
Future<LoanRequestModel?> getLoanByWorkOrderId(int id) async {
LoanRequestModel? loanData;
try {
Response response = await ApiManager.instance.get(URLs.getLoanByWorkOrderId + "?woId=$id", enableToastMessage: false);
if (response.statusCode >= 200 && response.statusCode < 300) {
loanData = LoanRequestModel.fromJson(json.decode(response.body)["data"]);
}
} catch (error) {
print(error);
}
return loanData;
}
}

@ -47,10 +47,10 @@ class _TaskRequestDetailsViewState extends State<TaskRequestDetailsView> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
getTaskData();
});
super.initState();
}
@override

@ -3,6 +3,7 @@ import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
@ -35,6 +36,7 @@ import 'package:test_sa/providers/task_request_provider/task_job_provider.dart';
import 'package:test_sa/providers/task_request_provider/task_request_provider.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
@ -65,6 +67,7 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
String comments = '';
List<TimerHistoryModel> timerList = [];
double totalWorkingHours = 0;
Uint8List? newSignature;
@override
void initState() {
@ -152,12 +155,24 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
if (taskProvider.taskRequestModel?.taskType?.isRecallAndAlert == true) ...[
recallAlertTypeWidget(taskModel: taskProvider.taskRequestModel!),
],
// if (previousComments.isNotEmpty) ...[
// 'Previous Comments'.bodyText2(context).custom(color: AppColor.neutral50),
// 8.height,
//Not good approach need to use enums ....
if (taskProvider.taskRequestModel?.taskType?.typeName == "PullOut") ...[
ESignature(
title: "End-user signature",
backgroundColor: AppColor.fieldBgColor(context),
showShadow: false,
oldSignature: taskProvider.taskRequestModel?.signature,
newSignature: newSignature,
onSaved: (signature) {
newSignature = signature;
if (signature == null || signature.isEmpty) return;
taskProvider.taskRequestModel?.signature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
},
),
8.height,
],
buildPreviousComments(taskProvider: taskProvider),
// 8.height,
// ],
AppTextFormField(
initialValue: "",
labelText: context.translation.technicalComment,
@ -186,7 +201,6 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
TaskRequestAssistantEmployeeList(
assetId: taskProvider.taskRequestModel?.asset?.id,
createdDate: widget.createdDate ?? '',
//widget.requestDetails?.date
assistantEmployeeList: taskProvider.taskRequestModel?.taskJobAssistantEmployees,
cardPadding: 0,
onListChanged: (updatedList) {
@ -233,15 +247,9 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
void _updateTask({required BuildContext context, required int status}) async {
TaskRequestProvider taskRequestProvider = Provider.of<TaskRequestProvider>(context, listen: false);
_formKey.currentState?.save();
TaskData? taskModel = TaskData.copyWith(taskRequestProvider.taskRequestModel!);
taskModel?.statusValue = status;
// taskModel.taskTimePicker = taskRequestProvider.taskRequestModel?.taskTimePicker;
// taskModel.totalWorkingHours = taskRequestProvider.taskRequestModel?.totalWorkingHours;
// taskModel.taskTimerModel = taskRequestProvider.taskRequestModel?.taskTimerModel;
// taskModel.timerModelList = taskRequestProvider.taskRequestModel?.timerModelList;
taskModel.statusValue = status;
if (validate(model: taskModel)) {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
@ -253,10 +261,10 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
String fileName = CMRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? '';
taskAttachment.add(TaskJobAttachment(id: item.id, name: fileName));
}
taskModel?.taskJobAttachments = taskAttachment;
taskModel.taskJobAttachments = taskAttachment;
if (taskModel?.taskTimePicker != null) {
int durationInSecond = taskModel!.taskTimePicker!.endAt!.difference(taskModel.taskTimePicker!.startAt!).inSeconds;
if (taskModel.taskTimePicker != null) {
int durationInSecond = taskModel.taskTimePicker!.endAt!.difference(taskModel.taskTimePicker!.startAt!).inSeconds;
taskModel.taskJobActivityEngineerTimers?.add(
TaskJobActivityEngineerTimer(
id: 0,
@ -267,11 +275,10 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
),
);
}
taskModel?.timerModelList?.forEach((timer) {
taskModel.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
taskModel.taskJobActivityEngineerTimers?.add(
TaskJobActivityEngineerTimer (
TaskJobActivityEngineerTimer(
id: 0, startDate: timer.startAt!.toIso8601String(), endDate: timer.endAt?.toIso8601String(), totalWorkingHour: ((durationInSecond) / 60 / 60), comment: timer.comments ?? comments),
);
});

@ -117,6 +117,7 @@ class _CreateTRAFRequestPageState extends State<CreateTRAFRequestPage> {
// trafRequest?.qty = 0;
} else if (requestType?.value == 2) {
trafRequest?.assetNDId = null;
trafRequest?.qty = 1;
}
setState(() {});
},
@ -133,6 +134,23 @@ class _CreateTRAFRequestPageState extends State<CreateTRAFRequestPage> {
// setState(() {});
},
),
12.height,
AppTextFormField(
initialValue: trafRequest?.qty?.toString() ?? "",
makeMultiLinesNull: true,
labelText: "Quantity",
validator: (value) {
if ((value ?? "").isEmpty) return "Mandatory";
return null;
},
backgroundColor: AppColor.fieldBgColor(context),
labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)),
showShadow: false,
textInputType: TextInputType.number,
onChange: (value) {
trafRequest?.qty = int.parse(value);
},
),
],
if (requestType?.value == 2) ...[
12.height,

@ -6,28 +6,13 @@ import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/controllers/providers/api/hospitals_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/building.dart';
import 'package:test_sa/models/new_models/department.dart';
import 'package:test_sa/models/new_models/floor.dart';
import 'package:test_sa/models/new_models/site.dart';
import 'package:test_sa/models/new_models/task_request/task_request_model.dart';
import 'package:test_sa/models/new_models/task_request/task_type_model.dart';
import 'package:test_sa/models/service_request/pending_service_request_model.dart';
import 'package:test_sa/models/service_request/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/service_request/service_request_search.dart';
import 'package:test_sa/models/service_request/spare_parts.dart';
import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart';
import 'package:test_sa/models/service_request/supplier_engineer_model.dart';
import 'package:test_sa/models/timer_model.dart';
import '../../models/service_request/search_work_order.dart';
import '../../models/service_request/wo_call_request.dart';
import '../../models/user.dart';
import '../../new_views/common_widgets/app_lazy_loading.dart';
class TaskRequestProvider extends ChangeNotifier {

Loading…
Cancel
Save