Estimator Electrical Module
The CrestApps.OrchardCore.Estimator.Electrical module is the electrical package. It adds feeders to estimate revisions, which make their conduit, fittings, supports, conductors, ground, lugs and pull boxes as estimate lines, two electrical checks, and a recipe with the data an electrical contractor starts from.
| Feature ID | Name | Category | Dependencies |
|---|---|---|---|
CrestApps.OrchardCore.Estimator.Electrical | Estimator Electrical | Estimator | CrestApps.OrchardCore.Estimator.Catalog, CrestApps.OrchardCore.Estimator.Estimates, CrestApps.OrchardCore.Estimator.Proposals |
The Estimator setup recipe enables the feature. The data comes from the Estimator electrical package recipe (EstimatorElectricalPackage), which a site runs when it wants it. The design is recorded in docs/engineering/adr/0013-electrical-package.md in the repository.
Feeders follow the access to their project, as estimates do: CanViewAsync to see them, CanManageAsync to add, change and delete them. The module adds no permission.
Data model
| Type | What it holds |
|---|---|
ElectricalFeeder | A feeder of a revision: RevisionId, EstimateId, ProjectId, Name, From, To, Sets, Conductors (per set), Size, Material (Copper, Aluminum), GroundSize, ConduitType (Emt, Pvc, Rmc), ConduitSize (null for the smallest the fill allows), Length, MakeupFeet (3), OffsetPercent (10), ElbowsPer100Feet (2), PullBoxInterval (0 for none), Terminate (true), NodeId, and the LineIds it made |
FeederBuild | What the builder makes of a feeder: the Components (FeederComponent: Code, Quantity), the ConduitSize used, the SuggestedConduitSize, FillPercent, FillLimitPercent and IsOverfilled |
Feeders are in the Estimator collection with ElectricalFeederIndex (ItemId, RevisionId, EstimateId, Name), created by ElectricalMigrations.
The feeder builder
FeederBuilder.Build(feeder) is a pure function. For each set it makes:
| Component | Code | Quantity |
|---|---|---|
| Conduit | EL-{EMT,PVC,RMC}-{trade} | The length plus OffsetPercent, per set |
| Couplings | EL-{type}CPL-{trade} | One per 10 ft of conduit |
| Connectors | EL-{type}CON-{trade} | Two per set |
| Elbows | EL-{type}ELL-{trade} | ElbowsPer100Feet per 100 ft, rounded up |
| Straps | EL-STRAP-{trade} | One per 8 ft of conduit |
| Conductors | EL-W-{CU,AL}-{size} | (length + 2 × MakeupFeet) × conductors |
| Ground | EL-W-CU-{size} | (length + 2 × MakeupFeet), one per set |
| Lugs | EL-LUG-{size} | Two per conductor and two per ground, when Terminate |
| Pull boxes | EL-PB-{trade} | One per PullBoxInterval, rounded down |
Trade sizes are tokens: 050 for 1/2", 250 for 2-1/2", 400 for 4". Wire sizes keep their name with / as -: 4-0 for 4/0, 350 for 350 kcmil.
ElectricalTables holds the conductor areas (THHN/THWN-2, NEC Chapter 9 Table 5) for #14 to 750 kcmil and the internal areas of EMT, PVC Schedule 40 and RMC (Table 4) for 1/2" to 4". The fill limit is 53% for one conductor, 31% for two and 40% for more (Table 1). The builder picks the smallest trade size within the limit, keeps a size the feeder gives even when it is too full, and gives ConduitSize = null when no size holds the conductors. The fill is an estimating aid, not a code determination.
Services
| Service | Lifetime | What it does |
|---|---|---|
IElectricalFeederStore (ElectricalFeederStore) | Scoped | The feeders of a revision by name, or of every revision of an estimate |
FeederService | Scoped | Normalize, Validate (FeederProblem), SaveAsync(revision, feeder) (builds the feeder and replaces its lines with EstimateWorkspace.SaveLinesAsync, on the feeder's breakdown node, with the note Feeder F-1: MSB to LP-1), DeleteAsync (with its lines). Both refuse a locked revision |
ElectricalFeederHandlers | Scoped | An IEstimateRevisionEventHandler that copies the feeders of the parent revision to a new one (lines keep their identifiers in a copy, so the copies keep their lines), and an IEstimateEventHandler that deletes the feeders of a deleted estimate. It uses only the store, because EstimateWorkspace calls it |
FeederEstimateValidator | Scoped | The electrical checks (below) |
ElectricalIssueDescriber | Scoped | The text of the electrical checks, and the feeder editor as the page that fixes them (GetUrl) |
Checks
| Code | Severity | Rule |
|---|---|---|
ELEC-005 | Blocking | A feeder with no length or no terminations. Arguments: the name, and whether the length is missing |
ELEC-007 | Warning | The conduit is fuller than the limit, or no trade size holds the conductors. Arguments: the name, the fill, the limit, the size and the suggested size |
Issues have the Other target with the feeder as TargetId. ELEC-010 is the core rule EST-060. The other rules of the plan need schedule extraction, specifications or bid history; see the ADR.
Admin routes
| Route | Action |
|---|---|
Admin/estimator/feeders/Index/{estimateId} | The feeders of the current revision (AdminList, with a fill badge) |
Admin/estimator/feeders/Create/{estimateId} | Add a feeder |
Admin/estimator/feeders/Edit/{feederId} | The editor, with what the feeder makes; read-only on a locked revision |
Admin/estimator/feeders/Delete/{feederId} | Delete a feeder and its lines |
The Feeders button of the workspace comes from FeederEstimateDisplayDriver (EstimateDisplayTypes.WorkspaceActions).
The electrical package recipe
Recipes/estimator-electrical-package.recipe.json enables the feature and runs:
| Step | Content |
|---|---|
EstimatorCatalog | 263 items: conduit, couplings, connectors and elbows of the three raceways in ten trade sizes, straps and pull boxes, copper conductors #14 to 750 kcmil, aluminum from #6, lugs for every size, MC cable, boxes, devices, fixtures, panels, breakers, disconnects, fuses, transformers, grounding and supports. Labor categories: Rough-in, Wire pulling, Trim, Lighting, Gear |
EstimatorAssemblies | 304 assemblies: conduit runs per foot; branch circuits per foot in the smallest raceway the fill allows; feeders per foot by ampacity (30 A to 400 A, copper and aluminum, with or without a neutral, in each raceway); devices in MC cable or EMT; fixtures, also above 15 ft; panels with breakers; disconnects; transformers; pull boxes; penetrations; grounding; MC cable runs |
EstimatorLabor | Job condition factors (working height, ceiling type, phasing, after-hours work, material handling, more building types) and a feeder crew and a lighting crew |
EstimatorProposalClauses | 13 electrical inclusions, exclusions and clarifications |
EstimatorEstimateTemplates | The Electrical – Commercial template: recap settings, a breakdown and ten direct job expense and supervision lines |
The prices and labor units are fictional sample data. Every step replaces what it added before by its key (item number, assembly code, factor group and name, crew name, clause kind and text, template name), so the recipe can run again. ElectricalPackageRecipeTests checks that the catalog has every code the feeder builder makes, that the assemblies use known items and assemblies, and that the steps load without errors.
Extension points
- Add raceways or conductor insulations: extend
ConduitTypeandElectricalTables, and add the items of the new codes. - Use other item numbers: the builder's codes are fixed, so a site that keeps its own numbers adds catalog items with the
EL-numbers, or a later version maps them. - Another industry package follows the same pattern: a module with its records per revision, an
IEstimateRevisionEventHandlerand anIEstimateEventHandlerthat copy and delete them, validators and a describer, a workspace action, and a recipe.
Tests
tests/CrestApps.OrchardCore.Estimator.Tests/Electrical holds the tests of the builder and its tables, the service and the handlers (on real SQLite), the checks and their texts, and the package recipe.