From 954c1e7e102beca6048d1685dc104a600405c8d8 Mon Sep 17 00:00:00 2001 From: Doug Le Tough Date: Sat, 21 Oct 2017 10:44:11 +0200 Subject: [PATCH] "liste + delete composants" --- static/images/edit.png | Bin 0 -> 374 bytes static/images/refresh.png | Bin 0 -> 312 bytes static/images/trash.png | Bin 0 -> 327 bytes static/scripts/tetalab.js | 59 ++++++++++ static/style/style.css | 189 +++++++++++++++++++++++++++++++ stock.sql | 94 ++++++++++++--- templates/componant.html | 132 +++++++++++++++++++++ templates/componants.html | 52 +++++++++ templates/index.html | 5 +- templates/users.html | 56 +++++++++ stock_tetalab.py => tetastock.py | 119 ++++++++++++++++--- 11 files changed, 673 insertions(+), 33 deletions(-) create mode 100644 static/images/edit.png create mode 100644 static/images/refresh.png create mode 100644 static/images/trash.png create mode 100644 templates/componant.html create mode 100644 templates/componants.html create mode 100644 templates/users.html rename stock_tetalab.py => tetastock.py (58%) diff --git a/static/images/edit.png b/static/images/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..49e0b4fc295415a7a3a386f6c6e9b1064f688c23 GIT binary patch literal 374 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPtmoPUcbF5#xD+2=~v!{z=h{frtmuMYZs+LuR+KF19MK>7NIj_@LdNE{P$&+`|_N#by_FwP2 zW3?=Ce~ju0>56j`UMIZU@tV_=@A-uO!j|`XjruVO`i^aP=X|!cdBm%}@c!i^Q&t(p z?%@8b7xZM?0Ue`_Z#|_q>oo?>ICdw;04l`Fa+edpj=3s=l@PCe4_3s{V_u4!hYUk&3SO zrzR~7o5vh|bpGx*4R)T(%k}-{g4cUyJ;j(JpB>RzKo2o^y85}Sb4q9e E08h?%`2YX_ literal 0 HcmV?d00001 diff --git a/static/images/trash.png b/static/images/trash.png new file mode 100644 index 0000000000000000000000000000000000000000..ed387d96ba06a91a6dd883bace9f97c89957d72d GIT binary patch literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPtmoPUcf5?y1c|f5no-U3d7N_4{w)bjw6kz>ufBFw` zo<+Gf4Xy4QE=yN5nCxs?`#|$j6|;WA>hudv0?dwEI$CG3T)bhE`gf9Bj!uoin+?W$ zYB!%r7CZeSIjY-w%d4~8mfAT9?7Jlrzopr05-9H#sB~S literal 0 HcmV?d00001 diff --git a/static/scripts/tetalab.js b/static/scripts/tetalab.js index e69de29..f706fc8 100644 --- a/static/scripts/tetalab.js +++ b/static/scripts/tetalab.js @@ -0,0 +1,59 @@ +var red = "#FF0000"; +var green = "#00FF00"; +var light_red = "#FCD5DC"; +var light_green = "#D5FCD8"; +var base_bg = "#FEFEFE"; +var base_border = "#555555"; + +function update_componant(obj, componant_id, type) { + if (type == 'numeric') { + if (isNaN(obj.value)) { + alert('Valeur numérique uniquement'); + return; + } + } + + var xhttp = new XMLHttpRequest(); + xhttp.onerror = function(){ + obj.style.backgroundColor = light_red; + setTimeout( function() { + obj.style.backgroundColor = base_bg; + } + , 2000); + }; + + xhttp.onload = function(){ + var bg_color = light_red; + var border_color = red; + if (xhttp.status == 200) { + var response = xhttp.responseText; + if (response == 'OK'){ + bg_color = light_green; + border_color = base_border; + } + } + obj.style.backgroundColor = bg_color; + obj.style.borderColor = border_color; + setTimeout( function() { + obj.style.backgroundColor = base_bg; + } + , 2000); + }; + + xhttp.onreadystatechange = function() { + if (xhttp.readyState == 4 && xhttp.status == 200) { + var reponse = xhttp.responseText; + if (xhttp.responseText != 'OK') + obj.style.backgroundColor = light_red; + } + }; + + xhttp.open('POST', '/componant/update/'+componant_id, true); + xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + xhttp.send('field='+obj.id+'&value='+obj.value); +} + +function confirm_delete() { + var msg="La suppression est définitive \net n'est pas autorisée si le \ncomposant fait partie d'un Kit.\n\nConfirmer ?"; + return confirm(msg) +} diff --git a/static/style/style.css b/static/style/style.css index 10d2f85..d0f1a42 100644 --- a/static/style/style.css +++ b/static/style/style.css @@ -184,6 +184,195 @@ div.footer { text-align: center; } +/* *********************************** + * Tables +*********************************** */ + +.border_left { + border-left-width: 1px; + border-left-style: solid; +} + +.border_right { + border-right-width: 1px; + border-right-style: solid; +} + +div.block { + overflow: hidden; + width: 1000px; + border-top-style: solid; + border-top-width: 1px; + height: 20px; +/* + background-color: red; +*/ +} + +div.inner{ + overflow: hidden; + float: center; + height: 20px; +} + +div.pages_nav_bar { + overflow: hidden; + width: 1000px; + border-top-style: solid; + border-top-width: 1px; + height: 20px; + text-align: right; + padding-top: 10px; +} + +div.block text{ + width: 200px; + float: left; + text-align: left; + padding: 0 4px 0 4px; +} + +div.block text.num{ + width: 200px; + float: left; + padding: 0 4px 0 4px; + text-align: right; +} + +div.inner text.edit, div.block text.edit { + background: url(../images/edit.png); +} + +div.inner text.trash { + background: url(../images/trash.png); +} + +div.block text.refresh { + background: url(../images/refresh.png); +} + +div.inner text.edit:hover, div.inner text.trash:hover, div.block text.refresh:hover { + background-color: #FFB387; + cursor: pointer; +} + +div.inner text.edit { + width: 16px; + float:left; + height: 16px; + margin: 2px 0px 0px 20px; + border-radius: 2px; + background-repeat: no-repeat; +} + +div.inner text.trash, div.inner text.edit, div.block text.refresh { + width: 8px; + float:left; + height: 16px; + margin: 2px 0px 0px 20px; + border-radius: 2px; + background-repeat: no-repeat; +} + +div.even { + background-color: #FFFFFF; +} + +div.odd { + background-color: #E5E5E5; +} + +div.block label { + width: 200px; + display: block; + float: left; + text-align: center; + font-weight: bold; + background-color: #FF5D00; +} + +div.block label:hover { + cursor: pointer; +} + +div.block .input{ + margin-left:4px; + float:left; +} + + +div.action_bar { + display: inline-block; + width: 50px; + height: 32px; +} + + +span.prev_page, span.next_page { + color: #FF5D00; + font-weight: bold; + font-size: 12px; +} + +span.prev_page:hover, span.next_page:hover { + color: #FFFFFF; + background-color: #FF5D00; + cursor: pointer; +} + +span.page_num { + font-size: 12px; +} + +/* *********************************** + * Editables +*********************************** */ + +div.no_border { + border-style: none; + border-width: 0px; +} + +div.margin_bottom { + margin-bottom: 4px; +} + +div.block label.editable { + height: 18px; + text-align: left; + padding: 0 4px 0 4px; +} + +div.block text.editable { + width: 200px; + float: left; + padding: 0 4px 0 4px; + margin-left: 4px; + text-align: right; + background-color: #FFFFFF; + border-style: solid; + border-width: 1px; + height: 18px; +} + +div.block select, div.block input { + width: 310px; + float: left; + padding: 0 4px 0 4px; + margin-left: 4px; + text-align: right; + background-color: #FFFFFF; + border-style: solid; + border-width: 1px; + border-color: #555555; + color: #555555; + height: 18px; +} + +div.block input { + height: 17px; + width: 300px; +} /* *********************************** * Classes génériques diff --git a/stock.sql b/stock.sql index 1786748..ac11f69 100644 --- a/stock.sql +++ b/stock.sql @@ -1,43 +1,109 @@ -CREATE TABLE Stock_users ( +drop database tetalab_stock; +create database tetalab_stock; + +\c tetalab_stock; + +CREATE TABLE stock_users ( id serial primary key, mail text not NULL, password text not NULL, name text not NULL ); - -CREATE TABLE Stock_kits ( +CREATE TABLE stock_kits ( id serial primary key, name text not NULL, description text not NULL ); - -CREATE TABLE Stock_providers ( +CREATE TABLE stock_providers ( id serial primary key, + name text not NULL, address text not NULL, mail text not NULL, url text not NULL, comment text not NULL ); - -CREATE TABLE Stock_componants ( +CREATE TABLE stock_componants ( id serial primary key, - name text not NULL, - description text not NULL, + reference varchar(20) unique not NULL, + designation varchar(50) not NULL, last_price NUMERIC not NULL, mean_price NUMERIC not NULL, quantity NUMERIC not NULL, min_quantity NUMERIC not NULL, - place text not NULL, - provider_id integer REFERENCES Stock_providers(id) + place varchar(15) not NULL, + provider_id integer REFERENCES stock_providers(id) ); - -CREATE TABLE Stock_kit_compositions ( +CREATE TABLE stock_kit_compositions ( id serial primary key, kit_id integer REFERENCES Stock_kits(id), - componant_id integer REFERENCES Stock_componants(id), + componant_id integer REFERENCES stock_componants(id), quantity integer not NULL ); + +alter table stock_users owner to tetalab_user; +alter table stock_kits owner to tetalab_user; +alter table stock_providers owner to tetalab_user; +alter table stock_componants owner to tetalab_user; +alter table stock_kit_compositions owner to tetalab_user; +alter database tetalab_stock owner to tetalab_user; + + +insert into stock_providers (name, address, mail, url, comment) + values ('China Elec Co', 'Beijing', 'sales@chinaelecco.cc', 'https://chinaelecco', 'Pas cher, mais...'); + +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-01', 'Resistance 10KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Lor-01', '1 Lorem ipsum dolor sit ametconsectetur adipiscing', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-02', 'Resistance 11KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-03', 'Resistance 12KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-04', 'Resistance 13KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-05', 'Resistance 14KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Lor-02', '2 Lorem ipsum dolor sit ametconsectetur adipiscing', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-06', 'Resistance 15KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-07', 'Resistance 16KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-08', 'Resistance 17KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-09', 'Resistance 18KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Lor-03', '3 Lorem ipsum dolor sit ametconsectetur adipiscing', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-10', 'Resistance 19KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-11', 'Resistance 20KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-12', 'Resistance 21KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-13', 'Resistance 22KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Lor-04', '4 Lorem ipsum dolor sit ametconsectetur adipiscing', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-14', 'Resistance 23KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-15', 'Resistance 24KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-16', 'Resistance 25KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-17', 'Resistance 26KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Lor-05', '5 Lorem ipsum dolor sit ametconsectetur adipiscing', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-18', 'Resistance 27KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-19', 'Resistance 28KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); +insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) + values ('Res-20', 'Resistance 29KΩ', 13.34, 12.42, 73, 0, 'B 43', 1); + +\c postgres; diff --git a/templates/componant.html b/templates/componant.html new file mode 100644 index 0000000..d5f798c --- /dev/null +++ b/templates/componant.html @@ -0,0 +1,132 @@ +{% extends "index.html" %} +{% block title %}Éditer un composant{% endblock %} + {% block top_menu %} + Nouveau composant + Rechercher un composant + Éditer un composant + Entrée de stock + Sortie de stock + {% endblock %} + + {% block left_menu %} +
+ Accueil +
+
+ Composants +
+
+ Kits +
+
+ Fournisseurs +
+ {% endblock %} + + {% block content %} +

