Page cover image

Accessible files

Here you can find all the files which can be edite to make the asset compatible with your server.

config.lua
Config = {}
Config.Core = "ESX"
Config.BrutalNotify = true -- Buy here: (4€+VAT) https://store.brutalscripts.com | Or set up your own notify >> cl_utils.lua
Config.Locale = "en" -- check locales/xy.json

Config.MenuOpenCommand = 'billing'
Config.MenuOpenKey = ''

Config.AdminGroups = {'superadmin', 'admin', 'mod'}
Config.InvoiceDistance = 15
Config.AutoDeletePaidInvoices = false
Config.DeletePaidInvoicesEvery = 30 -- How often it should delete the paid invoices (in minutes)
Config.PenaltyPercent = 10 -- If the player does not pay the bill on time
Config.Vat = 27 -- The global VAT percent

Config.InspectCitizenSocieties = { -- Which jobs have access to check the players' bills
    ["police"] = true,
    ["ambulance"] = true
}

Config.SocietyAccessRanks = { -- Which ranks of the society have access to Society Invoices and City Invoices
    ['police'] = {'boss','chief'},
    ['ambulance'] = {'boss','chief'},
}

Config.BillsList = {
    ['police'] = {
        {label = 'High Speed', value = 550},
        {label = 'Parking on bridge', value = 1200},
        {label = 'Jumping a red light', value = 250},
        {label = 'Driving dangerously', value = 750},
        {label = 'Reckless driving', value = 1000},
        {label = 'Custom', value = nil},
    },
    ['ambulance'] = {
        {label = 'Ambulance Ride', value = 550},
        {label = 'Medical treatment 1', value = 750},
        {label = 'Medical treatment 2', value = 1200},
        {label = 'Medical treatment 3', value = 250},
        {label = 'Medical treatment 4', value = 400},
        {label = 'Custom', value = nil},
    },
}

Config.Notify = { 
    [1] = {"Billing", "You have paid all your invoices!", 5000, "info"},
    [2] = {"Billing", "You have paid an invoice!", 5000, "success"},
    [3] = {"Billing", "You have successfully created an invoice!", 5000, "success"},
    [4] = {"Billing", "You have successfully canceled the player's invoice!", 5000, "success"},
    [5] = {"Billing", "You have received a new invoice!", 5000, "info"},
    [6] = {"Billing", "You don't have enough money!", 5000, "error"},
}

Config.defaultTheme = {
    background = { background = "#2e3136" },
    openMenu = {
        header = {
            color = "white"
        },
        card = {
            background = { background = "#575c63" },
            i = { color = "#EEEEEE" },
            p = { color = "#EEEEEE" }
        }
    },
    invoiceMenu = {
        header = { color = "white" },
        columns = {
            header = { color = "white" },
            pTitle = { color = "#b0b0b0" },
            hr = { background = "grey" },
            input = {
                background = "#404449",
                color = "white"
            },
            p = { color = "white" },
            background = { background = "#43464b" },
            card = { background = "#565a62" },
            buttonsColor = {
                background = "#686D76",
                color = "white",
                hover = "#DC5F00",
                fontSize = "1vh",
            },
            pageButtons = {
                background = "#686D76",
                color = "white",
                active = "#686D76",
                hover = "#DC5F00"
            },
            cancelButtonColor = {
                background = "#ff4545",
                color = "white",
                hover = "pink"
            }
        }
    },
    payRef = {
        header = { color = "white" },
        background = { background = "#43464b" },
        button = { background = "#686D76", color = "white", hover = "#DC5F00" },
        input = {
            placeholderColor = "white",
            background = "#686D76",
            color = "white"
        },
        pTitle = { color = "#b0b0b0" },
        pValue = {
            background = "#686D76",
            color = "white"
        }
    },
    create = {
        header = { color = "white" },
        background = { background = "#43464b" },
        button = { background = "#686D76", color = "white", hover = "#DC5F00" },
        input = {
            placeholderColor = "white",
            background = "#686D76",
            color = "white",
            hover = "grey"
        },
        pTitle = { color = "#b0b0b0" },
        playerCard = { background = "black" }
    },
    inspect = {
        header = { color = "white" },
        background = { background = "#43464b" },
        button = { background = "#686D76", color = "white", hover = "#DC5F00" },
        input = {
            background = "#686D76",
            color = "white"
        }
    }
}
client-utils.lua
RegisterNetEvent('brutal_billing:client:SendNotify')
AddEventHandler('brutal_billing:client:SendNotify', function(title, text, time, type)
	notification(title, text, time, type)
end)

