fix-logs: пофиксил неверную запись entity id, убрал экспорт удаленных всп, нельзя выбрать удаленный ссп при создании проекта, добавил FK для таблиц, поправил работу фильтра для журнала аудита по дате, админ может получить удаленный всп

This commit is contained in:
tsygankoviva 2026-07-28 12:17:05 +03:00
parent e0941e0a5c
commit 13e7791866
14 changed files with 307 additions and 26 deletions

View File

@ -0,0 +1,84 @@
import os
import re
import time
from alembic import op
import sqlalchemy as sa
revision = "0011"
down_revision = "0010"
branch_labels = None
depends_on = None
_DOLLAR_TAG_RE = re.compile(r"\$\w+\$")
def _find_dollar_tag(line: str) -> str | None:
m = _DOLLAR_TAG_RE.search(line.strip())
return m.group(0) if m else None
def _split_statements(sql: str) -> list[str]:
statements: list[str] = []
current: list[str] = []
in_dollar = False
dollar_tag: str | None = None
for line in sql.split("\n"):
stripped = line.strip()
if stripped.startswith("--"):
continue
if not in_dollar:
tag = _find_dollar_tag(stripped)
if tag and tag.endswith("$") and tag.startswith("$"):
dollar_tag = tag
in_dollar = True
current.append(line)
continue
if in_dollar and dollar_tag and stripped.startswith(dollar_tag):
after = stripped[len(dollar_tag):].strip()
if after == ";" or after == "":
in_dollar = False
dollar_tag = None
if after == ";":
current.append(line)
statements.append("\n".join(current))
current = []
continue
if not in_dollar and stripped.rstrip().endswith(";"):
current.append(line)
statements.append("\n".join(current))
current = []
continue
current.append(line)
remaining = "\n".join(current).strip()
if remaining:
statements.append(remaining)
return statements
def upgrade() -> None:
ddl_path = os.path.join(os.path.dirname(__file__), "sql", "0011_form3_log.sql")
with open(ddl_path) as f:
content = f.read()
statements = _split_statements(content)
for stmt in statements:
stripped = stmt.strip().rstrip(";").strip()
if not stripped:
continue
if all(l.strip().startswith("--") or not l.strip() for l in stripped.split("\n")):
continue
op.execute(stripped)
def downgrade() -> None:
pass

View File

