Vai al contenuto

Anagrafiche vs Documenti in SAP Business One

In SAP Business One, l'architettura dei dati si divide principalmente in due macro-categorie: le Anagrafiche (Master Data) e i Documenti (Marketing Documents). Comprendere la differenza tra questi due concetti è fondamentale sia per lo sviluppo con la DI API che per la stesura di query SQL.

Cosa sono le Anagrafiche (Master Data)

Le anagrafiche rappresentano i dati di base del sistema che raramente subiscono modifiche strutturali. Esempi classici sono i Business Partner (Clienti, Fornitori, Lead) e gli Articoli di magazzino.

  • Struttura piatta: Generalmente, un'anagrafica è rappresentata da un singolo record principale (es. la tabella OCRD per i Business Partner o OITM per gli Articoli). Sebbene possano avere tabelle collegate (come gli indirizzi CRD1 o i contatti OCPR), non seguono la rigida struttura testata/riga dei documenti.
  • Nessun ciclo di vita documentale: Un'anagrafica non passa da uno stato "Aperto" a "Chiuso" o "Annullato" come un documento. Può essere "Attiva", "Inattiva" o "Avanzata", ma non ha flussi logistici o contabili intrinseci.

Cosa sono i Documenti (Marketing Documents)

I documenti rappresentano le transazioni aziendali. Esempi sono gli Ordini di Vendita (ORDR), le Fatture (OINV) o i Documenti di Trasporto/DDT (ODLN).

  • Struttura Complessa: I documenti hanno sempre una testata (Header) e una o più righe (Lines). Possono includere anche spese aggiuntive (Freight), condizioni di pagamento e rate.
  • Ciclo di vita (Lifecycle): Un documento nasce solitamente come "Aperto" (es. un Ordine), e viene "Chiuso" quando copiato in un documento successivo (es. in un DDT o Fattura) o "Annullato".
  • Meccanismo Copy-From / Copy-To: I documenti sono concatenati tra loro tramite una mappa delle relazioni.
flowchart LR
    A(Ordine di Vendita<br/>ORDR) -->|Copy-To| B(Documento di Trasporto<br/>ODLN)
    B -->|Copy-To| C(Fattura di Vendita<br/>OINV)
    style A fill:#e1f5fe,stroke:#01579b
    style B fill:#fff3e0,stroke:#e65100
    style C fill:#e8f5e9,stroke:#1b5e20

Differenze strutturali nel Database

Tipo Testata Righe Spese Aggiuntive Rate Esempio (Vendite)
Anagrafica Tabella Unica (es. OCRD) (Indirizzi: CRD1, ecc.) N/A N/A Business Partner (OCRD)
Documento Tabella O... (es. ORDR) Tabella ...1 (es. RDR1) Tabella ...2 (es. RDR2) Tabella ...3 (es. RDR3) Ordine di Vendita (ORDR, RDR1, RDR2)

Convenzione dei Nomi

Notare come per i documenti, togliendo la "O" iniziale dalla tabella di testata, si ottiene la radice per le tabelle collegate (es. ORDR -> RDR, da cui RDR1, RDR2, RDR3).

Differenze nella DI API

Nella DI API di SAP Business One, queste due entità vengono gestite in modo diverso.

  • Oggetto per le Anagrafiche: Si usa l'oggetto specifico (es. BusinessPartners o Items). Enumeratore: BoObjectTypes.oBusinessPartners
  • Oggetto per i Documenti: Si usa l'oggetto generico Documents. Enumeratore: BoObjectTypes.oOrders, BoObjectTypes.oInvoices, ecc.

Creazione di un'Anagrafica (Business Partner)

// Istanziare l'oggetto Business Partner
SAPbobsCOM.BusinessPartners oBP = (SAPbobsCOM.BusinessPartners)oCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oBusinessPartners);

oBP.CardCode = "C99999";
oBP.CardName = "Mario Rossi S.p.A.";
oBP.CardType = SAPbobsCOM.BoCardTypes.cCustomer;

// Aggiungere l'anagrafica
int retCode = oBP.Add();

if (retCode != 0) {
    Console.WriteLine($"Errore: {oCompany.GetLastErrorDescription()}");
} else {
    Console.WriteLine($"Cliente creato con successo: {oCompany.GetNewObjectKey()}");
}

Creazione di un Documento (Ordine di Vendita)

// Istanziare l'oggetto Documents specificando il tipo Ordine
SAPbobsCOM.Documents oOrder = (SAPbobsCOM.Documents)oCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oOrders);

// Dati di Testata
oOrder.CardCode = "C99999";
oOrder.DocDate = DateTime.Now;
oOrder.DocDueDate = DateTime.Now.AddDays(30);

// Dati di Riga (Linee)
oOrder.Lines.ItemCode = "A00001";
oOrder.Lines.Quantity = 10;
oOrder.Lines.UnitPrice = 150.50;

// Aggiunta di una seconda riga
oOrder.Lines.Add();
oOrder.Lines.ItemCode = "A00002";
oOrder.Lines.Quantity = 5;

// Aggiungere il documento
int retCode = oOrder.Add();

if (retCode != 0) {
    Console.WriteLine($"Errore: {oCompany.GetLastErrorDescription()}");
} else {
    Console.WriteLine($"Ordine creato con numero interno: {oCompany.GetNewObjectKey()}");
}

Attenzione alle righe dei documenti

Quando si compila un documento tramite DI API, non bisogna chiamare .Add() sulla prima riga, altrimenti si crea una riga vuota iniziale che manderà in errore il salvataggio. .Add() si usa solo dalla seconda riga in poi.

Tabella di Sintesi Comparativa

Caratteristica Anagrafiche (Master Data) Documenti (Marketing Documents)
Scopo Dati anagrafici e di base Transazioni aziendali
Struttura DB Tabella principale e tabelle di appoggio Testata, righe, spese, rate
Oggetto DI API Oggetti dedicati (es. BusinessPartners) Oggetto generico Documents
Enumeratore DI API oBusinessPartners, oItems oOrders, oInvoices, oDeliveryNotes
Ciclo di Vita Nessuno (Attivo/Inattivo) Aperto -> Chiuso/Annullato
Legami Isolati o collegati a documenti Concatenati (Copy-To / Copy-From)