Skip to main content

Overview

The Quotation model represents construction project quotations with a complex nested structure. It includes factory information, financial calculations, and a hierarchical organization of sections and items. This model is designed to handle detailed cost breakdowns for construction projects.

Schema Definition

The Quotation model uses Mongoose with pagination support through the mongoose-paginate-v2 plugin. It features nested subdocuments for sections and items.

Source Location

src/models/quotation.js

Top-Level Fields

factory
String
required
Name or identifier of the factory or manufacturing facility associated with the quotation.Constraints:
  • Required: Yes
fix
String
required
Fixed reference or identifier for the quotation.Constraints:
  • Required: Yes
description_quotation
String
required
Detailed description of the quotation, including project overview and scope.Constraints:
  • Required: Yes
subtotal
Number
required
Base cost before additional charges and taxes.Constraints:
  • Required: Yes
unexpected
Number
required
Contingency amount for unexpected costs or changes.Constraints:
  • Required: Yes
iva
Number
required
VAT (Value Added Tax) or IVA amount.Constraints:
  • Required: Yes
administratitive
Number
required
Administrative costs and overhead.Constraints:
  • Required: Yes
utility
Number
required
Profit margin or utility percentage.Constraints:
  • Required: Yes
total_price
Number
required
Final total price including all costs, fees, and taxes.Constraints:
  • Required: Yes

Nested Structure

Sections Array

sections
Array<Object>
Array of section objects representing different phases or areas of the construction project.

Plugins

mongoose-paginate-v2

The Quotation schema includes the mongoose-paginate-v2 plugin for efficient pagination of quotation queries. Enabled Methods:
  • Quotation.paginate(query, options) - Paginated query with customizable page size and sorting

Example Document

{
  "_id": "507f1f77bcf86cd799439011",
  "factory": "ABC Construction Factory",
  "fix": "QT-2024-001",
  "description_quotation": "Residential building renovation project",
  "subtotal": 50000,
  "unexpected": 5000,
  "iva": 9500,
  "administratitive": 3000,
  "utility": 7500,
  "total_price": 75000,
  "sections": [
    {
      "description_sections": "Foundation and Structural Work",
      "section_price": 25000,
      "items": [
        {
          "item_name": "Concrete Pouring",
          "item_description": "High-strength concrete for foundation",
          "item_total": 15000,
          "quantity": 50,
          "unity": "m3",
          "item_value": 300
        },
        {
          "item_name": "Steel Reinforcement",
          "item_description": "Rebar installation for structural support",
          "item_total": 10000,
          "quantity": 2000,
          "unity": "kg",
          "item_value": 5
        }
      ]
    },
    {
      "description_sections": "Electrical Installation",
      "section_price": 12000,
      "items": [
        {
          "item_name": "Wiring",
          "item_description": "Complete electrical wiring installation",
          "item_total": 8000,
          "quantity": 200,
          "unity": "m",
          "item_value": 40
        },
        {
          "item_name": "Circuit Breakers",
          "item_description": "Main and secondary circuit breakers",
          "item_total": 4000,
          "quantity": 10,
          "unity": "unit",
          "item_value": 400
        }
      ]
    }
  ],
  "__v": 0
}

Validation Rules

Hierarchical Structure

The Quotation model follows a three-level hierarchy:
Quotation
├── Top-level fields (factory, fix, prices, etc.)
└── sections[] (Array)
    ├── Section fields (description, price)
    └── items[] (Array)
        └── Item fields (name, description, quantity, unity, value, total)

Usage Examples

Creating a New Quotation

import Quotation from './models/quotation.js';

const newQuotation = await Quotation.create({
  factory: "XYZ Construction",
  fix: "QT-2024-042",
  description_quotation: "Office building renovation",
  subtotal: 100000,
  unexpected: 10000,
  iva: 19000,
  administratitive: 5000,
  utility: 15000,
  total_price: 149000,
  sections: [
    {
      description_sections: "Plumbing Work",
      section_price: 30000,
      items: [
        {
          item_name: "Pipe Installation",
          item_description: "PVC pipes for water supply",
          item_total: 20000,
          quantity: 100,
          unity: "m",
          item_value: 200
        }
      ]
    }
  ]
});

Querying with Pagination

const options = {
  page: 1,
  limit: 10,
  sort: { total_price: -1 }
};

const result = await Quotation.paginate(
  { factory: "ABC Construction Factory" },
  options
);

console.log(result.docs); // Array of quotation documents
console.log(result.totalDocs); // Total number of quotations

Accessing Nested Data

const quotation = await Quotation.findById(quotationId);

// Access sections
quotation.sections.forEach(section => {
  console.log(section.description_sections, section.section_price);
  
  // Access items within each section
  section.items.forEach(item => {
    console.log(item.item_name, item.quantity, item.unity);
  });
});

Calculation Notes

Price Calculations: The schema stores calculated values like item_total, section_price, and total_price. Ensure these are properly calculated before saving:
  • item_total = quantity × item_value
  • section_price = sum of all item_total in that section
  • total_price = subtotal + unexpected + iva + administratitive + utility
Consider adding pre-save hooks to automatically calculate these values.
Typo Notice: The field name administratitive appears to be a typo of “administrative”. This is preserved from the source schema but should be noted for potential future refactoring.
  • User: Quotations may be associated with users who created or are responsible for them

Best Practices

  1. Data Consistency: Always validate that calculated fields match the sum of their components
  2. Nested Updates: Use Mongoose subdocument methods when updating sections or items
  3. Indexing: Consider adding indexes on factory and fix fields for faster queries
  4. Validation: Implement custom validators to ensure at least one section exists in meaningful quotations

Build docs developers (and LLMs) love