"Gestion complète des compositions de kits"

This commit is contained in:
Doug Le Tough 2017-10-28 11:22:59 +02:00
parent 45e7968544
commit 76cf51831b
14 changed files with 448 additions and 40 deletions

BIN
static/images/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 327 B

After

Width:  |  Height:  |  Size: 878 B

View File

@ -9,9 +9,7 @@ var base_border = "#555555";
* GLOBAL * GLOBAL
* **************************************************************************************/ * **************************************************************************************/
///////////////////////////////////////////
// Cookies // Cookies
///////////////////////////////////////////
function setcookie(cname, cvalue, exdays) { function setcookie(cname, cvalue, exdays) {
var d = new Date(); var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000)); d.setTime(d.getTime() + (exdays*24*60*60*1000));
@ -25,10 +23,7 @@ function getcookie(cname) {
if (parts.length == 2) return parts.pop().split(";").shift(); if (parts.length == 2) return parts.pop().split(";").shift();
} }
///////////////////////////////////////////
// Eye candies // Eye candies
///////////////////////////////////////////
function invalid_input(obj) { function invalid_input(obj) {
obj.style.backgroundColor = light_red; obj.style.backgroundColor = light_red;
setTimeout( function() { setTimeout( function() {
@ -106,8 +101,7 @@ function update_componants() {
xhttp.send(); xhttp.send();
} }
// Result ordering // Result ordering and navigation
function update_componants_by_reference(order) { function update_componants_by_reference(order) {
setcookie('c_order', order, 30); setcookie('c_order', order, 30);
setcookie('c_sort', 'reference', 30); setcookie('c_sort', 'reference', 30);
@ -148,7 +142,6 @@ function c_next_page(nexthop) {
// Search componants // Search componants
function search_componants_by_reference(obj) { function search_componants_by_reference(obj) {
setcookie('c_reference', obj.value, 30); setcookie('c_reference', obj.value, 30);
update_componants(); update_componants();
@ -170,14 +163,12 @@ function search_componants_by_provider(obj) {
} }
// Delete componant // Delete componant
function confirm_componant_delete() { function confirm_componant_delete() {
var msg="La suppression est définitive \net n'est pas autorisée si le \ncomposant fait partie d'un Kit.\n\nConfirmer ?"; 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); return confirm(msg);
} }
// New componant // New componant
function new_componant() { function new_componant() {
var err = false; var err = false;
var obj = {}; var obj = {};
@ -231,7 +222,6 @@ function create_componant() {
} }
// Update componant // Update componant
function update_componant(obj, componant_id, type) { function update_componant(obj, componant_id, type) {
if (type == 'numeric') { if (type == 'numeric') {
if (isNaN(obj.value)) { if (isNaN(obj.value)) {
@ -292,8 +282,7 @@ function update_providers() {
xhttp.send(); xhttp.send();
} }
// Result ordering // Result ordering and navigation
function update_providers_by_name(order) { function update_providers_by_name(order) {
setcookie('p_order', order, 30); setcookie('p_order', order, 30);
setcookie('p_sort', 'name', 30); setcookie('p_sort', 'name', 30);
@ -340,7 +329,6 @@ function p_next_page(nexthop) {
} }
// Search providers // Search providers
function search_providers_by_name(obj) { function search_providers_by_name(obj) {
setcookie('p_name', obj.value, 30); setcookie('p_name', obj.value, 30);
update_providers(); update_providers();
@ -367,7 +355,6 @@ function search_providers_by_comment(obj) {
} }
// New provider // New provider
function new_provider() { function new_provider() {
var err = false; var err = false;
var obj = {}; var obj = {};
@ -410,14 +397,12 @@ function create_provider() {
} }
// Delete provider // Delete provider
function confirm_provider_delete() { function confirm_provider_delete() {
var msg="La suppression est définitive \net n'est pas autorisée si le \nfournisseur est référencé \npar un composant.\n\nConfirmer ?"; var msg="La suppression est définitive \net n'est pas autorisée si le \nfournisseur est référencé \npar un composant.\n\nConfirmer ?";
return confirm(msg); return confirm(msg);
} }
// Update provider // Update provider
function update_provider(obj, provider_id, type) { function update_provider(obj, provider_id, type) {
var xhttp = new XMLHttpRequest(); var xhttp = new XMLHttpRequest();
xhttp.onerror = function(){ xhttp.onerror = function(){
@ -472,8 +457,7 @@ function update_kits() {
xhttp.send(); xhttp.send();
} }
// Result ordering // Result ordering and navigation
function update_kits_by_name(order) { function update_kits_by_name(order) {
setcookie('k_order', order, 30); setcookie('k_order', order, 30);
setcookie('k_sort', 'name', 30); setcookie('k_sort', 'name', 30);
@ -506,7 +490,6 @@ function k_next_kage(nexthop) {
} }
// Search kits // Search kits
function search_kits_by_name(obj) { function search_kits_by_name(obj) {
setcookie('k_name', obj.value, 30); setcookie('k_name', obj.value, 30);
update_kits(); update_kits();
@ -518,7 +501,6 @@ function search_kits_by_designation(obj) {
} }
// New kit // New kit
function new_kit() { function new_kit() {
var err = false; var err = false;
var obj = {}; var obj = {};
@ -569,14 +551,12 @@ function create_kit() {
} }
// Delete kit // Delete kit
function confirm_kit_delete() { function confirm_kit_delete() {
var msg="La suppression d'un kit est définitive.\n\nConfirmer ?"; var msg="La suppression d'un kit est définitive.\n\nConfirmer ?";
return confirm(msg); return confirm(msg);
} }
// Update kit // Update kit
function update_kit(obj, kit_id, type) { function update_kit(obj, kit_id, type) {
var xhttp = new XMLHttpRequest(); var xhttp = new XMLHttpRequest();
xhttp.onerror = function(){ xhttp.onerror = function(){
@ -599,3 +579,146 @@ function update_kit(obj, kit_id, type) {
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send('field='+obj.id+'&value='+obj.value); xhttp.send('field='+obj.id+'&value='+obj.value);
} }
/* **************************************************************************************
* KIT COMPOSITIONS
* **************************************************************************************/
// Update kit composition
function update_kit_composition(kit_id) {
obj = document.getElementById('kit_composition');
var xhttp = new XMLHttpRequest();
xhttp.onerror = function(){
obj.innerHTML = "Erreur lors de la mise à jour de la liste (1)"
};
xhttp.onload = function(){
if (xhttp.status != 200) {
obj.innerHTML = "Erreur lors de la mise à jour de la liste (2)"
}
};
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var response = xhttp.responseText;
obj.innerHTML = response;
return true;
}
};
xhttp.open('POST', '/kits/composition/'+kit_id, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send();
}
// Remove componant from kit
function confirm_componant_remove(designation) {
var msg="Supprimer le composant \n'"+designation+"'\ndu kit ?";
return confirm(msg);
}
// Add componant to kit
function add_kit_componant(kit_id, componant_id) {
var quantity = prompt("Quantité");
if (quantity < 1){
alert('La quantité doit être au moins égale à 1');
return;
}
setcookie('kc_quantity', quantity, 30);
setcookie('kc_componant_id', componant_id, 30);
var xhttp = new XMLHttpRequest();
xhttp.onerror = function(){
alert("Erreur lors de l'ajout du composant (1).");
};
xhttp.onload = function(){
if (xhttp.status != 200) {
alert("Erreur lors de l'ajout du composant (2).");
}
};
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var response = xhttp.responseText;
update_kit_composition(kit_id);
return true;
}
};
xhttp.open('POST', '/kits/add/'+kit_id+'/'+componant_id, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send();
}
// Edit componant_composition quantity
function edit_kit_composition(kit_id, componant_id){
var quantity = prompt('Nouvelle quantité');
if (quantity < 1){
alert('La quantité doit être au moins égale à 1.');
return;
}
setcookie('kc_quantity', quantity, 30);
setcookie('kc_componant_id', componant_id, 30);
var xhttp = new XMLHttpRequest();
xhttp.onerror = function(){
alert("Erreur lors de la mise à jour de la liste (1)");
};
xhttp.onload = function(){
if (xhttp.status != 200) {
alert("Erreur lors de la mise à jour de la liste (2)");
}
};
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var response = xhttp.responseText;
update_kit_composition(kit_id);
return true;
}
};
xhttp.open('POST', '/kits/composition/update/'+kit_id, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send();
}
// Update search result
function update_kit_componants(kit_id) {
obj = document.getElementById('result_container');
var xhttp = new XMLHttpRequest();
xhttp.onerror = function(){
obj.innerHTML = "Erreur lors de la mise à jour de la liste (1)"
};
xhttp.onload = function(){
if (xhttp.status != 200) {
obj.innerHTML = "Erreur lors de la mise à jour de la liste (2)"
}
};
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var response = xhttp.responseText;
obj.innerHTML = response;
return true;
}
};
xhttp.open('POST', '/kits/componants/update/'+kit_id, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send();
}
// Search componants
function search_kit_componants_by_reference(obj, kit_id) {
setcookie('kc_reference', obj.value, 30);
update_kit_componants(kit_id);
}
function search_kit_componants_by_designation(obj, kit_id) {
setcookie('kc_designation', obj.value, 30);
update_kit_componants(kit_id);
}

View File

@ -332,6 +332,7 @@ span.page_num {
} }
div.row_block { div.row_block {
display: inline-block;
margin: 0 0 4px 0; margin: 0 0 4px 0;
height: 20px; height: 20px;
width: 1000px; width: 1000px;
@ -344,13 +345,14 @@ div.nav_page_block {
} }
div.action_bar_block { div.action_bar_block {
display: inline;
overflow: hidden; overflow: hidden;
float: center; float: center;
height: 20px; height: 20px;
} }
div.row_block label { div.row_block label {
display: block; display: inline;
float: left; float: left;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
@ -369,7 +371,7 @@ div.row_block text.border_left {
} }
div.row_block text { div.row_block text {
display: block; display: inline;
float: left; float: left;
font-weight: normal; font-weight: normal;
text-align: left; text-align: left;
@ -383,13 +385,27 @@ div.row_block text.num {
text-align: right; text-align: right;
} }
div.row_block text.red {
color: #FF0000;
font-weight: bold;
border-color: #555555;
}
div.nav_page_block text { div.nav_page_block text {
display: block; display: block;
white-space: nowrap; white-space: nowrap;
} }
div.action_bar_block input { div.action_bar_block input {
display: inline;
height: 17px; height: 17px;
width: 16px; width: 16px;
margin-left: 20px; margin-left: 20px;
margin-top: 1px;
background-color: #F5D00;
}
div.action_bar_block input:hover {
cursor: pointer;
background-color: #FF5D00;
} }

View File

@ -128,3 +128,19 @@ insert into stock_componants (reference, designation, last_price, mean_price, qu
values ('Res-19', 'Resistance 28KΩ', 13.34, 12.42, 73, 0, 'B 43', 3); values ('Res-19', 'Resistance 28KΩ', 13.34, 12.42, 73, 0, 'B 43', 3);
insert into stock_componants (reference, designation, last_price, mean_price, quantity, min_quantity, place, provider_id) 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', 3); values ('Res-20', 'Resistance 29KΩ', 13.34, 12.42, 73, 0, 'B 43', 3);
insert into stock_kits (name, designation) values ('Kit_test', 'Kit de test');
insert into stock_kits (name, designation) values ('Kit2_test2', 'Kit de test 2');
insert into stock_kits (name, designation) values ('MF_K', 'Mother fucking kit');
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (1, 5, 1);
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (1, 8, 2);
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (1, 10, 2);
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (1, 12, 7);
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (2, 5, 2);
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (2, 4, 1);
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (2, 9, 3);
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (2, 22, 2);
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (2, 1, 5);
insert into stock_kit_compositions (kit_id, componant_id, quantity) values (2, 14, 8);

View File

@ -1,7 +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>
<title>Référentiel Infrastructure Tetalab - {% block title %}How The Fuck{% endblock %}</title> <title>Tetastock</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" />
@ -10,8 +10,8 @@
<body> <body>
<div class='main_wrapper'> <div class='main_wrapper'>
<div class='center'> <div class='center'>
<div class='banner' title='Référentiel infrastrusture Tetalab'> <div class='banner' title='Tetastock'>
Référentiel Infrastructure Tetalab Tetastock
</div> </div>
<div class='top_menu'> <div class='top_menu'>
<span class='top_menu_item' onclick='javascript:document.location="/";'>Retour</span> <span class='top_menu_item' onclick='javascript:document.location="/";'>Retour</span>

View File

@ -1,4 +1,7 @@
{% extends "index.html" %} {% extends "index.html" %}
{% block bodyheader %}
<body onload="update_kit_composition({{ kit.id }});">
{% endblock %}
{% block title %}Éditer un kit{% endblock %} {% block title %}Éditer un kit{% endblock %}
{% block top_menu %} {% block top_menu %}
<span class='top_menu_item' onclick='javascript:document.location="/providers";'>Gérer les kits</span> <span class='top_menu_item' onclick='javascript:document.location="/providers";'>Gérer les kits</span>
@ -44,4 +47,8 @@
value='{{ kit.designation }}' /> value='{{ kit.designation }}' />
</div> </div>
</div> </div>
<div id='kit_composition' class='main_block'>
</div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,67 @@
<div class='main_block border_bottom'>
<text style='margin-top: 10px;'>Nombre maximum de kits: {{ max_kit }}</text>
<text style='margin-top: 10px;'>Composition:</text>
<div class='row_block border_bottom'>
<label style='width: 200px;'>Référence</label>
<label class='border_left' style='width: 499px;'>Désignation</label>
<label class='border_left' style='width: 99px;'>Quantité</label>
<label class='border_left' style='width: 99px;'>Disponible</label>
<label class='border_left' style='width: 99px;' style='cursor: default;'>Action</label>
</div>
{% set row_class = cycler('odd', 'even') %}
{% for componant in kit_composition %}
{% set qclass='' %}
{% if componant.needed > componant.quantity %}
{% set qclass='red' %}
{% endif %}
<div class='row_block {{ row_class.next() }}'>
<text style='width: 190px;'>{{ componant.reference }}</text>
<text class='border_left' style='width: 489px;'>{{ componant.designation }}</text>
<text class='num border_left {{ qclass }}' style='width: 89px;'>{{ componant.needed }}</text>
<text class='num border_right border_left {{ qclass }}' style='width: 89px;'>{{ componant.quantity }}</text>
<div class='action_bar_block border_left' style='width: 89px;'>
<input
type='image'
src='/static/images/edit.png'
title='Éditer'
onclick='javascript:edit_kit_composition({{ kit_id }}, {{ componant.id }});'/>
<input
type='image'
src='/static/images/trash.png'
title='Supprimer'
onclick='javascript:confirm_componant_remove("{{ componant.designation }}")?document.location="/kits/remove/{{ kit_id }}/{{ componant.id }}":false;'/>
</div>
</div>
{% endfor %}
</div>
<div class='main_block'>
<text style='margin-top: 10px;'>Ajouter un composant:</text>
<div class='input_block'>
<label>Référence</label>
<input
id='reference'
type='text'
onkeyup='javascript:search_kit_componants_by_reference(this, {{ kit_id }});'
maxlength='20'
title='Référence interne unique (max. 20)'
placeholder='Référence interne unique (max. 20)'
value='{{ reference }}' />
</div>
<div class='input_block'>
<label>Désignation</label>
<input
id='designation'
type='text'
onkeyup='javascript:search_kit_componants_by_designation(this, {{ kit_id }});'
maxlength='50'
title='Désignation (max. 50)'
placeholder='Désignation (max. 50)'
value='{{ designation }}' />
</div>
</div>
<!-- ----------------------------------------------------
Resultat
----------------------------------------------------- -->
<div id='result_container' class='main_block'>
</div>

View File

@ -2,7 +2,7 @@
{% block bodyheader %} {% block bodyheader %}
<body onload="javascript:update_kits();"> <body onload="javascript:update_kits();">
{% endblock %} {% endblock %}
{% block title %}Liste des fournisseurs{% endblock %} {% block title %}Liste des Kits{% endblock %}
{% block top_menu %} {% block top_menu %}
<span class='top_menu_item_selected' onclick='javascript:document.location="/kits";'>Gérer les kits</span> <span class='top_menu_item_selected' onclick='javascript:document.location="/kits";'>Gérer les kits</span>
{% endblock %} {% endblock %}

View File

@ -1,5 +1,5 @@
<div class='main_block'> <div class='main_block'>
<text>Résultat: <text style='margin-top: 10px;'>Résultat:
{% set ss='' %} {% set ss='' %}
{% if row_count > 1 %} {% if row_count > 1 %}
{% set ss='s' %} {% set ss='s' %}

View File

@ -0,0 +1,26 @@
<div class='main_block'>
<text style='margin-top: 10px;'>Résultat:</text>
<div class='row_block border_bottom'>
<label style='width: 200px;'>Référence</label>
<label class='border_left' style='width: 449px;'>Désignation</label>
<label class='border_left' style='width: 99px;'>Quantité</label>
<label class='border_left' style='width: 149px;'>Emplacement</label>
<label class='border_left' style='width: 99px; cursor: default;'>Action</label>
</div>
{% set row_class = cycler('odd', 'even') %}
{% for componant in componants %}
<div class='row_block {{ row_class.next() }}'>
<text style='width: 190px;'>{{ componant.reference }}</text>
<text class='border_left' style='width: 439px;'>{{ componant.designation }}</text>
<text class='num border_left' style='width: 89px;'>{{ componant.quantity }}</text>
<text class='num border_right border_left' style='width: 139px;'>{{ componant.place }}</text>
<div class='action_bar_block border_left' style='width: 89px;'>
<input
type='image'
src='/static/images/add.png'
title='Ajouter au kit'
onclick='javascript:add_kit_componant({{ kit_id }}, {{ componant.id }});'/>
</div>
</div>
{% endfor %}
</div>

View File

@ -1,5 +1,5 @@
<div class='main_block'> <div class='main_block'>
<text>Résultat: <text style='margin-top: 10px;'>Résultat:
{% set ss='' %} {% set ss='' %}
{% if row_count > 1 %} {% if row_count > 1 %}
{% set ss='s' %} {% set ss='s' %}

View File

@ -26,12 +26,14 @@ db = SQLAlchemy(app)
# Database # Database
######################################################################## ########################################################################
class Stock_users(db.Model): class Stock_users(db.Model):
__tablename__ = 'stock_users'
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
mail = db.Column(db.Text, nullable=False) mail = db.Column(db.Text, nullable=False)
password = db.Column(db.Text, nullable=False) password = db.Column(db.Text, nullable=False)
name = db.Column(db.Text, nullable=False) name = db.Column(db.Text, nullable=False)
class Stock_componants(db.Model): class Stock_componants(db.Model):
__tablename__ = 'stock_componants'
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
reference = db.Column(db.Text, nullable=False) reference = db.Column(db.Text, nullable=False)
designation = db.Column(db.Text, nullable=False) designation = db.Column(db.Text, nullable=False)
@ -43,6 +45,7 @@ class Stock_componants(db.Model):
provider_id = db.Column(db.Integer, nullable=False) provider_id = db.Column(db.Integer, nullable=False)
class Stock_providers(db.Model): class Stock_providers(db.Model):
__tablename__ = 'stock_providers'
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)
address = db.Column(db.Text) address = db.Column(db.Text)
@ -51,26 +54,32 @@ class Stock_providers(db.Model):
comment = db.Column(db.Text) comment = db.Column(db.Text)
class Stock_kits(db.Model): class Stock_kits(db.Model):
__tablename__ = 'stock_kits'
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)
designation = db.Column(db.Text, nullable=False) designation = db.Column(db.Text, nullable=False)
class Stock_kit_compositions(db.Model): class Stock_kit_compositions(db.Model):
__tablename__ = 'stock_kit_compositions'
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
kit_id = db.Column(db.Integer, db.ForeignKey('Stock_kits.id'), nullable=False) kit_id = db.Column(db.Integer, db.ForeignKey('stock_kits.id'), nullable=False)
componant_id = db.Column(db.Integer, db.ForeignKey('Stock_componants.id'), nullable=False) componant_id = db.Column(db.Integer, db.ForeignKey('stock_componants.id'), nullable=False)
quantity = db.Column(db.Integer, nullable=False) quantity = db.Column(db.Integer, nullable=False)
price = db.Column(db.Integer, nullable=False)
class Stock_orders(db.Model): class Stock_orders(db.Model):
__tablename__ = 'stock_orders'
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
componant_id = db.Column(db.Integer, db.ForeignKey('Stock_componants.id')) componant_id = db.Column(db.Integer, db.ForeignKey('stock_componants.id'))
componant_quantity = db.Column(db.Integer, nullable=False) componant_quantity = db.Column(db.Integer, nullable=False)
date = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow) date = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
injected = db.Column(db.Boolean, nullable=False, default=False) injected = db.Column(db.Boolean, nullable=False, default=False)
########################################################################
# Here comes the fun
########################################################################
def sync_cookies(response, session): def sync_cookies(response, session):
""" Sync cookies from session """ """ Sync cookies with session """
for key in session: for key in session:
response.set_cookie(key, value=str(session[key])) response.set_cookie(key, value=str(session[key]))
if key != u'session': if key != u'session':
@ -126,9 +135,10 @@ def check_user(request, session):
def resume_session(func): def resume_session(func):
""" Resume pending session """
@wraps(func) @wraps(func)
def check(*args, **kwargs): def check(*args, **kwargs):
# Motherfuckin' bunch of defaults values # A motherfuckin' bunch of defaults values
empty=u'' empty=u''
limit = 10 limit = 10
offset = 0 offset = 0
@ -144,6 +154,8 @@ def resume_session(func):
p_count = 0 p_count = 0
k_sort = u'name' k_sort = u'name'
k_count = 0 k_count = 0
kc_quantity = 0
kc_limit = 3
offset_reset = [u'c_reference', u'c_designation', u'c_place', offset_reset = [u'c_reference', u'c_designation', u'c_place',
u'c_provider', u'p_name', u'p_address', u'p_mail', u'p_url', u'c_provider', u'p_name', u'p_address', u'p_mail', u'p_url',
u'k_name', u'k_designation'] u'k_name', u'k_designation']
@ -237,7 +249,16 @@ def resume_session(func):
session[u'k_designation'] = empty session[u'k_designation'] = empty
if not u'k_count' in session: if not u'k_count' in session:
session[u'k_count'] = k_count session[u'k_count'] = k_count
if not u'kc_limit' in session:
session[u'kc_limit'] = kc_limit
if not u'kc_componant_id' in session:
session[u'kc_componant_id'] = empty
if not u'kc_quantity' in session:
session[u'kc_quantity'] = kc_quantity
if not u'kc_designation' in session:
session[u'kc_designation'] = empty
if not u'kc_reference' in session:
session[u'kc_reference'] = empty
# Cookies/session sync # Cookies/session sync
sync_session(request, session, offset_reset) sync_session(request, session, offset_reset)
@ -266,11 +287,13 @@ def resume_session(func):
######################################################################## ########################################################################
@app.errorhandler(404) @app.errorhandler(404)
def page_not_found(e): def page_not_found(e):
return render_template('error.html'), 404 """ 404 not found """
return render_template('error.html'), 404
@app.route("/", methods=['GET', 'POST']) @app.route("/", methods=['GET', 'POST'])
@resume_session @resume_session
def authenticate(): def authenticate():
""" Friend or foo ? """
response = app.make_response(render_template('index.html')) response = app.make_response(render_template('index.html'))
sync_cookies(response, session) sync_cookies(response, session)
return response return response
@ -283,7 +306,7 @@ def authenticate():
@app.route('/componants', methods=['GET', 'POST']) @app.route('/componants', methods=['GET', 'POST'])
@resume_session @resume_session
def componants(): def componants():
""" Main page """ """ Componants list """
providers = Stock_providers.query.order_by(Stock_providers.id).all() providers = Stock_providers.query.order_by(Stock_providers.id).all()
return render_template('componants.html', return render_template('componants.html',
providers=providers, providers=providers,
@ -336,6 +359,7 @@ def delete_componant(componant_id):
except ValueError as e: except ValueError as e:
return render_template('error.html'), 404 return render_template('error.html'), 404
except Exception as e: except Exception as e:
db.session.rollback()
print "[+] Error at delete_componant:" print "[+] Error at delete_componant:"
print "------------------------------" print "------------------------------"
print "%s" % e.message print "%s" % e.message
@ -358,6 +382,7 @@ def new_componant():
db.session.add(componant) db.session.add(componant)
commit = db.session.commit() commit = db.session.commit()
except Exception as e: except Exception as e:
db.session.rollback()
print "[+] Error at new_componant:" print "[+] Error at new_componant:"
print "------------------------------" print "------------------------------"
print "%s" % e.message print "%s" % e.message
@ -440,6 +465,7 @@ def update_componants():
@app.route('/providers', methods=['GET', 'POST']) @app.route('/providers', methods=['GET', 'POST'])
@resume_session @resume_session
def providers(): def providers():
""" Providers list """
return render_template('providers.html', return render_template('providers.html',
name=session[u'p_name'].decode('utf8'), name=session[u'p_name'].decode('utf8'),
address=session[u'p_address'].decode('utf8'), address=session[u'p_address'].decode('utf8'),
@ -491,6 +517,7 @@ def new_provider():
db.session.add(provider) db.session.add(provider)
commit = db.session.commit() commit = db.session.commit()
except Exception as e: except Exception as e:
db.session.rollback()
print "[+] Error at new_provider:" print "[+] Error at new_provider:"
print "------------------------------" print "------------------------------"
print "%s" % e.message print "%s" % e.message
@ -511,6 +538,7 @@ def delete_provider(provider_id):
except ValueError as e: except ValueError as e:
return render_template('error.html'), 404 return render_template('error.html'), 404
except Exception as e: except Exception as e:
db.session.rollback()
print "[+] Error at delete_provider:" print "[+] Error at delete_provider:"
print "------------------------------" print "------------------------------"
print "%s" % e.message print "%s" % e.message
@ -627,6 +655,7 @@ def new_kit():
db.session.add(kit) db.session.add(kit)
commit = db.session.commit() commit = db.session.commit()
except Exception as e: except Exception as e:
db.session.rollback()
print "[+] Error at new_kit:" print "[+] Error at new_kit:"
print "------------------------------" print "------------------------------"
print "%s" % e.message print "%s" % e.message
@ -648,6 +677,7 @@ def delete_kit(kit_id):
except ValueError as e: except ValueError as e:
return render_template('error.html'), 404 return render_template('error.html'), 404
except Exception as e: except Exception as e:
db.session.rollback()
print "[+] Error at delete_kit:" print "[+] Error at delete_kit:"
print "------------------------------" print "------------------------------"
print "%s" % e.message print "%s" % e.message
@ -705,6 +735,129 @@ def search_kits():
print '[c]', key, session[key] print '[c]', key, session[key]
return response return response
@app.route('/kits/composition/<kit_id>', methods=['POST'])
@resume_session
def get_kit_composition(kit_id):
default_max_kit = 999999999999999
kit_composition = []
max_kit = default_max_kit
composition = Stock_kit_compositions.query.filter_by(kit_id=kit_id).with_entities(
Stock_kit_compositions.componant_id,
Stock_kit_compositions.quantity).all()
# FIXME: Use join rather than this ugly work around
# FIXME: Good luck !
for c_componant in composition:
componant = Stock_componants.query.filter_by(id=c_componant.componant_id).first()
if componant:
c = {u'id': componant.id,
u'reference': componant.reference,
u'designation': componant.designation,
u'quantity': componant.quantity,
u'needed': c_componant.quantity
}
kit_composition.append(c)
try:
mkit = int(componant.quantity) / int(c_componant.quantity)
except ZeroDivisionError as e:
print "[+] Error at get_kit_composition:"
print "------------------------------"
print "%s" % e.message
print "------------------------------"
if mkit < max_kit:
max_kit = mkit
if max_kit == default_max_kit:
max_kit = 0
if len(kit_composition) > 0:
return render_template('kit_composition.html', kit_composition=kit_composition, max_kit=max_kit, kit_id=kit_id)
return "Aucun composant"
@app.route('/kits/remove/<kit_id>/<componant_id>', methods=['GET'])
@resume_session
def remove_componant_from_kit(kit_id, componant_id):
""" Remove componant from kit """
try:
kit_id = int(kit_id)
Stock_kit_compositions.query.filter_by(kit_id=kit_id).filter_by(componant_id=componant_id).delete()
db.session.commit()
except ValueError as e:
return render_template('error.html'), 404
except Exception as e:
db.session.rollback()
print "[+] Error at remove_componant_from_kit:"
print "------------------------------"
print "%s" % e.message
print "------------------------------"
return get_kit(kit_id)
@app.route('/kits/add/<kit_id>/<componant_id>', methods=['POST', 'GET'])
@resume_session
def add_componant_to_kit(kit_id, componant_id):
""" Add componant to kit """
try:
kit_id = int(kit_id)
count = Stock_kit_compositions.query.filter_by(kit_id=kit_id, componant_id=componant_id).count()
if count > 0:
# Componant already in kit composition
# => Updating with new quantity
return update_kit_composition(kit_id)
composition = Stock_kit_compositions(kit_id=kit_id,
componant_id=componant_id,
quantity=session[u'kc_quantity'])
db.session.add(composition)
commit = db.session.commit()
except ValueError as e:
return render_template('error.html'), 404
except Exception as e:
db.session.rollback()
print "[+] Error at add_componant_to_kit:"
print "------------------------------"
print "%s" % e.message
print "------------------------------"
return 'KO'
if commit != None:
return 'KO'
return 'OK'
@app.route('/kits/composition/update/<kit_id>', methods=['GET', 'POST'])
@resume_session
def update_kit_composition(kit_id):
""" Update componant quantity """
try:
kit_id = int(kit_id)
composition = Stock_kit_compositions.query.filter_by(
kit_id=kit_id, componant_id=session[u'kc_componant_id']).first()
composition.quantity = session[u'kc_quantity']
db.session.commit()
except ValueError as e:
return render_template('error.html'), 404
except Exception as e:
db.session.rollback()
print "[+] Error at update_kit_composition:"
print "------------------------------"
print "%s" % e.message
print "------------------------------"
return get_kit(kit_id)
## Componants update result set
@app.route('/kits/componants/update/<kit_id>', methods=['POST'])
@resume_session
def update_kit_componants(kit_id):
""" Display componants list """
# search by reference
like = '%s%s%s' % ('%', str(session[u'kc_reference']), '%')
componants = Stock_componants.query.filter(Stock_componants.reference.like(like))
# search by designation
like = '%s%s%s' % ('%', str(session[u'kc_designation']), '%')
componants = componants.filter(Stock_componants.designation.like(like))
# Applying limit
componants = componants.limit(session[u'kc_limit'])
# Get result
componants = componants.all()
response = app.make_response(render_template('result_kit_componants.html', kit_id=kit_id, componants=componants))
sync_cookies(response, session)
return response
# Main ####################################### # Main #######################################
if __name__ == '__main__': if __name__ == '__main__':