Make it possible to track a chore execution without the time part, only the day

This commit is contained in:
Bernd Bestel 2019-05-04 16:13:05 +02:00
parent 98fcd767b3
commit 9ef55f1f01
No known key found for this signature in database
GPG Key ID: 71BD34C0D4891300
10 changed files with 112 additions and 42 deletions

View File

@ -14,6 +14,7 @@
- It's now possible to customize the default amount for purchase/consume (see stock settings under the settings icon on the top right)
- Chores improvements
- New recurrence patterns - chores can now also be "scheduled" to repat daily/weekly/monthly
- It's now possible to track the day of a chore execution only (without the time, option per chore)
- Recipe improvements
- It's now possible to enter a "variable amount" (e. g. if a recipe needs "1 - 2 cups"), the original amount is still used for stock fulfillment checking (if enabled for that recipe ingredient)
- New translations: (thanks all the translators)

View File

@ -2780,6 +2780,9 @@
"period_days": {
"type": "integer"
},
"track_date_only": {
"type": "boolean"
},
"row_created_timestamp": {
"type": "string",
"format": "date-time"

View File

@ -1227,3 +1227,9 @@ msgstr ""
msgid "When this is not empty, it will be shown instead of the amount entered above while the amount there will still be used for stock fulfillment checking"
msgstr ""
msgid "Track date only"
msgstr ""
msgid "When enabled only the day of an execution is tracked, not the time"
msgstr ""

2
migrations/0069.sql Normal file
View File

@ -0,0 +1,2 @@
ALTER TABLE chores
ADD track_date_only TINYINT DEFAULT 0;

View File

@ -2,7 +2,7 @@
{
e.preventDefault();
var jsonData = $('#chore-form').serializeJSON();
var jsonData = $('#chore-form').serializeJSON({ checkboxUncheckedValue: "0" });
Grocy.FrontendHelpers.BeginUiBusy("chore-form");
if (Grocy.EditMode === 'create')

View File

@ -65,51 +65,66 @@ $(document).on('click', '.track-chore-button', function(e)
var choreId = $(e.currentTarget).attr('data-chore-id');
var choreName = $(e.currentTarget).attr('data-chore-name');
var trackedTime = moment().format('YYYY-MM-DD HH:mm:ss');
Grocy.Api.Post('chores/' + choreId + '/execute', { 'tracked_time': trackedTime },
function()
Grocy.Api.Get('objects/chores/' + choreId,
function(chore)
{
Grocy.Api.Get('chores/' + choreId,
function(result)
var trackedTime = moment().format('YYYY-MM-DD HH:mm:ss');
if (chore.track_date_only == 1)
{
trackedTime = moment().format('YYYY-MM-DD');
}
Grocy.Api.Post('chores/' + choreId + '/execute', { 'tracked_time': trackedTime },
function()
{
var choreRow = $('#chore-' + choreId + '-row');
var nextXDaysThreshold = moment().add($("#info-due-chores").data("next-x-days"), "days");
var now = moment();
var nextExecutionTime = moment(result.next_estimated_execution_time);
choreRow.removeClass("table-warning");
choreRow.removeClass("table-danger");
if (nextExecutionTime.isBefore(now))
{
choreRow.addClass("table-danger");
}
else if (nextExecutionTime.isBefore(nextXDaysThreshold))
{
choreRow.addClass("table-warning");
}
$('#chore-' + choreId + '-last-tracked-time').parent().effect('highlight', { }, 500);
$('#chore-' + choreId + '-last-tracked-time').fadeOut(500, function()
{
$(this).text(trackedTime).fadeIn(500);
});
$('#chore-' + choreId + '-last-tracked-time-timeago').attr('datetime', trackedTime);
if (result.chore.period_type == "dynamic-regular")
{
$('#chore-' + choreId + '-next-execution-time').parent().effect('highlight', { }, 500);
$('#chore-' + choreId + '-next-execution-time').fadeOut(500, function()
Grocy.Api.Get('chores/' + choreId,
function(result)
{
$(this).text(result.next_estimated_execution_time).fadeIn(500);
});
$('#chore-' + choreId + '-next-execution-time-timeago').attr('datetime', result.next_estimated_execution_time);
}
var choreRow = $('#chore-' + choreId + '-row');
var nextXDaysThreshold = moment().add($("#info-due-chores").data("next-x-days"), "days");
var now = moment();
var nextExecutionTime = moment(result.next_estimated_execution_time);
Grocy.FrontendHelpers.EndUiBusy();
toastr.success(__t('Tracked execution of chore %s on %s', choreName, trackedTime));
RefreshContextualTimeago();
RefreshStatistics();
choreRow.removeClass("table-warning");
choreRow.removeClass("table-danger");
if (nextExecutionTime.isBefore(now))
{
choreRow.addClass("table-danger");
}
else if (nextExecutionTime.isBefore(nextXDaysThreshold))
{
choreRow.addClass("table-warning");
}
$('#chore-' + choreId + '-last-tracked-time').parent().effect('highlight', { }, 500);
$('#chore-' + choreId + '-last-tracked-time').fadeOut(500, function()
{
$(this).text(trackedTime).fadeIn(500);
});
$('#chore-' + choreId + '-last-tracked-time-timeago').attr('datetime', trackedTime);
if (result.chore.period_type == "dynamic-regular")
{
$('#chore-' + choreId + '-next-execution-time').parent().effect('highlight', { }, 500);
$('#chore-' + choreId + '-next-execution-time').fadeOut(500, function()
{
$(this).text(result.next_estimated_execution_time).fadeIn(500);
});
$('#chore-' + choreId + '-next-execution-time-timeago').attr('datetime', result.next_estimated_execution_time);
}
Grocy.FrontendHelpers.EndUiBusy();
toastr.success(__t('Tracked execution of chore %s on %s', choreName, trackedTime));
RefreshContextualTimeago();
RefreshStatistics();
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy();
console.error(xhr);
}
);
},
function(xhr)
{
@ -120,7 +135,7 @@ $(document).on('click', '.track-chore-button', function(e)
},
function(xhr)
{
Grocy.FrontendHelpers.EndUiBusy();
Grocy.FrontendHelpers.EndUiBusy("choretracking-form");
console.error(xhr);
}
);

View File

@ -45,6 +45,26 @@ $('#chore_id').on('change', function(e)
var choreId = $(e.target).val();
if (choreId)
{
Grocy.Api.Get('objects/chores/' + choreId,
function(chore)
{
if (chore.track_date_only == 1)
{
Grocy.Components.DateTimePicker.ChangeFormat("YYYY-MM-DD");
Grocy.Components.DateTimePicker.SetValue(moment().format("YYYY-MM-DD"));
}
else
{
Grocy.Components.DateTimePicker.ChangeFormat("YYYY-MM-DD HH:mm:ss");
Grocy.Components.DateTimePicker.SetValue(moment().format("YYYY-MM-DD HH:mm:ss"));
}
},
function(xhr)
{
console.error(xhr);
}
);
Grocy.Components.ChoreCard.Refresh(choreId);
Grocy.Components.DateTimePicker.GetInputElement().focus();
Grocy.FrontendHelpers.ValidateForm('choretracking-form');

View File

@ -43,6 +43,13 @@ Grocy.Components.DateTimePicker.Clear = function()
$('#datetimepicker-timeago').text('');
}
Grocy.Components.DateTimePicker.ChangeFormat = function(format)
{
$(".datetimepicker").datetimepicker("destroy");
Grocy.Components.DateTimePicker.GetInputElement().data("format", format);
Grocy.Components.DateTimePicker.Init();
}
var startDate = null;
if (Grocy.Components.DateTimePicker.GetInputElement().data('init-with-now') === true)
{

View File

@ -58,6 +58,12 @@ class ChoresService extends BaseService
{
throw new \Exception('User does not exist');
}
$chore = $this->Database->chores($choreId);
if ($chore->track_date_only == 1)
{
$trackedTime = substr($trackedTime, 0, 10) . ' 00:00:00';
}
$logRow = $this->Database->chores_log()->createRow(array(
'chore_id' => $choreId,

View File

@ -87,6 +87,16 @@
<input type="hidden" id="period_config" name="period_config" value="@if($mode == 'edit'){{ $chore->period_config }}@endif">
<div class="form-group">
<div class="form-check">
<input type="hidden" name="track_date_only" value="0">
<input @if($mode == 'edit' && $chore->track_date_only == 1) checked @endif class="form-check-input" type="checkbox" id="track_date_only" name="track_date_only" value="1">
<label class="form-check-label" for="track_date_only">{{ $__t('Track date only') }}
<span class="text-muted small">{{ $__t('When enabled only the day of an execution is tracked, not the time') }}</span>
</label>
</div>
</div>
@include('components.userfieldsform', array(
'userfields' => $userfields,
'entity' => 'chores'