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 userBox; /// A Box of etablishment late final Box etabBox; /// A Box of etablishment competitor late final Box etabCompetitorBox; /// A Box of visit late final Box visitBox; /// A Box for all visit tag by distributor / language late final Box visitTagBox; /// A Box of visit Photo late final Box visitPhotoBox; /// A Box of photo typology late final Box PhotoTypologyBox; /// A Box of log. late final Box logBox; ObjectBox._create(this.store) { userBox = Box(store); etabBox = Box(store); etabCompetitorBox = Box(store); visitBox = Box(store); visitTagBox = Box(store); PhotoTypologyBox = Box(store); visitPhotoBox = Box(store); logBox = Box(store); } /// Create an instance of ObjectBox to use throughout the app. static Future create() async { // Future 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. List parseEtabs(List responseDataList) { final parsed = responseDataList.cast>(); return parsed.map((json) => Etab.fromJson(json)).toList(); } Future addEtabs(List _listEtabs) => store.runInTransactionAsync( TxMode.write, _addEtabsInTx, parseEtabs(_listEtabs)); static void _addEtabsInTx(Store store, _Etabs) { store.box().putMany(_Etabs); } Future 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().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. List parseEtabCompetitor(List responseDataList) { final parsed = responseDataList.cast>(); return parsed .map((json) => EtabCompetitor.fromJson(json)) .toList(); } Future addEtabCompetitors(List _listPhotoCompetitors) => store.runInTransactionAsync(TxMode.write, _addEtabCompetitorsInTx, parseEtabCompetitor(_listPhotoCompetitors)); static void _addEtabCompetitorsInTx(Store store, _Competitors) { store.box().putMany(_Competitors); } Future 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().put(_Competitor); } List 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> 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 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 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 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 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. List parseVisit(List responseDataList) { final parsed = responseDataList.cast>(); return parsed.map((json) => Visit.fromJson(json)).toList(); } // TODO : Enregistre urlphotoprincipale sur le disque pour l'avoir en cache ? Future addVisits(List _listVisits) => store.runInTransactionAsync( TxMode.write, _addVisitsInTx, parseVisit(_listVisits)); static void _addVisitsInTx(Store store, _Visits) { store.box().putMany(_Visits); } Future 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().put(_Visite); } Future syncVisits(List _listVisits) async { final toSyncId_visite = _listVisits.map((v) => v['id_visite']).toList(); final existingVisitsQuery = visitBox.query(Visit_.id_visite.oneOf(toSyncId_visite)); final existingVisits = existingVisitsQuery.build().find(); final existingVisitIds = existingVisits.map((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 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. List parseVisitTags(List responseDataList) { final parsed = responseDataList.cast>(); return parsed.map((json) => VisitTag.fromJson(json)).toList(); } Future addVisitTags(List _listVisitTags) => store.runInTransactionAsync( TxMode.write, _addVisitTagsInTx, parseVisitTags(_listVisitTags)); static void _addVisitTagsInTx(Store store, _VisitTags) { store.box().putMany(_VisitTags); } /// save new tag for a distributor / langage Future 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().put(_VisitTag); } List getVisitTagsLabels(int distribId, String langage) { final query = visitTagBox .query(VisitTag_.id_distrib.equals(distribId) & VisitTag_.langage.equals(langage)) //.order(VisitTag_.libelle) .build(); PropertyQuery pq = query.property(VisitTag_.libelle); pq.distinct = true; pq.caseSensitive = false; return pq.find(); } int getVisitTagCount() { return visitTagBox.count(); } /// PHOTO -------------------------------------------------------------------- /// /// Future> addPhotos(List photos) async { final addedPhotos = await visitPhotoBox.putAndGetManyAsync(photos); return addedPhotos; } Future 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().put(_Photo); } List 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 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 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> 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 tags) { final photo = visitPhotoBox.get(photoId); if (photo != null) { final updatedPhoto = photo.copyWith(tags: tags.join(",")); visitPhotoBox.put(updatedPhoto); } } void putPhotoVisibilities(int photoId, List 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 parsePhotoTypologies(List responseDataList) { final parsed = responseDataList.cast>(); return parsed .map((json) => PhotoTypology.fromJson(json)) .toList(); } Future addPhotoTypologies(List _listPhotoTypologies) => store.runInTransactionAsync(TxMode.write, _addPhotoTypologiesInTx, parsePhotoTypologies(_listPhotoTypologies)); static void _addPhotoTypologiesInTx(Store store, _PhotoTypologies) { store.box().putMany(_PhotoTypologies); } Future 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().put(_PhotoTypology); } List getPhotoTypologiesLabels() { final query = PhotoTypologyBox.query().order(PhotoTypology_.ordre).build(); final photoTypologies = query.find(); return photoTypologies .map((photoTypology) => photoTypology.libelle) .toList(); } List getPhotoTypologiesList() { final query = PhotoTypologyBox.query().order(PhotoTypology_.ordre).build(); final photoTypologies = query.find(); return photoTypologies.toList(); } Stream> 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 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().put(_Log); } Stream> 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(); } }