Skip to main content

Download PDF

Download a PDF
Platform: Odidor (Confirmed)

Ashtech Stoneworks – Odidor ERP Implementation

Live implementation tracker and specification for the Estimation Module and subsequent phases

Odidor has been selected as the ERP platform for Ashtech Stoneworks. This page serves as the main communication interface between Ashtech, Odidor, and Xappert (implementation partner).

Implementation Partner:Xappert Incorporated
Platform:Odidor ERP
Target Go-Live:Early February 2026

For Ashtech

Overview

Client-friendly summary of the Odidor ERP implementation

Problem

Ashtech Stoneworks currently relies on complex, manually-maintained Excel files to estimate multi-unit stone fabrication and installation projects.

This creates several challenges:

  • Time-consuming to update for each new project.
  • High risk of formula errors or broken links.
  • Difficult for new staff to learn.
  • No direct integration with CRM, Procurement, or Project delivery.

Solution

The Odidor Estimation Module transforms this manual process into a structured, ERP-native workflow.

Key Capabilities

  • Centralized project setup (unit mix + amenities).
  • Smart catalog of materials, labour rates, edges, and sinks.
  • Automated SQFT, wastage, and cost calculations.
  • Reusable templates for standard kitchen and vanity packages.
  • Approval workflow and professional, branded client quotes.
  • Integration with CRM (Opportunities & Quotes) and future modules.

Benefits for Ashtech

Faster Estimates

  • From hours of spreadsheet work → minutes in Odidor.
  • Templates let estimators reuse common configurations across projects.

Fewer Errors

  • Formulas live in a controlled calculation engine, not scattered across cells.
  • Role-based approvals ensure review before quotes go out.

Better Visibility

  • Clear breakdown of:
    • Material cost.
    • Labour cost.
    • Edges, sinks, and extras.
  • Consistent pricing standards across all projects.

Integration-Ready

  • Estimates will feed:
    • Future procurement planning (slabs, sinks, accessories).
    • Future production and job scheduling.

How It Fits in the Overall ERP

The Estimation Module is the front door of the operational workflow:

Detailed Implementation Plan (Phase 1 & 2)

  • Ashtech Stoneworks – ERP Implementation Tracker (Phase 1 & 2 Focus)

Project Window: 18 Nov 2025 → 12 Jan 2026

Platforms: Odidor ERP (recommended)

Overall Goal: CRM + Estimation + Procurement + Inventory fully functional by Jan 12

PHASE 1 — CRM + Sales + Estimation

Timeline: Nov 18 → Dec 22 (5 weeks)

Goal: Fully functional CRM pipeline, quotation flow, estimation workflow, material + labour logic

Week 1 (Nov 18–24) – Project Kickoff & Business Requirements

Deliverables:

  • Kickoff meeting + scope confirmation

Finalize detailed workflows for:

  • Lead → Opportunity → Quotation

  • Estimation inputs (material, labour, wastage, markup, commission)

  • Map Ashtech’s existing Excel (estimation) → Odidor fields

Data structures:

  • Customer master fields

  • Product categories (Slabs, Quartz, Granite, Services)

  • Installation service line items

  • Prepare import templates for CRM + Products

Technical setup:

  • Odidor environment provisioning

  • User roles / permissions defined

  • Access provisioning

Week 2 (Nov 25–Dec 1) – CRM Pipeline Build

Deliverables:

Configure CRM stages:

  • New Lead → Qualified → On-Site → Estimation → Review → Won/Lost

  • Lead capture forms + assignment rules

  • Customer master creation (fields, tags, segmentation)

  • Setup communication logs & meeting notes

Import:

  • Sample customers

  • Sample leads

  • Demo + Adjustments round 1

Week 3 (Dec 2–Dec 8) – Quotation + Estimation Engine (Core)

Deliverables:

Build quotation template:

  • Header + job site details

  • Material selection

  • Edge types, sink cutouts, extras

  • Fabrication labour

  • Installation labour

Configure estimation logic:

  • Slab cost per sqft

  • Wastage factor rule

  • Fabrication labour multiplier

  • Installation labour tiers

  • Optional add-ons logic

  • Tax rules (GST/PST)

  • Price list setup + overrides

Week 4 (Dec 9–Dec 15) – Approval Workflow + Document Templates

Deliverables:

Set up approval flow:

  • Estimator → Manager → Final Quote

