Files
service-finder/frontend/src/stores/cost.ts

103 lines
3.0 KiB
TypeScript

import { defineStore } from 'pinia'
import { ref } from 'vue'
import api from '../api/axios'
/**
* Payload shape for creating a new expense via POST /expenses/
*/
export interface AddExpensePayload {
asset_id: string
organization_id?: number | null // Auto-resolved by backend from asset if omitted
category_id: number
amount_net: number
currency?: string
date: string
mileage_at_cost?: number | null
description?: string | null
data?: Record<string, any>
}
/**
* Response shape from POST /expenses/
*/
export interface ExpenseResponse {
status: string
id: string
asset_id: string
cost_category: string
amount_net: number
date: string
}
export const useCostStore = defineStore('cost', () => {
// ── State ──────────────────────────────────────────────────────────
const isSubmitting = ref(false)
const lastError = ref<string | null>(null)
const lastSuccess = ref<ExpenseResponse | null>(null)
// ── Actions ────────────────────────────────────────────────────────
/**
* Add a new expense (fuel, fee, or other cost) via POST /expenses/.
* Used by SimpleFuelModal, ComplexExpenseModal, and the dashboard cost card.
*/
async function addExpense(payload: AddExpensePayload): Promise<ExpenseResponse | null> {
isSubmitting.value = true
lastError.value = null
lastSuccess.value = null
try {
// Build request body — omit organization_id if not provided (backend resolves it)
const body: Record<string, any> = {
asset_id: payload.asset_id,
category_id: payload.category_id,
amount_net: payload.amount_net,
currency: payload.currency || 'HUF',
date: payload.date,
mileage_at_cost: payload.mileage_at_cost ?? null,
description: payload.description || null,
data: payload.data || {},
}
if (payload.organization_id != null) {
body.organization_id = payload.organization_id
}
const res = await api.post('/expenses/', body)
const responseData = res.data as ExpenseResponse
lastSuccess.value = responseData
console.log('[CostStore] Expense created successfully:', responseData)
return responseData
} catch (err: any) {
const message =
err.response?.data?.detail ||
err.response?.data?.message ||
'Nem sikerült rögzíteni a költséget. Ellenőrizd a kapcsolatot.'
lastError.value = message
console.error('[CostStore] addExpense error:', err)
return null
} finally {
isSubmitting.value = false
}
}
/**
* Clear the last error and success state.
*/
function resetState() {
lastError.value = null
lastSuccess.value = null
}
return {
// State
isSubmitting,
lastError,
lastSuccess,
// Actions
addExpense,
resetState,
}
})