diff --git a/fdm-app/CHANGELOG.md b/fdm-app/CHANGELOG.md index 85944f2e4..2b266056e 100644 --- a/fdm-app/CHANGELOG.md +++ b/fdm-app/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog fdm-app +## 0.29.5 + +### Patch Changes + +- [#569](https://github.com/nmi-agro/fdm/pull/569) [`6fd2c63`](https://github.com/nmi-agro/fdm/commit/6fd2c6312c08ef4ae3934761d6f5242b16c779a7) Thanks [@SvenVw](https://github.com/SvenVw)! - Fix the "Gewasresten achterlaten" input visibility to depend on crop rotation category (`b_lu_croprotation === 'cereal'`) and ensure its default value is `undefined` when hidden. + +- Updated dependencies [[`8d7bf3f`](https://github.com/nmi-agro/fdm/commit/8d7bf3f26700d764a8d253087e1b966dc47d035e)]: + - @nmi-agro/fdm-calculator@0.13.2 + - @nmi-agro/fdm-agents@0.2.1 + ## 0.29.4 ### Patch Changes diff --git a/fdm-app/app/components/blocks/cultivation/card-details.tsx b/fdm-app/app/components/blocks/cultivation/card-details.tsx index 6cf22727d..9ca507889 100644 --- a/fdm-app/app/components/blocks/cultivation/card-details.tsx +++ b/fdm-app/app/components/blocks/cultivation/card-details.tsx @@ -47,8 +47,9 @@ export function CultivationDetailsCard({ ? new Date(cultivation.b_lu_end) : null, m_cropresidue: - !!cultivation.b_lu_eom_residue && - (cultivation.m_cropresidue ?? false), + cultivation.b_lu_croprotation === "cereal" + ? (cultivation.m_cropresidue ?? undefined) + : undefined, b_lu_variety: cultivation.b_lu_variety ?? null, }, }) @@ -63,8 +64,9 @@ export function CultivationDetailsCard({ ? new Date(cultivation.b_lu_end) : null, m_cropresidue: - !!cultivation.b_lu_eom_residue && - (cultivation.m_cropresidue ?? false), + cultivation.b_lu_croprotation === "cereal" + ? (cultivation.m_cropresidue ?? undefined) + : undefined, b_lu_variety: cultivation.b_lu_variety ?? null, }) }, [cultivation, form.reset]) @@ -135,8 +137,8 @@ export function CultivationDetailsCard({ diff --git a/fdm-app/app/components/blocks/rotation/columns.tsx b/fdm-app/app/components/blocks/rotation/columns.tsx index 7d28aa894..71e6de977 100644 --- a/fdm-app/app/components/blocks/rotation/columns.tsx +++ b/fdm-app/app/components/blocks/rotation/columns.tsx @@ -264,7 +264,7 @@ export const columns: ColumnDef[] = [ }, enableHiding: true, // Enable hiding for mobile cell: (props) => - (props.row.original.b_lu_eom_residue ?? 0) !== 0 && ( + props.row.original.b_lu_croprotation === "cereal" && ( ), }, diff --git a/fdm-app/package.json b/fdm-app/package.json index 142643f3d..a23478775 100644 --- a/fdm-app/package.json +++ b/fdm-app/package.json @@ -1,6 +1,6 @@ { "name": "@nmi-agro/fdm-app", - "version": "0.29.4", + "version": "0.29.5", "private": true, "sideEffects": false, "type": "module", diff --git a/fdm-calculator/CHANGELOG.md b/fdm-calculator/CHANGELOG.md index 44ea2347d..6f05c6c2f 100644 --- a/fdm-calculator/CHANGELOG.md +++ b/fdm-calculator/CHANGELOG.md @@ -1,5 +1,11 @@ # fdm-calculator +## 0.13.2 + +### Patch Changes + +- [#569](https://github.com/nmi-agro/fdm/pull/569) [`8d7bf3f`](https://github.com/nmi-agro/fdm/commit/8d7bf3f26700d764a8d253087e1b966dc47d035e) Thanks [@SvenVw](https://github.com/SvenVw)! - Fix a bug in organic matter supply calculation where `undefined` crop residues yielded zero supply; it now correctly calculates supply for residues that are not explicitly removed. + ## 0.13.1 ### Patch Changes diff --git a/fdm-calculator/package.json b/fdm-calculator/package.json index 85f982232..91ed15dd5 100644 --- a/fdm-calculator/package.json +++ b/fdm-calculator/package.json @@ -1,7 +1,7 @@ { "name": "@nmi-agro/fdm-calculator", "private": false, - "version": "0.13.1", + "version": "0.13.2", "description": "Calculate various insights based on the Farm Data Model", "license": "MIT", "homepage": "https://github.com/nmi-agro/fdm", diff --git a/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts b/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts index fa9b8538a..ab96d63ed 100644 --- a/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts +++ b/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts @@ -254,6 +254,32 @@ describe("calculateNitrogenRemovalByResidue", () => { }) }) + it("should handle undefined m_cropresidue as not removed (return 0)", () => { + const cultivations: FieldInput["cultivations"] = [ + { + b_lu: "cultivation1", + b_lu_catalogue: "catalogue1", + b_lu_start: new Date("2022-01-01"), + b_lu_end: new Date("2022-12-31"), + m_cropresidue: null, // null residue handling (represents undefined in UI) + b_lu_name: "Cultivation 1", + b_lu_croprotation: "cereal", + }, + ] + const harvests: FieldInput["harvests"] = [] + + const result = calculateNitrogenRemovalByResidue( + cultivations, + harvests, + cultivationDetailsMap, + ) + + expect(result).toEqual({ + total: new Decimal(0), + cultivations: [{ id: "cultivation1", value: new Decimal(0) }], + }) + }) + it("should handle empty harvestable_analyses array", () => { const cultivations: FieldInput["cultivations"] = [ { diff --git a/fdm-calculator/src/balance/organic-matter/supply/residues.test.ts b/fdm-calculator/src/balance/organic-matter/supply/residues.test.ts index e884ea13e..bf7502661 100644 --- a/fdm-calculator/src/balance/organic-matter/supply/residues.test.ts +++ b/fdm-calculator/src/balance/organic-matter/supply/residues.test.ts @@ -66,6 +66,31 @@ describe("calculateOrganicMatterSupplyByResidues", () => { }) }) + it("should calculate EOM supply from residues if m_cropresidue is undefined (standard practice)", () => { + const cultivations: FieldInput["cultivations"] = [ + { + b_lu: "cult1", + b_lu_catalogue: "maize", + m_cropresidue: null, // null residue handling (represents undefined in UI) + b_lu_end: new Date("2023-10-15"), + b_lu_name: "test", + b_lu_start: new Date("2023-05-01"), + }, + ] as FieldInput["cultivations"] + + const result = calculateOrganicMatterSupplyByResidues( + cultivations, + cultivationDetailsMap, + timeFrame, + ) + + expect(result.total.toNumber()).toBe(800) + expect(result.cultivations[0]).toEqual({ + id: "cult1", + value: new Decimal(800), + }) + }) + it("should return zero if m_cropresidue is false", () => { const cultivations: FieldInput["cultivations"] = [ { diff --git a/fdm-calculator/src/balance/organic-matter/supply/residues.ts b/fdm-calculator/src/balance/organic-matter/supply/residues.ts index b13151e14..3662b1e4f 100644 --- a/fdm-calculator/src/balance/organic-matter/supply/residues.ts +++ b/fdm-calculator/src/balance/organic-matter/supply/residues.ts @@ -11,8 +11,10 @@ import type { * * This function evaluates each cultivation to determine if its residues contribute to the soil's organic matter. * The contribution is only counted if two conditions are met: - * 1. The `m_cropresidue` flag for the cultivation is true, indicating that residues were incorporated into the soil. - * 2. The cultivation's end date (`b_lu_end`) falls within the specified calculation timeframe. + * 1. The `cultivationDetail.b_lu_eom_residue` value is present (not null or undefined) in the catalogue. + * 2. The `cult.m_cropresidue` flag is NOT explicitly set to `false`. This means residues are considered left + * on the field when `m_cropresidue` is either `true` or `undefined` (standard practice). + * 3. The cultivation's end date (`b_lu_end`) falls within the specified calculation timeframe. * * The EOM value for residues is sourced from the cultivation catalogue (`b_lu_eom_residue`). * @@ -35,8 +37,11 @@ export function calculateOrganicMatterSupplyByResidues( const cultivationDetail = cultivationDetailsMap.get(cult.b_lu_catalogue) // Proceed only if the cultivation type has a defined EOM value for residues - // and the 'm_cropresidue' flag is explicitly set to true. - if (cultivationDetail?.b_lu_eom_residue != null && cult.m_cropresidue) { + // and the 'm_cropresidue' flag is not explicitly set to false. + if ( + cultivationDetail?.b_lu_eom_residue != null && + cult.m_cropresidue !== false + ) { // Ensure the cultivation ended within the calculation timeframe. const terminationDate = cult.b_lu_end ? new Date(cult.b_lu_end)