You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			412 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			412 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Dart
		
	
import 'dart:convert';
 | 
						|
import 'dart:io';
 | 
						|
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
import 'package:fluttertoast/fluttertoast.dart';
 | 
						|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
 | 
						|
import 'package:provider/provider.dart';
 | 
						|
import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
 | 
						|
import 'package:test_sa/controllers/localization/localization.dart';
 | 
						|
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
 | 
						|
import 'package:test_sa/controllers/providers/api/user_provider.dart';
 | 
						|
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
 | 
						|
import 'package:test_sa/controllers/validator/validator.dart';
 | 
						|
import 'package:test_sa/extensions/int_extensions.dart';
 | 
						|
import 'package:test_sa/extensions/widget_extensions.dart';
 | 
						|
import 'package:test_sa/models/device/device.dart';
 | 
						|
import 'package:test_sa/models/service_request/service_request.dart';
 | 
						|
import 'package:test_sa/models/subtitle.dart';
 | 
						|
import 'package:test_sa/views/app_style/colors.dart';
 | 
						|
import 'package:test_sa/views/widgets/app_text_form_field.dart';
 | 
						|
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
 | 
						|
import 'package:test_sa/views/widgets/buttons/app_button.dart';
 | 
						|
import 'package:test_sa/views/widgets/equipment/device_button.dart';
 | 
						|
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
 | 
						|
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
 | 
						|
import 'package:test_sa/views/widgets/sound/record_sound.dart';
 | 
						|
import 'package:test_sa/views/widgets/speech_to_text/speech_to_text.dart';
 | 
						|
import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart';
 | 
						|
import 'package:test_sa/views/widgets/status/service_request/service_request_priority_mune.dart';
 | 
						|
import 'package:test_sa/views/widgets/status/service_request/service_request_through_mune.dart';
 | 
						|
import 'package:test_sa/views/widgets/status/service_request/service_request_types_mune.dart';
 | 
						|
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
 | 
						|
 | 
						|
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_through_provider.dart';
 | 
						|
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_type_provider.dart';
 | 
						|
import '../../../app_style/sizing.dart';
 | 
						|
import '../../../widgets/date_and_time/date_picker.dart';
 | 
						|
import '../../../widgets/status/service_request/service_request_first_action.dart';
 | 
						|
import '../../../widgets/status/service_request/service_request_loan_availability.dart';
 | 
						|
 | 
						|
class CreateRequestPage extends StatefulWidget {
 | 
						|
  static const String id = "/create-request";
 | 
						|
  final ServiceRequest serviceRequest;
 | 
						|
 | 
						|
  const CreateRequestPage({this.serviceRequest, Key key}) : super(key: key);
 | 
						|
 | 
						|
  @override
 | 
						|
  CreateRequestPageState createState() => CreateRequestPageState();
 | 
						|
}
 | 
						|
 | 
						|
