PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 17/06/2010 16:07:29

LeHibou
Membre

Facture avec postgreSQL

PostgreSQL 8.4 - Debian - OOo Base 3 - PgAdmin 3


Bonjour à tous,

Je développe ma BDD pour ma société et actuellement j'en suis à la facturaton.

Actuellement, elle compte à peu près 12-13 tables différentes (fournisseurs, stocks...).

Mon ennui actuellement, c'est que j'ai besoin de réaliser les champs pour la facturation.

Pour la présentation j'ai OOo Base. Je les fais déjà fonctionner ensemble, tout va bien. Je ne veux pas de log externe (FactOoor..).

J'ai reproduit ci-dessous un exemple de ce que je veux (attention, cette table ne comporte qu'un champ mais j'ai besoin de la logique):

Table 1

-- Table: "Calculs"."Champs"

-- DROP TABLE "Calculs"."Champs";

CREATE TABLE "Calculs"."Champs"
(
  "Champ 1" numeric,
  "Id_Opération" integer NOT NULL,
  CONSTRAINT "Champs_pkey" PRIMARY KEY ("Id_Opération")
)
WITH (
  OIDS=FALSE
);
ALTER TABLE "Calculs"."Champs" OWNER TO postgres;

Puis la table de résultat:

-- Table: "Calculs"."Résultat"

-- DROP TABLE "Calculs"."Résultat";

CREATE TABLE "Calculs"."Résultat"
(
  resultat numeric
)
WITH (
  OIDS=FALSE
);
ALTER TABLE "Calculs"."Résultat" OWNER TO postgres;

Ce que je souhaite:
Que la table Résultat calcule toutes les lignes du champs 1. Résultat correspond en vrai au Total à payer.
Pourtant je parviens à effectuer des triggers mais que sur une ligne.
Sur plusieurs lignes voire plusieurs tables, je suis perdu.

Mais j'ai envie d'apprendre.

Pouvez-vous m'aider, svp?

LeHibou

Dernière modification par LeHibou (17/06/2010 16:07:45)

Hors ligne

#2 17/06/2010 16:20:42

Marc Cousin
Membre

Re : Facture avec postgreSQL

Bonjour,

Pourrais tu reformuler la question ? Une table ne calcule pas, c'est juste un moyen de stockage. Calculer quoi sur champ1 ?


Marc.

Hors ligne

#3 17/06/2010 16:49:36

LeHibou
Membre

Re : Facture avec postgreSQL

Bien sûr, au temps pour moi, je me suis mal exprimé.

Voici le schéma ci dessous qui représente la situation:

Table 1

Id Produit
Prix unitaire
Quantité
Remise
Prix net HT
Taux Tva
Tva totale

La table 2, quant à elle, permet de calculer le total à payer.

Total HT
Total TTC

Bien sûr, la présentation, ni toutes les fonctionnalités ne sont pas là mais au moins, c'est plus simple.

J'ai été piégé car je ne peux pas mettre de trigger dans la même table. en effet, il ne me permet d'avoir que les résultats sur la ligne (à mon niveau de connaissance!).

Il faudrait que je puisse avoir les totaux pour préparer mes facturations. Sachant que ce que j'attends de postgresql, ce ne sont que les calculs, la présentation, je la fais dans un formulaire OOo Base.

Ce que je veux est possible ou pas? Sinon je passe sous OOo Calc pour mes factures et serai obligé de maintenir à jour ma base manuellement... Pas top.

Dernière modification par LeHibou (17/06/2010 16:49:58)

Hors ligne

#4 17/06/2010 17:03:10

Marc Cousin
Membre

Re : Facture avec postgreSQL

Si je comprends bien, ce que vous voulez, c'est un trigger sur la table 1 qui maintienne les totaux de la table 2 à jour ?


Marc.

Hors ligne

#5 17/06/2010 17:07:27

LeHibou
Membre

Re : Facture avec postgreSQL

Tout à fait!

Hors ligne

#6 17/06/2010 18:14:16

Marc Cousin
Membre

Re : Facture avec postgreSQL

Voici un exemple de code qui ferait ce genre de travail.

marc=# CREATE TABLE detail (commande int, montant numeric);
CREATE TABLE
marc=# CREATE TABLE somme (commande int, somme numeric);
CREATE TABLE


CREATE OR REPLACE FUNCTION calc_somme () RETURNS trigger as $code$
BEGIN
        IF (TG_OP = 'DELETE') THEN
                UPDATE somme SET somme=somme-OLD.montant WHERE commande=OLD.commande; -- Aucune importance si l'enregistrement n'existe pas
                RETURN OLD;
        ELSIF (TG_OP = 'UPDATE') THEN
                UPDATE somme SET somme=somme-old.montant+new.montant WHERE commande=new.commande;
                IF NOT FOUND THEN
                        INSERT INTO somme (commande,somme) VALUES (NEW.commande,NEW.montant);
                END IF;
                RETURN NEW;
        ELSIF (TG_OP = 'INSERT') THEN
                UPDATE somme SET somme=somme+NEW.montant WHERE commande=NEW.commande;
                if NOT FOUND THEN
                        INSERT INTO somme (commande,somme) VALUES (NEW.commande,NEW.montant);
                END IF;
                RETURN NEW;
        END IF;
        RETURN NEW;