Build document templates:

  • Quotation PDF

  • Work Order (Export for Factory)

  • Customer Approval document

  • Add automated email dispatch

  • Add notifications & reminders

  • Demo + Adjustments round 2

Week 5 (Dec 16–Dec 22) – Phase 1 UAT + Go-Live

Deliverables:

  • Full UAT with Ashtech

  • Fixes + polish

  • Staff training (CRM + Estimation)

Create:

  • Quick reference guide

  • Training videos (short clips optional)

  • Phase 1 Go-Live → Dec 22

PHASE 2 — Procurement + Inventory

Timeline: Dec 23 → Jan 12 (3 weeks)

Goal: Purchase orders, supplier workflows, slab & stock tracking, factory receiving, job-site allocation

Week 6 (Dec 23–Dec 29) – Procurement Framework

Deliverables:

  • Vendor master creation

Purchase workflow:

  • Requisition → PO → Receipt → Bill

Configure cost centres for:

  • Factory

  • Job sites

Setup product variants:

  • 2cm / 3cm slabs

  • Colours

  • Finishes

  • Link estimation → procurement items

Week 7 (Dec 30–Jan 5) – Inventory + Factory Logistics

Deliverables:

  • Warehouse/factory location setup

Map physical movements:

  • Supplier → Factory

  • Factory → Job site

Slab tracking model:

  • Batch/Lot

  • Dimensions

  • Remnant logic (optional)

  • Create receiving workflow

  • Create stock availability reports

  • Alerts for low stock / reserved slabs

Week 8 (Jan 6–Jan 12) – Phase 2 UAT + Go-Live

Deliverables:

  • Procurement + Inventory UAT

  • Fixes + improvements

  • Staff training

  • Factory team workflow onboarding

  • Phase 2 Go-Live → Jan 12

For Odidor Engineering

Architecture

System architecture and data flow diagrams

Context & Goals

Ashtech Stoneworks currently uses complex Excel workbooks to estimate multi-unit stone projects.
The Odidor Estimation Module replaces this with a structured ERP-native engine.

Goals:

  • Consistent calculations
  • Versioning + approvals
  • Project/unit/amenity configuration
  • CRM integration
  • Future feed into Procurement & Projects

High-Level Architecture


Core Backend Services

Project Service

  • CRUD projects
  • Manage unit types + amenities

Estimation Service

  • Manage estimate headers & versions
  • Handle status transitions
  • Coordinate calculation + CRM sync

Estimation Line Service

  • CRUD estimate lines
  • Supports unit-based + amenity-based logic

Calculation Engine

  • Stateless computation engine
  • Applies core formulas for SQFT, wastage, material, labour, edges, sinks
  • Writes totals back to DB

PDF Service

  • Generates branded client quote
  • Based on HTML template

CRM Integration Service

  • Updates opportunity status:
    • Approved → Quoted
    • Accepted → Won

Data Layer

Main tables:

  • projects
  • unit_types
  • amenities
  • materials
  • labour_rates
  • edge_profiles
  • sink_types
  • estimates
  • estimate_lines

Estimate lines store snapshots of pricing + wastage.


Data Flow & Sequence


Integration Points

CRM

  • Estimate status drives Opportunity stage.

Procurement (Future)

  • Aggregate required slab SQFT & sink/accessory counts.

Projects & Field Service (Future)

  • Accepted estimates become:
    • Job records
    • Baseline budgets

Design Considerations

  • Calculation engine must be idempotent and consistent.
  • Store rate snapshots on each line.
  • Handle large projects (100+ unit types, 500+ lines).
  • Clear audit logs for approvals and rate overrides.

Project Timeline

Timeline & Project Tracker

Phase 1 (CRM + Estimation) and Phase 2 (Procurement + Inventory) delivery schedule

Note: This timeline tracks Phase 1 (CRM + Estimation) and Phase 2 (Procurement + Inventory), aligned to Ashtech's required dates (Phase 1 ~ Dec 22, Phase 2 ~ Jan 12).

WeekDatesMilestone
1Nov 18 – Nov 24Project & requirements finalization
2Nov 25 – Dec 1Data model & master data configuration
3Dec 2 – Dec 8Estimation engine backend + basic UI
4Dec 9 – Dec 15Templates, unit/amenity logic, and calculations
5Dec 16 – Dec 22Approvals, PDF quotes, internal testing
6Dec 23 – Dec 29UAT prep + Veritas-style project replication
7Dec 30 – Jan 5UAT with Ashtech, fixes, refinements
8Jan 6 – Jan 12Training, documentation, sign-off

