# @acorex/modules/measurement-core


# 📘 Measurement Core Module (README)

The **Measurement Core** module provides the foundational measurement system used across the ACoreX Platform.  
It defines how units, conversions, and physical quantities are structured and processed.

The module includes five main entities:

1. **Unit of Measure (UoM)**
2. **UoM Type**
3. **UoM Group**
4. **UoM Conversion**
5. **Quantity Type**

---

# 🧩 1. Unit of Measure (UoM)

Represents a measurable unit such as *kilogram*, *meter*, *piece*, or *box*.

### Example

```json
{
  "id": "uom-kg",
  "code": "KG",
  "name": "Kilogram",
  "symbol": "kg",
  "uomTypeId": "type-mass",
  "system": "metric",
  "isActive": true
}
```

```json
{
  "id": "uom-box",
  "code": "BOX",
  "name": "Box",
  "symbol": "box",
  "uomTypeId": "type-count",
  "system": "custom",
  "isActive": true
}
```

---

# 🧩 2. UoM Type

Defines the **physical nature** of units:

- Mass  
- Length  
- Volume  
- Count  
- Time  
- Custom  

These values are mostly **system-defined and fixed**.

### Example

```json
{
  "id": "type-mass",
  "code": "MASS",
  "name": "Mass",
  "isSystem": true
}
```

```json
{
  "id": "type-count",
  "code": "COUNT",
  "name": "Count",
  "isSystem": true
}
```

---

# 🧩 3. UoM Group

A **dynamic grouping** of UoMs that can convert into each other.

Groups prevent invalid conversions such as meter ↔ kilogram and allow logical groups like:

- kg ↔ g  
- piece ↔ box ↔ carton  
- liter ↔ milliliter  

### Example

```json
{
  "id": "group-count",
  "code": "COUNT-UNITS",
  "name": "Count-Based Units",
  "allowedUoms": ["uom-pc", "uom-box"],
  "isActive": true
}
```

---

# 🧩 4. UoM Conversion

Defines **how two UoMs convert** inside the same group.

### Example

```json
{
  "id": "conv-box-to-pc",
  "fromUomId": "uom-box",
  "toUomId": "uom-pc",
  "factor": 12,
  "operator": "multiply"
}
```

```json
{
  "id": "conv-kg-to-g",
  "fromUomId": "uom-kg",
  "toUomId": "uom-g",
  "factor": 1000,
  "operator": "multiply"
}
```

---

# 🧩 5. Quantity Type

A **quantity type** defines the *meaning* of a measurable value:

- What does this number represent?  
- What is its default UoM?  
- How many decimals are allowed?  
- How should rounding work?  

### Examples

```json
{
  "id": "qty-net-weight",
  "code": "NET_WEIGHT",
  "name": "Net Weight",
  "defaultUomId": "uom-kg",
  "decimalPlaces": 3,
  "roundingMode": "nearest",
  "isActive": true
}
```

```json
{
  "id": "qty-item-count",
  "code": "ITEM_COUNT",
  "name": "Item Count",
  "defaultUomId": "uom-pc",
  "decimalPlaces": 0,
  "roundingMode": "down",
  "isActive": true
}
```

---

# 🔗 Summary of Relationships

| Entity | Purpose | Relationship |
|--------|---------|--------------|
| **UoM Type** | Physical nature | UoM belongs to one UoM Type |
| **UoM** | Actual measurable unit | Optional: part of UoM Group |
| **UoM Group** | Logical convertible collection | Contains multiple UoMs |
| **UoM Conversion** | Defines how units convert | Only valid inside a group |
| **Quantity Type** | Meaning + UoM rules | References default UoM |

---

# ✔ Example: Putting It All Together

Imagine a product “Sugar 1kg”:

- Base UoM = KG  
- Quantity Type = NET_WEIGHT  
- Group = WEIGHT (KG/G/Ton)  
- Conversions available → (KG ↔ G)  
- UI shows decimals = 3 because NET_WEIGHT says so  
- Inventory can convert KG to G  
- Ordering can accept “1 box = 12 pc” if count UoM group used  

The measurement-core allows all modules to work consistently.

---

# ✔ Module Purpose

The measurement-core is used by:

- Product Catalog (weight, dimensions, packaging)  
- Ordering (quantity input, UoM conversions)  
- Inventory (stock in different UoMs)  
- Purchase (supplier UoM vs internal UoM)  
- Logistics (volume, weight for shipping)  
- Manufacturing (BOM quantities, yield, consumption)  

This makes it a **critical enterprise-level core module**.