Note:

+

Cette page vous permet de modifier directement un composant.

+

À moins de vouloir corriger une erreur de saisie, ou de saisir un inventaire vous ne devez + PAS modifier directement + les quantités d'un composant.

+

Cliquez sur les liens suivants pour saisir des entrées + ou sorties de stock.

+

Composant:

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ {% endblock %} diff --git a/templates/componants.html b/templates/componants.html new file mode 100644 index 0000000..db43549 --- /dev/null +++ b/templates/componants.html @@ -0,0 +1,52 @@ +{% extends "index.html" %} +{% block title %}Liste des composants{% endblock %} + {% block top_menu %} + Nouveau composant + Rechercher un composant + Entrée de stock + Sortie de stock + {% endblock %} + + {% block left_menu %} +
+ Accueil +
+
+ Composants +
+
+ Kits +
+
+ Fournisseurs +
+ {% endblock %} + + {% block content %} +

Liste des composants

+
+ + + + + +
+ {% set row_class = cycler('odd', 'even') %} + {% for componant in componants %} +
+ {{ componant.reference }} + {{ componant.designation }} + {{ componant.quantity }} + {{ componant.place }} +
+ + +
+
+ {% endfor %} +
+ < + {{ page }} / {{ page_count }} + > +
+ {% endblock %} diff --git a/templates/index.html b/templates/index.html index f0a0f24..6977762 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,8 +1,7 @@ - - Stock Tetalab - {% block title %}Accueil{% endblock %} + Tetastock - {% block title %}Accueil{% endblock %} @@ -12,7 +11,7 @@
{% block top_menu %} Accueil {% endblock %} diff --git a/templates/users.html b/templates/users.html new file mode 100644 index 0000000..f0a0f24 --- /dev/null +++ b/templates/users.html @@ -0,0 +1,56 @@ + + + + + Stock Tetalab - {% block title %}Accueil{% endblock %} + + + + + + +
+
+ +
+ {% block top_menu %} Accueil {% endblock %} +
+
+
+ {% block left_menu %} +
+ Accueil +
+
+ Composants +
+
+ Kits +
+
+ Fournisseurs +
{% endblock %} +
+
+ {% block content %} +