END;
$code$ LANGUAGE plpgsql;

CREATE TRIGGER maj_somme AFTER INSERT OR UPDATE OR DELETE ON detail FOR EACH ROW EXECUTE PROCEDURE calc_somme();


Marc.

Hors ligne

#7 17/06/2010 19:55:02

LeHibou
Membre

Re : Facture avec postgreSQL

Merci Marc,

J'ai tenté, j'ai échoué.

Le problème, c'est je tente de personnaliser le code suivant la structure schéma.table ou table.colonne mais je m'y perd dans la dénomination -identique- du nom de la table et du nom de la colonne "somme".
C'est à dire que je tente de comprendre mais ne suis pas sûr de ce à quoi fait référence somme dans un cas et somme dans l'autre.

J'attends vos précisions? merci d'avance en tout cas, je n'aurais jamais trouvé ce code.

Hors ligne

#8 17/06/2010 20:10:45

Marc Cousin
Membre

Re : Facture avec postgreSQL

Ah oui, ok. Je la refais en remplacant ça.

marc=# CREATE TABLE detail (commande int, montant numeric);
CREATE TABLE
marc=# CREATE TABLE facture (commande int, somme numeric);
CREATE TABLE


CREATE OR REPLACE FUNCTION calc_somme () RETURNS trigger as $code$
BEGIN
        IF (TG_OP = 'DELETE') THEN
                UPDATE facture SET somme=somme-OLD.montant WHERE commande=OLD.commande; -- Aucune importance si l'enregistrement n'existe pas
                RETURN OLD;
        ELSIF (TG_OP = 'UPDATE') THEN
                UPDATE facture SET somme=somme-old.montant+new.montant WHERE commande=new.commande;
                IF NOT FOUND THEN
                        INSERT INTO facture (commande,somme) VALUES (NEW.commande,NEW.montant);
                END IF;
                RETURN NEW;
        ELSIF (TG_OP = 'INSERT') THEN
                UPDATE facture SET somme=somme+NEW.montant WHERE commande=NEW.commande;
                if NOT FOUND THEN
                        INSERT INTO facture (commande,somme) VALUES (NEW.commande,NEW.montant);
                END IF;
                RETURN NEW;
        END IF;
        RETURN NEW;
END;
$code$ LANGUAGE plpgsql;

CREATE TRIGGER maj_somme AFTER INSERT OR UPDATE OR DELETE ON detail FOR EACH ROW EXECUTE PROCEDURE calc_somme();


Mais n'essayez pas de simplement remplacer des morceaux en espérant que ça marche. Il faut vraiment que vous vous appropriez le fonctionnement des triggers.

Au fait, sinon vous avez 10 fois plus simple, si vous voulez juste une 'table' qui contienne les sommes :

CREATE VIEW facture AS SELECT commande,sum(montant) AS somme FROM detail;


Marc.

Hors ligne

#9 17/06/2010 20:18:25

LeHibou
Membre

Re : Facture avec postgreSQL

Pas du tout!!

J'ai modifié le code pour vraiment le personnaliser. C'est bon, ça y est ça marche.

Par contre, j'ai fait des recherches sur Tg_op. Je n'arrive pas à saisir son fonctionnement. La page de PostgreSQL n'est pas claire à ce sujet. J'ai cherché mais ne suis tombé que sur des posts qui ont des problèmes avec mais pas d'explication particulière.

Je ne veux pas abuser de votre générosité Marc, vous m'avez sorti d'un sacré pétrin.

En tout cas voilà un merci sincère...

Hors ligne

#10 17/06/2010 21:40:18

Marc Cousin
Membre

Re : Facture avec postgreSQL

C'est assez simple : TG_OP contient le type d'opération qui a déclenché le trigger. On pourrait très bien imaginer faire 3 triggers différents, un par type d'opération. C'est un choix, en termes de lisibilité.

La doc sur le sujet : http://docs.postgresql.fr/8.4/plpgsql-trigger.html

D'ailleurs mon code en était assez fortement inspiré.


Marc.

Hors ligne

#11 17/06/2010 21:50:21

LeHibou
Membre

Re : Facture avec postgreSQL

d'accord... J'avais besoin que cela soit présenté ainsi.

C'est juste un gain en rapidité.

J'avais vu déjà le lien. Mais honnêtement, il y a tellement de types de triggers qu'il y a de quoi se perdre.

J'arrête ici mes questionnements mais recommence mes remerciements.

A bientôt Marc et bonne continuation jusque là,

LeHibou

Hors ligne

Pied de page des forums