Made the shopping list print view configurable (closes #740)

This commit is contained in:
Bernd Bestel
2020-12-19 23:57:33 +01:00
parent 77e842a736
commit 832141a718
5 changed files with 153 additions and 28 deletions

View File

@@ -92,6 +92,7 @@
- Added a button to add all currently in-stock but overdue and expired products to the shopping list (thanks @m-byte) - Added a button to add all currently in-stock but overdue and expired products to the shopping list (thanks @m-byte)
- Improved that when `FEATURE_FLAG_STOCK` is disabled, all product/stock related inputs and buttons are now hidden on the shopping list page (thanks @fipwmaqzufheoxq92ebc) - Improved that when `FEATURE_FLAG_STOCK` is disabled, all product/stock related inputs and buttons are now hidden on the shopping list page (thanks @fipwmaqzufheoxq92ebc)
- Shopping list items can now have their own Userfields (entity `shopping_list`), on the shopping list table those fields are rendered additionally to the product Userfields - Shopping list items can now have their own Userfields (entity `shopping_list`), on the shopping list table those fields are rendered additionally to the product Userfields
- Made the print view configurable (new dialog before printing - option to hide header, group products by their product group, alternative list layout)
- Fixed that "Add products that are below defined min. stock amount" always rounded up the missing amount to an integral number, this now allows decimal numbers - Fixed that "Add products that are below defined min. stock amount" always rounded up the missing amount to an integral number, this now allows decimal numbers
### Recipe improvements/fixes ### Recipe improvements/fixes

View File

@@ -1537,9 +1537,6 @@ msgstr ""
msgid "per day" msgid "per day"
msgstr "" msgstr ""
msgid "Normal view"
msgstr ""
msgid "Only undone items" msgid "Only undone items"
msgstr "" msgstr ""
@@ -2035,3 +2032,15 @@ msgstr ""
msgid "Last price (Total)" msgid "Last price (Total)"
msgstr "" msgstr ""
msgid "Show header"
msgstr ""
msgid "Group by product group"
msgstr ""
msgid "Table"
msgstr ""
msgid "Layout type"
msgstr ""

View File

@@ -813,7 +813,7 @@ $.extend(true, $.fn.dataTable.defaults, {
}); });
return $("<tr/>") return $("<tr/>")
.append('<td colspan="' + rows.columns()[0].length + '">' + group + ' <span class="fa fa-fw ' + toggleClass + '"/></td>') .append('<td colspan="' + rows.columns()[0].length + '">' + group + ' <span class="fa fa-fw d-print-none ' + toggleClass + '"/></td>')
.attr("data-name", group) .attr("data-name", group)
.toggleClass("collapsed", collapsed); .toggleClass("collapsed", collapsed);
} }

View File

@@ -19,6 +19,20 @@
$('#shoppinglist-table tbody').removeClass("d-none"); $('#shoppinglist-table tbody').removeClass("d-none");
shoppingListTable.columns.adjust().draw(); shoppingListTable.columns.adjust().draw();
var shoppingListPrintShadowTable = $('#shopping-list-print-shadow-table').DataTable({
'order': [[1, 'asc']],
"orderFixed": [[2, 'asc']],
'columnDefs': [
{ 'visible': false, 'targets': 2 },
{ 'orderable': false, 'targets': '_all' }
].concat($.fn.dataTable.defaults.columnDefs),
'rowGroup': {
enable: true,
dataSrc: 2
}
});
shoppingListPrintShadowTable.columns.adjust().draw();
$("#search").on("keyup", Delay(function() $("#search").on("keyup", Delay(function()
{ {
var value = $(this).val(); var value = $(this).val();
@@ -367,9 +381,99 @@ OnListItemRemoved();
$(document).on("click", "#print-shopping-list-button", function(e) $(document).on("click", "#print-shopping-list-button", function(e)
{ {
$(".print-timestamp").text(moment().format("l LT")); var dialogHtml = ' \
$("#description-for-print").html($("#description").val()); <div class="custom-control custom-checkbox"> \
window.print(); <input id="print-show-header" \
checked \
class="form-check-input custom-control-input" \
type="checkbox" \
value="1"> \
<label class="form-check-label custom-control-label" \
for="print-show-header">' + __t('Show header') + ' \
</label> \
</div> \
<div class="custom-control custom-checkbox"> \
<input id="print-group-by-product-group" \
checked \
class="form-check-input custom-control-input" \
type="checkbox" \
value="1"> \
<label class="form-check-label custom-control-label" \
for="print-group-by-product-group">' + __t('Group by product group') + ' \
</label> \
</div> \
<h5 class="pt-3 pb-0">' + __t('Layout type') + '</h5> \
<div class="custom-control custom-radio"> \
<input id="print-layout-type-table" \
checked \
class="custom-control-input" \
type="radio" \
name="print-layout-type" \
value="print-layout-type-table"> \
<label class="custom-control-label" \
for="print-layout-type-table">' + __t('Table') + ' \
</label> \
</div> \
<div class="custom-control custom-radio"> \
<input id="print-layout-type-list" \
class="custom-control-input" \
type="radio" \
name="print-layout-type" \
value="print-layout-type-list"> \
<label class="custom-control-label" \
for="print-layout-type-list">' + __t('List') + ' \
</label> \
</div>';
bootbox.dialog({
message: dialogHtml,
size: 'small',
backdrop: true,
closeButton: false,
className: "d-print-none",
buttons: {
cancel: {
label: __t('Cancel'),
className: 'btn-secondary',
callback: function()
{
bootbox.hideAll();
}
},
ok: {
label: __t('Print'),
className: 'btn-primary responsive-button',
callback: function()
{
bootbox.hideAll();
$(".print-timestamp").text(moment().format("l LT"));
$("#description-for-print").html($("#description").val());
if ($("#description").text().isEmpty())
{
$("#description-for-print").parent().addClass("d-print-none");
}
if (!$("#print-show-header").prop("checked"))
{
$("#print-header").addClass("d-none");
}
if (!$("#print-group-by-product-group").prop("checked"))
{
shoppingListPrintShadowTable.rowGroup().enable(false);
shoppingListPrintShadowTable.order.fixed({});
shoppingListPrintShadowTable.draw();
}
$("." + $("input[name='print-layout-type']:checked").val()).removeClass("d-none");
window.print();
}
}
}
});
}); });
$("#description").on("summernote.change", function() $("#description").on("summernote.change", function()

View File

@@ -147,11 +147,6 @@
<div id="shoppinglist-main" <div id="shoppinglist-main"
class="row d-print-none"> class="row d-print-none">
<div class="@if(boolval($userSettings['shopping_list_show_calendar'])) col-xs-12 col-md-8 @else col-12 @endif pb-3"> <div class="@if(boolval($userSettings['shopping_list_show_calendar'])) col-xs-12 col-md-8 @else col-12 @endif pb-3">
<a id="shopping-list-normal-view-button"
class="btn btn-outline-dark btn-block switch-view-mode-button d-none"
href="#">
{{ $__t('Normal view') }}
</a>
<table id="shoppinglist-table" <table id="shoppinglist-table"
class="table table-sm table-striped nowrap w-100"> class="table table-sm table-striped nowrap w-100">
<thead> <thead>
@@ -312,28 +307,33 @@
</div> </div>
<div class="d-none d-print-block"> <div class="d-none d-print-block">
<h1 class="text-center"> <div id="print-header"
<h1
class="text-center">
<img src="{{ $U('/img/grocy_logo.svg?v=', true) }}{{ $version }}" <img src="{{ $U('/img/grocy_logo.svg?v=', true) }}{{ $version }}"
height="30" height="30"
class="d-print-flex mx-auto"> class="d-print-flex mx-auto">
{{ $__t("Shopping list") }} {{ $__t("Shopping list") }}
</h1> </h1>
@if (FindObjectInArrayByPropertyValue($shoppingLists, 'id', $selectedShoppingListId)->name != $__t("Shopping list")) @if (FindObjectInArrayByPropertyValue($shoppingLists, 'id', $selectedShoppingListId)->name != $__t("Shopping list"))
<h3 class="text-center"> <h3 class="text-center">
{{ FindObjectInArrayByPropertyValue($shoppingLists, 'id', $selectedShoppingListId)->name }} {{ FindObjectInArrayByPropertyValue($shoppingLists, 'id', $selectedShoppingListId)->name }}
</h3> </h3>
@endif @endif
<h6 class="text-center mb-4"> <h6 class="text-center mb-4">
{{ $__t('Time of printing') }}: {{ $__t('Time of printing') }}:
<span class="d-inline print-timestamp"></span> <span class="d-inline print-timestamp"></span>
</h6> </h6>
<div class="row w-75"> </div>
<div class="col"> <div class="w-75 print-layout-type-table d-none">
<table class="table"> <div>
<table id="shopping-list-print-shadow-table"
class="table table-sm table-striped nowrap">
<thead> <thead>
<tr> <tr>
<th>{{ $__t('Product') }} / <em>{{ $__t('Note') }}</em></th> <th>{{ $__t('Product') }} / <em>{{ $__t('Note') }}</em></th>
<th>{{ $__t('Amount') }}</th> <th>{{ $__t('Amount') }}</th>
<th>{{ $__t('Product group') }}</th>
@include('components.userfields_thead', array( @include('components.userfields_thead', array(
'userfields' => $userfields 'userfields' => $userfields
@@ -350,6 +350,9 @@
<td> <td>
<span class="locale-number locale-number-quantity-amount">{{ $listItem->amount }}</span> @if(!empty($listItem->product_id)){{ $__n($listItem->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $listItem->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $listItem->qu_id)->name_plural) }}@endif <span class="locale-number locale-number-quantity-amount">{{ $listItem->amount }}</span> @if(!empty($listItem->product_id)){{ $__n($listItem->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $listItem->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $listItem->qu_id)->name_plural) }}@endif
</td> </td>
<td>
@if(!empty(FindObjectInArrayByPropertyValue($products, 'id', $listItem->product_id)->product_group_id)) {{ FindObjectInArrayByPropertyValue($productGroups, 'id', FindObjectInArrayByPropertyValue($products, 'id', $listItem->product_id)->product_group_id)->name }} @else <span class="font-italic font-weight-light">{{ $__t('Ungrouped') }}</span> @endif
</td>
@include('components.userfields_tbody', array( @include('components.userfields_tbody', array(
'userfields' => $userfields, 'userfields' => $userfields,
@@ -362,8 +365,16 @@
</table> </table>
</div> </div>
</div> </div>
<div class="row w-75"> <div class="w-75 print-layout-type-list d-none">
<div class="col"> @foreach($listItems as $listItem)
<div class="py-0">
<span class="locale-number locale-number-quantity-amount">{{ $listItem->amount }}</span> @if(!empty($listItem->product_id)){{ $__n($listItem->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $listItem->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $listItem->qu_id)->name_plural) }}@endif
@if(!empty($listItem->product_id)) {{ FindObjectInArrayByPropertyValue($products, 'id', $listItem->product_id)->name }}<br>@endif<em>{!! nl2br($listItem->note) !!}</em>
</div><br>
@endforeach
</div>
<div class="w-75 pt-3">
<div>
<h5>{{ $__t('Notes') }}</h5> <h5>{{ $__t('Notes') }}</h5>
<p id="description-for-print"></p> <p id="description-for-print"></p>
</div> </div>