Skip to content

Commit

Permalink
SW-6204 Disallow replacement of 25m plots (#2552)
Browse files Browse the repository at this point in the history
When we switch to the 30m plot size, there may be existing observations in
progress. They are able to finish as normal, but since we no longer support
creating new 4-plot clusters, we can't support the "request monitoring plot
replacement" feature for those observations since plot replacement can
trigger creation of new permanent clusters.

Add a check to reject attempts to replace plots with sizes different from
the current size we use for new plots. In practice, this means replacing 25m
plots will fail but replacing 30m plots will succeed.
  • Loading branch information
sgrimm authored Nov 1, 2024
1 parent e9e4831 commit 58e3143
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.terraformation.backend.db.tracking.ObservationId
import com.terraformation.backend.db.tracking.ObservationPlotPosition
import com.terraformation.backend.db.tracking.ObservationState
import com.terraformation.backend.db.tracking.PlantingSiteId
import com.terraformation.backend.db.tracking.tables.daos.MonitoringPlotsDao
import com.terraformation.backend.db.tracking.tables.daos.ObservationPhotosDao
import com.terraformation.backend.db.tracking.tables.pojos.ObservationPhotosRow
import com.terraformation.backend.db.tracking.tables.references.OBSERVATION_PHOTOS
Expand All @@ -28,13 +29,15 @@ import com.terraformation.backend.tracking.db.PlantingSiteStore
import com.terraformation.backend.tracking.db.PlotAlreadyCompletedException
import com.terraformation.backend.tracking.db.PlotNotFoundException
import com.terraformation.backend.tracking.db.PlotNotInObservationException
import com.terraformation.backend.tracking.db.PlotSizeNotReplaceableException
import com.terraformation.backend.tracking.db.ScheduleObservationWithoutPlantsException
import com.terraformation.backend.tracking.event.ObservationPlotReplacedEvent
import com.terraformation.backend.tracking.event.ObservationRescheduledEvent
import com.terraformation.backend.tracking.event.ObservationScheduledEvent
import com.terraformation.backend.tracking.event.ObservationStartedEvent
import com.terraformation.backend.tracking.event.PlantingSiteDeletionStartedEvent
import com.terraformation.backend.tracking.event.PlantingSiteMapEditedEvent
import com.terraformation.backend.tracking.model.MONITORING_PLOT_SIZE_INT
import com.terraformation.backend.tracking.model.NewObservationModel
import com.terraformation.backend.tracking.model.NotificationCriteria
import com.terraformation.backend.tracking.model.PlantingSiteDepth
Expand All @@ -58,6 +61,7 @@ class ObservationService(
private val dslContext: DSLContext,
private val eventPublisher: ApplicationEventPublisher,
private val fileService: FileService,
private val monitoringPlotsDao: MonitoringPlotsDao,
private val observationPhotosDao: ObservationPhotosDao,
private val observationStore: ObservationStore,
private val plantingSiteStore: PlantingSiteStore,
Expand Down Expand Up @@ -287,6 +291,12 @@ class ObservationService(
?: throw PlotNotInObservationException(observationId, monitoringPlotId)
val plantedSubzoneIds =
plantingSiteStore.countReportedPlantsInSubzones(observation.plantingSiteId).keys
val monitoringPlotsRow =
monitoringPlotsDao.fetchOneById(observationPlot.model.monitoringPlotId)

if (monitoringPlotsRow?.sizeMeters != MONITORING_PLOT_SIZE_INT) {
throw PlotSizeNotReplaceableException(observationId, monitoringPlotId)
}

if (!allowCompleted && observationPlot.model.completedTime != null) {
throw PlotAlreadyCompletedException(monitoringPlotId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ class PlotNotInObservationException(
EntityNotFoundException(
"Monitoring plot $monitoringPlotId is not assigned to observation $observationId")

class PlotSizeNotReplaceableException(
val observationId: ObservationId,
val monitoringPlotId: MonitoringPlotId
) :
MismatchedStateException(
"Monitoring plot $monitoringPlotId has old size; can't replace it in observation $observationId")

class ReassignmentExistsException(val plantingId: PlantingId) :
MismatchedStateException(
"Cannot reassign from planting $plantingId because it already has a reassignment")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import com.terraformation.backend.tracking.db.PlantingSiteNotFoundException
import com.terraformation.backend.tracking.db.PlantingSiteStore
import com.terraformation.backend.tracking.db.PlotAlreadyCompletedException
import com.terraformation.backend.tracking.db.PlotNotInObservationException
import com.terraformation.backend.tracking.db.PlotSizeNotReplaceableException
import com.terraformation.backend.tracking.db.ScheduleObservationWithoutPlantsException
import com.terraformation.backend.tracking.edit.PlantingSiteEdit
import com.terraformation.backend.tracking.event.ObservationPlotReplacedEvent
Expand All @@ -58,6 +59,7 @@ import com.terraformation.backend.tracking.event.PlantingSiteMapEditedEvent
import com.terraformation.backend.tracking.model.ExistingObservationModel
import com.terraformation.backend.tracking.model.ExistingPlantingSiteModel
import com.terraformation.backend.tracking.model.MONITORING_PLOT_SIZE
import com.terraformation.backend.tracking.model.MONITORING_PLOT_SIZE_INT
import com.terraformation.backend.tracking.model.NewObservationModel
import com.terraformation.backend.tracking.model.NotificationCriteria
import com.terraformation.backend.tracking.model.PlantingSiteDepth
Expand Down Expand Up @@ -138,6 +140,7 @@ class ObservationServiceTest : DatabaseTest(), RunsAsUser {
dslContext,
eventPublisher,
fileService,
monitoringPlotsDao,
observationPhotosDao,
observationStore,
plantingSiteStore,
Expand Down Expand Up @@ -1782,6 +1785,17 @@ class ObservationServiceTest : DatabaseTest(), RunsAsUser {
}
}

@Test
fun `throws exception if plot size is different from the size of newly-created plots`() {
val monitoringPlotId = insertMonitoringPlot(sizeMeters = MONITORING_PLOT_SIZE_INT - 1)
insertObservationPlot()

assertThrows<PlotSizeNotReplaceableException> {
service.replaceMonitoringPlot(
observationId, monitoringPlotId, "justification", ReplacementDuration.LongTerm)
}
}

@Test
fun `throws access denied exception if no permission to replace plot`() {
val monitoringPlotId = insertMonitoringPlot()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class PlotAssignmentTest : DatabaseTest(), RunsAsUser {
dslContext,
eventPublisher,
mockk(),
monitoringPlotsDao,
observationPhotosDao,
observationStore,
plantingSiteStore,
Expand Down

0 comments on commit 58e3143

Please sign in to comment.