Compare commits

...

9 Commits

Author SHA1 Message Date
PotapovaA
64302ea127 Merge branch 'test' into form-4-add-row 2026-07-28 18:26:59 +03:00
d9f67b68a9 Merge pull request '[AURORA-1206] - добавление новых типов в фильтрах журнал аудита' (#52) from AURORA-1206 into test
Reviewed-on: #52
Reviewed-by: PotapovaA <potapovaanna113@mail.ru>
2026-07-28 17:23:32 +03:00
95f9e1a0d9 Merge pull request '[AURORA-894] - фикс удаления строк' (#51) from AURORA-894 into test
Reviewed-on: #51
Reviewed-by: PotapovaA <potapovaanna113@mail.ru>
2026-07-28 17:23:18 +03:00
b4139cd66a Merge pull request 'fix-logs: пофиксил неверную запись entity id, убрал экспорт удаленных всп, нельзя выбрать удаленный ссп при создании проекта, добавил FK для таблиц…' (#53) from fix-logs into test
Reviewed-on: #53
Reviewed-by: Raykov-MS <RaykovMS@avt.rshb.ru>
Reviewed-by: PotapovaA <potapovaanna113@mail.ru>
Reviewed-by: Veronika <veronika.amilonn@gmail.com>
2026-07-28 13:17:37 +03:00
13e7791866 fix-logs: пофиксил неверную запись entity id, убрал экспорт удаленных всп, нельзя выбрать удаленный ссп при создании проекта, добавил FK для таблиц, поправил работу фильтра для журнала аудита по дате, админ может получить удаленный всп 2026-07-28 12:17:24 +03:00
a586ce3adc [AURORA-1206] - добавление новых типов в фильтрах журнал аудита 2026-07-28 09:59:40 +03:00
0b451b2499 [AURORA-894] - фикс удаления строк 2026-07-28 09:50:35 +03:00
e0941e0a5c Merge pull request 'add-line-log-hotfix: пишем лог корректно' (#50) from add-line-log-hotfix into test
Reviewed-on: #50
Reviewed-by: Raykov-MS <RaykovMS@avt.rshb.ru>
2026-07-27 15:56:42 +03:00
49e2183693 add-line-log-hotfix: пишем лог корректно 2026-07-27 15:06:53 +03:00
19 changed files with 325 additions and 33 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

@ -822,7 +822,7 @@ BEGIN
-- 5а. Аудит: ROW_CREATE
PERFORM v3.log_event(
'ROW_CREATE', 'ROW_CREATE',
'ROW_CREATE', 'ROW',
jsonb_build_object(
'sheet', v_sheet,
'line_id', v_new_id,

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_max=staff_count_max,
load_org_unit=True,
is_active=True,
with_count=True,
)
return BaseListResponse(

View File

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

View File

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

View File

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

View File

@ -36,7 +36,11 @@ class VSPService:
self.user_repo = UserRepository(db)
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:
return None
if user.role_id == UserRoleEnum.ADMIN:
@ -173,7 +177,7 @@ class VSPService:
placement_type=placement_type,
staff_count_min=staff_count_min,
staff_count_max=staff_count_max,
is_active=None,
is_active=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
def test_vsp_get_by_id(client, admin_tokens, auth_headers):
response = client.get("/api/v1/dict/info/1", headers=auth_headers(admin_tokens))
def test_vsp_get_by_id(client, isp_tokens, auth_headers):
response = client.get("/api/v1/dict/info/1", headers=auth_headers(isp_tokens))
assert response.status_code == 200
payload = response.json()
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');
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),
(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'),
(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');
(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',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',1,'3434',NULL,'2','примечание','567','2027-07-01');
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

View File

@ -1,4 +1,4 @@
import { getParentId } from "./rowUtils";
import { getDataRowId, getParentId } from "./rowUtils";
export function setNewValueToData(data, colId, rowId, value) {
let targetObject = data;
@ -209,8 +209,9 @@ export function deleteRow(data, lineId) {
function findAndDelete(rows) {
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const rowId = getDataRowId(row.data);
if (row.data.line_id == lineId) {
if (rowId == lineId) {
rowDeleteSortOrder = row.sort_order;
rows.splice(i, 1);
i--;
@ -221,7 +222,7 @@ export function deleteRow(data, lineId) {
}
if (row.subRows && Array.isArray(row.subRows) && row.subRows.length > 0) {
const found = findAndDelete(row.subRows);
findAndDelete(row.subRows);
}
}
}

View File

@ -1,5 +1,9 @@
export function getDataRowId(data) {
return data?.id || data?.line_id;
}
export function getRowId(row) {
return row.original.data.id || row.original.data.line_id;
return getDataRowId(row.original.data);
}
export function isVspRow(row) {

View File

@ -22,7 +22,7 @@ import { CalendarInput } from './Calendar/CalendarInput';
import { Cancel } from '../common/icons/icons';
import { getStageStatus, getStatusColors } from './StagesTable/utils';
import { StageStatusChip } from './StageStatusChip';
import { formatDateForApi } from './utils';
import { formatDateForApi } from '../../utils/formatDate';
import CollapsibleTree from '../common/CollapsibleTree';
import { collectLeafColumns } from '../RealtimeTable/utils/columnUtils';
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) => {
if (!value) return false;
const date = new Date(value);
@ -14,4 +6,3 @@ export const isPastDate = (value) => {
today.setHours(0, 0, 0, 0);
return date < today;
};

View File

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

View File

@ -129,7 +129,11 @@ const AuditLogsTable = ({
header: 'Контекст',
size: 160,
Cell: ({ row }) => (
<Typography>{`${ENTITY_RUSSIAN_NAMES[row.original.entity.toUpperCase()][1]} #${row.original.entity_id}`}</Typography>
<Typography>
{ENTITY_RUSSIAN_NAMES[row.original.entity?.toUpperCase()]?.[1] != null
? `${ENTITY_RUSSIAN_NAMES[row.original.entity?.toUpperCase()]?.[1]} #${row.original.entity_id}`
: '-'}
</Typography>
),
enableColumnActions: false,
enableSorting: false,

View File

@ -13,6 +13,8 @@ export const DEFAULT_ACTIONS = {
VSP_CREATE: 'Создание ВСП',
VSP_UPDATE: 'Обновление ВСП',
DELETE_VSP: 'Удаление ВСП',
PROJECT_CREATE: 'Создание проекта',
PROJECT_DELETE: 'Удаление проекта',
};
export const ENTITY_RUSSIAN_NAMES = {

View File

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

View File

@ -5,3 +5,22 @@ export const formatDate = (dateString) => {
const year = date.getFullYear();
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;
};