- Pinia stores: orders (CRUD, line management, totals recalc, stats) and vehicles (CRUD, search, marca/model cascade) - useSync composable: auto-sync on window focus + periodic 60s interval - VehiclePicker component: debounced autocomplete search by nr. inmatriculare or client name - OrderLineForm component: manopera/material toggle with live total preview - DashboardView: stats cards (orders, vehicles, revenue), recent orders list - OrdersListView: filterable table (all/draft/validat/facturat), clickable rows - OrderCreateView: vehicle picker + inline new vehicle form, tip deviz select, km/observatii - OrderDetailView: order info, lines table with add/remove, totals, validate action - VehiclesListView: searchable table, inline create form with marca/model cascade - AppLayout: mobile hamburger menu with slide-in sidebar overlay Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
105 lines
3.6 KiB
JavaScript
105 lines
3.6 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { execSQL, notifyTableChanged } from '../db/database.js'
|
|
import { syncEngine } from '../db/sync.js'
|
|
import { useAuthStore } from './auth.js'
|
|
|
|
export const useVehiclesStore = defineStore('vehicles', () => {
|
|
const auth = useAuthStore()
|
|
|
|
async function getAll(search = '') {
|
|
if (search) {
|
|
const like = `%${search}%`
|
|
return execSQL(
|
|
`SELECT v.*, m.denumire as marca_denumire, mo.denumire as model_denumire
|
|
FROM vehicles v
|
|
LEFT JOIN catalog_marci m ON v.marca_id = m.id
|
|
LEFT JOIN catalog_modele mo ON v.model_id = mo.id
|
|
WHERE v.tenant_id = ? AND (v.nr_inmatriculare LIKE ? OR v.client_nume LIKE ? OR v.serie_sasiu LIKE ?)
|
|
ORDER BY v.created_at DESC`,
|
|
[auth.tenantId, like, like, like]
|
|
)
|
|
}
|
|
return execSQL(
|
|
`SELECT v.*, m.denumire as marca_denumire, mo.denumire as model_denumire
|
|
FROM vehicles v
|
|
LEFT JOIN catalog_marci m ON v.marca_id = m.id
|
|
LEFT JOIN catalog_modele mo ON v.model_id = mo.id
|
|
WHERE v.tenant_id = ?
|
|
ORDER BY v.created_at DESC`,
|
|
[auth.tenantId]
|
|
)
|
|
}
|
|
|
|
async function getById(id) {
|
|
const rows = await execSQL(
|
|
`SELECT v.*, m.denumire as marca_denumire, mo.denumire as model_denumire
|
|
FROM vehicles v
|
|
LEFT JOIN catalog_marci m ON v.marca_id = m.id
|
|
LEFT JOIN catalog_modele mo ON v.model_id = mo.id
|
|
WHERE v.id = ?`,
|
|
[id]
|
|
)
|
|
return rows[0] || null
|
|
}
|
|
|
|
async function create(data) {
|
|
const id = crypto.randomUUID()
|
|
const now = new Date().toISOString()
|
|
|
|
await execSQL(
|
|
`INSERT INTO vehicles (id, tenant_id, client_nume, client_telefon, client_email, client_cod_fiscal, client_adresa, nr_inmatriculare, marca_id, model_id, an_fabricatie, serie_sasiu, tip_motor_id, created_at, updated_at)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,
|
|
[id, auth.tenantId, data.client_nume || '', data.client_telefon || '',
|
|
data.client_email || '', data.client_cod_fiscal || '', data.client_adresa || '',
|
|
data.nr_inmatriculare || '', data.marca_id || null, data.model_id || null,
|
|
data.an_fabricatie || null, data.serie_sasiu || '', data.tip_motor_id || null, now, now]
|
|
)
|
|
notifyTableChanged('vehicles')
|
|
await syncEngine.addToQueue('vehicles', id, 'INSERT', {
|
|
id, tenant_id: auth.tenantId, ...data
|
|
})
|
|
return id
|
|
}
|
|
|
|
async function update(id, data) {
|
|
const sets = Object.keys(data).map(k => `${k} = ?`).join(', ')
|
|
const now = new Date().toISOString()
|
|
await execSQL(
|
|
`UPDATE vehicles SET ${sets}, updated_at = ? WHERE id = ?`,
|
|
[...Object.values(data), now, id]
|
|
)
|
|
notifyTableChanged('vehicles')
|
|
await syncEngine.addToQueue('vehicles', id, 'UPDATE', data)
|
|
}
|
|
|
|
async function search(query) {
|
|
if (!query || query.length < 2) return []
|
|
const like = `%${query}%`
|
|
return execSQL(
|
|
`SELECT v.*, m.denumire as marca_denumire, mo.denumire as model_denumire
|
|
FROM vehicles v
|
|
LEFT JOIN catalog_marci m ON v.marca_id = m.id
|
|
LEFT JOIN catalog_modele mo ON v.model_id = mo.id
|
|
WHERE v.tenant_id = ? AND (v.nr_inmatriculare LIKE ? OR v.client_nume LIKE ?)
|
|
ORDER BY v.nr_inmatriculare LIMIT 10`,
|
|
[auth.tenantId, like, like]
|
|
)
|
|
}
|
|
|
|
async function getMarci() {
|
|
return execSQL(
|
|
`SELECT * FROM catalog_marci WHERE tenant_id = ? AND activ = 1 ORDER BY denumire`,
|
|
[auth.tenantId]
|
|
)
|
|
}
|
|
|
|
async function getModele(marcaId) {
|
|
return execSQL(
|
|
`SELECT * FROM catalog_modele WHERE marca_id = ? ORDER BY denumire`,
|
|
[marcaId]
|
|
)
|
|
}
|
|
|
|
return { getAll, getById, create, update, search, getMarci, getModele }
|
|
})
|