"liste + delete composants"
This commit is contained in:
parent
33131ed07b
commit
954c1e7e10
BIN
static/images/edit.png
Normal file
BIN
static/images/edit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 374 B |
BIN
static/images/refresh.png
Normal file
BIN
static/images/refresh.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 312 B |
BIN
static/images/trash.png
Normal file
BIN
static/images/trash.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 327 B |
@ -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)
|
||||||
|
}
|
@ -184,6 +184,195 @@ div.footer {
|
|||||||
text-align: center;
|
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
|
* Classes génériques
|
||||||
|
94
stock.sql
94
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,
|
id serial primary key,
|
||||||
mail text not NULL,
|
mail text not NULL,
|
||||||
password text not NULL,
|
password text not NULL,
|
||||||
name text not NULL
|
name text not NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE stock_kits (
|
||||||
CREATE TABLE Stock_kits (
|
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
name text not NULL,
|
name text not NULL,
|
||||||
description text not NULL
|
description text not NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE stock_providers (
|
||||||
CREATE TABLE Stock_providers (
|
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
|
name text not NULL,
|
||||||
address text not NULL,
|
address text not NULL,
|
||||||
mail text not NULL,
|
mail text not NULL,
|
||||||
url text not NULL,
|
url text not NULL,
|
||||||
comment text not NULL
|
comment text not NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE stock_componants (
|
||||||
CREATE TABLE Stock_componants (
|
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
name text not NULL,
|
reference varchar(20) unique not NULL,
|
||||||
description text not NULL,
|
designation varchar(50) not NULL,
|
||||||
last_price NUMERIC not NULL,
|
last_price NUMERIC not NULL,
|
||||||
mean_price NUMERIC not NULL,
|
mean_price NUMERIC not NULL,
|
||||||
quantity NUMERIC not NULL,
|
quantity NUMERIC not NULL,
|
||||||
min_quantity NUMERIC not NULL,
|
min_quantity NUMERIC not NULL,
|
||||||
place text not NULL,
|
place varchar(15) not NULL,
|
||||||
provider_id integer REFERENCES Stock_providers(id)
|
provider_id integer REFERENCES stock_providers(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE stock_kit_compositions (
|
||||||
CREATE TABLE Stock_kit_compositions (
|
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
kit_id integer REFERENCES Stock_kits(id),
|
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
|
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
templates/componant.html
Normal file
132
templates/componant.html
Normal 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
templates/componants.html
Normal file
52
templates/componants.html
Normal 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 %}
|
@ -1,8 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
|
||||||
<head>
|
<head>
|
||||||
<meta name="generator" content="HTML Tidy for HTML5 for Linux version 5.5.21" />
|
<title>Tetastock - {% block title %}Accueil{% endblock %}</title>
|
||||||
<title>Stock Tetalab - {% block title %}Accueil{% endblock %}</title>
|
|
||||||
<meta name="viewport" content="initial-scale=1.0" />
|
<meta name="viewport" content="initial-scale=1.0" />
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
<link rel="stylesheet" type="text/css" href="/static/style/style.css" />
|
<link rel="stylesheet" type="text/css" href="/static/style/style.css" />
|
||||||
@ -12,7 +11,7 @@
|
|||||||
<div class='main_wrapper'>
|
<div class='main_wrapper'>
|
||||||
<div class='center'>
|
<div class='center'>
|
||||||
<div class='banner' title='Stock Tetalab'>
|
<div class='banner' title='Stock Tetalab'>
|
||||||
Stock Tetalab
|
Tetastock
|
||||||
</div>
|
</div>
|
||||||
<div class='top_menu'>
|
<div class='top_menu'>
|
||||||
{% block top_menu %} <span class='top_menu_item_selected' onclick='javascript:document.location="./";'>Accueil</span> {% endblock %}
|
{% block top_menu %} <span class='top_menu_item_selected' onclick='javascript:document.location="./";'>Accueil</span> {% endblock %}
|
||||||
|
56
templates/users.html
Normal file
56
templates/users.html
Normal 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>
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8
|
# -*- coding: utf-8
|
||||||
|
|
||||||
|
import math
|
||||||
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
|
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
@ -19,8 +20,8 @@ class Stock_users(db.Model):
|
|||||||
|
|
||||||
class Stock_componants(db.Model):
|
class Stock_componants(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name = db.Column(db.Text, nullable=False)
|
reference = db.Column(db.Text, nullable=False)
|
||||||
description = db.Column(db.Text, nullable=False)
|
designation = db.Column(db.Text, nullable=False)
|
||||||
last_price = db.Column(db.Float)
|
last_price = db.Column(db.Float)
|
||||||
mean_price = db.Column(db.Float)
|
mean_price = db.Column(db.Float)
|
||||||
quantity = db.Column(db.Integer)
|
quantity = db.Column(db.Integer)
|
||||||
@ -31,7 +32,7 @@ class Stock_componants(db.Model):
|
|||||||
class Stock_providers(db.Model):
|
class Stock_providers(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name = db.Column(db.Text, nullable=False)
|
name = db.Column(db.Text, nullable=False)
|
||||||
postal_address = db.Column(db.Text)
|
address = db.Column(db.Text)
|
||||||
url = db.Column(db.Text)
|
url = db.Column(db.Text)
|
||||||
comment = db.Column(db.Text)
|
comment = db.Column(db.Text)
|
||||||
|
|
||||||
@ -58,32 +59,107 @@ def authenticate():
|
|||||||
########################################################################
|
########################################################################
|
||||||
# Componants
|
# Componants
|
||||||
########################################################################
|
########################################################################
|
||||||
@app.route('/componants')
|
@app.route('/componants', methods=['GET', 'POST'])
|
||||||
def get_componants():
|
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/<componant_id>')
|
@app.route('/componants/<componant_id>')
|
||||||
def get_componant(componant_id):
|
def get_componant(componant_id):
|
||||||
return render_template('wip.html')
|
try:
|
||||||
|
componant_id = int(componant_id)
|
||||||
@app.route('/componants/add/<componant_id>')
|
except ValueError as e:
|
||||||
def add_componant(componant_id):
|
return render_template('error.html'), 404
|
||||||
return render_template('wip.html')
|
componant = Stock_componants.query.filter_by(id=componant_id).first()
|
||||||
|
if componant:
|
||||||
@app.route('/componants/edit/<componant_id>')
|
providers = Stock_providers.query.order_by(Stock_providers.name).all()
|
||||||
def edit_componant(componant_id):
|
provider = componant.provider_id
|
||||||
return render_template('wip.html')
|
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/<componant_id>')
|
@app.route('/componants/delete/<componant_id>')
|
||||||
def delete_componant(componant_id):
|
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/<componant_id>')
|
||||||
|
def add_componant(componant_id):
|
||||||
return render_template('wip.html')
|
return render_template('wip.html')
|
||||||
|
|
||||||
|
@app.route('/componants/in/<componant_id>')
|
||||||
|
def in_componants():
|
||||||
|
return render_template('wip.html')
|
||||||
|
|
||||||
|
@app.route('/componants/out/<componant_id>')
|
||||||
|
def out_componants():
|
||||||
|
return render_template('wip.html')
|
||||||
|
|
||||||
|
@app.route('/componant/update/<componant_id>', 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
|
# Kits
|
||||||
########################################################################
|
########################################################################
|
||||||
@app.route('/kits')
|
@app.route('/kits')
|
||||||
def get_kits():
|
def get_kits():
|
||||||
return render_template('wip.html')
|
return render_template('kits.html')
|
||||||
|
|
||||||
@app.route('/kits/<kit_id>')
|
@app.route('/kits/<kit_id>')
|
||||||
def get_kit(kit_id):
|
def get_kit(kit_id):
|
||||||
@ -101,12 +177,16 @@ def edit_kit(kit_id):
|
|||||||
def delete_kit(kit_id):
|
def delete_kit(kit_id):
|
||||||
return render_template('wip.html')
|
return render_template('wip.html')
|
||||||
|
|
||||||
|
@app.route('/kits/search')
|
||||||
|
def search_kits():
|
||||||
|
return render_template('wip.html')
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Providers
|
# Providers
|
||||||
########################################################################
|
########################################################################
|
||||||
@app.route('/providers')
|
@app.route('/providers')
|
||||||
def get_providers():
|
def get_providers():
|
||||||
return render_template('wip.html')
|
return render_template('providers.html')
|
||||||
|
|
||||||
@app.route('/providers/<provider_id>')
|
@app.route('/providers/<provider_id>')
|
||||||
def get_provider(provider_id):
|
def get_provider(provider_id):
|
||||||
@ -124,6 +204,10 @@ def edit_provider(provider_id):
|
|||||||
def delete_provider(provider_id):
|
def delete_provider(provider_id):
|
||||||
return render_template('wip.html')
|
return render_template('wip.html')
|
||||||
|
|
||||||
|
@app.route('/providers/search')
|
||||||
|
def search_providers():
|
||||||
|
return render_template('wip.html')
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Users
|
# Users
|
||||||
########################################################################
|
########################################################################
|
||||||
@ -147,6 +231,9 @@ def edit_user(user_id):
|
|||||||
def delete_user(user_id):
|
def delete_user(user_id):
|
||||||
return render_template('wip.html')
|
return render_template('wip.html')
|
||||||
|
|
||||||
|
@app.route('/users/search')
|
||||||
|
def search_users():
|
||||||
|
return render_template('wip.html')
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
|
|
Loading…
Reference in New Issue
Block a user