Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/famous-hats-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@svenvw/fdm-app": minor
---

At Gebruiksruimte make 2026 also available
5 changes: 5 additions & 0 deletions .changeset/perky-heads-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@svenvw/fdm-calculator": patch
---

Fix calculating korting at stikstofgebruiksnorm when vangewas is sown on October 15th
5 changes: 5 additions & 0 deletions .changeset/ready-geckos-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@svenvw/fdm-app": minor
---

Enable to create a farm for next year
5 changes: 5 additions & 0 deletions .changeset/silly-signs-ring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@svenvw/fdm-calculator": minor
---

Add calculation support of Dutch norms for fertilizer applications for 2026
5 changes: 5 additions & 0 deletions .changeset/small-icons-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@svenvw/fdm-app": minor
---

Make next year also available
5 changes: 5 additions & 0 deletions .changeset/thick-bottles-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@svenvw/fdm-calculator": minor
---

Include at NL Stikstofgebruiksnormen that nl_335 (Natuurterreinen (incl. heide)) is set to be not bouwland
4 changes: 2 additions & 2 deletions fdm-app/app/lib/calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Timeframe } from "@svenvw/fdm-core"
import type { Params } from "react-router"

const yearStart = 2020
const yearEnd = new Date().getFullYear()
const yearEnd = new Date().getFullYear() + 1

