Browse Source

"liste + delete composants"

master
Doug Le Tough 4 years ago
parent
commit
954c1e7e10
11 changed files with 670 additions and 30 deletions
  1. BIN
      static/images/edit.png
  2. BIN
      static/images/refresh.png
  3. BIN
      static/images/trash.png
  4. +59
    -0
      static/scripts/tetalab.js
  5. +189
    -0
      static/style/style.css
  6. +80
    -14
      stock.sql
  7. +132
    -0
      templates/componant.html
  8. +52
    -0
      templates/componants.html
  9. +2
    -3
      templates/index.html
  10. +56
    -0
      templates/users.html
  11. +100
    -13
      tetastock.py

BIN
static/images/edit.png View File

Before After
Width: 16  |  Height: 16  |  Size: 374 B

BIN
static/images/refresh.png View File

Before After
Width: 16  |  Height: 16  |  Size: 312 B

BIN
static/images/trash.png View File

Before After
Width: 16  |  Height: 16  |  Size: 327 B

+ 59
- 0
static/scripts/tetalab.js View File

@ -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)
}

+ 189
- 0
static/style/style.css View File

@ -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


+ 80
- 14
stock.sql View File

@ -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;

+ 132
- 0
templates/componant.html View File

@ -0,0 +1,132 @@
{% extends "index.html" %}
{% block title %}Éditer un composant{% endblock %}
{% block top_menu %}
<span class='top_menu_item' onclick='javascript:document.location="/componants/new";'>Nouveau composant</span>
<span class='top_menu_item' onclick='javascript:document.location="/componants/search";'>Rechercher un composant</span>
<span class='top_menu_item_selected' onclick='javascript:document.location="/componants/search";'>Éditer un composant</span>
<span class='top_menu_item' onclick='javascript:document.location="/componants/in";'>Entrée de stock</span>
<span class='top_menu_item' onclick='javascript:document.location="/componants/out";'>Sortie de stock</span>
{% endblock %}
{% block left_menu %}
<div class='left_menu_item' onclick='javascript:document.location="/";'>
Accueil
</div>
<div class='left_menu_item_selected' onclick='javascript:document.location="/componants";'>
Composants
</div>
<div class='left_menu_item' onclick='javascript:document.location="/kits";'>
Kits
</div>
<div class='left_menu_item' onclick='javascript:document.location="/providers";'>
Fournisseurs
</div>
{% endblock %}
{% block content %}
<h3>Note:</h3>
<p>Cette page vous permet de modifier directement un composant.</p>
<p>À moins de vouloir corriger une erreur de saisie, ou de saisir un inventaire vous ne devez
<strong>PAS</strong> modifier directement
les quantités d'un composant.</p>
<p>Cliquez sur les liens suivants pour saisir des <a href='/componant/in/{{ componant.id }}'>entrées</a>
ou <a href='/componant/out/{{ componant.id }}'>sorties</a> de stock.</p>
<h3>Composant:</h3>
<div class='block margin_bottom no_border'>
<label class='editable'>Référence (unique)</label>
<input
id='reference'
type='text'
class='editable'
onchange='javascript:update_componant(this, {{ componant.id }}, "text");'
maxlength='20'
title='Référence interne unique (max. 20)'
placeholder='Référence interne unique (max. 20)'
value='{{ componant.reference }}' />
</div>
<div class='block margin_bottom no_border'>
<label class='editable'>Désignation</label>
<input
id='designation'
type='text'
class='editable'
onchange='javascript:update_componant(this, {{ componant.id }}, "text");'
maxlength='50'
title='Désignation (max. 50)'
placeholder='Désignation (max. 50)'
value='{{ componant.designation }}' />
</div>
<div class='block margin_bottom no_border'>
<label class='editable'>Dernier prix d'achat</label>
<input
id='last_price'
type='text'
class='editable'
onchange='javascript:update_componant(this, {{ componant.id }}, "numeric");'
maxlength='15'
title="Dernier prix d'achat"
placeholder="Dernier prix d'achat"
value='{{ componant.last_price }}' />
</div>
<div class='block margin_bottom no_border'>
<label class='editable'>Coût d'achat moyen pondéré</label>
<input
id='mean_price'
type='text'
class='editable'
maxlength='15'
title='CMP (non éditable)'
readonly value='{{ componant.mean_price }}' />
</div>
<div class='block margin_bottom no_border'>
<label class='editable'>Quantité</label>
<input
id='quantity'
type='text'
class='editable'
onchange='javascript:update_componant(this, {{ componant.id }}, "numeric");'
maxlength='15'
title='Quantité'
placeholder='Quantité'
value='{{ componant.quantity }}' />
</div>
<div class='block margin_bottom no_border'>
<label class='editable'>Quantité minimum</label>
<input
id='min_quantity'
type='text'
class='editable'
onchange='javascript:update_componant(this, {{ componant.id }}, "numeric");'
maxlength='15'
title='Quantité minimum'
placeholder='Quantité minimum'
value='{{ componant.min_quantity }}' />
</div>
<div class='block margin_bottom no_border'>
<label class='editable'>Emplacement</label>
<input
id='place'
type='text'
class='editable'
onchange='javascript:update_componant(this, {{ componant.id }}, "text");'
maxlength='15'
title='Emplacement (max. 15)'
placeholder='Emplacement (max. 15)'
value='{{ componant.place }}' />
</div>
<div class='block margin_bottom no_border'>
<label class='editable'>Fournisseur</label>
<select
id='provider_id'
onchange='javascript:update_componant(this, {{ componant.id }}, "numeric");'
title='Fournisseur'>
{% for prov in providers %}
{% set option_selected = '' %}
{% if prov.id == provider.id %}
{% set option_selected = 'selected="selected"' %}
{% endif %}
<option {{ option_selected }} value='prov.id'>{{ prov.name }}</option>
{% endfor %}
</select>
</div>
{% endblock %}