Detailed Breakdown

For Ashtech & Odidor

Requirements

Functional, non-functional, and validation requirements for Phase 1

Goals

The Estimation Builder UI should enable estimators to:

  • Configure projects (unit mix + amenities).
  • Build and edit estimation lines quickly.
  • See totals update in real time.
  • Move estimates through approvals confidently.

Screen Overview

2.1 Project Detail Screen

Tabs:

Layout & Sections

Content loading...

For Odidor Engineering

Technical Details

Database schema, APIs, and calculation engine specifications

Overview

The Estimation Module is a subdomain with the following main aggregates:

  • Project
  • UnitType
  • Amenity
  • Estimate
  • EstimateLine
  • Reference data: Material, LabourRate, EdgeProfile, SinkType, WastageRule.

All endpoints should be namespaced, e.g., /api/estimation/... or /api/projects/... per Odidor conventions.


Data Model

2.1 Project

| Field | Type | Notes | |----------------|----------|-------------------------------------| | id | UUID | Primary key | | name | string | Project name | | client_id | UUID | FK to Customer | | address | string | Optional | | estimator_id | UUID | FK to User | | status | enum | draft, active, completed, archived | | crm_opportunity_id | UUID | Optional link | | created_at | datetime | | | updated_at | datetime | |

2.2 UnitType

| Field | Type | Notes | |--------------|--------|--------------------------------| | id | UUID | PK | | project_id | UUID | FK → Project | | label | string | e.g., "A1" | | description | string | Optional | | count | int | Number of such units | | avg_area_sqft| float | Optional, informational only |

2.3 Amenity

| Field | Type | Notes | |--------------------|--------|-----------------------| | id | UUID | PK | | project_id | UUID | FK → Project | | name | string | e.g., "Lobby" | | area_sqft | float | Required | | material_profile_id| UUID | Optional FK |

2.4 Material

| Field | Type | Notes | |---------------|--------|------------------------------| | id | UUID | PK | | name | string | | | category | string | quartz, granite, porcelain… | | thickness_mm | float | | | rate_sqft | float | Default price per sqft | | wastage_pct | float | Default | | uom | enum | sqft, lf, ea | | active | bool | |

2.5 LabourRate

| Field | Type | Notes | |---------|--------|----------------------------| | id | UUID | PK | | name | string | | | rate | float | | | uom | enum | sqft, lf, ea, day | | category| string | install, fabrication, etc. | | active | bool | |

2.6 Estimate

| Field | Type | Notes | |--------------------|----------|----------------------------------------| | id | UUID | PK | | project_id | UUID | FK → Project | | version_no | int | Starts at 1 | | status | enum | draft, in_review, approved, sent, accepted, rejected, cancelled | | valid_until | date | Optional | | discount_pct | float | Optional | | total_material_cost| float | Calculated | | total_labour_cost | float | Calculated | | total_extra_cost | float | Calculated (edges + sinks + extras) | | total_before_tax | float | Calculated | | tax_amount | float | Calculated | | grand_total | float | Calculated | | created_by | UUID | FK → User | | approved_by | UUID | FK → User, nullable | | created_at | datetime | | | updated_at | datetime | |

2.7 EstimateLine

| Field | Type | Notes | |-----------------|----------|--------------------------------------------| | id | UUID | PK | | estimate_id | UUID | FK → Estimate | | line_type | string | kitchen, island, vanity, amenity, edge… | | category | string | kitchen, vanity, amenity, other | | unit_type_id | UUID | FK → UnitType, nullable | | amenity_id | UUID | FK → Amenity, nullable | | description | string | | | quantity_units | float | e.g., number of units | | length | float | | | width | float | | | area_sqft | float | stored or recalculated | | wastage_pct | float | per-line override | | material_id | UUID | FK → Material | | material_rate | float | snapshot of rate | | labour_rate_id | UUID | FK → LabourRate | | labour_rate | float | snapshot | | edge_profile_id | UUID | FK → EdgeProfile, nullable | | edge_lf | float | linear feet | | edge_rate | float | snapshot | | sink_type_id | UUID | FK → SinkType, nullable | | sink_count | float | | | sink_rate_total | float | snapshot combined rate per sink | | extra_cost | float | manual extras | | material_cost | float | calculated | | labour_cost | float | calculated | | edge_cost | float | calculated | | sink_cost | float | calculated | | line_total | float | calculated | | source | string | manual/template/imported |


