From 4e1ec778c13781d50d1b005411b7dff68a0ce09f Mon Sep 17 00:00:00 2001 From: keplyx Date: Thu, 12 Sep 2019 00:08:46 +0200 Subject: [PATCH] Added ability to edit article categories, added compatibility conversion between stock json versions --- admin/categories.php | 87 ++++++++++++++++++++++++ admin/convert_json.php | 57 ++++++++++++++++ admin/index.php | 87 +++--------------------- admin/stock.php | 113 +++++++++++++++++++++++++++++++ admin/write_json.php | 6 +- ajax/scan_article.php | 2 +- assets/css/admin.css | 9 +++ assets/css/categories.css | 19 ++++++ assets/css/stock.css | 14 ++-- assets/js/categories.js | 135 ++++++++++++++++++++++++++++++++++++++ assets/js/saveManager.js | 78 ++++++++++++++++++++++ assets/js/stock.js | 86 ++++++++++-------------- 12 files changed, 556 insertions(+), 137 deletions(-) create mode 100644 admin/categories.php create mode 100644 admin/convert_json.php create mode 100644 admin/stock.php create mode 100644 assets/css/admin.css create mode 100644 assets/css/categories.css create mode 100644 assets/js/categories.js create mode 100644 assets/js/saveManager.js diff --git a/admin/categories.php b/admin/categories.php new file mode 100644 index 0000000..c20403b --- /dev/null +++ b/admin/categories.php @@ -0,0 +1,87 @@ + + + Id + Nom + + + Icone + + + + Actions + + +
+ + + + + +

Gestion des Catégories

+

Ajouter une catégorie

+ + + + + + + + + + +
+ + + + + + + +
+ +

Liste des catégories

+ + + + +
+ +
+ +
+ + + + + + + + + + + +"; +include($relativePath . "includes/template.php"); +?> diff --git a/admin/convert_json.php b/admin/convert_json.php new file mode 100644 index 0000000..09e427f --- /dev/null +++ b/admin/convert_json.php @@ -0,0 +1,57 @@ + strval($counter), "name" => $type, "icon" => "file"]); + $counter += 1; + } + return $newTypes; +} + +function getConvertedArticles($articles, $newTypes) { + foreach ($articles as $article) { + $article->description = "Pas de description"; + foreach ($article->type as $key=>$value) { + $article->type[$key] = getTypeIdFromName($value, $newTypes); + } + } + return $articles; +} + +function getTypeIdFromName($name, $types) { + foreach ($types as $type) { + if ($type->name == $name) + return $type->id; + } +} + +if ($result) { + echo 'Conversion en cours... + '; + $newTypes = getConvertedTypes($result->types); + $newArticles = getConvertedArticles($result->articles, $newTypes); + $v2File = json_encode(["types"=>$newTypes, "articles"=>$newArticles]); + echo 'Conversion réussie... + '; + echo 'Sauvegarde dans fichier V2... + '; + $fp = fopen('../data/stock-v2.json', 'w'); + $result = fwrite($fp, $v2File); + fclose($fp); + echo 'Sauvegarde réussie... + '; +} else { + echo 'Echec! + '; // Allows to create a newline + var_dump($_POST); +} diff --git a/admin/index.php b/admin/index.php index 482d9a2..58ec880 100644 --- a/admin/index.php +++ b/admin/index.php @@ -1,87 +1,20 @@ - - Nom - Quantité - Prix - Code Barre - Type - Image - Actions - - -
- -

Gestion des Stocks

-

Ajouter un article

- - - - - - - - - - - - - -
- - - - - - - - - - - - - -
- -

Liste d'articles

- - - - -
- -
- -
- - - - - - - + + "; +$pageTitle = "Admin"; include($relativePath . "includes/template.php"); ?> diff --git a/admin/stock.php b/admin/stock.php new file mode 100644 index 0000000..167012d --- /dev/null +++ b/admin/stock.php @@ -0,0 +1,113 @@ + + + Nom + Description + Quantité + Prix + Code Barre + Type + Image + Actions + + +
+ + + + + +

Gestion des Stocks

+ +

Ajouter un article

+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +

Liste d'articles

+ + + + +
+ +
+ +
+ +

Fichier de stock V2 non trouvé

