diff --git a/client.lua b/client.lua new file mode 100644 index 0000000..f23a12a --- /dev/null +++ b/client.lua @@ -0,0 +1,52 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +PlayerJob = {} + +local onDuty = false + +RegisterNetEvent('QBCore:Client:OnPlayerLoaded') +AddEventHandler('QBCore:Client:OnPlayerLoaded', function() + QBCore.Functions.GetPlayerData(function(PlayerData) + PlayerJob = PlayerData.job + end) +end) + +RegisterNetEvent('QBCore:Client:OnJobUpdate') +AddEventHandler('QBCore:Client:OnJobUpdate', function(JobInfo) + PlayerJob = JobInfo + onDuty = PlayerJob.onduty +end) + +RegisterNetEvent('QBCore:Client:SetDuty') +AddEventHandler('QBCore:Client:SetDuty', function(duty) + onDuty = duty +end) + +--Keeps track of duty on script restarts +AddEventHandler('onResourceStart', function(resource) if GetCurrentResourceName() == resource then QBCore.Functions.GetPlayerData(function(PlayerData) PlayerJob = PlayerData.job end) end end) + +Citizen.CreateThread(function() + local jobroles = {} + for k, v in pairs(Config.Jobs) do jobroles[tostring(k)] = 0 end + exports['qb-target']:AddBoxZone("JimBank", vector3(251.75, 222.17, 106.2), 0.6, 2.0, { name="JimBank", heading = 340.0, debugPoly=false, minZ = 105.75, maxZ = 107.29, }, + { options = { { type = 'server', event = "jim-payments:Tickets:Sell", icon = "fas fa-receipt", label = "Cash in Receipts", job = jobroles }, }, + distance = 2.0 + }) +end) + +RegisterNetEvent('jim-payments:client:Charge', function() + if not onDuty then TriggerEvent("QBCore:Notify", "Not Clocked in!", "error") return end -- Require to be on duty when making a payment + QBCore.Functions.TriggerCallback('jim-payments:server:GetCurrentPlayers', function(playerList) + if playerList[1] == nil then TriggerEvent("QBCore:Notify", "No one near by to charge", "error") return end + local dialog = exports['qb-input']:ShowInput({ header = "Charge Customer", submitText = "Send", + inputs = { + { text = "Citizen", name = "citizen", type = "select", options = playerList }, + { type = 'number', isRequired = true, name = 'price', text = 'Amount to Charge' }, + { type = 'radio', name = 'billtype', text = 'Payment Type', options = { { value = "cash", text = "Cash" }, { value = "card", text = "Card" } } }, } + }) + if dialog then + if not dialog.citizen or not dialog.price then return end + TriggerServerEvent('jim-payments:server:Charge', dialog.citizen, dialog.price, dialog.billtype) + end + end) +end) \ No newline at end of file diff --git a/config.lua b/config.lua new file mode 100644 index 0000000..5afdab7 --- /dev/null +++ b/config.lua @@ -0,0 +1,20 @@ +print("Jim-Payments v1.0 - Payments Script by Jimathy") + +-- If you need support I now have a discord available, it helps me keep track of issues and give better support. + +-- https://discord.gg/xKgQZ6wZvS + +Config = {} + +Config.PaymentRadius = 30 -- This is how far the player list will check + +Config.Jobs = { + ['popsdiner'] = { MinAmountforTicket = 50, PayPerTicket = 50 }, + ['henhouse'] = { MinAmountforTicket = 50, PayPerTicket = 50 }, + ['pizzathis'] = { MinAmountforTicket = 50, PayPerTicket = 50 }, + ['burgershot'] = { MinAmountforTicket = 50, PayPerTicket = 50 }, + ['catcafe'] = { MinAmountforTicket = 50, PayPerTicket = 50 }, + ['tequilala'] = { MinAmountforTicket = 50, PayPerTicket = 50 }, + ['vanilla'] = { MinAmountforTicket = 50, PayPerTicket = 50 }, + ['mechanic'] = { MinAmountforTicket = 1000, PayPerTicket = 500 }, +} \ No newline at end of file diff --git a/fxmanifest.lua b/fxmanifest.lua new file mode 100644 index 0000000..386e9f9 --- /dev/null +++ b/fxmanifest.lua @@ -0,0 +1,23 @@ +name "Jim-Payments" +author "Jimathy" +version "v1.0" +description "Payment Script By Jimathy" +fx_version "cerulean" +game "gta5" + +dependencies { + 'qb-input', +} + +client_scripts { + 'client.lua' +} + +server_scripts { + '@oxmysql/lib/MySQL.lua', + 'server.lua' +} + +shared_scripts { + 'config.lua', +} \ No newline at end of file diff --git a/images/ticket.png b/images/ticket.png new file mode 100644 index 0000000..eefef4f Binary files /dev/null and b/images/ticket.png differ diff --git a/server.lua b/server.lua new file mode 100644 index 0000000..65e5df5 --- /dev/null +++ b/server.lua @@ -0,0 +1,76 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +RegisterServerEvent('jim-payments:Tickets:Give') +AddEventHandler('jim-payments:Tickets:Give', function(amount, job) + for k, v in pairs(QBCore.Functions.GetPlayers()) do + local Player = QBCore.Functions.GetPlayer(v) + if Player ~= nil then + if Player.PlayerData.job.name == job and Player.PlayerData.job.onduty then + if amount >= Config.Jobs[job].MinAmountforTicket then + Player.Functions.AddItem('payticket', 1, false, {["quality"] = nil}) + TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, 'Receipt received', 'success') + TriggerClientEvent('inventory:client:ItemBox', Player.PlayerData.source, QBCore.Shared.Items['payticket'], "add", 1) + elseif amount < Config.Jobs[job].MinAmountforTicket then + TriggerClientEvent("QBCore:Notify", Player.PlayerData.source, "Amount too low, didn't receive a receipt", "error") + end + end + end + end +end) + +RegisterServerEvent('jim-payments:Tickets:Sell') +AddEventHandler('jim-payments:Tickets:Sell', function(data) + local Player = QBCore.Functions.GetPlayer(source) + if Player.Functions.GetItemByName("payticket") == nil then TriggerClientEvent('QBCore:Notify', source, "No tickets to trade", 'error') return + else + tickets = Player.Functions.GetItemByName("payticket").amount + Player.Functions.RemoveItem('payticket', tickets) + Player.Functions.AddMoney('bank', (tickets * Confing.Jobs[Player.PlayerData.job.name].PayPerTicket), 'ticket-payment') + TriggerClientEvent('inventory:client:ItemBox', source, QBCore.Shared.Items['payticket'], "remove", tickets) + TriggerClientEvent('QBCore:Notify', source, "Tickets: "..tickets.." Total: $"..pay, 'success') + end +end) + +RegisterServerEvent("jim-payments:server:Charge", function(citizen, price, billtype) + local biller = QBCore.Functions.GetPlayer(source) + local billed = QBCore.Functions.GetPlayer(tonumber(citizen)) + local amount = tonumber(price) + local billtype = string.lower(tostring(billtype)) + + if billed ~= nil then + if billtype == "cash" then balance = billed.Functions.GetMoney(billtype) + if source == tonumber(citizen) then TriggerClientEvent('QBCore:Notify', source, 'You Cannot Bill Yourself', 'error') return end + if balance >= amount then + billed.Functions.RemoveMoney('cash', amount) TriggerEvent("qb-bossmenu:server:addAccountMoney", tostring(biller.PlayerData.job.name), amount) + TriggerEvent('jim-payments:Tickets:Give', amount, tostring(biller.PlayerData.job.name)) + elseif balance < amount then + TriggerClientEvent("QBCore:Notify", source, "Customer doesn't have enough cash to pay", "error") + TriggerClientEvent("QBCore:Notify", tonumber(citizen), "You don't have enough cash to pay", "error") + end + elseif billtype == "card" then + if biller.PlayerData.citizenid == billed.PlayerData.citizenid then TriggerClientEvent('QBCore:Notify', source, 'You Cannot Bill Yourself', 'error') return end + if amount and amount > 0 then + MySQL.Async.insert( + 'INSERT INTO phone_invoices (citizenid, amount, society, sender, sendercitizenid) VALUES (?, ?, ?, ?, ?)', + {billed.PlayerData.citizenid, amount, biller.PlayerData.job.name, + biller.PlayerData.charinfo.firstname, biller.PlayerData.citizenid}) + TriggerClientEvent('qb-phone:RefreshPhone', billed.PlayerData.source) + TriggerClientEvent('QBCore:Notify', source, 'Invoice Successfully Sent', 'success') + TriggerClientEvent('QBCore:Notify', billed.PlayerData.source, 'New Invoice Received') + else TriggerClientEvent('QBCore:Notify', source, 'Must Be A Valid Amount Above 0', 'error') end + end + else TriggerClientEvent('QBCore:Notify', source, 'Player Not Online', 'error') end +end) + +QBCore.Functions.CreateCallback('jim-payments:server:GetCurrentPlayers', function(source, cb) + local onlineList = {} + local SPlayer = QBCore.Functions.GetPlayer(source) + for k, v in pairs(QBCore.Functions.GetPlayers()) do + local Player = QBCore.Functions.GetPlayer(v) + if Player ~= nil and v ~= source then + local dist = #(vector3(Player.PlayerData.position.x, Player.PlayerData.position.y, Player.PlayerData.position.z) - vector3(SPlayer.PlayerData.position.x, SPlayer.PlayerData.position.y, SPlayer.PlayerData.position.z)) + if dist < Config.PaymentRadius then onlineList[#onlineList+1] = { value = tonumber(v), text = "["..v.."] - "..Player.PlayerData.charinfo.firstname..' '..Player.PlayerData.charinfo.lastname } end + end + end + cb(onlineList) +end) \ No newline at end of file