|
|
|
@ -2,7 +2,6 @@ import 'dart:convert';
|
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter/rendering.dart';
|
|
|
|
|
import 'package:fluttertoast/fluttertoast.dart';
|
|
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
|
import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
|
|
|
|
@ -15,7 +14,6 @@ import 'package:test_sa/controllers/validator/validator.dart';
|
|
|
|
|
import 'package:test_sa/models/part.dart';
|
|
|
|
|
import 'package:test_sa/models/service_report.dart';
|
|
|
|
|
import 'package:test_sa/models/service_request/service_request.dart';
|
|
|
|
|
import 'package:test_sa/models/lookup.dart';
|
|
|
|
|
import 'package:test_sa/models/subtitle.dart';
|
|
|
|
|
import 'package:test_sa/views/app_style/colors.dart';
|
|
|
|
|
import 'package:test_sa/views/app_style/sizing.dart';
|
|
|
|
@ -33,22 +31,22 @@ import 'package:test_sa/views/widgets/status/employee/engineers_mune.dart';
|
|
|
|
|
import 'package:test_sa/views/widgets/status/report/service_report_last_call.dart';
|
|
|
|
|
import 'package:test_sa/views/widgets/status/report/service_report_reasons.dart';
|
|
|
|
|
import 'package:test_sa/views/widgets/status/report/service_report_status.dart';
|
|
|
|
|
import 'package:test_sa/views/widgets/status/report/service_report_type.dart';
|
|
|
|
|
import 'package:test_sa/views/widgets/status/report/service_status.dart';
|
|
|
|
|
import 'package:test_sa/views/widgets/timer/app_timer.dart';
|
|
|
|
|
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
|
|
|
|
|
|
|
|
|
|
import '../../../../widgets/status/report/service_report_repair_location.dart';
|
|
|
|
|
|
|
|
|
|
class CreateServiceReport extends StatefulWidget {
|
|
|
|
|
static final String id = "/create-service-report";
|
|
|
|
|
final ServiceRequest request ;
|
|
|
|
|
final ServiceRequest request;
|
|
|
|
|
|
|
|
|
|
const CreateServiceReport({Key key, this.request}) : super(key: key);
|
|
|
|
|
@override
|
|
|
|
|
_CreateServiceReportState createState() => _CreateServiceReportState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _CreateServiceReportState extends State<CreateServiceReport> with TickerProviderStateMixin{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _CreateServiceReportState extends State<CreateServiceReport> with TickerProviderStateMixin {
|
|
|
|
|
UserProvider _userProvider;
|
|
|
|
|
SettingProvider _settingProvider;
|
|
|
|
|
ServiceRequestsProvider _serviceRequestsProvider;
|
|
|
|
@ -67,11 +65,10 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
_serviceReport = ServiceReport(
|
|
|
|
|
visitDate: DateTime.now(),
|
|
|
|
|
//type: const Lookup(value: 2),
|
|
|
|
|
device: widget.request.device,
|
|
|
|
|
parts: []
|
|
|
|
|
);
|
|
|
|
|
visitDate: DateTime.now(),
|
|
|
|
|
//type: const Lookup(value: 2),
|
|
|
|
|
device: widget.request.device,
|
|
|
|
|
parts: []);
|
|
|
|
|
super.initState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -81,6 +78,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
_workPreformedController.dispose();
|
|
|
|
|
super.dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
_userProvider = Provider.of<UserProvider>(context);
|
|
|
|
@ -102,52 +100,54 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
ListView(
|
|
|
|
|
children: [
|
|
|
|
|
//AppNameBar(),
|
|
|
|
|
const SizedBox(height: 16,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 16,
|
|
|
|
|
),
|
|
|
|
|
Center(
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
|
child: Text(
|
|
|
|
|
_subtitle.newServiceReport,
|
|
|
|
|
style: Theme.of(context).textTheme.headline5.copyWith(
|
|
|
|
|
color: AColors.cyan,
|
|
|
|
|
fontSize: 28,
|
|
|
|
|
fontWeight: FontWeight.bold
|
|
|
|
|
),
|
|
|
|
|
style: Theme.of(context).textTheme.headline5.copyWith(color: AColors.cyan, fontSize: 28, fontWeight: FontWeight.bold),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Container(
|
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
|
|
|
margin: const EdgeInsets.symmetric(horizontal: 16,vertical: 16),
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
|
|
|
|
|
decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [
|
|
|
|
|
const BoxShadow(
|
|
|
|
|
color: AColors.grey,
|
|
|
|
|
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)),
|
|
|
|
|
boxShadow: [
|
|
|
|
|
const BoxShadow(
|
|
|
|
|
color: AColors.grey,
|
|
|
|
|
offset: Offset(0,-1),
|
|
|
|
|
)
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
offset: Offset(0, -1),
|
|
|
|
|
)
|
|
|
|
|
]),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
Wrap(
|
|
|
|
|
spacing: 10,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle("${_subtitle.callId}: ${widget.request.requestCode}",font: 14,),
|
|
|
|
|
widget.request.deviceSerialNumber == null ? const SizedBox():
|
|
|
|
|
ASubTitle("${_subtitle.deviceSN}: ${widget.request.deviceSerialNumber}",font: 14,),
|
|
|
|
|
ASubTitle(
|
|
|
|
|
"${_subtitle.callId}: ${widget.request.requestCode}",
|
|
|
|
|
font: 14,
|
|
|
|
|
),
|
|
|
|
|
widget.request.deviceSerialNumber == null
|
|
|
|
|
? const SizedBox()
|
|
|
|
|
: ASubTitle(
|
|
|
|
|
"${_subtitle.deviceSN}: ${widget.request.deviceSerialNumber}",
|
|
|
|
|
font: 14,
|
|
|
|
|
),
|
|
|
|
|
Text(
|
|
|
|
|
"${_subtitle.customer}: ${widget.request.hospitalName}",
|
|
|
|
|
style: Theme.of(context).textTheme.subtitle1.copyWith(
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
),
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
),
|
|
|
|
|
textScaleFactor: AppStyle.getScaleFactor(context),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
const Divider(),
|
|
|
|
@ -181,9 +181,12 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.visitDate),
|
|
|
|
|
_validate && _serviceReport.visitDate == null ?
|
|
|
|
|
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
|
|
|
|
|
const SizedBox.shrink(),
|
|
|
|
|
_validate && _serviceReport.visitDate == null
|
|
|
|
|
? ASubTitle(
|
|
|
|
|
_subtitle.requiredWord,
|
|
|
|
|
color: Colors.red,
|
|
|
|
|
)
|
|
|
|
|
: const SizedBox.shrink(),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
@ -191,7 +194,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
date: _serviceReport.visitDate,
|
|
|
|
|
from: DateTime.now().subtract(const Duration(days: 365)),
|
|
|
|
|
to: DateTime.now().add(const Duration(days: 365)),
|
|
|
|
|
onDatePicker: (date){
|
|
|
|
|
onDatePicker: (date) {
|
|
|
|
|
_serviceReport.visitDate = date;
|
|
|
|
|
setState(() {});
|
|
|
|
|
},
|
|
|
|
@ -202,10 +205,11 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
// device sn
|
|
|
|
|
Visibility(
|
|
|
|
|
visible: widget.request.deviceSerialNumber == null,
|
|
|
|
@ -213,33 +217,47 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.deviceSN),
|
|
|
|
|
_validate && _serviceReport.device?.id == null ?
|
|
|
|
|
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
|
|
|
|
|
const SizedBox.shrink(),
|
|
|
|
|
_validate && _serviceReport.device?.id == null
|
|
|
|
|
? ASubTitle(
|
|
|
|
|
_subtitle.requiredWord,
|
|
|
|
|
color: Colors.red,
|
|
|
|
|
)
|
|
|
|
|
: const SizedBox.shrink(),
|
|
|
|
|
AutoCompleteDeviceField(
|
|
|
|
|
hospitalId: widget.request.hospitalId,
|
|
|
|
|
initialValue: _serviceReport.device,
|
|
|
|
|
onPick: (id){
|
|
|
|
|
onPick: (id) {
|
|
|
|
|
_serviceReport.device.id = id;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
ASubTitle(_subtitle.serviceType),
|
|
|
|
|
_validate && _serviceReport.assetType == null ?
|
|
|
|
|
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
|
|
|
|
|
const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(height: 4,),
|
|
|
|
|
_validate && _serviceReport.assetType == null
|
|
|
|
|
? ASubTitle(
|
|
|
|
|
_subtitle.requiredWord,
|
|
|
|
|
color: Colors.red,
|
|
|
|
|
)
|
|
|
|
|
: const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 4,
|
|
|
|
|
),
|
|
|
|
|
ServiceAssetTypeMenu(
|
|
|
|
|
initialValue: _serviceReport.assetType,
|
|
|
|
|
onSelect: (status){
|
|
|
|
|
onSelect: (status) {
|
|
|
|
|
_serviceReport.assetType = status;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
// Report status and Service Type
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
@ -249,40 +267,51 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.reportStatus),
|
|
|
|
|
_validate && _serviceReport.status == null ?
|
|
|
|
|
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
|
|
|
|
|
const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(height: 4,),
|
|
|
|
|
_validate && _serviceReport.status == null
|
|
|
|
|
? ASubTitle(
|
|
|
|
|
_subtitle.requiredWord,
|
|
|
|
|
color: Colors.red,
|
|
|
|
|
)
|
|
|
|
|
: const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 4,
|
|
|
|
|
),
|
|
|
|
|
ServiceReportStatusMenu(
|
|
|
|
|
report: _serviceReport,
|
|
|
|
|
onSelect: (status){
|
|
|
|
|
onSelect: (status) {
|
|
|
|
|
_serviceReport.status = status;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(width: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
width: 8,
|
|
|
|
|
),
|
|
|
|
|
// Provider.of<ServiceReportLastCallsProvider>(context).isLoading == null
|
|
|
|
|
// ? const SizedBox.shrink():
|
|
|
|
|
// Call's last Situation
|
|
|
|
|
Consumer<ServiceReportLastCallsProvider>(
|
|
|
|
|
builder: (_, provider, __) {
|
|
|
|
|
if(provider.isLoading == null) return const SizedBox.shrink();
|
|
|
|
|
return Expanded(
|
|
|
|
|
if (provider.isLoading == null) return const SizedBox.shrink();
|
|
|
|
|
return Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.callLastSituation),
|
|
|
|
|
_validate && _serviceReport.callLastSituation == null ?
|
|
|
|
|
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
|
|
|
|
|
const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(height: 4,),
|
|
|
|
|
_validate && _serviceReport.callLastSituation == null
|
|
|
|
|
? ASubTitle(
|
|
|
|
|
_subtitle.requiredWord,
|
|
|
|
|
color: Colors.red,
|
|
|
|
|
)
|
|
|
|
|
: const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 4,
|
|
|
|
|
),
|
|
|
|
|
ServiceReportLastCallsMenu(
|
|
|
|
|
report: _serviceReport,
|
|
|
|
|
onSelect: (status){
|
|
|
|
|
if(status?.value == 12
|
|
|
|
|
|| _serviceReport.callLastSituation?.value == 12){
|
|
|
|
|
onSelect: (status) {
|
|
|
|
|
if (status?.value == 12 || _serviceReport.callLastSituation?.value == 12) {
|
|
|
|
|
_serviceReport.callLastSituation = status;
|
|
|
|
|
setState(() {});
|
|
|
|
|
} else {
|
|
|
|
@ -297,70 +326,83 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
|
|
|
|
|
const ASubTitle("Assign Employee"),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
_validate && _serviceReport.engineer == null ?
|
|
|
|
|
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
|
|
|
|
|
const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(height: 4,),
|
|
|
|
|
SizedBox(
|
|
|
|
|
height: 8 * AppStyle.getScaleFactor(context),
|
|
|
|
|
),
|
|
|
|
|
const ASubTitle("Assigned Employee"),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
_validate && _serviceReport.engineer == null
|
|
|
|
|
? ASubTitle(
|
|
|
|
|
_subtitle.requiredWord,
|
|
|
|
|
color: Colors.red,
|
|
|
|
|
)
|
|
|
|
|
: const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 4,
|
|
|
|
|
),
|
|
|
|
|
EngineersMenu(
|
|
|
|
|
initialValue: _serviceReport.engineer,
|
|
|
|
|
onSelect: (engineer){
|
|
|
|
|
onSelect: (engineer) {
|
|
|
|
|
_serviceReport.engineer = engineer;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
// invoice number & code
|
|
|
|
|
_serviceReport.callLastSituation?.id != 12 ? const SizedBox.shrink():
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
_serviceReport.callLastSituation?.id != 12
|
|
|
|
|
? const SizedBox.shrink()
|
|
|
|
|
: Row(
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.invoiceNumber),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
ATextFormField(
|
|
|
|
|
initialValue: _serviceReport?.invoiceNumber,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
style: Theme.of(context).textTheme.subtitle1,
|
|
|
|
|
validator: (value) =>
|
|
|
|
|
Validator.hasValue(value)
|
|
|
|
|
? null : _subtitle.requiredWord,
|
|
|
|
|
textInputType: TextInputType.number,
|
|
|
|
|
onSaved: (value){
|
|
|
|
|
_serviceReport.invoiceNumber = value;
|
|
|
|
|
},
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.invoiceNumber),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
ATextFormField(
|
|
|
|
|
initialValue: _serviceReport?.invoiceNumber,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
style: Theme.of(context).textTheme.subtitle1,
|
|
|
|
|
validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord,
|
|
|
|
|
textInputType: TextInputType.number,
|
|
|
|
|
onSaved: (value) {
|
|
|
|
|
_serviceReport.invoiceNumber = value;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(width: 8,),
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.invoiceCode),
|
|
|
|
|
const SizedBox(height: 4,),
|
|
|
|
|
ATextFormField(
|
|
|
|
|
initialValue: _serviceReport?.invoiceCode,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
style: Theme.of(context).textTheme.subtitle1,
|
|
|
|
|
validator: (value) =>
|
|
|
|
|
Validator.hasValue(value)
|
|
|
|
|
? null : _subtitle.requiredWord,
|
|
|
|
|
textInputType: TextInputType.text,
|
|
|
|
|
onSaved: (value){
|
|
|
|
|
_serviceReport.invoiceCode = value;
|
|
|
|
|
},
|
|
|
|
|
const SizedBox(
|
|
|
|
|
width: 8,
|
|
|
|
|
),
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.invoiceCode),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 4,
|
|
|
|
|
),
|
|
|
|
|
ATextFormField(
|
|
|
|
|
initialValue: _serviceReport?.invoiceCode,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
style: Theme.of(context).textTheme.subtitle1,
|
|
|
|
|
validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord,
|
|
|
|
|
textInputType: TextInputType.text,
|
|
|
|
|
onSaved: (value) {
|
|
|
|
|
_serviceReport.invoiceCode = value;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
// const SizedBox(height: 8,),
|
|
|
|
|
// Row(
|
|
|
|
|
// children: [
|
|
|
|
@ -421,7 +463,9 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
// ),
|
|
|
|
|
// const SizedBox(height: 8,),
|
|
|
|
|
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
// reasons
|
|
|
|
@ -430,17 +474,21 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.reasons),
|
|
|
|
|
const SizedBox(height: 4,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 4,
|
|
|
|
|
),
|
|
|
|
|
ServiceReportReasonsMenu(
|
|
|
|
|
initialValue: _serviceReport.reason,
|
|
|
|
|
onSelect: (status){
|
|
|
|
|
onSelect: (status) {
|
|
|
|
|
_serviceReport.reason = status;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(width: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
width: 8,
|
|
|
|
|
),
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
@ -449,8 +497,8 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
AMiniOneImagePicker(
|
|
|
|
|
//error: _validate && _serviceReport.image == null,
|
|
|
|
|
image: _image,
|
|
|
|
|
onPick: (image){
|
|
|
|
|
_image =image;
|
|
|
|
|
onPick: (image) {
|
|
|
|
|
_image = image;
|
|
|
|
|
_serviceReport.image = "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}";
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
@ -459,7 +507,49 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
ASubTitle(_subtitle.repairLocation),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 4,
|
|
|
|
|
),
|
|
|
|
|
ServiceReportRepairLocation(
|
|
|
|
|
initialValue: _serviceReport.repairLocation,
|
|
|
|
|
onSelect: (status) {
|
|
|
|
|
_serviceReport.repairLocation = status;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 16,
|
|
|
|
|
),
|
|
|
|
|
ATextFormField(
|
|
|
|
|
initialValue: _serviceReport?.travelingExpense?.toString(),
|
|
|
|
|
hintText: _subtitle.travelingExpense,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
style: Theme.of(context).textTheme.titleMedium,
|
|
|
|
|
textInputType: TextInputType.number,
|
|
|
|
|
onSaved: (value) {
|
|
|
|
|
_serviceReport.travelingExpense = int.tryParse(value) ?? 0;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
ATextFormField(
|
|
|
|
|
initialValue: _serviceReport?.comment,
|
|
|
|
|
hintText: _subtitle.comment,
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
style: Theme.of(context).textTheme.titleMedium,
|
|
|
|
|
textInputType: TextInputType.multiline,
|
|
|
|
|
onSaved: (value) {
|
|
|
|
|
_serviceReport.comment = value;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
// Traveling Hours & Working Hours
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
@ -468,13 +558,15 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.workingHours),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: AppTimer(
|
|
|
|
|
timer: _serviceReport.timer,
|
|
|
|
|
onChange: (timer) async{
|
|
|
|
|
onChange: (timer) async {
|
|
|
|
|
_serviceReport.timer = timer;
|
|
|
|
|
return true;
|
|
|
|
|
},
|
|
|
|
@ -523,7 +615,9 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
// ),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
// Operating Hours and Job Sheet Number
|
|
|
|
|
// Row(
|
|
|
|
|
// children: [
|
|
|
|
@ -570,30 +664,39 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
// ),
|
|
|
|
|
// ],
|
|
|
|
|
// ),
|
|
|
|
|
//const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
const ASubTitle("Nurse Signature"),
|
|
|
|
|
ESignature(
|
|
|
|
|
oldSignature: _serviceReport.signatureNurse,
|
|
|
|
|
newSignature: _serviceReport.localNurseSignature,
|
|
|
|
|
onSaved: (signature){
|
|
|
|
|
if(signature == null || signature.isEmpty) {return;}
|
|
|
|
|
onSaved: (signature) {
|
|
|
|
|
if (signature == null || signature.isEmpty) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_serviceReport.localNurseSignature = signature;
|
|
|
|
|
_serviceReport.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
const ASubTitle("Engineer Signature"),
|
|
|
|
|
ESignature(
|
|
|
|
|
oldSignature: _serviceReport.signatureEngineer,
|
|
|
|
|
newSignature: _serviceReport.localNurseSignature,
|
|
|
|
|
onSaved: (signature){
|
|
|
|
|
if(signature == null || signature.isEmpty) {return;}
|
|
|
|
|
onSaved: (signature) {
|
|
|
|
|
if (signature == null || signature.isEmpty) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_serviceReport.localNurseSignature = signature;
|
|
|
|
|
_serviceReport.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8,),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 8,
|
|
|
|
|
),
|
|
|
|
|
// Part Number and Quantity
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
@ -603,45 +706,49 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
ASubTitle(_subtitle.partNumber),
|
|
|
|
|
_validate && _serviceReport.parts == null ?
|
|
|
|
|
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
|
|
|
|
|
const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(height: 4,),
|
|
|
|
|
_validate && _serviceReport.parts == null
|
|
|
|
|
? ASubTitle(
|
|
|
|
|
_subtitle.requiredWord,
|
|
|
|
|
color: Colors.red,
|
|
|
|
|
)
|
|
|
|
|
: const SizedBox.shrink(),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 4,
|
|
|
|
|
),
|
|
|
|
|
AutoCompletePartsField(
|
|
|
|
|
onPick: (part){
|
|
|
|
|
onPick: (part) {
|
|
|
|
|
_serviceReport.parts.add(part);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
SizedBox(height: 8*AppStyle.getScaleFactor(context),),
|
|
|
|
|
SizedBox(
|
|
|
|
|
height: 8 * AppStyle.getScaleFactor(context),
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(flex:3,child: Text(_subtitle.number)),
|
|
|
|
|
Expanded(flex: 1,child: Text(_subtitle.quantity)),
|
|
|
|
|
Expanded(flex: 3, child: Text(_subtitle.number)),
|
|
|
|
|
Expanded(flex: 1, child: Text(_subtitle.quantity)),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
Column(
|
|
|
|
|
children: List.generate(
|
|
|
|
|
_serviceReport.parts.length,
|
|
|
|
|
(index) {
|
|
|
|
|
Part _part = _serviceReport.parts[index];
|
|
|
|
|
return PartItem(
|
|
|
|
|
part: _part,
|
|
|
|
|
onDelete: (part){
|
|
|
|
|
_serviceReport.parts.remove(part);
|
|
|
|
|
setState(() {});
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
children: List.generate(_serviceReport.parts.length, (index) {
|
|
|
|
|
Part _part = _serviceReport.parts[index];
|
|
|
|
|
return PartItem(
|
|
|
|
|
part: _part,
|
|
|
|
|
onDelete: (part) {
|
|
|
|
|
_serviceReport.parts.remove(part);
|
|
|
|
|
setState(() {});
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 16,
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 16,),
|
|
|
|
|
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
@ -651,47 +758,48 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
|
|
|
|
|
text: _subtitle.submit,
|
|
|
|
|
onPressed: () async {
|
|
|
|
|
_validate = true;
|
|
|
|
|
if(!_formKey.currentState.validate()){
|
|
|
|
|
print(1);
|
|
|
|
|
if (!_formKey.currentState.validate()) {
|
|
|
|
|
print(2);
|
|
|
|
|
setState(() {});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(!_serviceReport.validate()) return;
|
|
|
|
|
print(3);
|
|
|
|
|
if (!_serviceReport.validate()) return;
|
|
|
|
|
print(4);
|
|
|
|
|
_formKey.currentState.save();
|
|
|
|
|
|
|
|
|
|
_isLoading =true;
|
|
|
|
|
print(5);
|
|
|
|
|
_isLoading = true;
|
|
|
|
|
setState(() {});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int status = await _serviceRequestsProvider.createServiceReport(
|
|
|
|
|
user: _userProvider.user,
|
|
|
|
|
host: _settingProvider.host,
|
|
|
|
|
report: _serviceReport,
|
|
|
|
|
request: widget.request
|
|
|
|
|
request: widget.request,
|
|
|
|
|
);
|
|
|
|
|
_isLoading =false;
|
|
|
|
|
print(6);
|
|
|
|
|
print(status);
|
|
|
|
|
_isLoading = false;
|
|
|
|
|
setState(() {});
|
|
|
|
|
if(status >= 200 && status < 300){
|
|
|
|
|
if (status >= 200 && status < 300) {
|
|
|
|
|
Fluttertoast.showToast(
|
|
|
|
|
msg: _subtitle.requestCompleteSuccessfully,
|
|
|
|
|
msg: _subtitle.requestCompleteSuccessfully,
|
|
|
|
|
);
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
|
}else{
|
|
|
|
|
String errorMessage = HttpStatusManger.getStatusMessage(
|
|
|
|
|
status: status, subtitle: _subtitle);
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
|
SnackBar(
|
|
|
|
|
content: Text(
|
|
|
|
|
errorMessage
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
|
|
|
|
content: Text(errorMessage),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 300,)
|
|
|
|
|
const SizedBox(
|
|
|
|
|
height: 300,
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
const ABackButton(),
|
|
|
|
|