# Integrations

### QBCore

#### qb-multicharacter

* Open [qb-multicharacter/server/main.lua](https://github.com/qbcore-framework/qb-multicharacter/blob/main/server/main.lua).
* Find the [GiveStarterItems](https://github.com/qbcore-framework/qb-multicharacter/blob/76c09e4b4a2faa683a3a8661bbe5b02b5198c29a/server/main.lua#L7C1-L27C4) function.
* Update the code for `id_card` and `driver_license` to utilize the `createCard` export.

```lua
local function GiveStarterItems(source)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    for _, v in pairs(QBCore.Shared.StarterItems) do
        local info = {}
        -- if v.item == 'id_card' then
        --     info.citizenid = Player.PlayerData.citizenid
        --     info.firstname = Player.PlayerData.charinfo.firstname
        --     info.lastname = Player.PlayerData.charinfo.lastname
        --     info.birthdate = Player.PlayerData.charinfo.birthdate
        --     info.gender = Player.PlayerData.charinfo.gender
        --     info.nationality = Player.PlayerData.charinfo.nationality
        -- elseif v.item == 'driver_license' then
        --     info.firstname = Player.PlayerData.charinfo.firstname
        --     info.lastname = Player.PlayerData.charinfo.lastname
        --     info.birthdate = Player.PlayerData.charinfo.birthdate
        --     info.type = 'Class C Driver License'
        -- end
        if v.item == 'id_card' or v.item == 'driver_license' then
            exports.rm_idcard:createCard(src, v.item)
        else
            exports['qb-inventory']:AddItem(src, v.item, v.amount, false, info, 'qb-multicharacter:GiveStarterItems')
        end
    end
end
```

#### qb-cityhall

* Open [qb-cityhall/server/main.lua](https://github.com/qbcore-framework/qb-cityhall/blob/main/server/main.lua).
* Find the [giveStarterItems](https://github.com/qbcore-framework/qb-cityhall/blob/4eefa1801321b0815d651996d82ec424d617c872/server/main.lua#L19C1-L39C4) function.
* Update the `id_card` and `driver_license` items to invoke the `createCard` export.

```lua
local function giveStarterItems()
    local Player = QBCore.Functions.GetPlayer(source)
    if not Player then return end
    for _, v in pairs(QBCore.Shared.StarterItems) do
        local info = {}
        -- if v.item == 'id_card' then
        --     info.citizenid = Player.PlayerData.citizenid
        --     info.firstname = Player.PlayerData.charinfo.firstname
        --     info.lastname = Player.PlayerData.charinfo.lastname
        --     info.birthdate = Player.PlayerData.charinfo.birthdate
        --     info.gender = Player.PlayerData.charinfo.gender
        --     info.nationality = Player.PlayerData.charinfo.nationality
        -- elseif v.item == 'driver_license' then
        --     info.firstname = Player.PlayerData.charinfo.firstname
        --     info.lastname = Player.PlayerData.charinfo.lastname
        --     info.birthdate = Player.PlayerData.charinfo.birthdate
        --     info.type = 'Class C Driver License'
        -- end
        if v.item == 'id_card' or v.item == 'driver_license' then
            exports.rm_idcard:createCard(source, v.item)
        else
            exports['qb-inventory']:AddItem(source, v.item, 1, false, info, 'qb-cityhall:giveStarterItems')
        end
    end
end
```

* Find the [qb-cityhall:server:requestId](https://github.com/qbcore-framework/qb-cityhall/blob/4eefa1801321b0815d651996d82ec424d617c872/server/main.lua#L65C1-L93C5) event.
* Initialize `id_card`, `driver_license`, and `weaponlicense` using the `createCard` export.

```lua
RegisterNetEvent('qb-cityhall:server:requestId', function(item, hall)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end
    local itemInfo = Config.Cityhalls[hall].licenses[item]
    if not Player.Functions.RemoveMoney('cash', itemInfo.cost, 'cityhall id') then return TriggerClientEvent('QBCore:Notify', src, ('You don\'t have enough money on you, you need %s cash'):format(itemInfo.cost), 'error') end
    local info = {}
    -- if item == 'id_card' then
    --     info.citizenid = Player.PlayerData.citizenid
    --     info.firstname = Player.PlayerData.charinfo.firstname
    --     info.lastname = Player.PlayerData.charinfo.lastname
    --     info.birthdate = Player.PlayerData.charinfo.birthdate
    --     info.gender = Player.PlayerData.charinfo.gender
    --     info.nationality = Player.PlayerData.charinfo.nationality
    -- elseif item == 'driver_license' then
    --     info.firstname = Player.PlayerData.charinfo.firstname
    --     info.lastname = Player.PlayerData.charinfo.lastname
    --     info.birthdate = Player.PlayerData.charinfo.birthdate
    --     info.type = 'Class C Driver License'
    -- elseif item == 'weaponlicense' then
    --     info.firstname = Player.PlayerData.charinfo.firstname
    --     info.lastname = Player.PlayerData.charinfo.lastname
    --     info.birthdate = Player.PlayerData.charinfo.birthdate
    if item == 'id_card' or item == 'driver_license' or item == 'weaponlicense' then
        exports.rm_idcard:createCard(src, item)
        return
    else
        return false
    end
    if not exports['qb-inventory']:AddItem(src, item, 1, false, info, 'qb-cityhall:server:requestId') then return end
    TriggerClientEvent('qb-inventory:client:ItemBox', src, QBCore.Shared.Items[item], 'add')
end)
```

<details>

<summary><strong>Optional:</strong> <code>rm_idcard</code> relies on its own NPC system for purchasing licenses. To avoid player confusion, you should disable the native options in the Cityhall script.</summary>

* Open [qb-cityhall/client/main.lua](https://github.com/qbcore-framework/qb-cityhall/blob/main/client/main.lua).
* Find the [openCityhallMenu](https://github.com/qbcore-framework/qb-cityhall/blob/4eefa1801321b0815d651996d82ec424d617c872/client/main.lua#L99C1-L129C4) function.
* Comment out the `ID Card` option.

```lua
local function openCityhallMenu()
    local mainMenu = {
        {
            header = 'City Hall',
            isMenuHeader = true
        },
        -- {
        --     header = 'ID Card',
        --     txt = 'Get your ID Card',
        --     params = {
        --         event = 'qb-cityhall:client:openIdentityMenu'
        --     }
        -- },
        {
            header = 'Job Center',
            txt = 'Available Jobs',
            params = {
                event = 'qb-cityhall:client:openJobMenu'
            }
        },
        {
            header = 'Close Menu',
            txt = '',
            params = {
                event = 'qb-menu:client:closeMenu'
            }
        }
    }

    exports['qb-menu']:openMenu(mainMenu)
end
```

</details>

#### qb-inventory

* Open [qb-inventory/server/main.lua](https://github.com/qbcore-framework/qb-inventory/blob/main/server/main.lua).
* Find the [qb-inventory:server:useItem](https://github.com/qbcore-framework/qb-inventory/blob/2bdea9b53237396178dcd8af776a55c1e857e864/server/main.lua#L180C1-L240C5) event.
* Comment out the logic for `id_card` and `driver_license` to prevent conflicts.

```lua
RegisterNetEvent('qb-inventory:server:useItem', function(item)
    local src = source
    local itemData = GetItemBySlot(src, item.slot)
    if not itemData then return end
    local itemInfo = QBCore.Shared.Items[itemData.name]
    if itemData.type == 'weapon' then
        TriggerClientEvent('qb-weapons:client:UseWeapon', src, itemData, itemData.info.quality and itemData.info.quality > 0)
        TriggerClientEvent('qb-inventory:client:ItemBox', src, itemInfo, 'use')
    -- elseif itemData.name == 'id_card' then
    --     UseItem(itemData.name, src, itemData)
    --     TriggerClientEvent('qb-inventory:client:ItemBox', source, itemInfo, 'use')
    --     local playerPed = GetPlayerPed(src)
    --     local playerCoords = GetEntityCoords(playerPed)
    --     local players = QBCore.Functions.GetPlayers()
    --     local gender = item.info.gender == 0 and 'Male' or 'Female'
    --     for _, v in pairs(players) do
    --         local targetPed = GetPlayerPed(v)
    --         local dist = #(playerCoords - GetEntityCoords(targetPed))
    --         if dist < 3.0 then
    --             TriggerClientEvent('chat:addMessage', v, {
    --                 template = '<div class="chat-message advert" style="background: linear-gradient(to right, rgba(5, 5, 5, 0.6), #74807c); display: flex;"><div style="margin-right: 10px;"><i class="far fa-id-card" style="height: 100%;"></i><strong> {0}</strong><br> <strong>Civ ID:</strong> {1} <br><strong>First Name:</strong> {2} <br><strong>Last Name:</strong> {3} <br><strong>Birthdate:</strong> {4} <br><strong>Gender:</strong> {5} <br><strong>Nationality:</strong> {6}</div></div>',
    --                 args = {
    --                     'ID Card',
    --                     item.info.citizenid,
    --                     item.info.firstname,
    --                     item.info.lastname,
    --                     item.info.birthdate,
    --                     gender,
    --                     item.info.nationality
    --                 }
    --             })
    --         end
    --     end
    -- elseif itemData.name == 'driver_license' then
    --     UseItem(itemData.name, src, itemData)
    --     TriggerClientEvent('qb-inventory:client:ItemBox', src, itemInfo, 'use')
    --     local playerPed = GetPlayerPed(src)
    --     local playerCoords = GetEntityCoords(playerPed)
    --     local players = QBCore.Functions.GetPlayers()
    --     for _, v in pairs(players) do
    --         local targetPed = GetPlayerPed(v)
    --         local dist = #(playerCoords - GetEntityCoords(targetPed))
    --         if dist < 3.0 then
    --             TriggerClientEvent('chat:addMessage', v, {
    --                 template = '<div class="chat-message advert" style="background: linear-gradient(to right, rgba(5, 5, 5, 0.6), #657175); display: flex;"><div style="margin-right: 10px;"><i class="far fa-id-card" style="height: 100%;"></i><strong> {0}</strong><br> <strong>First Name:</strong> {1} <br><strong>Last Name:</strong> {2} <br><strong>Birth Date:</strong> {3} <br><strong>Licenses:</strong> {4}</div></div>',
    --                 args = {
    --                     'Drivers License',
    --                     item.info.firstname,
    --                     item.info.lastname,
    --                     item.info.birthdate,
    --                     item.info.type
    --                 }
    --             }
    --             )
    --         end
    --     end
    else
        UseItem(itemData.name, src, itemData)
        TriggerClientEvent('qb-inventory:client:ItemBox', src, itemInfo, 'use')
    end
end)
```

* Open [qb-inventory/server/commands.lua](https://github.com/qbcore-framework/qb-inventory/blob/main/server/commands.lua)
* Find the [giveitem](https://github.com/qbcore-framework/qb-inventory/blob/2bdea9b53237396178dcd8af776a55c1e857e864/server/commands.lua#L3C1-L49C14) command.
* Modify the logic for `id_card` and `driver_license` to use the `createCard` export upon generation.

```lua
QBCore.Commands.Add('giveitem', 'Give An Item (Admin Only)', { { name = 'id', help = 'Player ID' }, { name = 'item', help = 'Name of the item (not a label)' }, { name = 'amount', help = 'Amount of items' } }, false, function(source, args)
    local id = tonumber(args[1])
    local player = QBCore.Functions.GetPlayer(id)
    local amount = tonumber(args[3]) or 1
    local itemData = QBCore.Shared.Items[tostring(args[2]):lower()]
    if player then
        if itemData then
            -- check iteminfo
            local info = {}
            -- if itemData['name'] == 'id_card' then
            --     info.citizenid = player.PlayerData.citizenid
            --     info.firstname = player.PlayerData.charinfo.firstname
            --     info.lastname = player.PlayerData.charinfo.lastname
            --     info.birthdate = player.PlayerData.charinfo.birthdate
            --     info.gender = player.PlayerData.charinfo.gender
            --     info.nationality = player.PlayerData.charinfo.nationality
            -- elseif itemData['name'] == 'driver_license' then
            --     info.firstname = player.PlayerData.charinfo.firstname
            --     info.lastname = player.PlayerData.charinfo.lastname
            --     info.birthdate = player.PlayerData.charinfo.birthdate
            --     info.type = 'Class C Driver License'
            if itemData['name'] == 'id_card' or itemData['name'] == 'driver_license' then
                exports.rm_idcard:createCard(source, itemData['name'])
                return
            elseif itemData['type'] == 'weapon' then
                amount = 1
                info.serie = tostring(QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(1) .. QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(4))
                info.quality = 100
            elseif itemData['name'] == 'harness' then
                info.uses = 20
            elseif itemData['name'] == 'markedbills' then
                info.worth = math.random(5000, 10000)
            elseif itemData['name'] == 'printerdocument' then
                info.url = 'https://cdn.discordapp.com/attachments/870094209783308299/870104331142189126/Logo_-_Display_Picture_-_Stylized_-_Red.png'
            end

            if AddItem(id, itemData['name'], amount, false, info, 'give item command') then
                QBCore.Functions.Notify(source, Lang:t('notify.yhg') .. GetPlayerName(id) .. ' ' .. amount .. ' ' .. itemData['name'] .. '', 'success')
                TriggerClientEvent('qb-inventory:client:ItemBox', id, itemData, 'add', amount)
                if Player(id).state.inv_busy then TriggerClientEvent('qb-inventory:client:updateInventory', id) end
            else
                QBCore.Functions.Notify(source, Lang:t('notify.cgitem'), 'error')
            end
        else
            QBCore.Functions.Notify(source, Lang:t('notify.idne'), 'error')
        end
    else
        QBCore.Functions.Notify(source, Lang:t('notify.pdne'), 'error')
    end
end, 'admin')
```

***

### QBox

#### qbx\_idcard

Ensure that the `qbx_idcard` script is not running. If there is a `qbx_idcard` folder under the \[qbx] folder, back it up and delete it. `rm_idcard` will provide the `GetMetaLicense` export.

#### qbx\_cityhall

<details>

<summary><strong>Optional:</strong> <code>rm_idcard</code> relies on its own NPC system for purchasing licenses. To avoid player confusion, you should disable the native options in the Cityhall script.</summary>

* Open [qbx\_cityhall/client/main.lua](https://github.com/qbcore-framework/qb-cityhall/blob/main/client/main.lua).
* Find the [openCityhallMenu](https://github.com/Qbox-project/qbx_cityhall/blob/d99876f00f9f63cc5c33b517f3f6eeb68e8d270d/client/main.lua#L103C1-L136C4) function.
* Comment out the `Identity` option.

```lua
local function openCityhallMenu()
    local closestCityhall = getClosestHall()
    local options = {}

    -- options[#options + 1] = {
    --     title = locale('info.identity'),
    --     description = locale('info.obtain_license_identity'),
    --     onSelect = function()
    --         openIdentificationMenu(closestCityhall)
    --     end
    -- }

    if sharedConfig.employment.enabled then
        options[#options + 1] = {
            title = locale('info.employment'),
            description = locale('info.select_job'),
            onSelect = openEmploymentMenu
        }
    end

    lib.registerContext({
        id = 'cityhall_menu',
        title = locale('info.cityhall'),
        onExit = function()
            if not config.useTarget and inRangeCityhall then
                lib.showTextUI(locale('info.open_cityhall'))
            end
        end,
        options = options
    })
    lib.showContext('cityhall_menu')
    if not config.useTarget then return end
    inRangeCityhall = false
end
```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rainmad.com/resources/id-card/integrations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
