Cadburry ScriptsCadburry Scripts

Framework, Utils & More

Quality of life scripts for your FiveM server. Performance optimized resources that install in minutes, with free updates and support that actually answers.

bridge/framework/client.lua

lua
function IsJobBoss(job)
    if GetResourceState('qbx_core') == 'started' then
        local data = exports.qbx_core:GetPlayerData()
        return data.job.name == job and data.job.grade.isboss
    elseif GetResourceState('qb-core') == 'started' then
        local PlayerData = exports['qb-core']:GetCoreObject().Functions.GetPlayerData()
        return PlayerData.job.name == job and PlayerData.job.grade.isboss
    else
        return false
    end
end

function GetJobLabel(job)
    if GetResourceState('qbx_core') == 'started' then
        local jobInfo = exports.qbx_core:GetJobs()[job]
        return jobInfo and jobInfo.label or 'None'
    elseif GetResourceState('qb-core') == 'started' then
        local jobInfo = exports['qb-core']:GetCoreObject().Shared.Jobs[job]
        return jobInfo and jobInfo.label or 'None'
    else
        return 'None'
    end
end

CreateThread(function()
    local timeout = 30000
    while GetResourceState('ox_inventory') ~= 'missing' and timeout > 0 do
        Wait(1000)
        timeout = timeout - 1000
        if GetResourceState('ox_inventory') == 'started' then
            exports.ox_inventory:displayMetadata({ job = 'Job' })
        end
    end
end)

-- For Inventory Use
local function useBusinessPos(data, slot)
    if not slot.metadata or not next(slot.metadata) then Notify("Not valid machine") return end
    PlayEmote()
    local jobName = slot.metadata?.jobName or GetJobLabel()
    local input = lib.inputDialog('Point of Sale (POS): '..jobName or slot.metadata.job, {
        {type = 'number', label = 'Person ID', icon = 'credit-card', min = 1},
        {type = 'number', label = 'Amount', icon = 'credit-card', min = 1},
        {type = 'input', label = 'Reason', icon = 'circle-question'},
        {type = 'select', label = 'Payment Mode', options = { { value = "cash", label = "Cash" }, { value = "bank", label = "Card" } }, default = "cash", required = true},
    })
    CancelEmote()
    if input then
        if not input[1] then Notify("Person ID not provided") return end
        if not input[2] then Notify("Amount not provided") return end
        if not input[3] then Notify("Reason not provided") return end
        if not input[4] then Notify("Payment mode not provided") return end
        TriggerServerEvent('payments:server:sendPaymentRequest', input, slot.metadata.job)
    end
end
RegisterNetEvent('payments:client:useBusinessPos', function(data)
    useBusinessPos(nil, data)
end)
exports('useBusinessPos', useBusinessPos)

-- For Inventory Use
local function useGeneralPos()
    PlayEmote()
    local input = lib.inputDialog('Point of Sale (POS)', {
        {type = 'number', label = 'Person ID', icon = 'credit-card', min = 1},
        {type = 'number', label = 'Amount', icon = 'credit-card', min = 1},
        {type = 'input', label = 'Reason', icon = 'circle-question'},
        {type = 'select', label = 'Payment Mode', options = { { value = "cash", label = "Cash" }, { value = "bank", label = "Card" } }, default = "cash", required = true},
    })
    CancelEmote()
    if input then
        if not input[1] then Notify("Person ID not provided") return end
        if not input[2] then Notify("Amount not provided") return end
        if not input[3] then Notify("Reason not provided") return end
        if not input[4] then Notify("Payment mode not provided") return end
        TriggerServerEvent('payments:server:sendPaymentRequest', input)
    end
end
RegisterNetEvent('payments:client:useGeneralPos', useGeneralPos)
exports('useGeneralPos', useGeneralPos)

bridge/framework/server.lua

lua
function GetJobLabel(job)
    if GetResourceState('qbx_core') == 'started' then
        local jobInfo = exports.qbx_core:GetJobs()[job]
        return jobInfo and jobInfo.label or 'None'
    elseif GetResourceState('qb-core') == 'started' then
        local jobInfo = exports['qb-core']:GetCoreObject().Shared.Jobs[job]
        return jobInfo and jobInfo.label or 'None'
    end
