feat: add clients nomenclator, order edit/delete/devalidate, invoice types, dashboard redesign
- New clients table with PF/PJ support, fiscal data (CUI, IBAN, eFactura fields) - Full CRUD API for clients with search, sync integration - Order lifecycle: edit header (DRAFT), devalidate (VALIDAT→DRAFT), delete order/invoice - Invoice types: FACTURA (B2B) vs BON_FISCAL (B2C) with different nr formats - OrderCreateView redesigned as multi-step flow (client→vehicle→details) - Autocomplete from catalog_norme/catalog_preturi in OrderLineForm - Dashboard now combines stats + full orders table with filter tabs and search - ClientPicker and VehiclePicker with inline creation capability - Frontend schema aligned with backend (missing columns causing sync errors) - Mobile responsive fixes for OrderDetailView buttons Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -42,14 +42,26 @@ export const useVehiclesStore = defineStore('vehicles', () => {
|
||||
return rows[0] || null
|
||||
}
|
||||
|
||||
async function getByClient(clientId) {
|
||||
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.client_id = ? AND v.tenant_id = ?
|
||||
ORDER BY v.nr_inmatriculare`,
|
||||
[clientId, auth.tenantId]
|
||||
)
|
||||
}
|
||||
|
||||
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 || '',
|
||||
`INSERT INTO vehicles (id, tenant_id, client_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_id || null, 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]
|
||||
@@ -72,9 +84,24 @@ export const useVehiclesStore = defineStore('vehicles', () => {
|
||||
await syncEngine.addToQueue('vehicles', id, 'UPDATE', data)
|
||||
}
|
||||
|
||||
async function search(query) {
|
||||
if (!query || query.length < 2) return []
|
||||
async function search(query, clientId = null) {
|
||||
if (!query || query.length < 2) {
|
||||
// If no query but clientId, return client vehicles
|
||||
if (clientId) return getByClient(clientId)
|
||||
return []
|
||||
}
|
||||
const like = `%${query}%`
|
||||
if (clientId) {
|
||||
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.client_id = ? AND (v.nr_inmatriculare LIKE ? OR v.client_nume LIKE ?)
|
||||
ORDER BY v.nr_inmatriculare LIMIT 10`,
|
||||
[auth.tenantId, clientId, like, like]
|
||||
)
|
||||
}
|
||||
return execSQL(
|
||||
`SELECT v.*, m.denumire as marca_denumire, mo.denumire as model_denumire
|
||||
FROM vehicles v
|
||||
@@ -100,5 +127,5 @@ export const useVehiclesStore = defineStore('vehicles', () => {
|
||||
)
|
||||
}
|
||||
|
||||
return { getAll, getById, create, update, search, getMarci, getModele }
|
||||
return { getAll, getById, getByClient, create, update, search, getMarci, getModele }
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user