Seera/src/services/assetService.ts
2025-11-24 19:39:38 +05:30

243 lines
6.1 KiB
TypeScript

import apiService from './apiService';
import API_CONFIG from '../config/api';
// Asset Interfaces
export interface Asset {
name: string;
asset_name: string;
company: string;
docstatus?: number; // 0 = Draft, 1 = Submitted, 2 = Cancelled
custom_serial_number?: string;
location?: string;
custom_manufacturer?: string;
department?: string;
custom_asset_type?: string;
custom_manufacturing_year?: string;
custom_model?: string;
custom_class?: string;
custom_device_status?: string;
custom_down_time?: number;
asset_owner_company?: string;
custom_up_time?: number;
custom_modality?: string;
custom_attach_image?: string;
custom_site_contractor?: string;
custom_total_amount?: number;
creation?: string;
modified?: string;
owner?: string;
modified_by?: string;
status?: string;
calculate_depreciation?: boolean;
gross_purchase_amount?: number;
available_for_use_date?:string;
finance_books?: AssetFinanceBookRow[];
custom_spare_parts?: Array<{
item_code?: string;
item_name?: string;
qty?: number;
rate?: number;
amount?: number;
uom?: string;
work_order?: string;
}>;
}
export interface AssetListResponse {
assets: Asset[];
total_count: number;
limit: number;
offset: number;
has_more: boolean;
}
export interface AssetFilters {
company?: string;
location?: string;
department?: string;
custom_asset_type?: string;
custom_manufacturer?: string;
custom_device_status?: string;
[key: string]: any;
}
export interface AssetFilterOptions {
companies: string[];
locations: string[];
departments: string[];
asset_types: string[];
manufacturers: string[];
device_statuses: string[];
}
export interface AssetStats {
total_assets: number;
by_status: Record<string, number>;
by_company: Record<string, number>;
by_type: Record<string, number>;
total_amount: number;
}
// Add child row type
export interface AssetFinanceBookRow {
finance_book?: string;
depreciation_method?: string;
total_number_of_depreciations?: number;
frequency_of_depreciation?: number;
depreciation_start_date?: string; // YYYY-MM-DD
}
export interface CreateAssetData {
asset_name: string;
company: string;
custom_serial_number?: string;
location?: string;
custom_manufacturer?: string;
department?: string;
custom_asset_type?: string;
custom_manufacturing_year?: string;
custom_model?: string;
custom_class?: string;
custom_device_status?: string;
custom_down_time?: number;
asset_owner_company?: string;
custom_up_time?: number;
custom_modality?: string;
custom_attach_image?: string;
custom_site_contractor?: string;
custom_total_amount?: number;
calculate_depreciation?: boolean;
finance_books?: AssetFinanceBookRow[];
[key: string]: any;
}
class AssetService {
/**
* Get list of assets with optional filters and pagination
*/
async getAssets(
filters?: AssetFilters,
fields?: string[],
limit: number = 20,
offset: number = 0,
orderBy?: string
): Promise<AssetListResponse> {
const params = new URLSearchParams();
if (filters) {
params.append('filters', JSON.stringify(filters));
}
if (fields && fields.length > 0) {
params.append('fields', JSON.stringify(fields));
}
params.append('limit', limit.toString());
params.append('offset', offset.toString());
if (orderBy) {
params.append('order_by', orderBy);
}
const endpoint = `${API_CONFIG.ENDPOINTS.GET_ASSETS}?${params.toString()}`;
return apiService.apiCall<AssetListResponse>(endpoint);
}
/**
* Get detailed information about a specific asset
*/
async getAssetDetails(assetName: string): Promise<Asset> {
const endpoint = `${API_CONFIG.ENDPOINTS.GET_ASSET_DETAILS}?asset_name=${encodeURIComponent(assetName)}`;
return apiService.apiCall<Asset>(endpoint);
}
/**
* Create a new asset
*/
async createAsset(assetData: CreateAssetData): Promise<{ success: boolean; asset: Asset; message: string }> {
return apiService.apiCall(API_CONFIG.ENDPOINTS.CREATE_ASSET, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ asset_data: assetData })
});
}
/**
* Update an existing asset
*/
async updateAsset(
assetName: string,
assetData: Partial<CreateAssetData>
): Promise<{ success: boolean; asset: Asset; message: string }> {
return apiService.apiCall(API_CONFIG.ENDPOINTS.UPDATE_ASSET, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
asset_name: assetName,
asset_data: assetData
})
});
}
/**
* Delete an asset
*/
async deleteAsset(assetName: string): Promise<{ success: boolean; message: string }> {
return apiService.apiCall(API_CONFIG.ENDPOINTS.DELETE_ASSET, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ asset_name: assetName })
});
}
/**
* Get available filter options
*/
async getAssetFilters(): Promise<AssetFilterOptions> {
return apiService.apiCall<AssetFilterOptions>(API_CONFIG.ENDPOINTS.GET_ASSET_FILTERS);
}
/**
* Get asset statistics
*/
async getAssetStats(): Promise<AssetStats> {
return apiService.apiCall<AssetStats>(API_CONFIG.ENDPOINTS.GET_ASSET_STATS);
}
/**
* Search assets by keyword
*/
async searchAssets(searchTerm: string, limit: number = 10): Promise<Asset[]> {
const endpoint = `${API_CONFIG.ENDPOINTS.SEARCH_ASSETS}?search_term=${encodeURIComponent(searchTerm)}&limit=${limit}`;
return apiService.apiCall<Asset[]>(endpoint);
}
/**
* Submit an asset document (changes docstatus from 0 to 1)
*/
async submitAsset(assetName: string): Promise<{ message: string }> {
return apiService.apiCall('/api/method/frappe.client.submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
doctype: 'Asset',
name: assetName
})
});
}
}
// Create and export singleton instance
const assetService = new AssetService();
export default assetService;