Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest
pip install -r requirements.txt

- name: Run manifest validator
run: python scripts/validator.py
Expand Down
47 changes: 46 additions & 1 deletion FiveM/nyx_core/server/tests.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12400,6 +12400,50 @@ function Nyx.Tests.TestIndustrialRefiningAndFunctionalPartsManufacturing()
end

-- 60. Test Pre-Trial Judicial Bail Bonds, Surety Escrow & Fugitive Recovery Warrants
function Nyx.Tests.TestMunicipalTollsAndWeighStations()
print("^3[Nyx:Tests] Running Municipal Toll Booths & Commercial Weigh Stations Suite...^7")
local passes = 0
local total = 5

local T = Nyx.TollsAndWeighing
if not T then
print("^1[Nyx:Test:FAIL]^7 Nyx.TollsAndWeighing shared module not loaded in environment")
return false
end

-- Sub-test A: Toll Fee Calculation
local sedanToll = T.CalculateTollFee(1, 5.00, 1.50, 1.00)
local commToll = T.CalculateTollFee(20, 5.00, 1.50, 1.00)
local testA_ok = (sedanToll == 5.00) and (commToll == 13.13)
if assertTest(testA_ok == true, "Toll Fee Pure Math Calculation", "Expected $5.00 sedan, $13.13 commercial toll", string.format("Sedan: $%.2f, Comm: $%.2f", sedanToll, commToll)) then passes = passes + 1 end

-- Sub-test B: Gross Vehicle Weight Rating (GVWR)
local gvwrSedan = T.CalculateGVWR(1, 150.0, 0.0)
local gvwrCommercial = T.CalculateGVWR(20, 500.0, 15000.0)
local testB_ok = (gvwrSedan == 1750.0) and (gvwrCommercial == 27500.0)
if assertTest(testB_ok == true, "GVWR Gross Weight Calculation", "Expected 1750kg sedan, 27500kg loaded semi", string.format("Sedan: %.1fkg, Semi: %.1fkg", gvwrSedan, gvwrCommercial)) then passes = passes + 1 end

-- Sub-test C: Overweight Fine Calculation
local fineZero = T.CalculateOverweightFine(14000.0, 15000.0)
local fineExcess = T.CalculateOverweightFine(17000.0, 15000.0, 2.50)
local testC_ok = (fineZero == 0.00) and (fineExcess == 5250.00)
if assertTest(testC_ok == true, "Statutory Overweight Fine Calculation", "Expected $0 fine below limit, $5250.00 fine for 2000kg excess", string.format("Zero: $%.2f, Excess: $%.2f", fineZero, fineExcess)) then passes = passes + 1 end

-- Sub-test D: Inspection Outcomes
local statusPass = T.DetermineInspectionStatus(14000.0, 15000.0, true, false, false)
local statusOver = T.DetermineInspectionStatus(17000.0, 15000.0, true, false, false)
local statusBypass = T.DetermineInspectionStatus(14000.0, 15000.0, true, false, true)
local testD_ok = (statusPass == "PASS") and (statusOver == "OVERWEIGHT") and (statusBypass == "BYPASSED")
if assertTest(testD_ok == true, "Weigh Station Inspection Outcome Resolution", "Expected PASS, OVERWEIGHT, BYPASSED", string.format("P: %s, O: %s, B: %s", statusPass, statusOver, statusBypass)) then passes = passes + 1 end

-- Sub-test E: Rounding Cents
local rounded = T.RoundToCent(12.3456)
local testE_ok = (rounded == 12.35)
if assertTest(testE_ok == true, "Round to Cent Exact Conservation", "Expected 12.35", string.format("%.2f", rounded)) then passes = passes + 1 end

return passes == total
end

function Nyx.Tests.TestJudicialBailBondsSuretyEscrowAndFugitiveRecovery()
print("^3[Nyx:Tests] Running Judicial Bail Bonds & Fugitive Recovery Suite...^7")
local passes = 0
Expand Down Expand Up @@ -12595,14 +12639,15 @@ function Nyx.Tests.RunAll()
local t58 = Nyx.Tests.TestPharmaceuticalRefiningAndPlayerChemicalLabs()
local t59 = Nyx.Tests.TestIndustrialRefiningAndFunctionalPartsManufacturing()
local t60 = Nyx.Tests.TestJudicialBailBondsSuretyEscrowAndFugitiveRecovery()
local t61 = Nyx.Tests.TestMunicipalTollsAndWeighStations()

