CREATE SCHEMA Magasin;
SET search_path TO Magasin, public;
CREATE TABLE Magasin.CaissesV2 (
  NumeroCaisse integer NOT NULL CHECK(NumeroCaisse > 0), 
  Caissiere text NOT NULL, 
  DateHeureDebut timestamp NOT NULL, -- timestamp = jour + heure
  DateHeureFin timestamp NOT NULL, 
  SommeDebut integer NOT NULL CHECK(SommeDebut > 0), 
  SommeFin integer NOT NULL, 
  PRIMARY KEY (NumeroCaisse, DateHeureDebut), -- ou bien UNIQUE
  UNIQUE (NumeroCaisse, DateHeureFin),        -- ou bien PRIMARY KEY
  CONSTRAINT bilan CHECK(SommeFin >= SommeDebut),
  CONSTRAINT creneau CHECK
    (DateHeureDebut < DateHeureFin AND DateHeureFin - DateHeureDebut <= '2h')
);
-- PostgreSQL n'accepte pas les contraintes d'integrite avec un SELECT
-- Il faut definir une fonction
CREATE FUNCTION Magasin.CreneauCorrectV2(timestamp, timestamp) 
  RETURNS boolean AS $$
SELECT NOT EXISTS (
  SELECT *
  FROM Magasin.CaissesV2
  WHERE (($1 >= DateHeureDebut) AND ($1 <= DateHeureFin)) 
     OR (($2 >= DateHeureDebut) AND ($2 <= DateHeureFin)))
$$ LANGUAGE SQL;
-- puis appeler la fonction dans une contrainte d'integrite
ALTER TABLE Magasin.CaissesV2 ADD CONSTRAINT CreneauPossible
  CHECK(Magasin.CreneauCorrectV2(DateHeureDebut, DateHeureFin) = TRUE);
CREATE TABLE Magasin.HeureFactureV2 (
  NumeroCaisse integer NOT NULL,
  DateHeure timestamp NOT NULL,
  DateHeureDebut timestamp NOT NULL,  -- ou bien DateHeureFin
  PRIMARY KEY (NumeroCaisse, DateHeure),
  FOREIGN KEY (NumeroCaisse, DateHeureDebut)
    REFERENCES Magasin.CaissesV2(NumeroCaisse, DateHeureDebut)
);
CREATE TABLE Magasin.FacturesV2 (
  NumeroFacture integer NOT NULL CHECK(NumeroFacture > 0),
  NumeroCaisse integer NOT NULL,
  DateHeure timestamp NOT NULL,
  Paiement text NOT NULL,
  PRIMARY KEY (NumeroFacture),
  FOREIGN KEY (NumeroCaisse, DateHeure)
    REFERENCES Magasin.HeureFactureV2(NumeroCaisse, DateHeure),
  CONSTRAINT TypePaiement
    CHECK(Paiement='Espece' OR Paiement='CB' OR Paiement='Cheque')
);
CREATE TABLE Magasin.ArticlesV2 (
  Article text NOT NULL,
  PrixUnitaire integer NOT NULL CHECK(PrixUnitaire > 0),
  PRIMARY KEY (Article)
);
CREATE TABLE Magasin.LignesfactureV2 (
  NumeroFacture integer NOT NULL REFERENCES Magasin.FacturesV2(NumeroFacture),
  Article text NOT NULL REFERENCES Magasin.ArticlesV2(Article),
  Quantite integer NOT NULL CHECK(Quantite > 0),
  PRIMARY KEY (NumeroFacture, Article)
);
