708 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			708 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
-- Initialize QBCore
 | 
						|
local QBCore = exports['qb-core']:GetCoreObject()
 | 
						|
 | 
						|
local isUiOpen = false
 | 
						|
local cooldown = false
 | 
						|
local pendingBills = {}
 | 
						|
 | 
						|
-- Command to open main billing menu
 | 
						|
RegisterCommand('bill', function()
 | 
						|
    OpenMainBillingMenu()
 | 
						|
end, false)
 | 
						|
 | 
						|
-- Keybind registration
 | 
						|
RegisterKeyMapping('bill', 'Open Billing Menu', 'keyboard', 'F7') -- Default key is F7, can be changed in settings
 | 
						|
 | 
						|
-- Function to open the main billing menu
 | 
						|
function OpenMainBillingMenu()
 | 
						|
    lib.registerContext({
 | 
						|
        id = 'main_billing_menu',
 | 
						|
        title = 'Billing System',
 | 
						|
        options = {
 | 
						|
            {
 | 
						|
                title = 'Rechnung erstellen',
 | 
						|
                description = 'Sende eine Rechnung an einen Spieler in der Nähe',
 | 
						|
                icon = 'file-invoice-dollar',
 | 
						|
                onSelect = function()
 | 
						|
                    OpenCreateBillMenu()
 | 
						|
                end
 | 
						|
            },
 | 
						|
            {
 | 
						|
                title = 'Meine Rechnungen',
 | 
						|
                description = 'Sehe & bezahle deine erhaltenen Rechnungen',
 | 
						|
                icon = 'money-check',
 | 
						|
                onSelect = function()
 | 
						|
                    ViewBills()
 | 
						|
                end
 | 
						|
            }
 | 
						|
        }
 | 
						|
    })
 | 
						|
    
 | 
						|
    lib.showContext('main_billing_menu')
 | 
						|
end
 | 
						|
 | 
						|
-- Function to open the create bill menu
 | 
						|
function OpenCreateBillMenu()
 | 
						|
    if cooldown then
 | 
						|
        lib.notify({
 | 
						|
            title = 'Billing System',
 | 
						|
            description = 'Bitte warte, bevor du das Abrechnungssystem erneut verwendest',
 | 
						|
            type = 'error'
 | 
						|
        })
 | 
						|
        return
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Get nearby players
 | 
						|
    local players = GetNearbyPlayers()
 | 
						|
    if #players == 0 then
 | 
						|
        lib.notify({
 | 
						|
            title = 'Billing System',
 | 
						|
            description = 'Keine Spieler in der Nähe zum Abrechnen',
 | 
						|
            type = 'error'
 | 
						|
        })
 | 
						|
        return
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Get player's accounts for receiving payment
 | 
						|
    local accounts = lib.callback.await('ps-banking:server:getAccounts', false) or {}
 | 
						|
    local accountOptions = {}
 | 
						|
    
 | 
						|
    -- Add default bank account
 | 
						|
    table.insert(accountOptions, {
 | 
						|
        value = 'personal',
 | 
						|
        label = 'Persönliches Bankkonto'
 | 
						|
    })
 | 
						|
    
 | 
						|
    -- Add other accounts
 | 
						|
    for _, account in ipairs(accounts) do
 | 
						|
        table.insert(accountOptions, {
 | 
						|
            value = account.id,
 | 
						|
            label = account.holder .. ' - ' .. account.cardNumber
 | 
						|
        })
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Show the list of nearby players
 | 
						|
    local playerOptions = {}
 | 
						|
    for _, player in ipairs(players) do
 | 
						|
        table.insert(playerOptions, {
 | 
						|
            title = player.name,
 | 
						|
            description = 'ID: ' .. player.id,
 | 
						|
            icon = 'user',
 | 
						|
            onSelect = function()
 | 
						|
                -- When a player is selected, show the billing form
 | 
						|
                ShowBillingForm(player, accountOptions)
 | 
						|
            end
 | 
						|
        })
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Register and show the player selection menu
 | 
						|
    lib.registerContext({
 | 
						|
        id = 'nearby_players_menu',
 | 
						|
        title = 'Spieler zum Abrechnen auswählen',
 | 
						|
        menu = 'main_billing_menu', -- Add back button to main menu
 | 
						|
        options = playerOptions
 | 
						|
    })
 | 
						|
    
 | 
						|
    lib.showContext('nearby_players_menu')
 | 
						|
end
 | 
						|
 | 
						|
-- Function to show the billing form after selecting a player
 | 
						|
function ShowBillingForm(selectedPlayer, accountOptions)
 | 
						|
    local input = lib.inputDialog('Rechnung erstellen für ' .. selectedPlayer.name, {
 | 
						|
        {
 | 
						|
            type = 'number',
 | 
						|
            label = 'Betrag ($)',
 | 
						|
            description = 'Gib den Rechnungsbetrag ein',
 | 
						|
            icon = 'dollar-sign',
 | 
						|
            required = true,
 | 
						|
            min = 1,
 | 
						|
            max = 100000
 | 
						|
        },
 | 
						|
        {
 | 
						|
            type = 'input',
 | 
						|
            label = 'Grund',
 | 
						|
            description = 'Gib den Grund für die Rechnung ein',
 | 
						|
            placeholder = 'Erbrachte Dienstleistungen...',
 | 
						|
            required = true
 | 
						|
        },
 | 
						|
        {
 | 
						|
            type = 'select',
 | 
						|
            label = 'Empfangskonto',
 | 
						|
            options = accountOptions,
 | 
						|
            required = true
 | 
						|
        }
 | 
						|
    })
 | 
						|
    
 | 
						|
    if not input then return end
 | 
						|
    
 | 
						|
    -- Play animation
 | 
						|
    PlayBillingAnimation()
 | 
						|
    
 | 
						|
    -- Send the bill
 | 
						|
    local billData = lib.callback.await('billing:server:sendBill', false, {
 | 
						|
        playerId = selectedPlayer.id,
 | 
						|
        amount = input[1],
 | 
						|
        reason = input[2],
 | 
						|
        account = input[3]
 | 
						|
    })
 | 
						|
    
 | 
						|
    if billData and billData.success then
 | 
						|
        lib.notify({
 | 
						|
            title = 'Billing System',
 | 
						|
            description = 'Rechnung erfolgreich an ' .. selectedPlayer.name .. ' gesendet',
 | 
						|
            type = 'success'
 | 
						|
        })
 | 
						|
        
 | 
						|
        -- Set cooldown
 | 
						|
        cooldown = true
 | 
						|
        SetTimeout(5000, function()
 | 
						|
            cooldown = false
 | 
						|
        end)
 | 
						|
        
 | 
						|
        -- Add to pending bills
 | 
						|
        pendingBills[billData.billId] = {
 | 
						|
            player = selectedPlayer,
 | 
						|
            amount = input[1],
 | 
						|
            reason = input[2],
 | 
						|
            account = input[3],
 | 
						|
            timestamp = GetGameTimer()
 | 
						|
        }
 | 
						|
        
 | 
						|
        -- Show waiting screen with all details
 | 
						|
        ShowWaitingScreen(billData.billId, selectedPlayer.name, input[1], input[2])
 | 
						|
    else
 | 
						|
        lib.notify({
 | 
						|
            title = 'Billing System',
 | 
						|
            description = 'Fehler beim Senden der Rechnung',
 | 
						|
            type = 'error'
 | 
						|
        })
 | 
						|
        
 | 
						|
        -- Return to main menu
 | 
						|
        OpenMainBillingMenu()
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
-- Function to show waiting screen
 | 
						|
function ShowWaitingScreen(billId, playerName, amount, reason)
 | 
						|
    -- Create a more informative waiting screen
 | 
						|
    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 = 'Warte auf Antwort',
 | 
						|
                progress = 100, -- This creates a loading bar
 | 
						|
                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
 | 
						|
            }
 | 
						|
        }
 | 
						|
    })
 | 
						|
    
 | 
						|
    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
 | 
						|
 | 
						|
-- Function to show payment account selection
 | 
						|
function ShowPaymentAccountSelection(billId, amount, description)
 | 
						|
    -- Get player's accounts for payment
 | 
						|
    local accounts = lib.callback.await('ps-banking:server:getAccounts', false) or {}
 | 
						|
    local accountOptions = {}
 | 
						|
    
 | 
						|
    -- Add default bank account
 | 
						|
    table.insert(accountOptions, {
 | 
						|
        value = 'personal',
 | 
						|
        label = 'Persönliches Bankkonto',
 | 
						|
        description = 'Bezahlen mit deinem Hauptkonto'
 | 
						|
    })
 | 
						|
    
 | 
						|
    -- Add other accounts
 | 
						|
    for _, account in ipairs(accounts) do
 | 
						|
        table.insert(accountOptions, {
 | 
						|
            value = account.id,
 | 
						|
            label = account.holder .. ' - ' .. account.cardNumber,
 | 
						|
            description = 'Kontostand: $' .. account.balance
 | 
						|
        })
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Register and show the account selection menu
 | 
						|
    lib.registerContext({
 | 
						|
        id = 'payment_account_menu',
 | 
						|
        title = 'Wähle Zahlungskonto',
 | 
						|
        menu = 'billing_menu', -- Add back button to bills menu
 | 
						|
        options = accountOptions,
 | 
						|
        onExit = function()
 | 
						|
            ViewBills() -- Return to bills menu
 | 
						|
        end,
 | 
						|
        onSelect = function(selected)
 | 
						|
            local accountId = selected.value
 | 
						|
            
 | 
						|
            local confirm = lib.alertDialog({
 | 
						|
                header = 'Rechnung bezahlen',
 | 
						|
                content = ('Möchtest du $%s für %s von diesem Konto bezahlen?'):format(amount, description),
 | 
						|
                centered = true,
 | 
						|
                cancel = true
 | 
						|
            })
 | 
						|
            
 | 
						|
            if confirm == 'confirm' then
 | 
						|
                local success = lib.callback.await('billing:server:payBillFromAccount', false, {
 | 
						|
                    billId = billId,
 | 
						|
                    accountId = accountId
 | 
						|
                })
 | 
						|
                
 | 
						|
                if success then
 | 
						|
                    lib.notify({
 | 
						|
                        title = 'Billing System',
 | 
						|
                        description = 'Rechnung erfolgreich bezahlt',
 | 
						|
                        type = 'success'
 | 
						|
                    })
 | 
						|
                    ViewBills() -- Refresh the list
 | 
						|
                else
 | 
						|
                    lib.notify({
 | 
						|
                        title = 'Billing System',
 | 
						|
                        description = 'Fehler beim Bezahlen der Rechnung. Unzureichendes Guthaben.',
 | 
						|
                        type = 'error'
 | 
						|
                    })
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
    })
 | 
						|
    
 | 
						|
    lib.showContext('payment_account_menu')
 | 
						|
end
 | 
						|
 | 
						|
-- Function to view received bills
 | 
						|
function ViewBills()
 | 
						|
    -- Get all bills from ps-banking
 | 
						|
    local bills = lib.callback.await('ps-banking:server:getBills', false)
 | 
						|
    
 | 
						|
    if not bills or #bills == 0 then
 | 
						|
        lib.notify({
 | 
						|
            title = 'Billing System',
 | 
						|
            description = 'Du hast keine unbezahlten Rechnungen',
 | 
						|
            type = 'info'
 | 
						|
        })
 | 
						|
        
 | 
						|
        -- Return to main menu after a short delay
 | 
						|
        SetTimeout(1000, function()
 | 
						|
            OpenMainBillingMenu()
 | 
						|
        end)
 | 
						|
        return
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Get bill statuses from our custom table
 | 
						|
    local billStatuses = lib.callback.await('billing:server:getAllBillStatuses', false)
 | 
						|
    local statusMap = {}
 | 
						|
    
 | 
						|
    -- Create a map of bill ID to status for quick lookup
 | 
						|
    if billStatuses then
 | 
						|
        for _, status in ipairs(billStatuses) do
 | 
						|
            statusMap[status.bill_id] = status
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    local billOptions = {}
 | 
						|
    for _, bill in ipairs(bills) do
 | 
						|
        local timestamp = os.date('%Y-%m-%d %H:%M', bill.date)
 | 
						|
        
 | 
						|
        -- Check if bill is declined in our custom table
 | 
						|
        local billStatus = statusMap[bill.id]
 | 
						|
        local isDeclined = billStatus and billStatus.declined == 1
 | 
						|
        
 | 
						|
        local status = 'Unbezahlt'
 | 
						|
        if bill.isPaid then
 | 
						|
            status = 'Bezahlt'
 | 
						|
        elseif isDeclined then
 | 
						|
            status = 'Abgelehnt'
 | 
						|
        end
 | 
						|
        
 | 
						|
        table.insert(billOptions, {
 | 
						|
            title = bill.description,
 | 
						|
            description = ('Betrag: $%s | Datum: %s'):format(bill.amount, timestamp),
 | 
						|
            icon = 'file-invoice',
 | 
						|
            metadata = {
 | 
						|
                {label = 'Rechnungs-ID', value = bill.id},
 | 
						|
                {label = 'Typ', value = bill.type},
 | 
						|
                {label = 'Status', value = status}
 | 
						|
            },
 | 
						|
            onSelect = function()
 | 
						|
                if not bill.isPaid and not isDeclined then
 | 
						|
                    -- Show account selection for payment
 | 
						|
                    ShowPaymentAccountSelection(bill.id, bill.amount, bill.description)
 | 
						|
                end
 | 
						|
            end
 | 
						|
        })
 | 
						|
    end
 | 
						|
    
 | 
						|
    lib.registerContext({
 | 
						|
        id = 'billing_menu',
 | 
						|
        title = 'Deine Rechnungen',
 | 
						|
        menu = 'main_billing_menu', -- Add back button to main menu
 | 
						|
        options = billOptions
 | 
						|
    })
 | 
						|
    
 | 
						|
    lib.showContext('billing_menu')
 | 
						|
end
 | 
						|
 | 
						|
-- Helper function to get nearby players
 | 
						|
function GetNearbyPlayers()
 | 
						|
    local playerPed = PlayerPedId()
 | 
						|
    local playerCoords = GetEntityCoords(playerPed)
 | 
						|
    local players = {}
 | 
						|
    
 | 
						|
    -- Get all players
 | 
						|
    local allPlayers = GetActivePlayers()
 | 
						|
    
 | 
						|
    for _, player in ipairs(allPlayers) do
 | 
						|
        local targetPed = GetPlayerPed(player)
 | 
						|
        local targetCoords = GetEntityCoords(targetPed)
 | 
						|
        local distance = #(playerCoords - targetCoords)
 | 
						|
        
 | 
						|
        if distance <= 5.0 and targetPed ~= playerPed then
 | 
						|
            local targetId = GetPlayerServerId(player)
 | 
						|
            local targetName = GetPlayerName(player)
 | 
						|
            table.insert(players, {id = targetId, name = targetName})
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    return players
 | 
						|
end
 | 
						|
 | 
						|
-- Animation function
 | 
						|
function PlayBillingAnimation()
 | 
						|
    lib.requestAnimDict("cellphone@")
 | 
						|
    
 | 
						|
    -- Request the prop model
 | 
						|
    local propModel = 'bzzz_prop_payment_terminal'
 | 
						|
    lib.requestModel(propModel)
 | 
						|
    
 | 
						|
    -- Create prop
 | 
						|
    local playerPed = PlayerPedId()
 | 
						|
    local coords = GetEntityCoords(playerPed)
 | 
						|
    local prop = CreateObject(GetHashKey(propModel), coords.x, coords.y, coords.z, true, true, true)
 | 
						|
    
 | 
						|
    -- Attach prop to player
 | 
						|
    AttachEntityToEntity(prop, playerPed, GetPedBoneIndex(playerPed, 57005), 
 | 
						|
        0.18, 0.01, 0.0, -54.0, 220.0, 43.0, 
 | 
						|
        true, true, false, true, 1, true)
 | 
						|
    
 | 
						|
    -- Play animation
 | 
						|
    TaskPlayAnim(playerPed, "cellphone@", "cellphone_text_read_base", 2.0, 3.0, -1, 49, 0, false, false, false)
 | 
						|
    
 | 
						|
    -- Wait for animation to complete
 | 
						|
    Wait(5000)
 | 
						|
    
 | 
						|
    -- Clear animation and delete prop
 | 
						|
    ClearPedTasks(playerPed)
 | 
						|
    DeleteEntity(prop)
 | 
						|
end
 | 
						|
 | 
						|
-- Event to show payment prompt when receiving a bill
 | 
						|
RegisterNetEvent('billing:client:showPaymentPrompt', function(data)
 | 
						|
    -- Play a notification sound
 | 
						|
    PlaySound(-1, "Event_Start_Text", "GTAO_FM_Events_Soundset", 0, 0, 1)
 | 
						|
    
 | 
						|
    -- Get player's accounts for payment
 | 
						|
    local accounts = lib.callback.await('ps-banking:server:getAccounts', false) or {}
 | 
						|
    local accountOptions = {}
 | 
						|
    
 | 
						|
    -- Add default bank account
 | 
						|
    table.insert(accountOptions, {
 | 
						|
        title = 'Persönliches Bankkonto',
 | 
						|
        description = 'Bezahlen mit deinem Hauptkonto',
 | 
						|
        icon = 'credit-card',
 | 
						|
        onSelect = function()
 | 
						|
            local success = lib.callback.await('billing:server:handleBillResponse', false, {
 | 
						|
                action = 'pay',
 | 
						|
                billId = data.billId,
 | 
						|
                accountId = 'personal'
 | 
						|
            })
 | 
						|
            
 | 
						|
            if success then
 | 
						|
                lib.notify({
 | 
						|
                    title = 'Rechnung bezahlt',
 | 
						|
                    description = 'Du hast die Rechnung erfolgreich bezahlt',
 | 
						|
                    type = 'success'
 | 
						|
                })
 | 
						|
                
 | 
						|
                -- Notify the sender
 | 
						|
                TriggerServerEvent('billing:server:notifyBillSender', data.billId, 'pay')
 | 
						|
            else
 | 
						|
                lib.notify({
 | 
						|
                    title = 'Zahlung fehlgeschlagen',
 | 
						|
                    description = 'Du hast nicht genug Geld auf deinem Konto',
 | 
						|
                    type = 'error'
 | 
						|
                })
 | 
						|
            end
 | 
						|
        end
 | 
						|
    })
 | 
						|
    
 | 
						|
    -- Add other accounts
 | 
						|
    for _, account in ipairs(accounts) do
 | 
						|
        table.insert(accountOptions, {
 | 
						|
            title = account.holder .. ' - ' .. account.cardNumber,
 | 
						|
            description = 'Kontostand: $' .. account.balance,
 | 
						|
            icon = 'university',
 | 
						|
            onSelect = function()
 | 
						|
                local success = lib.callback.await('billing:server:handleBillResponse', false, {
 | 
						|
                    action = 'pay',
 | 
						|
                    billId = data.billId,
 | 
						|
                    accountId = account.id
 | 
						|
                })
 | 
						|
                
 | 
						|
                if success then
 | 
						|
                    lib.notify({
 | 
						|
                        title = 'Rechnung bezahlt',
 | 
						|
                        description = 'Du hast die Rechnung erfolgreich bezahlt',
 | 
						|
                        type = 'success'
 | 
						|
                    })
 | 
						|
                    
 | 
						|
                    -- Notify the sender
 | 
						|
                    TriggerServerEvent('billing:server:notifyBillSender', data.billId, 'pay')
 | 
						|
                else
 | 
						|
                    lib.notify({
 | 
						|
                        title = 'Zahlung fehlgeschlagen',
 | 
						|
                        description = 'Nicht genug Geld auf diesem Konto',
 | 
						|
                        type = 'error'
 | 
						|
                    })
 | 
						|
                end
 | 
						|
            end
 | 
						|
        })
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Create the payment prompt
 | 
						|
    lib.registerContext({
 | 
						|
        id = 'bill_payment_prompt',
 | 
						|
        title = 'Neue Rechnung erhalten',
 | 
						|
        options = {
 | 
						|
            {
 | 
						|
                title = 'Rechnung Details',
 | 
						|
                description = 'Von: ' .. data.sender,
 | 
						|
                metadata = {
 | 
						|
                    {label = 'Betrag', value = '$' .. data.amount},
 | 
						|
                    {label = 'Grund', value = data.reason},
 | 
						|
                }
 | 
						|
            },
 | 
						|
            {
 | 
						|
                title = 'Bezahlen',
 | 
						|
                description = 'Wähle ein Konto zum Bezahlen',
 | 
						|
                icon = 'money-bill',
 | 
						|
                menu = 'payment_account_selection'
 | 
						|
            },
 | 
						|
            {
 | 
						|
                title = 'Ablehnen',
 | 
						|
                description = 'Rechnung ablehnen',
 | 
						|
                icon = 'times-circle',
 | 
						|
                onSelect = function()
 | 
						|
                    local confirm = lib.alertDialog({
 | 
						|
                        header = 'Rechnung ablehnen',
 | 
						|
                        content = 'Bist du sicher, dass du diese Rechnung ablehnen möchtest?',
 | 
						|
                        centered = true,
 | 
						|
                        cancel = true
 | 
						|
                    })
 | 
						|
                    
 | 
						|
                    if confirm == 'confirm' then
 | 
						|
                        local success = lib.callback.await('billing:server:handleBillResponse', false, {
 | 
						|
                            action = 'decline',
 | 
						|
                            billId = data.billId
 | 
						|
                        })
 | 
						|
                        
 | 
						|
                        if success then
 | 
						|
                            lib.notify({
 | 
						|
                                title = 'Rechnung abgelehnt',
 | 
						|
                                description = 'Du hast die Rechnung abgelehnt',
 | 
						|
                                type = 'info'
 | 
						|
                            })
 | 
						|
                            
 | 
						|
                            -- Notify the sender
 | 
						|
                            TriggerServerEvent('billing:server:notifyBillSender', data.billId, 'decline')
 | 
						|
                        else
 | 
						|
                            lib.notify({
 | 
						|
                                title = 'Fehler',
 | 
						|
                                description = 'Fehler beim Ablehnen der Rechnung',
 | 
						|
                                type = 'error'
 | 
						|
                            })
 | 
						|
                        end
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            }
 | 
						|
            -- "Pay Later" option removed
 | 
						|
        }
 | 
						|
    })
 | 
						|
    
 | 
						|
    -- Register the account selection submenu
 | 
						|
    lib.registerContext({
 | 
						|
        id = 'payment_account_selection',
 | 
						|
        title = 'Wähle Zahlungskonto',
 | 
						|
        menu = 'bill_payment_prompt',
 | 
						|
        options = accountOptions
 | 
						|
    })
 | 
						|
    
 | 
						|
    -- Show the payment prompt
 | 
						|
    lib.showContext('bill_payment_prompt')
 | 
						|
end)
 | 
						|
 | 
						|
