Module:USASpending-recent-awards

From Defense Knowledge

Documentation for this module may be created at Module:USASpending-recent-awards/doc

local p = {}

    local function checkLastUpdated()
        local check = mw.ext.externalData.getWebData {
           url = 'https://api.usaspending.gov/api/v2/awards/last_updated/',
           format = 'JSON',
           ['cache seconds'] = 3600
        }
        local lastUpdate = check.last_updated
        return lastUpdate
    end

    -- Handle URL
    local baseUrl = 'https://api.usaspending.gov'
    local queryUrl = '/api/v2/search/spending_by_category/recipient/'
    local apiUrl = baseUrl .. queryUrl
    local lang = mw.language.getContentLanguage()

    -- Function to format number with two decimals and group separator
    function formatNumberWithSeparator(num)

       local integerPart = math.floor(num)
       local decimalPart = string.format("%.2f", num - integerPart):sub(3) 

       -- Format the integer part with group separators
       local formattedInteger = lang:formatNum(integerPart)

       -- Combine integer part and decimal part
       return formattedInteger .. "." .. decimalPart

    end

    -- Helper date formatter
    local function formatDate(frame, timestamp)
        local formattedDate = frame:preprocess("{{#time: M j, Y|" .. timestamp .. "}}")
        return formattedDate
    end


function p.awardsByPeriod(frame)

    local args = frame.args

    -- Function to autocreate pages with preloaded data
    local function autoCreateWithPreload(frame, autopage, content)
        local autocreate =  frame:callParserFunction(
		'#createpageifnotex',
          autopage,
          content
	    )
        return autocreate
    end

    -- Set parameters
    local startDate = args.from or os.date("%Y-%m-%d", os.time() - 3 * 24 * 60 * 60)
    local endDate = args.to or os.date("%Y-%m-%d")
    local pageFromTitle = frame:preprocess('{{#titleparts:{{FULLPAGENAME}}||-1}}') 
    local pageNumber = args.page or pageFromTitle or 1
    local limit = args.limit or 100

    -- Handle request body
 
    local postBody = '{"filters":{"time_period":[{"start_date":"' .. startDate .. '","end_date":"' .. endDate .. '"}]},"recipient_id": ".*P$", "category":"recipient","limit":' .. limit .. ',"page":' .. pageNumber .. '}'

    -- Fetch data from the API
    local data = mw.ext.externalData.getWebData {
        url = apiUrl,
        format = 'JSON',
        ['post data'] = postBody, 
        data = {
            json = '__json'
        },
        ['cache seconds'] = 86400
    }

    -- Create an HTML structure
    local output = {}

    table.insert(output, '<div class="mb-3 date-range-container font-weight-bold">' 
          .. formatDate(frame, startDate) 
          .. ' — ' 
          .. formatDate(frame, endDate)
          .. '</div>'
    )
    table.insert(output, '<small class="text-muted">Last updated on: ' .. checkLastUpdated() .. '</small>')

 local results = data.json.results or {}

if results then
    local recipient_id = results.recipient_id
    local name = results.name or "N/A"
    local amount = results.amount or 0

    table.insert(output, '<table class="w-100 wikitable sortable">')
    table.insert(output, '<tr>')
    table.insert(output, '<th>Recipient</th>')
    table.insert(output, '<th>Amount</th>')
    table.insert(output, '</tr>')

    for _, recipient in ipairs(results) do
        local auto = recipient.recipient_id or ""
        local isParent = false

        if auto ~= "" and string.match(auto, "-P$") then
            isParent = true
        end

        local printval = ''
        if isParent then
            printval = '[[' .. auto .. '|' .. recipient.name .. ']]'
        else
            printval = '<span title="' .. auto .. '">' .. recipient.name .. '</span>'
        end

        if auto ~= "" then
            table.insert(output, '<tr>')
            table.insert(output, '<td>' .. printval .. '</td>')
            table.insert(output, '<td align="right" data-sort="' .. recipient.amount .. '">' 
                .. formatNumberWithSeparator(recipient.amount) .. '</td>')
            if isParent then
                table.insert(output, autoCreateWithPreload(frame, auto, '{{Recipient}}'))
            end
            table.insert(output, '</tr>')
        end
    end

    table.insert(output, '</table>')
end

local result = table.concat(output, "\n")

    return result
end

return p