meraproject/themes/merakomis/fot/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

620 lines
22 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 themes\merakomis;
use core\columns\structure\eFilterType;
use core\db\structure\Column as C;
use core\db\structure\eColumnType;
use core\lang\structure\LangVariable as V;
use ModuleBZ\Form\Input\Hidden;
use ModuleBZ\Form\Input\Select;
use ModuleBZ\Layout\Column;
use ms\ms\structure\msModuleTable;
use common\Image;
use ModuleBZ\Form\Input\ImagePicker;
use ModuleBZ\Form\Input\Switcher;
use ModuleBZ\Form\Input\Text;
use ModuleBZ\Form\Input\Textarea;
use ModuleBZ\Layout\Row;
use themes\Merakomis;
use themes\merakomis\dictionary\City;
use themes\merakomis\dictionary\EmpStatus;
use themes\merakomis\dictionary\Org;
use themes\merakomis\dictionary\OrgType;
use themes\merakomis\fot\Budget;
use themes\merakomis\fot\structure\eFotStatus;
use themes\merakomis\fot\structure\lang as Vars;
use themes\merakomis\emp\structure\tMerakomisEmpLang as EmpVars;
use themes\merakomis\input\Save as InputSave;
use themes\merakomis\structure\merakomisModuleTable;
class Fot extends merakomisModuleTable {
static $self;
static $cache = [];
static $table_name = 'tMerakomisFot';
static $controller = 'themes.merakomis.fot';
static $ID = 'id';
static $NAME = 'name';
static $EMP = 'emp';
static $YM = 'ym';
static $YEAR = 'year';
static $MONTH = 'month';
static $FZP = 'fzp';
static $K = 'k';
static $ADD = 'add';
static $INSURE = 'insure';
static $FOT = 'fot';
static $PK = 'pk';
static $PER_HOUR = 'per_hour';
static $STATUS = 'status';
//----
static $EMP_NAME = 'empName';
static $EMP_ROLES = 'empRoles';
static $EMP_DEPARTMENT = 'empDepartment';
static $EMP_CITY = 'empCity';
static $EMP_ORG = 'empOrg';
static $EMP_ORG_TYPE = 'empOrgType';
static $EMP_IS_FREELANCE = 'empIsFreelance';
static $EMP_STATUS = 'empStatus';
public static function installUniques()
{
\Db::addUnique(self::$table_name,self::$table_name.'_unique',[self::$EMP,self::$YEAR,self::$MONTH]);
}
public static function checkUserAddAccess(array $values = [], int $id = 0, bool $isEdit = false): bool
{
return true;
}
static $ENC_COLUMNS;
static function getEncryptedColumns()
{
return self::$ENC_COLUMNS ?? self::$ENC_COLUMNS = [
self::$FZP,
self::$K,
self::$ADD,
self::$INSURE,
self::$FOT,
self::$PK,
self::$PER_HOUR,
];
}
public static function getByID(int $id)
{
$res = parent::getByID($id);
self::decrypt($res);
return $res;
}
static public function decrypt(&$l)
{
$enc = self::getEncryptedColumns();
foreach ($enc as $c) {
if(isset($l[$c])) $l[$c] = Merakomis::decryptNumber($l[$c]);
}
}
static function getTitle(){return V::get(Vars::$MODULE_NAME);}
static function getSystemLangValues():array{ return Vars::getArray(); }
public function _insert(array $values, array $options = array())
{
$m = $values[self::$MONTH];
$values[self::$YM] = $values[self::$YEAR].'-'.($m<10?'0':'').$m;
$enc = self::getEncryptedColumns();
foreach ($enc as $c) {
if(isset($values[$c])) $values[$c] = Merakomis::encryptNumber($values[$c]);
}
$r = parent::_insert($values, $options);
//if($r) Fot::math($r->id);
return $r;
}
public function _update(\Where $w, array $values)
{
$enc = self::getEncryptedColumns();
foreach ($enc as $c) {
if(isset($values[$c])) $values[$c] = Merakomis::encryptNumber($values[$c]);
}
return parent::_update($w, $values); // TODO: Change the autogenerated stub
}
public static function afterUadd($values, $id, $result)
{
// self::math($id);
}
public static function getEmpIdsForBudget($year,$month)
{
$res = [];
$begin = $year.'-'.($month<10?'0':'').$month.'-01';
$end = date('Y-m-d',strtotime($begin.' + 1 month - 1 day'));
$r = Time::select([
\Query::SELECT => ['DISTINCT '.Time::$EMP],
\Query::WHERE => new \Where(\Where::_and([
\Where::_between(Time::$DATE,$begin,$end),
])),
]);
while($l = \DB::fetch($r)){
$res[] = $l[Time::$EMP];
}
return $res;
}
public static function generate($year,$month){
$r = Emp::getAll();
$empAllIds = array_keys($r);
//$need_ids = self::getEmpIdsForBudget($year,$month);
$emp_ids = [];
$need_ids = [];
$time = strtotime($year.'-'.$month.'-01');
$prevTime = strtotime("-1 month", $time);
$prevMonth = date('m',$prevTime);
$prevYear = date('Y',$prevTime);
$need_and = Time::getEmpWhereAnd(date('Y-m-d',$time),date('Y-m-t',$time));
$r = Emp::select([
\Query::SELECT => [Emp::$ID],
\Query::WHERE => new \Where($need_and),
]);
while($l = \DB::fetch($r)){
$need_ids[] = $l[Emp::$ID];
}
$need_remove = array_diff($empAllIds,$need_ids);
if($need_remove) {
$rr = self::delete(new \Where(
\Where::_and([
\Where::_in(self::$EMP, $need_remove),
\Where::_operator(self::$MONTH,'=',$month),
\Where::_operator(self::$YEAR,'=',$year),
])
));
}
$r = self::select([
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(self::$MONTH,'=',$month),
\Where::_operator(self::$YEAR,'=',$year),
]))
]);
$copy_prev = [];
while($l = \DB::fetch($r)){
self::decrypt($l);
$emp_ids[] = $l[self::$EMP];
$fzp = cfloatval($l[self::$FZP]);
if(!$fzp && !$l[self::$STATUS]){
$copy_prev[$l[self::$ID]] = $l[self::$EMP];
}
}
$need_ids = array_diff($need_ids,$emp_ids);
foreach ($need_ids as $id){
$r = self::insert([
self::$EMP => $id,
self::$MONTH => $month,
self::$YEAR => $year,
]);
$copy_prev[$r->id] = $id;
}
foreach ($copy_prev as $id=>$emp_id){
$r = self::select([
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(self::$EMP,'=',$emp_id),
\Where::_operator(self::$MONTH,'=',$prevMonth),
\Where::_operator(self::$YEAR,'=',$prevYear),
])),
\Query::COUNT => 1
]);
if(\DB::numRows($r)){
$l = \DB::fetch($r);
Fot::decrypt($l);
$x = self::updateById($id,[self::$FZP => $l[self::$FZP]]);
}
}
if($copy_prev) {
Budget::mathByYearMonth($year,$month,['not_generate'=>true]);
}
}
public static function beforeUadd(array $values = []): array {
$res = [];
if(!$values[self::$YEAR]){
$res[self::$YEAR][] = 'Не указан год';
}
if(!$values[self::$MONTH]){
$res[self::$MONTH][] = 'Не указан месяц';
}
if(!$res) {
$r = self::select([
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(self::$YEAR, '=', $values[self::$YEAR]),
\Where::_operator(self::$MONTH, '=', $values[self::$MONTH]),
\Where::_operator(self::$EMP, '=', $values[self::$EMP]),
]))
]);
if (\DB::numRows($r)) {
$l = \DB::fetch($r);
if ($l[self::$ID] == $values[self::$ID]) {
} else {
$res[self::$YEAR][] = 'Такая комбинация года и месяца уже существует';
}
}
}
return $res;
}
public function _updateById(int $id, array $values)
{
$res = parent::_updateById($id, $values); // TODO: Change the autogenerated stub
if(!isset($values[self::$FOT])) {
// self::math($id);
};
return $res;
}
static function getForEmp($emp,$year,$month){
$key = md5($emp.$year.$month);
if(isset(self::$cache[$key])) return self::$cache[$key];
$r = self::select([
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(self::$EMP,'=',$emp),
\Where::_operator(self::$MONTH,'=',$month),
\Where::_operator(self::$YEAR,'=',$year),
])),
\Query::COUNT => 1
]);
$l = \DB::fetch($r);
self::decrypt($l);
return self::$cache[$key] = $l;
}
static function math($id){
$C = self::getByID($id);
/*
$allVars = Variable::getAllVariables();
$vars = $allVars[$C[self::$YEAR]];
$fond0 = (1+$vars[Variable::$FOND1]/100);
$fond1 = (1+$vars[Variable::$FOND2]/100);
$fond2 = (1+$vars[Variable::$FOND3]/100);
$insurance = $vars[Variable::$MROT] * $fond0 * $fond1
+ ( $C[self::$FZP] - ( $fond1 * $vars[Variable::$MROT]) ) * $fond2
;
$C[self::$FOT] = $C[self::$FZP] + $C[self::$ADD] + $insurance;
*/
//$C[self::$FOT] = $C[self::$FZP] * (1+$C[self::$K]);
//$C[self::$FOT] = $budget * (1+$C[self::$K]);
$beginDay = $C[self::$YEAR].'-'.$C[self::$MONTH].'-01';
$days = date('t',strtotime($beginDay));
$endDay = $C[self::$YEAR].'-'.$C[self::$MONTH].'-'.$days;
//$days = Day::getWorkDays($beginDay,$endDay);
$hours = Day::getWorkHours($beginDay,$endDay);
$C[self::$PK] = $hours;
$C[self::$PER_HOUR] = ($C[self::$FOT] / $hours);
//$C[self::$INSURE] = $insurance;
self::updateByID($C[self::$ID],$C);
}
static function getMonths(){
return [
['id'=>1,'title'=>'Январь'],
['id'=>2,'title'=>'Февраль'],
['id'=>3,'title'=>'Март'],
['id'=>4,'title'=>'Апрель'],
['id'=>5,'title'=>'Май'],
['id'=>6,'title'=>'Июнь'],
['id'=>7,'title'=>'Июль'],
['id'=>8,'title'=>'Август'],
['id'=>9,'title'=>'Сентябрь'],
['id'=>10,'title'=>'Октябрь'],
['id'=>11,'title'=>'Ноябрь'],
['id'=>12,'title'=>'Декабрь'],
];
}
static function getStatusName($x){
return eFotStatus::getName($x);
}
static function getFormInputs(\ModuleBZ\Form &$form, array $data, $C, bool $isEdit) {
$emp_id = $C[self::$EMP]??$_POST['params']['id'];
$form
->addRow((new Row())
->addColumn((new Column())->setClassAll('c-40 ')
->addRow((new Row())))
->addColumn(
(new Column())->setClassAll('c-20 ')
->addRow((new Row())
->addColumn(((new Hidden())
->setName(self::$EMP)
->setValue($emp_id)
->setClassAll('c-100')
))
->addColumn(((new Text())
->setName(self::$YEAR)
->setValue($C[self::$YEAR])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$YEAR))
->setPlaceholder($c)
))
->addColumn(((new Select())
->setName(self::$MONTH)
->setValue(intval($C[self::$MONTH]))
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$MONTH))
->setPlaceholder($c)
->setOptions(self::getMonths())
))
->addColumn(((new Text())
->setName(self::$FZP)
->setValue($C[self::$FZP])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$FZP))
->setPlaceholder($c)
))
->addColumn(((new Text())
->setName(self::$ADD)
->setValue($C[self::$ADD])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$ADD))
->setPlaceholder($c)
))
->addColumn(((new Select())
->setName(self::$STATUS)
->setValue(intval($C[self::$STATUS]))
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$STATUS))
->setPlaceholder($c)
->setOptions(eFotStatus::getNameList())
))
)->addRow((new Row())
->addColumn(((new InputSave())->setClassAll('c-100')->setName('save')))
)
)
)
;
}
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::$NAME,
C::TYPE => eColumnType::TEXT,
C::TH => V::get(EmpVars::$NAME),
]),
//----
new C([
C::VAR_NAME => &self::$EMP_NAME,
C::TYPE => eColumnType::NONE,
C::TH => V::get(EmpVars::$NAME),
C::FUNC_VALUE_DATA => function($v) {
return [
'id'=>$v[Emp::$ID],
'archive'=>boolval($v[Emp::$ARCHIVE]),
'name'=>Emp::SurnameIO($v),
];
}
]),
new C([
C::VAR_NAME => &self::$EMP_ROLES,
C::TYPE => eColumnType::NONE,
C::TH => V::get(EmpVars::$STAFFING),
C::TD_CLASS => 'pre_wrap',
C::FUNC_VALUE_DATA => function($v) {
return implode("\n",Emp::getStaffingList($v));
//return Emp::getDepartmentList($v);
}
]),
new C([
C::VAR_NAME => &self::$EMP_DEPARTMENT,
C::TYPE => eColumnType::NONE,
C::TH => V::get(EmpVars::$ROLES),
C::TD_CLASS => 'pre_wrap',
C::FUNC_VALUE_DATA => function($v) {
return implode("\n",Emp::getDepartmentList($v));
//return Emp::getDepartmentList($v);
}
]),
new C([
C::VAR_NAME => &self::$EMP_CITY,
C::TYPE => eColumnType::NONE,
C::FILTER_TYPE => eFilterType::SELECT,
C::DEFAULT => 0,
C::TH => V::get(EmpVars::$CITY),
C::FUNC_VALUE_DATA => function($v){
return City::getName( City::getByIDCached(intval($v[Emp::$CITY])) );
},
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return City::getNameList();
},
]),
new C([
C::VAR_NAME => &self::$EMP_IS_FREELANCE,
C::TYPE => eColumnType::NONE,
C::FILTER_TYPE => eFilterType::BOOLEAN,
C::DEFAULT => 0,
// C::HIDDEN => true,
C::TH => V::get(EmpVars::$IS_FREELANCER),
//C::TH => 'Удалёнка',
C::FUNC_VALUE_DATA => function($v){
return Merakomis::fbool($v[Emp::$IS_FREELANCER]);
},
]),
new C([
C::VAR_NAME => &self::$EMP_ORG,
C::TYPE => eColumnType::NONE,
C::LENGTH => 1,
C::DEFAULT => 1,
C::TH => V::get(EmpVars::$ORG),
C::FILTER_TYPE => eFilterType::SELECT,
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return Org::getNameList();
},
C::FUNC_VALUE_DATA => function($v){
return Org::getName(Org::getByIDCached(intval($v[Emp::$ORG])));
},
]),
new C([
C::VAR_NAME => &self::$EMP_ORG_TYPE,
C::TYPE => eColumnType::NONE,
C::LENGTH => 1,
C::DEFAULT => 1,
//C::TH => V::get(Vars::$ORG_TYPE),
C::TH => 'Вид',
C::FILTER_TYPE => eFilterType::SELECT,
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return OrgType::getNameList();
},
C::FUNC_VALUE_DATA => function($v){
return OrgType::getName(OrgType::getByIDCached(intval($v[Emp::$ORG_TYPE])));
},
]),
new C([
C::VAR_NAME => &self::$EMP_STATUS,
C::TYPE => eColumnType::NONE,
C::LENGTH => 1,
C::DEFAULT => '0',
C::TH => V::get(EmpVars::$STATUS),
C::FILTER_TYPE => eFilterType::SELECT,
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return EmpStatus::getNameList();
},
C::FUNC_VALUE_DATA => function($v){
return EmpStatus::getName(EmpStatus::getByIDCached(intval($v[Emp::$STATUS])));
},
]),
//----
new C([
C::VAR_NAME => &self::$EMP,
C::TYPE => eColumnType::INT,
C::TH => V::get(Vars::$EMP),
]),
new C([
C::VAR_NAME => &self::$STATUS,
C::TYPE => eColumnType::TINYINT,
C::DEFAULT => '0',
C::TH => V::get(Vars::$STATUS),
C::FUNC_VALUE_DATA => function($v) { return self::getStatusName($v[self::$STATUS]); }
]),
new C([
C::VAR_NAME => &self::$YM,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => '7',
C::HIDDEN => true,
C::TH => V::get(Vars::$YM),
]),
new C([
C::VAR_NAME => &self::$YEAR,
C::TYPE => eColumnType::INT,
C::TH => V::get(Vars::$YEAR),
]),
new C([
C::VAR_NAME => &self::$MONTH,
C::TYPE => eColumnType::INT,
C::TH => V::get(Vars::$MONTH),
]),
new C([
C::VAR_NAME => &self::$FZP,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => '128',
C::DEFAULT => '0',
C::TH => V::get(Vars::$FZP),
]),
new C([
C::VAR_NAME => &self::$K,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => '128',
C::DEFAULT => '0',
//C::TH => V::get(Vars::$K),
]),
new C([
C::VAR_NAME => &self::$ADD,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => '128',
C::TH => V::get(Vars::$ADD),
]),
new C([
C::VAR_NAME => &self::$INSURE,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => '128',
C::DEFAULT => '0',
C::TH => V::get(Vars::$INSURE),
]),
new C([
C::VAR_NAME => &self::$FOT,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => '128',
C::DEFAULT => '0',
C::TH => V::get(Vars::$FOT),
]),
new C([
C::VAR_NAME => &self::$PK,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => '128',
C::DEFAULT => '0',
C::TH => V::get(Vars::$PK),
]),
new C([
C::VAR_NAME => &self::$PER_HOUR,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => '128',
C::DEFAULT => '0',
C::TH => V::get(Vars::$PER_HOUR),
]),
];
}
}
new Fot();