assets list api changes
This commit is contained in:
parent
7516354ce5
commit
b4141b9b5b
@ -892,7 +892,7 @@ flowchart TD
|
||||
end
|
||||
|
||||
PREVIEW --> CALC[calculateDepreciation]
|
||||
CREATE --> STORE[(assets: method, rate, cost, salvage, life, purchase_date)]
|
||||
CREATE --> STORE[(assets: method, rate, cost, salvage, life, commencement/purchase date)]
|
||||
STORE --> READ["GET /assets/:id"]
|
||||
READ --> CALC
|
||||
|
||||
@ -903,19 +903,92 @@ flowchart TD
|
||||
OTHER --> CALC
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<h3>Input fields used in calculation</h3>
|
||||
<table>
|
||||
<thead><tr><th>Method</th><th>Rate auto-calc?</th><th>Formula concept</th></tr></thead>
|
||||
<thead><tr><th>Field</th><th>Meaning</th><th>Role in formula</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><strong>SLM</strong></td><td>Yes (if rate omitted)</td><td>Equal yearly depreciation on original cost</td></tr>
|
||||
<tr><td><strong>WDV</strong></td><td>Yes (if rate omitted)</td><td>Depreciation on reducing book value year-by-year</td></tr>
|
||||
<tr><td><strong>OTHER</strong></td><td>No — user must send <code>depreciation_rate</code></td><td>Custom % on cost</td></tr>
|
||||
<tr><td><code>purchase_cost</code></td><td>Asset cost / amount</td><td>Starting book value; base for rate & annual dep</td></tr>
|
||||
<tr><td><code>salvage_value</code></td><td>Residual value at end of life</td><td>Floor for book value; used in rate auto-calc</td></tr>
|
||||
<tr><td><code>useful_life_years</code></td><td>Expected life in years</td><td>Rate auto-calc + cap on years elapsed</td></tr>
|
||||
<tr><td><code>commencement_date</code></td><td>Usage / put-to-use date</td><td><strong>Primary</strong> start date for years elapsed</td></tr>
|
||||
<tr><td><code>purchase_date</code></td><td>Purchase date</td><td>Fallback start date if commencement is null</td></tr>
|
||||
<tr><td><code>depreciation_method</code></td><td><code>SLM</code> / <code>WDV</code> / <code>OTHER</code></td><td>Which formula path to run</td></tr>
|
||||
<tr><td><code>depreciation_rate</code></td><td>% per year</td><td>Optional for SLM/WDV (auto); required for OTHER</td></tr>
|
||||
<tr><td><code>as_of_date</code></td><td>Calculate as of (preview only)</td><td>Defaults to today</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Date → years elapsed</h3>
|
||||
<pre><code>depreciation_start_date = commencement_date || purchase_date
|
||||
years_elapsed = (as_of_date − depreciation_start_date) / 365.25 days
|
||||
capped_years = min(years_elapsed, useful_life_years) // if life is set
|
||||
</code></pre>
|
||||
<p>Accumulated depreciation uses <code>capped_years</code> so it never exceeds useful life.</p>
|
||||
|
||||
<h3>Method 1 — SLM (Straight Line)</h3>
|
||||
<p>Equal depreciation every year on <strong>original cost</strong>, never below salvage.</p>
|
||||
<p><strong>Auto rate</strong> (when <code>depreciation_rate</code> omitted):</p>
|
||||
<pre><code>depreciable_amount = max(purchase_cost − salvage_value, 0)
|
||||
depreciation_rate = (depreciable_amount / purchase_cost / useful_life_years) × 100
|
||||
</code></pre>
|
||||
<p><strong>Amounts:</strong></p>
|
||||
<pre><code>annual_depreciation = purchase_cost × rate / 100
|
||||
accumulated_depreciation = min(annual_depreciation × capped_years, purchase_cost − salvage_value)
|
||||
book_value = max(purchase_cost − accumulated_depreciation, salvage_value)
|
||||
</code></pre>
|
||||
<p><strong>Example:</strong> cost = ₹1,00,000 · salvage = ₹10,000 · life = 10 years · start = 1 year ago</p>
|
||||
<ul>
|
||||
<li>Rate = ((100000−10000)/100000/10)×100 = <strong>9%</strong></li>
|
||||
<li>Annual = 100000 × 9% = <strong>₹9,000</strong></li>
|
||||
<li>Accumulated (1 yr) = <strong>₹9,000</strong></li>
|
||||
<li>Book value = <strong>₹91,000</strong></li>
|
||||
</ul>
|
||||
|
||||
<h3>Method 2 — WDV (Written Down Value)</h3>
|
||||
<p>Depreciation each year on the <strong>reducing book value</strong> (not original cost). Book value never goes below salvage.</p>
|
||||
<p><strong>Auto rate</strong> (when <code>depreciation_rate</code> omitted; needs salvage > 0 and < cost):</p>
|
||||
<pre><code>depreciation_rate = (1 − (salvage_value / purchase_cost)^(1 / useful_life_years)) × 100
|
||||
</code></pre>
|
||||
<p><strong>Amounts (year-by-year):</strong></p>
|
||||
<pre><code>book_value = purchase_cost
|
||||
for each full year in capped_years:
|
||||
year_dep = book_value × rate / 100
|
||||
book_value = max(book_value − year_dep, salvage_value)
|
||||
if fractional year remains:
|
||||
year_dep = (book_value × rate / 100) × fraction
|
||||
book_value = max(book_value − year_dep, salvage_value)
|
||||
|
||||
accumulated_depreciation = purchase_cost − book_value
|
||||
annual_depreciation = book_value × rate / 100 // next year's dep on current WDV
|
||||
</code></pre>
|
||||
<p><strong>Example:</strong> cost = ₹1,00,000 · salvage = ₹10,000 · life = 10 years · start = 1 year ago</p>
|
||||
<ul>
|
||||
<li>Rate ≈ (1 − (10000/100000)^(1/10)) × 100 ≈ <strong>20.57%</strong></li>
|
||||
<li>Year 1 dep ≈ 100000 × 20.57% ≈ <strong>₹20,570</strong></li>
|
||||
<li>Book value ≈ <strong>₹79,430</strong></li>
|
||||
<li>Accumulated ≈ <strong>₹20,570</strong></li>
|
||||
<li>Next annual (on WDV) ≈ 79430 × 20.57% ≈ <strong>₹16,340</strong></li>
|
||||
</ul>
|
||||
|
||||
<h3>OTHER method</h3>
|
||||
<p>Same accumulation style as SLM, but <code>depreciation_rate</code> is <strong>mandatory</strong> (no auto-calc).</p>
|
||||
|
||||
<table>
|
||||
<thead><tr><th>Method</th><th>Rate auto-calc?</th><th>Depreciates on</th><th>Salvage role</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><strong>SLM</strong></td><td>Yes (if rate omitted)</td><td>Original <code>purchase_cost</code> every year</td><td>In rate formula + book-value floor</td></tr>
|
||||
<tr><td><strong>WDV</strong></td><td>Yes (if rate omitted)</td><td>Reducing book value each year</td><td>In rate formula + book-value floor</td></tr>
|
||||
<tr><td><strong>OTHER</strong></td><td>No — send <code>depreciation_rate</code></td><td>Original cost × rate (like SLM)</td><td>Book-value floor only</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p><strong>FE usage:</strong></p>
|
||||
<ul>
|
||||
<li><strong>Live preview</strong> → <code>POST /assets/depreciation/calculate</code> (no save)</li>
|
||||
<li><strong>Saved asset view</strong> → <code>GET /assets/:id</code> → <code>data.depreciation</code> object</li>
|
||||
<li><strong>Method dropdown</strong> → <code>GET /assets/depreciation-methods</code></li>
|
||||
<li>Prefer sending <code>commencement_date</code>; backend falls back to <code>purchase_date</code></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="s12">12. Alerts flow (cross-asset dashboards)</h2>
|
||||
|
||||
@ -501,7 +501,7 @@ flowchart TD
|
||||
end
|
||||
|
||||
PREVIEW --> CALC[calculateDepreciation]
|
||||
CREATE --> STORE[(assets: method, rate, cost, salvage, life, purchase_date)]
|
||||
CREATE --> STORE[(assets: method, rate, cost, salvage, life, commencement/purchase date)]
|
||||
STORE --> READ["GET /assets/:id"]
|
||||
READ --> CALC
|
||||
|
||||
@ -512,17 +512,104 @@ flowchart TD
|
||||
OTHER --> CALC
|
||||
```
|
||||
|
||||
| Method | Rate auto-calc? | Formula concept |
|
||||
### Input fields used in calculation
|
||||
|
||||
| Field | Meaning | Role in formula |
|
||||
|---|---|---|
|
||||
| **SLM** | Yes (if rate omitted) | Equal yearly depreciation on original cost |
|
||||
| **WDV** | Yes (if rate omitted) | Depreciation on reducing book value year-by-year |
|
||||
| **OTHER** | No — user must send `depreciation_rate` | Custom % on cost |
|
||||
| `purchase_cost` | Asset cost / amount | Starting book value; base for rate & annual dep |
|
||||
| `salvage_value` | Residual value at end of life | Floor for book value; used in rate auto-calc |
|
||||
| `useful_life_years` | Expected life in years | Rate auto-calc + cap on years elapsed |
|
||||
| `commencement_date` | Usage / put-to-use date | **Primary** start date for years elapsed |
|
||||
| `purchase_date` | Purchase date | Fallback start date if commencement is null |
|
||||
| `depreciation_method` | `SLM` / `WDV` / `OTHER` | Which formula path to run |
|
||||
| `depreciation_rate` | % per year | Optional for SLM/WDV (auto); required for OTHER |
|
||||
| `as_of_date` | Calculate as of (preview only) | Defaults to today |
|
||||
|
||||
### Date → years elapsed
|
||||
|
||||
```
|
||||
depreciation_start_date = commencement_date || purchase_date
|
||||
years_elapsed = (as_of_date − depreciation_start_date) / 365.25 days
|
||||
capped_years = min(years_elapsed, useful_life_years) // if life is set
|
||||
```
|
||||
|
||||
Accumulated depreciation uses `capped_years` so it never exceeds useful life.
|
||||
|
||||
### Method 1 — SLM (Straight Line)
|
||||
|
||||
Equal depreciation every year on **original cost**, never below salvage.
|
||||
|
||||
**Auto rate** (when `depreciation_rate` omitted):
|
||||
|
||||
```
|
||||
depreciable_amount = max(purchase_cost − salvage_value, 0)
|
||||
depreciation_rate = (depreciable_amount / purchase_cost / useful_life_years) × 100
|
||||
```
|
||||
|
||||
**Amounts:**
|
||||
|
||||
```
|
||||
annual_depreciation = purchase_cost × rate / 100
|
||||
accumulated_depreciation = min(annual_depreciation × capped_years, purchase_cost − salvage_value)
|
||||
book_value = max(purchase_cost − accumulated_depreciation, salvage_value)
|
||||
```
|
||||
|
||||
**Example:** cost = ₹1,00,000 · salvage = ₹10,000 · life = 10 years · start = 1 year ago
|
||||
|
||||
- Rate = ((100000−10000)/100000/10)×100 = **9%**
|
||||
- Annual = 100000 × 9% = **₹9,000**
|
||||
- Accumulated (1 yr) = **₹9,000**
|
||||
- Book value = **₹91,000**
|
||||
|
||||
### Method 2 — WDV (Written Down Value)
|
||||
|
||||
Depreciation each year on the **reducing book value**. Book value never goes below salvage.
|
||||
|
||||
**Auto rate** (when `depreciation_rate` omitted; needs salvage > 0 and < cost):
|
||||
|
||||
```
|
||||
depreciation_rate = (1 − (salvage_value / purchase_cost)^(1 / useful_life_years)) × 100
|
||||
```
|
||||
|
||||
**Amounts (year-by-year):**
|
||||
|
||||
```
|
||||
book_value = purchase_cost
|
||||
for each full year in capped_years:
|
||||
year_dep = book_value × rate / 100
|
||||
book_value = max(book_value − year_dep, salvage_value)
|
||||
if fractional year remains:
|
||||
year_dep = (book_value × rate / 100) × fraction
|
||||
book_value = max(book_value − year_dep, salvage_value)
|
||||
|
||||
accumulated_depreciation = purchase_cost − book_value
|
||||
annual_depreciation = book_value × rate / 100 // next year's dep on current WDV
|
||||
```
|
||||
|
||||
**Example:** cost = ₹1,00,000 · salvage = ₹10,000 · life = 10 years · start = 1 year ago
|
||||
|
||||
- Rate ≈ (1 − (10000/100000)^(1/10)) × 100 ≈ **20.57%**
|
||||
- Year 1 dep ≈ 100000 × 20.57% ≈ **₹20,570**
|
||||
- Book value ≈ **₹79,430**
|
||||
- Accumulated ≈ **₹20,570**
|
||||
- Next annual (on WDV) ≈ 79430 × 20.57% ≈ **₹16,340**
|
||||
|
||||
### OTHER method
|
||||
|
||||
Same accumulation style as SLM, but `depreciation_rate` is **mandatory** (no auto-calc).
|
||||
|
||||
| Method | Rate auto-calc? | Depreciates on | Salvage role |
|
||||
|---|---|---|---|
|
||||
| **SLM** | Yes (if rate omitted) | Original `purchase_cost` every year | In rate formula + book-value floor |
|
||||
| **WDV** | Yes (if rate omitted) | Reducing book value each year | In rate formula + book-value floor |
|
||||
| **OTHER** | No — send `depreciation_rate` | Original cost × rate (like SLM) | Book-value floor only |
|
||||
|
||||
**FE usage:**
|
||||
|
||||
- **Live preview** → `POST /assets/depreciation/calculate` (no save)
|
||||
- **Saved asset view** → `GET /assets/:id` → `data.depreciation` object
|
||||
- **Method dropdown** → `GET /assets/depreciation-methods`
|
||||
- Prefer sending `commencement_date`; backend falls back to `purchase_date`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -509,6 +509,9 @@ paths:
|
||||
get:
|
||||
tags: [Assets]
|
||||
summary: List assets
|
||||
description: >
|
||||
Each item includes purchase_cost, current_value (book value after depreciation),
|
||||
and a depreciation summary object (method, rate, annual, accumulated, book_value, years_elapsed).
|
||||
parameters:
|
||||
- { name: page, in: query, schema: { type: integer } }
|
||||
- { name: limit, in: query, schema: { type: integer } }
|
||||
|
||||
@ -148,12 +148,24 @@ const sanitizeAsset = (asset) => {
|
||||
? Number(rest.depreciation_rate)
|
||||
: null;
|
||||
|
||||
const depreciation = calculateDepreciation({
|
||||
depreciation_method: rest.depreciation_method,
|
||||
depreciation_rate: depreciationRate,
|
||||
purchase_cost: purchaseCost,
|
||||
salvage_value: salvageValue,
|
||||
useful_life_years: rest.useful_life_years,
|
||||
commencement_date: rest.commencement_date,
|
||||
purchase_date: rest.purchase_date,
|
||||
});
|
||||
|
||||
return {
|
||||
...rest,
|
||||
maintenance_checklist_json: presentChecklistTemplate(rest.maintenance_checklist_json),
|
||||
purchase_cost: purchaseCost,
|
||||
salvage_value: salvageValue,
|
||||
depreciation_rate: depreciationRate,
|
||||
// Current written-down / book value after depreciation (same as depreciation.book_value)
|
||||
current_value: depreciation.book_value,
|
||||
item_category: item_categories || null,
|
||||
item_subcategory: item_subcategories || null,
|
||||
location: location || null,
|
||||
@ -167,15 +179,10 @@ const sanitizeAsset = (asset) => {
|
||||
created_by_user: users_assets_created_byTousers || null,
|
||||
updated_by_user: users_assets_updated_byTousers || null,
|
||||
attachments: (asset_attachments || []).map(sanitizeAttachment),
|
||||
depreciation: calculateDepreciation({
|
||||
depreciation_method: rest.depreciation_method,
|
||||
depreciation_rate: depreciationRate,
|
||||
purchase_cost: purchaseCost,
|
||||
salvage_value: salvageValue,
|
||||
useful_life_years: rest.useful_life_years,
|
||||
commencement_date: rest.commencement_date,
|
||||
purchase_date: rest.purchase_date,
|
||||
}),
|
||||
depreciation: {
|
||||
...depreciation,
|
||||
current_value: depreciation.book_value,
|
||||
},
|
||||
item_categories: undefined,
|
||||
item_subcategories: undefined,
|
||||
departments: undefined,
|
||||
@ -486,6 +493,11 @@ const exportAssets = async (query) => {
|
||||
{ key: 'commencement_date', header: 'Commencement Date', type: 'date' },
|
||||
{ key: 'purchase_date', header: 'Purchase Date', type: 'date' },
|
||||
{ key: 'purchase_cost', header: 'Purchase Cost' },
|
||||
{ key: 'current_value', header: 'Current Value' },
|
||||
{ key: (row) => row.depreciation?.accumulated_depreciation ?? '', header: 'Accumulated Depreciation' },
|
||||
{ key: (row) => row.depreciation?.annual_depreciation ?? '', header: 'Annual Depreciation' },
|
||||
{ key: (row) => row.depreciation?.depreciation_method || '', header: 'Depreciation Method' },
|
||||
{ key: (row) => row.depreciation?.depreciation_rate ?? '', header: 'Depreciation Rate %' },
|
||||
{ key: 'warranty_expiry_date', header: 'Warranty Expiry', type: 'date' },
|
||||
{
|
||||
key: (row) => row.maintenance_incharge_user?.full_name || '',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user