export function getCalendar(params: Params): string {
const calendar = params.calendar as string
Expand Down Expand Up @@ -37,7 +37,7 @@ export function getTimeframe(params: Params): Timeframe {
}

export function getCalendarSelection(): string[] {
// Create array of years from 2020 to current year
// Create array of years from 2020 to next year
const years = []
for (let i = yearStart; i <= yearEnd; i++) {
years.push(i.toString())
Expand Down
4 changes: 2 additions & 2 deletions fdm-app/app/routes/farm.$b_id_farm.$calendar.norms.$b_id.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
})

const asyncData = (async () => {
if (calendar !== "2025") {
if (calendar !== "2025" && calendar !== "2026") {
return {
fieldNormData: undefined,
errorMessage:
"Gebruiksnormen zijn alleen beschikbaar voor 2025.",
"Gebruiksnormen zijn alleen beschikbaar voor 2025 en 2026.",
}
}

Expand Down
6 changes: 3 additions & 3 deletions fdm-app/app/routes/farm.$b_id_farm.$calendar.norms._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
)

const asyncData = (async () => {
// Currently only 2025 is supported
if (calendar !== "2025") {
// Currently only 2025 and 2026 are supported
if (calendar !== "2025" && calendar !== "2026") {
return {}
}

Expand Down Expand Up @@ -453,7 +453,7 @@ function Norms(loaderData: Awaited<ReturnType<typeof loader>>) {
</h1>
<p className="text-sm text-muted-foreground">
Op dit moment kunnen we alleen nog de gebruiksnormen voor
2025 berekenen en weergeven.
2025 en 2026 berekenen en weergeven.
</p>
<NavLink to={`/farm/${loaderData.b_id_farm}/2025/norms`}>
<Button>Ga naar 2025</Button>
Expand Down
33 changes: 16 additions & 17 deletions fdm-app/app/routes/farm.create._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { clientConfig } from "~/lib/config"
import { handleActionError } from "~/lib/error"
import { fdm } from "~/lib/fdm.server"
import { extractFormValuesFromRequest } from "~/lib/form"
import { getCalendarSelection } from "../lib/calendar"

// Meta
export const meta: MetaFunction = () => {
Expand Down Expand Up @@ -89,9 +90,11 @@ const FormSchema = z.object({

// Loader
export async function loader({ request }: LoaderFunctionArgs) {
const yearSelection = getCalendarSelection()

return {
b_name_farm: null,
year: new Date().getFullYear(),
yearSelection: yearSelection,
}
}

Expand All @@ -101,25 +104,19 @@ export async function loader({ request }: LoaderFunctionArgs) {
* @returns The JSX element representing the add farm page.
*/
export default function AddFarmPage() {
const loaderData = useLoaderData<typeof loader>()
const { year, yearSelection } = useLoaderData<typeof loader>()

const form = useRemixForm<z.infer<typeof FormSchema>>({
mode: "onTouched",
resolver: zodResolver(FormSchema),
defaultValues: {
b_name_farm: loaderData.b_name_farm ?? "",
year: loaderData.year,
b_name_farm: "",
year: year,
has_derogation: false,
derogation_start_year: loaderData.year,
derogation_start_year: 2025,
},
})

const currentYear = new Date().getFullYear()
const years = Array.from(
{ length: currentYear - 2020 + 1 },
(_, i) => currentYear - i,
)

return (
<SidebarInset>
<Header action={undefined}>
Expand Down Expand Up @@ -217,7 +214,7 @@ export default function AddFarmPage() {
field.onChange
}
defaultValue={String(
new Date().getFullYear(),
field.value,
)}
>
<FormControl>
Expand Down Expand Up @@ -289,18 +286,20 @@ export default function AddFarmPage() {
</SelectTrigger>
</FormControl>
<SelectContent>
{years.map(
{yearSelection.map(
(
year,
yearOption: string,
) => (
<SelectItem
key={
year
yearOption
}
value={
yearOption
}
value={year.toString()}
>
{
year
yearOption
}
</SelectItem>
),
Expand Down
6 changes: 3 additions & 3 deletions fdm-calculator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export type {
InputAggregateNormFillingsToFarmLevel,
InputAggregateNormsToFarmLevel,
} from "./norms/farm"
export type { NormFilling } from "./norms/nl/2025/filling/types"
export {
isFieldInGWGBGebied,
isFieldInNatura2000Gebied,
Expand All @@ -60,10 +59,11 @@ export {
getRegion,
isFieldInNVGebied,
} from "./norms/nl/2025/value/stikstofgebruiksnorm"
export type { NL2025NormsInput } from "./norms/nl/2025/value/types"
export type {
GebruiksnormResult,
NL2025NormsInput,
} from "./norms/nl/2025/value/types"
NormFilling,
} from "./norms/nl/types"
export {
getNutrientAdvice,
requestNutrientAdvice,
Expand Down
4 changes: 2 additions & 2 deletions fdm-calculator/src/norms/farm.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Decimal } from "decimal.js"
import type { NormFilling } from "./nl/2025/filling/types"
import type { GebruiksnormResult } from "./nl/2025/value/types"
import type { NormFilling } from "./nl/types"
import type { GebruiksnormResult } from "./nl/types"

/**
* Represents the input structure for the `aggregateNormsToFarmLevel` function.
Expand Down
57 changes: 54 additions & 3 deletions fdm-calculator/src/norms/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,20 @@ import {
} from "./index"
import { getNL2025FertilizerApplicationFillingForDierlijkeMestGebruiksNorm } from "./nl/2025/filling/dierlijke-mest-gebruiksnorm"
import { getNL2025FertilizerApplicationFillingForFosfaatGebruiksNorm } from "./nl/2025/filling/fosfaatgebruiksnorm"
import { collectInputForFertilizerApplicationFilling } from "./nl/2025/filling/input"
import { collectNL2025InputForFertilizerApplicationFilling } from "./nl/2025/filling/input"
import { getNL2025FertilizerApplicationFillingForStikstofGebruiksNorm } from "./nl/2025/filling/stikstofgebruiksnorm"
import { getNL2025DierlijkeMestGebruiksNorm } from "./nl/2025/value/dierlijke-mest-gebruiksnorm"
import { getNL2025FosfaatGebruiksNorm } from "./nl/2025/value/fosfaatgebruiksnorm"
import { collectNL2025InputForNorms } from "./nl/2025/value/input"
import { getNL2025StikstofGebruiksNorm } from "./nl/2025/value/stikstofgebruiksnorm"
import { collectNL2026InputForNorms } from "./nl/2026/value/input"
import { getNL2026StikstofGebruiksNorm } from "./nl/2026/value/stikstofgebruiksnorm"
import { getNL2026DierlijkeMestGebruiksNorm } from "./nl/2026/value/dierlijke-mest-gebruiksnorm"
import { getNL2026FosfaatGebruiksNorm } from "./nl/2026/value/fosfaatgebruiksnorm"
import { getNL2026FertilizerApplicationFillingForFosfaatGebruiksNorm } from "./nl/2026/filling/fosfaatgebruiksnorm"
import { getNL2026FertilizerApplicationFillingForDierlijkeMestGebruiksNorm } from "./nl/2026/filling/dierlijke-mest-gebruiksnorm"
import { getNL2026FertilizerApplicationFillingForStikstofGebruiksNorm } from "./nl/2026/filling/stikstofgebruiksnorm"
import { collectNL2026InputForFertilizerApplicationFilling } from "./nl/2026/filling/input"

describe("createFunctionsForNorms", () => {
it("should return the correct functions for NL region and year 2025", () => {
Expand All @@ -34,13 +42,32 @@ describe("createFunctionsForNorms", () => {
)
})

it("should return the correct functions for NL region and year 2026", () => {
const functions = createFunctionsForNorms("NL", "2026")
expect(functions.collectInputForNorms).toBe(collectNL2026InputForNorms)
expect(functions.calculateNormForNitrogen).toBe(
getNL2026StikstofGebruiksNorm,
)
expect(functions.calculateNormForManure).toBe(
getNL2026DierlijkeMestGebruiksNorm,
)
expect(functions.calculateNormForPhosphate).toBe(
getNL2026FosfaatGebruiksNorm,
)
expect(functions.aggregateNormsToFarmLevel).toBe(
aggregateNormsToFarmLevel,
)
})

it("should throw an error for an unsupported year", () => {
expect(() => createFunctionsForNorms("NL", " 2024")).toThrow(
//@ts-expect-error
expect(() => createFunctionsForNorms("NL", "2024")).toThrow(
"Year not supported",
)
})

it("should throw an error for an unsupported region", () => {
//@ts-expect-error
expect(() => createFunctionsForNorms("BE", "2025")).toThrow(
"Region not supported",
)
Expand All @@ -54,7 +81,7 @@ describe("createFunctionsForFertilizerApplicationFilling", () => {
"2025",
)
expect(functions.collectInputForFertilizerApplicationFilling).toBe(
collectInputForFertilizerApplicationFilling,
collectNL2025InputForFertilizerApplicationFilling,
)
expect(functions.calculateFertilizerApplicationFillingForNitrogen).toBe(
getNL2025FertilizerApplicationFillingForStikstofGebruiksNorm,
Expand All @@ -70,14 +97,38 @@ describe("createFunctionsForFertilizerApplicationFilling", () => {
)
})

it("should return the correct functions for NL region and year 2026", () => {
const functions = createFunctionsForFertilizerApplicationFilling(
"NL",
"2026",
)
expect(functions.collectInputForFertilizerApplicationFilling).toBe(
collectNL2026InputForFertilizerApplicationFilling,
)
expect(functions.calculateFertilizerApplicationFillingForNitrogen).toBe(
getNL2026FertilizerApplicationFillingForStikstofGebruiksNorm,
)
expect(functions.calculateFertilizerApplicationFillingForManure).toBe(
getNL2026FertilizerApplicationFillingForDierlijkeMestGebruiksNorm,
)
expect(
functions.calculateFertilizerApplicationFillingForPhosphate,
).toBe(getNL2026FertilizerApplicationFillingForFosfaatGebruiksNorm)
expect(functions.aggregateNormFillingsToFarmLevel).toBe(
aggregateNormFillingsToFarmLevel,
)
})

it("should throw an error for an unsupported year", () => {
expect(() =>
//@ts-expect-error
createFunctionsForFertilizerApplicationFilling("NL", "2024"),
).toThrow("Year not supported")
})

it("should throw an error for an unsupported region", () => {
expect(() =>
//@ts-expect-error
createFunctionsForFertilizerApplicationFilling("BE", "2025"),
).toThrow("Region not supported")
})
Expand Down
46 changes: 40 additions & 6 deletions fdm-calculator/src/norms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,26 @@ import {
} from "./farm"
import { getNL2025FertilizerApplicationFillingForDierlijkeMestGebruiksNorm } from "./nl/2025/filling/dierlijke-mest-gebruiksnorm"
import { getNL2025FertilizerApplicationFillingForFosfaatGebruiksNorm } from "./nl/2025/filling/fosfaatgebruiksnorm"
import { collectInputForFertilizerApplicationFilling } from "./nl/2025/filling/input"
import { collectNL2025InputForFertilizerApplicationFilling } from "./nl/2025/filling/input"
import { getNL2025FertilizerApplicationFillingForStikstofGebruiksNorm } from "./nl/2025/filling/stikstofgebruiksnorm"
import type { NormFilling } from "./nl/2025/filling/types"
import { getNL2025DierlijkeMestGebruiksNorm } from "./nl/2025/value/dierlijke-mest-gebruiksnorm"
import { getNL2025FosfaatGebruiksNorm } from "./nl/2025/value/fosfaatgebruiksnorm"
import { collectNL2025InputForNorms } from "./nl/2025/value/input"
import { getNL2025StikstofGebruiksNorm } from "./nl/2025/value/stikstofgebruiksnorm"
import { getNL2026FertilizerApplicationFillingForDierlijkeMestGebruiksNorm } from "./nl/2026/filling/dierlijke-mest-gebruiksnorm"
import { getNL2026FertilizerApplicationFillingForFosfaatGebruiksNorm } from "./nl/2026/filling/fosfaatgebruiksnorm"
import { collectNL2026InputForFertilizerApplicationFilling } from "./nl/2026/filling/input"
import { getNL2026FertilizerApplicationFillingForStikstofGebruiksNorm } from "./nl/2026/filling/stikstofgebruiksnorm"
import { getNL2026DierlijkeMestGebruiksNorm } from "./nl/2026/value/dierlijke-mest-gebruiksnorm"
import { getNL2026FosfaatGebruiksNorm } from "./nl/2026/value/fosfaatgebruiksnorm"
import { collectNL2026InputForNorms } from "./nl/2026/value/input"
import { getNL2026StikstofGebruiksNorm } from "./nl/2026/value/stikstofgebruiksnorm"
import type { NormFilling } from "./nl/types"

export function createFunctionsForNorms(b_region: "NL", year: "2025") {
type Years = "2025" | "2026"
type Regions = "NL"

export function createFunctionsForNorms(b_region: Regions, year: Years) {
if (b_region === "NL") {
if (year === "2025") {
return {
Expand All @@ -23,20 +34,29 @@ export function createFunctionsForNorms(b_region: "NL", year: "2025") {
aggregateNormsToFarmLevel: aggregateNormsToFarmLevel,
}
}
if (year === "2026") {
return {
collectInputForNorms: collectNL2026InputForNorms,
calculateNormForNitrogen: getNL2026StikstofGebruiksNorm,
calculateNormForManure: getNL2026DierlijkeMestGebruiksNorm,
calculateNormForPhosphate: getNL2026FosfaatGebruiksNorm,
aggregateNormsToFarmLevel: aggregateNormsToFarmLevel,
}
}
throw new Error("Year not supported")
}
throw new Error("Region not supported")
}

export function createFunctionsForFertilizerApplicationFilling(
b_region: "NL",
year: "2025",
b_region: Regions,
year: Years,
) {
if (b_region === "NL") {
if (year === "2025") {
return {
collectInputForFertilizerApplicationFilling:
collectInputForFertilizerApplicationFilling,
collectNL2025InputForFertilizerApplicationFilling,
calculateFertilizerApplicationFillingForNitrogen:
getNL2025FertilizerApplicationFillingForStikstofGebruiksNorm,
calculateFertilizerApplicationFillingForManure:
Expand All @@ -47,6 +67,20 @@ export function createFunctionsForFertilizerApplicationFilling(
aggregateNormFillingsToFarmLevel,
}
}
if (year === "2026") {
return {
collectInputForFertilizerApplicationFilling:
collectNL2026InputForFertilizerApplicationFilling,
calculateFertilizerApplicationFillingForNitrogen:
getNL2026FertilizerApplicationFillingForStikstofGebruiksNorm,
calculateFertilizerApplicationFillingForManure:
getNL2026FertilizerApplicationFillingForDierlijkeMestGebruiksNorm,
calculateFertilizerApplicationFillingForPhosphate:
getNL2026FertilizerApplicationFillingForFosfaatGebruiksNorm,
aggregateNormFillingsToFarmLevel:
aggregateNormFillingsToFarmLevel,
}
}
throw new Error("Year not supported")
}
throw new Error("Region not supported")
Expand Down
Loading