Gestion du stock

+

Ceci est l'outil de gestion de stock du Tetalab.

+

Cet outil vous permet: +

    +
  • De gérer la liste des composants électroniques en possession du Tetalab
  • +
  • De gérer la liste des fournisseurs de composants
  • +
  • De gérer la liste des kits de montage
  • +
+

+ {% endblock %} +
+
+ +
+
+ + diff --git a/stock_tetalab.py b/tetastock.py similarity index 58% rename from stock_tetalab.py rename to tetastock.py index 2e722e5..e5f09ae 100755 --- a/stock_tetalab.py +++ b/tetastock.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 +import math from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash from flask_sqlalchemy import SQLAlchemy @@ -19,8 +20,8 @@ class Stock_users(db.Model): class Stock_componants(db.Model): id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.Text, nullable=False) - description = db.Column(db.Text, nullable=False) + reference = db.Column(db.Text, nullable=False) + designation = db.Column(db.Text, nullable=False) last_price = db.Column(db.Float) mean_price = db.Column(db.Float) quantity = db.Column(db.Integer) @@ -31,7 +32,7 @@ class Stock_componants(db.Model): class Stock_providers(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Text, nullable=False) - postal_address = db.Column(db.Text) + address = db.Column(db.Text) url = db.Column(db.Text) comment = db.Column(db.Text) @@ -58,32 +59,107 @@ def authenticate(): ######################################################################## # Componants ######################################################################## -@app.route('/componants') +@app.route('/componants', methods=['GET', 'POST']) def get_componants(): - return render_template('wip.html') + limit = 16 + offset = 0 + sort = 'reference' + order = 'asc' + norder = 'desc' + print '*', sort + if len(request.args): + if 'offset' in request.args: + offset = request.args['offset'] + if 's' in request.args: + sort = request.args['s'] + if 'o' in request.args: + order = request.args['o'] + try: + offset = int(offset) + except ValueError: + offset = 0 + row_count = db.session.query(Stock_componants.id).count() + page_count = int(math.ceil(row_count / float(limit))) + page = int(math.ceil(float(offset + 1) / float(limit))) + nexthop = offset + limit + if nexthop > row_count - 1: + nexthop = offset + prevhop = offset - limit + if prevhop < 0: + prevhop = 0 + if order == 'asc': + norder = 'desc' + componants = Stock_componants.query.order_by(getattr(Stock_componants, sort)).offset(offset).limit(limit).all() + else: + norder = 'asc' + componants = Stock_componants.query.order_by(getattr(Stock_componants, sort).desc()).offset(offset).limit(limit).all() + return render_template('componants.html', + componants=componants, + offset=offset, + nexthop=nexthop, + prevhop=prevhop, + page_count=page_count, + page=page, + sort=sort, + order=order, + norder=norder) @app.route('/componants/') def get_componant(componant_id): - return render_template('wip.html') - -@app.route('/componants/add/') -def add_componant(componant_id): - return render_template('wip.html') - -@app.route('/componants/edit/') -def edit_componant(componant_id): - return render_template('wip.html') + try: + componant_id = int(componant_id) + except ValueError as e: + return render_template('error.html'), 404 + componant = Stock_componants.query.filter_by(id=componant_id).first() + if componant: + providers = Stock_providers.query.order_by(Stock_providers.name).all() + provider = componant.provider_id + provider = Stock_providers.query.filter_by(id=provider).first() + return render_template('componant.html', componant=componant, providers=providers, provider=provider) + return render_template('error.html'), 404 @app.route('/componants/delete/') def delete_componant(componant_id): + try: + componant_id = int(componant_id) + except ValueError as e: + return render_template('error.html'), 404 + Stock_componants.query.filter_by(id=componant_id).delete() + db.session.commit() + return get_componants() + +@app.route('/componants/new/') +def add_componant(componant_id): return render_template('wip.html') +@app.route('/componants/in/') +def in_componants(): + return render_template('wip.html') + +@app.route('/componants/out/') +def out_componants(): + return render_template('wip.html') + +@app.route('/componant/update/', methods=['POST']) +def update_componants(componant_id): + field = request.form['field'] + value = request.form['value'] + if field and value: + try: + componant = Stock_componants.query.filter_by(id=componant_id).first() + setattr(componant, field, value) + db.session.commit() + except Exception as e: + return 'KO' + return 'OK' + + ######################################################################## # Kits ######################################################################## @app.route('/kits') def get_kits(): - return render_template('wip.html') + return render_template('kits.html') @app.route('/kits/') def get_kit(kit_id): @@ -101,12 +177,16 @@ def edit_kit(kit_id): def delete_kit(kit_id): return render_template('wip.html') +@app.route('/kits/search') +def search_kits(): + return render_template('wip.html') + ######################################################################## # Providers ######################################################################## @app.route('/providers') def get_providers(): - return render_template('wip.html') + return render_template('providers.html') @app.route('/providers/') def get_provider(provider_id): @@ -124,6 +204,10 @@ def edit_provider(provider_id): def delete_provider(provider_id): return render_template('wip.html') +@app.route('/providers/search') +def search_providers(): + return render_template('wip.html') + ######################################################################## # Users ######################################################################## @@ -147,6 +231,9 @@ def edit_user(user_id): def delete_user(user_id): return render_template('wip.html') +@app.route('/users/search') +def search_users(): + return render_template('wip.html') ##############################################