150 lines
5.0 KiB
JavaScript
150 lines
5.0 KiB
JavaScript
/** @odoo-module **/
|
|
|
|
import { registry } from "@web/core/registry";
|
|
import { reactive } from "@odoo/owl";
|
|
|
|
const ENDPOINT_BASE = "/fusion/assets";
|
|
|
|
export class AssetsService {
|
|
constructor(env, services) {
|
|
this.env = env;
|
|
this.rpc = services.rpc;
|
|
this.notification = services.notification;
|
|
|
|
this.state = reactive({
|
|
assets: [],
|
|
count: 0,
|
|
total: 0,
|
|
stateFilter: null,
|
|
categoryFilter: null,
|
|
isLoading: false,
|
|
isProcessing: false,
|
|
selectedAssetId: null,
|
|
selectedDetail: null,
|
|
companyId: null,
|
|
limit: 50,
|
|
offset: 0,
|
|
anomalies: [],
|
|
});
|
|
}
|
|
|
|
async loadAssets(companyId = null) {
|
|
this.state.companyId = companyId;
|
|
this.state.isLoading = true;
|
|
try {
|
|
const result = await this.rpc(`${ENDPOINT_BASE}/list`, {
|
|
state: this.state.stateFilter,
|
|
category_id: this.state.categoryFilter,
|
|
limit: this.state.limit,
|
|
offset: this.state.offset,
|
|
company_id: companyId,
|
|
});
|
|
this.state.assets = result.assets;
|
|
this.state.count = result.count;
|
|
this.state.total = result.total;
|
|
} finally {
|
|
this.state.isLoading = false;
|
|
}
|
|
}
|
|
|
|
async selectAsset(assetId) {
|
|
this.state.selectedAssetId = assetId;
|
|
this.state.selectedDetail = null;
|
|
try {
|
|
const result = await this.rpc(`${ENDPOINT_BASE}/get_detail`, {
|
|
asset_id: assetId,
|
|
});
|
|
this.state.selectedDetail = result;
|
|
} catch (err) {
|
|
this.notification.add(`Failed to load asset detail: ${err.message || err}`, { type: "danger" });
|
|
}
|
|
}
|
|
|
|
async computeSchedule(assetId, recompute = false) {
|
|
this.state.isProcessing = true;
|
|
try {
|
|
const result = await this.rpc(`${ENDPOINT_BASE}/compute_schedule`, {
|
|
asset_id: assetId, recompute: recompute,
|
|
});
|
|
this.notification.add(`Schedule computed (${result.lines_created} lines)`, { type: "success" });
|
|
if (this.state.selectedAssetId === assetId) {
|
|
await this.selectAsset(assetId);
|
|
}
|
|
return result;
|
|
} catch (err) {
|
|
this.notification.add(`Compute failed: ${err.message || err}`, { type: "danger" });
|
|
throw err;
|
|
} finally {
|
|
this.state.isProcessing = false;
|
|
}
|
|
}
|
|
|
|
async postDepreciation(assetId) {
|
|
this.state.isProcessing = true;
|
|
try {
|
|
const result = await this.rpc(`${ENDPOINT_BASE}/post_depreciation`, {
|
|
asset_id: assetId,
|
|
});
|
|
this.notification.add(`Posted ${result.posted_count} period(s)`, { type: "success" });
|
|
if (this.state.selectedAssetId === assetId) {
|
|
await this.selectAsset(assetId);
|
|
}
|
|
return result;
|
|
} catch (err) {
|
|
this.notification.add(`Post failed: ${err.message || err}`, { type: "danger" });
|
|
throw err;
|
|
} finally {
|
|
this.state.isProcessing = false;
|
|
}
|
|
}
|
|
|
|
async disposeAsset(assetId, { saleAmount = 0, saleDate = null, salePartnerId = null, disposalType = "sale" } = {}) {
|
|
this.state.isProcessing = true;
|
|
try {
|
|
const result = await this.rpc(`${ENDPOINT_BASE}/dispose`, {
|
|
asset_id: assetId, sale_amount: saleAmount,
|
|
sale_date: saleDate, sale_partner_id: salePartnerId,
|
|
disposal_type: disposalType,
|
|
});
|
|
this.notification.add(`Asset disposed: gain/loss $${result.gain_loss_amount.toFixed(2)}`, { type: "success" });
|
|
await this.loadAssets(this.state.companyId);
|
|
return result;
|
|
} catch (err) {
|
|
this.notification.add(`Dispose failed: ${err.message || err}`, { type: "danger" });
|
|
throw err;
|
|
} finally {
|
|
this.state.isProcessing = false;
|
|
}
|
|
}
|
|
|
|
async fetchAnomalies(severity = null) {
|
|
try {
|
|
const result = await this.rpc(`${ENDPOINT_BASE}/get_anomalies`, {
|
|
severity: severity, company_id: this.state.companyId,
|
|
});
|
|
this.state.anomalies = result.anomalies || [];
|
|
} catch (err) {
|
|
this.state.anomalies = [];
|
|
}
|
|
}
|
|
|
|
async suggestUsefulLife(description, amount = null, partnerName = null) {
|
|
return await this.rpc(`${ENDPOINT_BASE}/suggest_useful_life`, {
|
|
description: description, amount: amount, partner_name: partnerName,
|
|
});
|
|
}
|
|
|
|
setStateFilter(state) {
|
|
this.state.stateFilter = state;
|
|
this.state.offset = 0;
|
|
this.loadAssets(this.state.companyId);
|
|
}
|
|
}
|
|
|
|
export const assetsService = {
|
|
dependencies: ["rpc", "notification"],
|
|
start(env, services) { return new AssetsService(env, services); },
|
|
};
|
|
|
|
registry.category("services").add("fusion_assets", assetsService);
|