diff --git a/migrations/0040.sql b/migrations/0040.sql
new file mode 100644
index 00000000..8abf173f
--- /dev/null
+++ b/migrations/0040.sql
@@ -0,0 +1,2 @@
+ALTER TABLE products
+ADD picture_file_name TEXT;
diff --git a/public/js/grocy.js b/public/js/grocy.js
index 4aa2acc7..3b21527d 100644
--- a/public/js/grocy.js
+++ b/public/js/grocy.js
@@ -177,6 +177,42 @@ Grocy.Api.Post = function(apiFunction, jsonData, success, error)
xhr.send(JSON.stringify(jsonData));
};
+Grocy.Api.UploadFile = function(fileInput, group, success, error)
+{
+ if (fileInput[0].files.length === 0)
+ {
+ return;
+ }
+
+ var xhr = new XMLHttpRequest();
+ var url = U('/api/files/upload/' + group + '?file_name=' + encodeURIComponent(fileInput[0].files[0].name));
+
+ xhr.onreadystatechange = function()
+ {
+ if (xhr.readyState === XMLHttpRequest.DONE)
+ {
+ if (xhr.status === 200)
+ {
+ if (success)
+ {
+ success(JSON.parse(xhr.responseText));
+ }
+ }
+ else
+ {
+ if (error)
+ {
+ error(xhr);
+ }
+ }
+ }
+ };
+
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-type', 'application/octet-stream');
+ xhr.send(fileInput[0].files[0]);
+};
+
Grocy.FrontendHelpers = { };
Grocy.FrontendHelpers.ValidateForm = function(formId)
{
diff --git a/public/viewjs/productform.js b/public/viewjs/productform.js
index d9a053d3..59a2ce1a 100644
--- a/public/viewjs/productform.js
+++ b/public/viewjs/productform.js
@@ -9,12 +9,34 @@
redirectDestination = returnTo + '?createdproduct=' + encodeURIComponent($('#name').val());
}
+ var jsonData = $('#product-form').serializeJSON();
+ if ($("#product-picture")[0].files.length > 0)
+ {
+ jsonData.picture_file_name = $("#product-picture")[0].files[0].name;
+ }
+
if (Grocy.EditMode === 'create')
{
- Grocy.Api.Post('add-object/products', $('#product-form').serializeJSON(),
+ Grocy.Api.Post('add-object/products', jsonData,
function(result)
{
- window.location.href = redirectDestination;
+ if (jsonData.hasOwnProperty("picture_file_name"))
+ {
+ Grocy.Api.UploadFile($("#product-picture"), 'productpictures',
+ function(result)
+ {
+ window.location.href = redirectDestination;
+ },
+ function(xhr)
+ {
+ Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
+ }
+ );
+ }
+ else
+ {
+ window.location.href = redirectDestination;
+ }
},
function(xhr)
{
@@ -24,10 +46,26 @@
}
else
{
- Grocy.Api.Post('edit-object/products/' + Grocy.EditObjectId, $('#product-form').serializeJSON(),
+ Grocy.Api.Post('edit-object/products/' + Grocy.EditObjectId, jsonData,
function(result)
{
- window.location.href = redirectDestination;
+ if (jsonData.hasOwnProperty("picture_file_name"))
+ {
+ Grocy.Api.UploadFile($("#product-picture"), 'productpictures',
+ function(result)
+ {
+ window.location.href = redirectDestination;
+ },
+ function(xhr)
+ {
+ Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
+ }
+ );
+ }
+ else
+ {
+ window.location.href = redirectDestination;
+ }
},
function(xhr)
{
diff --git a/public/viewjs/stockoverview.js b/public/viewjs/stockoverview.js
index ddc3f9df..06c1772e 100644
--- a/public/viewjs/stockoverview.js
+++ b/public/viewjs/stockoverview.js
@@ -141,6 +141,17 @@ $(document).on('click', '.product-consume-button', function(e)
);
});
+$(document).on("click", ".show-product-picture-button", function(e)
+{
+ var pictureUrl = $(e.currentTarget).attr("data-picture-url");
+ var productName = $(e.currentTarget).attr("data-product-name");
+
+ bootbox.alert({
+ title: L("Image of product #1", productName),
+ message: ""
+ });
+});
+
function RefreshStatistics()
{
Grocy.Api.Get('stock/get-current-stock',
diff --git a/views/productform.blade.php b/views/productform.blade.php
index fceec874..c062ca43 100644
--- a/views/productform.blade.php
+++ b/views/productform.blade.php
@@ -108,6 +108,16 @@
'additionalHtmlElements' => '