diff --git a/packages/webapp/public/locales/en/translation.json b/packages/webapp/public/locales/en/translation.json index fb5cbabdaf..6a274c83c7 100644 --- a/packages/webapp/public/locales/en/translation.json +++ b/packages/webapp/public/locales/en/translation.json @@ -1995,6 +1995,7 @@ "SELECT_DATE": "Select the task date", "SELECT_TASK_LOCATIONS": "Select the task location(s)", "SELECT_WILD_CROP": "This task targets a wild crop", + "SOIL_AMENDMENT_LOCATION": "Select the soil amendment location(s)", "STATUS": { "ABANDONED": "Abandoned", "COMPLETED": "Completed", diff --git a/packages/webapp/public/locales/es/translation.json b/packages/webapp/public/locales/es/translation.json index 34156942a9..54d0c6e290 100644 --- a/packages/webapp/public/locales/es/translation.json +++ b/packages/webapp/public/locales/es/translation.json @@ -2005,6 +2005,7 @@ "SELECT_DATE": "Seleccione la fecha de la tarea", "SELECT_TASK_LOCATIONS": "Seleccione la(s) ubicación(es) de la tarea", "SELECT_WILD_CROP": "Esta tarea se dirige a un cultivo silvestre", + "SOIL_AMENDMENT_LOCATION": "MISSING", "STATUS": { "ABANDONED": "Abandonada", "COMPLETED": "Completada", diff --git a/packages/webapp/public/locales/fr/translation.json b/packages/webapp/public/locales/fr/translation.json index 61c8bb7e6f..bcb16c171c 100644 --- a/packages/webapp/public/locales/fr/translation.json +++ b/packages/webapp/public/locales/fr/translation.json @@ -2005,6 +2005,7 @@ "SELECT_DATE": "Sélectionnez la date de la tâche", "SELECT_TASK_LOCATIONS": "Sélectionnez le(s) emplacement(s) de la tâche", "SELECT_WILD_CROP": "Cette tâche cible une culture sauvage", + "SOIL_AMENDMENT_LOCATION": "MISSING", "STATUS": { "ABANDONED": "Abandonnée", "COMPLETED": "Terminée", diff --git a/packages/webapp/public/locales/pt/translation.json b/packages/webapp/public/locales/pt/translation.json index dfe5885042..0bea94b396 100644 --- a/packages/webapp/public/locales/pt/translation.json +++ b/packages/webapp/public/locales/pt/translation.json @@ -2004,6 +2004,7 @@ "SELECT_DATE": "Selecionar a data da tarefa", "SELECT_TASK_LOCATIONS": "Selecionar o(s) local(is) da tarefa", "SELECT_WILD_CROP": "Esta tarefa é para um cultivo silvestre", + "SOIL_AMENDMENT_LOCATION": "MISSING", "STATUS": { "ABANDONED": "Abandonada", "COMPLETED": "Completa", diff --git a/packages/webapp/src/containers/Task/TaskLocations/index.jsx b/packages/webapp/src/containers/Task/TaskLocations/index.jsx index 5680fbd8bd..5e85ef8db2 100644 --- a/packages/webapp/src/containers/Task/TaskLocations/index.jsx +++ b/packages/webapp/src/containers/Task/TaskLocations/index.jsx @@ -27,6 +27,7 @@ export default function TaskLocationsSwitch({ history, match, location }) { const isHarvestLocation = useIsTaskType('HARVEST_TASK'); const isIrrigationLocation = useIsTaskType('IRRIGATION_TASK'); const isTransplantLocation = useIsTaskType('TRANSPLANT_TASK'); + const isSoilAmendmentLocation = useIsTaskType('SOIL_AMENDMENT_TASK'); if (isHarvestLocation) { return ; @@ -40,6 +41,10 @@ export default function TaskLocationsSwitch({ history, match, location }) { return ; } + if (isSoilAmendmentLocation) { + return ; + } + return ; } @@ -111,6 +116,26 @@ function TaskIrrigationLocations({ history, location }) { ); } +//This goes to all crop locations, multiSelect, not wildCrops with pins +function TaskSoilAmendmentLocations({ history, location }) { + const { t } = useTranslation(); + const cropLocations = useSelector(cropLocationsSelector); + const onContinue = () => { + history.push('/add_task/task_crops', location.state); + }; + + return ( + + ); +} + function TaskAllLocations({ history, location }) { const dispatch = useDispatch(); const locations = useSelector(locationsSelector); diff --git a/packages/webapp/src/containers/Task/saga.js b/packages/webapp/src/containers/Task/saga.js index 24948eef9b..48e2e1d630 100644 --- a/packages/webapp/src/containers/Task/saga.js +++ b/packages/webapp/src/containers/Task/saga.js @@ -83,7 +83,11 @@ import { createCompleteTaskUrl, } from '../../util/siteMapConstants'; import { setPersistedPaths, setFormData } from '../hooks/useHookFormPersist/hookFormPersistSlice'; -import { formatSoilAmendmentProductToDBStructure, getRemovedTaskProductIds } from '../../util/task'; +import { + formatSoilAmendmentTaskToDBStructure, + formatSoilAmendmentProductToDBStructure, + getRemovedTaskProductIds, +} from '../../util/task'; import { TASKTYPE_PRODUCT_MAP } from './constants'; import { api } from '../../store/api/apiSlice'; @@ -526,10 +530,13 @@ const getSoilAmendmentTaskBody = ( data, endpoint, managementPlanWithCurrentLocationEntities, - { purposes }, + { purposes, methods }, ) => { return { ...getPostTaskBody(data, endpoint, managementPlanWithCurrentLocationEntities), + soil_amendment_task: formatSoilAmendmentTaskToDBStructure(data.soil_amendment_task, { + methods, + }), soil_amendment_task_products: formatSoilAmendmentProductToDBStructure( data.soil_amendment_task_products, { purposes }, @@ -591,6 +598,8 @@ export function* createTaskSaga({ payload }) { api.endpoints.getSoilAmendmentPurposes.select()(state), ); taskTypeSpecificData.purposes = purposes.data; + const methods = yield select((state) => api.endpoints.getSoilAmendmentMethods.select()(state)); + taskTypeSpecificData.methods = methods.data; } const header = getHeader(user_id, farm_id); const isCustomTask = !!task_farm_id; @@ -773,12 +782,17 @@ const getCompleteIrrigationTaskBody = (task_translation_key) => (data) => { }; const getCompleteSoilAmendmentTaskBody = (data, taskTypeSpecificData) => { + const soilAmendmentTask = formatSoilAmendmentTaskToDBStructure( + data.soil_amendment_task, + taskTypeSpecificData, + ); const soilAmendmentTaskProducts = formatSoilAmendmentProductToDBStructure( data.soil_amendment_task_products, taskTypeSpecificData, ); return { ...data.taskData, + soil_amendment_task: soilAmendmentTask, soil_amendment_task_products: soilAmendmentTaskProducts, }; }; @@ -814,6 +828,8 @@ export function* completeTaskSaga({ payload: { task_id, data, returnPath } }) { api.endpoints.getSoilAmendmentPurposes.select()(state), ); taskTypeSpecificData.purposes = purposes.data; + const methods = yield select((state) => api.endpoints.getSoilAmendmentMethods.select()(state)); + taskTypeSpecificData.methods = methods.data; } const taskData = taskTypeGetCompleteTaskBodyFunctionMap[task_translation_key] ? taskTypeGetCompleteTaskBodyFunctionMap[task_translation_key](data, taskTypeSpecificData) diff --git a/packages/webapp/src/util/task.ts b/packages/webapp/src/util/task.ts index c633cc5f24..cfacb90f5b 100644 --- a/packages/webapp/src/util/task.ts +++ b/packages/webapp/src/util/task.ts @@ -13,7 +13,7 @@ * GNU General Public License for more details, see . */ -import { SoilAmendmentPurpose } from '../store/api/types'; +import { SoilAmendmentMethod, SoilAmendmentPurpose } from '../store/api/types'; import { getUnitOptionMap } from './convert-units/getUnitOptionMap'; interface UnitOption { @@ -61,27 +61,37 @@ type FormSoilAmendmentTaskProduct = { }; type DBSoilAmendmentTask = { - soil_amendment_task_products: DBSoilAmendmentTaskProduct[]; + furrow_hole_depth?: number; + furrow_hole_depth_unit?: string; + other_application_method?: string; [key: string]: any; }; type FormSoilAmendmentTask = { + furrow_hole_depth?: number; + furrow_hole_depth_unit?: UnitOption; + other_application_method?: string; + [key: string]: any; +}; + +type DBTask = { + soil_amendment_task_products: DBSoilAmendmentTaskProduct[]; + [key: string]: any; +}; + +type FormTask = { soil_amendment_task_products: FormSoilAmendmentTaskProduct[]; [key: string]: any; }; // Type guard -function isFormSoilAmendmentTask( - task: DBSoilAmendmentTask | FormSoilAmendmentTask, -): task is FormSoilAmendmentTask { +function isFormSoilAmendmentTask(task: DBTask | FormTask): task is FormTask { return 'purposes' in task.soil_amendment_task_products[0]; } -export const formatSoilAmendmentTaskToFormStructure = ( - task: DBSoilAmendmentTask | FormSoilAmendmentTask, -): FormSoilAmendmentTask => { +export const formatSoilAmendmentTaskToFormStructure = (task: DBTask | FormTask): FormTask => { if (isFormSoilAmendmentTask(task)) { - return task as FormSoilAmendmentTask; + return task as FormTask; } const taskClone = structuredClone(task); @@ -177,12 +187,41 @@ export const formatSoilAmendmentProductToDBStructure = ( }); }; +export const formatSoilAmendmentTaskToDBStructure = ( + soilAmendmentTask: FormSoilAmendmentTask, + { methods }: { methods: SoilAmendmentMethod[] }, +): DBSoilAmendmentTask => { + const { + method_id, + furrow_hole_depth, + furrow_hole_depth_unit, + other_application_method, + ...rest + } = soilAmendmentTask; + const furrowHoleId = methods?.find(({ key }) => key === 'FURROW_HOLE')?.id; + const otherMethodId = methods?.find(({ key }) => key === 'OTHER')?.id; + if (!furrowHoleId) { + throw Error('id for FURROW_HOLE method does not exist'); + } + if (!otherMethodId) { + throw Error('id for OTHER method does not exist'); + } + return { + ...rest, + method_id, + furrow_hole_depth: method_id === furrowHoleId ? furrow_hole_depth : undefined, + furrow_hole_depth_unit: method_id === furrowHoleId ? furrow_hole_depth_unit?.value : undefined, + other_application_method: + soilAmendmentTask.method_id === otherMethodId ? other_application_method : undefined, + }; +}; + export const formatTaskReadOnlyDefaultValues = (task: { taskType?: { task_translation_key: string }; [key: string]: any; }) => { if (task.taskType?.task_translation_key === 'SOIL_AMENDMENT_TASK') { - return formatSoilAmendmentTaskToFormStructure(task as DBSoilAmendmentTask); + return formatSoilAmendmentTaskToFormStructure(task as DBTask); } return structuredClone(task);