- 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.
126 lines
3.2 KiB
PHP
126 lines
3.2 KiB
PHP
<?php
|
|
namespace Domain\Tasks;
|
|
|
|
class WorkTimeRepository
|
|
{
|
|
private const UNSETTLED_TASK_STATUSES = [ 1, 3 ]; // do sprawdzenia, do rozliczenia
|
|
private $mdb;
|
|
|
|
public function __construct( $mdb = null )
|
|
{
|
|
if ( $mdb )
|
|
$this -> mdb = $mdb;
|
|
else
|
|
{
|
|
global $mdb;
|
|
$this -> mdb = $mdb;
|
|
}
|
|
}
|
|
|
|
public function getClientsWithUnsettledTasks()
|
|
{
|
|
$clients = $this -> mdb -> select( 'crm_client', '*', [ 'ORDER' => [ 'firm' => 'ASC' ] ] );
|
|
$work_time = [];
|
|
|
|
if ( !is_array( $clients ) or !count( $clients ) )
|
|
return $work_time;
|
|
|
|
foreach ( $clients as $client )
|
|
{
|
|
$task_rows = $this -> getClientTaskRows( (int)$client['id'] );
|
|
$client['tasks'] = self::buildClientTasksByMonth( $task_rows, function( $task_id, $month ) {
|
|
return (int)$this -> getTaskTotalTimeByMonth( $task_id, $month );
|
|
} );
|
|
|
|
if ( is_array( $client['tasks'] ) and count( $client['tasks'] ) )
|
|
krsort( $client['tasks'] );
|
|
|
|
$work_time[] = $client;
|
|
}
|
|
|
|
return $work_time;
|
|
}
|
|
|
|
public static function buildClientTasksByMonth( array $task_rows, callable $task_time_provider )
|
|
{
|
|
$tasks = [];
|
|
$seen = [];
|
|
|
|
foreach ( $task_rows as $row )
|
|
{
|
|
if ( !isset( $row['month'] ) or !isset( $row['id'] ) )
|
|
continue;
|
|
|
|
$month = (string)$row['month'];
|
|
$task_id = (int)$row['id'];
|
|
$dedupe_key = $task_id . ':' . $month;
|
|
|
|
if ( isset( $seen[$dedupe_key] ) )
|
|
continue;
|
|
|
|
$seen[$dedupe_key] = true;
|
|
|
|
$tasks[ $month ][] = [
|
|
'id' => $task_id,
|
|
'name' => $row['name'],
|
|
'pay_rate' => $row['pay_rate'],
|
|
'time' => (int)call_user_func( $task_time_provider, $task_id, $month )
|
|
];
|
|
}
|
|
|
|
return $tasks;
|
|
}
|
|
|
|
private function getClientTaskRows( $client_id )
|
|
{
|
|
$statuses = implode( ',', self::UNSETTLED_TASK_STATUSES );
|
|
|
|
return $this -> mdb -> query(
|
|
'SELECT DISTINCT '
|
|
. 't.id, t.name, t.pay_rate, DATE_FORMAT(tw.date_end, \'%Y-%m\') AS month '
|
|
. 'FROM tasks AS t '
|
|
. 'INNER JOIN tasks_work AS tw ON t.id = tw.task_id '
|
|
. 'WHERE t.status IN (' . $statuses . ') '
|
|
. 'AND t.client_id = ' . (int)$client_id . ' '
|
|
. 'AND tw.deleted = 0 '
|
|
. 'AND tw.date_end IS NOT NULL '
|
|
. 'ORDER BY month DESC, t.date_add DESC'
|
|
) -> fetchAll( \PDO::FETCH_ASSOC );
|
|
}
|
|
|
|
public static function getUnsettledTaskStatuses()
|
|
{
|
|
return self::UNSETTLED_TASK_STATUSES;
|
|
}
|
|
|
|
private function getTaskTotalTimeByMonth( $task_id, $month )
|
|
{
|
|
$seconds = 0;
|
|
$date_from = $month . '-01 00:00:00';
|
|
$date_to = $month . '-' . date( 't', strtotime( $month ) ) . ' 23:59:59';
|
|
|
|
$rows = $this -> mdb -> select( 'tasks_work', [ 'date_start', 'date_end' ], [
|
|
'AND' => [
|
|
'deleted' => 0,
|
|
'task_id' => (int)$task_id,
|
|
'date_end[>=]' => $date_from,
|
|
'date_end[<=]' => $date_to
|
|
],
|
|
'ORDER' => [ 'id' => 'ASC' ]
|
|
] );
|
|
|
|
if ( !is_array( $rows ) or !count( $rows ) )
|
|
return 0;
|
|
|
|
foreach ( $rows as $row )
|
|
{
|
|
if ( !$row['date_end'] )
|
|
$row['date_end'] = date( 'Y-m-d H:i:s' );
|
|
|
|
$seconds += strtotime( $row['date_end'] ) - strtotime( $row['date_start'] );
|
|
}
|
|
|
|
return $seconds;
|
|
}
|
|
}
|