601 lines
19 KiB
Dart
601 lines
19 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_photo.dart';
|
|
import 'package:mobdr/db/box_photo_typology.dart';
|
|
|
|
import 'model.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 notes.
|
|
late final Box<Note> noteBox;
|
|
|
|
/// 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<Visite> visitBox;
|
|
|
|
/// A Box for all visit tag by distributor / language
|
|
late final Box<VisiteTag> 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) {
|
|
noteBox = Box<Note>(store);
|
|
userBox = Box<User>(store);
|
|
etabBox = Box<Etab>(store);
|
|
etabCompetitorBox = Box<EtabCompetitor>(store);
|
|
visitBox = Box<Visite>(store);
|
|
visitTagBox = Box<VisiteTag>(store);
|
|
PhotoTypologyBox = Box<PhotoTypology>(store);
|
|
visitPhotoBox = Box<VisitPhoto>(store);
|
|
logBox = Box<Log>(store);
|
|
|
|
// Add some demo data if the box is empty.
|
|
if (noteBox.isEmpty()) {
|
|
_putDemoData();
|
|
}
|
|
|
|
userBox.removeAll();
|
|
|
|
//etabBox.removeAll();
|
|
//etabCompetitorBox.removeAll();
|
|
//visitBox.removeAll();
|
|
//visitTagBox.removeAll();
|
|
//visitPhotoBox.removeAll();
|
|
//PhotoTypologyBox.removeAll();
|
|
|
|
// Add some demo data if the box is empty.
|
|
if (userBox.isEmpty()) {
|
|
_putUserAdminData();
|
|
}
|
|
}
|
|
|
|
/// 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);
|
|
}
|
|
|
|
void _putDemoData() {
|
|
final demoNotes = [
|
|
Note('Quickly add a note by writing text and pressing Enter'),
|
|
Note('Delete notes by tapping on one'),
|
|
Note('Write a demo app for ObjectBox')
|
|
];
|
|
store.runInTransactionAsync(TxMode.write, _putNotesInTx, demoNotes);
|
|
}
|
|
|
|
void _putUserAdminData() {
|
|
//addUSer(0, 'root', 'admim', 'admin', '');
|
|
}
|
|
|
|
Stream<List<Note>> getNotes() {
|
|
// Query for all notes, sorted by their date.
|
|
// https://docs.objectbox.io/queries
|
|
final builder = noteBox.query().order(Note_.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());
|
|
}
|
|
|
|
static void _putNotesInTx(Store store, List<Note> notes) =>
|
|
store.box<Note>().putMany(notes);
|
|
|
|
/// Add a note within a transaction.
|
|
///
|
|
/// To avoid frame drops, run ObjectBox operations that take longer than a
|
|
/// few milliseconds, e.g. putting many objects, in an isolate with its
|
|
/// own Store instance.
|
|
/// For this example only a single object is put which would also be fine if
|
|
/// done here directly.
|
|
Future<void> addNote(String text) =>
|
|
store.runInTransactionAsync(TxMode.write, _addNoteInTx, text);
|
|
|
|
/// Note: due to [dart-lang/sdk#36983](https://github.com/dart-lang/sdk/issues/36983)
|
|
/// not using a closure as it may capture more objects than expected.
|
|
/// These might not be send-able to an isolate. See Store.runAsync for details.
|
|
static void _addNoteInTx(Store store, String text) {
|
|
// Perform ObjectBox operations that take longer than a few milliseconds
|
|
// here. To keep it simple, this example just puts a single object.
|
|
store.box<Note>().put(Note(text));
|
|
}
|
|
|
|
/// USER ---------------------------------------------------------------------
|
|
///
|
|
|
|
Future<void> addUSer(int _id_utilisateur, String _login, String _nom,
|
|
String _prenom, String _photo) =>
|
|
store.runInTransactionAsync(
|
|
TxMode.write,
|
|
_addUserInTx,
|
|
User(
|
|
id_utilisateur: _id_utilisateur,
|
|
login: _login,
|
|
nom: _nom,
|
|
prenom: _prenom,
|
|
photo: _photo));
|
|
|
|
static void _addUserInTx(Store store, _User) {
|
|
store.box<User>().put(_User);
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
/// PHOTO COMPETITOR ---------------------------------------------------------------
|
|
///
|
|
|
|
// A function that converts a response body list into a List<Competitor>.
|
|
List<EtabCompetitor> parsePhotoCompetitor(List responseDataList) {
|
|
final parsed = responseDataList.cast<Map<String, dynamic>>();
|
|
return parsed
|
|
.map<EtabCompetitor>((json) => EtabCompetitor.fromJson(json))
|
|
.toList();
|
|
}
|
|
|
|
Future<void> addPhotoCompetitors(List<dynamic> _listPhotoCompetitors) =>
|
|
store.runInTransactionAsync(TxMode.write, _addPhotoCompetitorsInTx,
|
|
parsePhotoCompetitor(_listPhotoCompetitors));
|
|
|
|
static void _addPhotoCompetitorsInTx(Store store, _Competitors) {
|
|
store.box<EtabCompetitor>().putMany(_Competitors);
|
|
}
|
|
|
|
Future<void> addPhotoCompetitor(
|
|
int _id_concurrence_lien, int _id_etab, _nom) =>
|
|
store.runInTransactionAsync(
|
|
TxMode.write,
|
|
_addPhotoCompetitorInTx,
|
|
EtabCompetitor(
|
|
id_concurrence_lien: _id_concurrence_lien,
|
|
id_etab: _id_etab,
|
|
nom: _nom,
|
|
));
|
|
|
|
static void _addPhotoCompetitorInTx(Store store, _Competitor) {
|
|
store.box<EtabCompetitor>().put(_Competitor);
|
|
}
|
|
|
|
List<EtabCompetitor> getPhotoCompetitorList() {
|
|
final query = etabCompetitorBox
|
|
.query(EtabCompetitor_.id_etab.equals(1417))
|
|
.order(EtabCompetitor_.nom)
|
|
.build();
|
|
final photoCompetitors = query.find();
|
|
|
|
return photoCompetitors.toList();
|
|
}
|
|
|
|
int getPhotoCompetitorsCount() {
|
|
return etabCompetitorBox.count();
|
|
}
|
|
|
|
/// VISITE ------------------------------------------------------------------
|
|
///
|
|
|
|
Stream<List<Visite>> getVisitesStream() {
|
|
// Query for all visites, sorted by their date.
|
|
// https://docs.objectbox.io/queries
|
|
final builder =
|
|
visitBox.query().order(Visite_.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<Visite> getAllVisites() {
|
|
// Query for all visites, sorted by their date.
|
|
final builder = visitBox
|
|
.query()
|
|
.order(Visite_.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<Visite> parseVisites(List responseDataList) {
|
|
final parsed = responseDataList.cast<Map<String, dynamic>>();
|
|
return parsed.map<Visite>((json) => Visite.fromJson(json)).toList();
|
|
}
|
|
|
|
// TODO : Enregistre urlphotoprincipale sur le disque pour l'avoir en cache ?
|
|
Future<void> addVisites(List<dynamic> _listVisites) =>
|
|
store.runInTransactionAsync(
|
|
TxMode.write, _addVisitesInTx, parseVisites(_listVisites));
|
|
|
|
static void _addVisitesInTx(Store store, _Visites) {
|
|
store.box<Visite>().putMany(_Visites);
|
|
}
|
|
|
|
Future<void> addVisite(
|
|
int _id_visite,
|
|
DateTime _date_visite,
|
|
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,
|
|
_addVisiteInTx,
|
|
Visite(
|
|
id_visite: _id_visite,
|
|
date_visite: _date_visite,
|
|
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 _addVisiteInTx(Store store, _Visite) {
|
|
store.box<Visite>().put(_Visite);
|
|
}
|
|
|
|
int getVisiteCount() {
|
|
return visitBox.count();
|
|
}
|
|
|
|
//TODO changer en PHOTO TAG / mettre dans l'ordre CRUD
|
|
/// PHOTO TAG ---------------------------------------------------------------
|
|
///
|
|
|
|
// converts a response body list into a List<VisiteTag>.
|
|
List<VisiteTag> parseVisiteTags(List responseDataList) {
|
|
final parsed = responseDataList.cast<Map<String, dynamic>>();
|
|
return parsed.map<VisiteTag>((json) => VisiteTag.fromJson(json)).toList();
|
|
}
|
|
|
|
Future<void> addVisiteTags(List<dynamic> _listVisiteTags) =>
|
|
store.runInTransactionAsync(
|
|
TxMode.write, _addVisiteTagsInTx, parseVisiteTags(_listVisiteTags));
|
|
|
|
static void _addVisiteTagsInTx(Store store, _VisiteTags) {
|
|
store.box<VisiteTag>().putMany(_VisiteTags);
|
|
}
|
|
|
|
/// save new tag for a distributor / langage
|
|
Future<void> addVisiteTag(
|
|
int _id_visite_tag,
|
|
int _id_distrib,
|
|
String _libelle,
|
|
String _langage,
|
|
) =>
|
|
store.runInTransactionAsync(
|
|
TxMode.write,
|
|
_addVisiteTagInTx,
|
|
VisiteTag(
|
|
id_visite_tag: _id_visite_tag,
|
|
id_distrib: _id_distrib,
|
|
libelle: _libelle,
|
|
langage: _langage,
|
|
));
|
|
|
|
static void _addVisiteTagInTx(Store store, _VisiteTag) {
|
|
store.box<VisiteTag>().put(_VisiteTag);
|
|
}
|
|
|
|
List<String> getVisiteTagsLabels(int distribId, String langage) {
|
|
final query = visitTagBox
|
|
.query(VisiteTag_.id_distrib.equals(distribId) &
|
|
VisiteTag_.langage.equals(langage))
|
|
//.order(VisiteTag_.libelle)
|
|
.build();
|
|
PropertyQuery<String> pq = query.property(VisiteTag_.libelle);
|
|
pq.distinct = true;
|
|
pq.caseSensitive = false;
|
|
return pq.find();
|
|
}
|
|
|
|
int getVisiteTagCount() {
|
|
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 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_photo) {
|
|
final photo = visitPhotoBox.get(id_photo);
|
|
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());
|
|
}
|
|
|
|
void delPhoto(String _name) {
|
|
final query =
|
|
visitPhotoBox.query(VisitPhoto_.image_name.equals(_name)).build();
|
|
final results = query.find();
|
|
if (results.isNotEmpty) {
|
|
final photoToDelete = results.first;
|
|
visitPhotoBox.removeAsync(photoToDelete.id);
|
|
}
|
|
}
|
|
|
|
int getVisitPhotoCount(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();
|
|
}
|
|
|
|
Future<void> putPhotoTypologie(int photoId, int typologieId) async {
|
|
final photo = visitPhotoBox.get(photoId);
|
|
|
|
if (photo != null) {
|
|
final updatedPhoto = photo.copyWith(id_photo_typologie: typologieId);
|
|
await visitPhotoBox.putAsync(updatedPhoto);
|
|
}
|
|
}
|
|
|
|
Future<void> putPhotoTags(int photoId, List<String> tags) async {
|
|
final photo = visitPhotoBox.get(photoId);
|
|
|
|
if (photo != null) {
|
|
final updatedPhoto = photo.copyWith(tags: tags.join(","));
|
|
await visitPhotoBox.putAsync(updatedPhoto);
|
|
}
|
|
}
|
|
|
|
Future<void> putPhotoVisibilities(
|
|
int photoId, List<String> visibilities) async {
|
|
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);
|
|
await visitPhotoBox.putAsync(updatedPhoto);
|
|
}
|
|
}
|
|
|
|
/* remettre les principal à zero
|
|
final queryBuilder = box.query(VisitPhoto_.visite_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());
|
|
}
|
|
}
|