end

function GetPlayer(src)
    if GetResourceState('qbx_core') == 'started' then
        local player = exports.qbx_core:GetPlayer(src)
        return player and {
            source = player.PlayerData.source,
            name = string.format('%s %s', player.PlayerData.charinfo.firstname, player.PlayerData.charinfo.lastname),
            cash = player.PlayerData.money.cash,
            bank = player.PlayerData.money.bank,
            addMoney = function(mtype, amount, reason)
                return player.Functions.AddMoney(mtype, amount, reason)
            end,
            removeMoney = function(mtype, amount, reason)
                return player.Functions.RemoveMoney(mtype, amount, reason)
            end
        }
    elseif GetResourceState('qb-core') == 'started' then
        local player = exports['qb-core']:GetCoreObject().Functions.GetPlayer(src)
        return player and {
            source = player.PlayerData.source,
            name = string.format('%s %s', player.PlayerData.charinfo.firstname, player.PlayerData.charinfo.lastname),
            cash = player.PlayerData.money.cash,
            bank = player.PlayerData.money.bank,
            addMoney = function(mtype, amount, reason)
                return player.Functions.AddMoney(mtype, amount, reason)
            end,
            removeMoney = function(mtype, amount, reason)
                return player.Functions.RemoveMoney(mtype, amount, reason)
            end
        }
    end
end

function HasItem(src, item, amount)
    if GetResourceState('ox_inventory') == 'started' then
        local count = exports.ox_inventory:GetItem(src, item, nil, true)
        return (count and count >= amount) or 0
    elseif GetResourceState('qb-inventory') == 'started' then
        return exports['qb-inventory']:HasItem(src, item, amount)
    elseif GetResourceState('qs-inventory') == 'started' then
        local totalAmount = exports['qs-inventory']:GetItemTotalAmount(src, item)
        return (totalAmount and totalAmount >= amount)
    end
end

function AddItem(src, item, amount, metadata)
    if GetResourceState('ox_inventory') == 'started' then
        return exports.ox_inventory:AddItem(src, item, amount, metadata)
    elseif GetResourceState('qb-inventory') == 'started' then
        return exports['qb-inventory']:AddItem(src, item, amount, nil, metadata)
    elseif GetResourceState('qs-inventory') == 'started' then
        return exports['qs-inventory']:AddItem(src, item, amount, nil, metadata)
    end
end

function RemoveItem(src, item, amount)
    if GetResourceState('ox_inventory') == 'started' then
        return exports.ox_inventory:RemoveItem(src, item, amount)
    elseif GetResourceState('qb-inventory') == 'started' then
        return exports['qb-inventory']:RemoveItem(src, item, amount)
    elseif GetResourceState('qs-inventory') == 'started' then
        return exports['qs-inventory']:RemoveItem(src, item, amount)
    end
end

function AddMoneyToAccount(accountName, amount, reason)
    if GetResourceState('qb-banking') == 'started' then
        return exports['qb-banking']:AddMoney(accountName, amount, reason)
    elseif GetResourceState('snipe-banking') == 'started' then
        return exports['snipe-banking']:AddMoneyToAccount(accountName, amount, reason)
    elseif GetResourceState('Renewed-Banking') == 'started' then
        return exports['Renewed-Banking']:addAccountMoney(accountName, amount)
    elseif GetResourceState('qb-management') == 'started' then
        return exports["qb-management"]:AddMoney(accountName, amount, reason)
    elseif GetResourceState('fd_banking') == 'started' then
        return exports['fd_banking']:AddMoney(accountName, amount, reason)
    elseif GetResourceState('okokBanking') == 'started' then
        return exports['okokBanking']:AddMoney(accountName, amount, reason)
    elseif GetResourceState('kartik-banking') == 'started' then
        return exports['kartik-banking']:AddAccountMoney(accountName, amount, reason)
    else
        return false
    end
end

