678 lines
36 KiB
PHP
678 lines
36 KiB
PHP
<?php
|
|
|
|
namespace Modules\ProjectManagement\Database\Seeders;
|
|
|
|
use App\Models\User;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Database\Seeder;
|
|
use Modules\ContractorManagement\Models\Contractor;
|
|
use Modules\ProjectManagement\Models\Project;
|
|
use Modules\ProjectManagement\Models\ProjectMilestone;
|
|
use Modules\ProjectManagement\Models\Task;
|
|
use Modules\ProjectManagement\Models\TaskMaterial;
|
|
use Modules\ProjectManagement\Models\TaskEquipment;
|
|
use Modules\MasterData\Models\Material;
|
|
use Modules\Equipments\Models\Equipment;
|
|
use Modules\ProjectManagement\Enums\ProjectStatus;
|
|
use Modules\ProjectManagement\Enums\TaskStatus;
|
|
|
|
class FgenPpaServiceRoadSeeder extends Seeder
|
|
{
|
|
/**
|
|
* Run the database seeds.
|
|
*/
|
|
public function run(): void
|
|
{
|
|
// 1. Security Check: Only Super Admin can run it in session/web context.
|
|
if (auth()->check() && !auth()->user()->hasRole('Super Admin')) {
|
|
throw new \Illuminate\Auth\Access\AuthorizationException('Only Super Admin is authorized to run this seeder.');
|
|
}
|
|
|
|
// 2. Setup Contractor
|
|
$contractor = Contractor::firstOrCreate(
|
|
['email' => 'contractor-fgen@demo.com'],
|
|
[
|
|
'company_name' => 'FGEN Construction Corp',
|
|
'contact_person' => 'Juan dela Cruz',
|
|
'phone' => '+63 917 123 4567',
|
|
'specialization' => 'Civil Works',
|
|
'address' => 'Batangas, Philippines',
|
|
'status' => 'active',
|
|
'type' => 'main',
|
|
]
|
|
);
|
|
|
|
// 3. Setup Customer User (Client)
|
|
$customer = User::where('user_type', 'customer')->first();
|
|
if (!$customer) {
|
|
$customer = User::create([
|
|
'name' => 'First Gen Power Corporation',
|
|
'email' => 'client-fgen@demo.com',
|
|
'password' => bcrypt('password'),
|
|
'user_type' => 'customer',
|
|
'status' => 'active',
|
|
]);
|
|
}
|
|
|
|
// 4. Setup Employees and Roles
|
|
$pm = User::where('email', 'pm@fgen.com')->first();
|
|
if (!$pm) {
|
|
$pm = User::create([
|
|
'name' => 'Pedro Penduko',
|
|
'email' => 'pm@fgen.com',
|
|
'password' => bcrypt('password'),
|
|
'user_type' => 'employee',
|
|
'status' => 'active',
|
|
'contractor_id' => $contractor->id,
|
|
]);
|
|
$pm->assignRole('Project Manager');
|
|
}
|
|
|
|
$engineer = User::where('email', 'engineer@fgen.com')->first();
|
|
if (!$engineer) {
|
|
$engineer = User::create([
|
|
'name' => 'Engr. Maria Santos',
|
|
'email' => 'engineer@fgen.com',
|
|
'password' => bcrypt('password'),
|
|
'user_type' => 'employee',
|
|
'status' => 'active',
|
|
'contractor_id' => $contractor->id,
|
|
]);
|
|
$engineer->assignRole('Site Technical');
|
|
}
|
|
|
|
$foreman = User::where('email', 'foreman@fgen.com')->first();
|
|
if (!$foreman) {
|
|
$foreman = User::create([
|
|
'name' => 'Foreman Tomas',
|
|
'email' => 'foreman@fgen.com',
|
|
'password' => bcrypt('password'),
|
|
'user_type' => 'employee',
|
|
'status' => 'active',
|
|
'contractor_id' => $contractor->id,
|
|
]);
|
|
$foreman->assignRole('Construction Supervisor');
|
|
}
|
|
|
|
// 5. Seed Materials
|
|
$materialsData = [
|
|
'Selected Fill Materials' => ['category' => 'Aggregates', 'unit' => 'Ton', 'unit_cost' => 18.00, 'description' => 'Selected fill materials for compaction and grading.'],
|
|
'Water for Compaction' => ['category' => 'Aggregates', 'unit' => 'Kiloliter', 'unit_cost' => 50.00, 'description' => 'Water used for moisture conditioning and compaction.'],
|
|
'Reinforced Concrete Pipes (RCP)' => ['category' => 'Concrete & Cement', 'unit' => 'Piece', 'unit_cost' => 150.00, 'description' => 'Reinforced Concrete Pipes (RCP) for drainage lines.'],
|
|
'Portland Cement Type I' => ['category' => 'Concrete & Cement', 'unit' => 'Bag (40kg)', 'unit_cost' => 8.50, 'description' => 'Standard portland cement.'],
|
|
'River Sand' => ['category' => 'Aggregates', 'unit' => 'Ton', 'unit_cost' => 20.00, 'description' => 'Washed river sand.'],
|
|
'Crushed Stone (Gravel) 3/4"' => ['category' => 'Aggregates', 'unit' => 'Ton', 'unit_cost' => 25.00, 'description' => '3/4 inch crushed gravel.'],
|
|
'Rebar #4 (1/2" x 20 ft)' => ['category' => 'Steel & Metal', 'unit' => 'Piece', 'unit_cost' => 6.20, 'description' => 'Standard #4 reinforcing bar.'],
|
|
'Plywood (CDX) 15/32" (4x8 ft)' => ['category' => 'Timber & Wood', 'unit' => 'Sheet', 'unit_cost' => 22.00, 'description' => 'Plywood for concrete formworks.'],
|
|
'Backfill Materials' => ['category' => 'Aggregates', 'unit' => 'Ton', 'unit_cost' => 15.00, 'description' => 'Backfill materials for drainage structures.'],
|
|
'Soil Stabilizer' => ['category' => 'Concrete & Cement', 'unit' => 'Bag (40kg)', 'unit_cost' => 12.00, 'description' => 'Chemical stabilizer for subgrade improvement.'],
|
|
'Base Gravel (Class 5)' => ['category' => 'Aggregates', 'unit' => 'Ton', 'unit_cost' => 18.00, 'description' => 'Class 5 aggregate base course.'],
|
|
'Ready Mix Concrete (30 MPa)' => ['category' => 'Concrete & Cement', 'unit' => 'Cubic Meter', 'unit_cost' => 130.00, 'description' => '30 MPa Ready-mix concrete.'],
|
|
'Tie Bars' => ['category' => 'Steel & Metal', 'unit' => 'Piece', 'unit_cost' => 4.50, 'description' => 'Steel tie bars for pavement joints.'],
|
|
'Dowel Bars' => ['category' => 'Steel & Metal', 'unit' => 'Piece', 'unit_cost' => 5.50, 'description' => 'Steel dowel bars for load transfer.'],
|
|
'Joint Sealant' => ['category' => 'Consumables', 'unit' => 'Tube', 'unit_cost' => 7.00, 'description' => 'Elastomeric joint sealant.'],
|
|
'Curing Compound' => ['category' => 'Consumables', 'unit' => 'Pail (20L)', 'unit_cost' => 45.00, 'description' => 'Concrete curing compound.'],
|
|
'Riprap Stones' => ['category' => 'Aggregates', 'unit' => 'Ton', 'unit_cost' => 35.00, 'description' => 'Stones for slope protection riprap.'],
|
|
'Geotextile Fabric' => ['category' => 'Consumables', 'unit' => 'Roll', 'unit_cost' => 150.00, 'description' => 'Filter fabric for drainage and slope protection.'],
|
|
'Traffic Signs' => ['category' => 'Safety & Finishing', 'unit' => 'Piece', 'unit_cost' => 85.00, 'description' => 'Reflective road signs.'],
|
|
'Guardrails' => ['category' => 'Safety & Finishing', 'unit' => 'Piece', 'unit_cost' => 110.00, 'description' => 'Metal guardrail beams.'],
|
|
'Thermoplastic Paint' => ['category' => 'Safety & Finishing', 'unit' => 'Bag (25kg)', 'unit_cost' => 40.00, 'description' => 'Thermoplastic road marking paint.'],
|
|
'Glass Beads' => ['category' => 'Safety & Finishing', 'unit' => 'Bag (25kg)', 'unit_cost' => 25.00, 'description' => 'Reflective glass beads for thermoplastic paint.'],
|
|
'Reflectors' => ['category' => 'Safety & Finishing', 'unit' => 'Piece', 'unit_cost' => 12.00, 'description' => 'Cat-eye road reflectors.'],
|
|
'Delineators' => ['category' => 'Safety & Finishing', 'unit' => 'Piece', 'unit_cost' => 15.00, 'description' => 'Flexible guide posts.'],
|
|
'Topsoil' => ['category' => 'Aggregates', 'unit' => 'Ton', 'unit_cost' => 22.00, 'description' => 'Topsoil for landscape restoration.'],
|
|
'Landscaping Materials' => ['category' => 'Aggregates', 'unit' => 'Pack', 'unit_cost' => 50.00, 'description' => 'Grass seeds, turf, and other plantings.'],
|
|
];
|
|
|
|
$materials = [];
|
|
foreach ($materialsData as $name => $meta) {
|
|
$materials[$name] = Material::where('name', $name)
|
|
->where(fn($q) => $q->where('contractor_id', $contractor->id)->orWhereNull('contractor_id'))
|
|
->first();
|
|
if (!$materials[$name]) {
|
|
$baseSku = strtoupper(substr($meta['category'], 0, 3)) . '-' . rand(1000, 9999);
|
|
$materials[$name] = Material::create([
|
|
'name' => $name,
|
|
'contractor_id' => $contractor->id,
|
|
'sku' => $baseSku,
|
|
'category' => $meta['category'],
|
|
'unit' => $meta['unit'],
|
|
'unit_cost' => $meta['unit_cost'],
|
|
'description' => $meta['description'],
|
|
'type' => 'single',
|
|
'status' => 'active',
|
|
]);
|
|
}
|
|
}
|
|
|
|
// 6. Seed Equipment
|
|
$equipmentsData = [
|
|
'Excavator' => ['hourly_rate' => 1500.00],
|
|
'Bulldozer' => ['hourly_rate' => 1600.00],
|
|
'Motor Grader' => ['hourly_rate' => 1400.00],
|
|
'Vibratory Roller' => ['hourly_rate' => 1200.00],
|
|
'Water Truck' => ['hourly_rate' => 1000.00],
|
|
'Dump Truck' => ['hourly_rate' => 1200.00],
|
|
'Concrete Mixer' => ['hourly_rate' => 350.00],
|
|
'Concrete Vibrator' => ['hourly_rate' => 150.00],
|
|
'Plate Compactor' => ['hourly_rate' => 200.00],
|
|
'Wheel Loader' => ['hourly_rate' => 1300.00],
|
|
'Transit Mixer' => ['hourly_rate' => 1100.00],
|
|
'Concrete Cutter' => ['hourly_rate' => 250.00],
|
|
'Power Trowel' => ['hourly_rate' => 200.00],
|
|
'Crane' => ['hourly_rate' => 2500.00],
|
|
'Road Marking Machine' => ['hourly_rate' => 300.00],
|
|
'Air Compressor' => ['hourly_rate' => 250.00],
|
|
'Pickup Truck' => ['hourly_rate' => 400.00],
|
|
];
|
|
|
|
$equipments = [];
|
|
foreach ($equipmentsData as $name => $meta) {
|
|
$equipments[$name] = Equipment::firstOrCreate(
|
|
['name' => $name],
|
|
[
|
|
'owner_name' => 'Company Owned',
|
|
'hourly_rate' => $meta['hourly_rate'],
|
|
'status' => 'active',
|
|
]
|
|
);
|
|
}
|
|
|
|
// 7. Seed Project
|
|
$project = Project::firstOrCreate(
|
|
['name' => 'Construction of FGEN-PPA Service Road'],
|
|
[
|
|
'description' => 'Construction of the FGEN-PPA Service Road including site clearing, drainage, subgrade prep, base course, concrete pavement, shoulder protection, safety markings, and cleanup.',
|
|
'customer_id' => $customer->id ?? null,
|
|
'client_name' => $customer ? $customer->name : 'First Gen Power Corporation',
|
|
'contractor_id' => $contractor->id,
|
|
'location' => 'Batangas, Philippines',
|
|
'status' => ProjectStatus::Planning,
|
|
'contract_value' => 15500000.00,
|
|
'total_estimated_value' => 15500000.00,
|
|
'contract_duration' => 8,
|
|
'start_date' => '2026-07-01',
|
|
'target_end_date' => '2027-02-28',
|
|
'completion_percentage' => 0.00,
|
|
'total_capitalization' => 0.00,
|
|
]
|
|
);
|
|
|
|
// Sync contractor relation safely
|
|
$contractor->projects()->syncWithoutDetaching([
|
|
$project->id => ['role' => 'Primary Contractor', 'contract_amount' => $project->contract_value]
|
|
]);
|
|
|
|
// Assign PM to Project
|
|
$project->personnel()->syncWithoutDetaching([
|
|
$pm->id => ['role' => 'pm'],
|
|
$engineer->id => ['role' => 'engineer'],
|
|
$foreman->id => ['role' => 'laborer'],
|
|
]);
|
|
|
|
// Transition Project Status to In Progress
|
|
if ($project->status !== ProjectStatus::InProgress) {
|
|
if ($project->status === ProjectStatus::UnderBidding) {
|
|
$project->transitionTo(ProjectStatus::Planning);
|
|
}
|
|
if ($project->status === ProjectStatus::Planning) {
|
|
$project->transitionTo(ProjectStatus::InProgress);
|
|
}
|
|
}
|
|
|
|
// 8. Seed Milestones and Tasks
|
|
$milestonesConfig = [
|
|
[
|
|
'name' => 'Milestone 1: Site Clearing and Earthworks',
|
|
'description' => 'Site clearing, grubbing, unsuitable soil removal, and embankment compaction.',
|
|
'weight' => 10.0,
|
|
'tasks' => [
|
|
[
|
|
'name' => 'Clearing and grubbing using excavators, bulldozers, chainsaws, and dump trucks',
|
|
'description' => 'Remove vegetation, roots, and topsoil to clear the road path.',
|
|
'est_hours' => 80,
|
|
'labor_cost' => 50000.00,
|
|
'equipment_cost' => 120000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Excavator' => 80, 'Bulldozer' => 40, 'Dump Truck' => 80],
|
|
],
|
|
[
|
|
'name' => 'Removal and hauling of unsuitable materials using excavators and dump trucks',
|
|
'description' => 'Excavate unsuitable materials and transport them to the designated disposal site.',
|
|
'est_hours' => 60,
|
|
'labor_cost' => 40000.00,
|
|
'equipment_cost' => 90000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Excavator' => 60, 'Dump Truck' => 120],
|
|
],
|
|
[
|
|
'name' => 'Excavation and embankment works using excavators, bulldozers, graders, and dump trucks',
|
|
'description' => 'Perform roadbed cutting and filling to meet design elevation.',
|
|
'est_hours' => 120,
|
|
'labor_cost' => 80000.00,
|
|
'equipment_cost' => 200000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Excavator' => 120, 'Bulldozer' => 60, 'Motor Grader' => 60, 'Dump Truck' => 120],
|
|
],
|
|
[
|
|
'name' => 'Filling and spreading of selected fill materials using graders and bulldozers',
|
|
'description' => 'Spread selected borrow materials on the roadbed in layers.',
|
|
'est_hours' => 80,
|
|
'labor_cost' => 50000.00,
|
|
'equipment_cost' => 130000.00,
|
|
'materials' => ['Selected Fill Materials' => 500.0],
|
|
'equipments' => ['Motor Grader' => 80, 'Bulldozer' => 40],
|
|
],
|
|
[
|
|
'name' => 'Compaction of embankment and subgrade using vibratory rollers and water trucks',
|
|
'description' => 'Apply water and compact the fill layers to the required density.',
|
|
'est_hours' => 60,
|
|
'labor_cost' => 30000.00,
|
|
'equipment_cost' => 100000.00,
|
|
'materials' => ['Water for Compaction' => 200.0],
|
|
'equipments' => ['Vibratory Roller' => 60, 'Water Truck' => 60],
|
|
],
|
|
]
|
|
],
|
|
[
|
|
'name' => 'Milestone 2: Drainage Construction',
|
|
'description' => 'Drainage excavation, RCP installation, catch basins, and backfilling.',
|
|
'weight' => 15.0,
|
|
'tasks' => [
|
|
[
|
|
'name' => 'Excavation for drainage lines and structures',
|
|
'description' => 'Excavate trenches for stormwater drainage pipes and structures.',
|
|
'est_hours' => 50,
|
|
'labor_cost' => 30000.00,
|
|
'equipment_cost' => 75000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Excavator' => 50],
|
|
],
|
|
[
|
|
'name' => 'Installation of reinforced concrete pipes (RCP)',
|
|
'description' => 'Lay and align reinforced concrete pipes in the excavated trenches.',
|
|
'est_hours' => 80,
|
|
'labor_cost' => 60000.00,
|
|
'equipment_cost' => 80000.00,
|
|
'materials' => ['Reinforced Concrete Pipes (RCP)' => 150.0],
|
|
'equipments' => ['Excavator' => 40, 'Dump Truck' => 40],
|
|
],
|
|
[
|
|
'name' => 'Placement of bedding materials',
|
|
'description' => 'Place sand or gravel bedding at the bottom of the trenches before laying pipes.',
|
|
'est_hours' => 40,
|
|
'labor_cost' => 25000.00,
|
|
'equipment_cost' => 15000.00,
|
|
'materials' => ['Crushed Stone (Gravel) 3/4"' => 80.0, 'River Sand' => 50.0],
|
|
'equipments' => [],
|
|
],
|
|
[
|
|
'name' => 'Construction of catch basins and manholes',
|
|
'description' => 'Form and pour concrete for catch basins and junction manholes.',
|
|
'est_hours' => 100,
|
|
'labor_cost' => 90000.00,
|
|
'equipment_cost' => 30000.00,
|
|
'materials' => ['Portland Cement Type I' => 120.0, 'River Sand' => 15.0, 'Crushed Stone (Gravel) 3/4"' => 25.0, 'Rebar #4 (1/2" x 20 ft)' => 100.0, 'Plywood (CDX) 15/32" (4x8 ft)' => 20.0],
|
|
'equipments' => ['Concrete Mixer' => 80, 'Concrete Vibrator' => 80],
|
|
],
|
|
[
|
|
'name' => 'Concrete pouring for drainage structures',
|
|
'description' => 'Pour concrete for headwalls, wingwalls, and drainage aprons.',
|
|
'est_hours' => 60,
|
|
'labor_cost' => 50000.00,
|
|
'equipment_cost' => 20000.00,
|
|
'materials' => ['Portland Cement Type I' => 80.0, 'River Sand' => 10.0, 'Crushed Stone (Gravel) 3/4"' => 18.0, 'Rebar #4 (1/2" x 20 ft)' => 50.0, 'Plywood (CDX) 15/32" (4x8 ft)' => 15.0],
|
|
'equipments' => ['Concrete Mixer' => 40, 'Concrete Vibrator' => 40],
|
|
],
|
|
[
|
|
'name' => 'Backfilling and compaction around drainage facilities',
|
|
'description' => 'Backfill around catch basins and pipes, then compact using plate compactors.',
|
|
'est_hours' => 40,
|
|
'labor_cost' => 20000.00,
|
|
'equipment_cost' => 25000.00,
|
|
'materials' => ['Backfill Materials' => 120.0],
|
|
'equipments' => ['Dump Truck' => 40, 'Plate Compactor' => 40],
|
|
],
|
|
]
|
|
],
|
|
[
|
|
'name' => 'Milestone 3: Subgrade Preparation',
|
|
'description' => 'Final roadbed grading, moisture conditioning, and stabilization.',
|
|
'weight' => 10.0,
|
|
'tasks' => [
|
|
[
|
|
'name' => 'Final grading and shaping of roadbed',
|
|
'description' => 'Grade the road subgrade to the design crown and cross-slope.',
|
|
'est_hours' => 50,
|
|
'labor_cost' => 30000.00,
|
|
'equipment_cost' => 70000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Motor Grader' => 50],
|
|
],
|
|
[
|
|
'name' => 'Moisture conditioning',
|
|
'description' => 'Sprinkle water or aerate subgrade soil to achieve optimum moisture content.',
|
|
'est_hours' => 30,
|
|
'labor_cost' => 15000.00,
|
|
'equipment_cost' => 30000.00,
|
|
'materials' => ['Water for Compaction' => 100.0],
|
|
'equipments' => ['Water Truck' => 30],
|
|
],
|
|
[
|
|
'name' => 'Compaction of subgrade layer',
|
|
'description' => 'Roll the subgrade to achieve at least 95% maximum dry density.',
|
|
'est_hours' => 40,
|
|
'labor_cost' => 20000.00,
|
|
'equipment_cost' => 50000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Vibratory Roller' => 40, 'Plate Compactor' => 20],
|
|
],
|
|
[
|
|
'name' => 'Subgrade stabilization (if required)',
|
|
'description' => 'Mix in soil stabilizers to improve bearing capacity in soft areas.',
|
|
'est_hours' => 60,
|
|
'labor_cost' => 45000.00,
|
|
'equipment_cost' => 84000.00,
|
|
'materials' => ['Soil Stabilizer' => 150.0, 'Base Gravel (Class 5)' => 100.0],
|
|
'equipments' => ['Motor Grader' => 40, 'Vibratory Roller' => 30],
|
|
],
|
|
]
|
|
],
|
|
[
|
|
'name' => 'Milestone 4: Aggregate Base Course Installation',
|
|
'description' => 'Delivery, spreading, leveling, and compacting aggregate base course.',
|
|
'weight' => 15.0,
|
|
'tasks' => [
|
|
[
|
|
'name' => 'Delivery and stockpiling of aggregate base materials',
|
|
'description' => 'Haul and dump aggregate base material at designated intervals on the road.',
|
|
'est_hours' => 80,
|
|
'labor_cost' => 40000.00,
|
|
'equipment_cost' => 96000.00,
|
|
'materials' => ['Base Gravel (Class 5)' => 1200.0],
|
|
'equipments' => ['Dump Truck' => 80],
|
|
],
|
|
[
|
|
'name' => 'Spreading and leveling of aggregate base course',
|
|
'description' => 'Spread base gravel to a uniform thickness using graders.',
|
|
'est_hours' => 60,
|
|
'labor_cost' => 35000.00,
|
|
'equipment_cost' => 110000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Motor Grader' => 60, 'Wheel Loader' => 30],
|
|
],
|
|
[
|
|
'name' => 'Water application and compaction',
|
|
'description' => 'Condition aggregate base course with water and compact thoroughly.',
|
|
'est_hours' => 50,
|
|
'labor_cost' => 25000.00,
|
|
'equipment_cost' => 85000.00,
|
|
'materials' => ['Water for Compaction' => 300.0],
|
|
'equipments' => ['Vibratory Roller' => 50, 'Water Truck' => 50],
|
|
],
|
|
[
|
|
'name' => 'Layer thickness adjustments',
|
|
'description' => 'Correct grade deviations and ensure thickness meets target specifications.',
|
|
'est_hours' => 30,
|
|
'labor_cost' => 18000.00,
|
|
'equipment_cost' => 42000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Motor Grader' => 30],
|
|
],
|
|
]
|
|
],
|
|
[
|
|
'name' => 'Milestone 5: Concrete Pavement Construction',
|
|
'description' => 'Formworks, rebar/dowel setup, concrete pouring, finishing, curing, and jointing.',
|
|
'weight' => 30.0,
|
|
'tasks' => [
|
|
[
|
|
'name' => 'Installation of formworks',
|
|
'description' => 'Set up and align steel or timber forms to define the concrete road edge.',
|
|
'est_hours' => 80,
|
|
'labor_cost' => 60000.00,
|
|
'equipment_cost' => 15000.00,
|
|
'materials' => ['Plywood (CDX) 15/32" (4x8 ft)' => 100.0],
|
|
'equipments' => ['Pickup Truck' => 40],
|
|
],
|
|
[
|
|
'name' => 'Placement of reinforcing steel (if specified)',
|
|
'description' => 'Assemble and lay down tie bars and dowel bars at joint assemblies.',
|
|
'est_hours' => 80,
|
|
'labor_cost' => 70000.00,
|
|
'equipment_cost' => 20000.00,
|
|
'materials' => ['Rebar #4 (1/2" x 20 ft)' => 200.0, 'Tie Bars' => 250.0, 'Dowel Bars' => 250.0],
|
|
'equipments' => ['Pickup Truck' => 20],
|
|
],
|
|
[
|
|
'name' => 'Concrete batching and delivery',
|
|
'description' => 'Batch concrete and deliver to site using transit mixers.',
|
|
'est_hours' => 120,
|
|
'labor_cost' => 80000.00,
|
|
'equipment_cost' => 160000.00,
|
|
'materials' => ['Ready Mix Concrete (30 MPa)' => 600.0],
|
|
'equipments' => ['Transit Mixer' => 120, 'Concrete Mixer' => 40],
|
|
],
|
|
[
|
|
'name' => 'Concrete pouring and finishing',
|
|
'description' => 'Pour concrete into forms, consolidate with vibrators, and strike off.',
|
|
'est_hours' => 100,
|
|
'labor_cost' => 110000.00,
|
|
'equipment_cost' => 40000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Concrete Vibrator' => 100, 'Power Trowel' => 50],
|
|
],
|
|
[
|
|
'name' => 'Concrete curing',
|
|
'description' => 'Apply curing compound or pond water to ensure proper hydration.',
|
|
'est_hours' => 40,
|
|
'labor_cost' => 20000.00,
|
|
'equipment_cost' => 40000.00,
|
|
'materials' => ['Curing Compound' => 30.0, 'Water for Compaction' => 150.0],
|
|
'equipments' => ['Water Truck' => 40],
|
|
],
|
|
[
|
|
'name' => 'Joint cutting and sealing',
|
|
'description' => 'Saw contraction joints in hardened concrete and apply joint sealant.',
|
|
'est_hours' => 50,
|
|
'labor_cost' => 35000.00,
|
|
'equipment_cost' => 20000.00,
|
|
'materials' => ['Joint Sealant' => 80.0],
|
|
'equipments' => ['Concrete Cutter' => 50],
|
|
],
|
|
]
|
|
],
|
|
[
|
|
'name' => 'Milestone 6: Shoulder and Slope Protection Works',
|
|
'description' => 'Shoulder fill placement, riprap construction, and compaction.',
|
|
'weight' => 10.0,
|
|
'tasks' => [
|
|
[
|
|
'name' => 'Placement of shoulder materials',
|
|
'description' => 'Lay aggregate shoulder material along the edges of the concrete pavement.',
|
|
'est_hours' => 60,
|
|
'labor_cost' => 35000.00,
|
|
'equipment_cost' => 75000.00,
|
|
'materials' => ['Selected Fill Materials' => 200.0, 'Base Gravel (Class 5)' => 150.0],
|
|
'equipments' => ['Excavator' => 30, 'Dump Truck' => 30, 'Wheel Loader' => 30],
|
|
],
|
|
[
|
|
'name' => 'Construction of riprap or slope protection',
|
|
'description' => 'Place riprap stones and geotextile fabric on slopes to prevent erosion.',
|
|
'est_hours' => 100,
|
|
'labor_cost' => 85000.00,
|
|
'equipment_cost' => 90000.00,
|
|
'materials' => ['Riprap Stones' => 400.0, 'Geotextile Fabric' => 10.0],
|
|
'equipments' => ['Excavator' => 60, 'Dump Truck' => 40],
|
|
],
|
|
[
|
|
'name' => 'Compaction of shoulder areas',
|
|
'description' => 'Compact the shoulder aggregate to align with road surface.',
|
|
'est_hours' => 40,
|
|
'labor_cost' => 20000.00,
|
|
'equipment_cost' => 48000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Vibratory Roller' => 40],
|
|
],
|
|
]
|
|
],
|
|
[
|
|
'name' => 'Milestone 7: Road Safety and Finishing Works',
|
|
'description' => 'Road signs, guardrails, pavement markings, and reflectors.',
|
|
'weight' => 5.0,
|
|
'tasks' => [
|
|
[
|
|
'name' => 'Installation of road signs',
|
|
'description' => 'Erect regulatory, warning, and guide signs along the road alignment.',
|
|
'est_hours' => 30,
|
|
'labor_cost' => 20000.00,
|
|
'equipment_cost' => 15000.00,
|
|
'materials' => ['Traffic Signs' => 15.0],
|
|
'equipments' => ['Pickup Truck' => 30],
|
|
],
|
|
[
|
|
'name' => 'Installation of guardrails',
|
|
'description' => 'Install steel guardrails in high embankment or curve zones.',
|
|
'est_hours' => 50,
|
|
'labor_cost' => 35000.00,
|
|
'equipment_cost' => 25000.00,
|
|
'materials' => ['Guardrails' => 50.0],
|
|
'equipments' => ['Pickup Truck' => 40],
|
|
],
|
|
[
|
|
'name' => 'Application of pavement markings',
|
|
'description' => 'Apply thermoplastic markings for centerlines and edge lines.',
|
|
'est_hours' => 40,
|
|
'labor_cost' => 30000.00,
|
|
'equipment_cost' => 20000.00,
|
|
'materials' => ['Thermoplastic Paint' => 25.0, 'Glass Beads' => 10.0],
|
|
'equipments' => ['Road Marking Machine' => 40, 'Air Compressor' => 40],
|
|
],
|
|
[
|
|
'name' => 'Installation of reflectors and delineators',
|
|
'description' => 'Fix cat-eye reflectors and flexible delineator posts on the road surface.',
|
|
'est_hours' => 30,
|
|
'labor_cost' => 15000.00,
|
|
'equipment_cost' => 5000.00,
|
|
'materials' => ['Reflectors' => 120.0, 'Delineators' => 80.0],
|
|
'equipments' => [],
|
|
],
|
|
]
|
|
],
|
|
[
|
|
'name' => 'Milestone 8: Final Restoration and Site Cleanup',
|
|
'description' => 'Removal of excess materials, site grading, restoration, and debris disposal.',
|
|
'weight' => 5.0,
|
|
'tasks' => [
|
|
[
|
|
'name' => 'Removal of excess materials',
|
|
'description' => 'Load and transport leftover gravel, wood, and other items from the site.',
|
|
'est_hours' => 40,
|
|
'labor_cost' => 20000.00,
|
|
'equipment_cost' => 60000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Excavator' => 20, 'Dump Truck' => 40, 'Wheel Loader' => 20],
|
|
],
|
|
[
|
|
'name' => 'Site grading and restoration',
|
|
'description' => 'Perform cosmetic grading and layout topsoil/vegetation along the roadside.',
|
|
'est_hours' => 50,
|
|
'labor_cost' => 30000.00,
|
|
'equipment_cost' => 70000.00,
|
|
'materials' => ['Topsoil' => 100.0, 'Landscaping Materials' => 20.0],
|
|
'equipments' => ['Motor Grader' => 30, 'Wheel Loader' => 20],
|
|
],
|
|
[
|
|
'name' => 'Disposal of construction debris',
|
|
'description' => 'Haul construction debris and waste materials to authorized landfills.',
|
|
'est_hours' => 30,
|
|
'labor_cost' => 15000.00,
|
|
'equipment_cost' => 36000.00,
|
|
'materials' => [],
|
|
'equipments' => ['Dump Truck' => 30],
|
|
],
|
|
]
|
|
],
|
|
];
|
|
|
|
$startDate = Carbon::parse($project->start_date);
|
|
|
|
foreach ($milestonesConfig as $idx => $mConfig) {
|
|
$plannedDate = $startDate->copy()->addMonths($idx)->endOfMonth();
|
|
|
|
$milestone = ProjectMilestone::firstOrCreate(
|
|
[
|
|
'project_id' => $project->id,
|
|
'name' => $mConfig['name']
|
|
],
|
|
[
|
|
'description' => $mConfig['description'],
|
|
'planned_date' => $plannedDate->format('Y-m-d'),
|
|
'sort_order' => $idx + 1,
|
|
'weight_percentage' => $mConfig['weight'],
|
|
'is_default' => false,
|
|
]
|
|
);
|
|
|
|
foreach ($mConfig['tasks'] as $tIdx => $tData) {
|
|
$task = Task::firstOrCreate(
|
|
[
|
|
'project_id' => $project->id,
|
|
'milestone_id' => $milestone->id,
|
|
'name' => $tData['name']
|
|
],
|
|
[
|
|
'description' => $tData['description'],
|
|
'status' => TaskStatus::Pending,
|
|
'sort_order' => $tIdx + 1,
|
|
'labor_cost' => $tData['labor_cost'],
|
|
'equipment_cost' => $tData['equipment_cost'],
|
|
'estimated_hours' => $tData['est_hours'],
|
|
'actual_hours' => 0.00,
|
|
'start_date' => $startDate->copy()->addMonths($idx)->startOfMonth()->format('Y-m-d'),
|
|
'end_date' => $plannedDate->format('Y-m-d'),
|
|
'completion_percentage' => 0.00,
|
|
]
|
|
);
|
|
|
|
// Assign users to the task
|
|
$task->users()->syncWithoutDetaching([$engineer->id, $foreman->id]);
|
|
|
|
// Seed task materials
|
|
foreach ($tData['materials'] as $mName => $qty) {
|
|
$material = $materials[$mName];
|
|
TaskMaterial::firstOrCreate(
|
|
[
|
|
'task_id' => $task->id,
|
|
'material_id' => $material->id
|
|
],
|
|
[
|
|
'planned_qty' => $qty,
|
|
'actual_qty' => 0.00,
|
|
'unit_cost' => $material->unit_cost,
|
|
]
|
|
);
|
|
}
|
|
|
|
// Seed task equipment
|
|
foreach ($tData['equipments'] as $eqName => $estHours) {
|
|
$eq = $equipments[$eqName];
|
|
TaskEquipment::firstOrCreate(
|
|
[
|
|
'task_id' => $task->id,
|
|
'equipment_id' => $eq->id
|
|
],
|
|
[
|
|
'estimated_hours' => $estHours,
|
|
'actual_hours' => 0.00,
|
|
]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 9. Recalculate Project Capitalization
|
|
$project->recalculateCapitalization();
|
|
}
|
|
}
|