76f51c7be7
Rent lager-flow viste 'sælg fra 90 %' / 'pris >= 90 %' selv om det aldrig sælger. Guidens Regler-trin, resuméet og statuslinjen viser nu kun salgsgrænser ved salg og lagergrænsen ved lager (v1.60.11.0).
151 lines
7.2 KiB
Lua
151 lines
7.2 KiB
Lua
-- Smart Pickup — fanen Flows
|
|
-- Tavlen (én række pr. flow, det valgte markeret med ">") bruges af fanerne Oversigt og Flows; Flows-fanens
|
|
-- resumé og guiden "Opsæt flow" ligger i gui/SmartPickupFlowGuide.lua. Her også bygnings-teksten og de
|
|
-- gamle klik-callbacks for retning/bygninger.
|
|
-- Funktionerne lægges på SmartPickupFrame (indlæses efter SmartPickupFrame.lua).
|
|
|
|
-- ---- tavlen ----
|
|
|
|
local function joinOr(list, empty)
|
|
if #list == 0 then return empty end
|
|
return table.concat(list, " + ")
|
|
end
|
|
|
|
-- Én række i Oversigt: {flow, varer, fra, til, traktorer "kører/i alt", status}.
|
|
-- Status = advarsel (!!), ellers begrundelse, ellers flowets regel.
|
|
function SmartPickupFrame:flowCells(adEnv, run)
|
|
local row = ADRunsController.getFlowRow(adEnv, run)
|
|
local i18n = self.i18n
|
|
local products
|
|
if row.productAuto then
|
|
products = i18n:getText("spu_flow_needBased")
|
|
else
|
|
local titles = {}
|
|
for _, name in ipairs(row.productNames) do
|
|
local index = g_fillTypeManager:getFillTypeIndexByName(name)
|
|
local title = index ~= nil and g_fillTypeManager.getFillTypeTitleByIndex ~= nil and g_fillTypeManager:getFillTypeTitleByIndex(index) or name
|
|
table.insert(titles, tostring(title))
|
|
end
|
|
products = joinOr(titles, i18n:getText("spu_flow_noProducts"))
|
|
end
|
|
local missing = {}
|
|
for _, name in ipairs(row.missing) do missing[name] = true end
|
|
local function mark(names)
|
|
local out = {}
|
|
for _, name in ipairs(names) do table.insert(out, missing[name] and (name .. " !") or name) end
|
|
return out
|
|
end
|
|
local from, to
|
|
if row.kind == "outbound" then
|
|
from = ADFlowView.joinCounted(mark(row.fromNames), " + ", i18n:getText("spu_flow_noSource"))
|
|
local seen, policies = {}, {}
|
|
for _, policy in ipairs(row.policies) do
|
|
if not seen[policy] then seen[policy] = true; table.insert(policies, i18n:getText("spu_policy_" .. policy)) end
|
|
end
|
|
to = joinOr(policies, i18n:getText("spu_flow_noProducts"))
|
|
else
|
|
from = i18n:getText("spu_from_allSilos")
|
|
to = ADFlowView.joinCounted(mark(row.toNames), " + ", i18n:getText("spu_flow_noTarget"))
|
|
end
|
|
local rule
|
|
if row.kind == "outbound" then
|
|
local sells, stores = ADFlowView.policyUse(row.policies)
|
|
local parts = {}
|
|
if sells then table.insert(parts, string.format(i18n:getText("spu_flow_ruleSell"), row.sellAtPercent or 90)) end
|
|
if stores then table.insert(parts, string.format(i18n:getText("spu_flow_ruleStore"), row.storeAbovePercent or 80)) end
|
|
rule = table.concat(parts, ", ")
|
|
if row.collectRound then rule = rule .. ", " .. i18n:getText("spu_flow_round") end
|
|
else
|
|
rule = row.loops ~= nil and row.loops > 0 and string.format(i18n:getText("spu_flow_ruleInLoops"), row.loops) or i18n:getText("spu_flow_ruleIn")
|
|
end
|
|
local status = rule
|
|
if row.warning ~= nil then
|
|
status = "!! " .. row.warning
|
|
elseif row.reason ~= nil then
|
|
status = row.reason
|
|
end
|
|
local name = (run.id == self.selectedRunId and "> " or "") .. tostring(run.name)
|
|
return {name, products, from, to, string.format("%d/%d", row.running, row.total), status}
|
|
end
|
|
|
|
-- Hele rækken klikbar med musen (Bitmap-rækker har ingen onClick). Klikket gemmes kun som
|
|
-- pendingClick; handlingen køres i update(), fordi genopbygningen sletter netop denne række.
|
|
local MOUSE_LEFT = Input ~= nil and Input.MOUSE_BUTTON_LEFT or 1
|
|
|
|
local function isInside(element, posX, posY)
|
|
local position, size = element.absPosition, element.absSize
|
|
if position == nil or size == nil then return false end
|
|
return posX >= position[1] and posX <= position[1] + size[1] and posY >= position[2] and posY <= position[2] + size[2]
|
|
end
|
|
|
|
function SmartPickupFrame:makeRowClickable(row, action)
|
|
local frame = self
|
|
local baseMouseEvent = row.mouseEvent
|
|
row.mouseEvent = function(element, posX, posY, isDown, isUp, button, eventUsed)
|
|
local used = baseMouseEvent(element, posX, posY, isDown, isUp, button, eventUsed)
|
|
-- også inden for listens synlige udsnit: rækker scrollet ud af syne må ikke fange klik
|
|
-- klik tæller inde i rækkens eget layout (listen eller redigeringsvinduet); listen er død mens vinduet er åbent
|
|
local layout = element.spuLayout or frame.boxLayout
|
|
local blockedByPanel = frame.editPanelOpen and layout == frame.boxLayout
|
|
if not used and not eventUsed and not blockedByPanel and isUp and button == MOUSE_LEFT and (element.getIsVisible == nil or element:getIsVisible())
|
|
and isInside(element, posX, posY) and isInside(layout, posX, posY) then
|
|
frame.lastClickX = posX
|
|
frame.pendingClick = action
|
|
return true
|
|
end
|
|
return used
|
|
end
|
|
end
|
|
|
|
-- Fanen Oversigt: alle flows som tabel, grupperet Ind/Ud efter navn. Klik på et flow = redigér det.
|
|
function SmartPickupFrame:fillOverviewRows(adEnv)
|
|
self.overviewRows = {}
|
|
local i18n = self.i18n
|
|
self:addTextRow(i18n:getText("spu_overview_hint"))
|
|
self:addCellRow(self.flowPrefab, {i18n:getText("spu_col_flow"), i18n:getText("spu_col_goods"), i18n:getText("spu_col_from"), i18n:getText("spu_col_to"), i18n:getText("spu_col_tractors"), i18n:getText("spu_col_status")})
|
|
for _, group in ipairs(ADFlowView.boardGroups(ADRunsController.store.runs)) do
|
|
self:addTextRow(i18n:getText(group.kind == "outbound" and "spu_board_outbound" or "spu_board_supply"))
|
|
for _, run in ipairs(group.runs) do
|
|
local cells = self:addCellRow(self.flowPrefab, self:flowCells(adEnv, run))
|
|
if cells[1] ~= nil and cells[1].parent ~= nil then
|
|
local runId = run.id
|
|
self:makeRowClickable(cells[1].parent, function(frame) frame:openFlow(runId) end)
|
|
end
|
|
table.insert(self.overviewRows, {runId = run.id, cells = cells})
|
|
end
|
|
end
|
|
if #ADRunsController.store.runs == 0 then
|
|
self:addTextRow(i18n:getText("spu_noRuns"))
|
|
end
|
|
end
|
|
|
|
function SmartPickupFrame:refreshOverview(adEnv)
|
|
for _, entry in ipairs(self.overviewRows or {}) do
|
|
local run = ADRuns.getRun(ADRunsController.store, entry.runId)
|
|
if run ~= nil then
|
|
SmartPickupFrame.setCells(entry.cells, self:flowCells(adEnv, run))
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ---- detail-blok ----
|
|
|
|
-- "Kostald 1 (stald) — markør 'cow 1 milk' 12 m" / "… — INGEN MARKØR inden for 40 m"
|
|
function SmartPickupFrame:describeBuilding(building, role)
|
|
local markers = ADBuildings.getMarkers ~= nil and ADBuildings.getMarkers(building, role) or {}
|
|
local kindText = self.i18n:getText("spu_source_kind_" .. tostring(building.kind))
|
|
if markers[1] == nil then
|
|
return string.format(" %s (%s) — %s", building.name, kindText, self.i18n:getText("spu_noMarker"))
|
|
end
|
|
-- kort form, så flere markører kan stå på én række: "Cow Barn (large) — Cow 1 Milk 6 m · Cow 1 Slurry 4 m"
|
|
local parts = {}
|
|
for _, marker in ipairs(markers) do
|
|
table.insert(parts, string.format(self.i18n:getText("spu_markerAt"), marker.name, marker.distance))
|
|
end
|
|
return string.format(" %s — %s", building.name, table.concat(parts, " · "))
|
|
end
|
|
|
|
-- ---- callbacks ----
|
|
|
|
|