-- Buy here: (4€+VAT) https://store.brutalscripts.com
function notification(title, text, time, type)
    if Config.BrutalNotify then
        exports['brutal_notify']:SendAlert(title, text, time, type)
    else
        -- Put here your own notify and set the Config.BrutalNotify to false
        SetNotificationTextEntry("STRING")
        AddTextComponentString(text)
        DrawNotification(0,1)

        -- Default ESX Notify:
        --TriggerEvent('esx:showNotification', text)

        -- Default QB Notify:
        --TriggerEvent('QBCore:Notify', text, 'info', 5000)

        -- OKOK Notify:
        -- exports['okokNotify']:Alert(title, text, time, type, false)

    end
end
server-utils.lua
-- local YourWebhook = 'WEBHOOK-HERE'  -- help: https://docs.brutalscripts.com/site/others/discord-webhook

-- function GetWebhook()
--     return YourWebhook
-- end

-- Buy here: (4€+VAT) https://store.brutalscripts.com
function notification(source, title, text, time, type)
    if Config.BrutalNotify then
        TriggerClientEvent('brutal_notify:SendAlert', source, title, text, time, type)
    else
        TriggerClientEvent('brutal_billing:client:DefaultNotify', source, text)
    end
end
client-core.lua
Core = nil

if Config['Core']:upper() == 'ESX' then
    local _esx_ = 'new' -- 'new' / 'old'

    if _esx_ then
        Core = exports['es_extended']:getSharedObject()
    else
        while Core == nil do
            TriggerEvent('esx:getSharedObject', function(obj) Core = obj end)
            Citizen.Wait(0)
        end
    end

    LoadedEvent = 'esx:playerLoaded'
    TSCB = Core.TriggerServerCallback
    PlayerDiedHealth = 0

    function GetNearbyPlayers(coords, maxDistance)
        return lib.getNearbyPlayers(coords, maxDistance, false)
    end

    function PlayerJob()
        return Core.GetPlayerData().job
    end

elseif Config['Core']:upper() == 'QBCORE' then
    Core = exports['qb-core']:GetCoreObject()
    LoadedEvent = 'QBCore:Client:OnPlayerLoaded'
    TSCB = Core.Functions.TriggerCallback
    PlayerDiedHealth = 100

    function GetNearbyPlayers(coords, maxDistance)
        return lib.getNearbyPlayers(coords, maxDistance, false)
    end

    function PlayerJob()
        return Core.Functions.GetPlayerData().job
    end
end
server-core.lua
Core = nil

if Config['Core']:upper() == 'ESX' then
    local _esx_ = 'new' -- 'new' / 'old'
    if _esx_ == 'new' then
        Core = exports['es_extended']:getSharedObject()
    else
        Core = nil
        TriggerEvent('esx:getSharedObject', function(obj) Core = obj end)
        while Core == nil do
            Citizen.Wait(0)
        end
    end

    RESCB = Core.RegisterServerCallback
    GETPFI = Core.GetPlayerFromId
    RUI = Core.RegisterUsableItem

    function GetPlayersFunction()
        return Core.GetPlayers()
    end

    function GetMoney(playerId)
        local xPlayer = GETPFI(playerId)
        return xPlayer.getAccount('bank').money
    end

    function RemoveMoney(playerId, amount)
        local xPlayer = GETPFI(playerId)
        xPlayer.addAccountMoney('bank', amount)
    end

    function AddMoney(playerId, amount)
        local xPlayer = GETPFI(playerId)
        xPlayer.addMoney(amount)
    end

    function GetPlayerJobFunction(playerId)
        local playerJob = Player(playerId).state.job
        return playerJob
    end

    function GetPlayerGroupFunction(playerId)
        local playerGroup = Player(playerId).state.group
        return playerGroup
    end

    function GetItemCount(playerId, item)
        local xPlayer = GETPFI(playerId)

        if _esx_ == 'new' then
            return xPlayer.getInventoryItem(item).count
        else
            if string.sub(item, 0, 6):lower() == 'weapon' then
                local loadoutNum, weapon = xPlayer.getWeapon(item:upper())

                if weapon then
                    return true
                else
                    return false
                end
            else
                return xPlayer.getInventoryItem(item).count
            end
        end
    end

    function AddItem(playerId, item, count)
        local xPlayer = GETPFI(playerId)
        if _esx_ == 'new' then
            xPlayer.addInventoryItem(item, count)
        else
            if string.sub(item, 0, 6):lower() == 'weapon' then
                xPlayer.addWeapon(item, 90)
            else
                xPlayer.addInventoryItem(item, count)
            end
        end
    end

    function RemoveItem(playerId, item, amount)
        local xPlayer = GETPFI(playerId)
        if _esx_ == 'new' then
            xPlayer.removeInventoryItem(item, amount)
        else
            if string.sub(item, 0, 6):lower() == 'weapon' then
                xPlayer.removeWeapon(item)
            else
                xPlayer.removeInventoryItem(item, amount)
            end
        end
    end

    function GetIdentifierFunction(playerId)
        local identifier = Player(playerId).state.identifier
        return identifier
    end

    function GetPlayerFromIdentifier(identifier)
        local xPlayer = Core.GetPlayerFromIdentifier(identifier)
        return xPlayer
    end

    function PlayerNameFunction(playerId)
        local xPlayer = GETPFI(playerId)
        return xPlayer.getName()
    end

    function GetOfflinePlayerName(identifier)
        local row = MySQL.single.await('SELECT `firstname`, `lastname` FROM `users` WHERE `identifier` = ? LIMIT 1', {identifier})
        local name = row and row.firstname .." ".. row.lastname or "Unknown"
        return name
    end

    function RemoveMoneyFromOfflinePlayer(identifier, amount)
        local query = 'UPDATE users SET accounts = JSON_SET(accounts, "$.bank", JSON_EXTRACT(accounts, "$.bank") - ?) WHERE identifier = ?;'
        local id = MySQL.query.await(query, {amount, identifier})
        return id
    end

    function PaySociety(society, amount)
        TriggerEvent('esx_addonaccount:getSharedAccount', ('society_%s'):format(society), function(account)
            account.addMoney(amount)
        end)
    end