print("^5--------------------------------------------------^7")
local suites1to50Passed = false
if t1 and t2 and t3 and t4 and t5 and t6 and t7 and t8 and t9 and t10 and t11 and t12 and t13 and t14 and t15 and t16 and t17 and t18 and t19 and t20 and t21 and t22 and t23 and t24 and t25 and t26 and t27 and t28 and t29 and t30 and t31 and t32 and t33 and t34 and t35 and t36 and t37 and t38 and t39 and t40 and t41 and t42 and t43 and t44 and t45 and t46 and t47 and t48 and t49 and t50 then
suites1to50Passed = true
end

if suites1to50Passed and t51 and t52 and t53 and t54 and t55 and t56 and t57 and t58 and t59 and t60 then
if suites1to50Passed and t51 and t52 and t53 and t54 and t55 and t56 and t57 and t58 and t59 and t60 and t61 then
print("^2>>> ALL NYXFRAMEWORK INTEGRATION TESTS PASSED! <<<^7")
else
print("^1>>> SOME NYXFRAMEWORK TESTS FAILED! CHECK LOGS. <<<^7")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
-- ============================================================================
-- Nyxframework: nyx_vehicles, nyx_logistics, nyx_treasury & nyx_mdt
-- Migration: 066_municipal_toll_booths_and_commercial_weigh_stations.sql
-- Description: Municipal transit infrastructure, highway toll plazas,
-- automated RFID toll deduction, commercial axle multipliers,
-- and commercial weigh station inspection/bypass logging.
-- Engine: InnoDB | Charset: utf8mb4 | Collation: utf8mb4_unicode_ci
-- ============================================================================

SET FOREIGN_KEY_CHECKS = 0;

