534 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			534 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
-- Initialize QBCore
 | 
						|
local QBCore = exports['qb-core']:GetCoreObject()
 | 
						|
 | 
						|
-- Register callback for sending bills
 | 
						|
lib.callback.register('billing:server:sendBill', function(source, data)
 | 
						|
    local src = source
 | 
						|
    local player = QBCore.Functions.GetPlayer(src)
 | 
						|
    local target = QBCore.Functions.GetPlayer(data.playerId)
 | 
						|
    
 | 
						|
    if not player or not target then
 | 
						|
        return { success = false }
 | 
						|
    end
 | 
						|
    
 | 
						|
    local senderName = player.PlayerData.charinfo.firstname .. ' ' .. player.PlayerData.charinfo.lastname
 | 
						|
    local description = data.reason .. ' (Von: ' .. senderName .. ')'
 | 
						|
    
 | 
						|
    -- Create the bill
 | 
						|
    exports["ps-banking"]:createBill({
 | 
						|
        identifier = target.PlayerData.citizenid,
 | 
						|
        description = description,
 | 
						|
        type = "Invoice",
 | 
						|
        amount = data.amount,
 | 
						|
    })
 | 
						|
    
 | 
						|
    -- Get the latest bill ID for this user (assuming it's the one we just created)
 | 
						|
    local result = MySQL.query.await('SELECT id FROM ps_banking_bills WHERE identifier = ? ORDER BY id DESC LIMIT 1', {
 | 
						|
        target.PlayerData.citizenid
 | 
						|
    })
 | 
						|
    
 | 
						|
    local billId = result[1] and result[1].id or nil
 | 
						|
    
 | 
						|
    if not billId then
 | 
						|
        return { success = false }
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- 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())', {
 | 
						|
        billId,
 | 
						|
        description,
 | 
						|
        player.PlayerData.citizenid,
 | 
						|
        target.PlayerData.citizenid,
 | 
						|
        data.account,
 | 
						|
        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
 | 
						|
    TriggerClientEvent('billing:client:showPaymentPrompt', data.playerId, {
 | 
						|
        billId = billId,
 | 
						|
        amount = data.amount,
 | 
						|
        reason = data.reason,
 | 
						|
        sender = senderName
 | 
						|
    })
 | 
						|
    
 | 
						|
    -- Notify the sender
 | 
						|
    TriggerClientEvent('QBCore:Notify', src, 'Rechnung über $' .. data.amount .. ' an ' .. target.PlayerData.charinfo.firstname .. ' gesendet', 'success')
 | 
						|
    
 | 
						|
    -- Return success with bill ID
 | 
						|
    return { 
 | 
						|
        success = true,
 | 
						|
        billId = billId
 | 
						|
    }
 | 
						|
end)
 | 
						|
 | 
						|
-- Add a callback to get bill status
 | 
						|
lib.callback.register('billing:server:getBillStatus', function(source, billId)
 | 
						|
    local src = source
 | 
						|
    local player = QBCore.Functions.GetPlayer(src)
 | 
						|
    
 | 
						|
    if not player then return nil end
 | 
						|
    
 | 
						|
    local result = MySQL.query.await('SELECT * FROM billing_accounts WHERE bill_id = ?', {billId})
 | 
						|
    if result and #result > 0 then
 | 
						|
        return result[1]
 | 
						|
    end
 | 
						|
    
 | 
						|
    return nil
 | 
						|
end)
 | 
						|
 | 
						|
-- Add a callback to get all bill statuses for a player
 | 
						|
lib.callback.register('billing:server:getAllBillStatuses', function(source)
 | 
						|
    local src = source
 | 
						|
    local player = QBCore.Functions.GetPlayer(src)
 | 
						|
    
 | 
						|
    if not player then return nil end
 | 
						|
    
 | 
						|
    local citizenId = player.PlayerData.citizenid
 | 
						|
    
 | 
						|
    -- Get all bill statuses for this player
 | 
						|
    local result = MySQL.query.await('SELECT * FROM billing_accounts WHERE receiver_id = ?', {citizenId})
 | 
						|
    if result and #result > 0 then
 | 
						|
        return result
 | 
						|
    end
 | 
						|
    
 | 
						|
    return {}
 | 
						|
end)
 | 
						|
 | 
						|