CreateThread(function ()
    local timeout = 60000
    if GetResourceState('qb-inventory') ~= 'missing' then
        while GetResourceState('qb-inventory') ~= 'started' and timeout > 0 do
            Wait(1000)
            timeout = timeout - 1000
        end
        exports['qb-core']:CreateUseableItem('businesspos', function(source, item)
            local Player = exports['qb-core']:GetPlayer(source)
	        if not Player.Functions.GetItemByName(item.name) then return end
            item.metadata = item.info
            TriggerClientEvent('payments:client:useBusinessPos', source, item)
        end)
        exports['qb-core']:CreateUseableItem('generalpos', function(source, item)
            local Player = exports['qb-core']:GetPlayer(source)
	        if not Player.Functions.GetItemByName(item.name) then return end
            TriggerClientEvent('payments:client:useGeneralPos', source)
        end)
    elseif GetResourceState('qs-inventory') ~= 'missing' then
        while GetResourceState('qs-inventory') ~= 'started' and timeout > 0 do
            Wait(1000)
            timeout = timeout - 1000
        end
        exports['qs-inventory']:CreateUsableItem('generalpos', function(source, item)
            if item.metadata and item.metadata.quality then
                TriggerClientEvent('payments:client:useGeneralPos', source, item)
            end
        end)
        exports['qs-inventory']:CreateUsableItem('businesspos', function(source, item)
            if item.metadata and item.metadata.quality then
                TriggerClientEvent('payments:client:useBusinessPos', source)
            end
        end)
    end
end)

bridge/utils/client.lua

lua
function Notify(msg, type)
    lib.notify({ description = msg, type = type })
    if Config.Notify == 'qb' then
        TriggerEvent("QBCore:Notify", msg, type, 10000)
    elseif Config.Notify == 'ox' then
        lib.notify({ description = msg, type = type, duration = 10000 })
    elseif Config.Notify == 'snappy-phone' then
        local data = {
            title = 'Payment Terminal',
            icon = 'cash-register',
            description = msg,
            duration = 5000,
        }
        exports['snappy-phone']:sendNotification(data)
    elseif Config.Notify == 'lb-phone' then
        local data = {
            title = 'Payment Terminal',
            content = msg
        }
        exports['lb-phone']:SendNotification(data)
    elseif Config.Notify == 'yseries' then
        TriggerServerEvent('yseries:server:qb-phone-bridge:send-notification', 'Payment Terminal', mst, 15000, GetPlayerServerId(PlayerId()))
    end
end

function PlayEmote()
    if GetResourceState('scully_emotemenu') == 'started' then
        exports.scully_emotemenu:playEmoteByCommand('terminal')
    elseif GetResourceState('rpemotes') == 'started' then
        exports.rpemotes:EmoteCommandStart('terminal')
    end
end

function CancelEmote()
    if GetResourceState('scully_emotemenu') == 'started' then
        exports.scully_emotemenu:cancelEmote()
    elseif GetResourceState('rpemotes') == 'started' then
        exports.rpemotes:EmoteCancel()
    end
end

function RequestConfirmation(data)
    local title = 'Payment Request: ' .. string.upper(data.name)
    local description = string.format('Payment of $%d requested for %s', data.amount, data.reason)
    if Config.Phone == 'snappy-phone' then
        local status = exports['snappy-phone']:sendConfirmation({
            title = title,
            description = description,
            icon = 'credit-card',
            duration = 10000,
        })
        return status
    elseif Config.Phone == 'lb-phone' then
        local result = promise:new()
        local notificationEvent
        CreateThread(function()
            notificationEvent = RegisterNetEvent('lbphone:notificationResponse', function(response)
                result:resolve(response.status)
                RemoveEventHandler(notificationEvent)
            end)
        end)
        exports['lb-phone']:SendNotification({
            title = title,
            content = description,
            customData = {
                buttons = {
                    { title = "Accept",  event = "lbphone:notificationResponse", data = { status = true } },
                    { title = "Decline", event = "lbphone:notificationResponse", data = { status = false } }
                }
            }
        })
        SetTimeout(15000, function()
            result:resolve(false)
        end)
        local response = Citizen.Await(result)
        return response
    elseif Config.Phone == 'yseries' then
        local result = promise:new()
        local notificationEvent
        CreateThread(function()
            notificationEvent = RegisterNetEvent('yseries:notificationResponse', function(response)
                result:resolve(response)
                RemoveEventHandler(notificationEvent)
            end)
        end)
        lib.callback.await('yseries:custom:sendMail', false, {
            title = title,
            sender = 'paymentshub@mayaalokam.com',
            senderDisplayName = 'Payments Hub',
            content = description,
            actions = {
                {
                    label = "Accept",
                    data = {
                        event = "yseries:notificationResponse",
                        isServer = false,
                        data = true,
                        shouldClose = true
                    }
                },
                {
                    label = "Decline",
                    data = {
                        event = "yseries:notificationResponse",
                        isServer = false,
                        data = false,
                        shouldClose = true
                    }
                }
            }
        })
        SetTimeout(15000, function()
            result:resolve(false)
        end)
        local response = Citizen.Await(result)
        return response
    end