elseif Config['Core']:upper() == 'QBCORE' then
    Core = exports['qb-core']:GetCoreObject()

    RESCB = Core.Functions.CreateCallback
    GETPFI = Core.Functions.GetPlayer
    RUI = Core.Functions.CreateUseableItem

    function GetPlayersFunction()
        return Core.Functions.GetPlayers()
    end

    function AddMoney(playerId, amount)
        local xPlayer = GETPFI(playerId)
        xPlayer.Functions.AddMoney('bank', amount)
    end

    function GetPlayerJobFunction(playerId)
        local xPlayer = GETPFI(playerId)
        local playerJob = xPlayer.PlayerData.job
        return playerJob
    end

    function GetPlayerGroupFunction(playerId)
        local xPlayer = GETPFI(playerId)
        local playerGroup = xPlayer.PlayerData.group
        return playerGroup
    end

    function GetItemCount(playerId, item)
        local xPlayer = GETPFI(playerId)

        local items = xPlayer.Functions.GetItemByName(item)
        local item_count = 0
        if items ~= nil then
            item_count = items.amount
        else
            item_count = 0
        end
        return item_count
    end

    function AddItem(playerId, item, count)
        local xPlayer = GETPFI(playerId)
        xPlayer.Functions.AddItem(item, count)
    end

    function RemoveItem(playerId, item, amount)
        local xPlayer = GETPFI(playerId)
        xPlayer.Functions.RemoveItem(item, amount)
    end

    function GetIdentifierFunction(playerId)
        local xPlayer = GETPFI(playerId)
        return xPlayer.PlayerData.citizenid
    end

    function GetPlayerFromIdentifier(identifier)
        return Core.Player.GetPlayerByLicense(identifier)
    end

    function PlayerNameFunction(playerId)
        return GetPlayerName(playerId)
    end

    function RemoveMoney(playerId, amount)
        local xPlayer = GETPFI(playerId)
        xPlayer.Functions.RemoveMoney('money', amount, 'Billing')
    end

    function GetMoney(playerId)
        local xPlayer = GETPFI(playerId)
        return xPlayer.PlayerData.money.bank
    end

    function GetOfflinePlayerName(identifier)
        local name = MySQL.scalar.await('SELECT `name`FROM `players` WHERE `license` = ? LIMIT 1', {identifier})
        return name or 'Unknown'
    end

    function RemoveMoneyFromOfflinePlayer(identifier, amount)
        local query = 'UPDATE players SET money = JSON_SET(money, "$.bank", JSON_EXTRACT(money, "$.bank") - ?) WHERE license = ?;'
        local id = MySQL.query.await(query, {amount, identifier})
        return id
    end

    function PaySociety(society, amount)
        -- TODO
    end
end

Last updated

Was this helpful?