+ 52
- 0
templates/componants.html View File

@ -0,0 +1,52 @@
{% extends "index.html" %}
{% block title %}Liste des composants{% endblock %}
{% block top_menu %}
<span class='top_menu_item' onclick='javascript:document.location="/componants/new";'>Nouveau composant</span>
<span class='top_menu_item' onclick='javascript:document.location="/componants/search";'>Rechercher un composant</span>
<span class='top_menu_item' onclick='javascript:document.location="/componants/in";'>Entrée de stock</span>
<span class='top_menu_item' onclick='javascript:document.location="/componants/out";'>Sortie de stock</span>
{% endblock %}
{% block left_menu %}
<div class='left_menu_item' onclick='javascript:document.location="/";'>
Accueil
</div>
<div class='left_menu_item_selected' onclick='javascript:document.location="/componants";'>
Composants
</div>
<div class='left_menu_item' onclick='javascript:document.location="/kits";'>
Kits
</div>
<div class='left_menu_item' onclick='javascript:document.location="/providers";'>
Fournisseurs
</div>
{% endblock %}
{% block content %}
<h3>Liste des composants</h3>
<div class='block' style='border-top-style: none;'>
<label onclick='document.location="/componants?offset={{ offset }}&s=reference&o={{ norder }}";'>Référence</label>
<label onclick='document.location="/componants?offset={{ offset }}&s=designation&o={{ norder }}";' class='border_left' style='width: 440px;'>Désignation</label>
<label onclick='document.location="/componants?offset={{ offset }}&s=quantity&o={{ norder }}";' class='border_left' style='width: 100px;'>Quantité</label>
<label onclick='document.location="/componants?offset={{ offset }}&s=place&o={{ norder }}";' class='border_right border_left' style='width: 160px;'>Emplacement</label>
<label style='width: 95px; cursor: default;'>Action</label>
</div>
{% set row_class = cycler('odd', 'even') %}
{% for componant in componants %}
<div class='block {{ row_class.next() }}'>
<text style='width: 192px;'>{{ componant.reference }}</text>
<text class='border_left' style='width: 432px;'>{{ componant.designation }}</text>
<text class='num border_left' style='width: 92px;'>{{ componant.quantity }}</text>
<text class='num border_right border_left' style='width: 152px;'>{{ componant.place }}</text>
<div class='inner' style='width: 95px;'>
<text class='edit' onclick='javascript:document.location="/componants/{{ componant.id }}"'></text>
<text class='trash' onclick='javascript:confirm_delete()?document.location="/componants/delete/{{ componant.id }}":false;'></text>
</div>
</div>
{% endfor %}
<div class='pages_nav_bar'>
<text><span class='prev_page' onclick='javascript:document.location="/componants?offset={{ prevhop }}&s={{ sort }}&o={{ order }}"'><</span></text>
<text><span class='page_num'>{{ page }} / {{ page_count }}</span></text>
<text><span class='next_page' onclick='javascript:document.location="/componants?offset={{ nexthop }}&s={{ sort }}&o={{ order }}"'>></span></text>
</div>
{% endblock %}

