Commit 86edeac7 by Félicie

Merge branch 'dev_cooperatic' into 2826-price-product

parents 8c4e7e33 04aedf66
Pipeline #2159 passed with stage
in 1 minute 30 seconds
"""Company specific data values."""
MAG_NAME = 'Cleme'
OFFICE_NAME = ''
MAX_BEGIN_HOUR = '19:00'
COMPANY_NAME = 'La Cagette'
WELCOME_ENTRANCE_MSG = 'Bienvenue à La Cagette !'
WELCOME_MAIL_SUBJECT = 'Dernière étape de votre inscription à la Cagette.'
WELCOME_MAIL_TEMPLATE = 'members/bienvenue.html'
BLOCK_SERVICE_EXCHANGE_24H_BEFORE = True
USE_NEW_MEMBERS_SPACE = True
ASSOCIATE_MEMBER_SHIFT = 429
START_DATE_FOR_POINTS_HISTORY = "2021-07-01"
START_DATE_FOR_SHIFTS_HISTORY = "2021-07-01"
COMPANY_CODE = "lacagette"
AMNISTIE_DATE= "2021-11-24 23:00:00"
DEFAULT_SHIFT_TYPE = 'standard'
SHOW_FTOP_BUTTON = False
USE_STANDARD_SHIFT = True
OPEN_ON_SUNDAY = True
FLV_CSV_NB = 4
CAP_JOURNAL_ID = 9
CAP_APPELE_NON_VERSE_ACCOUNT_ID = 529
CAP_APPELE_VERSE_ACCOUNT_ID = 8
CAP_INVOICE_LINE_ACCOUNT_ID = 8
FUNDRAISING_CAT_ID = 1
UNITE_UOM_ID = 1
PARTS_A_PRODUCT_ID = 1008
PARTS_A_PRICE_UNIT = 10.0
COOP_BARCODE_RULE_ID = 11
CHECK_PAYMENT_ID = 8
CASH_PAYMENT_ID = 18
STOCK_LOC_ID = 12
CATEG_FRUIT = 151
CATEG_LEGUME = 152
COEFF_MAG_ID = 1
LOSSES_LOC_ID = 33
LOSSES_PICKING_TYPE_ID = 10
AUTOCONSO_LOC_ID = 27
AUTOCONSO_PICKING_TYPE_ID = 7
MEALS_LOC_ID = 36
MEALS_PICKING_TYPE_ID = 16
DEFAULT_MAX_TIMESLOT_CARTS = 5
MIN_DELAY_FOR_SLOT = 4
HOURS_FOR_VALIDATION_SHOP = 3
CART_VALIDATION_BOTTOM_MSG = "Pour des raisons d'hygiène les commandes seront préparées dans des sacs en papier kraft qui vous seront facturées, 0,24€ pour les petits et 0,77€ pour les grands. Merci de votre compréhension"
SUBSCRIPTION_PAYMENT_MEANINGS = [{'code': 'cash', 'title': 'Espèces', 'journal_id': CASH_PAYMENT_ID},
{'code': 'ch', 'title': 'Chèque', 'journal_id': CHECK_PAYMENT_ID}]
EM_URL = ''
RECEPTION_MERGE_ORDERS_PSWD = 'jpsrcp'
DAV_PATH = '/shared_dir/dav/'
TOOLS_SERVER = 'http://10.203.101.242:2012'
ADMIN_IDS = [13]
BRINKS_MUST_IDENTIFY = False
SHOP_CAN_BUY = True
SHOP_OPENING = {'mar.': [{'start': '10:30', 'end': '14:00'}, {'start': '15:30', 'end': '20:00'}],
'mer.': [{'start': '10:30', 'end': '14:00'}, {'start': '15:30', 'end': '20:00'}],
'jeu.': [{'start': '10:30', 'end': '14:00'}, {'start': '15:30', 'end': '20:00'}],
'ven.': [{'start': '10:30', 'end': '14:00'}, {'start': '15:30', 'end': '20:00'}],
'sam.': [{'start': '10:30', 'end': '14:00'}, {'start': '15:30', 'end': '20:00'}]
}
#
# SHOP_OPENING = {}
SHOP_OPENING_START_DATE = '2020-06-02'
SHOP_SLOT_SIZE = 30 # minutes
SHOP_CATEGORIES = {'epicerie': {'id': 75, 'label': 'Epicerie'},
'liquide': {'id': 96, 'label': 'Liquides'},
'produits_frais': {'id': 104, 'label': 'Frais'},
'surgeles': {'id': 115, 'label': 'Surgelés'},
'bazar': {'id': 122, 'label': 'Bazar'},
'droguerie': {'id': 127, 'label': 'Droguerie Hygiène'},
'parfumerie': {'id': 133, 'label': 'Parfumerie'}}
SHOP_EXTRA_MENUS = ['shop/planning_livraison_pains.html', 'shop/combien_ca_pese.html']
SHOP_SURVEY_LINK = ''
SHOP_LIMIT_PRODUCTS = ['relatively_available', 'no_shelf']
SHOP_HEADER_IMG = "https://odoo.demo.cooperatic.fr/web/binary/company_logo?db=lacagette&company=1"
EXCLUDE_SHOP_CATEGORIES = [108]
PROMOTE_SHELFS_IDS = [68]
DISCOUNT_SHELFS_IDS = [74]
FL_SHELFS = [16, 17, 18]
VRAC_SHELFS = [20, 38]
SHIFT_EXCHANGE_DAYS_TO_HIDE = ''
SHIFT_INFO = """A la cagette, un service est une plage de trois heures un jour en particulier, par exemple : le mardi 25/09/2018 à 13h15.
<br />A l'inverse, un créneau est une plage de trois heures régulière, par exemple, tous les mardi de semaine A à 13h15."""
PB_INSTRUCTIONS = """Si j'ai un problème, que je suis désinscrit, que je veux changer de créneaux ou quoi que ce soit, merci de vous rendre dans la section \"J'ai un problème\" sur le site web de <a href=\"https://lacagette-coop.fr/?MonEspaceMembre\">La Cagette</a>"""
ENTRANCE_COME_FOR_SHOPING_MSG = "Hey coucou toi ! Cet été nous sommes plus de <strong>1000 acheteur·euses</strong> pour seulement <strong>300 coopérateur·rice·s</strong> en service. <br />Tu fais tes courses à La Cagette cet été ?<br/> Inscris-toi sur ton espace membre !"
ENTRANCE_EXTRA_BUTTONS_DISPLAY = False
ENTRANCE_EASY_SHIFT_VALIDATE = True
ENTRANCE_MISSED_SHIFT_BEGIN_MSG = """La période pendant laquelle il est possible de s'enregistrer est close.<br/>
Pour tout problème ou demande vous pouvez contacter le Bureau des Membres via les formulaires depuis votre espace membre.
"""
ENTRANCE_VALIDATE_PRESENCE_MESSAGE = """
<div class="explanations">
Ta présence a bien été validée ! Merci de te diriger au fond du magasin pour le lancement du créneau !
</div>
Ton prochain service <span class="service_verb">est prévu</span> le <span class="next_shift"></span>
"""
ENTRANCE_EASY_SHIFT_VALIDATE_MSG = """Si vous faites un service dans un comité, merci de <br/>
valider votre présence en cherchant<br/>
votre nom ou numéro ci-dessous
"""
# Members space / shifts
UNSUBSCRIBED_MSG = 'Vous êtes désincrit·e, merci de remplir <a href="">ce formulaire</a>'
UNSUBSCRIBED_FORM_LINK = ''
RECEPTION_PB = "Ici, vous pouvez signaler toute anomalie lors d'une réception, les produits non commandés, cassés ou pourris. \
Merci d'indiquer un maximum d'informations, le nom du produit et son code barre."
CONFIRME_PRESENT_BTN = 'Clique ici pour valider ta présence'
ORDERS_HELPER_METABASE_URL = ""
from django.test import SimpleTestCase
class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self):
assert 1==1
\ No newline at end of file
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test import Client
class TestUrls(SimpleTestCase): class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self): def testInventoryUrlIsResolved(self):
assert 1==1
\ No newline at end of file c = Client()
response = c.get('/reception/')
assert response.status_code == 200, "Inventory url is not resolved"
...@@ -773,4 +773,7 @@ $(document).ready(function() { ...@@ -773,4 +773,7 @@ $(document).ready(function() {
searchMembersForAssociate(); searchMembersForAssociate();
}); });
if (committees_shift_id !== "None") {
$("#shift_choice button[data-select='Volant']").text("Comités");
}
}); });
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test import Client
class TestUrls(SimpleTestCase): class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self): def testMembersUrlIsResolved(self):
assert 1==1
\ No newline at end of file c = Client()
response = c.get('/members/')
assert response.status_code == 200, "Members url is not resolved"
...@@ -87,24 +87,27 @@ def inscriptions(request, type=1): ...@@ -87,24 +87,27 @@ def inscriptions(request, type=1):
""" """
template = loader.get_template('members/inscriptions.html') template = loader.get_template('members/inscriptions.html')
context = {'type': type, 'title': 'Inscriptions', committees_shift_id = CagetteServices.get_committees_shift_id()
'couchdb_server': settings.COUCHDB['url'], context = {
'mag_place_string': settings.MAG_NAME, 'type': type, 'title': 'Inscriptions',
'office_place_string': settings.OFFICE_NAME, 'couchdb_server': settings.COUCHDB['url'],
'max_begin_hour': settings.MAX_BEGIN_HOUR, 'mag_place_string': settings.MAG_NAME,
'payment_meanings': settings.SUBSCRIPTION_PAYMENT_MEANINGS, 'office_place_string': settings.OFFICE_NAME,
'force_firstname_hyphen': getattr(settings, 'FORCE_HYPHEN_IN_SUBSCRIPTION_FIRSTNAME', True), 'max_begin_hour': settings.MAX_BEGIN_HOUR,
'input_barcode': getattr(settings, 'SUBSCRIPTION_INPUT_BARCODE', False), 'payment_meanings': settings.SUBSCRIPTION_PAYMENT_MEANINGS,
'email_domain': getattr(settings, 'EMAIL_DOMAIN', 'lacagette-coop.fr'), 'force_firstname_hyphen': getattr(settings, 'FORCE_HYPHEN_IN_SUBSCRIPTION_FIRSTNAME', True),
'ask_for_sex': getattr(settings, 'SUBSCRIPTION_ASK_FOR_SEX', False), 'input_barcode': getattr(settings, 'SUBSCRIPTION_INPUT_BARCODE', False),
'open_on_sunday': getattr(settings, 'OPEN_ON_SUNDAY', False), 'email_domain': getattr(settings, 'EMAIL_DOMAIN', 'lacagette-coop.fr'),
'POUCHDB_VERSION': getattr(settings, 'POUCHDB_VERSION', ''), 'ask_for_sex': getattr(settings, 'SUBSCRIPTION_ASK_FOR_SEX', False),
'max_chq_nb': getattr(settings, 'MAX_CHQ_NB', 12), 'open_on_sunday': getattr(settings, 'OPEN_ON_SUNDAY', False),
'show_ftop_button': getattr(settings, 'SHOW_FTOP_BUTTON', True), 'POUCHDB_VERSION': getattr(settings, 'POUCHDB_VERSION', ''),
'db': settings.COUCHDB['dbs']['member'], 'max_chq_nb': getattr(settings, 'MAX_CHQ_NB', 12),
'ASSOCIATE_MEMBER_SHIFT' : getattr(settings, 'ASSOCIATE_MEMBER_SHIFT', ''), 'show_ftop_button': getattr(settings, 'SHOW_FTOP_BUTTON', True),
'prepa_odoo_url' : getattr(settings, 'PREPA_ODOO_URL', '/members/prepa-odoo'), 'db': settings.COUCHDB['dbs']['member'],
} 'ASSOCIATE_MEMBER_SHIFT' : getattr(settings, 'ASSOCIATE_MEMBER_SHIFT', ''),
'prepa_odoo_url' : getattr(settings, 'PREPA_ODOO_URL', '/members/prepa-odoo'),
'committees_shift_id': committees_shift_id,
}
response = HttpResponse(template.render(context, request)) response = HttpResponse(template.render(context, request))
return response return response
......
...@@ -56,7 +56,8 @@ ...@@ -56,7 +56,8 @@
} }
/* - Order selection screen */ /* - Order selection screen */
#new_order_area { #new_order_area,
#existing_orders_area {
margin-bottom: 40px; margin-bottom: 40px;
} }
...@@ -167,6 +168,11 @@ ...@@ -167,6 +168,11 @@
border-bottom: 1px solid #004aa6; border-bottom: 1px solid #004aa6;
} }
#common_info_editor_container {
width: 50%;
margin: 15px auto;
}
/* -- Order data */ /* -- Order data */
#order_data_container { #order_data_container {
font-size: 1.8rem; font-size: 1.8rem;
...@@ -177,7 +183,7 @@ ...@@ -177,7 +183,7 @@
} }
#order_forms_container { #order_forms_container {
margin-top: 20px; margin: 25px 0;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-evenly; justify-content: space-evenly;
......
...@@ -10,10 +10,16 @@ var suppliers_list = [], ...@@ -10,10 +10,16 @@ var suppliers_list = [],
package_qty: null, package_qty: null,
price: null price: null
}, },
qties_values = {}; qties_values = {},
clicked_order_pill = null,
userAgent = navigator.userAgent;
timerId = null,
info_editor = null;
var dbc = null, var dbc = null,
sync = null, sync = null,
fingerprint = null,
order_doc = { order_doc = {
_id: null, _id: null,
coverage_days: null, coverage_days: null,
...@@ -27,11 +33,12 @@ var dbc = null, ...@@ -27,11 +33,12 @@ var dbc = null,
selected_suppliers: [], selected_suppliers: [],
selected_rows: [] selected_rows: []
}, },
fingerprint = null; common_info_doc_name = "common_info",
info_doc = {
_id: null,
content: ""
};
var clicked_order_pill = null;
let userAgent = navigator.userAgent;
var timerId = null;
/* - UTILS */ /* - UTILS */
...@@ -125,7 +132,9 @@ function debounceFunction(func, delay = 1000) { ...@@ -125,7 +132,9 @@ function debounceFunction(func, delay = 1000) {
timerId = setTimeout(func, delay); timerId = setTimeout(func, delay);
} }
/* - PRODUCTS */ /* - PRODUCTS */
var process_new_product_qty = function(input) { var process_new_product_qty = function(input) {
// Remove line coloring on input blur // Remove line coloring on input blur
const row = $(input).closest('tr'); const row = $(input).closest('tr');
...@@ -188,6 +197,7 @@ var process_new_product_qty = function(input) { ...@@ -188,6 +197,7 @@ var process_new_product_qty = function(input) {
} }
} }
}; };
/** /**
* Add a product. * Add a product.
* *
...@@ -2150,20 +2160,25 @@ function update_order_selection_screen() { ...@@ -2150,20 +2160,25 @@ function update_order_selection_screen() {
// Remove listener before recreating them // Remove listener before recreating them
$(".order_pill").off(); $(".order_pill").off();
// Reset orders data
let existing_orders_container = $("#existing_orders"); let existing_orders_container = $("#existing_orders");
existing_orders_container.empty(); existing_orders_container.empty();
$('#new_order_name').val(''); $('#new_order_name').val('');
if (result.rows.length === 0) { if (
result.rows.length === 0
|| result.rows.length === 0 && result.rows[0].id === common_info_doc_name) {
existing_orders_container.append(`<i>Aucune commande en cours...</i>`); existing_orders_container.append(`<i>Aucune commande en cours...</i>`);
} else { } else {
for (let row of result.rows) { for (let row of result.rows) {
let template = $("#templates #order_pill_template"); if (row.id !== common_info_doc_name) {
let template = $("#templates #order_pill_template");
template.find(".pill_order_name").text(row.id); template.find(".pill_order_name").text(row.id);
existing_orders_container.append(template.html()); existing_orders_container.append(template.html());
}
} }
$(".order_pill").on("click", order_pill_on_click); $(".order_pill").on("click", order_pill_on_click);
...@@ -2288,6 +2303,15 @@ function init_pouchdb_sync() { ...@@ -2288,6 +2303,15 @@ function init_pouchdb_sync() {
); );
back(); back();
break; break;
} else if (doc._id === common_info_doc_name) {
init_info_editor();
$.notify(
"Nouveau message dans le bloc d'information !",
{
globalPosition:"top right",
className: "info"
}
);
} }
} }
...@@ -2303,11 +2327,162 @@ function init_pouchdb_sync() { ...@@ -2303,11 +2327,162 @@ function init_pouchdb_sync() {
}); });
} }
/* - INFO AREA */
/**
* Init the Quill module (Text editor)
* @param {Object} params
*/
function quillify(params) {
info_editor = new Quill(params.id, {
modules: {
toolbar: [
[
{ header: [
1,
2,
false
] }
],
[
'bold',
'italic',
'underline'
],
[
{ 'size': [
'small',
false,
'large',
'huge'
] }
],
[
{ 'color': [] },
{ 'background': [] }
]
]
},
placeholder: "Indiquez ici un message pour le reste de l'équipe",
theme: 'snow'
});
info_editor.root.innerHTML = params.content;
}
/**
* Init object & dom for the info editor.
* Await retrieving content.
*/
async function init_info_editor() {
let info_content = await get_or_create_common_info();
// Reset info editor
info_editor = null;
$("#common_info_editor_container").empty();
$("#common_info_editor_container").append(`<div id="common_info_editor"></div>`);
// Init text editor for Info textarea
let quill_params = {
id: '#common_info_editor',
content: info_content
};
quillify(quill_params);
$("#save_common_info").on("click", function() {
if (is_time_to('save_common_info', 1000)) {
let content = $("#common_info_editor").find('.ql-editor')
.html();
if (content === "<p><br></p>") {
content = "";
}
update_common_info(content);
}
});
}
/**
* Get common info HTML content. If doc doesn't exist, create & return empty string
* @returns String HTML content | ""
*/
function get_or_create_common_info() {
// todo await async
return new Promise((resolve) => {
dbc.get(common_info_doc_name).then((doc) => {
info_doc = doc;
resolve(doc.content);
})
.catch(function (err) {
if (err.status == 404) {
// First access, create
info_doc._id = common_info_doc_name;
dbc.put(info_doc, function callback(err, result) {
if (!err) {
info_doc._rev = result.rev;
} else {
$.notify(
"Erreur lors de l'initialisation du bloc d'informations",
{
globalPosition:"top right",
className: "error"
}
);
console.log(err);
}
resolve("");
});
} else {
$.notify(
"Erreur lors de la récupération du bloc d'informations",
{
globalPosition:"top right",
className: "error"
}
);
console.log(err);
resolve("");
}
});
});
}
/**
* Update couchdb info document with textarea (HTML) content
* @param {String} content
*/
function update_common_info(content) {
info_doc.content = content;
dbc.put(info_doc, function callback(err, result) {
if (!err) {
info_doc._rev = result.rev;
$.notify(
"Bloc d'informations mis à jour",
{
globalPosition:"top right",
className: "success"
}
);
} else {
$.notify(
"Erreur lors de la mise à jour du bloc d'informations",
{
globalPosition:"top right",
className: "error"
}
);
console.log(err);
}
});
}
$(document).ready(function() { $(document).ready(function() {
if (coop_is_connected()) { if (coop_is_connected()) {
$('#new_order_form').show(); $('#new_order_form').show();
$('#existing_orders_area').show(); $('#existing_orders_area').show();
$('#common_info_area').show();
fingerprint = new Fingerprint({canvas: true}).get(); fingerprint = new Fingerprint({canvas: true}).get();
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } }); $.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
...@@ -2555,6 +2730,7 @@ $(document).ready(function() { ...@@ -2555,6 +2730,7 @@ $(document).ready(function() {
// Order selection screen // Order selection screen
update_order_selection_screen(); update_order_selection_screen();
init_info_editor();
$("#new_order_form").on("submit", function(e) { $("#new_order_form").on("submit", function(e) {
e.preventDefault(); e.preventDefault();
...@@ -2585,8 +2761,6 @@ $(document).ready(function() { ...@@ -2585,8 +2761,6 @@ $(document).ready(function() {
$("#supplier_input").autocomplete({ $("#supplier_input").autocomplete({
source: suppliers_list.map(a => a.display_name) source: suppliers_list.map(a => a.display_name)
}); });
}, },
error: function(data) { error: function(data) {
err = {msg: "erreur serveur lors de la récupération des fournisseurs", ctx: 'get_suppliers'}; err = {msg: "erreur serveur lors de la récupération des fournisseurs", ctx: 'get_suppliers'};
...@@ -2694,7 +2868,6 @@ $(document).ready(function() { ...@@ -2694,7 +2868,6 @@ $(document).ready(function() {
} }
}); });
} }
} else { } else {
$('#not_connected_content').show(); $('#not_connected_content').show();
} }
......
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test import Client
class TestUrls(SimpleTestCase): class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self): def testOrdersUrlIsResolved(self):
assert 1==1
\ No newline at end of file c = Client()
response = c.get('/orders/')
assert response.status_code == 200, "Orders url is not resolved"
...@@ -53,8 +53,13 @@ function subscribe_shift(shift_t_id) { ...@@ -53,8 +53,13 @@ function subscribe_shift(shift_t_id) {
var s_data = shift_templates[shift_t_id].data; var s_data = shift_templates[shift_t_id].data;
var shift_name = get_shift_name(s_data); var shift_name = get_shift_name(s_data);
if (committees_shift_id !== undefined && committees_shift_id !== "None" && shift_name === "Volant") {
shift_name = 'des Comités'
}
let msg = 'On inscrit le membre au créneau ' + shift_name
openModal( openModal(
'On inscrit le membre au créneau ' + shift_name, msg,
function() { function() {
closeModal(); closeModal();
current_coop.shift_template = shift_templates[shift_t_id]; current_coop.shift_template = shift_templates[shift_t_id];
...@@ -327,7 +332,14 @@ function retrieve_and_draw_shift_tempates() { ...@@ -327,7 +332,14 @@ function retrieve_and_draw_shift_tempates() {
$.each(shift_templates, function(i, e) { $.each(shift_templates, function(i, e) {
if (e.data.type == 2 && volant == null) { if (e.data.type == 2 && volant == null) {
volant = e.data.id; // has comitee shift
if (committees_shift_id !== undefined && committees_shift_id !== "None") {
if (e.data.id == parseInt(committees_shift_id)) {
volant = e.data.id
}
} else {
volant = e.data.id;
}
} }
}); });
......
from django.test import SimpleTestCase
class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self):
assert 1==1
\ No newline at end of file
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
}, },
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint . --max-warnings 326 '**/*.js'", "lint": "eslint . --max-warnings 292 '**/*.js'",
"lint-fix": "eslint . --fix --max-warnings 326 '**/*.js'" "lint-fix": "eslint . --fix --max-warnings 292 '**/*.js'"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
......
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test import Client
class TestUrls(SimpleTestCase): class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self): def testProductsUrlIsResolved(self):
assert 1==1
\ No newline at end of file c = Client()
response = c.get('/products/')
assert response.status_code == 200, "Products url is not resolved"
...@@ -30,7 +30,8 @@ var reception_status = null, ...@@ -30,7 +30,8 @@ var reception_status = null,
updatedProducts = [], // Keep record of updated products updatedProducts = [], // Keep record of updated products
validProducts = [], // Keep record of directly validated products validProducts = [], // Keep record of directly validated products
updateType = "", // step 1: qty_valid; step2: br_valid updateType = "", // step 1: qty_valid; step2: br_valid
barcodes = null; // Barcodes stored locally barcodes = null, // Barcodes stored locally
priceToWeightIsCorrect = true;
var dbc = null, var dbc = null,
sync = null, sync = null,
...@@ -67,38 +68,56 @@ function searchUpdatedProduct() { ...@@ -67,38 +68,56 @@ function searchUpdatedProduct() {
function select_product_from_bc(barcode) { function select_product_from_bc(barcode) {
try { try {
if (editing_product == null) { if (editing_product == null) {
let p = barcodes.get_corresponding_odoo_product(barcode); var scannedProduct = barcodes.get_corresponding_odoo_product(barcode);
if (p == null) { priceToWeightIsCorrect = true;
if (scannedProduct == null) {
alert("Le code-barre " + barcode + " ne correspond à aucun article connu."); alert("Le code-barre " + barcode + " ne correspond à aucun article connu.");
return -1; return -1;
} }
var found = {data: null, place: null}; var foundProduct = {data: null, place: null};
$.each(list_to_process, function(i, e) { $.each(list_to_process, function(i, e) {
if (e.product_id[0] == p.data[barcodes['keys']['id']]) { if (e.product_id[0] == scannedProduct.data[barcodes['keys']['id']]) {
found.data = e; foundProduct.data = e;
found.place = 'to_process'; foundProduct.place = 'to_process';
} }
}); });
if (found.data == null) { if (foundProduct.data == null) {
$.each(list_processed, function(i, e) { $.each(list_processed, function(i, e) {
if (e.product_id[0] == p.data[barcodes['keys']['id']]) { if (e.product_id[0] == scannedProduct.data[barcodes['keys']['id']]) {
found.data = JSON.parse(JSON.stringify(e)); foundProduct.data = JSON.parse(JSON.stringify(e));
found.place = 'processed'; foundProduct.data.product_qty = null;
foundProduct.place = 'processed';
} }
}); });
} }
if (found.data !== null) { if (foundProduct.data !== null) {
setLineEdition(found.data); if (foundProduct.data.product_uom[0] == 21) { //if qty is in weight
if (found.place === 'to_process') { if (scannedProduct.rule === 'weight') {
let row = table_to_process.row($('#'+found.data.product_id[0])); editing_product = foundProduct.data;
editProductInfo(foundProduct.data, scannedProduct.qty);
editing_product = null;
} else if (scannedProduct.rule === 'price_to_weight') {
openModal($('#templates #modal_confirm_price_to_weight').html(), price_to_weight_is_wrong, 'Non', false, true, price_to_weight_confirmed_callback(foundProduct, scannedProduct));
setupPopUpBtnStyle(scannedProduct);
}
}
if (scannedProduct.rule !== 'price_to_weight') {
if (foundProduct.data.product_uom[0] != 21) {
setLineEdition(foundProduct.data);
}
if (foundProduct.place === 'to_process') {
let row = table_to_process.row($('#'+foundProduct.data.product_id[0]));
remove_from_toProcess(row, found.data); remove_from_toProcess(row, foundProduct.data);
}
} }
} }
} }
...@@ -156,6 +175,65 @@ function update_distant_orders() { ...@@ -156,6 +175,65 @@ function update_distant_orders() {
}); });
} }
function price_to_weight_confirmed_callback(foundProduct, scannedProduct) {
return function() {
let newQty = null;
if (priceToWeightIsCorrect) {
newQty = scannedProduct.qty;
} else {
let tmp = Number((scannedProduct.value/document.getElementById("new_price_to_weight").value).toFixed(3));
if (isFinite(tmp)) {
newQty = tmp;
}
}
if (foundProduct.data !== null && newQty != null) {
if (foundProduct.place === 'to_process') {
let row = table_to_process.row($('#'+foundProduct.data.product_id[0]));
remove_from_toProcess(row, foundProduct.data);
}
editing_product = foundProduct.data;
editProductInfo(foundProduct.data, newQty);
editing_product = null;
resetPopUpButtons();
}
};
}
function price_to_weight_is_wrong() {
document.getElementById("new_price_to_weight").style.display = "";
document.getElementsByClassName("btn--success")[0].style.display = "none";
document.querySelector('#modal_closebtn_bottom').innerHTML = 'OK';
priceToWeightIsCorrect = false;
}
function setupPopUpBtnStyle(p) {
//On inverse en quelque sorte les boutons succes et d'annulation en mettant "Oui" sur le btn d'annulation
// et "Non" sur le bouton de reussite.
//Cela nous permet de reecrire moins de code puisque si la reponse est Oui on ne veut
//rien modifier et sortir du pop up, ce qui correspond au comportement du bouton annulation
//(ou aussi appeler cancel button)
document.querySelector('#modal_closebtn_bottom').innerHTML = 'Oui';
document.getElementById("modal_closebtn_bottom").style.backgroundColor = "green";
document.getElementsByClassName("btn--success")[0].style.backgroundColor = "red";
document.querySelector('#product_to_verify').innerHTML = p.data[0];
document.querySelector('#price_to_verify').innerHTML = p.data[6];
document.getElementById("new_price_to_weight").style.display = "none";
document.getElementsByClassName("btn--success")[0].style.display = "";
}
function resetPopUpButtons() {
document.getElementsByClassName("btn--success")[0].style.display = "";
document.getElementsByClassName("btn--success")[0].style.backgroundColor = "";
document.querySelector('#modal_closebtn_bottom').style.backgroundColor = "";
}
/* INIT */ /* INIT */
// Get order(s) data from server // Get order(s) data from server
...@@ -857,36 +935,47 @@ function editProductInfo (productToEdit, value = null, batch = false) { ...@@ -857,36 +935,47 @@ function editProductInfo (productToEdit, value = null, batch = false) {
// Check if the product is already in the 'updated' list // Check if the product is already in the 'updated' list
var index = searchUpdatedProduct(); var index = searchUpdatedProduct();
var firstUpdate = false; var firstUpdate = false;
var isValid = false;
let newValue = value; let newValue = value;
var addition = false; var addition = false;
// If 'value' parameter not set, get value from edition input // If 'value' parameter not set, get value from edition input
if (value == null) { if (value == null) {
newValue = parseFloat(document.getElementById('edition_input').value.replace(',', '.')); newValue = parseFloat(document.getElementById('edition_input').value.replace(',', '.'));
newValue = newValue.isFinite() ? newValue : 0;
} }
$.each(list_processed, function(i, e) { $.each(list_processed, function(i, e) {
if (e.product_id[0] == productToEdit.product_id[0]) { if (e.product_id[0] == productToEdit.product_id[0]) {
addition = true; addition = true;
productToEdit = e; productToEdit = e;
newValue = newValue + productToEdit.product_qty; newValue = Number((newValue + productToEdit.product_qty).toFixed(3));
} }
}); });
// If qty edition & Check if qty changed // If qty edition & Check if qty changed
if (reception_status == "False" && productToEdit.product_qty != newValue) { if (reception_status == "False") {
if (index == -1) { // First update firstUpdate = (index == -1); //first update
productToEdit.old_qty = productToEdit.product_qty; if (productToEdit.product_qty != newValue) {
firstUpdate = true; if (firstUpdate) {
} productToEdit.old_qty = productToEdit.product_qty;
} else {
//if it is not the first update AND newValue is equal to the validation qty then the product is valid
isValid = (newValue === productToEdit.old_qty);
}
// Edit product info // Edit product info
productToEdit.product_qty = newValue; productToEdit.product_qty = newValue;
/* /*
If qty has changed, we choose to set detailed values as follow: If qty has changed, we choose to set detailed values as follow:
1 package (product_qty_package) of X products (package_qty) 1 package (product_qty_package) of X products (package_qty)
*/ */
productToEdit.product_qty_package = 1; productToEdit.product_qty_package = 1;
productToEdit.package_qty = productToEdit.product_qty; productToEdit.package_qty = productToEdit.product_qty;
} else if (firstUpdate) {
// if the product is updated for the first time and productQty is equal to the newValue then the product is validated
isValid = true;
}
} }
// Check if price changed // Check if price changed
...@@ -920,27 +1009,56 @@ function editProductInfo (productToEdit, value = null, batch = false) { ...@@ -920,27 +1009,56 @@ function editProductInfo (productToEdit, value = null, batch = false) {
if (firstUpdate) { if (firstUpdate) {
updatedProducts.push(productToEdit); updatedProducts.push(productToEdit);
// Create 'updated_products' list in order if not exists //if product is validated thru edition -> add to valid_products
if (!orders[productToEdit.id_po]['updated_products']) { if (isValid) {
orders[productToEdit.id_po]['updated_products'] = []; // Create 'valid_products' list in order if not exists
} if (!orders[productToEdit.id_po]['valid_products']) {
orders[productToEdit.id_po]['valid_products'] = [];
}
orders[productToEdit.id_po]['valid_products'].push(productToEdit['id']);
} else {
// Create 'updated_products' list in order if not exists
if (!orders[productToEdit.id_po]['updated_products']) {
orders[productToEdit.id_po]['updated_products'] = [];
}
// Add product to order's updated products if first update // Add product to order's updated products if first update
orders[productToEdit.id_po]['updated_products'].push(productToEdit); orders[productToEdit.id_po]['updated_products'].push(productToEdit);
// May have been directly validated then updated from processed list // May have been directly validated then updated from processed list
// -> remove from 'valid_products' list // -> remove from 'valid_products' list
for (i in orders[productToEdit.id_po]['valid_products']) { for (i in orders[productToEdit.id_po]['valid_products']) {
if (orders[productToEdit.id_po]['valid_products'][i] == productToEdit['id']) { if (orders[productToEdit.id_po]['valid_products'][i] == productToEdit['id']) {
orders[productToEdit.id_po]['valid_products'].splice(i, 1); orders[productToEdit.id_po]['valid_products'].splice(i, 1);
}
} }
} }
} else { } else {
// Look for product in order's updated products list
for (i in orders[productToEdit.id_po]['updated_products']) { if (isValid) {
if (orders[productToEdit.id_po]['updated_products'][i]['product_id'][0] //if product is valid -> remove from updated_products list and add to valid_products list
== productToEdit['product_id'][0]) { //removing from updated_products
orders[productToEdit.id_po]['updated_products'][i] = productToEdit; for (i in orders[productToEdit.id_po]['updated_products']) {
if (orders[productToEdit.id_po]['updated_products'][i]['product_id'][0]
== productToEdit['product_id'][0]) {
orders[productToEdit.id_po]['updated_products'].splice(i, 1);
}
}
//add to valid_products
// Create 'valid_products' list in order if not exists
if (!orders[productToEdit.id_po]['valid_products']) {
orders[productToEdit.id_po]['valid_products'] = [];
}
orders[productToEdit.id_po]['valid_products'].push(productToEdit['id']);
} else {
// Look for product in order's updated products list
for (i in orders[productToEdit.id_po]['updated_products']) {
if (orders[productToEdit.id_po]['updated_products'][i]['product_id'][0]
== productToEdit['product_id'][0]) {
orders[productToEdit.id_po]['updated_products'][i] = productToEdit;
}
} }
} }
} }
......
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test import Client
class TestUrls(SimpleTestCase): class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self): def testReceptionUrlIsResolved(self):
assert 1==1
\ No newline at end of file c = Client()
response = c.get('/reception/')
assert response.status_code == 200 , "Reception url is not resolved"
from django.test import SimpleTestCase from django.test import SimpleTestCase
\ No newline at end of file
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test import Client
class TestUrls(SimpleTestCase): class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self): def testSalesUrlIsResolved(self):
assert 1==1
\ No newline at end of file c = Client()
response = c.get('/sales/')
assert response.status_code == 200, "Sales url is not resolved"
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test import Client
class TestUrls(SimpleTestCase): class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self): def testShelfsUrlIsResolved(self):
assert 1==1
\ No newline at end of file c = Client()
response = c.get('/shelfs/')
assert response.status_code == 200, "Shelfs url is not resolved"
from django.test import SimpleTestCase
class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self):
assert 1==1
\ No newline at end of file
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test import Client
class TestUrls(SimpleTestCase): class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self): def testShopUrlIsResolved(self):
assert 1==1
\ No newline at end of file c = Client()
response = c.get('/shop/')
assert response.status_code == 200, "Shop url is not resolved"
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test import Client
class TestUrls(SimpleTestCase): class TestUrls(SimpleTestCase):
def test_list_url_is_resolved(self): def testStockUrlIsResolved(self):
assert 1==1
\ No newline at end of file c = Client()
response = c.get('/stock/')
assert response.status_code == 200, "Stock url is not resolved"
...@@ -178,9 +178,11 @@ ...@@ -178,9 +178,11 @@
auto_compaction: false auto_compaction: false
}); });
var mag_place_string = '{{mag_place_string}}'; var mag_place_string = '{{mag_place_string}}';
var office_place_string = '{{office_place_string}}' var office_place_string = '{{office_place_string}}';
var max_begin_hour = '{{max_begin_hour}}' var max_begin_hour = '{{max_begin_hour}}';
var email_domain = '{{email_domain}}' var email_domain = '{{email_domain}}';
var committees_shift_id = '{{committees_shift_id}}';
</script> </script>
<script src="{% static "js/all_common.js" %}?v="></script> <script src="{% static "js/all_common.js" %}?v="></script>
<script src="{% static "js/common.js" %}?v="></script> <script src="{% static "js/common.js" %}?v="></script>
......
...@@ -5,12 +5,14 @@ ...@@ -5,12 +5,14 @@
<link rel="stylesheet" href="{% static 'css/datatables/jquery.dataTables.css' %}"> <link rel="stylesheet" href="{% static 'css/datatables/jquery.dataTables.css' %}">
<link rel="stylesheet" href="{% static 'jquery-ui-1.12.1/jquery-ui.min.css' %}"> <link rel="stylesheet" href="{% static 'jquery-ui-1.12.1/jquery-ui.min.css' %}">
<link rel="stylesheet" href="{% static 'css/oders_helper_style.css' %}"> <link rel="stylesheet" href="{% static 'css/oders_helper_style.css' %}">
<link rel="stylesheet" href="{% static 'quill/quill.snow.css' %}">
{% endblock %} {% endblock %}
{% block additionnal_scripts %} {% block additionnal_scripts %}
<script type="text/javascript" src="{% static 'jquery-ui-1.12.1/jquery-ui.min.js' %}?v="></script> <script type="text/javascript" src="{% static 'jquery-ui-1.12.1/jquery-ui.min.js' %}?v="></script>
<script type="text/javascript" src="{% static 'js/datatables/jquery.dataTables.min.js' %}"></script> <script type="text/javascript" src="{% static 'js/datatables/jquery.dataTables.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/notify.min.js' %}?v="></script> <script type="text/javascript" src="{% static 'js/notify.min.js' %}?v="></script>
<script type="text/javascript" src="{% static 'quill/quill.min.js' %}"></script>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
...@@ -33,6 +35,13 @@ ...@@ -33,6 +35,13 @@
<h2>Ou, continuer une commande en cours de création</h2> <h2>Ou, continuer une commande en cours de création</h2>
<div id="existing_orders"></div> <div id="existing_orders"></div>
</div> </div>
<div id="common_info_area" style="display:none;">
<h2>Informations</h2>
<div id="common_info_editor_container">
<div id="common_info_editor"></div>
</div>
<button class="btn--primary" id="save_common_info">Sauvegarder</button>
</div>
</div> </div>
<div id="main_content" class="page_content" style="display:none;"> <div id="main_content" class="page_content" style="display:none;">
...@@ -41,7 +50,6 @@ ...@@ -41,7 +50,6 @@
<i class="fas fa-arrow-left"></i>&nbsp; Retour <i class="fas fa-arrow-left"></i>&nbsp; Retour
</button> </button>
<div class="right_action_buttons"> <div class="right_action_buttons">
<div id="actions_buttons_wrapper"> <div id="actions_buttons_wrapper">
<button type="button" class='btn--primary' id="toggle_action_buttons"> <button type="button" class='btn--primary' id="toggle_action_buttons">
<span class="button_content"> <span class="button_content">
...@@ -214,7 +222,7 @@ ...@@ -214,7 +222,7 @@
<p class="remove_order_modal_text"> <p class="remove_order_modal_text">
Vous vous apprêtez à <b style="color: #d9534f;">supprimer</b> cette commande en cours : <span class="remove_order_name"></span>.<br/> Vous vous apprêtez à <b style="color: #d9534f;">supprimer</b> cette commande en cours : <span class="remove_order_name"></span>.<br/>
</p> </p>
<p>Êtez-vous sûr ?</p> <p>Êtez-vous sûr.e ?</p>
<hr/> <hr/>
</div> </div>
...@@ -225,7 +233,7 @@ ...@@ -225,7 +233,7 @@
Les produits associés uniquement à ce fournisseur seront supprimés du tableau.<br/> Les produits associés uniquement à ce fournisseur seront supprimés du tableau.<br/>
Les données renseignées dans la colonne de ce fournisseur seront perdues. Les données renseignées dans la colonne de ce fournisseur seront perdues.
</p> </p>
<p>Êtez-vous sûr ?</p> <p>Êtez-vous sûr.e ?</p>
<hr/> <hr/>
</div> </div>
...@@ -251,7 +259,7 @@ ...@@ -251,7 +259,7 @@
<p> <p>
L'association sera sauvegardée dès que vous aurez cliqué sur "Valider".<br/> L'association sera sauvegardée dès que vous aurez cliqué sur "Valider".<br/>
</p> </p>
<p>Êtez-vous sûr ?</p> <p>Êtez-vous sûr.e ?</p>
<hr/> <hr/>
</div> </div>
...@@ -264,7 +272,7 @@ ...@@ -264,7 +272,7 @@
<p> <p>
L'association sera supprimée dès que vous aurez cliqué sur "Valider".<br/> L'association sera supprimée dès que vous aurez cliqué sur "Valider".<br/>
</p> </p>
<p>Êtez-vous sûr ?</p> <p>Êtez-vous sûr.e ?</p>
<hr/> <hr/>
</div> </div>
...@@ -272,7 +280,7 @@ ...@@ -272,7 +280,7 @@
<p> <p>
Vous vous apprêtez à créer un inventaire de <span class="inventory_products_count"></span> produits. Vous vous apprêtez à créer un inventaire de <span class="inventory_products_count"></span> produits.
</p> </p>
<p>Êtez-vous sûr ?</p> <p>Êtez-vous sûr.e ?</p>
<hr/> <hr/>
</div> </div>
......
...@@ -177,6 +177,12 @@ ...@@ -177,6 +177,12 @@
<div id="modal_FAQ_content"></div> <div id="modal_FAQ_content"></div>
<div id="modal_qtiesValidated"></div> <div id="modal_qtiesValidated"></div>
<div id="modal_pricesValidated"></div> <div id="modal_pricesValidated"></div>
<div id="modal_confirm_price_to_weight">
<h3>Confirmation du prix</h3>
<p>Est ce que le prix au kilo du produit <b><span id="product_to_verify"></span></b>
est bien <b><span id="price_to_verify"></span></b> euros/Kg ?</p>
<input type="number" name="Prix au Kilo" id="new_price_to_weight">
</div>
</div> </div>
<br/> <br/>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment