forked from Simnation/Main
ed
This commit is contained in:
parent
d72b640e12
commit
bb5b4ae2f0
2 changed files with 169 additions and 112 deletions
|
@ -168,8 +168,8 @@ function ShowBillingForm(selectedPlayer, accountOptions)
|
||||||
timestamp = GetGameTimer()
|
timestamp = GetGameTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Show waiting screen
|
-- Show waiting screen with all details
|
||||||
ShowWaitingScreen(billData.billId, selectedPlayer.name)
|
ShowWaitingScreen(billData.billId, selectedPlayer.name, input[1], input[2])
|
||||||
else
|
else
|
||||||
lib.notify({
|
lib.notify({
|
||||||
title = 'Billing System',
|
title = 'Billing System',
|
||||||
|
@ -183,14 +183,27 @@ function ShowBillingForm(selectedPlayer, accountOptions)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Function to show waiting screen
|
-- Function to show waiting screen
|
||||||
function ShowWaitingScreen(billId, playerName)
|
function ShowWaitingScreen(billId, playerName, amount, reason)
|
||||||
|
-- Create a more informative waiting screen
|
||||||
lib.registerContext({
|
lib.registerContext({
|
||||||
id = 'bill_waiting_screen',
|
id = 'bill_waiting_screen',
|
||||||
title = 'Warte auf Antwort',
|
title = 'Warte auf Zahlung',
|
||||||
options = {
|
options = {
|
||||||
{
|
{
|
||||||
title = 'Rechnung gesendet',
|
title = 'Rechnung Details',
|
||||||
description = 'Warte auf Antwort von ' .. playerName,
|
description = 'Gesendet an: ' .. playerName,
|
||||||
|
metadata = {
|
||||||
|
{label = 'Betrag', value = '$' .. amount},
|
||||||
|
{label = 'Grund', value = reason},
|
||||||
|
{label = 'Status', value = 'Warte auf Antwort...'},
|
||||||
|
},
|
||||||
|
icon = 'file-invoice-dollar',
|
||||||
|
disabled = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title = 'Warte auf Antwort',
|
||||||
|
progress = 100, -- This creates a loading bar
|
||||||
|
description = playerName .. ' entscheidet über die Rechnung',
|
||||||
icon = 'clock',
|
icon = 'clock',
|
||||||
disabled = true
|
disabled = true
|
||||||
},
|
},
|
||||||
|
@ -207,6 +220,73 @@ function ShowWaitingScreen(billId, playerName)
|
||||||
})
|
})
|
||||||
|
|
||||||
lib.showContext('bill_waiting_screen')
|
lib.showContext('bill_waiting_screen')
|
||||||
|
|
||||||
|
-- Start a loading animation
|
||||||
|
Citizen.CreateThread(function()
|
||||||
|
local dots = 0
|
||||||
|
local loadingText = {'Warte', 'Warte.', 'Warte..', 'Warte...'}
|
||||||
|
local progress = 100
|
||||||
|
|
||||||
|
while pendingBills[billId] do
|
||||||
|
Citizen.Wait(500)
|
||||||
|
dots = (dots + 1) % 4
|
||||||
|
|
||||||
|
-- Update the context menu with new loading text
|
||||||
|
lib.registerContext({
|
||||||
|
id = 'bill_waiting_screen',
|
||||||
|
title = 'Warte auf Zahlung',
|
||||||
|
options = {
|
||||||
|
{
|
||||||
|
title = 'Rechnung Details',
|
||||||
|
description = 'Gesendet an: ' .. playerName,
|
||||||
|
metadata = {
|
||||||
|
{label = 'Betrag', value = '$' .. amount},
|
||||||
|
{label = 'Grund', value = reason},
|
||||||
|
{label = 'Status', value = 'Warte auf Antwort...'},
|
||||||
|
},
|
||||||
|
icon = 'file-invoice-dollar',
|
||||||
|
disabled = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title = loadingText[dots + 1],
|
||||||
|
progress = progress,
|
||||||
|
description = playerName .. ' entscheidet über die Rechnung',
|
||||||
|
icon = 'clock',
|
||||||
|
disabled = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title = 'Abbrechen',
|
||||||
|
description = 'Zurück zum Hauptmenü',
|
||||||
|
icon = 'times-circle',
|
||||||
|
onSelect = function()
|
||||||
|
pendingBills[billId] = nil
|
||||||
|
OpenMainBillingMenu()
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Only refresh the context if it's still showing
|
||||||
|
if isMenuOpen('bill_waiting_screen') then
|
||||||
|
lib.showContext('bill_waiting_screen')
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cycle the progress bar
|
||||||
|
progress = progress - 5
|
||||||
|
if progress <= 0 then
|
||||||
|
progress = 100
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Helper function to check if a menu is open
|
||||||
|
function isMenuOpen(menuId)
|
||||||
|
-- This is a placeholder - ox_lib doesn't provide a direct way to check
|
||||||
|
-- You might need to track this yourself or use a different approach
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Function to show payment account selection
|
-- Function to show payment account selection
|
||||||
|
@ -585,19 +665,46 @@ RegisterNetEvent('billing:client:billResponse', function(billId, action, playerN
|
||||||
lib.notify({
|
lib.notify({
|
||||||
title = 'Rechnung bezahlt',
|
title = 'Rechnung bezahlt',
|
||||||
description = playerName .. ' hat deine Rechnung über $' .. bill.amount .. ' bezahlt',
|
description = playerName .. ' hat deine Rechnung über $' .. bill.amount .. ' bezahlt',
|
||||||
type = 'success'
|
type = 'success',
|
||||||
|
duration = 7000
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Show a more detailed success message
|
||||||
|
lib.alertDialog({
|
||||||
|
header = 'Zahlung erhalten',
|
||||||
|
content = playerName .. ' hat deine Rechnung über $' .. bill.amount .. ' für "' .. bill.reason .. '" bezahlt.',
|
||||||
|
centered = true,
|
||||||
|
cancel = false
|
||||||
})
|
})
|
||||||
elseif action == 'decline' then
|
elseif action == 'decline' then
|
||||||
lib.notify({
|
lib.notify({
|
||||||
title = 'Rechnung abgelehnt',
|
title = 'Rechnung abgelehnt',
|
||||||
description = playerName .. ' hat deine Rechnung über $' .. bill.amount .. ' abgelehnt',
|
description = playerName .. ' hat deine Rechnung über $' .. bill.amount .. ' abgelehnt',
|
||||||
type = 'error'
|
type = 'error',
|
||||||
|
duration = 7000
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Show a more detailed decline message
|
||||||
|
lib.alertDialog({
|
||||||
|
header = 'Rechnung abgelehnt',
|
||||||
|
content = playerName .. ' hat deine Rechnung über $' .. bill.amount .. ' für "' .. bill.reason .. '" abgelehnt.',
|
||||||
|
centered = true,
|
||||||
|
cancel = false
|
||||||
})
|
})
|
||||||
elseif action == 'later' then
|
elseif action == 'later' then
|
||||||
lib.notify({
|
lib.notify({
|
||||||
title = 'Rechnung gespeichert',
|
title = 'Rechnung gespeichert',
|
||||||
description = playerName .. ' wird deine Rechnung später bezahlen',
|
description = playerName .. ' wird deine Rechnung später bezahlen',
|
||||||
type = 'info'
|
type = 'info',
|
||||||
|
duration = 7000
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Show a more detailed "pay later" message
|
||||||
|
lib.alertDialog({
|
||||||
|
header = 'Zahlung aufgeschoben',
|
||||||
|
content = playerName .. ' hat deine Rechnung über $' .. bill.amount .. ' für "' .. bill.reason .. '" für später gespeichert.',
|
||||||
|
centered = true,
|
||||||
|
cancel = false
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -640,5 +747,3 @@ Citizen.CreateThread(function()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ lib.callback.register('billing:server:sendBill', function(source, data)
|
||||||
local target = QBCore.Functions.GetPlayer(data.playerId)
|
local target = QBCore.Functions.GetPlayer(data.playerId)
|
||||||
|
|
||||||
if not player or not target then
|
if not player or not target then
|
||||||
return false
|
return { success = false }
|
||||||
end
|
end
|
||||||
|
|
||||||
local senderName = player.PlayerData.charinfo.firstname .. ' ' .. player.PlayerData.charinfo.lastname
|
local senderName = player.PlayerData.charinfo.firstname .. ' ' .. player.PlayerData.charinfo.lastname
|
||||||
|
@ -29,6 +29,10 @@ lib.callback.register('billing:server:sendBill', function(source, data)
|
||||||
|
|
||||||
local billId = result[1] and result[1].id or nil
|
local billId = result[1] and result[1].id or nil
|
||||||
|
|
||||||
|
if not billId then
|
||||||
|
return { success = false }
|
||||||
|
end
|
||||||
|
|
||||||
-- Store additional data about the bill
|
-- Store additional data about the bill
|
||||||
MySQL.insert.await('INSERT INTO billing_accounts (bill_id, bill_description, sender_id, receiver_id, account_id, amount, created_at) VALUES (?, ?, ?, ?, ?, ?, NOW())', {
|
MySQL.insert.await('INSERT INTO billing_accounts (bill_id, bill_description, sender_id, receiver_id, account_id, amount, created_at) VALUES (?, ?, ?, ?, ?, ?, NOW())', {
|
||||||
billId,
|
billId,
|
||||||
|
@ -39,6 +43,13 @@ lib.callback.register('billing:server:sendBill', function(source, data)
|
||||||
data.amount
|
data.amount
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- Store sender information for notifications
|
||||||
|
MySQL.insert.await('INSERT INTO billing_senders (bill_id, sender_id, sender_source) VALUES (?, ?, ?)', {
|
||||||
|
billId,
|
||||||
|
player.PlayerData.citizenid,
|
||||||
|
src
|
||||||
|
})
|
||||||
|
|
||||||
-- Send payment prompt to target player
|
-- Send payment prompt to target player
|
||||||
TriggerClientEvent('billing:client:showPaymentPrompt', data.playerId, {
|
TriggerClientEvent('billing:client:showPaymentPrompt', data.playerId, {
|
||||||
billId = billId,
|
billId = billId,
|
||||||
|
@ -50,7 +61,11 @@ lib.callback.register('billing:server:sendBill', function(source, data)
|
||||||
-- Notify the sender
|
-- Notify the sender
|
||||||
TriggerClientEvent('QBCore:Notify', src, 'Rechnung über $' .. data.amount .. ' an ' .. target.PlayerData.charinfo.firstname .. ' gesendet', 'success')
|
TriggerClientEvent('QBCore:Notify', src, 'Rechnung über $' .. data.amount .. ' an ' .. target.PlayerData.charinfo.firstname .. ' gesendet', 'success')
|
||||||
|
|
||||||
return true
|
-- Return success with bill ID
|
||||||
|
return {
|
||||||
|
success = true,
|
||||||
|
billId = billId
|
||||||
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Add a callback to get bill status
|
-- Add a callback to get bill status
|
||||||
|
@ -86,7 +101,7 @@ lib.callback.register('billing:server:getAllBillStatuses', function(source)
|
||||||
return {}
|
return {}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Add a new callback for handling bill responses
|
-- Add a callback for handling bill responses
|
||||||
lib.callback.register('billing:server:handleBillResponse', function(source, data)
|
lib.callback.register('billing:server:handleBillResponse', function(source, data)
|
||||||
local src = source
|
local src = source
|
||||||
local player = QBCore.Functions.GetPlayer(src)
|
local player = QBCore.Functions.GetPlayer(src)
|
||||||
|
@ -348,6 +363,17 @@ MySQL.ready(function()
|
||||||
print("^2[nordi_billing] Created billing_accounts table^7")
|
print("^2[nordi_billing] Created billing_accounts table^7")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Create billing_senders table for tracking bill senders
|
||||||
|
MySQL.query.await([[
|
||||||
|
CREATE TABLE IF NOT EXISTS billing_senders (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
bill_id INT,
|
||||||
|
sender_id VARCHAR(50),
|
||||||
|
sender_source INT,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)
|
||||||
|
]])
|
||||||
|
|
||||||
-- Create offline_payments table if it doesn't exist
|
-- Create offline_payments table if it doesn't exist
|
||||||
MySQL.query.await([[
|
MySQL.query.await([[
|
||||||
CREATE TABLE IF NOT EXISTS offline_payments (
|
CREATE TABLE IF NOT EXISTS offline_payments (
|
||||||
|
@ -360,9 +386,31 @@ MySQL.ready(function()
|
||||||
)
|
)
|
||||||
]])
|
]])
|
||||||
print("^2[nordi_billing] Database tables initialized^7")
|
print("^2[nordi_billing] Database tables initialized^7")
|
||||||
end) -- Added closing parenthesis here
|
end)
|
||||||
|
|
||||||
|
-- Event to notify bill sender
|
||||||
|
RegisterNetEvent('billing:server:notifyBillSender', function(billId, action)
|
||||||
|
local src = source
|
||||||
|
local player = QBCore.Functions.GetPlayer(src)
|
||||||
|
|
||||||
|
if not player then return end
|
||||||
|
|
||||||
|
-- Get sender information
|
||||||
|
local senderInfo = MySQL.query.await('SELECT * FROM billing_senders WHERE bill_id = ?', {billId})
|
||||||
|
if not senderInfo or #senderInfo == 0 then return end
|
||||||
|
|
||||||
|
local senderSource = senderInfo[1].sender_source
|
||||||
|
|
||||||
|
-- Get bill information
|
||||||
|
local billInfo = MySQL.query.await('SELECT * FROM billing_accounts WHERE bill_id = ?', {billId})
|
||||||
|
if not billInfo or #billInfo == 0 then return end
|
||||||
|
|
||||||
|
local amount = billInfo[1].amount
|
||||||
|
local playerName = player.PlayerData.charinfo.firstname .. ' ' .. player.PlayerData.charinfo.lastname
|
||||||
|
|
||||||
|
-- Notify the sender
|
||||||
|
TriggerClientEvent('billing:client:billResponse', senderSource, billId, action, playerName)
|
||||||
|
end)
|
||||||
|
|
||||||
-- Handle offline payments when a player logs in
|
-- Handle offline payments when a player logs in
|
||||||
RegisterNetEvent('QBCore:Server:PlayerLoaded', function()
|
RegisterNetEvent('QBCore:Server:PlayerLoaded', function()
|
||||||
|
@ -418,99 +466,3 @@ QBCore.Commands.Add('bills', 'Zeige deine unbezahlten Rechnungen an', {}, false,
|
||||||
-- This will trigger the client to open the bills menu
|
-- This will trigger the client to open the bills menu
|
||||||
TriggerClientEvent('billing:client:openBillsMenu', source)
|
TriggerClientEvent('billing:client:openBillsMenu', source)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Event handler for opening bills menu from command
|
|
||||||
RegisterNetEvent('billing:client:openBillsMenu', function()
|
|
||||||
-- This is handled on the client side
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Add a server event to notify bill sender when a bill is paid
|
|
||||||
RegisterServerEvent('billing:server:notifyBillPaid', function(senderId, amount, receiverName)
|
|
||||||
local sender = QBCore.Functions.GetPlayerByCitizenId(senderId)
|
|
||||||
if sender then
|
|
||||||
TriggerClientEvent('QBCore:Notify', sender.PlayerData.source, receiverName .. ' hat deine Rechnung über $' .. amount .. ' bezahlt', 'success')
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Add a server event to notify bill sender when a bill is declined
|
|
||||||
RegisterServerEvent('billing:server:notifyBillDeclined', function(senderId, amount, receiverName)
|
|
||||||
local sender = QBCore.Functions.GetPlayerByCitizenId(senderId)
|
|
||||||
if sender then
|
|
||||||
TriggerClientEvent('QBCore:Notify', sender.PlayerData.source, receiverName .. ' hat deine Rechnung über $' .. amount .. ' abgelehnt', 'error')
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Add a new callback for handling bill responses
|
|
||||||
lib.callback.register('billing:server:handleBillResponse', function(source, data)
|
|
||||||
local src = source
|
|
||||||
local player = QBCore.Functions.GetPlayer(src)
|
|
||||||
|
|
||||||
if not player then return false end
|
|
||||||
|
|
||||||
if data.action == 'pay' then
|
|
||||||
-- Process payment based on selected account
|
|
||||||
if data.accountId == 'personal' then
|
|
||||||
-- Pay from personal bank account
|
|
||||||
local billResult = MySQL.query.await('SELECT * FROM ps_banking_bills WHERE id = ?', {data.billId})
|
|
||||||
if not billResult or #billResult == 0 then return false end
|
|
||||||
|
|
||||||
local bill = billResult[1]
|
|
||||||
local amount = tonumber(bill.amount)
|
|
||||||
|
|
||||||
-- Check if player has enough money in their bank account
|
|
||||||
if player.PlayerData.money["bank"] < amount then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Process payment manually instead of using callback to avoid issues
|
|
||||||
player.Functions.RemoveMoney("bank", amount, "bill-payment")
|
|
||||||
|
|
||||||
-- IMPORTANT: Delete the bill from ps_banking_bills table
|
|
||||||
MySQL.query.await('DELETE FROM ps_banking_bills WHERE id = ?', {data.billId})
|
|
||||||
|
|
||||||
-- Process the payment to the recipient's account
|
|
||||||
ProcessBillPayment(data.billId)
|
|
||||||
|
|
||||||
-- Notify the player
|
|
||||||
TriggerClientEvent('QBCore:Notify', src, 'Du hast die Rechnung über $' .. amount .. ' bezahlt', 'success')
|
|
||||||
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
-- Pay from shared account
|
|
||||||
local success = PayBillFromSharedAccount(src, data.billId, data.accountId)
|
|
||||||
return success
|
|
||||||
end
|
|
||||||
elseif data.action == 'decline' then
|
|
||||||
-- Mark as declined in our system
|
|
||||||
MySQL.update.await('UPDATE billing_accounts SET declined = 1 WHERE bill_id = ?', {data.billId})
|
|
||||||
|
|
||||||
-- IMPORTANT: Delete the bill from ps_banking_bills table when declined
|
|
||||||
MySQL.query.await('DELETE FROM ps_banking_bills WHERE id = ?', {data.billId})
|
|
||||||
|
|
||||||
-- Find the sender to notify them
|
|
||||||
local billInfo = MySQL.query.await('SELECT * FROM billing_accounts WHERE bill_id = ?', {data.billId})
|
|
||||||
if billInfo and #billInfo > 0 then
|
|
||||||
local senderId = billInfo[1].sender_id
|
|
||||||
local sender = QBCore.Functions.GetPlayerByCitizenId(senderId)
|
|
||||||
|
|
||||||
if sender then
|
|
||||||
TriggerClientEvent('QBCore:Notify', sender.PlayerData.source, 'Deine Rechnung wurde abgelehnt', 'error')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Notify the player
|
|
||||||
TriggerClientEvent('QBCore:Notify', src, 'Du hast die Rechnung abgelehnt', 'info')
|
|
||||||
|
|
||||||
return true
|
|
||||||
elseif data.action == 'later' then
|
|
||||||
-- Simply close the prompt without any action
|
|
||||||
-- The bill will remain in the system as unpaid
|
|
||||||
|
|
||||||
-- Notify the player
|
|
||||||
TriggerClientEvent('QBCore:Notify', src, 'Die Rechnung wurde für später gespeichert', 'info')
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end)
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue