
Since it has many functions, there is this time a Google Docs link. Would be otherwise just too much :D
All info: https://docs.google.com/document/d/14GI3SOOqNOMVO-CIvzdiuTI5YidcfgvFIilYqS2yXjQ/edit?usp=sharing
Will it work with your vehicleshop/housing-system?
Tested with: myCardealer, qs-housing, loaf-housing
As long as your vehicle prices or house prices are saved in the database or stored in any file i can access, it should work fine.

- ESX
- OXMySQL
- Optional: esx_addonaccount
Why is esx_addonaccount optional?
esx_addonaccount is used to get the current balance of different businesses.
This function is not encrpyted. If you use any other system, its simple to implement it.

CFX Forumpost: https://forum.cfx.re/t/paid-esx-qb-advanced-tax-system-umfangreiches-steuersystem/5028062
Shared functions of the script to make sure that there are no implementation problems with your server!
SharedFunctions = {}
SharedFunctions.debug = function(type, msg)
if Config.useDebug then
local messagePraefix
if type == nil then
messagePraefix = ""
elseif type == "success" then
messagePraefix = "^2[SUCCESS]^0"
elseif type == "info" then
messagePraefix = "^4[INFO]^0"
elseif type == "warning" then
messagePraefix = "^3[WARNING]^0"
elseif type == "error" then
messagePraefix = "^1[ERROR]^0"
end
print("[DEBUG] " .. messagePraefix .. " " .. msg)
end
end-- Job messages notification system -- Server notification system
SharedFunctions.serverNotify = function(targetSrc, message)
local xPlayer = ESX.GetPlayerFromId(targetSrc)
xPlayer.showNotification(message)
end
SharedFunctions.clientNotify = function(message)
SetNotificationTextEntry('STRING')
AddTextComponentString(msg)
DrawNotification(0, 1)
end
--- Function to get the total vehicle value and amount of vehicles of a player
-- Function needs to be synced!
-- @return the total house value and the amount of houses
SharedFunctions.GetTotalVehicleValueForPlayer = function(citizenid)
local totalVehicleValue = 0
local result = MySQL.query.await('SELECT vehicle, plate FROM player_vehicles WHERE citizenid = ?', {citizenid})
if #result > 0 then
-- get total vehicle value
for k,v in pairs(result) do
if not ServerFunctions.isVehicleModelBlocked(v.vehicle) and not ServerFunctions.isVehiclePlateBlocked(v.plate) then
local vehiclePrice = QBCore.Shared.Vehicles[v.vehicle]['price']
if vehiclePrice ~= nil then
totalVehicleValue = totalVehicleValue + vehiclePrice
else
ConfigFunctions.debug("error", "Could not find any price for vehicle " .. v.vehicle .. " in QBCore.Shared.Vehicles!")
end
end
end
end
return totalVehicleValue
end
--- Function to get the total house value and the amount of houses of a player
-- Function needs to be synced!
-- @return the total house value and the amount of houses
SharedFunctions.GetTotalHouseValueForPlayer = function(citizenid)
local totalHouseValue = 0
local result = MySQL.query.await('SELECT price FROM houselocations NATURAL JOIN player_houses WHERE identifier = ? AND houselocations.owned = 1', {citizenid})
if #result > 0 then
for k,v in pairs(result) do
totalHouseValue = totalHouseValue + v.price
end
end
return totalHouseValue
end
-- Function to get the money from a society
-- You can implement your onw system here
SharedFunctions.GetSocietyMoney = function(SocietyName)
return exports['qb-management']:GetAccount(SocietyName)
end
-- Function to remove money from society
-- You can implement your onw system here
SharedFunctions.RemoveSocietyMoney = function(SocietyName, Amount)
exports['qb-management']:RemoveMoney(SocietyName, Amount)
end
-- Function to pay the tax amount given by the function
-- If you want to, you can also implement, that all players get a bill
-- and not just removing the money. Might be an option for some of you :D
SharedFunctions.payTaxFunction = function(playerData, player, moneyToRemove)
local playerMoney = playerData.money
if not Config.testMode then
if player == nil then
playerData.moneyTable.bank = playerMoney - moneyToRemove
MySQL.Sync.execute('UPDATE players SET money = @money WHERE citizenid = @citizenid', {
['@citizenid'] = playerData.citizenid,
['@money'] = json.encode(playerData.moneyTable)
})
else
player.Functions.RemoveMoney('bank', tonumber(moneyToRemove))
SharedFunctions.sendTaxPaidNotify(playerTaxData[playerData.citizenid], player.PlayerData.source)
end
end
SharedFunctions.debug("info", "Player ^4" .. playerData.name .. " ^0payed ^4$" .. moneyToRemove .. " ^0in total!")
end
-- Functions to send notify with tax amount payed
-- You can implement any system here to send the notify (like in your phone as notify)
SharedFunctions.sendTaxPaidNotify = function(playerTaxAmountData, source)
local moneyToPay = playerTaxAmountData.moneyTax + playerTaxAmountData.vehicleTax + playerTaxAmountData.houseTax
SharedFunctions.serverNotify(source, "Du hast $" .. moneyToPay .. " Steuern bezahlt.")
SharedFunctions.serverNotify(source, "Vermögenssteuer: $" .. playerTaxAmountData.moneyTax .. " " ..
"Fahrzeugsteuer: $" .. playerTaxAmountData.vehicleTax .. " " ..
"Haussteuer: $" .. playerTaxAmountData.houseTax)
end