b6a2c97f9f
Add comprehensive asset management system with depreciation tracking similar to Xero. Features: - Create and manage fixed assets with purchase details - Calculate depreciation using straight-line and declining balance methods - Track asset book value and accumulated depreciation - Dispose/sell assets with gain/loss calculations - Automatic depreciation schedule generation - Integration with chart of accounts for depreciation entries Database: - Add assets table with purchase and depreciation fields - Add asset_depreciation_entries table for schedule tracking - Add accumulated depreciation account to seed data Server-side: - Assets module with CRUD operations - Depreciation calculation service - Asset disposal service with gain/loss tracking - REST API endpoints with permission guards Frontend: - Assets list page with data table - Asset form with purchase and depreciation sections - React Query hooks for API integration - Sidebar navigation under Accounting Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
import { Knex } from 'knex';
|
|
import { Asset } from '../models/Asset.model';
|
|
import { AssetRepository } from '../repositories/Asset.repository';
|
|
import { CreateAssetDto } from '../dtos/CreateAsset.dto';
|
|
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
|
import { events } from '@/common/events/events';
|
|
|
|
@Injectable()
|
|
export class CreateAssetService {
|
|
constructor(
|
|
private readonly assetRepository: AssetRepository,
|
|
private readonly tenancyContext: TenancyContext,
|
|
private readonly eventEmitter: EventEmitter2,
|
|
) {}
|
|
|
|
/**
|
|
* Creates a new asset.
|
|
*/
|
|
public async createAsset(
|
|
dto: CreateAssetDto,
|
|
trx?: Knex.Transaction,
|
|
): Promise<Asset> {
|
|
const user = await this.tenancyContext.getSystemUser();
|
|
|
|
// Calculate initial book value
|
|
const bookValue = dto.purchasePrice - (dto.openingDepreciation || 0);
|
|
|
|
const assetData = {
|
|
...dto,
|
|
userId: user.id,
|
|
bookValue,
|
|
currentDepreciation: 0,
|
|
totalDepreciation: dto.openingDepreciation || 0,
|
|
status: 'active' as const,
|
|
};
|
|
|
|
// Create the asset within transaction if provided
|
|
const createQuery = trx
|
|
? this.assetRepository.model.query(trx).insert(assetData)
|
|
: this.assetRepository.model.query().insert(assetData);
|
|
|
|
const asset = await createQuery;
|
|
|
|
// Emit event
|
|
this.eventEmitter.emit(events.assets.onCreated, {
|
|
asset,
|
|
trx,
|
|
});
|
|
|
|
return asset;
|
|
}
|
|
}
|