-- ================================================================================
-- L'EMETTEUR DES FACTURES, ET LA PERIODE QU'UNE FACTURE COUVRE
-- ================================================================================
--
-- DEUX MANQUES QUI SE REPONDENT.
--
-- Une facture avait jusqu'ici un destinataire — la conciergerie, avec son adresse et son
-- SIRET depuis la migration 036 — mais AUCUN EMETTEUR. Or une facture sans emetteur
-- identifie n'est pas une facture : c'est un document sans valeur comptable, et
-- l'administration le refuse.
--
-- Et rien ne disait QUELLE PERIODE une facture couvrait. Tant que les factures se
-- creaient a la main, cela se lisait dans le libelle des lignes. Des lors qu'une tache
-- automatique en emet une chaque mois, il faut pouvoir repondre a « ce mois-la a-t-il
-- deja ete facture ? » — sinon un cron relance deux fois double la facturation, et le
-- probleme se decouvre chez le client.

-- ================================================================================
-- L'EMETTEUR
-- ================================================================================
--
-- UNE SEULE LIGNE, ET LE SCHEMA L'IMPOSE.
--
-- C'est la structure juridique qui exploite l'outil et facture les conciergeries. Il n'y en
-- a qu'une. Une table libre autoriserait un second enregistrement, et rien ne dirait lequel
-- fait foi : on lirait « le premier », c'est-a-dire le plus ancien, c'est-a-dire celui qu'on
-- vient justement de remplacer.
--
-- Le CHECK sur l'identifiant rend le second insert impossible. C'est plus sur qu'une
-- convention, et cela se lit dans le schema plutot que dans le code qui l'interroge.

CREATE TABLE emetteur (
    -- TINYINT et non BIGINT : cette table n'aura jamais qu'une ligne, et le type le dit.
    id                  TINYINT UNSIGNED NOT NULL DEFAULT 1,

    -- ---------------------------------------------------------------- L'identite
    --
    -- CE QUE LA LOI FRANCAISE EXIGE SUR UNE FACTURE, cote emetteur : la denomination, la
    -- forme juridique, le capital pour une societe, l'adresse du siege, le SIREN ou SIRET,
    -- la ville du greffe et le numero RCS, et le numero de TVA intracommunautaire.
    --
    -- TOUT EST NULLABLE SAUF LE NOM, et c'est delibere : on doit pouvoir enregistrer un
    -- emetteur incomplet et le completer, plutot que de bloquer l'ecran de reglages tant
    -- que la derniere mention n'est pas trouvee. C'est l'ECRAN qui signale ce qui manque
    -- pour qu'une facture soit valable, pas la base qui l'interdit.
    nom                 VARCHAR(160)    NOT NULL,
    forme_juridique     VARCHAR(60)     NULL,

    -- EN CENTIMES, comme tout l'argent de ce projet. « Capital de 1 000 € » s'ecrit 100000.
    capital_cents       BIGINT UNSIGNED NULL,

    adresse             VARCHAR(200)    NULL,
    code_postal         VARCHAR(10)     NULL,
    ville               VARCHAR(120)    NULL,
    pays                VARCHAR(60)     NULL DEFAULT 'France',

    -- VARCHAR ET NON UN ENTIER, la meme raison qu'a la migration 036 : le zero de tete fait
    -- partie du SIRET, et un entier le mangerait.
    siret               VARCHAR(14)     NULL,
    rcs_ville           VARCHAR(120)    NULL,
    tva_intracom        VARCHAR(20)     NULL,
    ape                 VARCHAR(10)     NULL,

    email               VARCHAR(190)    NULL,
    telephone           VARCHAR(30)     NULL,

    -- ---------------------------------------------------------------- Le reglement
    --
    -- L'IBAN FIGURE SUR LA FACTURE : sans lui, le client doit demander comment payer, et
    -- c'est autant de retard. Il n'est pas secret — il sert precisement a etre communique.
    iban                VARCHAR(34)     NULL,
    bic                 VARCHAR(11)     NULL,

    -- LE DELAI DE PAIEMENT, EN JOURS. Il decide de l'echeance de chaque facture emise.
    -- Trente jours est le defaut legal en France a defaut de convention contraire.
    delai_paiement_j    SMALLINT UNSIGNED NOT NULL DEFAULT 30,

    -- EN CENTIEMES DE POINT, comme factures.tva_taux : 2000 vaut 20,00 %. Un taux en
    -- pourcentage entier interdirait 5,5 % et 2,1 %, qui existent tous les deux.
    tva_taux            SMALLINT UNSIGNED NOT NULL DEFAULT 2000,

    -- ---------------------------------------------------------------- Les mentions
    --
    -- OBLIGATOIRES ENTRE PROFESSIONNELS, et oubliees neuf fois sur dix : le taux des
    -- penalites de retard, et l'indemnite forfaitaire de recouvrement de quarante euros.
    -- Les laisser en texte libre plutot qu'en champs separes permet de les adapter aux
    -- conditions generales sans une migration a chaque nuance.
    mentions            TEXT            NULL,

    cree_le             DATETIME        NOT NULL,
    modifie_le          DATETIME        NOT NULL,

    PRIMARY KEY (id),

    -- LA LIGNE UNIQUE, IMPOSEE PAR LE SCHEMA et non par une convention.
    CONSTRAINT ck_emetteur_ligne_unique CHECK (id = 1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ================================================================================
-- LA PERIODE COUVERTE PAR UNE FACTURE
-- ================================================================================
--
-- LA FACTURATION EST MENSUELLE ET A ECHOIR : la facture du mois de mars est emise au debut
-- de mars et couvre mars. Ces deux colonnes disent ce que le document couvre, ce que ni
-- « emise_le » ni « echeance_le » ne disent — une facture emise le 1er mars et payable le
-- 31 couvre mars, pas la periode du 1er au 31 mars de son reglement.
--
-- ELLES SONT NULLABLES : une facture saisie a la main — un ajustement, une prestation
-- exceptionnelle — ne couvre aucune periode d'abonnement. NULL veut dire « hors
-- abonnement », et non « periode inconnue ».

ALTER TABLE factures
    ADD COLUMN periode_debut DATE NULL AFTER abonnement_id,
    ADD COLUMN periode_fin   DATE NULL AFTER periode_debut;

-- ================================================================================
-- ET ON NE PEUT PLUS FACTURER DEUX FOIS LE MEME MOIS
-- ================================================================================
--
-- LE GARDE-FOU EST DANS LA BASE, ET C'EST TOUT L'INTERET.
--
-- Une tache automatique qui tourne chaque nuit peut etre relancee a la main, se chevaucher
-- avec elle-meme apres un incident, ou etre rejouee lors d'une restauration. Compter sur la
-- tache pour verifier qu'elle n'a pas deja fait le travail, c'est compter sur elle pour ne
-- jamais tourner deux fois — ce qui n'est vrai qu'entre deux incidents.
--
-- Ici, la seconde tentative echoue sur une contrainte, la transaction est annulee, et rien
-- n'est facture deux fois. Le code peut alors se contenter d'attraper le refus.
--
-- LES NULL NE GENENT PAS : MySQL accepte autant de NULL qu'on veut dans un index unique.
-- Les factures manuelles — sans abonnement ni periode — ne sont donc pas limitees a une.
ALTER TABLE factures
    ADD UNIQUE KEY uq_factures_periode (abonnement_id, periode_debut);