-- Event to handle bill response
 | 
						|
RegisterNetEvent('billing:client:billResponse', function(billId, action, playerName)
 | 
						|
    -- Check if this bill is in our pending bills
 | 
						|
    if pendingBills[billId] then
 | 
						|
        local bill = pendingBills[billId]
 | 
						|
        
 | 
						|
        if action == 'pay' then
 | 
						|
            lib.notify({
 | 
						|
                title = 'Rechnung bezahlt',
 | 
						|
                description = playerName .. ' hat deine Rechnung über $' .. bill.amount .. ' bezahlt',
 | 
						|
                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
 | 
						|
            lib.notify({
 | 
						|
                title = 'Rechnung abgelehnt',
 | 
						|
                description = playerName .. ' hat deine Rechnung über $' .. bill.amount .. ' abgelehnt',
 | 
						|
                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
 | 
						|
            })
 | 
						|
        }
 | 
						|
        -- "later" case removed
 | 
						|
        
 | 
						|
        -- Remove from pending bills
 | 
						|
        pendingBills[billId] = nil
 | 
						|
        
 | 
						|
        -- Return to main menu
 | 
						|
        OpenMainBillingMenu()
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Event handler for opening bills menu from command
 | 
						|
RegisterNetEvent('billing:client:openBillsMenu', function()
 | 
						|
    ViewBills()
 | 
						|
end)
 | 
						|
 | 
						|
-- Check for timed out bills every minute
 | 
						|
Citizen.CreateThread(function()
 | 
						|
    while true do
 | 
						|
        Citizen.Wait(60000) -- Check every minute
 | 
						|
        
 | 
						|
        local currentTime = GetGameTimer()
 | 
						|
        local timeoutBills = {}
 | 
						|
        
 | 
						|
        for billId, bill in pairs(pendingBills) do
 | 
						|
            -- If bill is older than 5 minutes, consider it timed out
 | 
						|
            if (currentTime - bill.timestamp) > 300000 then
 | 
						|
                table.insert(timeoutBills, billId)
 | 
						|
            end
 | 
						|
        end
 | 
						|
        
 | 
						|
        -- Clean up timed out bills
 | 
						|
        for _, billId in ipairs(timeoutBills) do
 | 
						|
            lib.notify({
 | 
						|
                title = 'Rechnung Timeout',
 | 
						|
                description = 'Keine Antwort von ' .. pendingBills[billId].player.name .. ' erhalten',
 | 
						|
                type = 'warning'
 | 
						|
            })
 | 
						|
            pendingBills[billId] = nil
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 |