Equipment Items
Overview
Equipment items represent rental equipment with two bidding modes:
- TRADITIONAL - Equipment assigned to individual scopes
- GANTT - Equipment tracked at bid level with timeline-based allocation
Traditional Mode
List Equipment Items
- Request
- Response
GET /api/equipment/scope/:scopeId
Cookie: sAccessToken=...; sRefreshToken=...
[
{
"id": "uuid",
"scopeId": "uuid",
"equipmentType": "Skid Steer",
"subcategory": "Daily",
"quantity": 1,
"durationValue": 5,
"durationUnit": "days",
"baseRentalCost": 2250.00,
"rentalTaxAmount": 185.63,
"rentalCost": 2435.63,
"fuelCharge": 250.00,
"deliveryFee": 150.00,
"trucksCost": 200.00,
"totalCost": 3035.63,
"pricingItemId": "uuid"
},
...
]
Roles: ADMIN, ESTIMATOR, PM
Create Equipment Item
- Request
- Response
POST /api/equipment
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"scopeId": "uuid",
"equipmentType": "Skid Steer",
"subcategory": "Daily",
"quantity": 1,
"durationValue": 5,
"durationUnit": "days",
"pricingItemId": "uuid",
"deliveryFee": 150.00
}
{
"id": "uuid",
"totalCost": 3035.63,
"message": "Equipment item created successfully"
}
Roles: ADMIN, ESTIMATOR
Required Fields:
scopeId(string, UUID) - Parent scopeequipmentType(string) - Equipment namesubcategory(string) - Rental period (Daily, Weekly, Monthly)quantity(number) - Number of unitsdurationValue(number) - Duration amountdurationUnit(string) - "days", "weeks", "months"pricingItemId(string, UUID) - Equipment pricing reference
Optional Fields:
deliveryFee(number) - One-time delivery chargefuelCharge(number) - Fuel coststrucksCost(number) - Hauling costs
Update Equipment Item
- Request
- Response
PUT /api/equipment/:id
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"durationValue": 7,
"quantity": 2
}
{
"id": "uuid",
"totalCost": 8500.00,
"message": "Equipment item updated successfully"
}
Roles: ADMIN, ESTIMATOR
Delete Equipment Item
- Request
- Response
DELETE /api/equipment/:id
Cookie: sAccessToken=...; sRefreshToken=...
{
"message": "Equipment item deleted successfully"
}
Roles: ADMIN, ESTIMATOR
Gantt Mode
When bid.equipmentBiddingMode = "GANTT", equipment is tracked at bid level with timeline-based allocation.
List Bid Equipment
- Request
- Response
GET /api/bids/:bidId/equipment
Cookie: sAccessToken=...; sRefreshToken=...
[
{
"id": "uuid",
"bidId": "uuid",
"equipmentType": "Skid Steer",
"description": "Skid Steer - Daily",
"pricingItemId": "uuid",
"quantity": 1,
"startDay": 5,
"durationDays": 10,
"dailyRate": 450.00,
"deliveryFee": 150.00,
"totalCost": 4650.00,
"distributions": [
{
"scopeId": "uuid",
"scopeName": "Foundation",
"overlapDays": 5,
"percentage": 50.0,
"allocatedCost": 2325.00,
"fuelCharge": 125.00,
"deliveryFee": 75.00
},
{
"scopeId": "uuid",
"scopeName": "Grade Beam",
"overlapDays": 5,
"percentage": 50.0,
"allocatedCost": 2325.00,
"fuelCharge": 125.00,
"deliveryFee": 75.00
}
]
},
...
]
Roles: ADMIN, ESTIMATOR, PM
Create Gantt Equipment
- Request
- Response
POST /api/bids/:bidId/equipment
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"equipmentType": "Skid Steer",
"description": "Skid Steer - Daily",
"pricingItemId": "uuid",
"quantity": 1,
"startDay": 5,
"durationDays": 10,
"dailyRate": 450.00,
"deliveryFee": 150.00
}
{
"id": "uuid",
"totalCost": 4650.00,
"message": "Equipment created successfully"
}
Roles: ADMIN, ESTIMATOR
Required Fields:
equipmentType(string) - Equipment namedescription(string) - Full descriptionpricingItemId(string, UUID) - Pricing referencequantity(number) - Number of unitsstartDay(number) - Start day (1-based)durationDays(number) - Duration in daysdailyRate(number) - Daily rental rate
Optional Fields:
deliveryFee(number) - One-time delivery charge
Update Gantt Equipment
- Request
- Response
PATCH /api/bids/:bidId/equipment/:id
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"startDay": 10,
"durationDays": 5
}
{
"id": "uuid",
"totalCost": 2400.00,
"message": "Equipment updated successfully"
}
Roles: ADMIN, ESTIMATOR
Delete Gantt Equipment
- Request
- Response
DELETE /api/bids/:bidId/equipment/:id
Cookie: sAccessToken=...; sRefreshToken=...
{
"message": "Equipment deleted successfully"
}
Roles: ADMIN, ESTIMATOR
Batch Update Equipment
- Request
- Response
POST /api/bids/:bidId/equipment/batch
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"create": [
{
"equipmentType": "Excavator",
"startDay": 1,
"durationDays": 5,
"dailyRate": 800.00,
"pricingItemId": "uuid"
}
],
"update": [
{
"id": "uuid",
"startDay": 10,
"durationDays": 5
}
],
"delete": ["uuid1", "uuid2"]
}
{
"created": 1,
"updated": 1,
"deleted": 2,
"message": "Batch update completed"
}
Roles: ADMIN, ESTIMATOR
Switch Equipment Bidding Mode
- Request
- Response
PATCH /api/bids/:bidId/equipment/mode
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"equipmentBiddingMode": "GANTT"
}
{
"message": "Equipment bidding mode updated to GANTT",
"warning": "This will clear existing equipment items"
}
Roles: ADMIN, ESTIMATOR
Switching modes will clear all existing equipment items. Use /mode/confirm to proceed.
Confirm Mode Switch
- Request
- Response
POST /api/bids/:bidId/equipment/mode/confirm
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json
{
"equipmentBiddingMode": "GANTT"
}
{
"message": "Equipment bidding mode switched to GANTT"
}
Roles: ADMIN, ESTIMATOR
Get Cost Distributions
- Request
- Response
GET /api/bids/:bidId/equipment/distributions
Cookie: sAccessToken=...; sRefreshToken=...
[
{
"equipmentId": "uuid",
"equipmentType": "Skid Steer",
"totalCost": 4650.00,
"distributions": [
{
"scopeId": "uuid",
"scopeName": "Foundation",
"overlapDays": 5,
"percentage": 50.0,
"allocatedCost": 2325.00,
"fuelCharge": 125.00,
"deliveryFee": 75.00
},
...
]
},
...
]
Roles: ADMIN, ESTIMATOR, PM
Get Scope Equipment Allocations
- Request
- Response
GET /api/bids/:bidId/equipment/scope/:scopeId
Cookie: sAccessToken=...; sRefreshToken=...
[
{
"equipmentId": "uuid",
"equipmentType": "Skid Steer",
"overlapDays": 5,
"percentage": 50.0,
"allocatedCost": 2325.00,
"fuelCharge": 125.00,
"deliveryFee": 75.00
},
...
]
Roles: ADMIN, ESTIMATOR, PM
Get Equipment Coverage Details
- Request
- Response
GET /api/bids/:bidId/equipment/:id/coverage
Cookie: sAccessToken=...; sRefreshToken=...
{
"equipment": {
"id": "uuid",
"equipmentType": "Skid Steer",
"startDay": 5,
"durationDays": 10,
"totalCost": 4650.00
},
"scopes": [
{
"scopeId": "uuid",
"scopeName": "Foundation",
"overlapDays": 5,
"percentage": 50.0,
"allocatedCost": 2325.00,
"fuelCharge": 125.00,
"deliveryFee": 75.00
},
...
]
}
Roles: ADMIN, ESTIMATOR, PM
Recalculate Distributions
- Request
- Response
POST /api/bids/:bidId/equipment/recalculate
Cookie: sAccessToken=...; sRefreshToken=...
{
"message": "Equipment distributions recalculated",
"totalEquipment": 3,
"totalScopes": 4
}
Roles: ADMIN, ESTIMATOR
Cost Calculations
Traditional Mode
// Base rental cost
baseRentalCost = quantity × durationValue × ratePerUnit
// Tax (if not tax exempt)
rentalTaxAmount = taxExempt ? 0 : baseRentalCost × rentalTaxRate
rentalCost = baseRentalCost + rentalTaxAmount
// Additional charges
fuelCharge = quantity × days × fuelChargePerDay
deliveryFee = onPrevious ? 0 : deliveryFee
trucksCost = truckCount × truckHaulCost
// Total
totalCost = rentalCost + fuelCharge + deliveryFee + trucksCost
Gantt Mode
// Base cost
rentalCost = dailyRate × durationDays
fuelCharge = calculateFuelCharge(equipment)
totalCost = rentalCost + fuelCharge + deliveryFee
// Distribute across scopes based on timeline overlap
for each scope {
overlapDays = calculateOverlap(equipment.startDay, equipment.durationDays, scope.timeline)
percentage = overlapDays / totalOverlapDays
allocatedCost = totalCost × percentage
allocatedFuel = fuelCharge × percentage
allocatedDelivery = deliveryFee × percentage
}
Fuel & Delivery Tracking (BM-88): As of February 2026, fuel charges and delivery fees are tracked separately in distributions for visibility in timeline tooltips and scope cost breakdowns.
Data Models
// Traditional Mode
interface EquipmentItem {
id: string
scopeId: string
equipmentType: string
subcategory: string
quantity: number
durationValue: number
durationUnit: string
baseRentalCost: number
rentalTaxAmount: number
rentalCost: number
fuelCharge: number
deliveryFee: number
trucksCost: number
totalCost: number
pricingItemId: string
}
// Gantt Mode
interface BidEquipment {
id: string
bidId: string
equipmentType: string
description: string
pricingItemId: string
quantity: number
startDay: number
durationDays: number
dailyRate: number
deliveryFee: number
totalCost: number
distributions: EquipmentDistribution[]
}
interface EquipmentDistribution {
scopeId: string
scopeName: string
overlapDays: number
percentage: number
allocatedCost: number
fuelCharge: number // Proportional fuel charge for this scope
deliveryFee: number // Proportional delivery fee for this scope
}