Files
crmPRO/autoload/Domain/Tasks/WorkTimeRepository.php
Jacek Pyziak 47ffc19a23 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.
2026-02-06 23:11:48 +01:00

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;
}
}