From c570b8a51bb22e513b4c07b0e9efdd072807dd5c Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Thu, 2 Apr 2026 13:59:44 +0200 Subject: [PATCH 1/4] fix: when cropresidues are left they are not included in the nitrogen removal. When residues are removed from the field they are included in the nitrogen removal --- .changeset/better-snakes-clap.md | 5 +++++ fdm-calculator/src/balance/nitrogen/removal/residue.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/better-snakes-clap.md diff --git a/.changeset/better-snakes-clap.md b/.changeset/better-snakes-clap.md new file mode 100644 index 000000000..864100417 --- /dev/null +++ b/.changeset/better-snakes-clap.md @@ -0,0 +1,5 @@ +--- +"@nmi-agro/fdm-calculator": patch +--- + +Fix that when cropresidues are left they are not included in the nitrogen removal. When residues are removed from the field they are included in the nitrogen removal diff --git a/fdm-calculator/src/balance/nitrogen/removal/residue.ts b/fdm-calculator/src/balance/nitrogen/removal/residue.ts index 2632cd7bf..e6b213809 100644 --- a/fdm-calculator/src/balance/nitrogen/removal/residue.ts +++ b/fdm-calculator/src/balance/nitrogen/removal/residue.ts @@ -39,8 +39,8 @@ export function calculateNitrogenRemovalByResidue( ) } - // If no crop residues are left or if this is not known return 0 for the amount of Nitrogen removed by crop residues - if (!cultivation.m_cropresidue) { + // If crop residues are left or if this is not known return 0 for the amount of Nitrogen removed by crop residues + if (cultivation.m_cropresidue) { return { id: cultivation.b_lu, value: new Decimal(0), From 22d207af14e7632f0b3922bb34e93e80b434334b Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Thu, 2 Apr 2026 14:10:30 +0200 Subject: [PATCH 2/4] tests: fixes --- .../balance/nitrogen/removal/index.test.ts | 6 ++--- .../balance/nitrogen/removal/residue.test.ts | 22 +++++++++---------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/fdm-calculator/src/balance/nitrogen/removal/index.test.ts b/fdm-calculator/src/balance/nitrogen/removal/index.test.ts index 97444a5f3..4404a00d5 100644 --- a/fdm-calculator/src/balance/nitrogen/removal/index.test.ts +++ b/fdm-calculator/src/balance/nitrogen/removal/index.test.ts @@ -66,9 +66,9 @@ describe("calculateNitrogenRemoval", () => { cultivationDetailsMap, ) - expect(result.total.toNumber()).toBeCloseTo(-23) // -20 from harvest + -3 from residue + expect(result.total.toNumber()).toBeCloseTo(-20) // -20 from harvest expect(result.harvests.total.toNumber()).toBeCloseTo(-20) - expect(result.residues.total.toNumber()).toBeCloseTo(-3) + expect(result.residues.total.toNumber()).toBeCloseTo(0) // No nitrogen removed by residues since m_cropresidue is true }) it("should handle cases with no harvests or residues", () => { @@ -76,7 +76,7 @@ describe("calculateNitrogenRemoval", () => { { b_lu: "cultivation1", b_lu_catalogue: "catalogue1", - m_cropresidue: false, + m_cropresidue: true, // Residues left on field, not removed b_lu_start: new Date("2022-01-01"), b_lu_end: new Date("2022-12-31"), b_lu_name: "Cultivation 1", diff --git a/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts b/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts index 490325409..435ea789c 100644 --- a/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts +++ b/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts @@ -31,14 +31,14 @@ describe("calculateNitrogenRemovalByResidue", () => { ], ]) - it("should return 0 if no crop residues are left", () => { + it("should return 0 if crop residues are left on the field", () => { 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: false, // No residue left + m_cropresidue: true, // Residues left on field, not removed b_lu_name: "Cultivation 1", b_lu_croprotation: "cereal", }, @@ -64,7 +64,7 @@ describe("calculateNitrogenRemovalByResidue", () => { b_lu_catalogue: "catalogue1", b_lu_start: new Date("2022-01-01"), b_lu_end: new Date("2022-12-31"), - m_cropresidue: true, + m_cropresidue: false, // Residues removed from field b_lu_name: "Cultivation 1", b_lu_croprotation: "cereal", }, @@ -116,7 +116,7 @@ describe("calculateNitrogenRemovalByResidue", () => { b_lu_catalogue: "catalogue1", b_lu_start: new Date("2022-01-01"), b_lu_end: new Date("2022-12-31"), - m_cropresidue: true, + m_cropresidue: false, // Residues removed from field b_lu_name: "Cultivation 1", b_lu_croprotation: "cereal", }, @@ -185,7 +185,7 @@ describe("calculateNitrogenRemovalByResidue", () => { b_lu_catalogue: "catalogue1", b_lu_start: new Date("2022-01-01"), b_lu_end: new Date("2022-12-31"), - m_cropresidue: true, + m_cropresidue: false, // Residues removed from field b_lu_name: "Cultivation 1", b_lu_croprotation: "cereal", }, @@ -228,7 +228,7 @@ describe("calculateNitrogenRemovalByResidue", () => { ) }) - it("should handle null m_cropresidue as false", () => { + it("should calculate nitrogen removal when m_cropresidue is null", () => { const cultivations: FieldInput["cultivations"] = [ { b_lu: "cultivation1", @@ -248,10 +248,8 @@ describe("calculateNitrogenRemovalByResidue", () => { cultivationDetailsMap, ) - expect(result).toEqual({ - total: new Decimal(0), - cultivations: [{ id: "cultivation1", value: new Decimal(0) }], - }) + expect(result.total.toNumber()).toBeCloseTo(-3) //Approximation due to floating point + expect(result.cultivations[0].value.toNumber()).toBeCloseTo(-3) //Approximation due to floating point }) it("should handle empty harvestable_analyses array", () => { @@ -261,7 +259,7 @@ describe("calculateNitrogenRemovalByResidue", () => { b_lu_catalogue: "catalogue1", b_lu_start: new Date("2022-01-01"), b_lu_end: new Date("2022-12-31"), - m_cropresidue: true, + m_cropresidue: false, // Residues removed from field b_lu_name: "Cultivation 1", b_lu_croprotation: "cereal", }, @@ -295,7 +293,7 @@ describe("calculateNitrogenRemovalByResidue", () => { b_lu_catalogue: "catalogue2", b_lu_start: new Date("2022-01-01"), b_lu_end: new Date("2022-12-31"), - m_cropresidue: true, + m_cropresidue: false, // Residues removed from field b_lu_name: "test", b_lu_croprotation: null, }, From 48e26b40fd3f05a92f7f562ac76c52ea39ae3689 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Thu, 2 Apr 2026 14:11:39 +0200 Subject: [PATCH 3/4] docs: improve changeset --- .changeset/better-snakes-clap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/better-snakes-clap.md b/.changeset/better-snakes-clap.md index 864100417..6f4d23ae5 100644 --- a/.changeset/better-snakes-clap.md +++ b/.changeset/better-snakes-clap.md @@ -2,4 +2,4 @@ "@nmi-agro/fdm-calculator": patch --- -Fix that when cropresidues are left they are not included in the nitrogen removal. When residues are removed from the field they are included in the nitrogen removal +Fix nitrogen removal for crop residues: residues left on the field are no longer counted as removed, while residues removed from the field are. From ea6cc5b5ecc65d500ba9c4d987513250f6c9c1f4 Mon Sep 17 00:00:00 2001 From: SvenVw <37927107+SvenVw@users.noreply.github.com> Date: Thu, 2 Apr 2026 14:13:16 +0200 Subject: [PATCH 4/4] fix: null values --- .../src/balance/nitrogen/removal/residue.test.ts | 8 +++++--- fdm-calculator/src/balance/nitrogen/removal/residue.ts | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts b/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts index 435ea789c..fa9b8538a 100644 --- a/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts +++ b/fdm-calculator/src/balance/nitrogen/removal/residue.test.ts @@ -228,7 +228,7 @@ describe("calculateNitrogenRemovalByResidue", () => { ) }) - it("should calculate nitrogen removal when m_cropresidue is null", () => { + it("should handle null m_cropresidue as not removed (return 0)", () => { const cultivations: FieldInput["cultivations"] = [ { b_lu: "cultivation1", @@ -248,8 +248,10 @@ describe("calculateNitrogenRemovalByResidue", () => { cultivationDetailsMap, ) - expect(result.total.toNumber()).toBeCloseTo(-3) //Approximation due to floating point - expect(result.cultivations[0].value.toNumber()).toBeCloseTo(-3) //Approximation due to floating point + expect(result).toEqual({ + total: new Decimal(0), + cultivations: [{ id: "cultivation1", value: new Decimal(0) }], + }) }) it("should handle empty harvestable_analyses array", () => { diff --git a/fdm-calculator/src/balance/nitrogen/removal/residue.ts b/fdm-calculator/src/balance/nitrogen/removal/residue.ts index e6b213809..fbfecc87e 100644 --- a/fdm-calculator/src/balance/nitrogen/removal/residue.ts +++ b/fdm-calculator/src/balance/nitrogen/removal/residue.ts @@ -40,7 +40,7 @@ export function calculateNitrogenRemovalByResidue( } // If crop residues are left or if this is not known return 0 for the amount of Nitrogen removed by crop residues - if (cultivation.m_cropresidue) { + if (cultivation.m_cropresidue !== false) { return { id: cultivation.b_lu, value: new Decimal(0),