Pour la structure de la base, je verrais bien une structure en trois tables :
  • Classe
    • Nom
    • Description
    • Code interne
      ...
  • Sous-classe
    • Nom
    • Description
    • Code interne
    • Code interne de la classe
      ...
  • Opération
    • Code interne
    • Code interne de la sous-classe
    • Description
    • Date
    • Différentiel du nombre de produits
      ...

Lorsque l'opération consiste à ajouter des produits à ton stock, le différentiel du nombre de produits est positif, sinon, il est négatif. Pour avoir l'état du stock à une date, tu fais la somme des différentiels de toutes les opérations avant la date.
Pour éviter les redondances sur les opérations, tu pourrais ajouter une table Type d'opération dont tu renseignerais la clé unique des enregistrements dans ceux de la table Opération.
avatar
Et bien merci beaucoup pour vos réponses, comme à mon habitude ça va me demander du temps pour méditer et digérer ça, parce que j'ai jamais eu affaire à ces problématiques.

Quant à SQLite en elle-même, ça m'a l'air vraiment simple à prendre en main. On crée des tables, on y établit une connexion, on fait des requêtes et on lit les résultats. Je ne suis sûr que d'une chose, c'est que mes requêtes seront certainement horribles vu mon inexpérience, mais je devrais arriver à faire ce que je veux.

Merci encore pour tout ! top
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Rah merde, ça a validé avant que je ne puisse finir...

Donc...
Cette solution ne permet plus de faire des opérations SQL simple de comptage (avec un SELECT COUNT). Par contre, elle te permet de gérer des opérations que tu n'as peut-être pas encore étudées à ce jour (typiquement, avec cette solution, tu peux avoir des opérations de type ENTREE, SORTIE, mais aussi INVENTAIRE, où tu fais un point à une date donnée sur l'état de ton inventaire).

Autre façon d'imaginer les choses : tu sais que tu n'auras que des opérations de type ENTREE ou SORTIE, du coup tu vires la colonne "Opération", et ta quantité te dis s'il s'agit d'une E ou d'une S (avec le signe).

Enfin, dernière façon : ton script transforme chaque entrée multiple en un nombre équivalent d'entrées E ou S, chacun pour un seul élément. C'est très verbeux, pas forcément optimisé, mais si tu veux faire des opérations via des requêtes, un SELECT COUNT sera plus facile (cela dit, ce n'est pas une solution que je recommanderais ; à mes yeux la première est peut-être la plus compliquée en terme de traitements complémentaires, mais la plus souple si ton application en vient à s'élargir).

