Config = {}RegisterCommand('orgpanel', function()openPanel()end)Config.tabletEntity =nil-- DO NOT CHANGEConfig.tabletModel ="prop_cs_tablet"Config.tabletDict ="amb@world_human_seat_wall_tablet@female@base"Config.tabletAnim ="base"Config.startTabletAnimation=function() lib.requestAnimDict(Config.tabletDict)if Config.tabletEntity then Config.stopTabletAnimation()end lib.requestModel(Config.tabletModel) Config.tabletEntity =CreateObject(GetHashKey(Config.tabletModel), 1.0, 1.0, 1.0, 1, 1, 0) AttachEntityToEntity(Config.tabletEntity, cache.ped, GetPedBoneIndex(cache.ped, 57005), 0.12, 0.10, -0.13, 25.0, 170.0, 160.0, true, true, false, true, 1, true)
TaskPlayAnim(cache.ped, Config.tabletDict, Config.tabletAnim, 8.0, -8.0, -1, 50, 0, false, false, false)endConfig.stopTabletAnimation=function()if Config.tabletEntity thenStopAnimTask(cache.ped, Config.tabletDict, Config.tabletAnim ,8.0, -8.0, -1, 50, 0, false, false, false)DeleteEntity(Config.tabletEntity) Config.tabletEntity =nilendendConfig.showNotification=function(msg) lib.notify({ title ='Organization Panel', description = msg, type ='inform' })endConfig.peds = { -- peds where you can create organization { coords =vec3(939.5922, -1490.5969, 30.0927), model ='a_m_m_og_boss_01', heading =180.0 }}Config.pedinteraction=function(ped) exports.ox_target:addBoxZone({ coords = ped.coords, size =vec3(1, 1, 2), rotation =340, debug = drawZones, options = { { icon ='fas fa-sitemap', label ='Create an organization', distance =2.0,onSelect=function(data) Framework.TriggerServerCallback('pp-orgpanel:getorganization', function(isinorganization) Config.createOrganization(isinorganization)end)end }, { icon ='fas fa-dollar-sign', label ="Deposit cash into the organization's account", distance =2.0,onSelect=function(data) Framework.TriggerServerCallback('pp-orgpanel:getorganization', function(isinorganization) Config.depositCash(isinorganization)end)end }, } })endConfig.createOrganization=function(isinorganization)if isinorganization thenreturn Config.showNotification('You are already in organization!')endlocal input = lib.inputDialog('Create organization', { {type ='input', label ='Organization name', description ='Cost: 40.000$', required =true, max =10}, })ifnot input thenreturnendTriggerServerEvent('pp-orgpanel:createneworg', input[1])endConfig.depositCash=function(isinorganization)ifnot isinorganization thenreturn Config.showNotification('You are not in any organization!')endlocal input = lib.inputDialog('Deposit cash', { {type ='number', label ='Deposit amount', required =true, min =0}, })ifnot input thenreturnendTriggerServerEvent('pp-orgpanel:sendmoney', input[1])endlib.callback.register('rc-orgpanel:addmember', function(orgname,name)local alert = lib.alertDialog({ header ='Atention!', content = name ..' invited you to join organization ' .. orgname ..', do you want to join?', centered =true, cancel =true })return alert =='confirm' andtrueorfalseend)Config.createStash=function(stash) exports.ox_target:addBoxZone({ coords = stash.coords, size = stash.size, rotation = stash.rotation, debug =false, options = { { icon ='fa-solid fa-hands', label =t('backend.open_stash'), distance =2.0,onSelect=function() exports.ox_inventory:openInventory('stash', 'orgstash_' .. stash.name)end } } })end
Server Config
Config = {}Config.ESXEvent =nil-- fill only when using older ESX versionConfig.Locales ='en'Config.interiors = { enabled =true,registerstash=function(result)local szafki = {}for _, data inpairs(result) dolocal coords = json.decode(data.coords)local upgrades = data.upgrades and json.decode(data.upgrades) or {}local capacity =100000local slots =50ifdoesinteriorhaveupgrade(upgrades, 'weight') then capacity =200000endifdoesinteriorhaveupgrade(upgrades, 'slots2') then slots =150elseifdoesinteriorhaveupgrade(upgrades, 'slots') then slots =100endtable.insert(szafki, {coords = coords, name = data.name, slots = slots, capacity = capacity})endfor _, stash inpairs(szafki) do exports.ox_inventory:RegisterStash('orgstash_' .. stash.name, 'Organization stash', stash.slots, stash.capacity, false)
endend, stashes = { -- this is synced with database, removing any values here will remove them from the database as well ['interior1'] = { size =vec3(1.20000004768371, 0.60000002384185, 3.0), coords =vec3(746.5399780273438, -1781.989990234375, 36.54000091552734), rotation =90, doorlock ='interior1' } }}Config.levels = { -- progress levels on the home page [1] = { expMin =0, expMax =100, }, [2] = { expMin =101, expMax =200, }, [3] = { expMin =201, expMax =300, }}Config.managementAccess=function(src) -- specifies access to the management tabreturnfalseendConfig.rankOrder = { -- grades in members tab ["Boss"] =1, ["Deputy boss"] =2, ["Senior member"] =3, ["Member"] =4, ["Beginner"] =5} Config.startMembers =5-- maximum members count when creating organizationConfig.search ='ssn' -- ssn | id (server id)Config.OrgCreationCost =40000-- cost of creating organization (in cash)Config.defaultWalletData = {bank = {value =0, unit ='$'}} -- data in the wallet set when creating the organizationConfig.GenerateAccountNumber=function()local first =math.random(100, 999)local second =math.random(100, 999)return first ..'-' .. secondendConfig.TransferFunction=function(src,identifier,amount,name) local export = exports.pefcl:addBankBalanceByIdentifier(src, { identifier = identifier, amount = amount, message = 'Transfer from ' .. name })
if export and export.status and export.status =='ok' thenreturntrueelsereturnfalseendendConfig.Queries = { ['identifierbyssn'] ='SELECT identifier FROM users WHERE ssn = @ssn', ['namebyidentifier'] ='SELECT firstname, lastname FROM users WHERE identifier = @identifier', ['nameandjoindate'] = 'SELECT u.firstname, u.lastname, om.join_date FROM organization_members om JOIN users u ON om.user_id = u.identifier WHERE om.org_id = @org_id',
['members'] =[[ SELECT om.user_id, om.permissions, om.join_date, u.firstname, u.lastname, om.rank, CASE WHEN o.owner_id = om.user_id THEN TRUE ELSE FALSE END AS isOwner FROM organization_members om INNER JOIN users u ON u.identifier = om.user_id LEFT JOIN organizations o ON o.id = om.org_id WHERE om.org_id = @org_id ]], ['transactions'] =[[ SELECT ot.*, u.firstname, u.lastname FROM organization_transactions ot LEFT JOIN users u ON u.identifier = ot.user_id WHERE ot.org_id = @org_id ORDER BY ot.date DESC LIMIT 30 ]]}Config.canCreateOrganization=function(orgname,ownerId,cb)cb({success =true, message =''}) -- message is displaying as error in modalendConfig.showNotification=function(source,msg)TriggerClientEvent('ox_lib:notify', source, { title ='Organization Panel', description = msg, type ='inform' })endConfig.upgrades = { { name ='unlocked_wallet', -- name (not seen by players) title ='Wallet', description ='Unlocks the wallet panel.', icon ='fas fa-wallet', -- fontawesome icon (https://fontawesome.com/search?o=r&m=free)--cost = {value = 100, type = 'crypto'}, -- organization walletcanBuy=function(source) local count = exports.ox_inventory:Search(source, 'count', 'pendrive_wlt')if count ==0thenreturn {success =false, message ="You don't have required item."}elsereturn {success =true, message =''}endend,onBuy=function(orgid,src,cb)local count = exports.ox_inventory:Search(src, 'count', 'pendrive_wlt')if count ==0thencb({success =false, message ="You don't have required item."})elselocal success, info = exports.ox_inventory:RemoveItem(src, 'pendrive_wlt', 1)cb({success =true, message =''})endend }, { name ='members_upgrade_10', title ='Members', description ='Increases the maximum number of members from 5 to 10.', icon ='fas fa-user', cost = {value =25, type ='bank'},onBuy=function(orgId,src,cb)maxmembers(orgId, 10, cb)end }, { name ='members_upgrade_15', title ='Members v2', description ='Increases the maximum number of members from 10 to 15.', icon ='fas fa-user', cost = {value =50, type ='SectoCoin'},onBuy=function(orgId,src,cb)maxmembers(orgId, 15, cb)end,disabled=function(orgId,cb)doesOrgHaveUpgrade(orgId, 'members_upgrade_10', function(hasUpgrade)ifnot hasUpgrade thencb({disabled =true, message ='To purchase this upgrade, you must have the "Members" upgrade.'})elsecb({disabled =false})endend)end, }, { name ='members_upgrade_20', title ='Members v3', description ='Increases the maximum number of members from 15 to 20.', icon ='fas fa-user', cost = {value =60, type ='SectoCoin'},onBuy=function(orgId,src,cb)maxmembers(orgId, 20, cb)end,disabled=function(orgId,cb)doesOrgHaveUpgrade(orgId, 'members_upgrade_15', function(hasUpgrade15)doesOrgHaveUpgrade(orgId, 'members_upgrade_10', function(hasUpgrade10)ifnot hasUpgrade10 ornot hasUpgrade15 then cb({disabled = true, message = 'To purchase this upgrade, you must have the "Members v2" upgrade.'})
elsecb({success =false})endend)end)end }, { name ='interior_slots', title ='Slots in the stash', description ='Increases the maximum slots in an organization stash to 100.', icon ='fas fa-arrow-up-1-9', cost = {value =50, type ='SectoCoin'},disabled=function(orgid,cb)doesorghaveinterior(orgid, function(hasinterior)ifnot hasinterior thencb({disabled =true, message ='The organization has no registered property.'})elsecb({success =false})endend)end,onBuy=function(orgid,src,cb)local xPlayer = Framework.getPlayerFromId(src) MySQL.Async.fetchAll('SELECT * FROM organization_interiors WHERE org_id = @org_id', { ['@org_id'] = orgid }, function(interiorsResult)if interiorsResult and#interiorsResult >0thenlocal upgradesJSON = interiorsResult[1].upgradeslocal upgradesFromDB = json.decode(upgradesJSON) or {}table.insert(upgradesFromDB, 'slots')local updatedUpgradesJSON = json.encode(upgradesFromDB) MySQL.Async.execute('UPDATE organization_interiors SET upgrades = @upgrades WHERE org_id = @org_id', {
['@upgrades'] = updatedUpgradesJSON, ['@org_id'] = orgid }, function(rowsChanged)if rowsChanged >0thenif xPlayer then Config.showNotification(Framework.getSource(xPlayer), 'Attention! The changes will be visible after the next server restart.')
endcb({success =true, message ='Upgrades updated correctly.'})elsecb({success =false, message ='Failed to update upgrades.'})endend)elsecb({success =false, message ="The organization's properties were not found."})endend)end },}