@ -0,0 +1,172 @@
CREATE OR REPLACE FUNCTION v3.add_project_year(p_project_id integer, p_year integer, p_emit_audit boolean DEFAULT true)
RETURNS TABLE(limit_report_id integer, current_expenses_report_id integer)
LANGUAGE plpgsql
AS $function$
DECLARE
v_lim INT;
v_cur INT;
BEGIN
IF p_year IS NULL THEN
RAISE EXCEPTION 'p_year обязателен';
END IF;
IF NOT EXISTS (SELECT 1 FROM v3.project WHERE id = p_project_id) THEN
RAISE EXCEPTION 'project id=% не существует', p_project_id;
END IF;
IF EXISTS (SELECT 1 FROM v3.rf_project_report
WHERE project_id = p_project_id AND year = p_year) THEN
RAISE EXCEPTION 'год % у проекта id=% уже заведён', p_year, p_project_id;
END IF;
INSERT INTO v3.rf_project_report (project_id, year, report_type)
VALUES (p_project_id, p_year, 'LIMIT') RETURNING id INTO v_lim;
INSERT INTO v3.rf_project_report (project_id, year, report_type)
VALUES (p_project_id, p_year, 'CURRENT_EXPENSES') RETURNING id INTO v_cur;
-- Snapshot RBAC-фаз (иначе default deny → отчёт read-only)
PERFORM v3.copy_template_to_report(v_lim);
PERFORM v3.copy_template_to_report(v_cur);
-- Фиксированная сетка статей на оба трека
PERFORM v3.seed_form3_report_lines(v_lim);
PERFORM v3.seed_form3_report_lines(v_cur);
IF p_emit_audit THEN
PERFORM v3.log_event(
'PROJECT_YEAR_ADD', 'PROJECT',
jsonb_build_object(
'project_id', p_project_id,
'year', p_year,
'limit_report_id', v_lim,
'current_expenses_report_id', v_cur
)
);
END IF;
RETURN QUERY SELECT v_lim, v_cur;
END;
$function$
;
-- FKs
ALTER TABLE v3.app_user ADD CONSTRAINT app_user_role_fk FOREIGN KEY (role_id) REFERENCES v3."role"(id);
ALTER TABLE v3.audit_log ADD CONSTRAINT audit_log_app_user_fk FOREIGN KEY (user_id) REFERENCES v3.app_user(id);
ALTER TABLE v3.audit_log ADD CONSTRAINT audit_log_org_unit_fk FOREIGN KEY (org_unit_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.audit_log ADD CONSTRAINT audit_log_budget_form_fk FOREIGN KEY (form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.booking ADD CONSTRAINT booking_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.budget_form ADD CONSTRAINT budget_form_app_user_fk FOREIGN KEY (created_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.budget_form ADD CONSTRAINT budget_form_app_user_fk_1 FOREIGN KEY (updated_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.budget_form ADD CONSTRAINT budget_form_org_unit_fk FOREIGN KEY (org_unit_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_budget_form_fk FOREIGN KEY (budget_form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_expense_item_fk FOREIGN KEY (expense_item_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_vsp_fk FOREIGN KEY (vsp_id) REFERENCES v3.vsp(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_app_user_fk FOREIGN KEY (created_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_app_user_fk_1 FOREIGN KEY (updated_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.budget_line_quarter ADD CONSTRAINT budget_line_quarter_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.ckk ADD CONSTRAINT ckk_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.collegial_approval ADD CONSTRAINT collegial_approval_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.contract_detail ADD CONSTRAINT contract_detail_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.contract_summary ADD CONSTRAINT contract_summary_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.expense_item ADD CONSTRAINT expense_item_expense_item_fk FOREIGN KEY (parent_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.expense_item_form_type ADD CONSTRAINT expense_item_form_type_expense_item_fk FOREIGN KEY (expense_item_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.fixed_asset_report ADD CONSTRAINT fixed_asset_report_budget_form_fk FOREIGN KEY (budget_form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.fixed_asset_report ADD CONSTRAINT fixed_asset_report_expense_item_fk FOREIGN KEY (expense_item_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.form3_phase ADD CONSTRAINT form3_phase_rf_project_report_fk FOREIGN KEY (rf_project_report_id) REFERENCES v3.rf_project_report(id);
ALTER TABLE v3.form_limit ADD CONSTRAINT form_limit_budget_form_fk FOREIGN KEY (budget_form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.form_phase ADD CONSTRAINT form_phase_budget_form_fk FOREIGN KEY (budget_form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.phase_template ADD CONSTRAINT phase_template_form_type_fk FOREIGN KEY (form_type) REFERENCES v3.form_type(code);
ALTER TABLE v3."plan" ADD CONSTRAINT plan_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.project ADD CONSTRAINT project_org_unit_fk FOREIGN KEY (org_unit_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.rent_detail ADD CONSTRAINT rent_detail_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.rent_detail ADD CONSTRAINT rent_detail_vsp_fk FOREIGN KEY (vsp_id) REFERENCES v3.vsp(id);
ALTER TABLE v3.reserve ADD CONSTRAINT reserve_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.rf_project_report ADD CONSTRAINT rf_project_report_project_fk FOREIGN KEY (project_id) REFERENCES v3.project(id);
ALTER TABLE v3.rf_project_report ADD CONSTRAINT rf_project_report_app_user_fk FOREIGN KEY (created_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.rf_project_report ADD CONSTRAINT rf_project_report_app_user_fk_1 FOREIGN KEY (updated_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.rf_project_report_line ADD CONSTRAINT rf_project_report_line_rf_project_report_fk FOREIGN KEY (rf_project_report_id) REFERENCES v3.rf_project_report(id);
ALTER TABLE v3.rf_project_report_line ADD CONSTRAINT rf_project_report_line_expense_item_fk FOREIGN KEY (expense_item_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.rf_project_report_quarter ADD CONSTRAINT rf_project_report_quarter_rf_project_report_line_fk FOREIGN KEY (rf_project_report_line_id) REFERENCES v3.rf_project_report_line(id);
ALTER TABLE v3.security_detail ADD CONSTRAINT security_detail_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.security_detail ADD CONSTRAINT security_detail_vsp_fk FOREIGN KEY (vsp_id) REFERENCES v3.vsp(id);
ALTER TABLE v3.sequestration ADD CONSTRAINT sequestration_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.user_org ADD CONSTRAINT user_org_app_user_fk FOREIGN KEY (user_id) REFERENCES v3.app_user(id);
ALTER TABLE v3.user_org ADD CONSTRAINT user_org_org_unit_fk FOREIGN KEY (org_unit_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.utility_detail ADD CONSTRAINT utility_detail_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.utility_detail ADD CONSTRAINT utility_detail_vsp_fk FOREIGN KEY (vsp_id) REFERENCES v3.vsp(id);
ALTER TABLE v3.vsp ADD CONSTRAINT vsp_org_unit_fk FOREIGN KEY (branch_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.vsp ADD CONSTRAINT vsp_app_user_fk FOREIGN KEY (created_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.vsp ADD CONSTRAINT vsp_app_user_fk_1 FOREIGN KEY (updated_by) REFERENCES v3.app_user(id);
-- DROP FUNCTION v3.add_project(varchar, int4, int4, varchar, int4, varchar, varchar, varchar, varchar, int4, numeric, varchar);
CREATE OR REPLACE FUNCTION v3.add_project(p_name character varying, p_year integer, p_org_unit_id integer, p_level character varying DEFAULT 'project'::character varying, p_parent_id integer DEFAULT NULL::integer, p_project_type character varying DEFAULT NULL::character varying, p_vsp_format character varying DEFAULT NULL::character varying, p_placement_type character varying DEFAULT NULL::character varying, p_object_address character varying DEFAULT NULL::character varying, p_staff_count integer DEFAULT NULL::integer, p_total_area numeric DEFAULT NULL::numeric, p_system_code character varying DEFAULT NULL::character varying)
RETURNS TABLE(project_id integer, limit_report_id integer, current_expenses_report_id integer)
LANGUAGE plpgsql
AS $function$
DECLARE
v_pid INT;
v_lim INT;
v_cur INT;
BEGIN
IF p_name IS NULL OR length(trim(p_name)) = 0 THEN
RAISE EXCEPTION 'p_name обязателен';
END IF;
IF p_year IS NULL THEN
RAISE EXCEPTION 'p_year обязателен';
END IF;
IF p_org_unit_id IS NULL THEN
RAISE EXCEPTION 'p_org_unit_id обязателен';
END IF;
IF NOT EXISTS (SELECT 1 FROM v3.org_unit ou WHERE id = p_org_unit_id AND ou.is_active ) THEN
RAISE EXCEPTION 'org_unit id=% не существует', p_org_unit_id;
END IF;
IF p_parent_id IS NOT NULL AND
NOT EXISTS (SELECT 1 FROM v3.project WHERE id = p_parent_id AND level = 'program') THEN
RAISE EXCEPTION 'parent project id=% не существует или не имеет level=program', p_parent_id;
END IF;
-- INSERT project (CHECK-ы name/project_type/vsp_format/placement_type
-- из migrate_form3_v1.sql применятся автоматически).
INSERT INTO v3.project (
name, level, parent_id, org_unit_id,
project_type, vsp_format, placement_type, object_address, staff_count, total_area,
system_code
) VALUES (
p_name, p_level, p_parent_id, p_org_unit_id,
p_project_type, p_vsp_format, p_placement_type, p_object_address, p_staff_count, p_total_area,
p_system_code
) RETURNING id INTO v_pid;
-- Первый год: 2 отчёта (LIMIT + CURRENT_EXPENSES) + snapshot фаз + сетка статей.
-- p_emit_audit=false — событие года покрыто PROJECT_CREATE ниже. Дальнейшие
-- годы добавляются отдельно через v3.add_project_year.
SELECT y.limit_report_id, y.current_expenses_report_id
INTO v_lim, v_cur
FROM v3.add_project_year(v_pid, p_year, false) y;
-- Аудит: PROJECT_CREATE — все заполненные поля + id отчётов
PERFORM v3.log_event(
'PROJECT_CREATE', 'PROJECT',
jsonb_strip_nulls(jsonb_build_object(
'project_id', v_pid,
'name', p_name,
'year', p_year,
'level', p_level,
'parent_id', p_parent_id,
'org_unit_id', p_org_unit_id,
'project_type', p_project_type,
'vsp_format', p_vsp_format,
'placement_type', p_placement_type,
'object_address', p_object_address,
'system_code', p_system_code,
'staff_count', p_staff_count,
'total_area', p_total_area,
'limit_report_id', v_lim,
'current_expenses_report_id', v_cur
))
);
RETURN QUERY SELECT v_pid, v_lim, v_cur;
END;
$function$
;

View File

@ -46,6 +46,7 @@ async def get_vsp(
staff_count_min=staff_count_min, staff_count_min=staff_count_min,
staff_count_max=staff_count_max, staff_count_max=staff_count_max,
load_org_unit=True, load_org_unit=True,
is_active=True,
with_count=True, with_count=True,
) )
return BaseListResponse( return BaseListResponse(

View File

@ -33,6 +33,7 @@ class Vsp(Base):
total_area: Mapped[float | None] = mapped_column(Numeric) total_area: Mapped[float | None] = mapped_column(Numeric)
closed_at: Mapped[date | None] = mapped_column(Date) closed_at: Mapped[date | None] = mapped_column(Date)
is_active: Mapped[bool] = mapped_column(Boolean, default=True) is_active: Mapped[bool] = mapped_column(Boolean, default=True)
#ToDo: а нужно ли нам и is_active и is_deleted?
is_deleted: Mapped[bool] = mapped_column(Boolean, default=False) is_deleted: Mapped[bool] = mapped_column(Boolean, default=False)
system_code: Mapped[str | None] = mapped_column(String(100), nullable=True) system_code: Mapped[str | None] = mapped_column(String(100), nullable=True)
created_at: Mapped[datetime] = mapped_column( created_at: Mapped[datetime] = mapped_column(

View File

@ -14,8 +14,14 @@ class VSPRepository:
def __init__(self, db: AsyncSession): def __init__(self, db: AsyncSession):
self.db = db self.db = db
async def get(self, vsp_id: int, is_active: bool | None = None, load_org_unit: bool = False) -> Optional[Vsp]: async def get(
queries = [Vsp.id == vsp_id, Vsp.is_deleted.is_(False)] self,
vsp_id: int,
is_active: bool | None = None,
load_org_unit: bool = False,
with_deleted: bool = False,
) -> Optional[Vsp]:
queries = [Vsp.id == vsp_id, Vsp.is_deleted.is_(with_deleted)]
if is_active is not None: if is_active is not None:
queries.append(Vsp.is_active == is_active) queries.append(Vsp.is_active == is_active)
if load_org_unit: if load_org_unit:

View File

@ -49,6 +49,7 @@ SHEET_NAMES = {
'AHR_SECURITY': 'АХР Безопасность', 'AHR_SECURITY': 'АХР Безопасность',
'AHR_UTILITY': 'АХР Коммунальные услуги', 'AHR_UTILITY': 'АХР Коммунальные услуги',
'SMETA': 'Смета', 'SMETA': 'Смета',
'STRUCTURE': 'Структура',
} }
SKIP_SHEETS = ('OTCH9F',) SKIP_SHEETS = ('OTCH9F',)
@ -327,8 +328,8 @@ class ExportService:
("Форма ID", form.id), ("Форма ID", form.id),
("Тип формы", form.form_type_code), ("Тип формы", form.form_type_code),
("Год", form.year), ("Год", form.year),
("Org Unit ID", form.org_unit_id), ("ID ССП.РФ", form.org_unit_id),
("Org Unit", form.org_unit.title if form.org_unit else None), ("ССП/РФ", form.org_unit.title if form.org_unit else None),
("Экспортировано", datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")), ("Экспортировано", datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")),
] ]
for row_idx, (key, value) in enumerate(metadata_rows, start=1): for row_idx, (key, value) in enumerate(metadata_rows, start=1):

View File

@ -36,7 +36,11 @@ class VSPService:
self.user_repo = UserRepository(db) self.user_repo = UserRepository(db)
async def get(self, vsp_id: int, user: AppUser, load_org_unit: bool = False) -> Optional[Vsp]: async def get(self, vsp_id: int, user: AppUser, load_org_unit: bool = False) -> Optional[Vsp]:
vsp = await self.vsp_repo.get(vsp_id=vsp_id, load_org_unit=load_org_unit) vsp = await self.vsp_repo.get(
vsp_id=vsp_id,
load_org_unit=load_org_unit,
with_deleted=user.role_id == UserRoleEnum.ADMIN,
)
if not vsp: if not vsp:
return None return None
if user.role_id == UserRoleEnum.ADMIN: if user.role_id == UserRoleEnum.ADMIN:
@ -173,7 +177,7 @@ class VSPService:
placement_type=placement_type, placement_type=placement_type,
staff_count_min=staff_count_min, staff_count_min=staff_count_min,
staff_count_max=staff_count_max, staff_count_max=staff_count_max,
is_active=None, is_active=True,
load_org_unit=True, load_org_unit=True,
) )

View File

@ -58,8 +58,8 @@ def test_vsp_dropdown_with_filter(client, admin_tokens, auth_headers, params, co
assert len(payload["result"]) == count assert len(payload["result"]) == count
def test_vsp_get_by_id(client, admin_tokens, auth_headers): def test_vsp_get_by_id(client, isp_tokens, auth_headers):
response = client.get("/api/v1/dict/info/1", headers=auth_headers(admin_tokens)) response = client.get("/api/v1/dict/info/1", headers=auth_headers(isp_tokens))
assert response.status_code == 200 assert response.status_code == 200
payload = response.json() payload = response.json()
assert "result" in payload assert "result" in payload

View File

@ -28,9 +28,9 @@ INSERT INTO v3.form_phase (budget_form_id,sheet,phase_code,"role",column_keys,op
(4,'AHR','test','DFIP','{{plan.q1}}','2029-05-05 03:00:00+05','2029-06-06 03:00:00+05'); (4,'AHR','test','DFIP','{{plan.q1}}','2029-05-05 03:00:00+05','2029-06-06 03:00:00+05');
INSERT INTO v3.vsp (id,branch_id,reg_number,address,format,opened_at,placement_type,staff_count,total_area,closed_at,is_active,updated_at,is_deleted,created_at,created_by,system_code,updated_by,vsp_type,notes,rent_contract_num,rent_end_date) VALUES INSERT INTO v3.vsp (id,branch_id,reg_number,address,format,opened_at,placement_type,staff_count,total_area,closed_at,is_active,updated_at,is_deleted,created_at,created_by,system_code,updated_by,vsp_type,notes,rent_contract_num,rent_end_date) VALUES
(1,2,'Тестовый всп 1','Тестовая 12','укукк','2026-05-07','ывс',2026,230,'2026-06-16',false,'2026-06-18 15:46:38.611903',false,'2026-06-04 14:36:59.737727',1,'1233',91,'','','',NULL), (1,2,'Тестовый всп 1','Тестовая 12','укукк','2026-05-07','ывс',2026,230,'2026-06-16',false,'2026-06-18 15:46:38.611903',false,'2026-06-04 14:36:59.737727',1,'1233',1,'','','',NULL),
(2,2,'Test12 -----','Тестовая 125','формат 15 ','2026-06-08',NULL,NULL,58,NULL,true,'2026-06-16 18:53:17.986651',false,'2026-06-09 09:04:33.29858',91,'123-1234',91,'субаренда','Работает ','12-45','2027-10-02'), (2,2,'Test12 -----','Тестовая 125','формат 15 ','2026-06-08',NULL,NULL,58,NULL,true,'2026-06-16 18:53:17.986651',false,'2026-06-09 09:04:33.29858',1,'123-1234',1,'субаренда','Работает ','12-45','2027-10-02'),
(3,2,'3434','победы 12','формат','2026-06-01','субаренда', NULL,34,NULL,true,'2026-07-01 13:32:35.327097',false,'2026-06-29 15:53:50.236062',91,'3434',NULL,'2','примечание','567','2027-07-01'); (3,2,'3434','победы 12','формат','2026-06-01','субаренда', NULL,34,NULL,true,'2026-07-01 13:32:35.327097',false,'2026-06-29 15:53:50.236062',1,'3434',NULL,'2','примечание','567','2027-07-01');
SELECT setval('v3.vsp_id_seq', 3); SELECT setval('v3.vsp_id_seq', 3);
INSERT INTO v3.project ("id","name","level",parent_id,project_type,vsp_format,placement_type,object_address,staff_count,total_area,org_unit_id) VALUES INSERT INTO v3.project ("id","name","level",parent_id,project_type,vsp_format,placement_type,object_address,staff_count,total_area,org_unit_id) VALUES

View File

@ -22,7 +22,7 @@ import { CalendarInput } from './Calendar/CalendarInput';
import { Cancel } from '../common/icons/icons'; import { Cancel } from '../common/icons/icons';
import { getStageStatus, getStatusColors } from './StagesTable/utils'; import { getStageStatus, getStatusColors } from './StagesTable/utils';
import { StageStatusChip } from './StageStatusChip'; import { StageStatusChip } from './StageStatusChip';
import { formatDateForApi } from './utils'; import { formatDateForApi } from '../../utils/formatDate';
import CollapsibleTree from '../common/CollapsibleTree'; import CollapsibleTree from '../common/CollapsibleTree';
import { collectLeafColumns } from '../RealtimeTable/utils/columnUtils'; import { collectLeafColumns } from '../RealtimeTable/utils/columnUtils';
import { STAGE_ROLE_RUSSIAN_NAME } from '../../constants/constants'; import { STAGE_ROLE_RUSSIAN_NAME } from '../../constants/constants';

View File

@ -1,11 +1,3 @@
export const formatDateForApi = (value) => {
if (!value) return '';
const d = new Date(value);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
export const isPastDate = (value) => { export const isPastDate = (value) => {
if (!value) return false; if (!value) return false;
const date = new Date(value); const date = new Date(value);
@ -14,4 +6,3 @@ export const isPastDate = (value) => {
today.setHours(0, 0, 0, 0); today.setHours(0, 0, 0, 0);
return date < today; return date < today;
}; };

View File

@ -12,6 +12,7 @@ import { UsersApi } from '../../../api/users';
import AuditLogsFilters from './components/AuditLogsFilters'; import AuditLogsFilters from './components/AuditLogsFilters';
import AuditLogsTable from './components/AuditLogsTable'; import AuditLogsTable from './components/AuditLogsTable';
import { DEFAULT_ACTIONS } from './constants/auditLogs.jsx'; import { DEFAULT_ACTIONS } from './constants/auditLogs.jsx';
import {formatDateForApi} from '../../../utils/formatDate.js'
const AuditLogsPage = () => { const AuditLogsPage = () => {
const { user } = useAuth(); const { user } = useAuth();
@ -71,12 +72,13 @@ const AuditLogsPage = () => {
user_id: selectedUser?.id, user_id: selectedUser?.id,
org_unit_id: selectedSsp?.id, org_unit_id: selectedSsp?.id,
event: selectedEventType?.id, event: selectedEventType?.id,
date_from: dateFrom ? dateFrom.toISOString().slice(0, 10) : undefined, // date_from: dateFrom ? new Date(dateFrom.getTime() - (dateFrom.getTimezoneOffset() * 60 * 1000)).toISOString().slice(0, 10): undefined,
date_to: dateTo ? dateTo.toISOString().slice(0, 10) : undefined, // date_to: dateTo ? new Date(dateTo.getTime() - (dateTo.getTimezoneOffset() * 60 * 1000)).toISOString().slice(0, 10) : undefined,
date_from: dateFrom ? formatDateForApi(dateFrom) : undefined,
date_to: dateTo ? formatDateForApi(dateTo) : undefined,
task_id: taskId ? taskId : undefined, task_id: taskId ? taskId : undefined,
form_id: formId ? formId : undefined, form_id: formId ? formId : undefined,
}; };
const data = await AuditLogsApi.getAll(params); const data = await AuditLogsApi.getAll(params);
setLogs(data.result ?? []); setLogs(data.result ?? []);
setTotalCount(data.count ?? 0); setTotalCount(data.count ?? 0);

View File

@ -76,7 +76,7 @@ export default function ProjectsPage() {
useEffect(() => { useEffect(() => {
if (!user) return; if (!user) return;
if (user.role_id == ROLES_NAME_ID.admin) { if (user.role_id == ROLES_NAME_ID.admin) {
SspApi.getAll().then(data => { SspApi.getAll({is_active: true}).then(data => {
if (data.success) { if (data.success) {
setProjectData(prev => ({ setProjectData(prev => ({
...prev, 'ССП/РФ': { ...prev, 'ССП/РФ': {

View File

@ -5,3 +5,22 @@ export const formatDate = (dateString) => {
const year = date.getFullYear(); const year = date.getFullYear();
return `${day}.${month}.${year}`; return `${day}.${month}.${year}`;
}; };
export const formatDateForApi = (value) => {
if (!value) return '';
const d = new Date(value);
const year = String(d.getFullYear()).padStart(4, '0');
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
export const isPastDate = (value) => {
if (!value) return false;
const date = new Date(value);
date.setHours(0, 0, 0, 0);
const today = new Date();
today.setHours(0, 0, 0, 0);
return date < today;
};