add initial functionality for timeunit cascades

This commit is contained in:
Eero Antikainen
2024-10-30 14:15:02 +01:00
committed by Aaro Koivukangas
parent 398ed9b046
commit 43c1922fb4
4 changed files with 102 additions and 3 deletions
+4 -1
View File
@@ -46,7 +46,10 @@ router.put(
if (validationErrors.length > 0) {
return res.status(403).send(validationErrors)
}
const tu_name = await writeTimeUnit(editedTimeUnit, comment, references, req.user!.initials)
const { tu_name, errorObject } = await writeTimeUnit(editedTimeUnit, comment, references, req.user!.initials)
if (errorObject !== undefined) {
return res.status(403).send({ errorObject })
}
return res.status(200).send({ tu_name })
}
)
+18
View File
@@ -111,3 +111,21 @@ export const deleteLocality = async (lid: number, user: User) => {
throw e
}
}
export const writeLocalityCascade = async (
locality: EditDataType<LocalityDetailsType>,
comment: string | undefined,
references: Reference[] | undefined,
authorizer: string
) => {
const writeHandler = getLocalityWriteHandler('update')
try {
await writeHandler.start()
await writeHandler.updateObject('now_loc', locality, ['lid'])
writeHandler.idValue = locality.lid
await writeHandler.logUpdatesAndComplete(authorizer, comment ?? '', references ?? [])
} catch (e) {
await writeHandler.end()
throw e
}
}
+29 -2
View File
@@ -1,9 +1,17 @@
import { EditDataType, Reference, TimeUnitDetailsType, User } from '../../../../frontend/src/backendTypes'
import {
EditDataType,
Reference,
TimeUnitDetailsType,
LocalityDetailsType,
User,
} from '../../../../frontend/src/backendTypes'
import { NOW_DB_NAME } from '../../utils/config'
import { WriteHandler } from './writeOperations/writeHandler'
import { getFieldsOfTables } from '../../utils/db'
import { ActionType } from './writeOperations/types'
import { getTimeUnitDetails } from '../timeUnit'
import { checkTimeUnitCascade } from '../../utils/cascadeHandler'
import { writeLocalityCascade } from './locality'
const getTimeUnitWriteHandler = (type: ActionType) => {
return new WriteHandler({
@@ -32,6 +40,25 @@ export const writeTimeUnit = async (
if (timeUnit.tu_name) {
await writeHandler.updateObject('now_time_unit', timeUnit, ['tu_name'])
const { cascadeErrors, calculatorErrors, localitiesToUpdate } = await checkTimeUnitCascade(timeUnit)
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 { tu_name: timeUnit.tu_name, errorObject: ErrorObject }
} else if (localitiesToUpdate.length > 0) {
for (const locality of localitiesToUpdate) {
await writeLocalityCascade(locality as EditDataType<LocalityDetailsType>, comment, references, authorizer)
}
}
} else {
timeUnit.tu_name = createTimeUnitId(timeUnit.tu_display_name!)
await writeHandler.createObject('now_time_unit', timeUnit, ['tu_name'])
@@ -40,7 +67,7 @@ export const writeTimeUnit = async (
await writeHandler.logUpdatesAndComplete(authorizer, comment ?? '', references ?? [])
await writeHandler.commit()
return timeUnit.tu_name
return { tu_name: timeUnit.tu_name, errorObject: undefined }
} catch (e) {
await writeHandler.end()
throw e
+51
View File
@@ -0,0 +1,51 @@
import { EditDataType, TimeUnitDetailsType } from '../../../frontend/src/backendTypes'
import { nowDb } from './db'
import { calculateLocalityMaxAge, calculateLocalityMinAge } from './ageCalculator'
export const checkTimeUnitCascade = async (timeUnit: EditDataType<TimeUnitDetailsType>) => {
const localities = await nowDb.now_loc.findMany({
where: {
OR: [{ bfa_max: timeUnit.tu_name }, { bfa_min: timeUnit.tu_name }],
},
})
const cascadeErrors: string[] = []
const calculatorErrors: string[] = []
const localitiesToUpdate = []
for (const locality of localities) {
let maxAgeAfterUpdate = locality.max_age
let minAgeAfterUpdate = locality.min_age
if (locality.bfa_max === timeUnit.tu_name) {
try {
maxAgeAfterUpdate = calculateLocalityMaxAge(
timeUnit.up_bound?.age as number,
timeUnit.low_bound?.age as number,
locality.frac_max
)
} catch (e) {
calculatorErrors.push(locality.loc_name)
}
}
if (locality.bfa_min === timeUnit.tu_name) {
try {
minAgeAfterUpdate = calculateLocalityMinAge(
timeUnit.up_bound?.age as number,
timeUnit.low_bound?.age as number,
locality.frac_max
)
} catch (e) {
calculatorErrors.push(locality.loc_name)
}
}
if (minAgeAfterUpdate < maxAgeAfterUpdate) {
const updatedLocality = {
...locality,
min_age: minAgeAfterUpdate,
max_age: maxAgeAfterUpdate,
}
localitiesToUpdate.push(updatedLocality)
} else {
cascadeErrors.push(locality.loc_name)
}
}
return { cascadeErrors, calculatorErrors, localitiesToUpdate }
}