fixed parking qr
parent
11de01e079
commit
8ae81d2b24
@ -0,0 +1,183 @@
|
|||||||
|
|
||||||
|
|
||||||
|
class QrParkingResponseModel {
|
||||||
|
dynamic totalRecords;
|
||||||
|
dynamic nRowID;
|
||||||
|
int? qRParkingID;
|
||||||
|
String? description;
|
||||||
|
String? descriptionN;
|
||||||
|
dynamic qRCompare;
|
||||||
|
dynamic qRValue;
|
||||||
|
String? imagePath;
|
||||||
|
bool? isActive;
|
||||||
|
int? parkingID;
|
||||||
|
int? branchID;
|
||||||
|
int? companyID;
|
||||||
|
int? buildingID;
|
||||||
|
int? rowID;
|
||||||
|
int? gateID;
|
||||||
|
int? floorID;
|
||||||
|
dynamic imagePath1;
|
||||||
|
int? createdBy;
|
||||||
|
String? createdOn;
|
||||||
|
dynamic editedBy;
|
||||||
|
dynamic editedOn;
|
||||||
|
String? parkingDescription;
|
||||||
|
String? parkingDescriptionN;
|
||||||
|
String? gateDescription;
|
||||||
|
String? gateDescriptionN;
|
||||||
|
String? branchDescription;
|
||||||
|
String? branchDescriptionN;
|
||||||
|
String? companyDescription;
|
||||||
|
String? companyDescriptionN;
|
||||||
|
String? rowDescription;
|
||||||
|
String? rowDescriptionN;
|
||||||
|
String? floorDescription;
|
||||||
|
String? floorDescriptionN;
|
||||||
|
String? buildingDescription;
|
||||||
|
String? buildingDescriptionN;
|
||||||
|
String? qRParkingCode;
|
||||||
|
String? parkingCode;
|
||||||
|
double? latitude;
|
||||||
|
double? longitude;
|
||||||
|
String? qRImageStr;
|
||||||
|
|
||||||
|
QrParkingResponseModel({
|
||||||
|
this.totalRecords,
|
||||||
|
this.nRowID,
|
||||||
|
this.qRParkingID,
|
||||||
|
this.description,
|
||||||
|
this.descriptionN,
|
||||||
|
this.qRCompare,
|
||||||
|
this.qRValue,
|
||||||
|
this.imagePath,
|
||||||
|
this.isActive,
|
||||||
|
this.parkingID,
|
||||||
|
this.branchID,
|
||||||
|
this.companyID,
|
||||||
|
this.buildingID,
|
||||||
|
this.rowID,
|
||||||
|
this.gateID,
|
||||||
|
this.floorID,
|
||||||
|
this.imagePath1,
|
||||||
|
this.createdBy,
|
||||||
|
this.createdOn,
|
||||||
|
this.editedBy,
|
||||||
|
this.editedOn,
|
||||||
|
this.parkingDescription,
|
||||||
|
this.parkingDescriptionN,
|
||||||
|
this.gateDescription,
|
||||||
|
this.gateDescriptionN,
|
||||||
|
this.branchDescription,
|
||||||
|
this.branchDescriptionN,
|
||||||
|
this.companyDescription,
|
||||||
|
this.companyDescriptionN,
|
||||||
|
this.rowDescription,
|
||||||
|
this.rowDescriptionN,
|
||||||
|
this.floorDescription,
|
||||||
|
this.floorDescriptionN,
|
||||||
|
this.buildingDescription,
|
||||||
|
this.buildingDescriptionN,
|
||||||
|
this.qRParkingCode,
|
||||||
|
this.parkingCode,
|
||||||
|
this.latitude,
|
||||||
|
this.longitude,
|
||||||
|
this.qRImageStr,
|
||||||
|
});
|
||||||
|
|
||||||
|
QrParkingResponseModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
totalRecords = json['TotalRecords'];
|
||||||
|
nRowID = json['nRowID'];
|
||||||
|
qRParkingID = json['QRParkingID'];
|
||||||
|
description = json['Description'];
|
||||||
|
descriptionN = json['DescriptionN'];
|
||||||
|
qRCompare = json['QRCompare'];
|
||||||
|
qRValue = json['QRValue'];
|
||||||
|
imagePath = json['ImagePath'];
|
||||||
|
isActive = json['IsActive'];
|
||||||
|
parkingID = json['ParkingID'];
|
||||||
|
branchID = json['BranchID'];
|
||||||
|
companyID = json['CompanyID'];
|
||||||
|
buildingID = json['BuildingID'];
|
||||||
|
rowID = json['RowID'];
|
||||||
|
gateID = json['GateID'];
|
||||||
|
floorID = json['FloorID'];
|
||||||
|
imagePath1 = json['ImagePath1'];
|
||||||
|
createdBy = json['CreatedBy'];
|
||||||
|
createdOn = json['CreatedOn'];
|
||||||
|
editedBy = json['EditedBy'];
|
||||||
|
editedOn = json['EditedOn'];
|
||||||
|
parkingDescription = json['ParkingDescription'];
|
||||||
|
parkingDescriptionN = json['ParkingDescriptionN'];
|
||||||
|
gateDescription = json['GateDescription'];
|
||||||
|
gateDescriptionN = json['GateDescriptionN'];
|
||||||
|
branchDescription = json['BranchDescription'];
|
||||||
|
branchDescriptionN = json['BranchDescriptionN'];
|
||||||
|
companyDescription = json['CompanyDescription'];
|
||||||
|
companyDescriptionN = json['CompanyDescriptionN'];
|
||||||
|
rowDescription = json['RowDescription'];
|
||||||
|
rowDescriptionN = json['RowDescriptionN'];
|
||||||
|
floorDescription = json['FloorDescription'];
|
||||||
|
floorDescriptionN = json['FloorDescriptionN'];
|
||||||
|
buildingDescription = json['BuildingDescription'];
|
||||||
|
buildingDescriptionN = json['BuildingDescriptionN'];
|
||||||
|
qRParkingCode = json['QRParkingCode'];
|
||||||
|
parkingCode = json['ParkingCode'];
|
||||||
|
latitude = _toDouble(json['Latitude']);
|
||||||
|
longitude = _toDouble(json['Longitude']);
|
||||||
|
qRImageStr = json['QRImageStr'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['TotalRecords'] = totalRecords;
|
||||||
|
data['nRowID'] = nRowID;
|
||||||
|
data['QRParkingID'] = qRParkingID;
|
||||||
|
data['Description'] = description;
|
||||||
|
data['DescriptionN'] = descriptionN;
|
||||||
|
data['QRCompare'] = qRCompare;
|
||||||
|
data['QRValue'] = qRValue;
|
||||||
|
data['ImagePath'] = imagePath;
|
||||||
|
data['IsActive'] = isActive;
|
||||||
|
data['ParkingID'] = parkingID;
|
||||||
|
data['BranchID'] = branchID;
|
||||||
|
data['CompanyID'] = companyID;
|
||||||
|
data['BuildingID'] = buildingID;
|
||||||
|
data['RowID'] = rowID;
|
||||||
|
data['GateID'] = gateID;
|
||||||
|
data['FloorID'] = floorID;
|
||||||
|
data['ImagePath1'] = imagePath1;
|
||||||
|
data['CreatedBy'] = createdBy;
|
||||||
|
data['CreatedOn'] = createdOn;
|
||||||
|
data['EditedBy'] = editedBy;
|
||||||
|
data['EditedOn'] = editedOn;
|
||||||
|
data['ParkingDescription'] = parkingDescription;
|
||||||
|
data['ParkingDescriptionN'] = parkingDescriptionN;
|
||||||
|
data['GateDescription'] = gateDescription;
|
||||||
|
data['GateDescriptionN'] = gateDescriptionN;
|
||||||
|
data['BranchDescription'] = branchDescription;
|
||||||
|
data['BranchDescriptionN'] = branchDescriptionN;
|
||||||
|
data['CompanyDescription'] = companyDescription;
|
||||||
|
data['CompanyDescriptionN'] = companyDescriptionN;
|
||||||
|
data['RowDescription'] = rowDescription;
|
||||||
|
data['RowDescriptionN'] = rowDescriptionN;
|
||||||
|
data['FloorDescription'] = floorDescription;
|
||||||
|
data['FloorDescriptionN'] = floorDescriptionN;
|
||||||
|
data['BuildingDescription'] = buildingDescription;
|
||||||
|
data['BuildingDescriptionN'] = buildingDescriptionN;
|
||||||
|
data['QRParkingCode'] = qRParkingCode;
|
||||||
|
data['ParkingCode'] = parkingCode;
|
||||||
|
data['Latitude'] = latitude;
|
||||||
|
data['Longitude'] = longitude;
|
||||||
|
data['QRImageStr'] = qRImageStr;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double? _toDouble(dynamic v) {
|
||||||
|
if (v == null) return null;
|
||||||
|
if (v is double) return v;
|
||||||
|
if (v is int) return v.toDouble();
|
||||||
|
return double.tryParse(v.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/qr_parking/models/qr_parking_response_model.dart';
|
||||||
|
import '../../core/api/api_client.dart';
|
||||||
|
import '../../core/api_consts.dart';
|
||||||
|
import '../../core/common_models/generic_api_model.dart';
|
||||||
|
import '../../core/exceptions/api_failure.dart';
|
||||||
|
import '../../services/logger_service.dart';
|
||||||
|
|
||||||
|
|
||||||
|
abstract class QrParkingRepo {
|
||||||
|
Future<Either<Failure, GenericApiModel<List<QrParkingResponseModel>>>>
|
||||||
|
getQrParking({
|
||||||
|
required int qrParkingId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class QrParkingRepoImp implements QrParkingRepo {
|
||||||
|
final ApiClient apiClient;
|
||||||
|
final LoggerService loggerService;
|
||||||
|
|
||||||
|
QrParkingRepoImp({
|
||||||
|
required this.loggerService,
|
||||||
|
required this.apiClient,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Failure, GenericApiModel<List<QrParkingResponseModel>>>>
|
||||||
|
getQrParking({required int qrParkingId}) async {
|
||||||
|
try {
|
||||||
|
GenericApiModel<List<QrParkingResponseModel>>? apiResponse;
|
||||||
|
Failure? failure;
|
||||||
|
|
||||||
|
await apiClient.post(
|
||||||
|
ApiConsts.getQrParkingDetails, // GetQRParkingByID
|
||||||
|
body: {'QRParkingID': qrParkingId},
|
||||||
|
onFailure: (error, statusCode,
|
||||||
|
{messageStatus, failureType}) {
|
||||||
|
failure = failureType ??
|
||||||
|
StatusCodeFailure("$error ($statusCode)");
|
||||||
|
},
|
||||||
|
onSuccess: (response, statusCode,
|
||||||
|
{messageStatus, errorMessage}) {
|
||||||
|
final list =
|
||||||
|
(response['List_SWP_QRParkingModel'] as List?) ?? [];
|
||||||
|
|
||||||
|
final res = list
|
||||||
|
.map((e) => QrParkingResponseModel.fromJson(
|
||||||
|
Map<String, dynamic>.from(e),
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
apiResponse = GenericApiModel<List<QrParkingResponseModel>>(
|
||||||
|
messageStatus: messageStatus,
|
||||||
|
statusCode: statusCode,
|
||||||
|
errorMessage: null,
|
||||||
|
data: res,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (failure != null) return Left(failure!);
|
||||||
|
if (apiResponse == null) {
|
||||||
|
return Left(ServerFailure("Unknown error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Right(apiResponse!);
|
||||||
|
} catch (e) {
|
||||||
|
return Left(UnknownFailure(e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,144 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/qr_parking/qr_parking_repo.dart';
|
||||||
|
|
||||||
|
import '../../services/cache_service.dart';
|
||||||
|
import '../../services/error_handler_service.dart';
|
||||||
|
import 'models/qr_parking_response_model.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class QrParkingViewModel extends ChangeNotifier {
|
||||||
|
final QrParkingRepo qrParkingRepo;
|
||||||
|
final ErrorHandlerService errorHandlerService;
|
||||||
|
final CacheService cacheService;
|
||||||
|
String IS_GO_TO_PARKING = 'IS_GO_TO_PARKING';
|
||||||
|
|
||||||
|
bool isLoading = false;
|
||||||
|
String? error;
|
||||||
|
|
||||||
|
bool isSavePark = false;
|
||||||
|
QrParkingResponseModel? qrParkingModel;
|
||||||
|
List<QrParkingResponseModel> qrParkingList = [];
|
||||||
|
|
||||||
|
QrParkingViewModel({
|
||||||
|
required this.qrParkingRepo,
|
||||||
|
required this.errorHandlerService,
|
||||||
|
required this.cacheService,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Future<QrParkingResponseModel?> scanAndGetParking() async {
|
||||||
|
try {
|
||||||
|
error = null;
|
||||||
|
isLoading = true;
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
|
final result = await BarcodeScanner.scan();
|
||||||
|
|
||||||
|
if (result.type != ResultType.Barcode) {
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final raw = result.rawContent.trim();
|
||||||
|
if (raw.isEmpty) {
|
||||||
|
error = "Invalid QR Code";
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final qrParkingId = _extractQrParkingId(raw);
|
||||||
|
if (qrParkingId == null) {
|
||||||
|
error = "Invalid QR Code";
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final apiResult =
|
||||||
|
await qrParkingRepo.getQrParking(qrParkingId: qrParkingId);
|
||||||
|
|
||||||
|
final model = apiResult.fold(
|
||||||
|
(failure) {
|
||||||
|
errorHandlerService.handleError(failure: failure);
|
||||||
|
error = failure.toString();
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
(apiResponse) {
|
||||||
|
qrParkingList = apiResponse.data ?? [];
|
||||||
|
if (qrParkingList.isNotEmpty) {
|
||||||
|
return qrParkingList.first;
|
||||||
|
}
|
||||||
|
error = "Invalid Qr Code";
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (model != null) {
|
||||||
|
qrParkingModel = model;
|
||||||
|
isSavePark = true;
|
||||||
|
|
||||||
|
await cacheService.saveObject(
|
||||||
|
key: IS_GO_TO_PARKING,
|
||||||
|
value: model.toJson(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return model;
|
||||||
|
} catch (e) {
|
||||||
|
error = "Scan error";
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load saved parking
|
||||||
|
Future<void> getIsSaveParking() async {
|
||||||
|
isLoading = true;
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
|
final parking =
|
||||||
|
await cacheService.getObject(key: IS_GO_TO_PARKING);
|
||||||
|
|
||||||
|
if (parking != null) {
|
||||||
|
isSavePark = true;
|
||||||
|
qrParkingModel = QrParkingResponseModel.fromJson(
|
||||||
|
Map<String, dynamic>.from(parking),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
isSavePark = false;
|
||||||
|
qrParkingModel = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset parking
|
||||||
|
Future<void> clearParking() async {
|
||||||
|
await cacheService.remove(key: IS_GO_TO_PARKING);
|
||||||
|
isSavePark = false;
|
||||||
|
qrParkingModel = null;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
int? _extractQrParkingId(String raw) {
|
||||||
|
try {
|
||||||
|
if (raw.startsWith("{")) {
|
||||||
|
final data = jsonDecode(raw);
|
||||||
|
return int.tryParse(data['QRParkingID'].toString());
|
||||||
|
}
|
||||||
|
return int.tryParse(raw);
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue