mobdr/lib/objectbox.dart

744 lines
23 KiB
Dart

import 'package:mobdr/db/box_user.dart';
import 'package:mobdr/db/box_log.dart';
import 'package:mobdr/db/box_etab.dart';
import 'package:mobdr/db/box_photo_competitor.dart';
import 'package:mobdr/db/box_visit.dart';
import 'package:mobdr/db/box_visit_tag.dart';
import 'package:mobdr/db/box_visit_photo.dart';
import 'package:mobdr/db/box_photo_typology.dart';
import 'package:mobdr/service/logger_util.dart';
import 'objectbox.g.dart'; // created by `flutter pub run build_runner build`
/// Provides access to the ObjectBox Store throughout the app.
///
/// Create this in the apps main function.
class ObjectBox {
/// The Store of this app.
late final Store store;
/// A Box of user
late final Box<User> userBox;
/// A Box of etablishment
late final Box<Etab> etabBox;
/// A Box of etablishment competitor
late final Box<EtabCompetitor> etabCompetitorBox;
/// A Box of visit
late final Box<Visit> visitBox;
/// A Box for all visit tag by distributor / language
late final Box<VisitTag> visitTagBox;
/// A Box of visit Photo
late final Box<VisitPhoto> visitPhotoBox;
/// A Box of photo typology
late final Box<PhotoTypology> PhotoTypologyBox;
/// A Box of log.
late final Box<Log> logBox;
ObjectBox._create(this.store) {
userBox = Box<User>(store);
etabBox = Box<Etab>(store);
etabCompetitorBox = Box<EtabCompetitor>(store);
visitBox = Box<Visit>(store);
visitTagBox = Box<VisitTag>(store);
PhotoTypologyBox = Box<PhotoTypology>(store);
visitPhotoBox = Box<VisitPhoto>(store);
logBox = Box<Log>(store);
}
/// Create an instance of ObjectBox to use throughout the app.
static Future<ObjectBox> create() async {
// Future<Store> openStore() {...} is defined in the generated objectbox.g.dart
final store = await openStore();
return ObjectBox._create(store);
}
/// USER ---------------------------------------------------------------------
///
void addUSer(int _id_utilisateur, String _login, String _nom, String _prenom,
String _photo) {
userBox.put(User(
id_utilisateur: _id_utilisateur,
login: _login,
nom: _nom,
prenom: _prenom,
photo: _photo));
}
String getUserAvatar(int id_utilisateur) {
final query =
userBox.query(User_.id_utilisateur.equals(id_utilisateur)).build();
var p = query.findFirst();
return p!.photo;
}
/// ETAB ---------------------------------------------------------------------
///
// A function that converts a response body into a List<Etab>.
List<Etab> parseEtabs(List responseDataList) {
final parsed = responseDataList.cast<Map<String, dynamic>>();
return parsed.map<Etab>((json) => Etab.fromJson(json)).toList();
}
Future<void> addEtabs(List<dynamic> _listEtabs) =>
store.runInTransactionAsync(
TxMode.write, _addEtabsInTx, parseEtabs(_listEtabs));
static void _addEtabsInTx(Store store, _Etabs) {
store.box<Etab>().putMany(_Etabs);
}
Future<void> addEtab(int _id_etab, String _nom, String _mail, String _tel,
String _photo_principale, String _longitude, String _latitude) =>
store.runInTransactionAsync(
TxMode.write,
_addEtabInTx,
Etab(
id_etab: _id_etab,
nom: _nom,
mail: _mail,
tel: _tel,
url_photo_principale: _photo_principale,
longitude: _longitude,
latitude: _latitude));
static void _addEtabInTx(Store store, _Etab) {
store.box<Etab>().put(_Etab);
}
String getEtabPhotoPrincipale(int _id_etab) {
final query = etabBox.query(Etab_.id_etab.equals(_id_etab)).build();
var p = query.findFirst();
return p!.url_photo_principale;
}
int getEtabCount() {
return etabBox.count();
}
/// ETAB COMPETITOR ---------------------------------------------------------------
///
// A function that converts a response body list into a List<Competitor>.
List<EtabCompetitor> parseEtabCompetitor(List responseDataList) {
final parsed = responseDataList.cast<Map<String, dynamic>>();
return parsed
.map<EtabCompetitor>((json) => EtabCompetitor.fromJson(json))
.toList();
}
Future<void> addEtabCompetitors(List<dynamic> _listPhotoCompetitors) =>
store.runInTransactionAsync(TxMode.write, _addEtabCompetitorsInTx,
parseEtabCompetitor(_listPhotoCompetitors));
static void _addEtabCompetitorsInTx(Store store, _Competitors) {
store.box<EtabCompetitor>().putMany(_Competitors);
}
Future<void> addEtabCompetitor(
int _id_concurrence_lien, int _id_etab, _nom) =>
store.runInTransactionAsync(
TxMode.write,
_addEtabCompetitorInTx,
EtabCompetitor(
id_concurrence_lien: _id_concurrence_lien,
id_etab: _id_etab,
nom: _nom,
));
static void _addEtabCompetitorInTx(Store store, _Competitor) {
store.box<EtabCompetitor>().put(_Competitor);
}
List<EtabCompetitor> getEtabCompetitorList(int _id_etab) {
final query = etabCompetitorBox
.query(EtabCompetitor_.id_etab.equals(_id_etab))
.order(EtabCompetitor_.nom)
.build();
final etabCompetitors = query.find();
return etabCompetitors.toList();
}
/// Retrieves a etab competitor object from the ObjectBox database with the specified ID.
///
/// Parameters:
/// _id_concurrence_lien : The _id_concurrence_lien of the competitor to retrieve.
///
/// Returns:
/// A Etab Competitor object, or null if no object is found.
EtabCompetitor? getEtabCompetitorByLink(int _id_concurrence_lien) {
final query = etabCompetitorBox
.query(EtabCompetitor_.id_concurrence_lien.equals(_id_concurrence_lien))
.build();
return query.findFirst();
}
int getEtabCompetitorsCount() {
return etabCompetitorBox.count();
}
/// VISITE ------------------------------------------------------------------
///
Stream<List<Visit>> getVisitStream() {
// Query for all visites, sorted by their date.
// https://docs.objectbox.io/queries
final builder =
visitBox.query().order(Visit_.date_visite, flags: Order.descending);
// Build and watch the query,
// set triggerImmediately to emit the query immediately on listen.
return builder
.watch(triggerImmediately: true)
// Map it to a list of notes to be used by a StreamBuilder.
.map((query) => query.find());
}
List<Visit> getAllVisit() {
// Query for all visites, sorted by their date.
final builder = visitBox
.query()
.order(Visit_.date_visite, flags: Order.descending)
.build();
// Execute the query and return the result.
return builder.find();
}
List<Visit> getTodayVisit() {
final now = DateTime.now();
// Get the start and end of the current day as timestamps.
final startOfDay =
DateTime(now.year, now.month, now.day).millisecondsSinceEpoch;
final endOfDay = DateTime(now.year, now.month, now.day, 23, 59, 59)
.millisecondsSinceEpoch;
// Query for all visits that occur on the current day and have not been abandoned.
final builder = visitBox
.query(Visit_.date_visite.between(startOfDay, endOfDay) &
Visit_.abandon.equals(0))
.order(Visit_.date_visite, flags: Order.descending)
.build();
// Execute the query and return the result.
return builder.find();
}
List<Visit> getActivePreviousVisit() {
// Get the previous date at midnight.
final now = DateTime.now();
final midnight = DateTime(now.year, now.month, now.day);
// Convert the date to an integer.
final millisecondsSinceEpoch = midnight.millisecondsSinceEpoch;
// Query for all visits that match the date and abandonment criteria, sorted by their date.
final builder = visitBox
.query(
Visit_.date_visite.lessThan(millisecondsSinceEpoch) &
Visit_.abandon.equals(0),
)
.order(Visit_.date_visite, flags: Order.descending)
.build();
// Execute the query and return the result.
return builder.find();
}
List<Visit> getPreviousVisit() {
// Get the previous date at midnight.
final now = DateTime.now();
final midnight = DateTime(now.year, now.month, now.day);
// Convert the date to an integer.
final millisecondsSinceEpoch = midnight.millisecondsSinceEpoch;
// Query for all visits that match the date criteria, sorted by their date.
final builder = visitBox
.query(Visit_.date_visite.lessThan(millisecondsSinceEpoch))
.order(Visit_.date_visite, flags: Order.descending)
.build();
// Execute the query and return the result.
return builder.find();
}
// A function that converts a response body list into a List<Visite>.
List<Visit> parseVisit(List responseDataList) {
final parsed = responseDataList.cast<Map<String, dynamic>>();
return parsed.map<Visit>((json) => Visit.fromJson(json)).toList();
}
// TODO : Enregistre urlphotoprincipale sur le disque pour l'avoir en cache ?
Future<void> addVisits(List<dynamic> _listVisits) =>
store.runInTransactionAsync(
TxMode.write, _addVisitsInTx, parseVisit(_listVisits));
static void _addVisitsInTx(Store store, _Visits) {
store.box<Visit>().putMany(_Visits);
}
Future<void> addVisit(
int _id_visite,
DateTime _date_visite,
DateTime _date_debut,
DateTime _date_fin,
DateTime _date_validation,
String _type_visite,
String _title,
bool _allDay,
String _start,
int _id_distrib_visite,
int _id_etab,
int _abandon,
String _end,
String _url_photo_principale,
String _langage) =>
store.runInTransactionAsync(
TxMode.write,
_addVisitInTx,
Visit(
id_visite: _id_visite,
date_visite: _date_visite,
date_debut: _date_debut,
date_fin: _date_fin,
date_validation: _date_validation,
type_visite: _type_visite,
title: _title,
allDay: _allDay,
id_distrib_visite: _id_distrib_visite,
id_etab: _id_etab,
abandon: _abandon,
url_photo_principale: _url_photo_principale,
langage: _langage));
static void _addVisitInTx(Store store, _Visite) {
store.box<Visit>().put(_Visite);
}
Future<void> syncVisits(List<dynamic> _listVisits) async {
final toSyncId_visite =
_listVisits.map<int>((v) => v['id_visite']).toList();
final existingVisitsQuery =
visitBox.query(Visit_.id_visite.oneOf(toSyncId_visite));
final existingVisits = existingVisitsQuery.build().find();
final existingVisitIds =
existingVisits.map<int>((v) => v.id_visite).toList();
final newVisits = _listVisits
.where((v) => !existingVisitIds.contains(v['id_visite']))
.toList();
final updatedVisits = _listVisits
.where((v) => existingVisitIds.contains(v['id_visite']))
.toList();
newVisits.forEach((v) {
visitBox.put(Visit.fromJson(v));
});
updatedVisits.forEach((v) {
final existingVisit =
existingVisits.firstWhere((ev) => ev.id_visite == v['id_visite']);
final updatedVisit = Visit.fromJson(v)..id = existingVisit.id;
visitBox.put(updatedVisit);
});
}
Future<void> DeleteVisitWithoutPhoto() async {
final visits = getAllVisit();
for (final visit in visits) {
final photoCount = getVisitPhotoTaken(visit.id_visite);
if (photoCount == 0) {
// Delete the visit
delVisitById(visit.id);
}
}
}
/// Removes a Visit object from the ObjectBox database with the specified ID.
///
/// Parameters:
/// id: The ID of the Visit object to remove.
///
/// Returns:
/// None.
void delVisitById(int id) {
if (visitBox.remove(id)) {
LoggerUtil.logNStacktackDebug("delete visit:${id}");
} else
LoggerUtil.logNStackError("delete visit:${id} KO");
}
int getVisitCount() {
return visitBox.count();
}
/// VISIT TAG ---------------------------------------------------------------
///
// converts a response body list into a List<VisitTag>.
List<VisitTag> parseVisitTags(List responseDataList) {
final parsed = responseDataList.cast<Map<String, dynamic>>();
return parsed.map<VisitTag>((json) => VisitTag.fromJson(json)).toList();
}
Future<void> addVisitTags(List<dynamic> _listVisitTags) =>
store.runInTransactionAsync(
TxMode.write, _addVisitTagsInTx, parseVisitTags(_listVisitTags));
static void _addVisitTagsInTx(Store store, _VisitTags) {
store.box<VisitTag>().putMany(_VisitTags);
}
/// save new tag for a distributor / langage
Future<void> addVisitTag(
int id_visite_tag,
int _id_distrib,
String _libelle,
String _langage,
) =>
store.runInTransactionAsync(
TxMode.write,
_addVisitTagInTx,
VisitTag(
id_visite_tag: id_visite_tag,
id_distrib: _id_distrib,
libelle: _libelle,
langage: _langage,
));
static void _addVisitTagInTx(Store store, _VisitTag) {
store.box<VisitTag>().put(_VisitTag);
}
List<String> getVisitTagsLabels(int distribId, String langage) {
final query = visitTagBox
.query(VisitTag_.id_distrib.equals(distribId) &
VisitTag_.langage.equals(langage))
//.order(VisitTag_.libelle)
.build();
PropertyQuery<String> pq = query.property(VisitTag_.libelle);
pq.distinct = true;
pq.caseSensitive = false;
return pq.find();
}
int getVisitTagCount() {
return visitTagBox.count();
}
/// PHOTO --------------------------------------------------------------------
///
///
Future<List<VisitPhoto>> addPhotos(List<VisitPhoto> photos) async {
final addedPhotos = await visitPhotoBox.putAndGetManyAsync(photos);
return addedPhotos;
}
Future<void> addPhoto(
int id_visite, int id_photo_typologie, String image_name) =>
store.runInTransactionAsync(
TxMode.write,
_addPhotoInTx,
VisitPhoto(
id_visite: id_visite,
id_photo_typologie: id_photo_typologie,
image_name: image_name));
static void _addPhotoInTx(Store store, _Photo) {
// Perform ObjectBox operations that take longer than a few milliseconds
// here. To keep it simple, this example just puts a single object.
store.box<VisitPhoto>().put(_Photo);
}
List<VisitPhoto> getAllVisitTypologyPhotos(
int id_visite, int _id_photo_typologie) {
// Query for all photos, sorted by their date.
// https://docs.objectbox.io/queries
final query = visitPhotoBox
.query(VisitPhoto_.id_visite.equals(id_visite) &
VisitPhoto_.id_photo_typologie.equals(_id_photo_typologie))
.order(VisitPhoto_.date_photo, flags: Order.descending)
.build();
return query.find();
}
// Retrieves a VisitPhoto object from the ObjectBox database with the specified visit ID.
///
/// Parameters:
/// _id_visite: The ID of the visit the photo belongs to.
///
/// Returns:
/// A VisitPhoto object, or null if no object is found.
List<VisitPhoto> getAllVisitPhotosByVisit(int id_visite) {
final query =
visitPhotoBox.query(VisitPhoto_.id_visite.equals(id_visite)).build();
return query.find();
}
/// Retrieves all VisitPhoto objects from the ObjectBox database.
///
/// Parameters:
/// None.
///
/// Returns:
/// A list of VisitPhoto objects, or an empty list if no objects are found.
List<VisitPhoto> getAllVisitPhotos() {
final query = visitPhotoBox.query().build();
return query.find();
}
/// Retrieves a Photo object from the ObjectBox database with the specified ID.
///
/// Parameters:
/// id_photo: The ID of the photo to retrieve.
///
/// Returns:
/// A Photo object, or null if no object is found.
VisitPhoto? getPhotoById(int _id) {
final photo = visitPhotoBox.get(_id);
return photo;
}
Stream<List<VisitPhoto>> getPhotos() {
// Query for all photos, sorted by their date.
// https://docs.objectbox.io/queries
final builder = visitPhotoBox
.query()
.order(VisitPhoto_.date_photo, flags: Order.descending);
// Build and watch the query,
// set triggerImmediately to emit the query immediately on listen.
return builder
.watch(triggerImmediately: true)
// Map it to a list of notes to be used by a StreamBuilder.
.map((query) => query.find());
}
/// Removes a VisitPhoto object from the ObjectBox database with the specified ID.
///
/// Parameters:
/// id: The ID of the VisitPhoto object to remove.
///
/// Returns:
/// None.
void delPhotoById(int id) {
if (visitPhotoBox.remove(id)) {
print("Supression photo :${id}");
} else
print("Supression photo :${id} KO");
}
/// Removes a VisitPhoto object from the ObjectBox database with the specified ID.
///
/// Parameters:
/// id: The NAME of the VisitPhoto object to remove.
///
/// Returns:
/// None.
void delPhotoByName(String _name) {
final query =
visitPhotoBox.query(VisitPhoto_.image_name.equals(_name)).build();
final results = query.find();
if (results.isNotEmpty) {
final photoToDelete = results.first;
visitPhotoBox.remove(photoToDelete.id);
}
}
int getVisitPhotoTaken(int _id_visite) {
final builder =
visitPhotoBox.query(VisitPhoto_.id_visite.equals(_id_visite)).build();
return builder.count();
}
int getVisitTypologiePhotoCount(int _id_visite, int _id_photo_typologie) {
final builder = visitPhotoBox
.query(VisitPhoto_.id_visite.equals(_id_visite) &
VisitPhoto_.id_photo_typologie.equals(_id_photo_typologie))
.build();
return builder.count();
}
void putPhotoIdMP4(int photoId, int id_photo_mp4) {
final photo = visitPhotoBox.get(photoId);
if (photo != null) {
final updatedPhoto = photo.copyWith(id_photo_mp4: id_photo_mp4);
visitPhotoBox.put(updatedPhoto);
}
}
void putPhotoTypologie(int photoId, int typologieId) {
final photo = visitPhotoBox.get(photoId);
if (photo != null) {
final updatedPhoto = photo.copyWith(id_photo_typologie: typologieId);
visitPhotoBox.put(updatedPhoto);
}
}
void putPhotoTags(int photoId, List<String> tags) {
final photo = visitPhotoBox.get(photoId);
if (photo != null) {
final updatedPhoto = photo.copyWith(tags: tags.join(","));
visitPhotoBox.put(updatedPhoto);
}
}
void putPhotoVisibilities(int photoId, List<String> visibilities) {
final photo = visitPhotoBox.get(photoId);
if (photo != null) {
final updatedPhoto = photo.copyWith(
photo_principale: visibilities.contains('principal') ? 1 : 0,
photo_privee: visibilities.contains('private') ? 1 : 0);
visitPhotoBox.put(updatedPhoto);
}
}
void putPhotoCompetitor(int photoId, int competitorId) {
final photo = visitPhotoBox.get(photoId);
if (photo != null) {
final updatedPhoto = photo.copyWith(id_concurrence_lien: competitorId);
visitPhotoBox.put(updatedPhoto);
}
}
int getVisitPhotoCount() {
return visitPhotoBox.count();
}
/* remettre les principal à zero
final queryBuilder = box.query(VisitPhoto_.Visit_id.equals(idVisite) & VisitPhoto_.photo_principale.equals(1));
final updatedPhotos = queryBuilder.build().find();
updatedPhotos.forEach((photo) {
photo.photo_principale = 0;
});
box.putMany(updatedPhotos);
*/
/// PHOTO TYPOLOGY -----------------------------------------------------------
///
List<PhotoTypology> parsePhotoTypologies(List responseDataList) {
final parsed = responseDataList.cast<Map<String, dynamic>>();
return parsed
.map<PhotoTypology>((json) => PhotoTypology.fromJson(json))
.toList();
}
Future<void> addPhotoTypologies(List<dynamic> _listPhotoTypologies) =>
store.runInTransactionAsync(TxMode.write, _addPhotoTypologiesInTx,
parsePhotoTypologies(_listPhotoTypologies));
static void _addPhotoTypologiesInTx(Store store, _PhotoTypologies) {
store.box<PhotoTypology>().putMany(_PhotoTypologies);
}
Future<void> addPhotoTypology(
int id_photo_typologie, String libelle, int ordre) =>
store.runInTransactionAsync(
TxMode.write,
_addPhotoTypologyInTx,
PhotoTypology(
id_photo_typologie: id_photo_typologie,
libelle: libelle,
ordre: ordre));
static void _addPhotoTypologyInTx(Store store, _PhotoTypology) {
// Perform ObjectBox operations that take longer than a few milliseconds
// here. To keep it simple, this example just puts a single object.
store.box<PhotoTypology>().put(_PhotoTypology);
}
List<String> getPhotoTypologiesLabels() {
final query = PhotoTypologyBox.query().order(PhotoTypology_.ordre).build();
final photoTypologies = query.find();
return photoTypologies
.map((photoTypology) => photoTypology.libelle)
.toList();
}
List<PhotoTypology> getPhotoTypologiesList() {
final query = PhotoTypologyBox.query().order(PhotoTypology_.ordre).build();
final photoTypologies = query.find();
return photoTypologies.toList();
}
Stream<List<PhotoTypology>> getPhotoTypologies() {
// Query for all Typologies, sorted by their order.
// https://docs.objectbox.io/queries
final builder = PhotoTypologyBox.query().order(PhotoTypology_.ordre);
// Build and watch the query,
// set triggerImmediately to emit the query immediately on listen.
return builder
.watch(triggerImmediately: true)
// Map it to a list of notes to be used by a StreamBuilder.
.map((query) => query.find());
}
/// LOG ----------------------------------------------------------------------
///
Future<void> addLog(String type, String module, String libelle, int duree) =>
store.runInTransactionAsync(
TxMode.write,
_addLogInTx,
Log(
type,
module,
libelle,
duree,
));
static void _addLogInTx(Store store, _Log) {
// Perform ObjectBox operations that take longer than a few milliseconds
// here. To keep it simple, this example just puts a single object.
store.box<Log>().put(_Log);
}
Stream<List<Log>> getLogs() {
// Query for all logs, sorted by their date.
// https://docs.objectbox.io/queries
final builder = logBox.query().order(Log_.date, flags: Order.descending);
// Build and watch the query,
// set triggerImmediately to emit the query immediately on listen.
return builder
.watch(triggerImmediately: true)
// Map it to a list of notes to be used by a StreamBuilder.
.map((query) => query.find());
}
/// Removes a Log object from the ObjectBox database with the specified ID.
///
/// Parameters:
/// id: The ID of the Log object to remove.
///
/// Returns:
/// None.
void delLogById(int id) {
if (!logBox.remove(id)) {
LoggerUtil.logNStackError("delete log:${id} KO");
}
}
int getLogCount() {
return logBox.count();
}
}