Pagina 1 di 1

Carrello mysql

Inviato: ven 16 ott 2015, 20:14
da darkstaring
Ciao a tutti :)...
Sto cercando di creare un database per la gestione di un magazzino.
Mi sto inceppando nel punto della fattura per il cliente, in pratica ho una tabella prodotti
ed una fattura, ma se il cliente compra più cose non và essendo una N a N.. così ho trovato 2 metodi:
nel primo (concettualm. sbagliato) uso un campo varchar in fattura e metto tutti gli id_prodotti separati da virgola (ma verrebbe difficile se non impossibile fare conti con solo sql)
nel secondo aggiunto una tabella carrello
dove metto:

Codice: Seleziona tutto

CREATE TABLE IF NOT EXISTS carrello
				    (
					id INTEGER primary key AUTO_INCREMENT,
					id_prodotto INT NOT NULL,
					id_cliente INT NOT NULL,
					id_fattura INT NOT NULL,
					FOREIGN KEY (id_prodotto) REFERENCES prodotti(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_fattura) REFERENCES fatture(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_cliente) REFERENCES clienti(id) ON DELETE NO ACTION ON UPDATE CASCADE
				    ) ENGINE=InnoDB;
Facendo così creo prima una fattura e poi aggiungo i vari prodotti al carrello...
Cosa ne dite..
Posso fare di meglio?

Grazie 1000
Francesco

Re: Carrello mysql

Inviato: ven 16 ott 2015, 21:35
da targzeta
Io vedo 4 oggetti (tabelle) interessanti: cliente, prodotto, fattura e carrello.

Dipende da cosa ti serve ma secondo me ci dovrebbero essere le seguenti associazioni:
  • cliente - carrello (1:N). Si risolve aggiungendo una chiave esterna al carrello che punta al cliente;
  • carrello - fattura (1:1). Puoi mettere la chiave esterna della fattura nel carrello;
  • carrello - prodotto (N:M). Si risolve creando una nuova tabella con le chiavi esterne interessate.

Codice: Seleziona tutto

+-----------+                        +------------+
|  Cliente  |                        |  Prodotto  |
+-----+-----+                        +------+-----+
      |                                     |
      |   1:N      +------------+     N:M   |
      +------------+  Carrello  +-----------+
                   +-----+------+
                         |
                         |1:1
                         |
                  +------+------+
                  |   Fattura   |
                  +-------------+
Quindi hai:
  • una tabella Cliente con i dati sul cliente;
  • una tabella Fattura con i dati della fattura;
  • una tabella Prodotto con i dati sul prodotto;
  • una tabella Carrello con i dati sul carrello (data e altro) le chiavi esterne per collegare cliente e fattura;
  • una tabella ProdottoInCarrello con le chiavi esterne che collegano quale prodotto va in quale carrello;
Ti consiglio di usare almeno un ORM se non addirittura un framework. Buon lavoro,
Emanuele

Re: Carrello mysql

Inviato: sab 17 ott 2015, 6:28
da darkstaring
Grazie targzeta, ma in effetti il db è più semplice.. non ho l'entità carrello ma solo magazzino e fatture (N:N) e per quello che ho creato carrello.
La mia domanda è solo questa:
devo aggiungere la fattura prima che sia stata emessa (magari si aggiunge un flag "in corso")
oppure posso riempire carrello e solo alla fine far la fattura?... :x

Offtopic: Come hai fatto a generare quel diagramma?

Re: Carrello mysql

Inviato: sab 17 ott 2015, 9:32
da aschenaz
Se dai un'occhiata all'organizzazione del database di un cms di e-commerce, resterai disorientato per la sua complessità (io, almeno, sono rimasto disorientato).
Ad un'amica che aveva bisogno di un sito e-commerce particolare, con un momento "a monte" di prenotazione (nei fatti, si tratta di liste nozze online), ho realizzato un sistemino da zero, puntualizzando l'attenzione su ciò di cui aveva veramente bisogno.
Queste sono le tabelle chiave:

Codice: Seleziona tutto

