mirror of
https://github.com/grocy/grocy.git
synced 2025-08-20 04:12:59 +00:00
First commit
This commit is contained in:
70
views/consumption.js
Normal file
70
views/consumption.js
Normal file
@@ -0,0 +1,70 @@
|
||||
$('#save-consumption-button').on('click', function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var jsonForm = $('#consumption-form').serializeJSON();
|
||||
|
||||
var spoiled = 0;
|
||||
if ($('#spoiled').is(':checked'))
|
||||
{
|
||||
spoiled = 1;
|
||||
}
|
||||
|
||||
Grocy.FetchJson('/api/consume-product/' + jsonForm.product_id + '/' + jsonForm.amount + '?spoiled=' + spoiled,
|
||||
function(result)
|
||||
{
|
||||
$('#product_id').val(null);
|
||||
$('#amount').val(1);
|
||||
$('#product_name').focus();
|
||||
$('#consumption-form').validator('validate');
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#product_id').on('change', function(e)
|
||||
{
|
||||
var productId = $(e.target).val();
|
||||
|
||||
Grocy.FetchJson('/api/get-product-statistics/' + productId,
|
||||
function(productStatistics)
|
||||
{
|
||||
$('#selected-product-name').text(productStatistics.product.name);
|
||||
$('#selected-product-stock-amount').text(productStatistics.stock_amount || '0');
|
||||
$('#selected-product-stock-qu-name').text(productStatistics.quantity_unit_stock.name);
|
||||
$('#selected-product-stock-qu-name2').text(productStatistics.quantity_unit_stock.name);
|
||||
$('#selected-product-last-purchased').text(productStatistics.last_purchased || 'never');
|
||||
$('#selected-product-last-used').text(productStatistics.last_used || 'never');
|
||||
$('#amount').attr('max', productStatistics.stock_amount);
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$(function()
|
||||
{
|
||||
$('.datepicker').datepicker(
|
||||
{
|
||||
format: 'yyyy-mm-dd',
|
||||
startDate: '-3d',
|
||||
todayHighlight: true,
|
||||
autoclose: true,
|
||||
calendarWeeks: true,
|
||||
orientation: 'bottom auto'
|
||||
});
|
||||
$('.datepicker').val(moment().format('YYYY-MM-DD'));
|
||||
$('.datepicker').trigger('change');
|
||||
|
||||
$('.combobox').combobox();
|
||||
$('#product_id').focus();
|
||||
$('#product_id').val(null);
|
||||
$('#product_name').trigger('change');
|
||||
$('#purchase-form').validator();
|
||||
$('#purchase-form').validator('validate');
|
||||
});
|
44
views/consumption.php
Normal file
44
views/consumption.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<div class="col-sm-3 col-sm-offset-3 col-md-3 col-md-offset-2 main">
|
||||
<h1 class="page-header">Record consumption</h1>
|
||||
|
||||
<form id="consumption-form">
|
||||
<div class="form-group">
|
||||
<label for="product_id">Product</label>
|
||||
<select class="form-control combobox" id="product_id" name="product_id" required>
|
||||
<option value=""></option>
|
||||
<?php foreach ($products as $product) : ?>
|
||||
<option value="<?php echo $product->id; ?>"><?php echo $product->name; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group date">
|
||||
<input type="text" class="form-control" id="barcode" name="barcode" />
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-barcode"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="amount">Amount</label>
|
||||
<input type="number" class="form-control" id="amount" name="amount" value="1" min="1" required>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label for="spoiled">
|
||||
<input type="checkbox" id="spoiled" name="spoiled"> Spoiled
|
||||
</label>
|
||||
</div>
|
||||
<button id="save-consumption-button" type="submit" class="btn btn-default">OK</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 col-md-3 main well">
|
||||
<h3>Product overview <strong><span id="selected-product-name"></span></strong></h3>
|
||||
<h4><strong>Stock quantity unit:</strong> <span id="selected-product-stock-qu-name"></span></h4>
|
||||
|
||||
<p>
|
||||
<strong>Stock amount:</strong> <span id="selected-product-stock-amount"></span> <span id="selected-product-stock-qu-name2"></span><br />
|
||||
<strong>Last purchased:</strong> <span id="selected-product-last-purchased"></span><br />
|
||||
<strong>Last used:</strong> <span id="selected-product-last-used"></span>
|
||||
</p>
|
||||
</div>
|
31
views/dashboard.php
Normal file
31
views/dashboard.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||
<h1 class="page-header">Dashboard</h1>
|
||||
|
||||
<h3>Current stock</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Product</th>
|
||||
<th>Amount</th>
|
||||
<th>Next best before date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($currentStock as $currentStockEntry) : ?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php echo Grocy::FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $currentStockEntry->amount; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $currentStockEntry->best_before_date; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
108
views/layout.php
Normal file
108
views/layout.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
|
||||
<meta name="author" content="Bernd Bestel (bernd@berrnd.de)" />
|
||||
|
||||
<title>
|
||||
<?php echo $title; ?> | grocy
|
||||
</title>
|
||||
|
||||
<link href="/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="/bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
|
||||
<link href="/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" rel="stylesheet" />
|
||||
<link href="/bower_components/bootstrap-combobox/css/bootstrap-combobox.css" rel="stylesheet" />
|
||||
<link href="/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
||||
<script src="/grocy.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-default navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<!--<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" >
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>-->
|
||||
<a class="navbar-brand" href="/">grocy</a>
|
||||
</div>
|
||||
|
||||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<!--<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<a href="#">About</a>
|
||||
</li>
|
||||
</ul>-->
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-md-2 sidebar">
|
||||
<ul class="nav nav-sidebar">
|
||||
<li data-nav-for-page="dashboard.php">
|
||||
<a class="discrete-link" href="/"><i class="fa fa-tachometer fa-fw"></i> Dashboard</a>
|
||||
</li>
|
||||
<li data-nav-for-page="purchase.php">
|
||||
<a class="discrete-link" href="/purchase"><i class="fa fa-shopping-cart fa-fw"></i> Record purchase</a>
|
||||
</li>
|
||||
<li data-nav-for-page="consumption.php">
|
||||
<a class="discrete-link" href="/consumption"><i class="fa fa-cutlery fa-fw"></i> Record consumption</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav nav-sidebar">
|
||||
<li data-nav-for-page="products.php">
|
||||
<a class="discrete-link" href="/products"><i class="fa fa-product-hunt fa-fw"></i> Manage products</a>
|
||||
</li>
|
||||
<li data-nav-for-page="locations.php">
|
||||
<a class="discrete-link" href="/locations"><i class="fa fa-map-marker fa-fw"></i> Manage locations</a>
|
||||
</li>
|
||||
<li data-nav-for-page="quantityunits.php">
|
||||
<a class="discrete-link" href="/quantityunits"><i class="fa fa-balance-scale fa-fw"></i> Manage quantity units</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="nav-copyright nav nav-sidebar">
|
||||
grocy is a project by
|
||||
<a class="discrete-link" href="https://berrnd.de" target="_blank">Bernd Bestel</a>
|
||||
<br />
|
||||
Created with passion since 2017
|
||||
<br />
|
||||
Version <?php echo file_get_contents('version.txt'); ?>
|
||||
<br />
|
||||
Life runs on code
|
||||
<br />
|
||||
<a class="discrete-link" href="https://github.com/berrnd/grocy" target="_blank">
|
||||
<i class="fa fa-github"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>Grocy.ContentPage = '<?php echo $contentPage; ?>';</script>
|
||||
<?php include $contentPage; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
<script src="/bower_components/bootbox/bootbox.js"></script>
|
||||
<script src="/bower_components/jquery.serializeJSON/jquery.serializejson.min.js"></script>
|
||||
<script src="/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
|
||||
<script src="/bower_components/moment/min/moment.min.js"></script>
|
||||
<script src="/bower_components/bootstrap-validator/dist/validator.min.js"></script>
|
||||
<script src="/bower_components/bootstrap-combobox/js/bootstrap-combobox.js"></script>
|
||||
|
||||
<?php if (file_exists('views/' . str_replace('.php', '.js', $contentPage))) : ?>
|
||||
<script src="/views/<?php echo str_replace('.php', '.js', $contentPage); ?>"></script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (file_exists('data/add_before_end_body.html')) include 'data/add_before_end_body.html' ?>
|
||||
</body>
|
||||
</html>
|
36
views/locationform.js
Normal file
36
views/locationform.js
Normal file
@@ -0,0 +1,36 @@
|
||||
$('#save-location-button').on('click', function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
if (Grocy.EditMode === 'create')
|
||||
{
|
||||
Grocy.PostJson('/api/add-object/locations', $('#location-form').serializeJSON(),
|
||||
function(result)
|
||||
{
|
||||
window.location.href = '/locations';
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Grocy.PostJson('/api/edit-object/locations/' + Grocy.EditObjectId, $('#location-form').serializeJSON(),
|
||||
function(result)
|
||||
{
|
||||
window.location.href = '/locations';
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$(function()
|
||||
{
|
||||
$('#name').focus();
|
||||
});
|
21
views/locationform.php
Normal file
21
views/locationform.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<div class="col-sm-3 col-sm-offset-3 col-md-4 col-md-offset-2 main">
|
||||
<h1 class="page-header"><?php echo $title; ?></h1>
|
||||
|
||||
<script>Grocy.EditMode = '<?php echo $mode; ?>';</script>
|
||||
|
||||
<?php if ($mode == 'edit') : ?>
|
||||
<script>Grocy.EditObjectId = <?php echo $location->id; ?>;</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<form id="location-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" value="<?php if ($mode == 'edit') echo $location->name; ?>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Description</label>
|
||||
<textarea class="form-control" rows="2" id="description" name="description"><?php if ($mode == 'edit') echo $location->description; ?></textarea>
|
||||
</div>
|
||||
<button id="save-location-button" type="submit" class="btn btn-default">Save</button>
|
||||
</form>
|
||||
</div>
|
32
views/locations.js
Normal file
32
views/locations.js
Normal file
@@ -0,0 +1,32 @@
|
||||
$(document).on('click', '.location-delete-button', function(e)
|
||||
{
|
||||
bootbox.confirm({
|
||||
message: 'Delete location <strong>' + $(e.target).attr('data-location-name') + '</strong>?',
|
||||
buttons: {
|
||||
confirm: {
|
||||
label: 'Yes',
|
||||
className: 'btn-success'
|
||||
},
|
||||
cancel: {
|
||||
label: 'No',
|
||||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
{
|
||||
if (result == true)
|
||||
{
|
||||
Grocy.FetchJson('/api/delete-object/locations/' + $(e.target).attr('data-location-id'),
|
||||
function(result)
|
||||
{
|
||||
window.location.href = '/locations';
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
40
views/locations.php
Normal file
40
views/locations.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||
<h1 class="page-header">
|
||||
Locations
|
||||
<a class="btn btn-default" href="/location/new" role="button">
|
||||
<i class="fa fa-plus"></i> Add
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($locations as $location) : ?>
|
||||
<tr>
|
||||
<td class="fit-content">
|
||||
<a class="btn btn-info" href="/location/<?php echo $location->id; ?>" role="button">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a class="btn btn-danger location-delete-button" href="#" role="button" data-location-id="<?php echo $location->id; ?>" data-location-name="<?php echo $location->name; ?>">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $location->name; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $location->description; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
36
views/productform.js
Normal file
36
views/productform.js
Normal file
@@ -0,0 +1,36 @@
|
||||
$('#save-product-button').on('click', function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
if (Grocy.EditMode === 'create')
|
||||
{
|
||||
Grocy.PostJson('/api/add-object/products', $('#product-form').serializeJSON(),
|
||||
function(result)
|
||||
{
|
||||
window.location.href = '/products';
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Grocy.PostJson('/api/edit-object/products/' + Grocy.EditObjectId, $('#product-form').serializeJSON(),
|
||||
function(result)
|
||||
{
|
||||
window.location.href = '/products';
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$(function()
|
||||
{
|
||||
$('#name').focus();
|
||||
});
|
58
views/productform.php
Normal file
58
views/productform.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<div class="col-sm-3 col-sm-offset-3 col-md-4 col-md-offset-2 main">
|
||||
<h1 class="page-header"><?php echo $title; ?></h1>
|
||||
|
||||
<script>Grocy.EditMode = '<?php echo $mode; ?>';</script>
|
||||
|
||||
<?php if ($mode == 'edit') : ?>
|
||||
<script>Grocy.EditObjectId = <?php echo $product->id; ?>;</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<form id="product-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" value="<?php if ($mode == 'edit') echo $product->name; ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="barcode">Barcode</label>
|
||||
<div class="input-group date">
|
||||
<input type="text" class="form-control" id="barcode" name="barcode" value="<?php if ($mode == 'edit') echo $product->barcode; ?>">
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-barcode"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Description</label>
|
||||
<textarea class="form-control" rows="2" id="description" name="description"><?php if ($mode == 'edit') echo $product->description; ?></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="location_id">Location</label>
|
||||
<select class="form-control" id="location_id" name="location_id">
|
||||
<?php foreach ($locations as $location) : ?>
|
||||
<option <?php if ($mode == 'edit' && $location->id == $product->location_id) echo 'selected="selected"'; ?> value="<?php echo $location->id; ?>"><?php echo $location->name; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="qu_id_purchase">Quantity unit purchase</label>
|
||||
<select class="form-control" id="qu_id_purchase" name="qu_id_purchase">
|
||||
<?php foreach ($quantityunits as $quantityunit) : ?>
|
||||
<option <?php if ($mode == 'edit' && $quantityunit->id == $product->qu_id_purchase) echo 'selected="selected"'; ?> value="<?php echo $quantityunit->id; ?>"><?php echo $quantityunit->name; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="qu_id_stock">Quantity unit stock</label>
|
||||
<select class="form-control" id="qu_id_stock" name="qu_id_stock">
|
||||
<?php foreach ($quantityunits as $quantityunit) : ?>
|
||||
<option <?php if ($mode == 'edit' && $quantityunit->id == $product->qu_id_stock) echo 'selected="selected"'; ?> value="<?php echo $quantityunit->id; ?>"><?php echo $quantityunit->name; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="qu_factor_purchase_to_stock">Factor purchase to stock quantity unit</label>
|
||||
<input type="text" class="form-control" id="qu_factor_purchase_to_stock" name="qu_factor_purchase_to_stock" value="<?php if ($mode == 'edit') echo $product->qu_factor_purchase_to_stock; else echo '1'; ?>">
|
||||
</div>
|
||||
<button id="save-product-button" type="submit" class="btn btn-default">Save</button>
|
||||
</form>
|
||||
</div>
|
32
views/products.js
Normal file
32
views/products.js
Normal file
@@ -0,0 +1,32 @@
|
||||
$(document).on('click', '.product-delete-button', function(e)
|
||||
{
|
||||
bootbox.confirm({
|
||||
message: 'Delete product <strong>' + $(e.target).attr('data-product-name') + '</strong>?',
|
||||
buttons: {
|
||||
confirm: {
|
||||
label: 'Yes',
|
||||
className: 'btn-success'
|
||||
},
|
||||
cancel: {
|
||||
label: 'No',
|
||||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
{
|
||||
if (result == true)
|
||||
{
|
||||
Grocy.FetchJson('/api/delete-object/products/' + $(e.target).attr('data-product-id'),
|
||||
function(result)
|
||||
{
|
||||
window.location.href = '/products';
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
56
views/products.php
Normal file
56
views/products.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||
<h1 class="page-header">
|
||||
Products
|
||||
<a class="btn btn-default" href="/product/new" role="button">
|
||||
<i class="fa fa-plus"></i> Add
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Name</th>
|
||||
<th>Location</th>
|
||||
<th>QU purchase</th>
|
||||
<th>QU stock</th>
|
||||
<th>QU factor</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($products as $product) : ?>
|
||||
<tr>
|
||||
<td class="fit-content">
|
||||
<a class="btn btn-info" href="/product/<?php echo $product->id; ?>" role="button">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a class="btn btn-danger product-delete-button" href="#" role="button" data-product-id="<?php echo $product->id; ?>" data-product-name="<?php echo $product->name; ?>">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $product->name; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo Grocy::FindObjectInArrayByPropertyValue($locations, 'id', $product->location_id)->name; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo Grocy::FindObjectInArrayByPropertyValue($quantityunits, 'id', $product->qu_id_purchase)->name; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo Grocy::FindObjectInArrayByPropertyValue($quantityunits, 'id', $product->qu_id_stock)->name; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $product->qu_factor_purchase_to_stock; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $product->description; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
75
views/purchase.js
Normal file
75
views/purchase.js
Normal file
@@ -0,0 +1,75 @@
|
||||
$('#save-purchase-button').on('click', function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var jsonForm = $('#purchase-form').serializeJSON();
|
||||
delete jsonForm.barcode;
|
||||
|
||||
Grocy.FetchJson('/api/get-object/products/' + jsonForm.product_id,
|
||||
function(product)
|
||||
{
|
||||
jsonForm.amount = jsonForm.amount * product.qu_factor_purchase_to_stock;
|
||||
|
||||
Grocy.PostJson('/api/add-object/stock', jsonForm,
|
||||
function(result)
|
||||
{
|
||||
$('#product_id').val(null);
|
||||
$('#amount').val(1);
|
||||
$('#product_id').focus();
|
||||
$('#purchase-form').validator('validate');
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#product_id').on('change', function(e)
|
||||
{
|
||||
var productId = $(e.target).val();
|
||||
|
||||
Grocy.FetchJson('/api/get-product-statistics/' + productId,
|
||||
function(productStatistics)
|
||||
{
|
||||
$('#selected-product-name').text(productStatistics.product.name);
|
||||
$('#selected-product-stock-amount').text(productStatistics.stock_amount || '0');
|
||||
$('#selected-product-stock-qu-name').text(productStatistics.quantity_unit_stock.name);
|
||||
$('#selected-product-purchase-qu-name').text(productStatistics.quantity_unit_purchase.name);
|
||||
$('#selected-product-last-purchased').text(productStatistics.last_purchased || 'never');
|
||||
$('#selected-product-last-used').text(productStatistics.last_used || 'never');
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$(function()
|
||||
{
|
||||
$('.datepicker').datepicker(
|
||||
{
|
||||
format: 'yyyy-mm-dd',
|
||||
startDate: '+7d',
|
||||
todayHighlight: true,
|
||||
autoclose: true,
|
||||
calendarWeeks: true,
|
||||
orientation: 'bottom auto'
|
||||
});
|
||||
$('.datepicker').val(moment().format('YYYY-MM-DD'));
|
||||
$('.datepicker').trigger('change');
|
||||
|
||||
$('.combobox').combobox();
|
||||
$('#product_id').focus();
|
||||
$('#product_id').val(null);
|
||||
$('#product_name').trigger('change');
|
||||
$('#purchase-form').validator();
|
||||
$('#purchase-form').validator('validate');
|
||||
});
|
49
views/purchase.php
Normal file
49
views/purchase.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<div class="col-sm-3 col-sm-offset-3 col-md-3 col-md-offset-2 main">
|
||||
<h1 class="page-header">Record purchase</h1>
|
||||
|
||||
<form id="purchase-form">
|
||||
<div class="form-group">
|
||||
<label for="product_id">Product</label>
|
||||
<select class="form-control combobox" id="product_id" name="product_id" required>
|
||||
<option value=""></option>
|
||||
<?php foreach ($products as $product) : ?>
|
||||
<option value="<?php echo $product->id; ?>"><?php echo $product->name; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group date">
|
||||
<input type="text" class="form-control" id="barcode" name="barcode" />
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-barcode"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="amount">Amount</label>
|
||||
<input type="number" class="form-control" id="amount" name="amount" value="1" min="1" required>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="best_before_date">Best before</label>
|
||||
<div class="input-group date">
|
||||
<input type="text" class="form-control datepicker" id="best_before_date" name="best_before_date" required>
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-calendar"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
<button id="save-purchase-button" type="submit" class="btn btn-default">OK</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 col-md-3 main well">
|
||||
<h3>Product overview <strong><span id="selected-product-name"></span></strong></h3>
|
||||
<h4><strong>Purchase quantity:</strong> <span id="selected-product-purchase-qu-name"></span></h4>
|
||||
|
||||
<p>
|
||||
<strong>Stock amount:</strong> <span id="selected-product-stock-amount"></span> <span id="selected-product-stock-qu-name"></span><br />
|
||||
<strong>Last purchased:</strong> <span id="selected-product-last-purchased"></span><br />
|
||||
<strong>Last used:</strong> <span id="selected-product-last-used"></span>
|
||||
</p>
|
||||
</div>
|
36
views/quantityunitform.js
Normal file
36
views/quantityunitform.js
Normal file
@@ -0,0 +1,36 @@
|
||||
$('#save-quantityunit-button').on('click', function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
if (Grocy.EditMode === 'create')
|
||||
{
|
||||
Grocy.PostJson('/api/add-object/quantity_units', $('#quantityunit-form').serializeJSON(),
|
||||
function(result)
|
||||
{
|
||||
window.location.href = '/quantityunits';
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Grocy.PostJson('/api/edit-object/quantity_units/' + Grocy.EditObjectId, $('#quantityunit-form').serializeJSON(),
|
||||
function(result)
|
||||
{
|
||||
window.location.href = '/quantityunits';
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$(function()
|
||||
{
|
||||
$('#name').focus();
|
||||
});
|
21
views/quantityunitform.php
Normal file
21
views/quantityunitform.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<div class="col-sm-3 col-sm-offset-3 col-md-4 col-md-offset-2 main">
|
||||
<h1 class="page-header"><?php echo $title; ?></h1>
|
||||
|
||||
<script>Grocy.EditMode = '<?php echo $mode; ?>';</script>
|
||||
|
||||
<?php if ($mode == 'edit') : ?>
|
||||
<script>Grocy.EditObjectId = <?php echo $quantityunit->id; ?>;</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<form id="quantityunit-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" value="<?php if ($mode == 'edit') echo $quantityunit->name; ?>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Description</label>
|
||||
<textarea class="form-control" rows="2" id="description" name="description"><?php if ($mode == 'edit') echo $quantityunit->description; ?></textarea>
|
||||
</div>
|
||||
<button id="save-quantityunit-button" type="submit" class="btn btn-default">Save</button>
|
||||
</form>
|
||||
</div>
|
32
views/quantityunits.js
Normal file
32
views/quantityunits.js
Normal file
@@ -0,0 +1,32 @@
|
||||
$(document).on('click', '.quantityunit-delete-button', function(e)
|
||||
{
|
||||
bootbox.confirm({
|
||||
message: 'Delete quantity unit <strong>' + $(e.target).attr('data-quantityunit-name') + '</strong>?',
|
||||
buttons: {
|
||||
confirm: {
|
||||
label: 'Yes',
|
||||
className: 'btn-success'
|
||||
},
|
||||
cancel: {
|
||||
label: 'No',
|
||||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
{
|
||||
if (result == true)
|
||||
{
|
||||
Grocy.FetchJson('/api/delete-object/quantity_units/' + $(e.target).attr('data-quantityunit-id'),
|
||||
function(result)
|
||||
{
|
||||
window.location.href = '/quantityunits';
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
40
views/quantityunits.php
Normal file
40
views/quantityunits.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||
<h1 class="page-header">
|
||||
Quantity units
|
||||
<a class="btn btn-default" href="/quantityunit/new" role="button">
|
||||
<i class="fa fa-plus"></i> Add
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($quantityunits as $quantityunit) : ?>
|
||||
<tr>
|
||||
<td class="fit-content">
|
||||
<a class="btn btn-info" href="/quantityunit/<?php echo $quantityunit->id; ?>" role="button">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a class="btn btn-danger quantityunit-delete-button" href="#" role="button" data-quantityunit-id="<?php echo $quantityunit->id; ?>" data-quantityunit-name="<?php echo $quantityunit->name; ?>">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $quantityunit->name; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $quantityunit->description; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
Reference in New Issue
Block a user