Refactor task management and add attachment functionality

- Updated task editing template to handle default status for new tasks and corrected variable names.
- Enhanced work time reporting by rounding time to the nearest quarter hour and adjusting amount formatting.
- Introduced TasksController to manage task-related operations, including status resolution and email notifications.
- Added TaskAttachmentRepository for handling task attachments, including upload, rename, and delete functionalities.
- Implemented WorkTimeRepository to fetch clients with unsettled tasks and calculate total work time.
- Created unit tests for TasksController and TaskAttachmentRepository to ensure functionality and correctness.
This commit is contained in:
2026-02-06 23:11:48 +01:00
parent 1722f171bc
commit 47ffc19a23
18 changed files with 546 additions and 79 deletions

View File

@@ -122,7 +122,7 @@ if ( is_array( $this -> parent_tasks ) )
'label' => 'Status',
'name' => 'status',
'id' => 'status',
'value' => $this -> task[ 'status' ],
'value' => $this -> task[ 'id' ] ? $this -> task[ 'status' ] : 5,
'values' => \factory\Tasks::get_statuses()
] );?>
<!-- priorytet -->
@@ -157,7 +157,7 @@ if ( is_array( $this -> priorities ) )
'label' => 'Powiadom o zmianie statusu',
'name' => 'status_change_mail',
'id' => 'status_change_mail',
'checked' => ( $this -> task[ 'status_change_mail' ] or !$this -> taks['id'] ) ? true : false,
'checked' => ( $this -> task[ 'status_change_mail' ] or !$this -> task['id'] ) ? true : false,
'type' => 'checkbox'
] );
?>
@@ -191,11 +191,11 @@ if ( is_array( $this -> priorities ) )
'type' => 'checkbox'
] );
?>
<div class="form_group" id="recursive-details">
<div class="form_group" id="recursive-details" style="<?= $this -> task[ 'recursively' ] ? '' : 'display: none;';?>">
<label class="label">Powtarzaj co:</label>
<div class="input">
<input type="text" class="form-control" name="frequency" value="<?= $this -> task[ 'id' ] ? $this -> task[ 'frequency' ] : 1;?>">
<select name="period" class="form-control">
<div class="input" style="display: flex; gap: 10px; align-items: center;">
<input type="text" class="form-control" name="frequency" style="max-width: 110px;" value="<?= $this -> task[ 'id' ] ? $this -> task[ 'frequency' ] : 1;?>">
<select name="period" class="form-control" style="max-width: 140px;">
<option value="1" <? if ( $this -> task[ 'period' ] == '1' ):?>selected="selected"<? endif;?>>dni</option>
<option value="2" <? if ( $this -> task[ 'period' ] == '2' ):?>selected="selected"<? endif;?>>m-ce</option>
<option value="3" <? if ( $this -> task[ 'period' ] == '3' ):?>selected="selected"<? endif;?>>lata</option>
@@ -216,7 +216,7 @@ if ( is_array( $this -> priorities ) )
'label' => 'Pokaż w kalendarzu',
'name' => 'show_in_calendar',
'id' => 'show_in_calendar',
'checked' => ( $this -> task[ 'show_in_calendar' ] or !$this -> taks['id'] ) ? true : false,
'checked' => ( $this -> task[ 'show_in_calendar' ] or !$this -> task['id'] ) ? true : false,
'type' => 'checkbox'
] );
?>
@@ -262,11 +262,24 @@ echo $grid -> draw();
<script type="text/javascript">
$(document).ready(function ()
{
function toggleRecursiveDetails() {
if ( $( '#recursively' ).is( ':checked' ) )
$( '#recursive-details' ).show();
else
$( '#recursive-details' ).hide();
}
$('input[type="checkbox"]').iCheck({
checkboxClass: 'icheckbox_square-blue',
radioClass: 'iradio_square-blue',
});
toggleRecursiveDetails();
$( '#recursively' ).on( 'ifChanged change', function() {
toggleRecursiveDetails();
});
$( 'body' ).on( 'click', '.task-remove', function(e)
{
e.preventDefault();
@@ -323,7 +336,19 @@ echo $grid -> draw();
});
$( '#project_id, #client_id, #status' ).select2({
theme: 'bootstrap-5'
theme: 'bootstrap-5',
minimumResultsForSearch: 0
});
$( '#project_id, #client_id, #status' ).on( 'select2:open', function() {
setTimeout( function() {
var search_field = document.querySelector( '.select2-container--open .select2-search__field' );
if ( search_field )
{
search_field.focus();
search_field.select();
}
}, 0 );
});
});
</script>
</script>