Skip to content

Commit

Permalink
Update 1.0.5 - Added new command for selling insurances.
Browse files Browse the repository at this point in the history
- Added locals for better user experience.
- Added a new export for looking if a player has an active insurance: `exports['muhaddil_insurance']:hasValidInsurance()` or exports['muhaddil_insurance']:hasValidInsurance(playerId)`. Both clientside and serverside.
  • Loading branch information
Muhaddil committed Nov 19, 2024
1 parent 4299b89 commit 6c2f2ec
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 27 deletions.
110 changes: 110 additions & 0 deletions client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ elseif Config.FrameWork == "qb" then
QBCore = exports['qb-core']:GetCoreObject()
end

lib.locale()

function Notify(msgtitle, msg, time, type2)
if Config.UseOXNotifications then
lib.notify({
Expand Down Expand Up @@ -292,3 +294,111 @@ AddEventHandler('muhaddil_insurances:insurance:buyDiscount', function(data)
Notify(Config.DiscountAlreadyUsedTitle, Config.DiscountAlreadyUsedMessage, Config.NotificationDuration, "error")
end
end)

RegisterNetEvent('muhaddil_insurances:insurance:customPrice', function()
local nearbyPlayers = lib.getNearbyPlayers(GetEntityCoords(PlayerPedId()), Config.SellInsuraceRange, Config.CanSellInsuraceToHimself)

if not nearbyPlayers or #nearbyPlayers == 0 then
print(locale('no_nearby_players'))
return
end

local playerOptions = {}
for _, player in ipairs(nearbyPlayers) do
local serverId = GetPlayerServerId(player.id)
table.insert(playerOptions, {
value = serverId,
label = locale('select_nearby_player_label') .. ': ' .. serverId
})
end

local selectPlayer = lib.inputDialog(locale('select_nearby_player'), {
{type = 'select', label = locale('select_nearby_player_label'), options = playerOptions, required = true}
})

if not selectPlayer then return end

local targetPlayerId = selectPlayer[1]

local input = lib.inputDialog(locale('configure_custom_insurance'), {
{type = 'input', label = locale('insurance_type'), description = locale('insurance_type_description'), required = true},
{type = 'number', label = locale('insurance_duration'), description = locale('insurance_duration_description'), required = true, min = 1, max = Config.SellInsuraceMaxDays},
{type = 'number', label = locale('insurance_price'), description = locale('insurance_price_description'), required = true, min = 1}
})

if not input then return end

local insuranceType = input[1]
local duration = tonumber(input[2])
local price = tonumber(input[3])

if not insuranceType or duration <= 0 or price <= 0 then
print(locale('invalid_data'))
return
end

local accountType = Config.Account
TriggerServerEvent('muhaddil_insurances:insurance:buy', {
type = insuranceType,
duration = duration,
price = price
}, accountType, targetPlayerId)
end)

if Config.EnableSellCommand then
RegisterCommand('sellinsurances', function()
local playerId = GetPlayerServerId(PlayerId())
local jobName = nil

local allowedJobs = Config.CheckInsuranceCommandJob

if Config.FrameWork == "esx" then
ESX.TriggerServerCallback('esx:getPlayerData', function(playerData)
jobName = playerData.job.name
local hasAccess = false

for _, job in ipairs(allowedJobs) do
if job == jobName then
hasAccess = true
break
end
end

if hasAccess then
openSellInsurance()
else
Notify(Config.AccessDeniedTitle, Config.AccessDeniedMessage, Config.NotificationDuration, "error")
end
end, playerId)
elseif Config.FrameWork == "qb" then
local PlayerData = QBCore.Functions.GetPlayerData()
jobName = PlayerData.job.name
local hasAccess = false

for _, job in ipairs(allowedJobs) do
if job == jobName then
hasAccess = true
break
end
end

if hasAccess then
openSellInsurance()
else
Notify(Config.AccessDeniedTitle, Config.AccessDeniedMessage, Config.NotificationDuration, "error")
end
end
end)
end

exports("hasValidInsurance", function()
local promise = promise.new()

TriggerServerEvent('muhaddil_insurance:checkInsuranceExport')

RegisterNetEvent('muhaddil_insurance:insuranceResult', function(result)
promise:resolve(result)
end)

return Citizen.Await(promise)
end)
74 changes: 48 additions & 26 deletions config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,59 +48,57 @@ Config.AutoVersionChecker = true -- Enable or disable the automatic version chec


-- Edit this function to suit your requirements

function openInsuranceMenu(insuranceData)
local options = {}

if insuranceData then
-- If the player has insurance, display the current insurance details.
-- Si el jugador tiene un seguro, mostrar los detalles del seguro actual.
table.insert(options, {
title = 'Seguro Actual', -- Title for the current insurance option.
description = 'Tipo: ' .. insuranceData.type .. '\nTiempo restante: ' .. insuranceData.timeLeft, -- Description of current insurance.
title = locale('current_insurance'),
description = locale('insurance_type') .. ': ' .. insuranceData.type .. '\n' .. locale('time_left') .. ': ' .. insuranceData.timeLeft,
icon = 'info-circle',
disabled = false -- Option is enabled since the player has insurance.
disabled = false -- La opción está habilitada ya que el jugador tiene seguro.
})
else -- If the player does not have insurance.
-- Notify the player that they currently have no insurance.
else -- Si el jugador no tiene seguro.
-- Notificar al jugador que actualmente no tiene seguro.
table.insert(options, {
title = 'No tienes seguro actualmente', -- Title for the no insurance option.
title = locale('no_current_insurance'),
icon = 'info-circle',
disabled = true -- Option is disabled since the player has no insurance.
disabled = true -- La opción está deshabilitada ya que el jugador no tiene seguro.
})

-- Add different insurance options for purchase.
table.insert(options, {
title = 'Seguro Básico', -- Title for Basic Insurance.
description = 'Duración: 3 días\nPrecio: $10000', -- Description of Basic Insurance.
title = locale('basic_insurance'),
description = locale('duration') .. ': 3 ' .. locale('days') .. '\n' .. locale('price') .. ': $10000',
icon = 'circle',
event = 'muhaddil_insurances:insurance:buy',
args = { type = "basico", duration = 3, price = 10000 } -- Arguments for the event.
args = { type = "basico", duration = 3, price = 10000 } -- Argumentos para el evento.
})
table.insert(options, {
title = 'Seguro Semanal', -- Title for Weekly Insurance.
description = 'Duración: 7 días\nPrecio: $25000', -- Description of Weekly Insurance.
title = locale('weekly_insurance'),
description = locale('duration') .. ': 7 ' .. locale('days') .. '\n' .. locale('price') .. ': $25000',
icon = 'circle',
event = 'muhaddil_insurances:insurance:buy',
args = { type = "semanal", duration = 7, price = 25000 } -- Arguments for the event.
args = { type = "semanal", duration = 7, price = 25000 } -- Argumentos para el evento.
})
table.insert(options, {
title = 'Seguro Completo', -- Title for Full Insurance.
description = 'Duración: 15 días\nPrecio: $50000', -- Description of Full Insurance.
title = locale('full_insurance'),
description = locale('duration') .. ': 15 ' .. locale('days') .. '\n' .. locale('price') .. ': $50000',
icon = 'circle',
event = 'muhaddil_insurances:insurance:buy',
args = { type = "completo", duration = 15, price = 50000 } -- Arguments for the event.
args = { type = "completo", duration = 15, price = 50000 } -- Argumentos para el evento.
})
table.insert(options, {
title = 'Seguro Premium', -- Title for Premium Insurance.
description = 'Duración: 30 días\nPrecio: $100000', -- Description of Premium Insurance.
title = locale('premium_insurance'),
description = locale('duration') .. ': 30 ' .. locale('days') .. '\n' .. locale('price') .. ': $100000',
icon = 'circle',
event = 'muhaddil_insurances:insurance:buy',
args = { type = "premium", duration = 30, price = 100000 } -- Arguments for the event.
args = { type = "premium", duration = 30, price = 100000 } -- Argumentos para el evento.
})
if CanSellDiscountInsurance() then
table.insert(options, {
title = 'Vender Seguro con Descuento',
description = 'Duración: 30 días\nPrecio: $50000 (descuento)',
title = locale('sell_discount_insurance'),
description = locale('duration') .. ': 30 ' .. locale('days') .. '\n' .. locale('price') .. ': $50000 (' .. locale('discount') .. ')',
icon = 'circle',
event = 'muhaddil_insurances:insurance:buyDiscount',
args = { type = "premium", duration = 30, price = 50000 }
Expand All @@ -110,9 +108,33 @@ function openInsuranceMenu(insuranceData)

lib.registerContext({
id = 'insurance_menu',
title = 'Menú de Seguros', -- Title of the menu.
title = locale('insurance_menu_title'),
options = options
})

lib.showContext('insurance_menu')
end
end

function openSellInsurance()
local options = {}

table.insert(options, {
title = locale('sell_custom_insurance'),
description = locale('custom_insurance_description'),
icon = 'circle',
event = 'muhaddil_insurances:insurance:customPrice'
})

lib.registerContext({
id = 'insurance_menu_sell',
title = locale('insurance_menu_title'),
options = options
})

lib.showContext('insurance_menu_sell')
end

Config.EnableSellCommand = true
Config.CanSellInsuraceToHimself = true
Config.SellInsuraceRange = 5.0
Config.SellInsuraceMaxDays = 30
6 changes: 5 additions & 1 deletion fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ lua54 'yes'

author 'Muhaddil'
description 'Simple Medical Insurance Script'
version 'v1.0.4'
version 'v1.0.5'

shared_script 'config.lua'
client_script 'client.lua'
Expand All @@ -14,3 +14,7 @@ server_script {
}

shared_script '@ox_lib/init.lua'

files {
'locales/*.json'
}
31 changes: 31 additions & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"no_nearby_players": "No nearby players.",
"select_nearby_player": "Select Nearby Player",
"select_nearby_player_label": "Nearby Player",
"configure_custom_insurance": "Configure Custom Insurance",
"insurance_type": "Insurance Type",
"insurance_type_description": "For example: basic, weekly, full, premium",
"insurance_duration": "Duration (days)",
"insurance_duration_description": "Duration of the insurance in days.",
"insurance_price": "Price ($)",
"insurance_price_description": "Price of the insurance in dollars.",
"invalid_data": "Invalid data provided.",
"player_not_available": "The selected player is not available.",
"insurance_assigned": "Insurance assigned to player %s by %s",
"sell_custom_insurance": "Sell Custom Insurance",
"custom_insurance_description": "Configure a custom price for the insurance and sell it.",
"insurance_menu_title": "Insurance Menu",
"current_insurance": "Current Insurance",
"time_left": "Time Left",
"no_current_insurance": "You have no current insurance",
"basic_insurance": "Basic Insurance",
"weekly_insurance": "Weekly Insurance",
"full_insurance": "Full Insurance",
"premium_insurance": "Premium Insurance",
"sell_discount_insurance": "Sell Discount Insurance",
"duration": "Duration",
"days": "days",
"price": "Price",
"discount": "discount"
}

31 changes: 31 additions & 0 deletions locales/es.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"no_nearby_players": "No hay jugadores cerca.",
"select_nearby_player": "Seleccionar Jugador Cercano",
"select_nearby_player_label": "Jugador Cercano",
"configure_custom_insurance": "Configurar Seguro Personalizado",
"insurance_type": "Tipo de Seguro",
"insurance_type_description": "Por ejemplo: básico, semanal, completo, premium",
"insurance_duration": "Duración (días)",
"insurance_duration_description": "Duración del seguro en días.",
"insurance_price": "Precio ($)",
"insurance_price_description": "Precio del seguro en dólares.",
"invalid_data": "Datos inválidos proporcionados.",
"player_not_available": "El jugador seleccionado no está disponible.",
"insurance_assigned": "Seguro asignado al jugador %s por %s",
"sell_custom_insurance": "Vender Seguro Personalizado",
"custom_insurance_description": "Configura un precio personalizado para el seguro y véndelo.",
"insurance_menu_title": "Menú de Seguros",
"current_insurance": "Seguro Actual",
"time_left": "Tiempo Restante",
"no_current_insurance": "No tienes seguro actualmente",
"basic_insurance": "Seguro Básico",
"weekly_insurance": "Seguro Semanal",
"full_insurance": "Seguro Completo",
"premium_insurance": "Seguro Premium",
"sell_discount_insurance": "Vender Seguro con Descuento",
"duration": "Duración",
"days": "días",
"price": "Precio",
"discount": "descuento"
}

49 changes: 49 additions & 0 deletions server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,52 @@ if Config.AutoVersionChecker then
end
end, 'GET')
end

exports("hasValidInsurance", function(playerId)
local Player
local identifier

if not playerId then
playerId = source
end

if Config.FrameWork == "esx" then
Player = ESX.GetPlayerFromId(playerId)
if Player then
identifier = Player.getIdentifier()
end
elseif Config.FrameWork == "qb" then
Player = QBCore.Functions.GetPlayer(playerId)
if Player then
identifier = Player.PlayerData.license
end
end

if identifier then
local promise = promise.new()
MySQL.Async.fetchScalar('SELECT COUNT(*) FROM user_insurances WHERE identifier = @identifier', {
['@identifier'] = identifier
}, function(result)
if result > 0 then
promise:resolve(true)
else
promise:resolve(false)
end
end)
return Citizen.Await(promise)
else
return false
end
end)

RegisterNetEvent('muhaddil_insurance:syncInsuranceStatus', function(playerId)
local hasInsurance = exports['muhaddil_insurance']:hasValidInsurance(playerId)
TriggerClientEvent('muhaddil_insurance:updateInsuranceStatus', playerId, hasInsurance)
end)

RegisterNetEvent('muhaddil_insurance:checkInsuranceExport', function()
local playerId = source
local hasInsurance = exports['muhaddil_insurance']:hasValidInsurance(playerId)

TriggerClientEvent('muhaddil_insurance:insuranceResult', playerId, hasInsurance)
end)

0 comments on commit 6c2f2ec

Please sign in to comment.