Moduł:Lista wikigrantów

Wikimedia Polska, polski partner Fundacji Wikimedia.
Przejdź do nawigacji Przejdź do wyszukiwania

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Lista wikigrantów/opis

local p = {}

-- Limity finansowania na poszczególne lata
local limits = {
	["2024"] = 25000,
	["2023"] = 20000,
	["2022"] = 20000,
	["2021"] = 20000,
	["2020"] = 12000,
	["2019"] = 12000,
	["2018"] = 15000,
	["2017"] = 20000,
	["2016"] = 20000,
	["2015"] = 25000,
	["2014"] = 30000,
	["2013"] = 5000,
}

-- Zwraca liczbę sformatowaną po polsku (z przecinkiem)
function formatNumber(num)
	if num == nil then
		return nil
	end
	num = (string.gsub(string.format('%.2f', num), '%.', ','))
	
	-- Dodaj separatory tysięcy
	while true do  
		num, k = string.gsub(num, "^(-?%d+)(%d%d%d)", '%1 %2')
		if k == 0 then
			break
		end
	end
	return num
end

-- Sprawdza, czy wniosek został zaakceptowany
-- (i np. należy wliczyć do przyznanych środków)
function isAccepted(status)
	return status == 'realizowany' or status == 'wykonany' or status == 'niezrealizowany'
end

-- Wczytuje stronę wniosku i zwraca wartości poszczególnych pól
function readApplicationPage(pageTitle)
	local title = mw.title.new(pageTitle, '')
	local content = title:getContent()
	if content == nil then
		return nil
	end
	
	-- Usuń z przetwarzanej treści wszystkie komentarze HTML
	content = (mw.ustring.gsub(content, '<!%-%-.-%-%->', ''))
	
	-- Spróbuj dopasować tekstową nazwę użytkownika, a jeśli się nie uda, to wikilink do niej
	local user = mw.ustring.match(content, '| *nazwa użytkownika *=%s*([^%[%]|}]-)%s*[|}]')
	user = user or mw.ustring.match(content, '| *nazwa użytkownika *=%s*(%b[])')
	local userWiki = mw.ustring.match(content, '| *wiki użytkownika *=%s*([^%[%]|}]-)%s*[|}]')
	userWiki = userWiki or mw.ustring.match(content, '| *wiki użytkownika *=%s*(%b[])')
	
	-- Pobierz opis i wytnij z niego linki zewnętrzne
	local purpose = mw.ustring.match(content, '| *na *=%s*(.-)%s*[|}]')
	purpose = purpose or mw.ustring.match(content, '| *dotyczący *=%s*(.-)%s*[|}]')
	if purpose ~= nil then
		purpose = (mw.ustring.gsub(purpose, '%[[^ ]+ (.-)%]', '%1'))
	end
	
	local status = mw.ustring.match(content, '| *status *=%s*(.-)%s*[|}]')
	
	-- Pobierz kwoty i przekonwertuj na gołe liczby z kropką dziesiętną
	local declaredValue = mw.ustring.match(content, '| *suma *=%s*(.-)%s*[|}]')
	if declaredValue ~= nil then
		declaredValue = (mw.ustring.gsub(declaredValue, '[^%d,]', ''))
		declaredValue = (mw.ustring.gsub(declaredValue, ',', '.'))
		declaredValue = tonumber(declaredValue)
	end
	local actualValue = mw.ustring.match(content, '| *rozliczono *=%s*(.-)%s*[|}]')
	if actualValue ~= nil then
		actualValue = (mw.ustring.gsub(actualValue, '[^%d,]', ''))
		actualValue = (mw.ustring.gsub(actualValue, ',', '.'))
		actualValue = tonumber(actualValue)
	end
	
	return {
		["user"] = user,
		["userWiki"] = userWiki,
		["purpose"] = purpose,
		["status"] = status,
		["declaredValue"] = declaredValue,
		["actualValue"] = actualValue
	}
end