-- Add a 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")
 | 
						|
            
 | 
						|
            -- Log transaction in ps-banking history for the payer
 | 
						|
            MySQL.insert.await('INSERT INTO ps_banking_transactions (identifier, description, type, amount, date, isIncome) VALUES (?, ?, ?, ?, NOW(), ?)', {
 | 
						|
                player.PlayerData.citizenid,
 | 
						|
                "Bezahlte Rechnung: " .. bill.description,
 | 
						|
                "bank",
 | 
						|
                amount,
 | 
						|
                false -- isIncome = false
 | 
						|
            })
 | 
						|
            
 | 
						|
            -- 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
 | 
						|
    end
 | 
						|
    
 | 
						|
    return false
 | 
						|
end)
 | 
						|
 | 
						|
-- Function to pay bill from a shared account
 | 
						|
function PayBillFromSharedAccount(source, billId, accountId)
 | 
						|
    local src = source
 | 
						|
    local player = QBCore.Functions.GetPlayer(src)
 | 
						|
    
 | 
						|
    if not player then return false end
 | 
						|
    
 | 
						|
    -- Get bill details
 | 
						|
    local billResult = MySQL.query.await('SELECT * FROM ps_banking_bills WHERE id = ?', {billId})
 | 
						|
    if not billResult or #billResult == 0 then return false end
 | 
						|
    
 | 
						|
    local bill = billResult[1]
 | 
						|
    local amount = tonumber(bill.amount)
 | 
						|
    
 | 
						|
    -- Get account details
 | 
						|
    local accountResult = MySQL.query.await('SELECT * FROM ps_banking_accounts WHERE id = ?', {accountId})
 | 
						|
    if not accountResult or #accountResult == 0 then return false end
 | 
						|
    
 | 
						|
    local account = accountResult[1]
 | 
						|
    
 | 
						|
    -- Check if player has access to this account
 | 
						|
    local hasAccess = false
 | 
						|
    local accountOwner = json.decode(account.owner)
 | 
						|
    local accountUsers = json.decode(account.users)
 | 
						|
    
 | 
						|
    if accountOwner.identifier == player.PlayerData.citizenid then
 | 
						|
        hasAccess = true
 | 
						|
    else
 | 
						|
        for _, user in ipairs(accountUsers) do
 | 
						|
            if user.identifier == player.PlayerData.citizenid then
 | 
						|
                hasAccess = true
 | 
						|
                break
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    if not hasAccess then 
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'Du hast keinen Zugriff auf dieses Konto', 'error')
 | 
						|
        return false 
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Check if account has enough balance
 | 
						|
    if tonumber(account.balance) < amount then 
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'Nicht genug Geld auf diesem Konto', 'error')
 | 
						|
        return false 
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Process payment
 | 
						|
    MySQL.update.await('UPDATE ps_banking_accounts SET balance = balance - ? WHERE id = ?', {amount, accountId})
 | 
						|
    
 | 
						|
    -- Log transaction in ps-banking history for the account owner
 | 
						|
    MySQL.insert.await('INSERT INTO ps_banking_transactions (identifier, description, type, amount, date, isIncome) VALUES (?, ?, ?, ?, NOW(), ?)', {
 | 
						|
        accountOwner.identifier,
 | 
						|
        "Bezahlte Rechnung von Konto " .. account.holder .. ": " .. bill.description,
 | 
						|
        "bank",
 | 
						|
        amount,
 | 
						|
        false -- isIncome = false
 | 
						|
    })
 | 
						|
    
 | 
						|
    -- IMPORTANT: Delete the bill from ps_banking_bills table
 | 
						|
    MySQL.query.await('DELETE FROM ps_banking_bills WHERE id = ?', {billId})
 | 
						|
    
 | 
						|
    -- Process the payment to the recipient's account
 | 
						|
    ProcessBillPayment(billId)
 | 
						|
    
 | 
						|
    -- Notify the player
 | 
						|
    TriggerClientEvent('QBCore:Notify', src, 'Du hast die Rechnung über $' .. amount .. ' vom Konto ' .. account.holder .. ' bezahlt', 'success')
 | 
						|
    
 | 
						|
    return true
 | 
						|