-- 1. Create municipal toll plazas table
CREATE TABLE IF NOT EXISTS `nyx_toll_plazas` (
`plaza_id` VARCHAR(32) NOT NULL PRIMARY KEY,
`zone_name` VARCHAR(64) NOT NULL,
`base_fee` DECIMAL(10, 2) NOT NULL DEFAULT 5.00,
`commercial_axle_multiplier` DECIMAL(5, 2) NOT NULL DEFAULT 1.50,
`active_status` TINYINT(1) NOT NULL DEFAULT 1,
`total_collected` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_toll_zone` (`zone_name`),
INDEX `idx_toll_status` (`active_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 2. Create automated commercial weigh station inspection logs table
CREATE TABLE IF NOT EXISTS `nyx_weigh_station_logs` (
`log_id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`vehicle_plate` VARCHAR(16) NOT NULL,
`driver_identifier` VARCHAR(64) NULL,
`manifest_id` VARCHAR(64) NULL,
`gross_weight_kg` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
`max_allowed_kg` DECIMAL(10, 2) NOT NULL DEFAULT 15000.00,
`overweight_fine` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
`inspection_status` ENUM('PASS', 'OVERWEIGHT', 'CONTRABAND_FLAG', 'BYPASSED') NOT NULL DEFAULT 'PASS',
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_weigh_plate` (`vehicle_plate`),
INDEX `idx_weigh_driver` (`driver_identifier`),
INDEX `idx_weigh_manifest` (`manifest_id`),
INDEX `idx_weigh_status` (`inspection_status`),
INDEX `idx_weigh_timestamp` (`timestamp` DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 3. Seed municipal highway toll plazas
INSERT INTO `nyx_toll_plazas`
(`plaza_id`, `zone_name`, `base_fee`, `commercial_axle_multiplier`, `active_status`, `total_collected`)
VALUES
('plaza_del_perro_fwy', 'Del Perro Freeway Gantry', 5.00, 1.50, 1, 0.00),
('plaza_la_puerta_fwy', 'La Puerta Freeway Toll Plaza', 7.50, 1.75, 1, 0.00),
('plaza_palomino_fwy', 'Palomino Freeway East Barrier', 10.00, 2.00, 1, 0.00),
('plaza_senora_fwy', 'Senora Freeway North Express Gantry', 6.00, 1.60, 1, 0.00)
ON DUPLICATE KEY UPDATE `zone_name` = VALUES(`zone_name`);

SET FOREIGN_KEY_CHECKS = 1;
3 changes: 2 additions & 1 deletion FiveM/nyx_core/sql/migrations/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,6 @@
"062_point_of_sale_physical_stocking_and_empty_shelf_displays.sql",
"063_pharmaceutical_refining_and_player_chemical_labs.sql",
"064_industrial_refining_and_functional_parts_manufacturing.sql",
"065_judicial_bail_bonds_surety_escrow_and_fugitive_recovery.sql"
"065_judicial_bail_bonds_surety_escrow_and_fugitive_recovery.sql",
"066_municipal_toll_booths_and_commercial_weigh_stations.sql"
]
9 changes: 7 additions & 2 deletions FiveM/nyx_logistics/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ Config.PalletModel = "prop_boxpile_06a"
Config.PalletMaxWeight = 1000000 -- 1,000 kg (1 metric ton) per freight pallet
Config.PalletMaxSlots = 20 -- Heavy slot capacity

-- Commercial Freight Weigh Stations & Toll Integration
Config.WeighStations = {
MaxCommercialGrossWeightKg = 40000.0, -- Maximum 40 metric tons total GVWR for commercial haulers
ScalePadStabilizationSeconds = 3, -- Required stationary time on scale pad
MandatoryFreightManifest = true -- Requires active haul contract / manifest ID when passing scale
}

-- Automated Shortage Contracts
Config.ShortageContractThreshold = 0.10 -- Generate freight contract when stock <= 10% of target capacity
Config.DefaultFreightPayoutMultiplier = 0.35 -- Payout per delivered unit = 35% of item base price
Expand Down Expand Up @@ -52,5 +59,3 @@ Config.Warehouse = {
"prop_boxpile_06a"
}
}


4 changes: 3 additions & 1 deletion FiveM/nyx_logistics/fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ dependencies {
'oxmysql',
'nyx_core',
'nyx_inventory',
'nyx_treasury'
'nyx_treasury',
'nyx_vehicles'
}

shared_scripts {
'@nyx_core/shared/math.lua',
'@nyx_vehicles/shared/tolls_and_weighing.lua',
'config.lua',
'shared/zones.lua',
'shared/nodes.lua',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
-- ============================================================================
-- Nyxframework: nyx_vehicles, nyx_logistics, nyx_treasury & nyx_mdt
-- Migration: 066_municipal_toll_booths_and_commercial_weigh_stations.sql
-- Description: Municipal transit infrastructure, highway toll plazas,
-- automated RFID toll deduction, commercial axle multipliers,
-- and commercial weigh station inspection/bypass logging.
-- Engine: InnoDB | Charset: utf8mb4 | Collation: utf8mb4_unicode_ci
-- ============================================================================

SET FOREIGN_KEY_CHECKS = 0;

-- 1. Create municipal toll plazas table
CREATE TABLE IF NOT EXISTS `nyx_toll_plazas` (
`plaza_id` VARCHAR(32) NOT NULL PRIMARY KEY,
`zone_name` VARCHAR(64) NOT NULL,
`base_fee` DECIMAL(10, 2) NOT NULL DEFAULT 5.00,
`commercial_axle_multiplier` DECIMAL(5, 2) NOT NULL DEFAULT 1.50,
`active_status` TINYINT(1) NOT NULL DEFAULT 1,
`total_collected` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_toll_zone` (`zone_name`),
INDEX `idx_toll_status` (`active_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 2. Create automated commercial weigh station inspection logs table
CREATE TABLE IF NOT EXISTS `nyx_weigh_station_logs` (
`log_id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`vehicle_plate` VARCHAR(16) NOT NULL,
`driver_identifier` VARCHAR(64) NULL,
`manifest_id` VARCHAR(64) NULL,
`gross_weight_kg` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
`max_allowed_kg` DECIMAL(10, 2) NOT NULL DEFAULT 15000.00,
`overweight_fine` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
`inspection_status` ENUM('PASS', 'OVERWEIGHT', 'CONTRABAND_FLAG', 'BYPASSED') NOT NULL DEFAULT 'PASS',
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_weigh_plate` (`vehicle_plate`),
INDEX `idx_weigh_driver` (`driver_identifier`),
INDEX `idx_weigh_manifest` (`manifest_id`),
INDEX `idx_weigh_status` (`inspection_status`),
INDEX `idx_weigh_timestamp` (`timestamp` DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 3. Seed municipal highway toll plazas
INSERT INTO `nyx_toll_plazas`
(`plaza_id`, `zone_name`, `base_fee`, `commercial_axle_multiplier`, `active_status`, `total_collected`)
VALUES
('plaza_del_perro_fwy', 'Del Perro Freeway Gantry', 5.00, 1.50, 1, 0.00),
('plaza_la_puerta_fwy', 'La Puerta Freeway Toll Plaza', 7.50, 1.75, 1, 0.00),
('plaza_palomino_fwy', 'Palomino Freeway East Barrier', 10.00, 2.00, 1, 0.00),
('plaza_senora_fwy', 'Senora Freeway North Express Gantry', 6.00, 1.60, 1, 0.00)
ON DUPLICATE KEY UPDATE `zone_name` = VALUES(`zone_name`);

SET FOREIGN_KEY_CHECKS = 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
-- ============================================================================
-- Nyxframework: nyx_vehicles, nyx_logistics, nyx_treasury & nyx_mdt
-- Migration: 066_municipal_toll_booths_and_commercial_weigh_stations.sql
-- Description: Municipal transit infrastructure, highway toll plazas,
-- automated RFID toll deduction, commercial axle multipliers,
-- and commercial weigh station inspection/bypass logging.
-- Engine: InnoDB | Charset: utf8mb4 | Collation: utf8mb4_unicode_ci
-- ============================================================================

SET FOREIGN_KEY_CHECKS = 0;

-- 1. Create municipal toll plazas table
CREATE TABLE IF NOT EXISTS `nyx_toll_plazas` (
`plaza_id` VARCHAR(32) NOT NULL PRIMARY KEY,
`zone_name` VARCHAR(64) NOT NULL,
`base_fee` DECIMAL(10, 2) NOT NULL DEFAULT 5.00,
`commercial_axle_multiplier` DECIMAL(5, 2) NOT NULL DEFAULT 1.50,
`active_status` TINYINT(1) NOT NULL DEFAULT 1,
`total_collected` DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_toll_zone` (`zone_name`),
INDEX `idx_toll_status` (`active_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 2. Create automated commercial weigh station inspection logs table
CREATE TABLE IF NOT EXISTS `nyx_weigh_station_logs` (
`log_id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`vehicle_plate` VARCHAR(16) NOT NULL,
`driver_identifier` VARCHAR(64) NULL,
`manifest_id` VARCHAR(64) NULL,
`gross_weight_kg` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
`max_allowed_kg` DECIMAL(10, 2) NOT NULL DEFAULT 15000.00,
`overweight_fine` DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
`inspection_status` ENUM('PASS', 'OVERWEIGHT', 'CONTRABAND_FLAG', 'BYPASSED') NOT NULL DEFAULT 'PASS',
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_weigh_plate` (`vehicle_plate`),
INDEX `idx_weigh_driver` (`driver_identifier`),
INDEX `idx_weigh_manifest` (`manifest_id`),
INDEX `idx_weigh_status` (`inspection_status`),
INDEX `idx_weigh_timestamp` (`timestamp` DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 3. Seed municipal highway toll plazas
INSERT INTO `nyx_toll_plazas`
(`plaza_id`, `zone_name`, `base_fee`, `commercial_axle_multiplier`, `active_status`, `total_collected`)
VALUES
('plaza_del_perro_fwy', 'Del Perro Freeway Gantry', 5.00, 1.50, 1, 0.00),
('plaza_la_puerta_fwy', 'La Puerta Freeway Toll Plaza', 7.50, 1.75, 1, 0.00),
('plaza_palomino_fwy', 'Palomino Freeway East Barrier', 10.00, 2.00, 1, 0.00),
('plaza_senora_fwy', 'Senora Freeway North Express Gantry', 6.00, 1.60, 1, 0.00)
ON DUPLICATE KEY UPDATE `zone_name` = VALUES(`zone_name`);

SET FOREIGN_KEY_CHECKS = 1;
Loading
Loading