Job Costing in Field Service: Time, Parts and Contract Type Without Custom Code
A technical guide for Dynamics 365 Field Service: cost and price on work order lines, three contract types, a rollup that does not break the platform, a reconciliation finance can use now and controls on closing jobs.
Job cost in Dynamics 365 Field Service belongs on the work order product and work order service lines, each carrying a unit cost and a unit price, rolled up to the work order. It does not belong in a formula field bolted onto the work order header: a calculated column cannot aggregate child rows, and custom writes into totals Field Service calculates itself usually broke earlier attempts. Configure three contract types through agreements, price lists and quantity to bill: fixed price, time and materials, and warranty at no charge. Sum the lines with a rollup column or a recalculating flow, reconcile past jobs in a spreadsheet for finance, and stop jobs with uncosted lines from being closed.
Where should job cost live in Dynamics 365 Field Service?
On the lines, not on the header. A work order is the job, and what the job consumed is recorded as child rows: work order products for parts and materials, work order services for labour and billable service time. Each line carries a quantity, a unit cost and a unit price, with estimate and actual versions, and Field Service already uses those lines to calculate the work order sales totals and to drive inventory and invoicing. Job cost is simply the sum of what those lines cost, and margin is the difference from what they are priced at.
The attempts that break things usually start from the header. Someone adds a calculated column to the work order and discovers it cannot see the lines. Then form JavaScript or a workflow writes a cost total onto the header on every save, colliding with the Field Service logic that recalculates totals, locking records while technicians sync, or double counting when a line is edited twice. Some teams write directly into the total amount column that Field Service owns and find their value overwritten. Keep the source of truth on the lines, roll it up into columns you own, and the platform logic stays untouched.
Which fields on work order products and services carry cost and price?
The logical names below are the ones we usually meet, with estimate and actual pairs on both tables. They vary between Field Service versions, and new columns appear over time, so confirm them in your environment and current Microsoft documentation before building anything on them. Notice that the header totals Field Service maintains are sales-side totals; whether a cost total exists on the work order in your version is exactly the thing to check, because it decides whether you need your own rollup.
| Record | Columns usually seen (hedged) | What they mean for costing |
|---|---|---|
| Work order product (msdyn_workorderproduct) | Line status Estimated or Used (msdyn_linestatus), estimate quantity and quantity, quantity to bill (msdyn_qtytobill), estimate unit cost and unit cost (msdyn_unitcost), total cost (msdyn_totalcost), unit amount and total amount (msdyn_totalamount), price list, booking | Only Used lines are actual consumption. Quantity to bill can differ from quantity used, which is how warranty parts keep their cost but bill nothing. |
| Work order service (msdyn_workorderservice) | Line status, estimate duration and duration, duration to bill, unit cost, total cost, unit amount, total amount, minimum charge columns, booking | Labour cost is duration multiplied by a cost rate; price is duration to bill multiplied by the price list rate, subject to minimum charge and rounding rules. |
| Work order (msdyn_workorder) header | Price list, agreement, subtotal and estimate subtotal amounts, total sales tax (msdyn_totalsalestax), total amount (msdyn_totalamount), system status | Sales totals maintained by Field Service. Read them, do not write into them. Add your own cost and margin columns alongside. |
| Bookable resource and booking journals | Hourly rate on the resource, journal durations and cost where your version records them | The source of labour cost per hour and of actual time worked; the same journals feed utilisation reporting. |
| Price list, price list items and Field Service price list item settings | Price per unit, currency, rounding and minimum charge settings for services | Where the price side comes from, per customer, agreement or contract type. |
Where do the cost and price on each line come from?
A line is only as good as the defaults it inherits, and most uncosted jobs are uncosted because the default was empty. Fix the sources once and every new line arrives with real values. Estimated lines added from incident types, and the difference between Estimated and Used as evidence of what was fitted, are covered in our Field Service proof of work guide.
- Parts cost: the product record carries cost columns, and the work order product unit cost defaults from the product cost your version uses. Decide who maintains product costs and how often, because a cost that was right last year makes every margin wrong this year.
- Labour cost: the bookable resource carries an hourly rate, which is where labour cost per hour comes from for booking journals and service lines in most configurations. Leave it empty and every hour costs nothing.
- Price: the work order price list, inherited from the billing account, the service account or the agreement, supplies unit prices. Field Service price list item settings add rounding and minimum charge rules for services.
- Currency: price lists carry a currency and currency columns on lines convert through the Dataverse exchange rate, so decide which currency finance wants margin reported in before you build the rollup.
- Manual overrides: allow unit price overrides only for a dispatcher or finance role, and record the reason, so a margin can be explained when finance asks about it.
How do you configure fixed price, time and materials and warranty jobs?
Most service organisations run the same three contract types, and each one needs the cost recorded exactly the same way. What changes is the price side and what gets billed. That separation is the whole design: cost is always the truth of what the job consumed, price depends on the contract, and margin compares the two. Agreement features, entitlements and invoice setups change between releases, so confirm the options available in your version.
| Fixed price agreement | Time and materials | Warranty or no charge | |
|---|---|---|---|
| How the work arrives | Work orders generated from agreement booking setups, or raised manually against the agreement | Reactive work orders on the customer account | Work orders on a customer asset under warranty, or a goodwill or recall job |
| Cost recording | Every part and hour recorded as Used lines with unit cost, as for any job | Same | Same, so the cost of warranty work is visible and can be claimed from a manufacturer where that applies |
| Price and billing | The agreement invoice setup bills the fixed amount on its schedule. Lines on generated work orders use an agreement price list or entitlement that brings billable amounts to zero, or quantity to bill set to zero, so nothing is billed twice | Standard or customer price list; quantity to bill and duration to bill follow what was used, with minimum charges and rounding from the price list item settings | Quantity to bill and duration to bill set to zero, or a zero price list for the warranty work type, while quantity used and cost stay intact |
| What margin means | Agreement revenue for the period against the summed cost of all its work orders | Line price against line cost per job | Pure cost, reported as warranty or goodwill cost rather than as a loss-making job |
| Where it goes wrong | Generated work orders using the default price list, so fixed price customers receive time and materials invoices | Empty hourly rates or product costs, so jobs look fully profitable | Lines deleted instead of set to zero to bill, so the cost disappears with the charge |
How do you roll line costs up to the work order without breaking anything?
There are three candidate mechanisms, and only two of them can sum child rows. Pick by how fresh the figure must be and by who will maintain it. Whichever you choose, write the result into columns you created, filter to Used lines, and treat a deleted line as a change that must reduce the total.
| Mechanism | Can it sum work order lines? | Strengths | Limits to check |
|---|---|---|---|
| Rollup column on the work order | Yes: SUM, COUNT, MIN or MAX over related lines, with filters such as line status equals Used | No code and no flow, recalculated by the platform, can be recalculated on demand on the form, and a filtered COUNT gives the uncosted line count for controls | Calculated asynchronously by a recurring system job, so the value lags; a limit on rollup columns per table; filters only on the related rows. Check current Microsoft documentation for the exact schedule and limits. |
| Power Automate flow on line create, update and delete | Yes, by listing all Used lines for the work order and summing them | Near real time, can calculate margin and currency conversion, and can write several columns in one update | Recalculate the full sum every time rather than adding the changed amount, turn on trigger conditions so it fires only on cost, quantity and status columns, and allow for flow runs and API limits at volume. |
| Calculated or formula column on the work order | No. It can read columns on the work order and on parent records through lookups, not child rows | Good for margin once the totals exist: total price minus total cost, or margin percentage | Cannot aggregate lines at all, which is why header formulas are where earlier attempts stall. |
What do you do when a calculated field cannot reach the related records?
Stop trying to make it reach them. A calculated or formula column looks upward through lookups, from a line to its work order or from a work order to its account, never downward to many child rows. Build in two layers instead. The first layer gets a sum onto the work order through a rollup column or a flow. The second layer is a calculated column that works only with columns on the work order itself: margin as total price minus your rolled-up total cost, and margin percentage from those two.
The same rule works in the other direction. If a line needs something from its parent, such as the agreement type to decide whether it bills, a calculated column on the line can read it through the work order lookup. And if the requirement genuinely needs synchronous, transactional totals that are never stale even for a moment, that is the point where a small server-side plug-in earns its place. Most costing requirements do not need it: finance needs correct numbers at close of day, not at the moment a technician taps Save.
How do you reconcile past jobs in a spreadsheet for finance this week?
Finance usually needs an answer about past jobs before any configuration can be deployed, so give them one from the data that already exists, and label it honestly. This is not a rebuild of history, it is a view of what was recorded and a list of what was not. Solzet integrates Field Service with your existing ERP or finance system but does not implement Dynamics 365 Finance, Business Central or other ERP systems, so the invoice side of the comparison comes from whatever finance already runs.
- Agree the period and scope with finance: completed and posted work orders, by completion date, for the months in question.
- Pull the lines with Export to Excel from a view, or with Power Query from Dataverse where the volume is large: work order number, system status, agreement, incident type, completion date, line type, line status, quantity, quantity to bill, unit cost, total cost, unit price and total amount.
- Pivot by work order: total cost, total price and margin, then split by contract type so fixed price, time and materials and warranty jobs are read on their own terms.
- Add exception columns: Used lines with no unit cost, lines with no price on time and materials jobs, completed or posted jobs that still have Estimated lines, and jobs with booking time but no service lines.
- Compare the job price totals with what was actually invoiced for the same period in the finance system, and list the differences by cause rather than as one number.
- Mark any job where a cost has been estimated after the fact as estimated in the spreadsheet, so finance can see which margins are measured and which are not.
What controls stop uncosted jobs from being closed?
A reconciliation fixes the past; controls protect the future. The aim is that a job cannot reach Completed, and certainly not Posted, while any Used line has no cost, and that anything that slips past the control is visible the next morning. These are configuration, apart from the optional plug-in.
- Count uncosted lines: a rollup COUNT of Used lines where unit cost has no value, or the same count written by the costing flow.
- Block completion on the form and in the mobile app with a business rule or form logic that shows an error when the system status moves to Completed and the uncosted count is above zero. Remember that a rollup can lag, so recalculate it on the form before the check.
- Restrict Posted: only a finance or operations role can move a work order to Posted, and posting is the step that should confirm cost, price and quantity to bill.
- Default the sources: a product cannot be made available to technicians without a cost, and a resource cannot be activated without an hourly rate.
- Run a daily exception view or Power Automate alert listing completed work orders with uncosted lines, Estimated lines left in place, or a margin outside the range finance expects.
- Where the rule must be enforced on the server for every channel, including imports and integrations, add a small plug-in on the status change. It is the one place a few lines of code are worth it.
Should job costing run in Field Service, Project Operations or a system you own?
We recommend the right solution - whether that's Microsoft Dynamics 365, Power Platform, or a custom-built CRM. Some businesses need the Microsoft ecosystem. Others need full control without licensing. We deliver both. For reactive and planned service work, costing on Field Service work order lines is the right amount of software. If jobs have budgets, staged billing and cost rates per role that finance wants while the job is running, that is the boundary where Field Service work orders and Project Operations part ways. And where per-user licensing does not fit a large or subcontracted field workforce, a custom-built CRM and job management system on React, Node.js, PostgreSQL or .NET can hold the same line-level cost model under your full control.
Should job costing run on Dynamics 365, Power Platform or a custom-built system?
Can afford licensing and want the Microsoft ecosystem
Dynamics 365
Microsoft 365, Teams and Outlook integration, a mature partner ecosystem, Copilot, and apps for sales, service and field operations that are configured rather than built.
Need full control and zero licensing
Custom CRM
A CRM built on React, Node.js, PostgreSQL or .NET that you own outright: your data model, your hosting, no per-user subscription, and features shaped exactly to your process.
Not sure which fits
We help you decide
A short discovery weighs licensing budget, process complexity, integrations and long-term ownership, then recommends one path. We deliver both, so the recommendation has no reason to lean.
What does a Field Service costing engagement with Solzet involve?
Solzet has 8+ years of Dynamics 365 Customer Engagement and Power Platform delivery. Senior consultants and full-stack developers start with the spreadsheet reconciliation so finance has an answer, then fix cost and price sources, configure the contract types, build the rollup or flow and the completion controls, and repeat the reconciliation after the first month. The wider Field Service build, when costing is one symptom of a bigger gap, is on our Field Service implementation partner page. We work remotely from Yerevan and directly or white-label for Microsoft partners, and for organisations in Armenia we run workshops and training in Armenian or Russian, as described on our CRM in Armenia page. Labour hours used for costing come from the same bookings as utilisation reporting. The order we configure it in is below.
- 1. Reconcile past jobs before changing anything. Export completed work orders with their Used product and service lines to a spreadsheet, total cost and price per job, and give finance the list of jobs with missing costs, missing prices or lines still Estimated. It answers the immediate question and shows which data problems the configuration must prevent.
- 2. Fix the sources of cost and price. Maintain a cost on every product that technicians use, an hourly rate on every bookable resource, and price lists with Field Service price list item settings for services, so new lines default to real values instead of zero.
- 3. Configure the three contract types. Fixed price work through an agreement with its own price list and invoice setup, time and materials through the standard price list, warranty and no charge work through quantity to bill and duration to bill set to zero, with cost still recorded.
- 4. Add cost and margin columns you own on the work order. Create your own total cost and margin columns on the work order, separate from the sales totals Field Service maintains, and never write into the Field Service managed total columns.
- 5. Roll the lines up with a rollup column or a recalculating flow. Use rollup columns filtered to Used lines where near real time is not required, or a Power Automate flow that recalculates the full sum from all lines whenever a line changes, rather than adding and subtracting increments.
- 6. Put controls on completion and posting. Count uncosted Used lines on the work order, stop completion on the form and in the mobile app when the count is above zero, restrict the Posted status to a finance role, and run a daily exception view for anything that slipped through.
- 7. Reconcile again after one month. Repeat the spreadsheet reconciliation for the first full month on the new configuration and compare it with what finance invoiced, fixing any rule or data source that still produces a difference.
What do people ask us?
How do you calculate job cost in Dynamics 365 Field Service?
Sum the total cost of the Used work order product lines for parts and the Used work order service lines for labour on each work order. Each line carries a unit cost from the product cost or the resource hourly rate, and a unit price from the price list. Roll the sum into your own total cost column on the work order with a rollup column or a Power Automate flow, then calculate margin against the price totals.
Why can a calculated column on the work order not total the work order products?
Calculated and formula columns in Dataverse read columns on the same row and on parent rows through lookups. They cannot aggregate many child rows, so a work order calculated column cannot see its product and service lines. Use a rollup column, which can sum related rows with filters, or a flow that recalculates the sum, and then a calculated column for margin from the rolled-up totals.
Should we use rollup columns or Power Automate to total work order costs?
Rollup columns need no code or flow and are the simpler choice when a value that lags by a while is acceptable, since they are recalculated asynchronously on a schedule and on demand. A flow gives near real time totals and can calculate several columns together, but must recalculate the full sum on every change and be tuned for volume. Check current Microsoft documentation for rollup schedules and limits.
How do we stop fixed price agreement customers being billed for parts and labour?
Bill the fixed amount through the agreement invoice setup, and make sure the work orders generated from the agreement use an agreement price list, an entitlement or quantity to bill set to zero so their lines carry cost but no billable amount. The usual fault is generated work orders falling back to the default price list, which produces time and materials invoices for customers on a fixed price.
How should warranty work be costed in Field Service?
Record every part and hour as Used lines with their real cost, exactly as for billable work, and set quantity to bill and duration to bill to zero or use a zero price list for warranty work. Do not delete the lines, because the cost disappears with the charge. Warranty cost then reports as its own figure and can support a claim to a manufacturer where that applies.
How do we stop technicians closing jobs with no cost recorded?
Count Used lines with no unit cost on the work order, block the move to Completed on the form and mobile app when that count is above zero, restrict the Posted status to a finance role, and run a daily exception view for anything that slipped through. Fix the sources too: products need a cost and resources need an hourly rate. Where enforcement must cover imports and integrations, add a small server-side plug-in.
Can Solzet configure Field Service job costing for a company in Armenia?
Yes. Solzet is based in Yerevan and configures Dynamics 365 Field Service costing for organisations in Armenia and internationally, with workshops and training in Armenian, Russian or English. We integrate with the finance or accounting system you already run, but we do not implement Dynamics 365 Finance, Business Central or other ERP systems.
Where should you go next?
Dynamics 365 Field Service implementation partner
The Field Service build: work orders, incident types, agreements, assets, mobile and offline design.
CRM in Armenia
Dynamics 365 and custom CRM for Armenian organisations, with delivery in Armenian and Russian.
Field Service proof of work
Estimated and Used work order products, parts linked to bookings and evidence that survives audit.
Field Service dispatch and multi-day jobs
When a job stays a work order and when it needs Project Operations budgets and cost rates.
Utilisation and first-time fix reporting
Defining the measures and using bookings and journals as the source of labour hours.
Custom CRM Development
Job management and costing on React, Node.js, PostgreSQL and .NET without Microsoft licensing.
Which solution is right for your business?
Tell us what you need. A senior consultant replies within one business day with a recommendation - Dynamics 365, Power Platform, or a custom-built CRM - not a sales script.