fix(kæde): højst 3 forslag pr. afgrøde og ét samlet kædepunkt i Kræver handling

This commit is contained in:
2026-09-30 14:26:09 +02:00
parent d2453f78fb
commit 9e34a16dfa
5 changed files with 31 additions and 22 deletions
+19 -5
View File
@@ -6,6 +6,8 @@ ADCropPlan = {}
ADCropPlan.HORIZON_MONTHS = 12
ADCropPlan.MIN_SHARE = 0.10
ADCropPlan.MIN_HA = 0.5
-- højst så mange forslag (ikke auto-skift) pr. afgrøde, så listen ikke vokser til snesevis af rækker
ADCropPlan.MAX_SUGGEST_PER_FRUIT = 3
function ADCropPlan.plannedFruit(field)
if field.targetFruit ~= nil and field.targetFruit ~= "" then return field.targetFruit end
@@ -43,16 +45,24 @@ local function isCandidate(field, used, dismissedFruit, fruit)
return dismissedFruit ~= fruit
end
-- prices: {[afgrøde] = pris} eller en funktion afgrøde -> pris (slås kun op for kandidaternes afgrøder).
function ADCropPlan.choose(shortages, fields, usedFruits, yields, prices, dismissed)
local actions, taken = {}, {}
local used = usedFruits or {}
local priceOf = type(prices) == "function" and prices or function(fruit) return (prices or {})[fruit] or 0 end
local priceCache = {}
local function valueOf(fruit)
if fruit == "" then return 0 end
if priceCache[fruit] == nil then priceCache[fruit] = ((yields or {})[fruit] or 0) * (priceOf(fruit) or 0) end
return priceCache[fruit]
end
for _, shortage in ipairs(shortages or {}) do
local remaining = shortage.missingHa
local candidates = {}
for _, field in ipairs(fields or {}) do
if not taken[field.id] and isCandidate(field, used, (dismissed or {})[field.id], shortage.fruit) then
local planned = ADCropPlan.plannedFruit(field) or ""
local value = ((yields or {})[planned] or 0) * ((prices or {})[planned] or 0)
local value = valueOf(planned)
table.insert(candidates, {field = field, value = value})
end
end
@@ -62,14 +72,18 @@ function ADCropPlan.choose(shortages, fields, usedFruits, yields, prices, dismis
if da ~= db then return da < db end
return a.field.id < b.field.id
end)
local suggested = 0
for _, candidate in ipairs(candidates) do
if remaining <= 0 then break end
local field = candidate.field
local auto = field.chainFree == true and field.targetSource ~= "user"
table.insert(actions, {fieldId = field.id, from = ADCropPlan.plannedFruit(field) or "", to = shortage.fruit,
hectares = field.areaHa or 0, reason = shortage.fruit, mode = auto and "auto" or "suggest"})
taken[field.id] = true
remaining = remaining - (field.areaHa or 0)
if auto or suggested < ADCropPlan.MAX_SUGGEST_PER_FRUIT then
table.insert(actions, {fieldId = field.id, from = ADCropPlan.plannedFruit(field) or "", to = shortage.fruit,
hectares = field.areaHa or 0, reason = shortage.fruit, mode = auto and "auto" or "suggest"})
taken[field.id] = true
remaining = remaining - (field.areaHa or 0)
if not auto then suggested = suggested + 1 end
end
end
end
return actions