API Design

Suggest RESTish JSON APIs. Examples:

3.1 Project APIs

  • POST /api/projects
  • GET /api/projects/:id
  • PATCH /api/projects/:id

3.2 Unit Types / Amenities

  • POST /api/projects/:projectId/unit-types
  • PATCH /api/unit-types/:id
  • POST /api/projects/:projectId/amenities

3.3 Estimate APIs

  • POST /api/projects/:projectId/estimates
  • GET /api/estimates/:id
  • POST /api/estimates/:id/version – clone estimate and increment version_no
  • PATCH /api/estimates/:id/status

3.4 Estimate Lines APIs

  • POST /api/estimates/:estimateId/lines
  • PATCH /api/estimate-lines/:id
  • DELETE /api/estimate-lines/:id

3.5 Calculation API

  • POST /api/estimates/:id/recalculate
    • Triggers full recompute of all lines and header totals.

Calculation Engine

Pseudo-logic:

function recalculateEstimate(estimateId: string) {
  const estimate = loadEstimate(estimateId);
  const lines = loadEstimateLines(estimateId);

  let totalMaterial = 0;
  let totalLabour = 0;
  let totalEdge = 0;
  let totalSink = 0;
  let totalExtra = 0;

  for (const line of lines) {
    const quantity = line.quantity_units ?? 1;

    const areaSqft = line.length * line.width;
    const netSqft = areaSqft * quantity;
    const wastageSqft = netSqft * (line.wastage_pct / 100);
    const totalSqft = netSqft + wastageSqft;

    const materialCost = totalSqft * line.material_rate;
    const labourCost = totalSqft * line.labour_rate;

    const edgeCost = (line.edge_lf ?? 0) * (line.edge_rate ?? 0);
    const sinkCost = (line.sink_count ?? 0) * (line.sink_rate_total ?? 0);
    const extraCost = line.extra_cost ?? 0;

    const lineTotal = materialCost + labourCost + edgeCost + sinkCost + extraCost;

    // accumulate
    totalMaterial += materialCost;
    totalLabour += labourCost;
    totalEdge += edgeCost;
    totalSink += sinkCost;
    totalExtra += extraCost;

    // update line
    updateLine(line.id, {
      area_sqft: areaSqft,
      material_cost: materialCost,
      labour_cost: labourCost,
      edge_cost: edgeCost,
      sink_cost: sinkCost,
      line_total: lineTotal,
    });
  }

  const totalBeforeTax = totalMaterial + totalLabour + totalEdge + totalSink + totalExtra;
  const taxAmount = computeTax(totalBeforeTax, estimate);
  const grandTotal = totalBeforeTax + taxAmount;

  updateEstimate(estimateId, {
    total_material_cost: totalMaterial,
    total_labour_cost: totalLabour,
    total_extra_cost: totalEdge + totalSink + totalExtra,
    total_before_tax: totalBeforeTax,
    tax_amount: taxAmount,
    grand_total: grandTotal,
  });
}

Status & Workflow Logic

State machine:

draft → in_review → approved → sent → accepted/rejected

in_review → draft (rejected back)

On approved:

Lock estimate lines from editing.

Snap totals for reference.

On accepted:

Trigger integration event:

estimate.accepted → used by CRM and, in future, Projects/Procurement.

PDF & Templates

Templating engine: HTML-based (Handlebars, etc.).

Data needed:

Project header.

Estimate header.

Grouped lines by category.

Single endpoint:

GET /api/estimates/:id/pdf

Validation & Error Handling

Business rules enforced at API layer:

No transition to in_review if:

No lines present.

Required fields missing.

No negative numeric values.

Unit-based lines must have unit_type_id.

Amenity-based lines must have amenity_id.

Return structured errors:

code, message, field (if applicable).

Payment & Engagement

Ready to Proceed?

Once you've reviewed the proposal, choose a phase and purchase implementation hours via Stripe. You can start with Phase 1 and add more hours as we go.

Once you've reviewed the proposal, choose a phase and purchase implementation hours via Stripe.

You can start with Phase 1 and add more hours as we go.