diff --git a/backend/src/services/write/timeBound.ts b/backend/src/services/write/timeBound.ts index b4da6d36..d67c9144 100644 --- a/backend/src/services/write/timeBound.ts +++ b/backend/src/services/write/timeBound.ts @@ -28,7 +28,18 @@ export const writeTimeBound = async ( try { await writeHandler.start() const result = await writeHandler.upsertObject('now_tu_bound', timeBound, ['bid']) - const { cascadeErrors, calculatorErrors, localitiesToUpdate } = await checkTimeBoundCascade(timeBound) + const { cascadeErrors, calculatorErrors, localitiesToUpdate, timeUnitsToUpdate } = await checkTimeBoundCascade(timeBound) + if (calculatorErrors.length > 0 || cascadeErrors.length > 0) { + const calculatorErrorsString = calculatorErrors.length > 0 ? `Check fractions of following localities: ${calculatorErrors.join(', ')}` : '' + const cascadeErrorsString = cascadeErrors.length > 0 ? `Following localities would become contradicting: ${cascadeErrors.join(', ')}` : '' + const errorObject = { + name: 'cascade', + calculatorErrors: calculatorErrorsString, + cascadeErrors: cascadeErrorsString, + } + await writeHandler.end() + return { result: writeHandler.idValue, errorObject } + } writeHandler.idValue = result ? (result.bid as number) : (timeBound.bid as number) await writeHandler.logUpdatesAndComplete(authorizer, comment ?? '', references ?? []) return { result: writeHandler.idValue, errorObject: undefined } diff --git a/backend/src/utils/cascadeHandler.ts b/backend/src/utils/cascadeHandler.ts index 328ded5b..d37ba121 100644 --- a/backend/src/utils/cascadeHandler.ts +++ b/backend/src/utils/cascadeHandler.ts @@ -61,12 +61,27 @@ type Unit = { low_bnd: number } +type EditedUnit = { + timeUnit: Unit + editedBounds: { upBoundAge: number, lowBoundAge: number } +} + +type Locality = { + loc_name: string + max_age: number + min_age: number + bfa_max: string + bfa_min: string + frac_max: string +} + export const checkTimeBoundCascade = async (timeBound: EditDataType) => { const cascadeErrors: string[] = [] const calculatorErrors: string[] = [] - const localitiesToCheck = [] + const localitiesToCheck: Locality[] = [] const timeUnitsToUpdate = [] + const timeUnits = await nowDb.now_time_unit.findMany({ select: { tu_name: true, @@ -77,6 +92,7 @@ export const checkTimeBoundCascade = async (timeBound: EditDataType editedBounds.upBoundAge) { - timeUnitsToUpdate.push(timeUnit) - } else { - cascadeErrors.push(timeUnit.tu_name) - } + + const editedBounds = calculateTimeUnitAges(timeUnit, bounds as Bounds[], timeBound.age as number, timeBound.bid as number); + + if (editedBounds) { + if (editedBounds.lowBoundAge > editedBounds.upBoundAge) { + timeUnitsToUpdate.push({ timeUnit, editedBounds }) } else { - calculatorErrors.push(timeUnit.tu_name) + cascadeErrors.push(timeUnit.tu_name) } } else { - console.log("Not enough bounds found for time unit. Bad") + calculatorErrors.push(timeUnit.tu_name) } } for (const timeUnit of timeUnitsToUpdate) { @@ -113,15 +127,16 @@ export const checkTimeBoundCascade = async (timeBound: EditDataType { +const handleLocalityAndTimeUnitLists = (localities: Locality[], timeUnits: EditedUnit[]) => { const cascadeErrorsLocalities: string[] = [] const calculatorErrorsLocalities: string[] = [] - const localitiesToUpdate: any[] = [] + const localitiesToUpdate: Locality[] = [] + const timeUnitNames = timeUnits.map(unit => unit.timeUnit.tu_name) + + for (const locality of localities) { + let maxAgeAfterUpdate = locality.max_age + let minAgeAfterUpdate = locality.min_age + + if (timeUnitNames.includes(locality.bfa_max)) { + const timeUnit = timeUnits.find(unit => unit.timeUnit.tu_name === locality.bfa_max) + try { + maxAgeAfterUpdate = calculateLocalityMaxAge(timeUnit?.editedBounds.upBoundAge as number, timeUnit?.editedBounds.lowBoundAge as number, locality.frac_max) + } catch (e) { + calculatorErrorsLocalities.push(locality.loc_name) + } + } + if (timeUnitNames.includes(locality.bfa_min)) { + const timeUnit = timeUnits.find(unit => unit.timeUnit.tu_name === locality.bfa_min) + try { + minAgeAfterUpdate = calculateLocalityMinAge(timeUnit?.editedBounds.upBoundAge as number, timeUnit?.editedBounds.lowBoundAge as number, locality.frac_max) + } catch (e) { + calculatorErrorsLocalities.push(locality.loc_name) + } + } + if (minAgeAfterUpdate < maxAgeAfterUpdate) { + const updatedLocality = { + ...locality, + min_age: minAgeAfterUpdate, + max_age: maxAgeAfterUpdate, + } + localitiesToUpdate.push(updatedLocality) + } else { + cascadeErrorsLocalities.push(locality.loc_name) + } + } return { cascadeErrorsLocalities, calculatorErrorsLocalities, localitiesToUpdate } } \ No newline at end of file