+ 2
- 3
templates/index.html View File

@ -1,8 +1,7 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
<head>
<meta name="generator" content="HTML Tidy for HTML5 for Linux version 5.5.21" />
<title>Stock Tetalab - {% block title %}Accueil{% endblock %}</title>
<title>Tetastock - {% block title %}Accueil{% endblock %}</title>
<meta name="viewport" content="initial-scale=1.0" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="/static/style/style.css" />
@ -12,7 +11,7 @@
<div class='main_wrapper'>
<div class='center'>
<div class='banner' title='Stock Tetalab'>
Stock Tetalab
Tetastock
</div>
<div class='top_menu'>
{% block top_menu %} <span class='top_menu_item_selected' onclick='javascript:document.location="./";'>Accueil</span> {% endblock %}


+ 56
- 0
templates/users.html View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
<head>
<meta name="generator" content="HTML Tidy for HTML5 for Linux version 5.5.21" />
<title>Stock Tetalab - {% block title %}Accueil{% endblock %}</title>
<meta name="viewport" content="initial-scale=1.0" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="/static/style/style.css" />
<script type="text/javascript" src="/static/scripts/tetalab.js"></script>
</head>
<body>
<div class='main_wrapper'>
<div class='center'>
<div class='banner' title='Stock Tetalab'>
Stock Tetalab
</div>
<div class='top_menu'>
{% block top_menu %} <span class='top_menu_item_selected' onclick='javascript:document.location="./";'>Accueil</span> {% endblock %}
</div>
<div class='content_wrapper'>
<div class='left_menu'>
{% block left_menu %}
<div class='left_menu_item_selected' onclick='javascript:document.location="/";'>
Accueil
</div>
<div class='left_menu_item' onclick='javascript:document.location="/componants";'>
Composants
</div>
<div class='left_menu_item' onclick='javascript:document.location="/kits";'>
Kits
</div>
<div class='left_menu_item' onclick='javascript:document.location="/providers";'>
Fournisseurs
</div>{% endblock %}
</div>
<div class='content'>
{% block content %}
<h1>Gestion du stock</h1>
<p>Ceci est l'outil de gestion de stock du <a href='https://www.tetalab.org'>Tetalab</a>.</p>
<p>Cet outil vous permet:
<ul>
<li>De gérer la liste des composants électroniques en possession du Tetalab</li>
<li>De gérer la liste des fournisseurs de composants</li>
<li>De gérer la liste des kits de montage</li>
</ul>
</p>
{% endblock %}
</div>
</div>
<div class='footer'>
Tetalab - Le Hacker Space Toulousaing' Putaing' Cong' -
</div>
</div>
</div>
</body>
</html>

stock_tetalab.py → tetastock.py View File


Loading…
Cancel
Save