+
+ +
+ + + + + + + + + + + +"; +include($relativePath . "includes/template.php"); +?> diff --git a/admin/write_json.php b/admin/write_json.php index f3069e0..3526666 100644 --- a/admin/write_json.php +++ b/admin/write_json.php @@ -5,8 +5,12 @@ $_POST = json_decode($rest_json, true); //var_dump($_POST); +$fp = fopen('../data/stock-v2.json', 'w'); +$result = fwrite($fp, json_encode($_POST["v2"])); +fclose($fp); + $fp = fopen('../data/stock.json', 'w'); -$result = fwrite($fp, json_encode($_POST)); +$result = fwrite($fp, json_encode($_POST["v1"])); fclose($fp); if ($result) { diff --git a/ajax/scan_article.php b/ajax/scan_article.php index 5cde426..8e640e0 100644 --- a/ajax/scan_article.php +++ b/ajax/scan_article.php @@ -11,7 +11,7 @@ if ($_POST["password"] != $password) die("Wrong Password"); // open the file and get the stock -$file = '../data/stock.json'; +$file = '../data/stock-v2.json'; $fp = fopen($file, 'r'); $result = json_decode(fread($fp, filesize($file))); fclose($fp); diff --git a/assets/css/admin.css b/assets/css/admin.css new file mode 100644 index 0000000..82c68ee --- /dev/null +++ b/assets/css/admin.css @@ -0,0 +1,9 @@ +.admin-container { + width: 90%; + margin: 50px auto auto auto; +} + +table { + width: 100%; + margin-bottom: 20px; +} diff --git a/assets/css/categories.css b/assets/css/categories.css new file mode 100644 index 0000000..072e5b1 --- /dev/null +++ b/assets/css/categories.css @@ -0,0 +1,19 @@ +#categoriesTable tr { + border-bottom: 1px solid #dedede; +} + +.mdi { + font-size: 2rem; +} + +.actions-column { + width: 100px; +} + +.id-column { + width: 200px; +} + +.icon-column { + width: 200px; +} diff --git a/assets/css/stock.css b/assets/css/stock.css index b1eeccc..52c0129 100644 --- a/assets/css/stock.css +++ b/assets/css/stock.css @@ -1,6 +1,6 @@ -table { - width: 100%; - margin-bottom: 20px; + +.name-column { + width: 200px; } .quantity-column, .price-column { @@ -24,12 +24,10 @@ table { width: 100px; } -.stock-container { - width: 90%; - margin: 50px auto auto auto; -} - #stockTable tr { border-bottom: 1px solid #dedede; } +.row-img { + height: 50px; +} diff --git a/assets/js/categories.js b/assets/js/categories.js new file mode 100644 index 0000000..666e537 --- /dev/null +++ b/assets/js/categories.js @@ -0,0 +1,135 @@ +let currentDataset = []; +let currentTypes = []; +let originalEditedItem = {}; + +function initValuesFromPHPDump() { + currentDataset = json_dump.articles; // json_dump is set using PHP + currentTypes = json_dump.types; + console.log(currentDataset); + console.log(currentTypes); + generateTable(currentTypes); +} + + +$(document).ready(function () { + initValuesFromPHPDump(); + setEditFieldValues('', '', ''); +}); + + +function generateTable(dataset) { + for (let i = 0; i < dataset.length; i++) { + generateLine(dataset[i]); + } +} + +function generateLine(item) { + $.selector_cache('#categoriesTable').append( + '' + + '' + item.id + '' + + '' + item.name + '' + + '' + + '' + + '' + + '' + + '' + + '' + ); +} + +function addNewItem() { + if (isItemInputFilled()) { + let item = { + id: $.selector_cache('#idInput').val(), + name: $.selector_cache('#nameInput').val(), + icon: $.selector_cache('#iconInput').val(), + }; + if (isIdAvailable(item.id)) { + updateExistingItemsType(originalEditedItem.id, item.id); + setEditFieldValues('', '', ''); + currentTypes.push(item); + generateLine(item); + } + } +} + +function editItem(elem) { + if (isItemInputEmpty()) { + let id = elem.id.replace('edit_', ''); + let item = getTypeOfId(id); + originalEditedItem = item; + setEditFieldValues(item.id, item.name, item.icon); + removeItemFromList(item); // Move the item in the edit fields + } +} + +function deleteItem(elem) { + let id = elem.id.replace('delete_', ''); + let item = getTypeOfId(id); + updateExistingItemsType(id, undefined); + removeItemFromList(item); +} + +function removeItemFromList(item) { + currentTypes.splice(currentTypes.indexOf(item), 1); + $('#row_' + item.id).remove(); +} + +function setEditFieldValues(id, name, icon) { + $.selector_cache('#idInput').val(id); + $.selector_cache('#nameInput').val(name); + $.selector_cache('#iconInput').val(icon); +} + +function updateExistingItemsType(oldTypeID, newTypeID) { + for (let i = 0; i < currentDataset.length; i++) { + for (let k = 0; k < currentDataset[i].type.length; k++) { + if (currentDataset[i].type[k] === oldTypeID) { + console.log(newTypeID); + if (newTypeID !== undefined) + currentDataset[i].type[k] = newTypeID; + else + currentDataset[i].type.splice(k, 1); + break; + } + } + } +} + +function getTypeOfId(id) { + let item = {}; + for (let i = 0; i < currentTypes.length; i++) { + if (currentTypes[i].id === id) { + item = currentTypes[i]; + break; + } + } + return item; +} + +function isIdAvailable(id) { + let isAvailable = true; + for (let i = 0; i < currentTypes.length; i++) { + if (currentTypes[i].id === id) { + isAvailable = false; + break; + } + } + return isAvailable; +} + +function isItemInputEmpty() { + return $.selector_cache('#idInput').val() === '' && + $.selector_cache('#nameInput').val() === '' && + $.selector_cache('#iconInput').val() === ''; +} + +function isItemInputFilled() { + return $.selector_cache('#idInput').val() !== '' && + $.selector_cache('#nameInput').val() !== '' && + $.selector_cache('#iconInput').val() !== ''; +} + +function saveDataset() { + SaveManager.saveData(currentTypes, currentDataset); +} diff --git a/assets/js/saveManager.js b/assets/js/saveManager.js new file mode 100644 index 0000000..c0142f5 --- /dev/null +++ b/assets/js/saveManager.js @@ -0,0 +1,78 @@ + +class SaveManager { + + static saveData(types, dataset) { + let finalDataset = { + v1: SaveManager.generateV1JSON(types, dataset), + v2: SaveManager.generateV2JSON(types, dataset) + }; + console.log(finalDataset); + $.ajax({ + type: "POST", + url: "write_json.php", + data: JSON.stringify(finalDataset), + dataType: "json", + contentType: "application/json; charset=utf-8", + complete: function (data) { + alert(data.responseText); + console.log(data); + }, + }); + } + + static generateV1JSON(savedTypes, savedDataset) { + let types = []; + // Replace type objects by names + for (let i = 0; i < savedTypes.length; i++) { + types.push(savedTypes[i].name); + } + let dataset = JSON.parse(JSON.stringify(savedDataset)); // Deep copy of object + for (let i = 0; i < dataset.length; i++) { + // Replace type ids by names + for (let k = 0; k < dataset[i].type.length; k++) { + dataset[i].type[k] = SaveManager.getTypeOfId(savedTypes, dataset[i].type[k]).name; + } + // remove the description field + delete dataset[i].description + } + return { + types: types, + articles: dataset + } + } + + static generateV2JSON(savedTypes, savedDataset) { + return { + types: savedTypes, + articles: savedDataset + } + } + + static getTypeOfId(types, id) { + let item = {}; + for (let i = 0; i < types.length; i++) { + if (types[i].id === id) { + item = types[i]; + break; + } + } + return item; + } + + static convertToV2() { + $.ajax({ + type: "POST", + url: "convert_json.php", + dataType: "json", + contentType: "application/json; charset=utf-8", + complete: function (data) { + alert(data.responseText); + console.log(data); + window.location.reload(); + }, + }); + } +} + + + diff --git a/assets/js/stock.js b/assets/js/stock.js index dfcf776..337eb23 100644 --- a/assets/js/stock.js +++ b/assets/js/stock.js @@ -1,23 +1,3 @@ -let defaultTypes = [ - 'Nouveau', - 'Alimentaire', - 'Boissons', - 'Utilitaires' -]; - -let defaultStock = [ - { - name: 'Granola', - quantity: '2', - price: '1.3', - code: '7622210601988', - image : 'https://cookieandkate.com/images/2015/10/granola-mixed-in-bowl.jpg', - type: [ - 'Alimentaire', - ] - } -]; - let currentDataset = []; let currentTypes = []; @@ -32,8 +12,11 @@ function initValuesFromPHPDump() { $(document).ready(function () { - initValuesFromPHPDump(); - generateTypeCheckboxes(); + if (json_dump !== undefined) { + initValuesFromPHPDump(); + generateTypeCheckboxes(); + } + setEditFieldValues('', '', '', '', '', '', ''); }); @@ -47,11 +30,12 @@ function generateLine(item) { $.selector_cache('#stockTable').append( '' + '' + item.name + '' + + '' + item.description + '' + '' + item.quantity + '' + '' + item.price + '' + '' + item.code + '' + - '
    ' + - 'LINK' + + '' + + '' + '' + '' + '' + @@ -60,24 +44,37 @@ function generateLine(item) { ); // Fill in the type cell for (let i = 0; i < item.type.length; i++) { + let type = getTypeOfId(item.type[i]); $('#typeList_' + item.code).append( - '
  • ' + item.type[i] + '
  • ' + '' ); } } function generateTypeCheckboxes() { for (let i = 0; i < currentTypes.length; i++) { - let id = 'typeCheck_' + currentTypes[i]; + let id = 'typeCheck_' + currentTypes[i].id; $('#typeCheckboxesCell').append( '
    ' + '' + - '' + + '' + '
    ' ); } } +function getTypeOfId(id) { + let item = {}; + for (let i = 0; i < currentTypes.length; i++) { + if (currentTypes[i].id === id) { + item = currentTypes[i]; + break; + } + } + return item; +} + function getItemOfCode(code) { let item = {}; for (let i = 0; i < currentDataset.length; i++) { @@ -93,6 +90,7 @@ function addNewItem() { if (isItemInputFilled()) { let item = { name: $.selector_cache('#nameInput').val(), + description: $.selector_cache('#descriptionInput').val(), quantity: $.selector_cache('#quantityInput').val(), price: $.selector_cache('#priceInput').val(), code: $.selector_cache('#codeInput').val(), @@ -100,7 +98,7 @@ function addNewItem() { image: $.selector_cache('#imageInput').val(), }; if (isCodeAvailable(item.code)) { - setEditFieldValues('', '', '', '', [], ''); + setEditFieldValues('', '', '', '', [], '', ''); currentDataset.push(item); generateLine(item); } @@ -111,7 +109,7 @@ function editItem(elem) { if (isItemInputEmpty()) { let code = elem.id.replace('edit_', ''); let item = getItemOfCode(code); - setEditFieldValues(item.name, item.quantity, item.price, item.code, item.type, item.image); + setEditFieldValues(item.name, item.description, item.quantity, item.price, item.code, item.type, item.image); removeItemFromList(item); // Move the item in the edit fields } } @@ -130,9 +128,9 @@ function removeItemFromList(item) { function getTypesChecked() { let types = []; for (let i = 0; i < currentTypes.length; i++) { - let id = 'typeCheck_' + currentTypes[i]; + let id = 'typeCheck_' + currentTypes[i].id; if ($('#' + id).is(':checked')) { - types.push(currentTypes[i]); + types.push(currentTypes[i].id); } } return types; @@ -140,14 +138,15 @@ function getTypesChecked() { function setTypesChecked(types) { for (let i = 0; i < currentTypes.length; i++) { - let id = 'typeCheck_' + currentTypes[i]; - $('#' + id).prop('checked', types.indexOf(currentTypes[i]) !== -1); + let id = 'typeCheck_' + currentTypes[i].id; + $('#' + id).prop('checked', types.indexOf(currentTypes[i].id) !== -1); } return types; } -function setEditFieldValues(name, quantity, price, code, type, image) { +function setEditFieldValues(name, description, quantity, price, code, type, image) { $.selector_cache('#nameInput').val(name); + $.selector_cache('#descriptionInput').val(description); $.selector_cache('#quantityInput').val(quantity); $.selector_cache('#priceInput').val(price); $.selector_cache('#codeInput').val(code); @@ -169,6 +168,7 @@ function isCodeAvailable (code) { function isItemInputEmpty() { return $.selector_cache('#nameInput').val() === '' && + $.selector_cache('#descriptionInput').val() === '' && $.selector_cache('#quantityInput').val() === '' && $.selector_cache('#priceInput').val() === '' && $.selector_cache('#codeInput').val() === '' && @@ -178,6 +178,7 @@ function isItemInputEmpty() { function isItemInputFilled() { return $.selector_cache('#nameInput').val() !== '' && + $.selector_cache('#descriptionInput').val() !== '' && $.selector_cache('#quantityInput').val() !== '' && $.selector_cache('#priceInput').val() !== '' && $.selector_cache('#codeInput').val() !== '' && @@ -188,22 +189,7 @@ function isItemInputFilled() { function saveDataset() { - let finalDataset = { - types: currentTypes, - articles: currentDataset - }; - console.log(finalDataset); - $.ajax({ - type: "POST", - url: "write_json.php", - data: JSON.stringify(finalDataset), - dataType: "json", - contentType: "application/json; charset=utf-8", - complete: function (data) { - alert(data.responseText); - console.log(data); - }, - }); + SaveManager.saveData(currentTypes, currentDataset); }