505 lines
16 KiB
Dart
505 lines
16 KiB
Dart
import 'dart:io';
|
|
import 'package:dio/dio.dart';
|
|
import 'dart:convert';
|
|
import 'package:crypto/crypto.dart';
|
|
import 'package:path/path.dart' as path;
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:http_parser/http_parser.dart';
|
|
import 'package:intl/intl.dart';
|
|
|
|
import 'package:mobdr/config/constant.dart';
|
|
import 'package:mobdr/main.dart';
|
|
import 'package:mobdr/service/shared_prefs.dart';
|
|
|
|
class ApiProvider {
|
|
final Dio _dio;
|
|
|
|
ApiProvider() : _dio = Dio();
|
|
|
|
String connErr = 'Please check your internet connection and try again';
|
|
|
|
Future<Response> getCrud(url, body) async {
|
|
print('url : ' + url.toString());
|
|
try {
|
|
_dio.options.headers['content-Type'] = 'application/json';
|
|
_dio.options.headers['Accept'] = 'application/json';
|
|
_dio.options.headers['Cookie'] = "pguid=${SharedPrefs().guid}";
|
|
|
|
_dio.options.connectTimeout = Duration(seconds: 5);
|
|
_dio.options.receiveTimeout = Duration(seconds: 4);
|
|
|
|
if (body != null) {
|
|
_dio.options.queryParameters = body;
|
|
}
|
|
|
|
return await _dio.get(url);
|
|
} on DioException catch (e) {
|
|
//print(e.toString()+' | '+url.toString());
|
|
if (e.type == DioExceptionType.badResponse) {
|
|
int? statusCode = e.response!.statusCode;
|
|
if (statusCode == STATUS_NOT_FOUND) {
|
|
throw "Api not found";
|
|
} else if (statusCode == STATUS_INTERNAL_ERROR) {
|
|
throw "Internal Server Error";
|
|
} else {
|
|
throw e.error.toString();
|
|
}
|
|
} else if (e.type == DioExceptionType.connectionTimeout) {
|
|
throw e.message.toString();
|
|
} else if (e.type == DioExceptionType.cancel) {
|
|
throw 'cancel';
|
|
}
|
|
throw connErr;
|
|
}
|
|
}
|
|
|
|
Future<Response> getConnect(url, apiToken) async {
|
|
print('url : ' + url.toString());
|
|
try {
|
|
_dio.options.headers['content-Type'] =
|
|
'application/x-www-form-urlencoded';
|
|
_dio.options.connectTimeout = Duration(seconds: 5);
|
|
_dio.options.receiveTimeout = Duration(seconds: 4);
|
|
|
|
return await _dio.post(url, cancelToken: apiToken);
|
|
} on DioException catch (e) {
|
|
//print(e.toString()+' | '+url.toString());
|
|
if (e.type == DioExceptionType.badResponse) {
|
|
int? statusCode = e.response!.statusCode;
|
|
if (statusCode == STATUS_NOT_FOUND) {
|
|
throw "Api not found";
|
|
} else if (statusCode == STATUS_INTERNAL_ERROR) {
|
|
throw "Internal Server Error";
|
|
} else {
|
|
throw e.error.toString();
|
|
}
|
|
} else if (e.type == DioExceptionType.connectionTimeout) {
|
|
throw e.message.toString();
|
|
} else if (e.type == DioExceptionType.cancel) {
|
|
throw 'cancel';
|
|
}
|
|
throw connErr;
|
|
}
|
|
}
|
|
|
|
Future<Response> postConnect(url, data, apiToken) async {
|
|
print('url : ' + url.toString());
|
|
print('postData : ' + data.toString());
|
|
try {
|
|
_dio.options.headers['content-Type'] =
|
|
'application/x-www-form-urlencoded';
|
|
_dio.options.connectTimeout = Duration(seconds: 5);
|
|
_dio.options.receiveTimeout = Duration(seconds: 4);
|
|
|
|
return await _dio.post(url, data: data, cancelToken: apiToken);
|
|
} on DioException catch (e) {
|
|
//print(e.toString()+' | '+url.toString());
|
|
if (e.type == DioExceptionType.badResponse) {
|
|
int? statusCode = e.response!.statusCode;
|
|
if (statusCode == STATUS_NOT_FOUND) {
|
|
throw "Api not found";
|
|
} else if (statusCode == STATUS_INTERNAL_ERROR) {
|
|
throw "Internal Server Error";
|
|
} else {
|
|
throw e.error.toString();
|
|
}
|
|
} else if (e.type == DioExceptionType.connectionTimeout) {
|
|
throw e.message.toString();
|
|
} else if (e.type == DioExceptionType.cancel) {
|
|
throw 'cancel';
|
|
}
|
|
throw connErr;
|
|
}
|
|
}
|
|
|
|
/// login function
|
|
Future<String> login(
|
|
String userName, String pinCode, String securityCode) async {
|
|
var body = {
|
|
"application": "MobDR " + SharedPrefs().appVersion,
|
|
"pin_code": md5.convert(utf8.encode(pinCode)),
|
|
"security_code": securityCode,
|
|
"langage": SharedPrefs().langage,
|
|
"screenheight": SharedPrefs().screenHeight.truncate().toString(),
|
|
"screenwidth": SharedPrefs().screenWidth.truncate().toString(),
|
|
"browser_name": "Natif",
|
|
"browser_version": "Flutter",
|
|
"engine_name": SharedPrefs().systemName,
|
|
"device_model": SharedPrefs().deviceModel,
|
|
"device_type": SharedPrefs().deviceName,
|
|
"device_vendor": SharedPrefs().systemName,
|
|
"ismobile": 1,
|
|
"engine_version": SharedPrefs().systemName,
|
|
"os_name": SharedPrefs().systemName,
|
|
"os_version": SharedPrefs().systemVersion,
|
|
"fingerprint": SharedPrefs().fingerPrint
|
|
};
|
|
Response response;
|
|
|
|
try {
|
|
response = await getCrud(
|
|
ApiConstants.baseUrl +
|
|
ApiConstants.mp4Endpoint +
|
|
ApiConstants.restEndpoint +
|
|
'/login/' +
|
|
userName +
|
|
'/guid',
|
|
body);
|
|
|
|
switch (response.data['autorisation']) {
|
|
case 1:
|
|
|
|
/// save user data
|
|
SharedPrefs().id_utilisateur = response.data['id_utilisateur'];
|
|
SharedPrefs().email = response.data['email'];
|
|
SharedPrefs().expire = response.data['expire'];
|
|
SharedPrefs().guid = response.data['guid'];
|
|
SharedPrefs().langage = response.data['langage'];
|
|
SharedPrefs().last_traduction = response.data['last_traduction'];
|
|
SharedPrefs().login = response.data['login'];
|
|
SharedPrefs().nom = response.data['nom'];
|
|
SharedPrefs().prenom = response.data['prenom'];
|
|
SharedPrefs().version = response.data['version'];
|
|
SharedPrefs().photo = response.data['photo'];
|
|
|
|
/// get image from url
|
|
Response ReponseImg =
|
|
await _dio.get(ApiConstants.baseUrl + response.data['photo'],
|
|
options: Options(
|
|
responseType: ResponseType.bytes,
|
|
contentType: 'application/octet-stream',
|
|
));
|
|
|
|
/// convert bytes to base64 string
|
|
String base64Photo = base64.encode(ReponseImg.data);
|
|
|
|
/// create box user
|
|
objectbox.userBox.removeAll();
|
|
objectbox.addUSer(
|
|
response.data['id_utilisateur'],
|
|
response.data['login'],
|
|
response.data['nom'],
|
|
response.data['prenom'],
|
|
base64Photo);
|
|
|
|
return 'OK';
|
|
case -1:
|
|
return 'Compte désactivé ...';
|
|
case -2:
|
|
return 'SECURITY_CODE';
|
|
case -3:
|
|
return 'Téléphone bloqué !';
|
|
case -4:
|
|
return 'Code PIN incorrect !';
|
|
default:
|
|
return "Une erreur inconnue s''est produite";
|
|
}
|
|
} catch (ex) {
|
|
return ex.toString(); // return ex.response!.data;
|
|
}
|
|
}
|
|
|
|
/// Synchronize all informations about store, competitor, calendar
|
|
Future<String> SyncCalendar() async {
|
|
DateTime now = DateTime.now();
|
|
DateTime end = now.add(Duration(days: 7));
|
|
|
|
String formattedStartDate = DateFormat('yyyyMMdd').format(now);
|
|
String formattedEndDate = DateFormat('yyyyMMdd').format(end);
|
|
|
|
try {
|
|
final responseFutures = Future.wait([
|
|
getCrud(
|
|
ApiConstants.baseUrl +
|
|
ApiConstants.externalEndpoint +
|
|
ApiConstants.restEndpoint +
|
|
'/mobDR/etablissement',
|
|
null,
|
|
),
|
|
getCrud(
|
|
ApiConstants.baseUrl +
|
|
ApiConstants.externalEndpoint +
|
|
ApiConstants.restEndpoint +
|
|
'/mobDR/etablissement/concurrent',
|
|
null,
|
|
),
|
|
getCrud(
|
|
ApiConstants.baseUrl +
|
|
ApiConstants.externalEndpoint +
|
|
ApiConstants.restEndpoint +
|
|
'/mobDR/visite/calendrier',
|
|
{
|
|
"id_utilisateur": SharedPrefs().id_utilisateur,
|
|
"start": formattedStartDate,
|
|
"end": formattedEndDate
|
|
},
|
|
),
|
|
getCrud(
|
|
ApiConstants.baseUrl +
|
|
ApiConstants.externalEndpoint +
|
|
ApiConstants.restEndpoint +
|
|
'/mobDR/visite/tag',
|
|
null,
|
|
),
|
|
getCrud(
|
|
ApiConstants.baseUrl +
|
|
ApiConstants.externalEndpoint +
|
|
ApiConstants.restEndpoint +
|
|
'/mobDR/visite/typologie',
|
|
null),
|
|
]);
|
|
|
|
final List<Response<dynamic>> responses =
|
|
await responseFutures.timeout(Duration(seconds: 30));
|
|
|
|
final etabResponse = responses[0];
|
|
final competitorResponse = responses[1];
|
|
final visitResponse = responses[2];
|
|
final visitTagResponse = responses[3];
|
|
final PhotoTypologyResponse = responses[4];
|
|
|
|
if (etabResponse.statusCode == STATUS_OK) {
|
|
// remove all objects
|
|
objectbox.etabBox.removeAll();
|
|
|
|
// fill box "Etabs"
|
|
objectbox.addEtabs(etabResponse.data['boutiques']);
|
|
}
|
|
|
|
if (competitorResponse.statusCode == STATUS_OK) {
|
|
// remove all objects
|
|
objectbox.etabCompetitorBox.removeAll();
|
|
|
|
// fill box "Etabs"
|
|
objectbox.addEtabCompetitors(competitorResponse.data['concurrents']);
|
|
}
|
|
|
|
if (visitResponse.statusCode == STATUS_OK) {
|
|
/// fill box "visite"
|
|
objectbox.syncVisits(visitResponse.data['events']);
|
|
}
|
|
|
|
if (visitTagResponse.statusCode == STATUS_OK) {
|
|
// remove all objects
|
|
objectbox.visitTagBox.removeAll();
|
|
|
|
/// fill box "visiteTag"
|
|
objectbox.addVisitTags(visitTagResponse.data['tags']);
|
|
}
|
|
|
|
if (PhotoTypologyResponse.statusCode == STATUS_OK) {
|
|
// remove all objects
|
|
objectbox.PhotoTypologyBox.removeAll();
|
|
|
|
/// fill box "PhotoTypology"
|
|
objectbox.addPhotoTypologies(PhotoTypologyResponse.data['typologies']);
|
|
}
|
|
|
|
if (etabResponse.statusCode == STATUS_OK &&
|
|
competitorResponse.statusCode == STATUS_OK &&
|
|
visitResponse.statusCode == STATUS_OK &&
|
|
visitTagResponse.statusCode == STATUS_OK &&
|
|
PhotoTypologyResponse.statusCode == STATUS_OK) {
|
|
return 'OK';
|
|
} else {
|
|
return etabResponse.statusMessage ??
|
|
competitorResponse.statusMessage ??
|
|
visitResponse.statusMessage ??
|
|
visitTagResponse.statusMessage ??
|
|
PhotoTypologyResponse.statusMessage ??
|
|
'Unknown error';
|
|
}
|
|
} catch (ex) {
|
|
return ex.toString();
|
|
}
|
|
}
|
|
|
|
Future<int> uploadPhotoServlet(int id_visite, String photoPath) async {
|
|
try {
|
|
final url = Uri.parse(SERVLET_API);
|
|
final file = File(photoPath);
|
|
final bytes = await file.readAsBytes();
|
|
|
|
final multipartRequest = http.MultipartRequest('POST', url)
|
|
..fields['id_visite'] = id_visite.toString()
|
|
..files.add(http.MultipartFile.fromBytes(
|
|
'photo',
|
|
bytes,
|
|
filename: path.basename(photoPath),
|
|
contentType: MediaType('image', 'jpeg'),
|
|
));
|
|
|
|
final headers = {'Cookie': "pguid=${SharedPrefs().guid};"};
|
|
multipartRequest.headers.addAll(headers);
|
|
|
|
final response = await multipartRequest.send();
|
|
final responseString = await response.stream.bytesToString();
|
|
|
|
final jsonResponse = jsonDecode(responseString);
|
|
final idPhotoString = jsonResponse[0]['id_photo'];
|
|
final idPhoto = int.parse(idPhotoString);
|
|
|
|
return idPhoto;
|
|
} catch (e) {
|
|
print('Error uploading photo: $e');
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
Future<bool> updatePhotoTypology(
|
|
int id_visite, int id_photo_mp4, int id_photo_typologie) async {
|
|
final url =
|
|
'${ApiConstants.baseUrl}${ApiConstants.mp4Endpoint}${ApiConstants.restEndpoint}/visite/$id_visite/photo/$id_photo_mp4/tri/typo';
|
|
|
|
final headers = {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'Accept': 'application/json',
|
|
'Cookie': 'pguid=${SharedPrefs().guid};',
|
|
};
|
|
|
|
final params = {
|
|
'id_typologie': id_photo_typologie.toString(),
|
|
};
|
|
|
|
final response =
|
|
await http.put(Uri.parse(url), headers: headers, body: params);
|
|
|
|
if (response.statusCode == 200) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> updatePhotoVisibility(int id_visite, int id_photo_mp4,
|
|
int photo_principale, int photo_privee) async {
|
|
final url =
|
|
'${ApiConstants.baseUrl}${ApiConstants.mp4Endpoint}${ApiConstants.restEndpoint}/visite/$id_visite/photo/$id_photo_mp4/tri/visibilite';
|
|
|
|
final headers = {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'Accept': 'application/json',
|
|
'Cookie': 'pguid=${SharedPrefs().guid};',
|
|
};
|
|
|
|
final params = {
|
|
'principale': photo_principale.toString(),
|
|
'privee': photo_privee.toString(),
|
|
};
|
|
|
|
final response =
|
|
await http.put(Uri.parse(url), headers: headers, body: params);
|
|
|
|
if (response.statusCode == 200) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> updatePhotoTags(
|
|
int id_visite, int id_photo_mp4, String tags) async {
|
|
final url =
|
|
'${ApiConstants.baseUrl}${ApiConstants.mp4Endpoint}${ApiConstants.restEndpoint}/visite/$id_visite/photo/$id_photo_mp4/tri/tags';
|
|
|
|
final headers = {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'Accept': 'application/json',
|
|
'Cookie': 'pguid=${SharedPrefs().guid};',
|
|
};
|
|
|
|
final params = {'tags': tags};
|
|
|
|
final response =
|
|
await http.put(Uri.parse(url), headers: headers, body: params);
|
|
|
|
if (response.statusCode == 200) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> updatePhotoConpetitor(
|
|
int id_visite, int id_photo_mp4, int id_concurrence_lien) async {
|
|
final url =
|
|
'${ApiConstants.baseUrl}${ApiConstants.mp4Endpoint}${ApiConstants.restEndpoint}/visite/$id_visite/photo/$id_photo_mp4/tri/concurrence';
|
|
|
|
final headers = {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'Accept': 'application/json',
|
|
'Cookie': 'pguid=${SharedPrefs().guid};',
|
|
};
|
|
|
|
final params = {
|
|
'id_concurrence_lien': id_concurrence_lien.toString(),
|
|
};
|
|
|
|
final response =
|
|
await http.put(Uri.parse(url), headers: headers, body: params);
|
|
|
|
if (response.statusCode == 200) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// Synchronize log
|
|
Future<String> SyncLog() async {
|
|
final url =
|
|
'${ApiConstants.baseUrl}${ApiConstants.externalEndpoint}${ApiConstants.restEndpoint}/mobDR/log';
|
|
|
|
final headers = {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'Accept': 'application/json',
|
|
'Cookie': 'pguid=${SharedPrefs().guid};',
|
|
};
|
|
|
|
final logs = await objectbox.getLogs().first;
|
|
|
|
for (final log in logs) {
|
|
final params = {
|
|
'date': log.dateEnFormat,
|
|
'libelle': '${log.module}.${log.libelle}',
|
|
'type': log.type,
|
|
'duree_ms': log.duree.toString(),
|
|
};
|
|
|
|
final response =
|
|
await http.post(Uri.parse(url), headers: headers, body: params);
|
|
|
|
if (response.statusCode == 200) {
|
|
// delete log
|
|
objectbox.delLogById(log.id);
|
|
}
|
|
}
|
|
|
|
return "OK";
|
|
}
|
|
|
|
void close() {
|
|
_dio.close();
|
|
}
|
|
|
|
Future<bool> checkAppVersion() async {
|
|
try {
|
|
final response = await http
|
|
.get(Uri.parse(DOMAIN_CHECK_VERSION + '/deploy/mobdr/version.json'));
|
|
final data = jsonDecode(response.body);
|
|
|
|
if (data.containsKey('latest_version')) {
|
|
if (data['latest_version'] != SharedPrefs().appVersion) {
|
|
// The versions differ
|
|
return true;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
print('Error verifying the version : $e');
|
|
}
|
|
|
|
// If an error has occurred or if the versions are identical
|
|
return false;
|
|
}
|
|
}
|