-- Przygotowuje wiersz danych do wyświetlenia
-- (wykonuje operacje na wartościach komórek, aby nadawały się do wyświetlenia)
function prepareForDisplay(rawData)
	local user = rawData.user
	if string.find(user, '[[', 1, true) == nil then
		-- Przygotuj link do strony użytkownika na podst. nazwy projektu
		local wg = require('Moduł:Wikigrant')
		user = wg.parseUser(user, rawData.userWiki, true)
	else
		-- Upewnij się, że wyświetlona zostanie tylko nazwa użytkownika (a nie np. cały link interwiki)
		local linkTarget, plainName = mw.ustring.match(user, '%[%[(.+:([^:|%]]+))[|%]]')
		user = '[[' .. linkTarget .. '|' .. plainName .. ']]'
	end
	
	local value = nil
	local financialStatus = nil
	
	if isAccepted(rawData.status) then
		value = formatNumber(rawData.actualValue)
		financialStatus = 'rozliczony'
		if value == nil then
			value = '(' .. formatNumber(rawData.declaredValue) .. ')'
			financialStatus = 'oczekuje'
		end
	end
	
	return {
		["user"] = user,
		["purpose"] = rawData.purpose,
		["status"] = rawData.status,
		["financialStatus"] = financialStatus,
		["value"] = value,
	}
end

-- Tworzy nagłówek tabeli
function makeListHeader()
	return [=[
{| class="wikitable" style="width:100%"
|-
! style="width:10%" | Numer wikigrantu
! style="width:10%" | Grantobiorca
! style="width:50%" | Cel
! style="width:10%" | Status wniosku
! style="width:10%" | Status rozliczenia
! style="width:10%" | Wartość (PLN)
]=]
end

-- Tworzy wiersz tabeli
function makeListRow(wgNumber, userLink, purpose, applicationStatus, financialStatus, value)
	local row = {
		'|-',
		'| [[' .. wgNumber .. ']]',
		'| ' .. userLink,
		'| ' .. purpose,
		'| ' .. applicationStatus,
		'| style="text-align:center;" | ' .. (financialStatus or '–––'),
		'| style="text-align:right;" | ' .. (value or '–––'),
	}
	return table.concat(row, '\n') .. '\n'
end

function makeEmptyStateListRow(year)
	return "|-\n| colspan='6' style='text-align:center;' | ''W roku " .. year .. " nie złożono jeszcze żadnego wniosku.''\n"
end

-- Tworzy stopkę tabeli
function makeListFooter(limit, totalGranted, totalInvoiced)
	local footer = {
		'|-',
		'! colspan="5" style="text-align:right" | Rozliczona SUMA',
		'! style="text-align:right; font-size:1.75em; color:red;" | ' .. formatNumber(totalInvoiced),
		'|-',
		'! colspan="5" style="text-align:right" | Ogółem przyznano',
		'! style="text-align:right; font-size:1.75em;" | ' .. formatNumber(totalGranted),
		'|-',
		'! colspan="5" style="text-align:right" | Nieprzyznane środki',
		'! style="text-align:right; font-size:1.75em; color:green;" | ' .. formatNumber(limit - totalGranted),
		'|-',
		'! colspan="5" style="text-align:right" | Oczekujące na rozliczenie',
		'! style="text-align:right; font-size:1.75em;" | ' .. formatNumber(totalGranted - totalInvoiced),
		'|}'
	}
	return table.concat(footer, '\n') .. '\n'
end

function p.lista(frame)
	local year = frame.args.rok
	local printToday = (frame.args.data or 'nie') == 'tak'
	if year == nil or #year == 0 then
		return '<span style="color:#f00; font-weight:bold">BŁĄD: Nie podano roku, dla którego wyświetlić listę wikigrantów.</span>'
	end
	
	local number = 1
	
	local limit = limits[year] or 0
	local sumTotal = 0
	local sumWithInvoice = 0

	local output = {}
	table.insert(output, makeListHeader())
	while true do
		local wgPage = 'WG ' .. year .. '-' .. number
		local data = readApplicationPage(wgPage)
		if data == nil then
			break
		end
		
		local row = prepareForDisplay(data)
		local statusBox = frame:expandTemplate{ title = 'Status wniosku', args = { row.status, ['tabela'] = 'tak' } }
		table.insert(output, makeListRow(wgPage, row.user, row.purpose, statusBox, row.financialStatus, row.value))
		number = number + 1
		
		if isAccepted(data.status) then
			sumTotal = sumTotal + (data.actualValue or data.declaredValue or 0)
			sumWithInvoice = sumWithInvoice + (data.actualValue or 0)
		end
	end
	
	if number == 1 then
		table.insert(output, makeEmptyStateListRow(year))
	end
	
	table.insert(output, makeListFooter(limit, sumTotal, sumWithInvoice))
	
	if printToday then
		local l = mw.getContentLanguage()
		local date = l:formatDate('j xg Y', nil, true)
		local time = l:formatDate('H:i', nil, true)
		table.insert(output, '<div style="text-align:right; font-size:0.85em; font-style:italic; margin-top:-1em;">Wygenerowano ' .. date .. ' o ' .. time .. '</div>')
	end
	
	return table.concat(output)
end

return p