meraproject/module/timer/history/model.php
keboss-m 5c21d25d45 Initial commit: Merakomis portal, Docker stack and user-reader API.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 11:04:05 +03:00

284 lines
11 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?
namespace timer;
use core\db\structure\Column as C;
use core\db\structure\eColumnType;
use Mpdf\Tag\P;
use ui\form\structure\eInputType;
use ui\Form;
use ui\input\Input;
use core\lang\structure\LangVariable as V;
use ms\ms\structure\msModuleTable;
use timer\history\structure\timerHistoryLang as Vars;
class History extends msModuleTable {
static $self;
static $table_name = 'timerHistory';
static $controller = 'timer.history';
static $ID = 'id';
static $ACTION = 'action';
static $BEGIN = 'begin';
static $END = 'end';
static $DATE_BEGIN = 'date_begin';
static $DATE_END = 'date_end';
static $DURATION = 'duration';
static $PAUSE = 'pause';
static $PROFILE = 'profile';
static $PORTAL = 'portal';
static $COMMENT = 'comment';
static $ACCOUNT = 'account';
static function getTitle(){return V::get(Vars::$MODULE_NAME);}
static function getSystemLangValues():array{ return Vars::getArray(); }
public static function installUniques() {
\DB::addIndex(self::$table_name,self::$PROFILE);
\DB::addIndex(self::$table_name,self::$PORTAL);
\DB::addIndex(self::$table_name,self::$BEGIN);
\DB::addIndex(self::$table_name,self::$END);
\DB::addIndex(self::$table_name,self::$DATE_BEGIN);
\DB::addIndex(self::$table_name,self::$DATE_END);
\DB::addIndex(self::$table_name,self::$ACCOUNT);
}
// ВЫБОРКА ЗА ДЕНЬ
static function getMyHistoryTotalThisDay(){
$a = Action::getMy();
$ids = array_keys($a);
return self::getHistoryTotalThisDay($ids);
}
static function getHistoryTotalThisDay($action_ids){
return self::getHistoryTotalDayByDate($action_ids,date('Y-m-d'));
}
static function getHistoryTotalDayByDate($action_ids,$date){
$time = strtotime($date);
return self::getHistoryTotal($action_ids,$time,$time+60*60*24);
}
// ВЫБОРКА ЗА НЕДЕЛЮ
static function getMyHistoryTotalThisWeek(){
$a = Action::getMy();
$ids = array_keys($a);
return self::getHistoryTotalThisWeek($ids);
}
static function getHistoryTotalThisWeek($action_ids){
return self::getHistoryTotalWeekByDate($action_ids,date('Y-m-d'));
}
static function getHistoryTotalWeekByDate($action_ids,$date){
$x = strtotime($date);
$w = intval(date('w',$x));
if(!$w) $w=7;
$date = new \DateTime($date);
$int = new \DateInterval('P'.(intval($w)-1).'D');
$date->sub($int);
$begin = $date->getTimestamp();
$int->d = 7;
$end = $date->add($int)->getTimestamp();
return self::getHistoryTotal($action_ids,$begin,$end);
}
// ВЫБОРКА ЗА МЕСЯЦ
static function getMyHistoryTotalThisMonth(){
$a = Action::getMy();
$ids = array_keys($a);
return self::getHistoryTotalThisDay($ids);
}
static function getHistoryTotalThisMonth($action_ids){
return self::getHistoryTotalMonthByDate($action_ids,date('Y-m-d'));
}
static function getHistoryTotalMonthByDate($action_ids,$date){
$begin = strtotime( date('Y-m-01'), strtotime($date) );
$end = $begin + 24*60*60*date('t',$begin);
return self::getHistoryTotal($action_ids,$begin,$end);
}
// ВЫБОРКА ЗА ГОД
static function getMyHistoryTotalThisYear(){
$a = Action::getMy();
$ids = array_keys($a);
return self::getHistoryTotalThisDay($ids);
}
static function getHistoryTotalThisYear($action_ids){
return self::getHistoryTotalYearByDate($action_ids,date('Y-m-d'));
}
static function getHistoryTotalYearByDate($action_ids,$date){
$begin = strtotime( date('Y-01-01'), strtotime($date) );
$end = $begin + 24*60*60*(date('L')?366:365);
return self::getHistoryTotal($action_ids,$begin,$end);
}
// ПОЛУЧЕНИЕ КОЛИЧЕСТВА ВРЕМЕНИ ДЕЙСТВИЙ ЗА ПЕРИОД
static function getHistoryTotal($action_ids,$begin,$end){
$res = [];
$ids = [];
foreach ($action_ids as $k=>$v){
$ids[$k] = intval($v);
}
$date_begin = date('Y-m-d',$begin);
$date_end = date('Y-m-d',$end-1);
if($ids){
// Сначала считаем те, которые чётко попали в промежуток
$r = self::select($q = [
\Query::SELECT => [
self::$ACTION,
'SUM('.self::$DURATION.') as duration',
],
\Query::WHERE => new \Where(\Where::_and([
\Where::_in(self::$ACTION,$ids),
\Where::_and([
\Where::_and([
\Where::_operator(self::$DATE_BEGIN,'>=',$date_begin),
\Where::_operator(self::$DATE_BEGIN,'<=',$date_end),
]),
\Where::_and([
\Where::_operator(self::$DATE_END,'>=',$date_begin),
\Where::_operator(self::$DATE_END,'<=',$date_end),
]),
])
])
),
\Query::GROUP_BY => self::$ACTION
]);
while($l = \DB::fetch($r)){
$action_id = intval($l[self::$ACTION]);
$res[$action_id] += $l['duration'];
}
/// Теперь надо посчитать те, которые попали в этот период, на частично.
$r = self::select([
\Query::SELECT => [
self::$ACTION,
self::$BEGIN,
self::$END,
],
\Query::WHERE => new \Where(\Where::_and([
\Where::_in(self::$ACTION,$ids),
\Where::_and([
\Where::_or([
// Либо те, у которых начало меньше, но окончание где-то за началом
\Where::_and([
\Where::_operator(self::$DATE_BEGIN,'<',$date_begin),
\Where::_operator(self::$DATE_END,'>=',$date_begin),
]),
// Либо те, у которых начало меньше окончания периода, но окончание за ним
\Where::_and([
\Where::_operator(self::$DATE_BEGIN,'<=',$date_end),
\Where::_operator(self::$DATE_END,'>',$date_end),
]),
])
])
])
),
]);
while($l = \DB::fetch($r)){
$action_id = $l[self::$ACTION];
$h_begin = $l[self::$BEGIN];
$h_end = $l[self::$END];
// Возможны три ситуации
// Дейстие начали и закончили вне рамок периода
if($h_begin < $begin and $h_end > $end){
// В таком случае, просто к длительности прибавляем весь период
$res[$action_id] += $end - $begin;
// Действие началось до начала, и закончилось, где-то в периоде
} else if($h_begin < $begin and $h_end < $end){
// В таком случае прибавляем разницу от начала периода до окончания
$res[$action_id] += $h_end - $begin;
// Случай, когда начало, позже начала периода, а окончание позже окончания пеиода
} else if($h_begin > $begin and $h_end > $end){
// В таком случаем, прибавлеям разницу от начала, до окончания периода
$res[$action_id] += $end - $h_begin;
}
}
}
return $res;
}
static function columnInfo() : array {
return [
new C([
C::VAR_NAME =>&self::$ID,
C::TYPE =>eColumnType::INT,
C::AUTO_INCREMENT =>true,
C::PRIMARY =>true,
C::DEFAULT =>0,
C::HIDDEN =>true,
C::TH =>V::get(Vars::$ID),
]),
new C([
C::VAR_NAME => &self::$ACTION,
C::TYPE => eColumnType::INT,
]),
new C([
C::VAR_NAME => &self::$BEGIN,
C::TYPE => eColumnType::INT,
]),
new C([
C::VAR_NAME => &self::$END,
C::TYPE => eColumnType::INT,
]),
new C([
C::VAR_NAME => &self::$DATE_BEGIN,
C::TYPE => eColumnType::DATE,
]),
new C([
C::VAR_NAME => &self::$DATE_END,
C::TYPE => eColumnType::DATE,
]),
new C([
C::VAR_NAME => &self::$DURATION,
C::TYPE => eColumnType::INT,
]),
new C([
C::VAR_NAME => &self::$PAUSE,
C::TYPE => eColumnType::INT,
]),
new C([
C::VAR_NAME => &self::$PROFILE,
C::TYPE => eColumnType::INT,
C::DEFAULT => intval(PID),
]),
new C([
C::VAR_NAME => &self::$PORTAL,
C::TYPE => eColumnType::INT,
C::DEFAULT => intval(\Site::$portal_id),
]),
new C([
C::VAR_NAME => &self::$COMMENT,
C::TYPE => eColumnType::TEXT,
]),
new C([
C::VAR_NAME => &self::$ACCOUNT,
C::TYPE => eColumnType::INT,
C::DEFAULT => intval(\Site::$owner_id),
]),
];
}
}
new History();
///