Follow all necessary steps to ensure the script works correctly
ESX
Check your es_extended/server/functions.lua to see if there is a function called ESX.RefreshJobs(), if this function is not included in your file, add it:
functionESX.RefreshJobs()local Jobs = {}local jobs = MySQL.query.await("SELECT * FROM jobs")for _, v inipairs(jobs) do Jobs[v.name] = v Jobs[v.name].grades = {}endlocal jobGrades = MySQL.query.await("SELECT * FROM job_grades")for _, v inipairs(jobGrades) doif Jobs[v.job_name] then Jobs[v.job_name].grades[tostring(v.grade)] = velseprint(('[^3WARNING^7] Ignoring job grades for ^5"%s"^0 due to missing job'):format(v.job_name))endendfor _, v inpairs(Jobs) doif ESX.Table.SizeOf(v.grades) ==0then Jobs[v.name] =nilprint(('[^3WARNING^7] Ignoring job ^5"%s"^0 due to no job grades found'):format(v.name))endendifnot Jobs then-- Fallback data, if no jobs exist ESX.Jobs["unemployed"] = { label ="Unemployed", grades = { ["0"] = { grade =0, label ="Unemployed", salary =200, skin_male = {}, skin_female = {} } } }else ESX.Jobs = Jobsendend
QB-Core
For proper operation in QB Core, you will need to go to the QB-core/server/player.lua folder and replace the entire QBCore.Player.CheckPlayerData file with this one:
function QBCore.Player.CheckPlayerData(source, PlayerData)
PlayerData = PlayerData or {}
local Offline = true
if source then
PlayerData.source = source
PlayerData.license = PlayerData.license or QBCore.Functions.GetIdentifier(source, 'license')
PlayerData.name = GetPlayerName(source)
Offline = false
end
PlayerData.citizenid = PlayerData.citizenid or QBCore.Player.CreateCitizenId()
PlayerData.cid = PlayerData.cid or 1
PlayerData.money = PlayerData.money or {}
PlayerData.optin = PlayerData.optin or true
for moneytype, startamount in pairs(QBCore.Config.Money.MoneyTypes) do
PlayerData.money[moneytype] = PlayerData.money[moneytype] or startamount
end
-- Charinfo
PlayerData.charinfo = PlayerData.charinfo or {}
PlayerData.charinfo.firstname = PlayerData.charinfo.firstname or 'Firstname'
PlayerData.charinfo.lastname = PlayerData.charinfo.lastname or 'Lastname'
PlayerData.charinfo.birthdate = PlayerData.charinfo.birthdate or '00-00-0000'
PlayerData.charinfo.gender = PlayerData.charinfo.gender or 0
PlayerData.charinfo.backstory = PlayerData.charinfo.backstory or 'placeholder backstory'
PlayerData.charinfo.nationality = PlayerData.charinfo.nationality or 'USA'
PlayerData.charinfo.phone = PlayerData.charinfo.phone or QBCore.Functions.CreatePhoneNumber()
PlayerData.charinfo.account = PlayerData.charinfo.account or QBCore.Functions.CreateAccountNumber()
-- Metadata
PlayerData.metadata = PlayerData.metadata or {}
PlayerData.metadata['hunger'] = PlayerData.metadata['hunger'] or 100
PlayerData.metadata['thirst'] = PlayerData.metadata['thirst'] or 100
PlayerData.metadata['stress'] = PlayerData.metadata['stress'] or 0
PlayerData.metadata['isdead'] = PlayerData.metadata['isdead'] or false
PlayerData.metadata['inlaststand'] = PlayerData.metadata['inlaststand'] or false
PlayerData.metadata['armor'] = PlayerData.metadata['armor'] or 0
PlayerData.metadata['ishandcuffed'] = PlayerData.metadata['ishandcuffed'] or false
PlayerData.metadata['tracker'] = PlayerData.metadata['tracker'] or false
PlayerData.metadata['injail'] = PlayerData.metadata['injail'] or 0
PlayerData.metadata['jailitems'] = PlayerData.metadata['jailitems'] or {}
PlayerData.metadata['status'] = PlayerData.metadata['status'] or {}
PlayerData.metadata['phone'] = PlayerData.metadata['phone'] or {}
PlayerData.metadata['fitbit'] = PlayerData.metadata['fitbit'] or {}
PlayerData.metadata['commandbinds'] = PlayerData.metadata['commandbinds'] or {}
PlayerData.metadata['bloodtype'] = PlayerData.metadata['bloodtype'] or QBCore.Config.Player.Bloodtypes[math.random(1, #QBCore.Config.Player.Bloodtypes)]
PlayerData.metadata['dealerrep'] = PlayerData.metadata['dealerrep'] or 0
PlayerData.metadata['craftingrep'] = PlayerData.metadata['craftingrep'] or 0
PlayerData.metadata['attachmentcraftingrep'] = PlayerData.metadata['attachmentcraftingrep'] or 0
PlayerData.metadata['currentapartment'] = PlayerData.metadata['currentapartment'] or nil
PlayerData.metadata['jobrep'] = PlayerData.metadata['jobrep'] or {}
PlayerData.metadata['jobrep']['tow'] = PlayerData.metadata['jobrep']['tow'] or 0
PlayerData.metadata['jobrep']['trucker'] = PlayerData.metadata['jobrep']['trucker'] or 0
PlayerData.metadata['jobrep']['taxi'] = PlayerData.metadata['jobrep']['taxi'] or 0
PlayerData.metadata['jobrep']['hotdog'] = PlayerData.metadata['jobrep']['hotdog'] or 0
PlayerData.metadata['callsign'] = PlayerData.metadata['callsign'] or 'NO CALLSIGN'
PlayerData.metadata['fingerprint'] = PlayerData.metadata['fingerprint'] or QBCore.Player.CreateFingerId()
PlayerData.metadata['walletid'] = PlayerData.metadata['walletid'] or QBCore.Player.CreateWalletId()
PlayerData.metadata['criminalrecord'] = PlayerData.metadata['criminalrecord'] or {
['hasRecord'] = false,
['date'] = nil
}
PlayerData.metadata['licences'] = PlayerData.metadata['licences'] or {
['driver'] = true,
['business'] = false,
['weapon'] = false
}
PlayerData.metadata['inside'] = PlayerData.metadata['inside'] or {
house = nil,
apartment = {
apartmentType = nil,
apartmentId = nil,
}
}
PlayerData.metadata['phonedata'] = PlayerData.metadata['phonedata'] or {
SerialNumber = QBCore.Player.CreateSerialNumber(),
InstalledApps = {},
}
-- Job
if PlayerData.job and PlayerData.job.name and not QBCore.Shared.Jobs[PlayerData.job.name] then
local negocio = MySQL.single.await("SELECT label FROM negocios_pasivos WHERE job = ?", { PlayerData.job.name })
if negocio then
local rangos = MySQL.query.await("SELECT grade, name, label, salary FROM negocios_grados WHERE job_name = ? ORDER BY grade ASC", { PlayerData.job.name })
QBCore.Shared.Jobs[PlayerData.job.name] = {
label = negocio.label,
defaultDuty = true,
grades = {}
}
for _, r in ipairs(rangos) do
QBCore.Shared.Jobs[PlayerData.job.name].grades[tostring(r.grade)] = {
name = r.name,
label = r.label,
payment = r.salary,
isboss = (r.grade == (#rangos - 1))
}
end
else
PlayerData.job = nil
end
end
PlayerData.job = PlayerData.job or {}
PlayerData.job.name = PlayerData.job.name or 'unemployed'
PlayerData.job.label = PlayerData.job.label or 'Civilian'
PlayerData.job.payment = PlayerData.job.payment or 10
PlayerData.job.type = PlayerData.job.type or 'none'
if QBCore.Shared.ForceJobDefaultDutyAtLogin or PlayerData.job.onduty == nil then
PlayerData.job.onduty = QBCore.Shared.Jobs[PlayerData.job.name].defaultDuty
end
PlayerData.job.isboss = PlayerData.job.isboss or false
PlayerData.job.grade = PlayerData.job.grade or {}
PlayerData.job.grade.name = PlayerData.job.grade.name or 'Freelancer'
PlayerData.job.grade.level = PlayerData.job.grade.level or 0
-- Gang
if PlayerData.gang and PlayerData.gang.name and not QBCore.Shared.Gangs[PlayerData.gang.name] then PlayerData.gang = nil end
PlayerData.gang = PlayerData.gang or {}
PlayerData.gang.name = PlayerData.gang.name or 'none'
PlayerData.gang.label = PlayerData.gang.label or 'No Gang Affiliaton'
PlayerData.gang.isboss = PlayerData.gang.isboss or false
PlayerData.gang.grade = PlayerData.gang.grade or {}
PlayerData.gang.grade.name = PlayerData.gang.grade.name or 'none'
PlayerData.gang.grade.level = PlayerData.gang.grade.level or 0
-- Other
PlayerData.position = PlayerData.position or QBConfig.DefaultSpawn
PlayerData.items = GetResourceState('qb-inventory') ~= 'missing' and exports['qb-inventory']:LoadInventory(PlayerData.source, PlayerData.citizenid) or {}
return QBCore.Player.CreatePlayer(PlayerData, Offline)
end
For proper operation in qbcore you will have to go to the qb-core/server/player.lua folder and replace the entire self.Functions.SetJob with this one:
function self.Functions.SetJob(job, grade)
job = job:lower()
grade = tonumber(grade) or 0
if QBCore.Shared.Jobs[job] then
self.PlayerData.job.name = job
self.PlayerData.job.label = QBCore.Shared.Jobs[job].label
self.PlayerData.job.onduty = QBCore.Shared.Jobs[job].defaultDuty
self.PlayerData.job.type = QBCore.Shared.Jobs[job].type or 'none'
if QBCore.Shared.Jobs[job].grades[tostring(grade)] then
local jobgrade = QBCore.Shared.Jobs[job].grades[tostring(grade)]
self.PlayerData.job.grade = {
name = jobgrade.name,
level = tonumber(grade),
}
self.PlayerData.job.payment = jobgrade.payment or 30
self.PlayerData.job.isboss = jobgrade.isboss or false
else
self.PlayerData.job.grade = {
name = 'No Grades',
level = 0,
}
self.PlayerData.job.payment = 30
self.PlayerData.job.isboss = false
end
else
local newJob = exports["jc_negocios"]:SetNegocioJob(self.PlayerData.source, job, grade)
if not newJob then
print("[SetJob] No se pudo asignar job desde jc_negocios")
return false
end
if job:lower() ~= self.PlayerData.job.name then
local newJob = exports["jc_negocios"]:SetNegocioJob(self.PlayerData.source, job, grade)
if not newJob then return false end
self.PlayerData.job = newJob
end
self.PlayerData.job = newJob
end
if not self.Offline then
self.Functions.UpdatePlayerData()
TriggerEvent('QBCore:Server:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
TriggerClientEvent('QBCore:Client:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
end
return true
end
Export
In order for stores to deduct money correctly and be added to the businesses you want, you'll need to add this export to the stores that deduct money.
-- Server Side
local coords = GetEntityCoords(GetPlayerPed(source))
exports["jc_negocios"]:sumarGanancia(price, coords.x, coords.y, coords.z)
Example
For example, for weapons shops, esx_weaponshop/server/main.lua, we'll look for the section where it deducts money from purchases and add the export to the section where it deducts the money from the player who buys. This way, we can create all the ammunition businesses we want. For clothing stores, badulaques, etc., it will be the same. Look for the section where it deducts money from the player and add the export. This way, you can use all the points from that business.