feat(udkørsel): 'Lager til' — tvunget aflæsningssted pr. flow (siloer/egne fabrikker; første med plads og vej), XML #storeBuildings (v1.18.0.0)

This commit is contained in:
2026-09-24 05:13:09 +02:00
parent c814557ae1
commit d0485caa33
16 changed files with 169 additions and 11 deletions
+24
View File
@@ -139,6 +139,30 @@ function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointI
return nil, string.format("%d silo(er) tager varen, men AutoDrive finder ingen rute fra traktoren til dem", withSpace)
end
-- Tvunget lagermål (flowets "Lager til"): kun de valgte aflæsningsmarkører, i rækkefølge. Første der
-- tager varen, har plads til læsset og kan nås, vinder. Returnerer marker — eller nil + forklaring.
function ADLoadSwap.findForcedDumpMarker(adEnv, vehicle, fillType, liters, markerIds, isReachable)
local farmId = ADSmartPickup.getFarmId(vehicle)
local reasons = {}
for _, wayPointId in ipairs(markerIds or {}) do
local marker = adEnv.ADGraphManager:getMapMarkerByWayPointId(wayPointId)
local station = marker ~= nil and ADSmartPickup.getUnloadStationAtWayPointId(adEnv, wayPointId, farmId) or nil
local name = marker ~= nil and tostring(marker.name) or tostring(wayPointId)
if station == nil then
table.insert(reasons, name .. ": ingen aflæsning ved markøren")
elseif station.getIsFillTypeSupported ~= nil and not station:getIsFillTypeSupported(fillType) then
table.insert(reasons, name .. ": tager ikke varen")
elseif not acceptsRest(station, fillType, liters, farmId) then
table.insert(reasons, name .. ": fuld")
elseif not isReachable(wayPointId) then
table.insert(reasons, name .. ": ingen vej")
else
return marker
end
end
return nil, "valgt lager: " .. (#reasons > 0 and table.concat(reasons, "; ") or "ingen markør")
end
-- Kaldes fra Wait-logikken hvert tick; redirect(task, id) og release(vehicle) er dens egne.
-- true = traktoren er sendt til en silo (Wait-punktet er frigivet).
function ADLoadSwap.tryFromWait(adEnv, task, wait, dt, redirect, release, isReachable)
+13 -3
View File
@@ -179,7 +179,7 @@ local function findSellQuote(adEnv, vehicle, product, sellMarkers, sellAtPercent
return quotes[1], nil
end
local function findStoreMarker(adEnv, vehicle, product, capacity, sources, litersOverride)
local function findStoreMarker(adEnv, vehicle, product, capacity, sources, litersOverride, run)
local isReachable = function(markerId)
return ADWaitPool.hasRouteTo(adEnv, vehicle, markerId)
end
@@ -200,6 +200,16 @@ local function findStoreMarker(adEnv, vehicle, product, capacity, sources, liter
end
end
local liters = math.max(1, math.min(available, capacity or available))
-- "Lager til" valgt i flowet: KUN de bygninger (fx gylle -> BGA, aldrig AIO-fabrikken)
local forced = run ~= nil and ADRunsController ~= nil and ADRunsController.getStoreMarkers ~= nil and ADRunsController.getStoreMarkers(adEnv, run) or {}
if #forced > 0 and ADLoadSwap.findForcedDumpMarker ~= nil then
local chosen, why = ADLoadSwap.findForcedDumpMarker(adEnv, vehicle, product.fillType, liters, forced, isReachable)
if chosen == nil then
warnOnce(adEnv, vehicle, "forced:" .. tostring(product.name) .. ":" .. tostring(why), string.format("'%s': %s kan ikke læsses af — %s", tostring(ADRuns.vehicleLabel(vehicle)), tostring(product.name), tostring(why)))
return nil
end
return {wayPointId = chosen.id, name = tostring(chosen.name), free = liters}
end
local avoid = ADRunsController ~= nil and ADRunsController.getPickupMarkers ~= nil and ADRunsController.getPickupMarkers() or nil
local marker = ADLoadSwap.findDumpMarker(adEnv, vehicle, product.fillType, liters, nil, isReachable, ADSources.getSourcePlaceables(sources), avoid, true)
if marker == nil then
@@ -293,7 +303,7 @@ function ADOutbound.buildPlanInput(adEnv, run, vehicle)
end
end
if wantsStore(product.policy) then
product.store = findStoreMarker(adEnv, vehicle, product, capacity, sources)
product.store = findStoreMarker(adEnv, vehicle, product, capacity, sources, nil, run)
end
end
local input = {
@@ -331,7 +341,7 @@ function ADOutbound.planCargoTarget(adEnv, run, vehicle, fillType, liters)
end
end
if wantsStore(policy) then
local store = findStoreMarker(adEnv, vehicle, product, capacity, sources, liters or capacity)
local store = findStoreMarker(adEnv, vehicle, product, capacity, sources, liters or capacity, run)
if store ~= nil then
return store.wayPointId
end
+12
View File
@@ -47,6 +47,7 @@ local function copyRun(run)
sourceWayPointIds = copyList(run.sourceWayPointIds),
sourceBuildingIds = copyList(run.sourceBuildingIds),
targetBuildingIds = copyList(run.targetBuildingIds),
storeBuildingIds = copyList(run.storeBuildingIds),
products = copyProducts(run.products),
sellAtPercent = run.sellAtPercent,
storeAbovePercent = run.storeAbovePercent,
@@ -93,6 +94,7 @@ function ADRuns.createRun(store, name, kind)
sourceWayPointIds = {},
sourceBuildingIds = {},
targetBuildingIds = {},
storeBuildingIds = {},
products = {},
sellAtPercent = ADRuns.DEFAULT_SELL_AT_PERCENT,
storeAbovePercent = ADRuns.DEFAULT_STORE_ABOVE_PERCENT,
@@ -158,6 +160,7 @@ function ADRuns.updateRun(store, runId, changes)
if changes.sourceWayPointIds ~= nil then run.sourceWayPointIds = copyList(changes.sourceWayPointIds) end
if changes.sourceBuildingIds ~= nil then run.sourceBuildingIds = copyList(changes.sourceBuildingIds) end
if changes.targetBuildingIds ~= nil then run.targetBuildingIds = copyList(changes.targetBuildingIds) end
if changes.storeBuildingIds ~= nil then run.storeBuildingIds = copyList(changes.storeBuildingIds) end
if changes.products ~= nil then run.products = copyProducts(changes.products) end
if changes.sellAtPercent ~= nil then run.sellAtPercent = clampRange(changes.sellAtPercent, ADRuns.DEFAULT_SELL_AT_PERCENT, ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT) end
if changes.storeAbovePercent ~= nil then run.storeAbovePercent = clampRange(changes.storeAbovePercent, ADRuns.DEFAULT_STORE_ABOVE_PERCENT, ADRuns.MIN_STORE_ABOVE_PERCENT, ADRuns.MAX_STORE_ABOVE_PERCENT) end
@@ -182,6 +185,13 @@ function ADRuns.toggleSourceBuilding(store, runId, buildingId)
return ADRuns.updateRun(store, runId, {sourceBuildingIds = toggleInList(run.sourceBuildingIds, buildingId)})
end
-- Tvunget lagermål for udkørsel: lagerture kører KUN til disse bygninger (tom = moden vælger selv).
function ADRuns.toggleStoreBuilding(store, runId, buildingId)
local run = ADRuns.getRun(store, runId)
if run == nil then return copyStore(store) end
return ADRuns.updateRun(store, runId, {storeBuildingIds = toggleInList(run.storeBuildingIds, buildingId)})
end
function ADRuns.toggleTargetBuilding(store, runId, buildingId)
local run = ADRuns.getRun(store, runId)
if run == nil then return copyStore(store) end
@@ -350,6 +360,7 @@ function ADRuns.toRecords(store)
sources = table.concat(run.sourceWayPointIds or {}, " "),
sourceBuildings = table.concat(run.sourceBuildingIds or {}, " "),
targetBuildings = table.concat(run.targetBuildingIds or {}, " "),
storeBuildings = table.concat(run.storeBuildingIds or {}, " "),
products = ADRuns.serializeProducts(run.products),
sellAt = run.sellAtPercent,
storeAbove = run.storeAbovePercent,
@@ -392,6 +403,7 @@ function ADRuns.fromRecords(records)
sourceWayPointIds = sources,
sourceBuildingIds = parseIds(record.sourceBuildings),
targetBuildingIds = parseIds(record.targetBuildings),
storeBuildingIds = parseIds(record.storeBuildings),
products = ADRuns.parseProducts(record.products),
sellAtPercent = clampRange(record.sellAt, ADRuns.DEFAULT_SELL_AT_PERCENT, ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT),
storeAbovePercent = clampRange(record.storeAbove, ADRuns.DEFAULT_STORE_ABOVE_PERCENT, ADRuns.MIN_STORE_ABOVE_PERCENT, ADRuns.MAX_STORE_ABOVE_PERCENT),
+14
View File
@@ -147,6 +147,20 @@ function ADRunsController.getPickupMarkers()
return result
end
-- "Lager til": aflæsningsmarkører for flowets valgte lagerbygninger, i valgt rækkefølge (tom = ingen tvang).
function ADRunsController.getStoreMarkers(adEnv, run)
local result = {}
if ADBuildings == nil or run == nil then return result end
local farmId = g_currentMission ~= nil and g_currentMission.getFarmId ~= nil and g_currentMission:getFarmId() or 1
for _, buildingId in ipairs(run.storeBuildingIds or {}) do
local building = ADBuildings.find(adEnv, farmId, buildingId)
if building ~= nil and building.unloadMarker ~= nil then
table.insert(result, building.unloadMarker.id)
end
end
return result
end
-- ---- køretøjsnavne ----
ADRunsController.NAME_INTERVAL_MS = 2000
+2
View File
@@ -42,6 +42,7 @@ function ADRunsStorage.writeRecords(xmlFile, records)
-- v3: bygninger (flow-tavlen)
xmlFile:setString(key .. "#sourceBuildings", record.sourceBuildings or "")
xmlFile:setString(key .. "#targetBuildings", record.targetBuildings or "")
xmlFile:setString(key .. "#storeBuildings", record.storeBuildings or "")
xmlFile:setString(key .. "#products", record.products or "")
xmlFile:setInt(key .. "#sellAt", record.sellAt or ADRuns.DEFAULT_SELL_AT_PERCENT)
xmlFile:setInt(key .. "#storeAbove", record.storeAbove or ADRuns.DEFAULT_STORE_ABOVE_PERCENT)
@@ -69,6 +70,7 @@ function ADRunsStorage.readRecords(xmlFile)
sources = xmlFile:getString(key .. "#sources"),
sourceBuildings = xmlFile:getString(key .. "#sourceBuildings"),
targetBuildings = xmlFile:getString(key .. "#targetBuildings"),
storeBuildings = xmlFile:getString(key .. "#storeBuildings"),
products = xmlFile:getString(key .. "#products"),
sellAt = xmlFile:getInt(key .. "#sellAt"),
storeAbove = xmlFile:getInt(key .. "#storeAbove"),
+15 -4
View File
@@ -122,22 +122,25 @@ function SmartPickupFrame:fillBuildingRows(adEnv, run, role)
return
end
local chosen = {}
local ids = role == "load" and run.sourceBuildingIds or run.targetBuildingIds
local ids = role == "load" and run.sourceBuildingIds or role == "store" and run.storeBuildingIds or run.targetBuildingIds
local rowKind = role == "load" and "sourceBuilding" or role == "store" and "storeBuilding" or "targetBuilding"
for _, id in ipairs(ids or {}) do chosen[id] = true end
local count = 0
for _, building in ipairs(ADBuildings.list(adEnv, g_currentMission:getFarmId())) do
-- "Lager til": siloer og gårdens fabrikker (fx BGA) — markøren er bygningens aflæsningsmarkør
local fits = (role == "load" and building.canBeSource) or (role == "unload" and building.canBeTarget)
or (role == "store" and (building.kind == "silo" or building.kind == "factory"))
if fits then
count = count + 1
local row = self:addRow(self.ingredientPrefab, {kind = role == "load" and "sourceBuilding" or "targetBuilding", buildingId = building.id})
row:getDescendantByName("title"):setText(self:describeBuilding(building, role))
local row = self:addRow(self.ingredientPrefab, {kind = rowKind, buildingId = building.id})
row:getDescendantByName("title"):setText(self:describeBuilding(building, role == "store" and "unload" or role))
row:getDescendantByName("option"):setState(chosen[building.id] and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false)
end
end
-- valgte bygninger der ikke længere findes (solgt)
for _, id in ipairs(ids or {}) do
if ADBuildings.find(adEnv, g_currentMission:getFarmId(), id) == nil then
local row = self:addRow(self.ingredientPrefab, {kind = role == "load" and "sourceBuilding" or "targetBuilding", buildingId = id})
local row = self:addRow(self.ingredientPrefab, {kind = rowKind, buildingId = id})
row:getDescendantByName("title"):setText(string.format(" %s — %s", tostring(id), self.i18n:getText("spu_buildingGone")))
row:getDescendantByName("option"):setState(SmartPickupFrame.STATE_ON, false)
end
@@ -162,6 +165,8 @@ function SmartPickupFrame:rebuildFlowDetail(adEnv, run)
self.sellAtOption:setState(SmartPickupFrame.getStepIndex(self.sellAtSteps, run.sellAtPercent, ADRuns.DEFAULT_SELL_AT_PERCENT), false)
self.storeAboveOption:setState(SmartPickupFrame.getStepIndex(self.storeAboveSteps, run.storeAbovePercent, ADRuns.DEFAULT_STORE_ABOVE_PERCENT), false)
self.collectRoundRowOption = self:addToggleRow("collectRound", self.i18n:getText("spu_collectRound"), {self.i18n:getText("ui_no"), self.i18n:getText("ui_yes")}, run.collectRound == true)
self:addTextRow(self.i18n:getText("spu_section_store"))
self:fillBuildingRows(adEnv, run, "store")
self:fillOutboundStatusRows(adEnv, run)
else
self:addTextRow(self.i18n:getText("spu_section_to"))
@@ -193,6 +198,12 @@ function SmartPickupFrame:onClickBuilding(state, element)
if run == nil or data == nil then return end
if data.kind == "sourceBuilding" then
ADRunsController.store = ADRuns.toggleSourceBuilding(ADRunsController.store, run.id, data.buildingId)
elseif data.kind == "storeBuilding" then
ADRunsController.store = ADRuns.toggleStoreBuilding(ADRunsController.store, run.id, data.buildingId)
local updatedStore = ADRuns.getRun(ADRunsController.store, run.id)
Logging.info(SmartPickupFrame.LOG_PREFIX .. "run '%s': storeBuildings=%s", tostring(run.name), table.concat(updatedStore.storeBuildingIds or {}, " "))
frame:requestRebuild()
return
else
ADRunsController.store = ADRuns.toggleTargetBuilding(ADRunsController.store, run.id, data.buildingId)
end
+1 -1
View File
@@ -678,7 +678,7 @@ function SmartPickupFrame:onClickIngredient(state, element)
return self:onClickCollectRound(state)
elseif data ~= nil and data.kind == "direction" then
return self:onClickDirection(state)
elseif data ~= nil and (data.kind == "sourceBuilding" or data.kind == "targetBuilding") then
elseif data ~= nil and (data.kind == "sourceBuilding" or data.kind == "targetBuilding" or data.kind == "storeBuilding") then
return self:onClickBuilding(state, element)
end
self:safe(function(frame)
+1
View File
@@ -134,6 +134,7 @@
<text name="spu_stat_use" text="forbrug %s/døgn"/>
<text name="spu_stat_prod" text="prod. %s/døgn"/>
<text name="spu_stat_total" text="Bygningen i alt"/>
<text name="spu_section_store" text="— Lager til (valgfrit; intet valgt = moden vælger selv) —"/>
<text name="spu_stat_rising" text="stiger"/>
<text name="spu_tab_factories" text="Fabrikker"/>
<text name="spu_tab_silos" text="Siloer"/>
+1
View File
@@ -134,6 +134,7 @@
<text name="spu_stat_use" text="use %s/day"/>
<text name="spu_stat_prod" text="prod. %s/day"/>
<text name="spu_stat_total" text="Building total"/>
<text name="spu_section_store" text="— Store to (optional; none chosen = the mod picks) —"/>
<text name="spu_stat_rising" text="rising"/>
<text name="spu_tab_factories" text="Factories"/>
<text name="spu_tab_silos" text="Silos"/>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107">
<author>masterdraco</author>
<version>1.17.7.0</version>
<version>1.18.0.0</version>
<title>
<en>AD Smart Pickup</en>
</title>
+10 -1
View File
@@ -1,6 +1,6 @@
# AD Smart Pickup — brugermanual
Version 1.17.7 · Farming Simulator 25 · tillæg til AutoDrive
Version 1.18.0 · Farming Simulator 25 · tillæg til AutoDrive
*English version: [USER_MANUAL.md](USER_MANUAL.md)*
@@ -298,6 +298,15 @@ Bulkvarer kræver en tipvogn eller tank. Pallevarer kræver en vogn med Universa
| **Kør til lager over** | Lager-varer køres væk, når kilden er fyldt over denne andel | 50–95 %, standard 80 % |
| **Saml op på én tur** | Opsamlingsrunde, se nedenfor | Ja/Nej |
### Lager til: tvunget aflæsningssted
Under reglerne står afsnittet **Lager til** med gårdens siloer og egne fabrikker. Vælger du én eller
flere, kører lagerture kun dertil. Den første i listen, der tager varen, har plads og kan nås, får
læsset. Et eksempel er gylle, der kun må til biogasanlægget og aldrig til AIO-fabrikken. Kan ingen af
de valgte tage læsset, venter traktoren ved Wait, og loggen skriver hvorfor, fx *valgt lager: BGA500kw:
fuld*. Vælger du ingen, finder moden selv den nærmeste silo eller egne fabrik, der bruger varen.
Paller følger stadig reglen om nærmeste palleskur.
### Sådan vælges hver tur
Før hver pålæsning, og hvert femte sekund mens traktoren holder, vurderer moden:
+10 -1
View File
@@ -1,6 +1,6 @@
# AD Smart Pickup — user manual
Version 1.17.7 · Farming Simulator 25 · add-on for AutoDrive
Version 1.18.0 · Farming Simulator 25 · add-on for AutoDrive
*Dansk version: [BRUGERMANUAL.md](BRUGERMANUAL.md)*
@@ -302,6 +302,15 @@ Bulk goods need a tipper or tank. Pallet goods need a trailer with Universal Aut
| **Drive to storage above** | Store goods are moved when the source is filled above this share | 50–95 %, default 80 % |
| **Collect in one trip** | Collection round, see below | Yes/No |
### Store to: forced drop-off
Below the rules there is a **Store to** section listing the farm's silos and own factories. If you
pick one or more, storage trips only go there. The first one in the list that accepts the good, has
room and can be reached gets the load. An example is slurry that must only go to the biogas plant and
never to the AIO factory. If none of the chosen buildings can take the load, the tractor waits at
Wait, and the log says why, such as *valgt lager: BGA500kw: fuld*. If you pick none, the mod finds the
nearest silo or own factory that uses the good by itself. Pallets still follow the nearest pallet shed rule.
### How each trip is chosen
Before each loading, and every five seconds while the tractor waits, the mod checks:
+25
View File
@@ -44,5 +44,30 @@ check("LS2 fremmed anlæg aldrig", L.isStoreTarget({owningPlaceable = foreignBio
check("LS2 hjemmet selv aldrig", L.isStoreTarget({owningPlaceable = biogas}, SLURRY, {owningPlaceable = biogas}, true), false)
g_currentMission = nil
-- LS3: tvunget lagermål — kun de valgte markører, i rækkefølge; første der tager varen, har plads og kan nås
do
local stations = {
[101] = {accepts = {[SLURRY] = true}, free = 0}, -- BGA fuld
[102] = {accepts = {[SLURRY] = true}, free = 900000}, -- gylletank
[103] = {accepts = {[MILK] = true}, free = 900000}, -- tager ikke gylle
}
for _, st in pairs(stations) do
st.getIsFillTypeSupported = function(self, ft) return self.accepts[ft] == true end
st.getFreeCapacity = function(self) return self.free end
end
ADSmartPickup = {getFarmId = function() return 1 end, getUnloadStationAtWayPointId = function(_, id) return stations[id] end}
local adEnv = {ADGraphManager = {getMapMarkerByWayPointId = function(_, id) return {id = id, name = "m" .. id} end}}
local vehicle = {}
local all = function() return true end
check("LS3 fuld BGA springes over -> tank", L.findForcedDumpMarker(adEnv, vehicle, SLURRY, 20000, {101, 102}, all).id, 102)
stations[101].free = 500000
check("LS3 BGA med plads vælges først", L.findForcedDumpMarker(adEnv, vehicle, SLURRY, 20000, {101, 102}, all).id, 101)
local none, why = L.findForcedDumpMarker(adEnv, vehicle, SLURRY, 20000, {103}, all)
check("LS3 intet valgt mål tager varen -> nil", none, nil)
check("LS3 forklaring", why ~= nil and why:find("valgt", 1, true) ~= nil, true)
check("LS3 ikke nåelig -> næste", L.findForcedDumpMarker(adEnv, vehicle, SLURRY, 20000, {101, 102}, function(id) return id ~= 101 end).id, 102)
ADSmartPickup = nil
end
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)
+17
View File
@@ -582,5 +582,22 @@ do
sources[31], sources[32], products[31], products[32] = nil, nil, nil, nil
end
-- O-forced: "Lager til" valgt -> lagerturen går til det valgte mål, ikke moden egen silo-valg
do
sources[41] = {kind = "silo", wayPointId = 41, station = {name = "gylleSilo"}, name = "Gyllesilo"}
products[41] = {{fillType = SUGAR, name = "SUGAR", title = "Sukker", available = 11000000, level = 11000000, capacity = 12000000, isPallet = false}}
local vF = newVehicle("Gyllevogn", 0, 0, 20000)
runs[vF] = outboundRun(79, {41}, {{fillType = "SUGAR", policy = "store"}})
runs[vF].forcedMarkers = {31}
ADRunsController.getStoreMarkers = function(_, run) return run.forcedMarkers or {} end
local forcedCalls = 0
ADLoadSwap.findForcedDumpMarker = function(_, _, _, _, ids) forcedCalls = forcedCalls + 1 return {id = ids[1], name = "BGA", markerIndex = 99} end
dumpMarker = mStore
ADOutbound.choosePickup(adEnv, vF)
check("O-forced valgt mål brugt", forcedCalls > 0, true)
check("O-forced tur-mål = BGA", ADOutbound.getTripFor(vF) and ADOutbound.getTripFor(vF).targetWayPointId, 31)
ADRunsController.getStoreMarkers, ADLoadSwap.findForcedDumpMarker = nil, nil
end
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)
+15
View File
@@ -307,5 +307,20 @@ do
check("RN ukendt køretøj", names.v9, nil)
end
-- RS: tvunget lagermål — storeBuildingIds (toggle, kopi, records roundtrip)
do
local store, run = ADRuns.createRun(ADRuns.newStore(), "Slurry", "outbound")
check("RS tom som standard", #run.storeBuildingIds, 0)
store = ADRuns.toggleStoreBuilding(store, run.id, "BGA500kw")
store = ADRuns.toggleStoreBuilding(store, run.id, "tank2")
check("RS to valgt", table.concat(ADRuns.getRun(store, run.id).storeBuildingIds, ","), "BGA500kw,tank2")
store = ADRuns.toggleStoreBuilding(store, run.id, "tank2")
check("RS fravalgt igen", table.concat(ADRuns.getRun(store, run.id).storeBuildingIds, ","), "BGA500kw")
local records = ADRuns.toRecords(store)
check("RS record", records[1].storeBuildings, "BGA500kw")
local back = ADRuns.fromRecords(records)
check("RS roundtrip", table.concat(ADRuns.getRun(back, run.id).storeBuildingIds, ","), "BGA500kw")
end
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)
+8
View File
@@ -700,6 +700,14 @@ local rowIn = ADRunsController.getFlowRow(adEnv, ADRuns.getRun(ADRunsController.
check("CF5 forsyning fra = alle siloer", rowIn.fromAllSilos, true)
check("CF5 forsyning til", table.concat(rowIn.toNames, ","), "Kostald 1,Sukkerfabrik")
check("CF5 forsyning auto-varer", rowIn.productAuto, true)
-- SB: "Lager til" — valgte bygninger -> deres aflæsningsmarkører (i valgt rækkefølge; ukendte udelades)
do
local sbRun = ADRunsController.createRun("Gylle", "outbound")
ADRunsController.updateRun(sbRun.id, {storeBuildingIds = {"mill", "findes-ikke", "barn1"}})
check("SB markører", table.concat(ADRunsController.getStoreMarkers(adEnv, ADRuns.getRun(ADRunsController.store, sbRun.id)), ","), "77,94")
ADRunsController.updateRun(sbRun.id, {storeBuildingIds = {}})
check("SB tom = ingen tvang", #ADRunsController.getStoreMarkers(adEnv, ADRuns.getRun(ADRunsController.store, sbRun.id)), 0)
end
ADBuildings = nil; ADSources = nil; ADOutbound = nil
-- RC-navne: køretøjer får AD-førernavn efter forløbet; ude af forløb -> modelnavnet igen