CREATE TABLE acquirenti (
  `ID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  Cognome varchar(100) NOT NULL DEFAULT 'temp',
  Nome varchar(100) NOT NULL DEFAULT 'temp',
  Nazione mediumint(4) unsigned NOT NULL DEFAULT '106',
  Comune int(5) unsigned NOT NULL DEFAULT '727',
  Provincia int(5) NOT NULL DEFAULT '24',
  Indirizzo varchar(255) NOT NULL DEFAULT 'temp',
  Cap varchar(5) NOT NULL DEFAULT ' ',
  Telefono varchar(50) DEFAULT NULL,
  Email varchar(100) DEFAULT NULL,
  IP varchar(15) NOT NULL DEFAULT '',
  Comune_est varchar(255) DEFAULT NULL,
  Provincia_est varchar(255) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;
(I valori di default sono dettati da particolari esigenze; non ho il tempo adesso di modificarli)
(Molti campi fanno rferimento naturalmente a tabelle esterne)

Codice: Seleziona tutto

CREATE TABLE acquisti (
  `ID` bigint(13) unsigned NOT NULL,
  Acquirente mediumint(8) unsigned NOT NULL,
  Sposi mediumint(8) unsigned NOT NULL,
  Regalo bigint(13) unsigned NOT NULL,
  Prezzo decimal(10,2) unsigned DEFAULT NULL,
  Esito enum('pendente','ordinato') NOT NULL DEFAULT 'pendente',
  `Timestamp` int(10) unsigned NOT NULL,
  Ordine varchar(100) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;
(Alcuni campi sono tipici, ma possono essere facilmente modificati)

Codice: Seleziona tutto

CREATE TABLE ordini (
  `ID` bigint(13) unsigned NOT NULL AUTO_INCREMENT,
  Ordine varchar(100) NOT NULL,
  Pagamento enum('paypal','bonifico','carta') NOT NULL,
  Annotazioni text,
  Firma varchar(255) DEFAULT NULL,
  Stato enum('da pagare','da evadere','evaso') NOT NULL DEFAULT 'da pagare',
  Importo decimal(10,2) unsigned DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;
Il riferimento con la tabella degli acquisti sembrerebbe ridondante (campo Ordine), ma ho dovuto adottare questa soluzione perché la tabella acquisti viene popolata prima e c'è bisogno di creare anticipatamente un identificativo univoco...
Il campo Importo si può evitare, in quanto i calcoli sarebbero poi affidati allo scripting in fase di elaborazione dell'ordine.

In pratica, ogni record della tabella ordini raccoglie l'uno o più record relativi agli acquisti fatti dalla stessa persona. Le operazioni di raccolta vengono naturalmente gestite dall'oggetto carrello (anch'esso realizzato in semplicità ex novo).
La tabella ordini può naturalmente essere utilizzata per la gestione e la stampa delle fatture. Partendo dalla sua "maschera", infatti, uno script andrebbe a raccogliere tutti i record della tabella acquisti in cui compare lo stesso identificativo Ordine, effettuando i dovuti calcoli e formattando i risultati.

I puristi troveranno sicuramente molte cose da ridire. :lol:
Ma io sono un essenzialista e mi basta che funzioni. ;)

Re: Carrello mysql

Inviato: mar 20 ott 2015, 11:08
da darkstaring
Non vedo le ralazioni :).. questo è il mio db:
Quì il diagramma
Ecco il codice

Codice: Seleziona tutto

                           $query="CREATE TABLE IF NOT EXISTS fornitori
				    (
					id INTEGER primary key AUTO_INCREMENT,
					nome varchar(50) NOT NULL,
					cognome varchar(50) NOT NULL,
					cod_fiscale varchar(16) DEFAULT NULL,
					partita_iva VARCHAR(50) DEFAULT NULL,
					via VARCHAR(100) DEFAULT NULL,
					telefono tinytext DEFAULT NULL,
					note TINYTEXT DEFAULT NULL,
					data_inserimento INT
				    )ENGINE=InnoDB;";
			    $result = $this->query($query);
			     
			    
			    $query="CREATE TABLE IF NOT EXISTS clienti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					nome varchar(50) NOT NULL,
					cognome varchar(50) NOT NULL,
					data_matrimonio date DEFAULT NULL,
					note TINYTEXT DEFAULT NULL,
					cod_fiscale varchar(16) DEFAULT NULL,
					partita_iva VARCHAR(50) DEFAULT NULL,
					via VARCHAR(100) DEFAULT NULL,
					telefono tinytext DEFAULT NULL,
					data_inserimento INT
				    )ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore clienti.<br>";
			    
			    
			    
			    $query="CREATE TABLE IF NOT EXISTS cat_appuntamenti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					nome varchar(50) NOT NULL
				    )ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore cat_appuntamenti.<br>";

			    $query="CREATE TABLE IF NOT EXISTS appuntamenti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					id_cat_appuntamenti INT NOT NULL,
					id_cliente INT NOT NULL,
					data_ora datetime not null,
					note TINYTEXT default NULL,
					FOREIGN KEY (id_cat_appuntamenti) REFERENCES cat_appuntamenti(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_cliente) REFERENCES clienti(id) ON DELETE NO ACTION ON UPDATE CASCADE
				    )ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore appuntamenti.<br>";


			    $query="CREATE TABLE IF NOT EXISTS categorie_prodotti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					nome VARCHAR(100) NOT NULL
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore categorie_prodotti.<br>";
			    
			    $query="CREATE TABLE IF NOT EXISTS prodotti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					id_categoria INT NOT NULL,
					id_fornitore INT NOT NULL,
					nome VARCHAR(100) NOT NULL,
					descrizione TINYTEXT DEFAULT NULL,
					prezzo FLOAT(10) DEFAULT NULL,
					quantita INT(10) DEFAULT NULL,
					riserva_min INT(10) DEFAULT NULL,
					data_acquisto date DEFAULT NULL,
					FOREIGN KEY (id_categoria) REFERENCES categorie_prodotti(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_fornitore) REFERENCES fornitori(id) ON DELETE NO ACTION ON UPDATE CASCADE
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore prodotti.<br>";
Ho da gestire prodotti ed appuntamenti.. il codice sopra si limita a gestire appuntamenti e caricare prodotti...
Ora devo aggiungere le fatture per i prodotti venduti....

Penso di aggiungere:

Codice: Seleziona tutto

			    
			    $query="CREATE TABLE IF NOT EXISTS fatture
				    (
					id INTEGER primary key AUTO_INCREMENT,
					prezzo FLOAT NOT NULL,
					stato bool NOT NULL,
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore fatture.<br>";
			    

			    $query="CREATE TABLE IF NOT EXISTS carrello
				    (
					id INTEGER primary key AUTO_INCREMENT,
					id_prodotto INT NOT NULL,
					id_cliente INT NOT NULL,
					id_fattura INT NOT NULL,
					prezzo FLOAT NOT NULL,
					FOREIGN KEY (id_prodotto) REFERENCES prodotti(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_fattura) REFERENCES fatture(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_cliente) REFERENCES clienti(id) ON DELETE NO ACTION ON UPDATE CASCADE
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore carrello.<br>";
Così non appena arriva un cliente che vuole acquistare faccio subito una fattura, recupero l'id e aggiungo i vari prodotti al carrello

Che ne dite?...
Grazie 1000
Francesco :)

p.s in fatture ho prezzo perchè mi è stato chiesto un prezzo modificabile alla fine :)

Re: Carrello mysql

Inviato: mar 20 ott 2015, 11:38
da lablinux
nella tabella fatture, gestisci la fase di "pre fattura", e solo all'atto dell'acquisto generi la fattura che significa aggiungere data e numero.
Nei prodotti non vedo la gestione dell'iva.

Nel mio piccolo avevo creato la tebella Fees "Tasse e tributi" (ebbene si per fare il figo ho fatto le tabelle in inglese) con relazione 1:n con Items "Articoli"

Re: Carrello mysql

Inviato: mar 20 ott 2015, 13:29
da darkstaring
Come soluzione ti sembra corretta?

Re: Carrello mysql

Inviato: mar 20 ott 2015, 14:06
da lablinux
non capisco perché in fattura hai un solo oggetto e nel carello tante fatture...
Ho riguardato il mio vecchio db (gestito con django).
La fattura è divisa in due, l'intestazione e il corpo. Nella prima parte c'è lo stato (bozza ,emessa, pagata), i dati dell'instazione e del cliente, numero e anno e un link univoco (*). Nel corpo l'elenco dei prodotti (prodotto e quantità) con relativa imposta e una descrizione aggiuntiva (oltre a quella del prodotto stesso), mi mancava la gestione di eventuali sconti.

[edit]
mi son dimenticato dell'asterisco...
* è un campo creato con sha224. lo usavo come link univoco della fattura e serviva in caso volessi inviare la fattura al cliente piuttosto che al commercialista, fornivo un link web.
In pratica:
http://miosito.com/getit/[b]6e3e24a2589 ... e36e16b204[/b]
recuperavo il pdf (salvato sul disco) dellla fattura con 6e3e24a2589832755de897c6713ceaf2730217cc2aa0f7e36e16b204 nel campo link univoco
[/edit]

Re: Carrello mysql

Inviato: mar 20 ott 2015, 16:25
da darkstaring
lablinux ha scritto:non capisco perché in fattura hai un solo oggetto e nel carello tante fatture...
Ho riguardato il mio vecchio db (gestito con django).
La fattura è divisa in due, l'intestazione e il corpo. Nella prima parte c'è lo stato (bozza ,emessa, pagata), i dati dell'instazione e del cliente, numero e anno e un link univoco (*). Nel corpo l'elenco dei prodotti (prodotto e quantità) con relativa imposta e una descrizione aggiuntiva (oltre a quella del prodotto stesso), mi mancava la gestione di eventuali sconti.
Ora sono ad un corso e non ho molta attenzione :).. ho interfacciato quasi tutte le tabelle con php tranne quelle legate alla fattura..
per ora la forma è questa:
https://drive.google.com/file/d/0B3jUoKO_PTegZS1sUGM0aUVGa1k/view?usp=sharing
questo il codice:

Codice: Seleziona tutto

<?php
                            $query="CREATE TABLE IF NOT EXISTS fornitori
				    (
					id INTEGER primary key AUTO_INCREMENT,
					nome varchar(50) NOT NULL,
					cognome varchar(50) NOT NULL,
					cod_fiscale varchar(16) DEFAULT NULL,
					partita_iva VARCHAR(50) DEFAULT NULL,
					via VARCHAR(100) DEFAULT NULL,
					telefono tinytext DEFAULT NULL,
					note TINYTEXT DEFAULT NULL,
					data_inserimento INT
				    )ENGINE=InnoDB;";
			    $result = $this->query($query);
			     
			    
			    $query="CREATE TABLE IF NOT EXISTS clienti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					nome varchar(50) NOT NULL,
					cognome varchar(50) NOT NULL,
					data_matrimonio date DEFAULT NULL,
					note TINYTEXT DEFAULT NULL,
					cod_fiscale varchar(16) DEFAULT NULL,
					partita_iva VARCHAR(50) DEFAULT NULL,
					via VARCHAR(100) DEFAULT NULL,
					telefono tinytext DEFAULT NULL,
					data_inserimento INT
				    )ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore clienti.<br>";
			    
			    
			    
			    $query="CREATE TABLE IF NOT EXISTS cat_appuntamenti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					nome varchar(50) NOT NULL
				    )ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore cat_appuntamenti.<br>";

			    $query="CREATE TABLE IF NOT EXISTS appuntamenti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					id_cat_appuntamenti INT NOT NULL,
					id_cliente INT NOT NULL,
					data_ora datetime not null,
					note TINYTEXT default NULL,
					FOREIGN KEY (id_cat_appuntamenti) REFERENCES cat_appuntamenti(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_cliente) REFERENCES clienti(id) ON DELETE NO ACTION ON UPDATE CASCADE
				    )ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore appuntamenti.<br>";


			    $query="CREATE TABLE IF NOT EXISTS categorie_prodotti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					nome VARCHAR(100) NOT NULL
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore categorie_prodotti.<br>";
			    
			    $query="CREATE TABLE IF NOT EXISTS prodotti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					id_categoria INT NOT NULL,
					id_fornitore INT NOT NULL,
					nome VARCHAR(100) NOT NULL,
					descrizione TINYTEXT DEFAULT NULL,
					prezzo FLOAT(10) DEFAULT NULL,
					quantita INT(10) DEFAULT NULL,
					riserva_min INT(10) DEFAULT NULL,
					data_acquisto date DEFAULT NULL,
					FOREIGN KEY (id_categoria) REFERENCES categorie_prodotti(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_fornitore) REFERENCES fornitori(id) ON DELETE NO ACTION ON UPDATE CASCADE
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore prodotti.<br>";

			    
			    $query="CREATE TABLE IF NOT EXISTS stato_fattura
				    (
					id INTEGER primary key AUTO_INCREMENT,
					nome VARCHAR(100) NOT NULL
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore categorie_prodotti.<br>";
			    
			    $query="CREATE TABLE IF NOT EXISTS fatture
				    (
					id INTEGER primary key AUTO_INCREMENT,
					prezzo FLOAT NOT NULL,
					stato INT NOT NULL,
					FOREIGN KEY (stato) REFERENCES stato_fattura(id) ON DELETE NO ACTION ON UPDATE CASCADE
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore fatture.<br>";

			    
			    $query="CREATE TABLE IF NOT EXISTS acconti
				    (
					id INTEGER primary key AUTO_INCREMENT,
					id_fattura INT NOT NULL,
					data date not null,
					quota FLOAT not null,
					note TINYTEXT DEFAULT NULL,
					FOREIGN KEY (id_fattura) REFERENCES fatture(id) ON DELETE NO ACTION ON UPDATE CASCADE
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore fatture.<br>";
			    

			    $query="CREATE TABLE IF NOT EXISTS carrello
				    (
					id INTEGER primary key AUTO_INCREMENT,
					id_prodotto INT NOT NULL,
					id_cliente INT NOT NULL,
					id_fattura INT NOT NULL,
					prezzo FLOAT NOT NULL,
					FOREIGN KEY (id_prodotto) REFERENCES prodotti(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_fattura) REFERENCES fatture(id) ON DELETE NO ACTION ON UPDATE CASCADE,
					FOREIGN KEY (id_cliente) REFERENCES clienti(id) ON DELETE NO ACTION ON UPDATE CASCADE
				    ) ENGINE=InnoDB;";
			    $result = $this->query($query);
			    if( ! $result) print "Errore carrello.<br>";
?>    
Più tardi, se modifico qualcosa ti farò sapere..
Grazie :thumbright: