feat(kæde): manglende led forklares i Kræver handling, fanen og som besked
problemText giver årsag og råd for køb/flaskehals/kredsløb og 'slukket af dig' (userOff-kopi på ADChain.last); modellens problemer får need. Fanen Kæder viser teksten som rød tekstrække under varen (foldet ud). Kræver handling får én rød post pr. kæde (højst 2, score 3500+alvor mellem rød tom og rød fuld); klik åbner fanen med kæden foldet ud. Engangsbesked pr. nyt led (rod|vare|art) kun fra tick, ikke i opstartsfristen eller på delvise data/ufærdig markscanning. Manualer og CHANGELOG opdateret.
This commit is contained in:
@@ -279,15 +279,75 @@ end
|
||||
-- "Kræver handling" fra kæden (ADChain.last): ÉT gult punkt "Kæde: N forslag" (klik -> fanen Kæder), så
|
||||
-- forslagene ikke fylder listen. Rangeres under alle røde punkter (>= 3000), øverst blandt de gule, over "sælg nu".
|
||||
ADStorageStats.CHAIN_SCORE = 2000
|
||||
-- Manglende led: én rød post pr. kæde ("Brød mangler et led: Mel"), højst MAX_CHAIN_PROBLEMS (resten står i
|
||||
-- fanen Kæder; den sidste viste post får more = antal skjulte). Score CHAIN_PROBLEM_SCORE + alvor (0-99): under
|
||||
-- "rød tom" (3900-4000: løber tør inden et døgn), over "rød fuld" (3000-3100). Alvor = manglende andel af behovet;
|
||||
-- kredsløb (kan ikke beregnes) = 99.
|
||||
ADStorageStats.CHAIN_PROBLEM_SCORE = 3500
|
||||
ADStorageStats.MAX_CHAIN_PROBLEMS = 2
|
||||
ADStorageStats.MAX_CHAIN_PROBLEM_ITEMS = 2
|
||||
|
||||
local function severity(problems)
|
||||
local missing, need = 0, 0
|
||||
for _, problem in ipairs(problems) do
|
||||
if problem.kind == "cycle" then return 99 end
|
||||
missing, need = missing + (problem.detail or 0), need + (problem.need or 0)
|
||||
end
|
||||
if need <= 0 then return 99 end
|
||||
return math.floor(99 * math.min(1, missing / need))
|
||||
end
|
||||
|
||||
local function problemEntry(root, problems, titleOf)
|
||||
local items, seen = {}, {}
|
||||
for _, problem in ipairs(problems) do
|
||||
local title = titleOf(problem.fillType)
|
||||
if not seen[title] then
|
||||
seen[title] = true
|
||||
table.insert(items, title)
|
||||
end
|
||||
end
|
||||
local shown = {}
|
||||
for index = 1, math.min(#items, ADStorageStats.MAX_CHAIN_PROBLEM_ITEMS) do shown[index] = items[index] end
|
||||
local itemsText = table.concat(shown, ", ")
|
||||
if #items > #shown then itemsText = itemsText .. " +" .. tostring(#items - #shown) end
|
||||
local rootTitle = titleOf(root.name)
|
||||
return {kind = "chainProblem", level = "red", score = ADStorageStats.CHAIN_PROBLEM_SCORE + severity(problems), rootKey = root.key,
|
||||
rootTitle = rootTitle, itemsText = itemsText, text = rootTitle .. ": " .. itemsText}
|
||||
end
|
||||
|
||||
local function chainProblemEntries(last)
|
||||
local titles = last.titles or {}
|
||||
local titleOf = function(name) return tostring(titles[name] or name) end
|
||||
local byRoot = {}
|
||||
for _, problem in ipairs(last.chain ~= nil and last.chain.problems or {}) do
|
||||
if problem.rootKey ~= nil then
|
||||
byRoot[problem.rootKey] = byRoot[problem.rootKey] or {}
|
||||
table.insert(byRoot[problem.rootKey], problem)
|
||||
end
|
||||
end
|
||||
local entries = {}
|
||||
for _, root in ipairs(last.chain ~= nil and last.chain.roots or {}) do
|
||||
if byRoot[root.key] ~= nil then table.insert(entries, problemEntry(root, byRoot[root.key], titleOf)) end
|
||||
end
|
||||
entries = ADStorageStats.rankAttention(entries)
|
||||
local result = {}
|
||||
for index = 1, math.min(#entries, ADStorageStats.MAX_CHAIN_PROBLEMS) do result[index] = entries[index] end
|
||||
if #entries > #result then result[#result].more = #entries - #result end
|
||||
return result
|
||||
end
|
||||
|
||||
function ADStorageStats.chainEntries(last)
|
||||
if last == nil then return {} end
|
||||
local result = chainProblemEntries(last)
|
||||
local count = 0
|
||||
for _, action in ipairs(last ~= nil and last.actions or {}) do
|
||||
for _, action in ipairs(last.actions or {}) do
|
||||
if action.mode == "suggest" then count = count + 1 end
|
||||
end
|
||||
if count == 0 then return {} end
|
||||
return {{kind = "chainSuggest", level = "yellow", score = ADStorageStats.CHAIN_SCORE, count = count,
|
||||
text = string.format("Kæde: %d", count)}}
|
||||
if count > 0 then
|
||||
table.insert(result, {kind = "chainSuggest", level = "yellow", score = ADStorageStats.CHAIN_SCORE, count = count,
|
||||
text = string.format("Kæde: %d", count)})
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- Varepunkterne (allerede rangeret) + kædens punkter, samme loft.
|
||||
|
||||
Reference in New Issue
Block a user