Files
eatvio_app/lib/features/diary/repositories/diary_repository.dart

254 lines
9.8 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:eatvio_app/features/diary/models/consultant_comment_model.dart';
import 'package:eatvio_app/features/diary/models/consultant_review_model.dart';
import 'package:eatvio_app/features/diary/models/create_day_model.dart';
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
import 'package:eatvio_app/features/diary/models/finish_diary_day_model.dart';
import 'package:eatvio_app/features/diary/models/nutrition_model.dart';
import 'package:eatvio_app/features/diary/models/product_moderation_model.dart';
import 'package:eatvio_app/features/diary/services/diary_service.dart';
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
class DiaryRepository {
final DiaryService diaryService;
final StreamController<String> _diaryForceFetchController = StreamController<String>.broadcast();
Stream<String> get forceFetchStream => _diaryForceFetchController.stream;
DiaryRepository({required this.diaryService});
PortionModel _portionWithGlossary(PortionModel portion, List<GlossaryModel> glossaries) {
final id = portion.productNutritionalValueId;
if (id == null) return portion;
final glossaryItem = glossaries.firstWhereOrNull((g) => g.id == id);
if (glossaryItem == null) return portion;
return portion.copyWith(
productCaloriesInfo: ProductCaloriesInfoModel(
id: glossaryItem.id,
productName: glossaryItem.name,
calories: glossaryItem.energyOn100Gr,
proteins: glossaryItem.proteinsOn100Gr,
fats: glossaryItem.fatsOn100Gr,
carbohydrates: glossaryItem.carbohydratesOn100Gr,
energyOnPortion: glossaryItem.energyOnPortion,
proteinsOnPortion: glossaryItem.proteinsOnPortion,
fatsOnPortion: glossaryItem.fatsOnPortion,
carbohydratesOnPortion: glossaryItem.carbohydratesOnPortion,
),
);
}
Future<DiaryDayModel> getDiaryByDate(String date) async {
final ids = <int>{};
final diaryDays = await getDiaryIndexByDate(date);
if (diaryDays.isEmpty) {
throw Exception('No diary entry found for $date');
}
final DiaryDayModel diaryDay = diaryDays.last;
for (var meal in diaryDay.meals) {
for (var portion in meal.portions) {
if (portion.productNutritionalValueId != null) {
ids.add(portion.productNutritionalValueId!);
}
}
}
if (ids.isEmpty) {
return diaryDay;
}
final glossary = await getGlossariesIndex(ids: ids.toList());
final glossaries = glossary.glossariesList;
final updatedMeals = diaryDay.meals.map((meal) {
final updatedPortions = meal.portions.map((p) => _portionWithGlossary(p, glossaries)).toList();
return meal.copyWith(portions: updatedPortions);
}).toList();
return diaryDay.copyWith(meals: updatedMeals);
}
Future<List<DiaryDayModel>> getDiaryIndexByDate(String date) async {
return diaryService.getDiaryIndexByDate(date: date);
}
Future<DiaryDayModel> getDiaryDay(int diaryId) async {
final diaryWrapper = await diaryService.getDiaryDay(diary: diaryId);
final DiaryDayModel diaryDay = diaryWrapper.diary;
final ids = <int>{};
for (var meal in diaryDay.meals) {
for (var portion in meal.portions) {
if (portion.productNutritionalValueId != null) {
ids.add(portion.productNutritionalValueId!);
}
}
}
if (ids.isEmpty) {
return diaryDay;
}
final glossary = await getGlossariesIndex(ids: ids.toList());
final glossaries = glossary.glossariesList;
final updatedMeals = diaryDay.meals.map((meal) {
final updatedPortions = meal.portions.map((p) => _portionWithGlossary(p, glossaries)).toList();
return meal.copyWith(portions: updatedPortions);
}).toList();
return diaryDay.copyWith(meals: updatedMeals);
}
Future<NutritionDataModel> getNutritionData(int index) async {
return diaryService.getNutrition(diary: index);
}
Future<void> addPortionToMeal({
required int diaryId,
required int mealId,
required String productName,
required String portion,
required int quantity,
int? productNutritionalValueId,
}) async {
return diaryService.addProductToMeal(
diary: diaryId,
typeNo: mealId,
productName: productName,
portion: portion,
quantity: quantity,
productNutritionalValueId: productNutritionalValueId,
);
}
Future<void> updateProductInMeal({
required int diaryId,
required int mealId,
required int portionId,
required String productName,
required String portion,
required int quantity,
int? productNutritionalValueId,
required PortionState portionState,
}) async {
final data = ProductInMeal(productName: productName, portion: portion, quantity: quantity).toJson();
if (productNutritionalValueId != null) data['product_nutritional_value_id'] = productNutritionalValueId;
data['state'] = portionState.name;
return diaryService.updateProductInMeal(diary: diaryId, typeNo: mealId, portionModel: portionId, productInMeal: data);
}
Future<void> markEaten({required int diaryId, required int mealId, required int portionId}) async {
return diaryService.markEaten(diary: diaryId, typeNo: mealId, portionModel: portionId);
}
Future<void> unmarkEaten({required int diaryId, required int mealId, required int portionId}) async {
return diaryService.unmarkEaten(diary: diaryId, typeNo: mealId, portionModel: portionId);
}
Future<void> restore({required int diaryId, required int mealId, required int portionId}) async {
return diaryService.restore(diary: diaryId, typeNo: mealId, portionModel: portionId);
}
Future<void> deleteProductFromMeal({required int diaryId, required int mealId, required int portionId}) async {
return diaryService.deleteProductFromMeal(diary: diaryId, typeNo: mealId, portionModel: portionId);
}
Future<void> uploadPhotos({required int diaryId, required int mealId, required List<File> files}) async {
for (var i = 0; i < files.length; i++) {
await diaryService.uploadPhotoOfMeal(diary: diaryId, typeNo: mealId, photo: files[i]);
}
}
Future<void> deletePhoto({required int diaryId, required int mealId, required DiaryPhotoModel photo}) async {
await diaryService.deletePhotoOfMeal(diaryId: diaryId, typeNo: mealId, userAttachment: photo.id);
}
Future<void> finishDiaryDay({required int diaryId, required String wakeUp, required String retire, String? comment}) async {
return diaryService.finishDiaryDay(
diary: diaryId,
finishDiaryDayModel: FinishDiaryDayModel(wakeUp: wakeUp, retire: retire, comment: comment),
);
}
Future<GlossaryModerationModel> sendProductToModeration({
required String name,
required double energy,
required double proteins,
required double fats,
required double carbohydrates,
}) async {
return diaryService.sendProductToModeration(
data: ProductModerationModel(name: name, energy: energy, proteins: proteins, fats: fats, carbohydrates: carbohydrates).toJson(),
);
}
Future<void> fillSatiety({required int diaryId, required int mealId, required int satiety}) async {
return diaryService.fillSatiety(diary: diaryId, typeNo: mealId, satiety: satiety);
}
Future<void> fillMood({required int diaryId, required int mealId, required int mood}) async {
return diaryService.fillMood(diary: diaryId, typeNo: mealId, mood: mood);
}
Future<void> fillTime({required int diaryId, required int mealId, required String time}) async {
return diaryService.fillTime(diary: diaryId, typeNo: mealId, time: time);
}
Future<void> fillWakeup({required int diaryId, required String time}) async {
return diaryService.fillWakeup(diary: diaryId, wakeUp: time);
}
Future<void> fillRetire({required int diaryId, required String time}) async {
return diaryService.fillRetire(diary: diaryId, retire: time);
}
Future<void> commentUserDay({required int diaryId, required ConsultantCommentModel commentModel}) async {
await diaryService.commentUserDay(id: diaryId, body: commentModel);
_diaryForceFetchController.add('force');
}
Future<ConsultantReviewModel> getDiaryComments({required int planId, required int diaryId}) async {
return diaryService.getDiaryComments(planId: planId, diaryId: diaryId);
}
Future<void> viewCommentOfDiaryDayByConsultant({required int diaryId}) async {
await diaryService.viewCommentOfDiaryDayByConsultant(diaryId: diaryId);
}
Future<GlossaryPaginationModel> getGlossariesIndex({required List<int> ids}) async {
final filters = <String, dynamic>{};
if (ids.isNotEmpty) {
for (var i = 0; i < ids.length; i++) {
filters['filters[id][\$in][$i]'] = ids[i];
}
}
return diaryService.getGlossariesIndex(filters: filters);
}
Future<DiaryDayModel> getDiaryDayV2({required String day}) async {
final diaryDay = await diaryService.getDiaryDayV2(day: day);
return setCPFCToDiary(diaryDay);
}
Future<void> createDiaryDay({required String day}) async {
await diaryService.createDay(body: CreateDayModel(day: day));
await getDiaryByDate(day);
}
Future<DiaryDayModel> setCPFCToDiary(DiaryDayModel diaryDay) async {
final ids = <int>{};
for (var meal in diaryDay.meals) {
for (var portion in meal.portions) {
if (portion.productNutritionalValueId != null) {
ids.add(portion.productNutritionalValueId!);
}
}
}
if (ids.isEmpty) {
return diaryDay;
}
final glossary = await getGlossariesIndex(ids: ids.toList());
final glossaries = glossary.glossariesList;
final updatedMeals = diaryDay.meals.map((meal) {
final updatedPortions = meal.portions.map((p) => _portionWithGlossary(p, glossaries)).toList();
return meal.copyWith(portions: updatedPortions);
}).toList();
return diaryDay.copyWith(meals: updatedMeals);
}
}