Services & Adapters

ErpDataService

Service fetch dati ERP da viste PostgREST. Metodo generico fetchSorgente + helper tipizzati per fatture, ordini, DDT, anagrafica, scadenze, calendario.

Costruttore

class ErpDataService {
  constructor(private readonly baseUrl: string)
}

Service per il fetch dati ERP da viste PostgREST. Espone un metodo generico (usato dalle sorgenti config-driven) e helper tipizzati per le viste più comuni dell'ERP PZeta.

API generica

async fetchSorgente(
  config: DataSourceConfig,
  filtriGlobali: GlobalFilters,
  catalogo: SorgenteCatalogo,
): Promise<{ righe: ErpRow[]; totale: number }>

Fetch generico, usato da useSpreadsheetERP.refreshSource(). Combina:

  • config.filtri — filtri specifici della sorgente
  • filtriGlobali — solo se config.usaFiltriGlobali === true
  • catalogo.endpoint — path relativo della vista
// Esempio interno
const filtri = { ...config.filtri }
if (config.usaFiltriGlobali) {
  if (filtriGlobali.periodo) {
    filtri.dataDa = filtriGlobali.periodo.da
    filtri.dataA = filtriGlobali.periodo.a
  }
  if (filtriGlobali.idcliente != null) {
    filtri.idcliente = filtriGlobali.idcliente
  }
}

const queryString = buildQueryString(filtri)
const url = `${baseUrl}${catalogo.endpoint}?${queryString}`

GET url
Headers: Range: 0-{limit-1}, Prefer: count=exact

Risposta:

return {
  righe: response.json(),
  totale: parseFromContentRange(response.headers.get('Content-Range')),
}

Mapping filtri

Il metodo privato buildQueryString traduce le chiavi:

Chiave inputOutput query string
dataDadatadocumento=gte.{val}
dataAdatadocumento=lte.{val}
limit(escluso dalla query string, gestito da header Range)
null / undefined(escluse)
altre chiavi{key}=eq.{val}

Esempio risolto:

input:  { tipooperazione: 'V', dataDa: '2026-01-01', dataA: '2026-12-31', idcliente: 42 }
output: tipooperazione=eq.V&datadocumento=gte.2026-01-01&datadocumento=lte.2026-12-31&idcliente=eq.42

Helper tipizzati

Helper specifici per le viste ERP standard. Tutti accettano filtri opzionali e ritornano Promise<ErpRow[]> (non includono il totale come fetchSorgente).

fetchFatture(params)

async fetchFatture(params: {
  tipooperazione?: string         // 'V' = vendita, 'A' = acquisto
  dataDa?: string                  // ISO date
  dataA?: string
  idcliente?: number
  limit?: number                   // default 100
}): Promise<ErpRow[]>

GET /v_fatture_riepilogo con i filtri applicati.

fetchOrdini(params)

async fetchOrdini(params: {
  idtipodocumento?: number
  dataDa?: string
  dataA?: string
  idcliente?: number
  limit?: number
}): Promise<ErpRow[]>

GET /v_ordini_riepilogo.

fetchDdt(params)

async fetchDdt(params: {
  idtipodocumento?: number
  dataDa?: string
  dataA?: string
  idcliente?: number
  limit?: number
}): Promise<ErpRow[]>

GET /v_ddt_riepilogo.

fetchAnagrafica(params)

async fetchAnagrafica(params: {
  codtipoanagrafica?: string
  limit?: number
}): Promise<ErpRow[]>

GET /anagrafica.

fetchElementi(params)

async fetchElementi(params: {
  idelementitipo?: number
  limit?: number
}): Promise<ErpRow[]>

GET /elementi.

fetchScadenze(params)

async fetchScadenze(params: {
  dataDa?: string
  dataA?: string
  limit?: number
}): Promise<ErpRow[]>

GET /scadenze.

fetchCalendario(params)

async fetchCalendario(params: {
  dataDa?: string
  dataA?: string
  limit?: number
}): Promise<ErpRow[]>

GET /calendarioeventi.

ErpRow

type ErpRow = Record<string, string | number | boolean | null>

Riga generica: dizionario di colonne con tipi primitivi. Le colonne effettive dipendono dalla vista PostgREST consultata.

Pattern: helper tipizzato in formula custom

I helper sono pensati per essere usati nelle funzioni ERP-native del workbook:

// In erp-functions.ts (custom implementation)
import { ErpDataService } from '@pzeta/vue-foglidicalcolo'

const erpSvc = new ErpDataService('https://api.example.com/rest')

const customErpFunctions = [
  {
    name: 'ERP.FATTURATO',
    handler: async (tipooperazione?, dataDa?, dataA?, idcliente?) => {
      const rows = await erpSvc.fetchFatture({
        tipooperazione: tipooperazione as string,
        dataDa: dataDa as string,
        dataA: dataA as string,
        idcliente: idcliente as number,
        limit: 10_000,
      })
      return rows.reduce((sum, r) => sum + (Number(r.imponibile) ?? 0), 0)
    },
  },
  // ...
]

Vedi erp-functions per il dettaglio dei placeholder.

Paginazione e count

Tutti i metodi usano:

Range: 0-{limit - 1}

Solo fetchSorgente aggiunge Prefer: count=exact per ottenere il Content-Range totale. Gli helper tipizzati non restituiscono il totale (caso d'uso primario: aggregazioni, non liste paginate).

Esempio diretto

import { ErpDataService } from '@pzeta/vue-foglidicalcolo'

const erp = new ErpDataService('https://api.example.com/rest')

// Solo fatture di vendita Q1 2026
const fatture = await erp.fetchFatture({
  tipooperazione: 'V',
  dataDa: '2026-01-01',
  dataA: '2026-03-31',
  limit: 1000,
})

const fatturatoQ1 = fatture.reduce((sum, f) => sum + Number(f.imponibile ?? 0), 0)
console.log(`Fatturato Q1: € ${fatturatoQ1.toFixed(2)}`)

Tipi correlati