From 4567285ec4415ef6aff5d4dafb48a0c88abe2153 Mon Sep 17 00:00:00 2001 From: Nemo D'ACREMONT Date: Mon, 2 Dec 2024 14:57:16 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20La=20liste=20des=20membres=20qui=20ont?= =?UTF-8?q?=20propos=C3=A9=20le=20plus=20de=20mod=C3=A8les?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 11 +++--- PostgreSQL/src/create.sql | 17 +++++++++ PostgreSQL/src/select.sql | 3 +- back-end/src/controllers/member.controller.ts | 6 ++++ back-end/src/routes/member.route.ts | 4 ++- back-end/src/services/member.service.ts | 31 ++++++++++++++-- back-end/src/templates/members.ejs | 2 +- back-end/src/templates/membersAndNbModels.ejs | 35 +++++++++++++++++++ back-end/src/templates/rendu.ejs | 4 +++ back-end/src/types/member.ts | 3 +- 10 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 back-end/src/templates/membersAndNbModels.ejs diff --git a/Makefile b/Makefile index 6c510ad..5666832 100644 --- a/Makefile +++ b/Makefile @@ -6,10 +6,10 @@ all: build build: dev dev: $(DIR_BACK)/.env - . $(DIR_BACK)/.env && docker-compose -f docker-compose.dev.yml up + . $(DIR_BACK)/.env && docker compose -f docker-compose.dev.yml up prod: - . $(DIR_BACK)/.env && docker-compose -f docker-compose.prod.yml up + . $(DIR_BACK)/.env && docker compose -f docker-compose.prod.yml up $(DIR_BACK)/.env: $(DIR_BACK)/.env.example cp $(DIR_BACK)/.env.example $(DIR_BACK)/.env @@ -17,11 +17,12 @@ $(DIR_BACK)/.env: $(DIR_BACK)/.env.example clean: ${RM} $(DIR_BACK)/.env - ${RM} -r dev-db || true + # Delete the db volume + sudo ${RM} -r dev-db || true cd $(DIR_SQL) && make clean - docker compose -f docker-compose.dev.yml down --rmi local -v --remove-orphans || true + docker compose -f docker compose.dev.yml down --rmi local -v --remove-orphans || true clean_prod: clean - docker compose -f docker-compose.prod.yml down --rmi local -v --remove-orphans || true + docker compose -f docker compose.prod.yml down --rmi local -v --remove-orphans || true .PHONY: clean all prepare_dev build clean_prod diff --git a/PostgreSQL/src/create.sql b/PostgreSQL/src/create.sql index d30ff45..3a1a9e7 100644 --- a/PostgreSQL/src/create.sql +++ b/PostgreSQL/src/create.sql @@ -367,3 +367,20 @@ ALTER TABLE varier -- ============================================================================ +-- Nombre de piece par boite +CREATE OR REPLACE VIEW nb_piece_par_boite AS +( + SELECT id_boite, SUM(quantite_contenir) as nb_piece + FROM contenir + GROUP BY id_boite +); + +-- nombre de modele proposés par membre +CREATE OR REPLACE VIEW nb_modele_par_membre AS +( + SELECT membres.*, COUNT(*) as nb_modele + FROM modeles + JOIN membres ON membres.id_membre = modeles.id_membre + WHERE membres.id_membre IS NOT NULL + GROUP BY membres.id_membre +); diff --git a/PostgreSQL/src/select.sql b/PostgreSQL/src/select.sql index 72a339a..9d18882 100644 --- a/PostgreSQL/src/select.sql +++ b/PostgreSQL/src/select.sql @@ -59,12 +59,11 @@ CREATE OR REPLACE VIEW nb_modele_par_membre AS -- La liste des membres qui ont proposé le plus de modèles. SELECT id_membre, nb_modele FROM nb_modele_par_membre -ORDER BY nb_boite +ORDER BY nb_modele DESC LIMIT 5 ; --- La liste des modèles, classés par note moyenne descendante. SELECT id_modele, AVG(note_noter) as note_moyenne FROM noter GROUP BY id_modele diff --git a/back-end/src/controllers/member.controller.ts b/back-end/src/controllers/member.controller.ts index b47db29..bf2f25f 100644 --- a/back-end/src/controllers/member.controller.ts +++ b/back-end/src/controllers/member.controller.ts @@ -19,6 +19,11 @@ const allMembers: RequestHandler = async (_req, res) => { res.render('members.ejs', { members }); }; +const allMembersByNbModels: RequestHandler = async (_req, res) => { + const members = await memberService.getAllMembersByNbModels(); + res.render('membersAndNbModels.ejs', { members }); +}; + const memberById: RequestHandler<{ id: string; }> = async (req, res) => { const id = parseInt(req.params.id); const memberEither = await memberService.getMember(id); @@ -37,6 +42,7 @@ const memberController = { memberByName, memberById, allMembers, + allMembersByNbModels }; export default memberController; diff --git a/back-end/src/routes/member.route.ts b/back-end/src/routes/member.route.ts index f5d52ab..eefdece 100644 --- a/back-end/src/routes/member.route.ts +++ b/back-end/src/routes/member.route.ts @@ -5,7 +5,9 @@ const router = express.Router(); router.get("/", memberController.allMembers); -router.get("/:name", memberController.memberByName); +router.get("/bynbmodels", memberController.allMembersByNbModels); + +router.get("/byname/:name", memberController.memberByName); router.get("/byid/:id", memberController.memberById); diff --git a/back-end/src/services/member.service.ts b/back-end/src/services/member.service.ts index f564c2d..8d718cf 100644 --- a/back-end/src/services/member.service.ts +++ b/back-end/src/services/member.service.ts @@ -1,5 +1,5 @@ import { new_client } from '../db/db_client'; -import { Member, User } from '../types/member'; +import { Member, MemberAndNbModels, User } from '../types/member'; import { Either, eitherLeft, eitherRight } from '../utils/utils'; type DBMembre = { @@ -8,7 +8,14 @@ type DBMembre = { mdp_membre: string; }; -function db2member(data: DBMembre) { +type DBMembreAndNbModels = { + id_membre: number; + nom_membre: string; + mdp_membre: string; + nb_modele: number; +}; + +function db2member(data: DBMembre): Member { const member: Member = { id_member: data.id_membre, name: data.nom_membre, @@ -17,6 +24,17 @@ function db2member(data: DBMembre) { return member; } +function db2memberAndNbModels(data: DBMembreAndNbModels): MemberAndNbModels { + const memberAndNbModels: MemberAndNbModels = { + id_member: data.id_membre, + name: data.nom_membre, + password: data.mdp_membre, + nb_models: data.nb_modele, + }; + + return memberAndNbModels; +} + const getMember = async (idOrName: number | string): Promise> => { const client = new_client(); await client.connect(); @@ -44,6 +62,14 @@ const getAllMembers = async () => { return res.rows.map(db2member); } +const getAllMembersByNbModels = async () => { + const client = new_client(); + await client.connect(); + const res = await client.query("SELECT * FROM nb_modele_par_membre ORDER BY nb_modele DESC LIMIT 5;"); + await client.end(); + return res.rows.map(db2memberAndNbModels); +} + const createMember = async (name: string, passwd: string): Promise> => { const gettingMember = await getMember(name); if (!gettingMember.hasRight) { @@ -75,6 +101,7 @@ const memberService = { getDefaultMember, userAdapter, getAllMembers, + getAllMembersByNbModels, }; export default memberService; diff --git a/back-end/src/templates/members.ejs b/back-end/src/templates/members.ejs index b8f26d3..049a9d8 100644 --- a/back-end/src/templates/members.ejs +++ b/back-end/src/templates/members.ejs @@ -19,7 +19,7 @@
    <% members.forEach(function(member) { %>
  • - + <%=member.name%>
  • diff --git a/back-end/src/templates/membersAndNbModels.ejs b/back-end/src/templates/membersAndNbModels.ejs new file mode 100644 index 0000000..a1168c5 --- /dev/null +++ b/back-end/src/templates/membersAndNbModels.ejs @@ -0,0 +1,35 @@ + + + + + + + Liste des membres qui ont proposés le plus de modèles + + + <%- include('partials/links.ejs') %> + + + <%- include('partials/header.ejs') %> + +

    + Liste des membres qui ont proposés le plus de modèles +

    + + + + + + diff --git a/back-end/src/templates/rendu.ejs b/back-end/src/templates/rendu.ejs index aeb247a..3218a55 100644 --- a/back-end/src/templates/rendu.ejs +++ b/back-end/src/templates/rendu.ejs @@ -19,6 +19,10 @@

    Liste des boites ayant moins de 5 ans

    + + +

    Liste des membres qui ont proposés le plus de modèles

    +
    diff --git a/back-end/src/types/member.ts b/back-end/src/types/member.ts index 53b898b..4c01fb8 100644 --- a/back-end/src/types/member.ts +++ b/back-end/src/types/member.ts @@ -4,5 +4,6 @@ type User = { } type Member = User & { password: string }; +type MemberAndNbModels = User & { password: string } & { nb_models: number }; -export { Member, User }; +export { Member, User, MemberAndNbModels };