end

CreateThread(function()
    for _, data in pairs(Config.Registers) do
        local point = lib.points.new({
            coords = vec3(data.coords.x, data.coords.y, data.coords.z),
            distance = data.distance,
            name = data.name,
            job = data.job
        })
        function point:onEnter()
            lib.showTextUI('[E] Access Register')
        end

        function point:onExit()
            lib.hideTextUI()
        end

        function point:nearby()
            if self.currentDistance < 2 and IsControlJustReleased(0, 46) then
                local options = {
                    {
                        title = 'Charge Customer',
                        icon = 'fa-solid fa-cash-register',
                        onSelect = function()
                            exports['cad-payments']:OpenChargeMenu(self.job)
                        end
                    },
                }
                if IsJobBoss(self.job) then
                    options[#options + 1] = {
                        title = 'Collect Cash',
                        icon = 'fa-solid fa-cash-register',
                        onSelect = function()
                            exports['cad-payments']:OpenCashRegister(self.job)
                        end
                    }
                end
                lib.registerContext({
                    id = 'payments_register',
                    title = self.name,
                    options = options
                })
                lib.showContext('payments_register')
            end
        end
    end
end)

bridge/utils/server.lua

lua
local webhooks = {
    ['police'] = '',
    ['ambulance'] = '',
    ['mechanic'] = '',
}

function Notify(src, msg, type)
    if Config.Notify == 'qb' then
        TriggerClientEvent("QBCore:Notify", src, msg, type, 5000)
    elseif Config.Notify == 'ox' then
        TriggerClientEvent("ox_lib:notify", src, {
            description = msg,
            type = type,
            duration = 5000
        })
    elseif Config.Notify == 'snappy-phone' then
        TriggerClientEvent('phone:client:notification', src, {
            title = 'Payment Terminal',
            icon = 'cash-register',
            description = msg,
            duration = 5000,
        })
    elseif Config.Notify == 'lb-phone' then
        exports["lb-phone"]:SendNotification(src, {
            title = 'Payment Terminal',
            content = msg
        })
    elseif Config.Notify == 'yseries' then
        exports.yseries:SendNotification({
            title = 'Payment Terminal',
            text = msg,
            timeout = 5000,
            icon = 'https://cdn-icons-png.flaticon.com/128/4645/4645352.png'
        }, 'source', src)
    end
end

function Sendlog(logName, logType, message)
    if not webhooks[logName] then return end
    local _data = json.encode({
        username = "Payments Portal",
        embeds = {
            {
                title = logType,
                color = 10650848,
                author = {
                    name = "Cadburry",
                },
                description = message,
                footer = {
                    text = os.date('%c'),
                },
            }
        }
    })
    PerformHttpRequest(webhooks[logName], function() end, 'POST', _data, { ['Content-Type'] = 'application/json' })
end

lib.callback.register('yseries:custom:sendMail', function(source, data)
    local insertId, received = exports.yseries:SendMail(data, 'source', source)
    return insertId and received
end)

lib.addCommand('give_pos', {
    help = 'Provide POS Machine',
    params = {
        {
            name = 'target',
            type = 'playerId',
            help = 'Target player\'s server id',
        },
        {
            name = 'job',
            type = 'string',
            help = 'Name of the job',
        }
    },
    restricted = 'group.admin'
}, function(source, args, raw)
    if not args.target then return end
    local jobName = args.job and GetJobLabel(args.job) or nil
    local itemName = (args.job and 'businesspos') or 'generalpos'
    AddItem(args.target, itemName, 1, { job = args.job, jobName = jobName })
end)
Last updated Cadburry Scripts