class CreateRequestPageState extends State<CreateRequestPage> {
 | 
						|
  double _height;
 | 
						|
  UserProvider _userProvider;
 | 
						|
  SettingProvider _settingProvider;
 | 
						|
  ServiceRequestsProvider _serviceRequestsProvider;
 | 
						|
  ServiceRequest _serviceRequest;
 | 
						|
  final List<File> _deviceImages = [];
 | 
						|
  bool _isLoading = false;
 | 
						|
  bool _showDatePicker = false;
 | 
						|
  Device _device;
 | 
						|
  Subtitle _subtitle;
 | 
						|
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
 | 
						|
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
 | 
						|
  TextEditingController _maintenanceController, _commentController, _reviewCommentController;
 | 
						|
  DateTime _dateTime;
 | 
						|
 | 
						|
  @override
 | 
						|
  void initState() {
 | 
						|
    _maintenanceController = TextEditingController();
 | 
						|
    _commentController = TextEditingController();
 | 
						|
    if (widget.serviceRequest != null) {
 | 
						|
      _serviceRequest = widget.serviceRequest;
 | 
						|
      _device = _serviceRequest.device;
 | 
						|
      _deviceImages.addAll(_serviceRequest.devicePhotos.map((e) => File(e)).toList());
 | 
						|
      _showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction.name == "Need a visit";
 | 
						|
    } else {
 | 
						|
      _serviceRequest = ServiceRequest();
 | 
						|
    }
 | 
						|
    super.initState();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void dispose() {
 | 
						|
    _maintenanceController.dispose();
 | 
						|
    _commentController.dispose();
 | 
						|
    super.dispose();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    _height = MediaQuery.of(context).size.height;
 | 
						|
    _userProvider = Provider.of<UserProvider>(context);
 | 
						|
    _settingProvider = Provider.of<SettingProvider>(context);
 | 
						|
    _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
 | 
						|
    _subtitle = AppLocalization.of(context).subtitle;
 | 
						|
    return Scaffold(
 | 
						|
      key: _scaffoldKey,
 | 
						|
      body: SafeArea(
 | 
						|
        child: LoadingManager(
 | 
						|
          isLoading: _isLoading,
 | 
						|
          isFailedLoading: false,
 | 
						|
          stateCode: 200,
 | 
						|
          onRefresh: () async {},
 | 
						|
          child: Form(
 | 
						|
            key: _formKey,
 | 
						|
            child: Stack(
 | 
						|
              children: [
 | 
						|
                ListView(
 | 
						|
                  children: [
 | 
						|
                    //AppNameBar(),
 | 
						|
                    const SizedBox(height: 16),
 | 
						|
                    Hero(
 | 
						|
                      tag: "logo",
 | 
						|
                      child: Image(
 | 
						|
                        height: _height / 6,
 | 
						|
                        image: const AssetImage("assets/images/logo.png"),
 | 
						|
                      ),
 | 
						|
                    ),
 | 
						|
                    Center(
 | 
						|
                      child: Padding(
 | 
						|
                        padding: const EdgeInsets.all(8.0),
 | 
						|
                        child: Text(
 | 
						|
                          widget.serviceRequest == null ? _subtitle.newServiceRequest : _subtitle.updateServiceRequest,
 | 
						|
                          style: Theme.of(context).textTheme.headline5.copyWith(color: AColors.cyan, fontWeight: FontWeight.w600),
 | 
						|
                        ),
 | 
						|
                      ),
 | 
						|
                    ),
 | 
						|
                    Column(
 | 
						|
                      crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                      children: [
 | 
						|
                        12.height,
 | 
						|
                        _userProvider.user.clientId == null
 | 
						|
                            ? const SizedBox.shrink()
 | 
						|
                            : ATextFormField(
 | 
						|
                                enable: false,
 | 
						|
                                initialValue: _userProvider.user.clientName ?? _subtitle.noHospitalFound,
 | 
						|
                                hintText: _subtitle.hospital,
 | 
						|
                                prefixIconData: FontAwesomeIcons.hospital,
 | 
						|
                                style: Theme.of(context).textTheme.subtitle1,
 | 
						|
                              ),
 | 
						|
                        12.height,
 | 
						|
                        _userProvider.user.departmentId == null || (_userProvider.user?.departmentId?.isEmpty ?? false)
 | 
						|
                            ? const SizedBox.shrink()
 | 
						|
                            : Container(
 | 
						|
                                padding: const EdgeInsets.all(12),
 | 
						|
                                decoration: BoxDecoration(
 | 
						|
                                  color: const Color(0xfff5f5f5),
 | 
						|
                                  border: Border.all(
 | 
						|
                                    color: const Color(0xffefefef),
 | 
						|
                                  ),
 | 
						|
                                  borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
 | 
						|
                                ),
 | 
						|
                                child: Row(
 | 
						|
                                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
						|
                                  children: [
 | 
						|
                                    Column(
 | 
						|
                                      crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                                      children: _userProvider.user.departmentName
 | 
						|
                                              ?.map(
 | 
						|
                                                (e) => Text(
 | 
						|
                                                  e?.trim() ?? "",
 | 
						|
                                                  style: Theme.of(context).textTheme.titleMedium.copyWith(color: AColors.black),
 | 
						|
                                                ),
 | 
						|
                                              )
 | 
						|
                                              ?.toList() ??
 | 
						|
                                          [],
 | 
						|
                                    ),
 | 
						|
                                    Icon(
 | 
						|
                                      FontAwesomeIcons.hospitalUser,
 | 
						|
                                      size: 20 * AppStyle.getScaleFactor(context),
 | 
						|
                                      color: const Color(0xff2e303a),
 | 
						|
                                    ),
 | 
						|
                                  ],
 | 
						|
                                ),
 | 
						|
                              ),
 | 
						|
                        12.height,
 | 
						|
                        DeviceButton(
 | 
						|
                          device: _device,
 | 
						|
                          onDevicePick: (device) {
 | 
						|
                            _device = device;
 | 
						|
                            setState(() {});
 | 
						|
                          },
 | 
						|
                        ),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 8,
 | 
						|
                        ),
 | 
						|
                        const ASubTitle("Priority"),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 4,
 | 
						|
                        ),
 | 
						|
                        ServiceRequestPriorityMenu(
 | 
						|
                          initialValue: widget.serviceRequest.priority,
 | 
						|
                          onSelect: (status) {
 | 
						|
                            _serviceRequest.priority = status;
 | 
						|
                          },
 | 
						|
                          enabled: widget.serviceRequest == null ? true : false,
 | 
						|
                        ),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 8,
 | 
						|
                        ),
 | 
						|
                        const ASubTitle("Equipment Status"),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 4,
 | 
						|
                        ),
 | 
						|
                        ServiceRequestDefectTypesMenu(
 | 
						|
                          initialValue: _serviceRequest.defectType,
 | 
						|
                          onSelect: (status) {
 | 
						|
                            _serviceRequest.defectType = status;
 | 
						|
                          },
 | 
						|
                          enabled: widget.serviceRequest == null ? true : false,
 | 
						|
                        ),
 | 
						|
                        12.height,
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 8,
 | 
						|
                        ),
 | 
						|
                        const ASubTitle("Type of Request"),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 4,
 | 
						|
                        ),
 | 
						|
                        ServiceRequestTypesMenu(
 | 
						|
                          initialValue: _serviceRequest.type,
 | 
						|
                          onSelect: (status) {
 | 
						|
                            _serviceRequest.type = status;
 | 
						|
                          },
 | 
						|
                          enabled: false,
 | 
						|
                          withDefaultItem: widget.serviceRequest == null,
 | 
						|
                        ),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 8,
 | 
						|
                        ),
 | 
						|
                        const ASubTitle("Through"),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 4,
 | 
						|
                        ),
 | 
						|
                        ServiceRequestedThroughMenu(
 | 
						|
                          initialValue: _serviceRequest.requestedThrough,
 | 
						|
                          enabled: false,
 | 
						|
                        ),
 | 
						|
                        if (widget.serviceRequest != null) 12.height,
 | 
						|
                        if (widget.serviceRequest != null) const ASubTitle("First Action"),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 4,
 | 
						|
                        ),
 | 
						|
                        if (widget.serviceRequest != null)
 | 
						|
                          ServiceRequestedFirstAction(
 | 
						|
                            initialValue: _serviceRequest.firstAction,
 | 
						|
                            onSelect: (status) {
 | 
						|
                              _dateTime = null;
 | 
						|
                              _serviceRequest.firstAction = status;
 | 
						|
                              _showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction.name == "Need a visit";
 | 
						|
                              _serviceRequestsProvider.notifyListeners();
 | 
						|
                            },
 | 
						|
                          ),
 | 
						|
                        if (_showDatePicker) 12.height,
 | 
						|
                        if (_showDatePicker)
 | 
						|
                          ADatePicker(
 | 
						|
                            date: _dateTime,
 | 
						|
                            from: DateTime.now(),
 | 
						|
                            onDatePicker: (date) {
 | 
						|
                              _dateTime = date;
 | 
						|
                              setState(() {});
 | 
						|
                            },
 | 
						|
                          ),
 | 
						|
                        if (widget.serviceRequest != null) 12.height,
 | 
						|
                        if (widget.serviceRequest != null) const ASubTitle("Loan Availability"),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 4,
 | 
						|
                        ),
 | 
						|
                        if (widget.serviceRequest != null)
 | 
						|
                          ServiceRequestedLoanAvailability(
 | 
						|
                            initialValue: _serviceRequest.loanAvailability,
 | 
						|
                            onSelect: (status) {
 | 
						|
                              _serviceRequest.loanAvailability = status;
 | 
						|
                            },
 | 
						|
                          ),
 | 
						|
                        12.height,
 | 
						|
                        if (widget.serviceRequest != null) const ASubTitle("Comments"),
 | 
						|
                        const SizedBox(
 | 
						|
                          height: 4,
 | 
						|
                        ),
 | 
						|
                        if (widget.serviceRequest != null)
 | 
						|
                          ATextFormField(
 | 
						|
                            controller: _reviewCommentController,
 | 
						|
                            initialValue: _serviceRequest.reviewComment,
 | 
						|
                            hintText: _subtitle.comment,
 | 
						|
                            style: Theme.of(context).textTheme.titleMedium,
 | 
						|
                            textInputType: TextInputType.multiline,
 | 
						|
                            onSaved: (value) {
 | 
						|
                              _serviceRequest.reviewComment = value;
 | 
						|
                            },
 | 
						|
                            enable: widget.serviceRequest != null ? false : true,
 | 
						|
                          ),
 | 
						|
                        12.height,
 | 
						|
                        MultiFilesPicker(
 | 
						|
                          label: _subtitle.deviceFiles,
 | 
						|
                          files: _deviceImages,
 | 
						|
                          enabled: widget.serviceRequest == null ? true : false,
 | 
						|
                        ),
 | 
						|
                        12.height,
 | 
						|
                        SpeechToTextButton(
 | 
						|
                          controller: _maintenanceController,
 | 
						|
                          enabled: widget.serviceRequest == null ? true : false,
 | 
						|
                        ),
 | 
						|
                        12.height,
 | 
						|
                        ATextFormField(
 | 
						|
                          controller: _maintenanceController,
 | 
						|
                          initialValue: _serviceRequest.callComments,
 | 
						|
                          hintText: _subtitle.maintenanceIssue,
 | 
						|
                          prefixIconData: FontAwesomeIcons.triangleExclamation,
 | 
						|
                          style: Theme.of(context).textTheme.titleLarge,
 | 
						|
                          textInputType: TextInputType.multiline,
 | 
						|
                          validator: (value) => Validator.hasValue(value) ? null : _subtitle.maintenanceIssueRequired,
 | 
						|
                          onSaved: (value) {
 | 
						|
                            _serviceRequest.callComments = value;
 | 
						|
                          },
 | 
						|
                          enable: widget.serviceRequest == null ? true : false,
 | 
						|
                        ),
 | 
						|
                        12.height,
 | 
						|
                        RecordSound(
 | 
						|
                          onRecord: (audio) {
 | 
						|
                            _serviceRequest.audio = audio;
 | 
						|
                          },
 | 
						|
                          enabled: widget.serviceRequest == null ? true : false,
 | 
						|
                        ),
 | 
						|
                        12.height,
 | 
						|
                        if (widget.serviceRequest != null)
 | 
						|
                          ATextFormField(
 | 
						|
                            controller: _commentController,
 | 
						|
                            initialValue: _serviceRequest.comments,
 | 
						|
                            hintText: _subtitle.comment,
 | 
						|
                            style: Theme.of(context).textTheme.titleMedium,
 | 
						|
                            textInputType: TextInputType.multiline,
 | 
						|
                            onSaved: (value) {
 | 
						|
                              _serviceRequest.comments = value;
 | 
						|
                            },
 | 
						|
                          ),
 | 
						|
                      ],
 | 
						|
                    ).paddingOnly(left: 20, right: 20),
 | 
						|
                    Padding(
 | 
						|
                      padding: const EdgeInsets.all(20.0),
 | 
						|
                      child: AButton(
 | 
						|
                        text: widget.serviceRequest == null ? _subtitle.submit : _subtitle.update,
 | 
						|
                        onPressed: () async {
 | 
						|
                          //if (!_formKey.currentState.validate()) return;
 | 
						|
                          if (_device?.id == null) {
 | 
						|
                            Fluttertoast.showToast(msg: _subtitle.pickDevice);
 | 
						|
                            return;
 | 
						|
                          }
 | 
						|
                          if (_serviceRequest.firstAction?.name == "Need a visit" && _dateTime == null) {
 | 
						|
                            Fluttertoast.showToast(msg: "first action is required");
 | 
						|
                            return;
 | 
						|
                          }
 | 
						|
                          if (widget.serviceRequest != null && (_serviceRequest?.engineerId == null || (_serviceRequest?.engineerId?.isEmpty ?? false))) {
 | 
						|
                            await Fluttertoast.showToast(msg: "No Assigned Employee");
 | 
						|
                            return;
 | 
						|
                          }
 | 
						|
                          _formKey.currentState.save();
 | 
						|
                          _serviceRequest.deviceId = _device?.id;
 | 
						|
                          if (widget.serviceRequest == null) {
 | 
						|
                            _serviceRequest.type = Provider.of<ServiceRequestTypeProvider>(context, listen: false).getDefaultItem();
 | 
						|
                          }
 | 
						|
                          _serviceRequest.requestedThrough = Provider.of<ServiceRequestedThroughProvider>(context, listen: false).getDefaultItem();
 | 
						|
                          _isLoading = true;
 | 
						|
                          setState(() {});
 | 
						|
                          _serviceRequest.devicePhotos = _deviceImages.map((e) => "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}").toList();
 | 
						|
                          if (_serviceRequest.audio != null) {
 | 
						|
                            final file = File(_serviceRequest.audio);
 | 
						|
                            _serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}";
 | 
						|
                          }
 | 
						|
                          int status = 0;
 | 
						|
                          if (widget.serviceRequest == null) {
 | 
						|
                            status = await _serviceRequestsProvider.createRequest(
 | 
						|
                              user: _userProvider.user,
 | 
						|
                              host: _settingProvider.host,
 | 
						|
                              serviceRequest: _serviceRequest,
 | 
						|
                            );
 | 
						|
                          } else {
 | 
						|
                            status = await _serviceRequestsProvider.updateDate(
 | 
						|
                              user: _userProvider.user,
 | 
						|
                              host: _settingProvider.host,
 | 
						|
                              request: _serviceRequest,
 | 
						|
                              date: _dateTime,
 | 
						|
                            );
 | 
						|
                          }
 | 
						|
                          _isLoading = false;
 | 
						|
                          setState(() {});
 | 
						|
                          if (status >= 200 && status < 300) {
 | 
						|
                            Fluttertoast.showToast(
 | 
						|
                              msg: _subtitle.requestCompleteSuccessfully,
 | 
						|
                            );
 | 
						|
                            Navigator.of(context).pop();
 | 
						|
                          } else {
 | 
						|
                            String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
 | 
						|
                            ScaffoldMessenger.of(context).showSnackBar(SnackBar(
 | 
						|
                              content: Text(errorMessage),
 | 
						|
                            ));
 | 
						|
                          }
 | 
						|
                        },
 | 
						|
                      ),
 | 
						|
                    ),
 | 
						|
                  ],
 | 
						|
                ),
 | 
						|
                const ABackButton(),
 | 
						|
              ],
 | 
						|
            ),
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |