# Modifications

Here you can see more in detail how the script can be modified. In the resource you have a config file where you can change things that are not framework specific (See under Config). You will also get three server files and three client files that control what framework you use. These will by default work with QBCore, QBX and ESX. You can see more on how you can modify these under Framework.

## Config

This shows the general structure of the config but the one provided in the resource is to long to add here

```lua
Config = {}

Config.Framework = "qb" --qb, qbx or esx

Config.PoliceJobs = {"police", "bcso", "lspd"}

Config.PoliceMenuCommand = "citations"

Config.CitationsPerRoll = 20

Config.PayLocations = {
    [1] = vector3(441.50741, -984.1696, 30.689334),
}

Config.UseTarget = false

Config.TargetLocation = {
    {
        label = "Paying menu",
        icon = "fas fa-sign-in-alt",
        coords = vector3(441.50885, -984.3801, 30.68931),
        heading = 265,
        width = 2,
        length = 2,
        minZ = 29,
        maxZ = 32,
    },
}

Config.ChargesCallback = "" --Leave as "" if you want to use charges by Config.PenalCodes. set to a qbcore callback name if you want it to be used

Config.PenalCodes = {
    { code = "(1)01", label = "Open Contain of Alcohol in MotorVehicle", fine = 130}
}

Config.VehcileColours = {
    ['0'] = "Metallic Black"
}

Config.Postals = {
    {
        x = 2325.4345703125,
        y = 5147.21484375,
        code = "2000"
    }
}
```

## Framework

This has the same structure for all frameworks here we show the one for QBCore to give you a reference of how it is used:

#### Server

```lua
if Config.Framework ~= "qb" then return end

local QB = exports["qb-core"]:GetCoreObject()

function AddMoney(society, money)
    --exports["qb-management"]:AddMoney(society, money) --Old QB
    exports["qb-banking"]:AddMoney(society, money) --Newest QB
end

function AddItem(source, item, amount, slot, info)
    exports["qb-inventory"]:AddItem(source, item, amount, slot, info)
end

function RemoveItem(source, item, amount, slot)
    exports["qb-inventory"]:RemoveItem(source, item, amount, slot)
end

function SetItemMetadata(src, item, metadata)
    local items = GetPlayerItems(src)
    items[item.slot].info = metadata
    QB.Functions.GetPlayer(src).Functions.SetPlayerData("items", items)
end

function GetitemMetadata(item)
    return item.info --qb-inventory
    --return item.metadata --ox_inventory
end

function MakeCitationUseable()
    QB.Functions.CreateUseableItem("citation", function(source, item)
        UseCitation(source, item)
    end)
end

function MakeCitationRollUseable()
    QB.Functions.CreateUseableItem("citation_roll", function(source, item)
        src = source
        UseCitationRoll(source, item)
    end)
end

function CreateControlPanelCommand()
    if Config.PoliceMenuCommand ~= "" then
        QB.Commands.Add(Config.PoliceMenuCommand, "Open Citation Control Panel", {}, false, function(source)
            ExecuteControlPanelCommand(source)
        end)
    end
end

function GetPlayerCitizenid(src)
    return QB.Functions.GetPlayer(src).PlayerData.citizenid
end

function GetPlayerJobName(src)
    return QB.Functions.GetPlayer(src).PlayerData.job.name
end

function GetPlayerItems(source)
    return QB.Functions.GetPlayer(source).PlayerData.items
end

function GetPlayerMoney(src, moneyType)
    return QB.Functions.GetPlayer(src).PlayerData.money[moneyType]
end

function GetFullPlayerName(citizenid)
    local player = QB.Functions.GetPlayerByCitizenId(citizenid)
    if not player then player = QB.Functions.GetOfflinePlayerByCitizenId(citizenid) end
    if not player then return "", "" end
    local charinfo = player.PlayerData.charinfo
    return charinfo.firstname, charinfo.lastname
end

function PlayerNameSearch(search, searchType)
    local sql = [[
    SELECT JSON_UNQUOTE(JSON_EXTRACT(p.charinfo, '$.firstname')) AS firstname,
           JSON_UNQUOTE(JSON_EXTRACT(p.charinfo, '$.lastname')) AS lastname,
           p.citizenid
    FROM players p
    WHERE LOWER(
      CONCAT(
        JSON_UNQUOTE(JSON_EXTRACT(p.charinfo, '$.]]..searchType..[[name'))
      )
    ) LIKE ?
    ]]
    return MySQL.query.await(sql, { string.lower('%'..search..'%') })
end

function RandomInt(len)
    return QB.Shared.RandomInt(len)
end

function RandomStr(len)
    return QB.Shared.RandomStr(len)
end
```

#### Client

```lua
if Config.Framework ~= "qb" then return end
local QB = exports["qb-core"]:GetCoreObject()

function CreateTarget(index, data)
    exports['qb-target']:AddBoxZone("RD_Citation_Paying_Menu:Index"..tostring(index), data.coords, data.width, data.length, {
        name = "RD_Citation_Paying_Menu:Index"..tostring(index),
        heading = data.heading,
        debugPoly = false,
        minZ = data.minZ,
        maxZ = data.maxZ,
    }, {
        options = {
            {
                type = "server",
                event = esp.."openpaylocation",
                icon = data.icon,
                label = data.label,
            },
        },
        distance = 2.5
    })
end

function LoadPenalCodes()
    return "CONFIG"
end

function GetVehicleInfo(model)
    vehicles = QB.Shared.Vehicles
    for i, v in pairs(vehicles) do
        if GetHashKey(i) == model then
            return {
                category = v.category,
                brand = v.brand
            }
        end
    end
    return nil
end

function GetOfficerData()
    PlayerData = QB.Functions.GetPlayerData()
    info = {}
    ci = PlayerData.charinfo
    rfn = ci.firstname
    fn = string.upper(string.sub(rfn, 1, 1))..string.sub(rfn, 2, #rfn)
    rln = ci.lastname
    ln = string.upper(string.sub(rln, 1, 1))..string.sub(rln, 2, #rln)
    info.name = fn.." "..ln
    info.badge = PlayerData.metadata["callsign"]
    info.agency = PlayerData.job.label
    return info
end

function GetSignuture()
    PlayerData = QB.Functions.GetPlayerData()
    ci = PlayerData.charinfo
    rfn = ci.firstname
    fn = string.upper(string.sub(rfn, 1, 1))
    rln = ci.lastname
    ln = string.upper(string.sub(rln, 1, 1))..string.sub(rln, 2, #rln)
    sign = fn..ln
    return sign
end

function Notify(msg, msgType)
    QB.Functions.Notify(msg, msgType)
end

function GetPlayerJobName()
    return QB.Functions.GetPlayerData().job.name
end

function TearSheetProgressbar(item)
    ped = PlayerPedId()
    QB.Functions.Progressbar("use_citation_roll", "Tearing new sheet..", 4000, false, true, {
		disableMovement = true,
		disableCarMovement = true,
		disableMouse = false,
		disableCombat = true,
	}, {
		animDict = "mp_arresting",
		anim = "a_uncuff",
		flags = 16,
	}, nil, nil, function() -- Done
		StopAnimTask(ped, "mini@repair", "fixing_a_player", 0.0)
        TSE("rollcut", item)
        TriggerEvent('inventory:client:ItemBox', QB.Shared.Items["citation"], 'add')
	end, function() -- Cancel
		StopAnimTask(ped, "mini@repair", "fixing_a_player", 1.0)
        Notify("Failed", "error")
    end)
end
```