Sachant qu'en plus, dans le cas présent, je ne peux que te conseiller soit d'avoir un timestamp à la place de la date, soit une colonne supplémentaire d'auto-incrément (pour la table E/S). Tout simplement pour ne jamais avoir deux lignes strictement identiques (sinon, tu peux vite galérer pour les opérations de suppressions ou de mise à jour de données : il te manquera un discriminant et c'est le meilleur moyen pour faire une fausse manip en impactant trop de lignes si tu as plusieurs opérations de même type réalisées sur un même produit).
avatar
(Ne t'inquiète pas trop pour la tête de tes requêtes : quand je vois ce qui sort du service de contrôle de gestion ici, je me dis que tout est possible cheeky )
avatar
(oui, mais Folco a des critères de qualité, lui embarrassed)
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
<@Zeph> et folco qui se met à faire du sql, il est foutu !
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
(Merci pour cet encouragement, sisi grin)
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Sans quoi, pour la valeur de ton stock, si ton produit n'a pas de N°S, tu t'en tamponne qu'on prenne le plus récent ou le plus vieux, tu valorise au prix de ta dernière commande pour peu que tu aies moins de stock que celle-ci
avatarpedrolane stoppe la chute des chevaux

La DNC-Team : un club plein de mystères
Pour ce genre d'opétations, je m'en fous en effet, on est bien d'accord.
Mais certaines "statistiques" n'auraient plus aucun sens.
Mais cette façon d'enregistrer les choses serait pourtant la plus simple et probablement la plus performante.
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Sans quoi, à chaque entrée de stock, tu valorises toutes tes pièces (y compris celles déjà présentes, tu modifies leur prix dans l'opération d'entrée en stock) au prix moyen de l'ensemble. Tu es au plus "juste" d'un point de vue comptable de ce que vaut vraiment ton stock. ça veut dire que tu fasses un formulaire d'entrée en stock qui prendra le stock théorique restant et recalculera la nouvelle valeur avant de mettre dans les tables.

Idée à deux balles, je ne maîtrise pas les structures des BDD, je ne sais pas déchiffrer correctement ce que vous avez écrit sur ce sujet précis : A moins que le prix d'achat réel ne soit contenu dans la table qui contient ton inventaire, et le prix moyen dans la table qui énumère les références article ?
avatarpedrolane stoppe la chute des chevaux

La DNC-Team : un club plein de mystères
moi je reste humble avec les performances SQL grin
Si tu as une t'entree pour chaque produit, ou du moins chaque commande avec le prix d'achat, tu t'en fout de savoir si c'est la version à X ou Y Dollars Zimbabwéensqui sors du moment que tu décompte le tout.

Si tu n'as pas pour le stock une entrée pour chaque pièces, tu auras au moins une entrée par arrivee dans le stock avec un champ "prix de là pièce" et u. Champ "combien qui en as"

quand une pièce d'un certain type sors tu prends dans cette liste le plus ancien qui a du stock, l'ancienneté est lie a l'identifiant unique de l'entrée, si c'est un compteur monotone, le numéro le plus faible est le plus ancien smile

Conseil si tu utilise cette approche, met un champ "stock à l'arrivée" et le champ "restant" garder une valeur correspondant au total de pièces de cette commande peu avoir des utilisations bien plus tard lors de vérification de stock par exemple!
avatarProud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.
squalyl (./40) :
moi je reste humble avec les performances SQL
Que veux-tu dire ? Que c'est toujours à la rue, ou qu'il faut être un dieu pour avoir quelque chose de potable ?
Dans ce dernier cas, je me pose évidemment une question : quel avantage à utiliser une bdd plutôt qu'un format perso ? Est-ce seulement du gain de temps de dev, ou une bdd a-t-elle des fonctionnalités essentielles et pénibles à implémenter ?
Godzil (./41) :
Si tu n'as pas pour le stock une entrée pour chaque pièces, tu auras au moins une entrée par arrivee dans le stock avec un champ "prix de là pièce" et u. Champ "combien qui en as"
j'aurais donc une redondance d'information : un prix par pièce pour chaque entrée, prix qui a priori sera quasi toujours le même.
Godzil (./41) :
quand une pièce d'un certain type sors tu prends dans cette liste le plus ancien qui a du stock, l'ancienneté est lie a l'identifiant unique de l'entrée, si c'est un compteur monotone, le numéro le plus faible est le plus ancien
oui, je peux gérer ça comme ça (fifo), mais ça donnera des couples de dates entrée/sortie complètement artificiels et faux.

Ceci dit, vu que tu parles d'identifiant unique, j'ai une question qui me taraude ? Où le stocker, cet identifiant ?
- c'est recalculable à l'ouverture de la bdd, mais c'est quand même con
- c'est stockable dans un fichier à part, mais ça me plait pas, parce que c'est intimement lié à la bdd, et qu'un effacement ou une édition poserait de gros pb
- c'est stockable dans la bdd, dans une table batarde où l'on met le nom du stock, l'identifiant unique courant et l'âge du capitaine

Comment s'y prend-t-on en général ?

Merci bien. smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
avatarMes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
Tu met une simple colone "ID", "Identifiant" ou "WTF" et tu y stoque un entier dont tu incremente la valeur a chaque nouvelle entrée (tu commence a 0 ou -42 si ca te chante l'important est que la valeur reste unique)
avatarProud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.
Folco: que c'est pas évident a prédire sans expérience (que je n'ai pas, juste des notions).

Avantage du SGBD -> toute la gestion du format est déja codée.

SQLITE donne automatiquement un numero unique 64 bits a chaque enregistrement de chaque table, strictement croissant (dans chaque table).

https://www.sqlite.org/lang_createtable.html#rowid

va falloir que tu rentres un peu dans la doc du sql...

en général une appli comme la tienne fait

-init: cherche les tables
-si elles existent pas -> on crée (ou upgrade)

puis on bosse avec.
Folco (./42) :
squalyl (./40) :
moi je reste humble avec les performances SQL
Que veux-tu dire ? Que c'est toujours à la rue, ou qu'il faut être un dieu pour avoir quelque chose de potable ?
Si tu as des opérations classiques, c'est facile d'avoir des perfs correctes.
Est-ce seulement du gain de temps de dev, ou une bdd a-t-elle des fonctionnalités essentielles et pénibles à implémenter ?
Merci bien. smile
Les deux. Ne serait-ce que l'indexation des colonnes pour trier les produits par nom puis par prix, calculer la somme des prix, etc.
avatar<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant
Godzil (./44) :
Tu met une simple colone "ID", "Identifiant" ou "WTF" et tu y stoque un entier dont tu incremente la valeur a chaque nouvelle entrée (tu commence a 0 ou -42 si ca te chante l'important est que la valeur reste unique)
Toute base de données qui se respecte est capable de faire ça automatiquement (autoincrement), j'ai déjà donné le lien qui explique comment faire pour SQLite.
avatarMes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
ca tombe même gratuitement en marche avec sqlite
Ok, merci beaucoup pour vos réponses et vos liens.
squalyl (./45) :
va falloir que tu rentres un peu dans la doc du sql...
C'est ce que j'ai fait ce week-end, je suis évidemment loin d'avoir fini, j'avais donc pas encore vu ça.

Mais ma question persiste, pour quelques autres infos que j'entrevois, comme une date de création ou un nom de base (autre que le nom de fichier) : une base sait-elle contenir autre chose que des tables ?
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
non, que des tables, c'est le but.

tu as besoin de stocker quoi d'autre qui peut pas être fait avec une table confus
Le nom de base est le nom du fichier. Certains SGBD permettent d'ajouter de la meta-information (description d'éléments, date de la dernière opération d'écriture, de l'utilisateur de DB ayant fait l'opération, date de modification ou de création d'un tuple, structure des données...), soit de façon native soit au travers de bases de données techniques dédiées dans lesquelles vont se retrouver ces informations. SQLite étant Lite, il ne permet pas tout ça. Cela dit, tu ne devrais pas en avoir besoin.
avatar
Rien. Je peux très bien faire une table pour le nom et l'adresse de la boite concernée (on a plusieurs sites), la date de création ou d'autres babioles. Il n'y a pas grand chose, je peux évidemment mettre ça dans une table, mais de simples variables auraient suffi.

Idéalement, j'aimerais n'avoir qu'un seul fichier sqlite par stock, avec tout ce dont j'ai besoin, et éviter ces deux cas de figures :
- 2+ fichiers de données à ouvrir pour un stock (que faire en cas de perte d'un fichier ?)
- sérialiser mes données et la base de sqlite dans un fichier (risque de corruption, dépendance éventuelle à un archiveur)
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
dans le cas sqlite je fais une table 'meta' avec une colonne string key et une colonne valeur.

et j'y mets des paires clé/valeur.

mais si t'as plusieurs établissements c'est une table dédiée.

au fait, tu peux faire plein d'essais avec le soft http://sqlitebrowser.org/
Merci bien !
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !


trivil
de.. je.. HEIN ?
"Eh, dis, comment je fais pour distinguer la table 'carré carré carré' de la table 'carré carré carré' ?!"
avatar
Attention pour la gestion de stock : y'a un truc qui est souvent oublié à la conception (et souvent ajouté à l'arrache après) c'est la non unicité des références.

Exemple : des écrous
le 10/04 tu entres 5000 écrous de 8 dans le stock
le 15/04 tu sors 1400 écrous de 8 du stock
le 20/04 tu entres 1000 écrous de 8 dans le stock
le 25/04 tu sors 3600 écrous de 8 du stock

il t'en reste 1000 mais tu ne sais pas dire de quand il date

Exemple : des produits avec numéro de série
le 10/04 tu entres 50 Ti89 avec les numéros de série 1 à 50
le 15/04 tu sors 14 Ti89 avec les numéros de série 1 à 14
le 20/04 tu entres 10 Ti89 avec les numéros de série 51 à 60
le 25/04 tu sors 36 Ti 89 avec les numéros 25 à 60

il t'en reste 10 et tu sais que les numéros de série sont 15 16 17 18 19 20 21 22 23 24 grâce à l'info sur l'unicité

Autre exemple : tu entres des yop sans cracher dedans
là c'est pas des numéros de série mais des dates de péremption...


Dernier point : penses à prévoir une "table d'équivalence" pour qu'une tige de 2.54mm ou une tige d'un pouce soient considérés comme "équivalentes" (à toi de voir si tu veux garder un compte séparé ou juste des synonymes de libellés)
avatarWebmaster du site Ti-FRv3 (et aussi de DevLynx)
Si moins de monde enculait le système, alors celui ci aurait plus de mal à nous sortir de si grosses merdes !
"L'erreur humaine est humaine"©Nil (2006) // topics/6238-moved-jamais-jaurais-pense-faire-ca
(Wow, ce remontage tongue )

Les SIGB connaissent bien ça, et il y a des tables d'homonymie pour à peu près tout (un roman peut être divisé en plusieurs tommes, ou faire partie d'un volume avec plusieurs romans ; il peut exister en différentes versions, avec des spécificités [de langue, de typographie [braille, grands caractères, édition augmentée...] ; mais le plus "amusant" concerne les noms des auteurs/compositeurs, comme Tchaïkovsky/Чайкoвский ou Szostakowicz/Chostakovitch/Шостакович/Shostakovich/... en sachant qu'en fonction des périodes, on telle ou telle graphie sera plébiscitée).
Heureusement, il existe des notices d'autorité qui permettent de limiter la casse (et grâce à Internet, on peut interroger de façon normalisée ces notices de façon asynchrones ou synchrones). En France, les notices d'autorité pour les auteurs et les ouvrages sont propagées par le SUDOC et la BNF, pour une remontée internationale grâce au VIAF.

Malheureusement, je ne crois pas que de telles bases (par exemple une base de données internationale avec toutes les références d'écrous, les correspondances entre les fabricants, les spécificités - filetage, diamètre, tête, longueur, angle...).
avatar