end
 | 
						|
 | 
						|
-- Add a callback for paying bill from selected account
 | 
						|
lib.callback.register('billing:server:payBillFromAccount', function(source, data)
 | 
						|
    local src = source
 | 
						|
    local player = QBCore.Functions.GetPlayer(src)
 | 
						|
    
 | 
						|
    if not player then return false end
 | 
						|
    
 | 
						|
    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
 | 
						|
            TriggerClientEvent('QBCore:Notify', src, 'Nicht genug Geld auf deinem Konto', 'error')
 | 
						|
            return false
 | 
						|
        end
 | 
						|
        
 | 
						|
        -- Process payment manually
 | 
						|
        player.Functions.RemoveMoney("bank", amount, "bill-payment")
 | 
						|
        
 | 
						|
        -- Log transaction in ps-banking history for the payer
 | 
						|
        MySQL.insert.await('INSERT INTO ps_banking_transactions (identifier, description, type, amount, date, isIncome) VALUES (?, ?, ?, ?, NOW(), ?)', {
 | 
						|
            player.PlayerData.citizenid,
 | 
						|
            "Bezahlte Rechnung: " .. bill.description,
 | 
						|
            "bank",
 | 
						|
            amount,
 | 
						|
            false -- isIncome = false
 | 
						|
        })
 | 
						|
        
 | 
						|
        -- 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
 | 
						|
        return PayBillFromSharedAccount(src, data.billId, data.accountId)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Function to process bill payment to recipient
 | 
						|
function ProcessBillPayment(billId)
 | 
						|
    -- Find the bill in our custom table
 | 
						|
    local billData = MySQL.query.await('SELECT * FROM billing_accounts WHERE bill_id = ?', {billId})
 | 
						|
    
 | 
						|
    if billData and #billData > 0 then
 | 
						|
        local bill = billData[1]
 | 
						|
        local receiverId = bill.sender_id
 | 
						|
        local accountId = bill.account_id
 | 
						|
        local amount = tonumber(bill.amount)
 | 
						|
        local description = bill.bill_description or "Rechnungszahlung"
 | 
						|
        
 | 
						|
        -- If it's a personal account
 | 
						|
        if accountId == 'personal' then
 | 
						|
            local receiver = QBCore.Functions.GetPlayerByCitizenId(receiverId)
 | 
						|
            if receiver then
 | 
						|
                -- Add money directly to the receiver's bank account
 | 
						|
                receiver.Functions.AddMoney('bank', amount, 'bill-payment')
 | 
						|
                
 | 
						|
                -- Log transaction in ps-banking history for the receiver
 | 
						|
                MySQL.insert.await('INSERT INTO ps_banking_transactions (identifier, description, type, amount, date, isIncome) VALUES (?, ?, ?, ?, NOW(), ?)', {
 | 
						|
                    receiverId,
 | 
						|
                    "Erhaltene Rechnung: " .. description,
 | 
						|
                    "bank",
 | 
						|
                    amount,
 | 
						|
                    true -- isIncome = true
 | 
						|
                })
 | 
						|
                
 | 
						|
                TriggerClientEvent('QBCore:Notify', receiver.PlayerData.source, 'Du hast $' .. amount .. ' von einer Rechnungszahlung erhalten', 'success')
 | 
						|
            else
 | 
						|
                -- Handle offline player
 | 
						|
                MySQL.insert.await('INSERT INTO offline_payments (citizen_id, amount, reason) VALUES (?, ?, ?)', {
 | 
						|
                    receiverId,
 | 
						|
                    amount,
 | 
						|
                    'Rechnungszahlung: ' .. description
 | 
						|
                })
 | 
						|
                
 | 
						|
                -- Log transaction in ps-banking history for offline player
 | 
						|
                MySQL.insert.await('INSERT INTO ps_banking_transactions (identifier, description, type, amount, date, isIncome) VALUES (?, ?, ?, ?, NOW(), ?)', {
 | 
						|
                    receiverId,
 | 
						|
                    "Erhaltene Rechnung: " .. description,
 | 
						|
                    "bank",
 | 
						|
                    amount,
 | 
						|
                    true -- isIncome = true
 | 
						|
                })
 | 
						|
            end
 | 
						|
        else
 | 
						|
            -- Add money to the specified account
 | 
						|
            MySQL.update.await('UPDATE ps_banking_accounts SET balance = balance + ? WHERE id = ?', {
 | 
						|
                amount,
 | 
						|
                accountId
 | 
						|
            })
 | 
						|
            
 | 
						|
            -- Try to notify the account owner if online
 | 
						|
            local accountResult = MySQL.query.await('SELECT * FROM ps_banking_accounts WHERE id = ?', {accountId})
 | 
						|
            if accountResult and #accountResult > 0 then
 | 
						|
                local account = accountResult[1]
 | 
						|
                local owner = json.decode(account.owner)
 | 
						|
                local ownerPlayer = QBCore.Functions.GetPlayerByCitizenId(owner.identifier)
 | 
						|
                
 | 
						|
                -- Log transaction in ps-banking history for the account
 | 
						|
                MySQL.insert.await('INSERT INTO ps_banking_transactions (identifier, description, type, amount, date, isIncome) VALUES (?, ?, ?, ?, NOW(), ?)', {
 | 
						|
                    owner.identifier,
 | 
						|
                    "Erhaltene Rechnung auf Konto " .. account.holder .. ": " .. description,
 | 
						|
                    "bank",
 | 
						|
                    amount,
 | 
						|
                    true -- isIncome = true
 | 
						|
                })
 | 
						|
                
 | 
						|
                if ownerPlayer then
 | 
						|
                    TriggerClientEvent('QBCore:Notify', ownerPlayer.PlayerData.source, 'Das Konto ' .. account.holder .. ' hat $' .. amount .. ' von einer Rechnungszahlung erhalten', 'success')
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
        
 | 
						|
        -- Update the bill status
 | 
						|
        MySQL.update.await('UPDATE billing_accounts SET paid = 1, paid_at = NOW() WHERE bill_id = ?', {billId})
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
-- Create the necessary database tables if they don't exist
 | 
						|
MySQL.ready(function()
 | 
						|
    -- First check if the billing_accounts table exists
 | 
						|
    local tableExists = MySQL.query.await("SHOW TABLES LIKE 'billing_accounts'")
 | 
						|
    
 | 
						|
    if #tableExists > 0 then
 | 
						|
        -- Table exists, check if the declined column exists
 | 
						|
        local columnExists = MySQL.query.await("SHOW COLUMNS FROM billing_accounts LIKE 'declined'")
 | 
						|
        
 | 
						|
        if #columnExists == 0 then
 | 
						|
            -- Add the declined column if it doesn't exist
 | 
						|
            MySQL.query.await("ALTER TABLE billing_accounts ADD COLUMN declined TINYINT DEFAULT 0")
 | 
						|
            print("^2[nordi_billing] Added 'declined' column to billing_accounts table^7")
 | 
						|
        end
 | 
						|
    else
 | 
						|
        -- Create the table with all required columns
 | 
						|
        MySQL.query.await([[
 | 
						|
            CREATE TABLE IF NOT EXISTS billing_accounts (
 | 
						|
                id INT AUTO_INCREMENT PRIMARY KEY,
 | 
						|
                bill_id INT,
 | 
						|
                bill_description VARCHAR(255),
 | 
						|
                sender_id VARCHAR(50),
 | 
						|
                receiver_id VARCHAR(50),
 | 
						|
                account_id VARCHAR(50),
 | 
						|
                amount DECIMAL(10,2),
 | 
						|
                created_at DATETIME,
 | 
						|
                paid TINYINT DEFAULT 0,
 | 
						|
                declined TINYINT DEFAULT 0,
 | 
						|
                paid_at DATETIME
 | 
						|
            )
 | 
						|
        ]])
 | 
						|
        print("^2[nordi_billing] Created billing_accounts table^7")
 | 
						|
    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
 | 
						|
    MySQL.query.await([[
 | 
						|
        CREATE TABLE IF NOT EXISTS offline_payments (
 | 
						|
            id INT AUTO_INCREMENT PRIMARY KEY,
 | 
						|
            citizen_id VARCHAR(50),
 | 
						|
            amount DECIMAL(10,2),
 | 
						|
            reason VARCHAR(255),
 | 
						|
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
						|
            processed TINYINT DEFAULT 0
 | 
						|
        )
 | 
						|
    ]])
 | 
						|
    print("^2[nordi_billing] Database tables initialized^7")
 | 
						|
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
 | 
						|
RegisterNetEvent('QBCore:Server:PlayerLoaded', function()
 | 
						|
    local src = source
 | 
						|
    local player = QBCore.Functions.GetPlayer(src)
 | 
						|
    
 | 
						|
    if not player then return end
 | 
						|
    
 | 
						|
    local citizenId = player.PlayerData.citizenid
 | 
						|
    local offlinePayments = MySQL.query.await('SELECT * FROM offline_payments WHERE citizen_id = ? AND processed = 0', {citizenId})
 | 
						|
    
 | 
						|
    if offlinePayments and #offlinePayments > 0 then
 | 
						|
        local totalAmount = 0
 | 
						|
        
 | 
						|
        for _, payment in ipairs(offlinePayments) do
 | 
						|
            totalAmount = totalAmount + payment.amount
 | 
						|
        end
 | 
						|
        
 | 
						|
        if totalAmount > 0 then
 | 
						|
            player.Functions.AddMoney('bank', totalAmount, 'offline-bill-payments')
 | 
						|
            TriggerClientEvent('QBCore:Notify', src, 'Du hast $' .. totalAmount .. ' von Rechnungszahlungen erhalten, während du offline warst', 'success')
 | 
						|
            
 | 
						|
            -- Mark payments as processed
 | 
						|
            MySQL.update.await('UPDATE offline_payments SET processed = 1 WHERE citizen_id = ? AND processed = 0', {citizenId})
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Check for unpaid bills
 | 
						|
    local unpaidBills = MySQL.query.await('SELECT COUNT(*) as count FROM ps_banking_bills WHERE identifier = ? AND isPaid = 0', {citizenId})
 | 
						|
    if unpaidBills and unpaidBills[1].count > 0 then
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'Du hast ' .. unpaidBills[1].count .. ' unbezahlte Rechnungen. Tippe /bills um sie anzuzeigen.', 'info')
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Hook into ps-banking bill payments
 | 
						|
-- This is crucial for handling payments made through ps-banking interface
 | 
						|
AddEventHandler('oxmysql:query', function(query, params)
 | 
						|
    if string.find(query, "DELETE FROM ps_banking_bills WHERE id = ?") then
 | 
						|
        -- This is likely a bill payment
 | 
						|
        local billId = params[1]
 | 
						|
        if billId then
 | 
						|
            -- Get bill details before it's deleted
 | 
						|
            local billResult = MySQL.query.await('SELECT * FROM ps_banking_bills WHERE id = ?', {billId})
 | 
						|
            if billResult and #billResult > 0 then
 | 
						|
                local bill = billResult[1]
 | 
						|
                local identifier = bill.identifier
 | 
						|
                local amount = tonumber(bill.amount)
 | 
						|
                local description = bill.description
 | 
						|
                
 | 
						|
                -- Log transaction in ps-banking history for the payer
 | 
						|
                MySQL.insert.await('INSERT INTO ps_banking_transactions (identifier, description, type, amount, date, isIncome) VALUES (?, ?, ?, ?, NOW(), ?)', {
 | 
						|
                    identifier,
 | 
						|
                    "Bezahlte Rechnung: " .. description,
 | 
						|
                    "bank",
 | 
						|
                    amount,
 | 
						|
                    false -- isIncome = false
 | 
						|
                })
 | 
						|
            end
 | 
						|
            
 | 
						|
            -- Small delay to ensure the deletion completes
 | 
						|
            SetTimeout(100, function()
 | 
						|
                ProcessBillPayment(billId)
 | 
						|
            end)
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Register a command to check bills
 | 
						|
QBCore.Commands.Add('bills', 'Zeige deine unbezahlten Rechnungen an', {}, false, function(source)
 | 
						|
    TriggerClientEvent('QBCore:Notify', source, 'Öffne Rechnungsübersicht...', 'info')
 | 
						|
    -- This will trigger the client to open the bills menu
 | 
						|
    TriggerClientEvent('billing:client:openBillsMenu', source)
 | 
						|
end)
 |