Skip to content

Commit

Permalink
fix: drink really not found (#620)
Browse files Browse the repository at this point in the history
Co-authored-by: YoanRos <yoan.roszak@etu.imt-nord-europe.fr>
  • Loading branch information
arnaudambro and YoanRos authored Sep 9, 2024
1 parent d486128 commit 7ed8eb0
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 50 deletions.
17 changes: 17 additions & 0 deletions api/src/controllers/consommation.js
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,21 @@ router.get(
})
);

router.post(
"/find-missing-own-drink",
catchErrors(async (req, res) => {
const { drinkKey, matomoId } = req.body;
if (!matomoId) return res.status(400).json({ ok: false, error: "no matomo id" });

// find user with matomoId
let user = await prisma.user.findUnique({ where: { matomo_id: matomoId } });

const conso = await prisma.consommation.findFirst({
where: { userId: user.id, drinkKey },
});

return res.status(200).send({ ok: true, data: conso });
})
);

module.exports = router;
47 changes: 38 additions & 9 deletions expo/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import "react-native-get-random-values";
import React, { useEffect, useState } from "react";
import * as Sentry from "@sentry/react-native";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { RecoilRoot } from "recoil";
import { RecoilRoot, useSetRecoilState } from "recoil";
import dayjs from "dayjs";
import * as SplashScreen from "expo-splash-screen";
import * as Application from "expo-application";
Expand All @@ -26,16 +26,18 @@ import {
migrateMissingDrinkKey,
sendPreviousDrinksToDB,
} from "./src/migrations";
import { reconciliateDrinksToDB, reconciliateGoalToDB } from "./src/reconciliations";
import { fixMissingDrinkKey, reconciliateDrinksToDB, reconciliateGoalToDB } from "./src/reconciliations";
import { drinksState, ownDrinksCatalogState } from "./src/recoil/consos";
import { drinksByWeekState, goalsState } from "./src/recoil/gains";
import { getInitValueFromStorage } from "./src/recoil/utils";

dayjs.locale("fr");
dayjs.extend(isSameOrAfter);
dayjs.extend(weekday);

SplashScreen.preventAutoHideAsync();

const release =
getBundleId() + "@" + Application.nativeApplicationVersion + "+" + Application.nativeBuildVersion; // ex : com.addicto.v1@1.18.0+198
const release = getBundleId() + "@" + Application.nativeApplicationVersion + "+" + Application.nativeBuildVersion; // ex : com.addicto.v1@1.18.0+198

Sentry.init({
dsn: __DEV__ ? "" : "https://0ef6896e639948fd9ba54b861186360d@sentry.fabrique.social.gouv.fr/80",
Expand All @@ -46,15 +48,14 @@ Sentry.init({
const App = () => {
// sync everytime we open the app
const [reconciliatedDrinksToDB, setReconciliatedDrinksToDB] = useState(false);
const [fixedMissingDrinkKey, setFixedMissingDrinkKey] = useState(false);
const [reconciliatedGoalsToDB, setReconciliatedGoalsToDB] = useState(false);

// migrate only once if not yet done
// TODO: clean migrations when it's time
const [_hasSentPreviousDrinksToDB, setHasSentPreviousDrinksToDB] =
useState(hasSentPreviousDrinksToDB);
const [_hasSentPreviousDrinksToDB, setHasSentPreviousDrinksToDB] = useState(hasSentPreviousDrinksToDB);
const [_hasCleanConsoAndCatalog, setHasCleanConsoAndCatalog] = useState(hasCleanConsoAndCatalog);
const [_hasMigrateMissingDrinkKey, sethasMigrateMissingDrinkKey] =
useState(hasMigrateMissingDrinkKey);
const [_hasMigrateMissingDrinkKey, sethasMigrateMissingDrinkKey] = useState(hasMigrateMissingDrinkKey);
const [_hasMigrateFromDailyGoalToWeekly, sethasMigrateFromDailyGoalToWeekly] = useState(
hasMigrateFromDailyGoalToWeekly
);
Expand All @@ -65,6 +66,10 @@ const App = () => {
await reconciliateDrinksToDB();
setReconciliatedDrinksToDB(true);
}
if (!fixedMissingDrinkKey) {
await fixMissingDrinkKey();
setFixedMissingDrinkKey(true);
}
if (!reconciliatedGoalsToDB) {
await reconciliateGoalToDB();
setReconciliatedGoalsToDB(true);
Expand Down Expand Up @@ -92,6 +97,7 @@ const App = () => {

if (
!reconciliatedDrinksToDB ||
!fixedMissingDrinkKey ||
!reconciliatedGoalsToDB ||
!_hasSentPreviousDrinksToDB ||
!_hasCleanConsoAndCatalog ||
Expand All @@ -101,15 +107,38 @@ const App = () => {
return null;
}

return <RecoiledApp />;
};

function RecoiledApp() {
return (
<RecoilRoot>
<ResetRecoilStatesAfterMigrationsAndReconciliations />
<ToastProvider>
<SafeAreaProvider>
<Router />
</SafeAreaProvider>
</ToastProvider>
</RecoilRoot>
);
};
}

// Why this function ?
// because we have a FUCKING HARD TIME to manage how and when recoil is initiated
// the default value of recoil's atoms is called AT FIRST, before any migration or reconciliation
// so we need to re-init the atoms we want to be initiated once the migrations/reconciliations are done
function ResetRecoilStatesAfterMigrationsAndReconciliations() {
const resetOwnDrinks = useSetRecoilState(ownDrinksCatalogState);
const resetDrinks = useSetRecoilState(drinksState);
const resetDrinksByWeek = useSetRecoilState(drinksByWeekState);
const resetGoals = useSetRecoilState(goalsState);
useEffect(() => {
resetOwnDrinks(getInitValueFromStorage("@OwnDrinks", []));
resetDrinks(getInitValueFromStorage("@Drinks", []));
resetDrinksByWeek(getInitValueFromStorage("@StoredDetaileddrinksByWeekState", []));
resetGoals(getInitValueFromStorage("goalsState", []));
}, []);
return null;
}

export default Sentry.wrap(App);
1 change: 1 addition & 0 deletions expo/src/Router.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const TabsNavigator = ({ navigation }) => {

const showBootSplash = useRecoilValue(showBootSplashState);
const [isInCraving, setIsInCraving] = useRecoilState(isInCravingKeyState);

return (
<>
<Tabs.Navigator
Expand Down
2 changes: 2 additions & 0 deletions expo/src/components/DrinkPersonalisation.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const DrinkPersonalisation = ({ updateDrinkKey, hide, quantitySelected, setQuant
const [isUpdateWanted, setIsUpdateWanted] = useState(true);
const volumeNumber = quantitySelected?.volume ?? drink?.volume.split(" ")[0];
const saveDrink = async () => {
console.log("SAVE DRINK");
const formatedPrice = drinkPrice.replace(",", ".");
const formatedAlcoolPercentage = drinkAlcoolPercentage.replace(",", ".");
const formatedVolume = volumeNumber.replace(",", ".");
Expand Down Expand Up @@ -115,6 +116,7 @@ const DrinkPersonalisation = ({ updateDrinkKey, hide, quantitySelected, setQuant
if (!hasChangedDrinkKey) return oldState;
return oldState.filter((oldStateDrink) => oldStateDrink.drinkKey !== oldDrink.drinkKey);
});

const matomoId = storage.getString("@UserIdv2");

API.post({
Expand Down
15 changes: 5 additions & 10 deletions expo/src/migrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ function cleanCatalog(oldDrinkCatalog) {
const alcoolPercentage = Number(oldDrink.categoryKey.split("-")[2])
? Number(oldDrink.categoryKey.split("-")[2])
: oldDrink.alcoolPercentage
? String(oldDrink.alcoolPercentage).replace(",", ".")
: 5;
? String(oldDrink.alcoolPercentage).replace(",", ".")
: 5;

// 4. create kcal and doses if they don't exist
const kcal = Math.round(((Number(alcoolPercentage) * 0.8 * volume) / 10) * 7);
Expand Down Expand Up @@ -172,8 +172,7 @@ function cleanCatalog(oldDrinkCatalog) {
: "ownDrink";

// 9. we fix the bug of the new cocktails
const categoryKeyEvolution2 =
drinkKeyEvolution1 === "ownCocktail" ? "ownCocktail" : categoryKeyEvolution1;
const categoryKeyEvolution2 = drinkKeyEvolution1 === "ownCocktail" ? "ownCocktail" : categoryKeyEvolution1;

newOwnDrinksCatalog.push({
drinkKey: drinkKeyEvolution2,
Expand All @@ -193,9 +192,7 @@ function cleanCatalog(oldDrinkCatalog) {
return newOwnDrinksCatalog;
}

export const hasMigrateFromDailyGoalToWeekly = storage.getBoolean(
"hasMigrateFromDailyGoalToWeekly"
);
export const hasMigrateFromDailyGoalToWeekly = storage.getBoolean("hasMigrateFromDailyGoalToWeekly");
export async function migrateFromDailyGoalToWeekly() {
try {
const drinksByDrinkingDayString = storage.getString("@StoredDetailedDrinksByDrinkingDay");
Expand All @@ -216,9 +213,7 @@ export async function migrateFromDailyGoalToWeekly() {
capture(e, {
extra: {
migration: "hasMigrateFromDailyGoalToWeekly",
"@StoredDetailedDrinksByDrinkingDay": storage.getString(
"@StoredDetailedDrinksByDrinkingDay"
),
"@StoredDetailedDrinksByDrinkingDay": storage.getString("@StoredDetailedDrinksByDrinkingDay"),
"@DaysWithGoalNoDrink": storage.getString("@DaysWithGoalNoDrink"),
},
user: {
Expand Down
5 changes: 1 addition & 4 deletions expo/src/recoil/consos.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ export const drinksState = atom({
onSet((newValue) => {
storage.set("@Drinks", JSON.stringify(newValue));
Sentry.setExtra("drinks", newValue.slice(0, 50));
Sentry.setExtra(
"all-drinks",
newValue.map(({ drinkKey, id }) => `${drinkKey}_${id}`).join("__")
);
Sentry.setExtra("all-drinks", newValue.map(({ drinkKey, id }) => `${drinkKey}_${id}`).join("__"));
}),
],
});
Expand Down
54 changes: 46 additions & 8 deletions expo/src/reconciliations.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getMaxDrinksPerWeek, getTotalDrinksByDrinkingDay } from "./helpers/gainsHelpers";
import { alcoolQuantityCatalog } from "./scenes/AddDrink/alcoolQuantityCatalog";
import { drinksCatalog } from "./scenes/ConsoFollowUp/drinksCatalog";
import API from "./services/api";
import { capture } from "./services/sentry";
Expand Down Expand Up @@ -26,10 +27,7 @@ export async function reconciliateDrinksToDB() {
},
}).then((response) => {
if (response?.ok) {
storage.set(
"@Drinks",
JSON.stringify(drinks.map((drink) => ({ ...drink, isSyncedWithDB: true })))
);
storage.set("@Drinks", JSON.stringify(drinks.map((drink) => ({ ...drink, isSyncedWithDB: true }))));
}
});
} catch (e) {
Expand Down Expand Up @@ -58,10 +56,7 @@ export async function reconciliateGoalToDB() {
const daysWithGoalNoDrink = JSON.parse(storage.getString("@DaysWithGoalNoDrink") || "[]");
const drinksByWeek = JSON.parse(storage.getString("@StoredDetaileddrinksByWeekState") || "[]");
const maxDrinksPerWeek = getMaxDrinksPerWeek(drinksByWeek);
const totalDrinksByDrinkingDay = getTotalDrinksByDrinkingDay(
maxDrinksPerWeek,
daysWithGoalNoDrink
);
const totalDrinksByDrinkingDay = getTotalDrinksByDrinkingDay(maxDrinksPerWeek, daysWithGoalNoDrink);

await API.post({
path: "/goal/sync",
Expand Down Expand Up @@ -90,3 +85,46 @@ export async function reconciliateGoalToDB() {
});
}
}

export async function fixMissingDrinkKey() {
const drinks = JSON.parse(storage.getString("@Drinks"));
const ownDrinksCatalog = JSON.parse(storage.getString("@OwnDrinks") || "[]");
const objectCatalog = {};
for (const ownDrink of ownDrinksCatalog) {
objectCatalog[ownDrink.drinkKey] = ownDrink;
}
for (const catalogDrink of drinksCatalog) {
objectCatalog[catalogDrink.drinkKey] = catalogDrink;
}
for (const drink of drinks) {
if (!objectCatalog[drink.drinkKey]) {
const response = await API.post({
path: "/consommation/find-missing-own-drink",
body: {
drinkKey: drink.drinkKey,
matomoId: storage.getString("@UserIdv2"),
},
});
if (response.ok && response.data) {
const missingDrink = {
categoryKey: "ownDrink",
drinkKey: drink.drinkKey,
displayFeed: drink.drinkKey,
displayDrinkModal: drink.drinkKey,
volume: response.data.volume,
price: Number(response.data.price),
doses: response.data.doses,
icon: alcoolQuantityCatalog.find((catalog) => catalog.volume === response.data.volume)?.icon,
// const doses = Math.round((formatedAlcoolPercentage * 0.8 * formatedVolume) / 10) / 10;
alcoolPercentage: (response.data.doses * 10 * 10) / (response.data.volume * 0.8),
kcal: response.data.kcal,
custom: true,
isDeleted: false,
};
ownDrinksCatalog.push(missingDrink);
objectCatalog[drink.drinkKey] = missingDrink;
storage.set("@OwnDrinks", JSON.stringify(ownDrinksCatalog));
}
}
}
}
16 changes: 3 additions & 13 deletions expo/src/scenes/ConsoFollowUp/ConsoFeedDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ const ConsoFeedDisplay = ({
({drink.volume})
</Volume>
)}
{(isFirst(position) || isAlone(position)) && (
<Hour>{new Date(timestamp).getLocaleTime("fr")}</Hour>
)}
{(isFirst(position) || isAlone(position)) && <Hour>{new Date(timestamp).getLocaleTime("fr")}</Hour>}
</>
) : (
<>
Expand All @@ -59,9 +57,7 @@ const ConsoFeedDisplay = ({
{quantity} {"Boisson inconnue"}{" "}
</Drink>

{(isFirst(position) || isAlone(position)) && (
<Hour>{new Date(timestamp).getLocaleTime("fr")}</Hour>
)}
{(isFirst(position) || isAlone(position)) && <Hour>{new Date(timestamp).getLocaleTime("fr")}</Hour>}
</>
)}
</Content>
Expand All @@ -70,13 +66,7 @@ const ConsoFeedDisplay = ({
{showButtons && (
<UpdateContainer>
<UpdateButton small content="Modifier" onPress={updateDrinkRequest} />
<DeleteButton
small
content="Supprimer"
onPress={deleteDrinkRequest}
color="#4030a5"
shadowColor="#171586"
/>
<DeleteButton small content="Supprimer" onPress={deleteDrinkRequest} color="#4030a5" shadowColor="#171586" />
</UpdateContainer>
)}
</>
Expand Down
12 changes: 6 additions & 6 deletions expo/src/scenes/ConsoFollowUp/drinksCatalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const mapDrinkToDose = ({ drinkKey, quantity }, catalogObject) => {
if (drinkKey === NO_CONSO) return 0;
const drink = catalogObject[drinkKey];
if (!drink) {
capture(new Error("drink really not found"), {
capture(new Error("drink really really not found"), {
extra: { drinkKey, catalogObject, function: "mapDrinkToDose" },
tags: { drinkKey },
});
Expand All @@ -83,7 +83,7 @@ export const mapDrinkToKcals = ({ drinkKey, quantity }, catalogObject) => {
if (drinkKey === NO_CONSO) return 0;
const drink = catalogObject[drinkKey];
if (!drink) {
capture(new Error("drink really not found"), {
capture(new Error("drink really really not found"), {
extra: { drinkKey, catalogObject, function: "mapDrinkToKcals" },
tags: { drinkKey },
});
Expand All @@ -97,7 +97,7 @@ export const mapDrinkToPrice = ({ drinkKey, quantity }, catalogObject) => {
if (drinkKey === NO_CONSO) return 0;
const drink = catalogObject[drinkKey];
if (!drink) {
capture(new Error("drink really not found"), {
capture(new Error("drink really really not found"), {
extra: { drinkKey, catalogObject, function: "mapDrinkToPrice" },
tags: { drinkKey },
});
Expand All @@ -111,7 +111,7 @@ export const getDisplayName = (drinkKey, quantity, catalogObject) => {
try {
const drink = catalogObject[drinkKey];
if (!drink) {
capture(new Error("drink really not found"), {
capture(new Error("drink really really not found"), {
extra: { drinkKey, catalogObject, function: "getDisplayName" },
tags: { drinkKey },
});
Expand All @@ -131,7 +131,7 @@ export const getDisplayDrinksModalName = (drinkKey, catalogObject, quantity = 1)
try {
const drink = catalogObject[drinkKey];
if (!drink) {
capture(new Error("drink really not found"), {
capture(new Error("drink really really not found"), {
extra: { drinkKey, catalogObject, function: "getDisplayDrinksModalName" },
tags: { drinkKey },
});
Expand All @@ -151,7 +151,7 @@ export const getDisplayDrinksModalName = (drinkKey, catalogObject, quantity = 1)
export const getIcon = (iconName) => {
const icon = mapIconNameToIcon[iconName];
if (!icon) {
capture(new Error("icon not found"), { extra: { iconName, function: "getIcon" } });
capture(new Error("icon really really not found"), { extra: { iconName, function: "getIcon" } });
return HalfBeer;
}
return icon;
Expand Down

0 comments on commit 7ed8eb0

Please sign in to comment.