526 lines
25 KiB
TypeScript
526 lines
25 KiB
TypeScript
|
|
|
|||
|
|
import { Building, District, EntranceSection, User, Employee, Candidate, Vacancy, PREvent, ResidentReport, DomaApplication, ResidentFeedback, StrategicGoal, Invoice, OfficeRequest, OfficeInventoryItem, OfficeDocument, OfficeAsset, LegalContract, LegalCourtCase, LegalCounterparty, PersonalAccount, AccountMeter, MeterReading } from './types';
|
|||
|
|
import {
|
|||
|
|
LayoutDashboard,
|
|||
|
|
Map,
|
|||
|
|
Wrench,
|
|||
|
|
Banknote,
|
|||
|
|
Scale,
|
|||
|
|
Briefcase,
|
|||
|
|
UsersRound,
|
|||
|
|
Megaphone,
|
|||
|
|
Building2,
|
|||
|
|
Settings,
|
|||
|
|
} from 'lucide-react';
|
|||
|
|
|
|||
|
|
export const CURRENT_USER_MOCK: User = {
|
|||
|
|
id: 'u1',
|
|||
|
|
name: 'Алексей Петров',
|
|||
|
|
role: 'DIRECTOR',
|
|||
|
|
avatar: 'https://picsum.photos/id/1005/64/64'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const MOCK_DISTRICTS: District[] = [];
|
|||
|
|
|
|||
|
|
export const EMPLOYEE_POSITIONS: string[] = [
|
|||
|
|
'Слесарь-сантехник',
|
|||
|
|
'Электрик',
|
|||
|
|
'Дворник',
|
|||
|
|
'Мастер участка',
|
|||
|
|
'Сантехник',
|
|||
|
|
'Сварщик',
|
|||
|
|
'Юрист по работе с дебиторской задолженностью',
|
|||
|
|
'Слесарь-сантехник (4-5 разряд)',
|
|||
|
|
'Другое'
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_EMPLOYEES: Employee[] = [
|
|||
|
|
{
|
|||
|
|
id: 'e1',
|
|||
|
|
name: 'Иванов Иван Иванович',
|
|||
|
|
position: 'Слесарь-сантехник',
|
|||
|
|
phone: '+7 900 123-45-67',
|
|||
|
|
status: 'active',
|
|||
|
|
salary: 45000,
|
|||
|
|
assignedDistrictId: 'd-1',
|
|||
|
|
birthDate: '1985-03-15',
|
|||
|
|
messengerLogins: [
|
|||
|
|
{ messenger: 'Telegram', login: '@ivanov_ii' },
|
|||
|
|
{ messenger: 'Max', login: '+7 900 123-45-67' }
|
|||
|
|
],
|
|||
|
|
photoUrl: 'https://picsum.photos/id/64/200/200',
|
|||
|
|
registrationDate: '2020-01-15',
|
|||
|
|
hrData: {
|
|||
|
|
passportData: {
|
|||
|
|
series: '4510',
|
|||
|
|
number: '123456',
|
|||
|
|
issuedBy: 'ОУФМС России по г. Москве',
|
|||
|
|
issuedDate: '2010-05-20',
|
|||
|
|
registrationAddress: 'г. Москва, ул. Ленина, д. 10, кв. 25'
|
|||
|
|
},
|
|||
|
|
laborBook: {
|
|||
|
|
number: 'ТК-123456',
|
|||
|
|
entries: [
|
|||
|
|
{ date: '2020-01-15', organization: 'ООО "УК Дружба"', position: 'Слесарь-сантехник' }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
certificates: [
|
|||
|
|
{ type: '2-НДФЛ', requestedDate: '2024-01-10', issuedDate: '2024-01-12', status: 'ready' },
|
|||
|
|
{ type: 'Справка с места работы', requestedDate: '2024-03-05', status: 'requested' }
|
|||
|
|
],
|
|||
|
|
otherDocuments: [
|
|||
|
|
{ name: 'Договор трудового найма', type: 'Трудовой договор', date: '2020-01-15' },
|
|||
|
|
{ name: 'Медицинская книжка', type: 'Мед. документ', date: '2023-06-10' }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'e2',
|
|||
|
|
name: 'Петров Петр Петрович',
|
|||
|
|
position: 'Электрик',
|
|||
|
|
phone: '+7 900 123-45-68',
|
|||
|
|
status: 'vacation',
|
|||
|
|
salary: 50000,
|
|||
|
|
assignedDistrictId: 'd-1',
|
|||
|
|
birthDate: '1988-07-22',
|
|||
|
|
messengerLogins: [
|
|||
|
|
{ messenger: 'Telegram', login: '@petrov_pp' }
|
|||
|
|
],
|
|||
|
|
registrationDate: '2019-05-10',
|
|||
|
|
hrData: {
|
|||
|
|
passportData: {
|
|||
|
|
series: '4512',
|
|||
|
|
number: '234567',
|
|||
|
|
issuedBy: 'ОУФМС России по г. Москве',
|
|||
|
|
issuedDate: '2012-08-15',
|
|||
|
|
registrationAddress: 'г. Москва, пр. Мира, д. 5, кв. 12'
|
|||
|
|
},
|
|||
|
|
laborBook: {
|
|||
|
|
number: 'ТК-234567',
|
|||
|
|
entries: [
|
|||
|
|
{ date: '2019-05-10', organization: 'ООО "УК Дружба"', position: 'Электрик' }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'e3',
|
|||
|
|
name: 'Сидорова Анна Александровна',
|
|||
|
|
position: 'Дворник',
|
|||
|
|
phone: '+7 900 123-45-69',
|
|||
|
|
status: 'active',
|
|||
|
|
salary: 25000,
|
|||
|
|
assignedDistrictId: 'd-2',
|
|||
|
|
birthDate: '1975-11-30',
|
|||
|
|
messengerLogins: [
|
|||
|
|
{ messenger: 'Max', login: '+7 900 123-45-69' }
|
|||
|
|
],
|
|||
|
|
photoUrl: 'https://picsum.photos/id/65/200/200',
|
|||
|
|
registrationDate: '2021-03-01',
|
|||
|
|
hrData: {
|
|||
|
|
passportData: {
|
|||
|
|
series: '4508',
|
|||
|
|
number: '345678',
|
|||
|
|
issuedBy: 'ОУФМС России по г. Москве',
|
|||
|
|
issuedDate: '2008-12-10',
|
|||
|
|
registrationAddress: 'г. Москва, ул. Заречная, д. 20, кв. 8'
|
|||
|
|
},
|
|||
|
|
laborBook: {
|
|||
|
|
number: 'ТК-345678',
|
|||
|
|
entries: [
|
|||
|
|
{ date: '2021-03-01', organization: 'ООО "УК Дружба"', position: 'Дворник' }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
certificates: [
|
|||
|
|
{ type: 'Справка о доходах', requestedDate: '2024-05-15', status: 'requested' }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'e4',
|
|||
|
|
name: 'Кузнецов Владимир Викторович',
|
|||
|
|
position: 'Мастер участка',
|
|||
|
|
phone: '+7 900 111-22-33',
|
|||
|
|
status: 'active',
|
|||
|
|
salary: 65000,
|
|||
|
|
assignedDistrictId: 'd-1',
|
|||
|
|
birthDate: '1980-02-14',
|
|||
|
|
messengerLogins: [
|
|||
|
|
{ messenger: 'Telegram', login: '@kuznetsov_vv' },
|
|||
|
|
{ messenger: 'Max', login: '+7 900 111-22-33' }
|
|||
|
|
],
|
|||
|
|
photoUrl: 'https://picsum.photos/id/66/200/200',
|
|||
|
|
registrationDate: '2018-09-01',
|
|||
|
|
hrData: {
|
|||
|
|
passportData: {
|
|||
|
|
series: '4509',
|
|||
|
|
number: '456789',
|
|||
|
|
issuedBy: 'ОУФМС России по г. Москве',
|
|||
|
|
issuedDate: '2009-03-25',
|
|||
|
|
registrationAddress: 'г. Москва, ул. Центральная, д. 15, кв. 45'
|
|||
|
|
},
|
|||
|
|
laborBook: {
|
|||
|
|
number: 'ТК-456789',
|
|||
|
|
entries: [
|
|||
|
|
{ date: '2018-09-01', organization: 'ООО "УК Дружба"', position: 'Мастер участка' },
|
|||
|
|
{ date: '2015-01-10', organization: 'ООО "СтройСервис"', position: 'Мастер' }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
certificates: [
|
|||
|
|
{ type: '2-НДФЛ', requestedDate: '2024-01-10', issuedDate: '2024-01-12', status: 'ready' }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'e5',
|
|||
|
|
name: 'Степанов Сергей Сергеевич',
|
|||
|
|
position: 'Сантехник',
|
|||
|
|
phone: '+7 900 444-55-66',
|
|||
|
|
status: 'active',
|
|||
|
|
salary: 42000,
|
|||
|
|
assignedDistrictId: 'd-2',
|
|||
|
|
birthDate: '1990-09-05',
|
|||
|
|
messengerLogins: [
|
|||
|
|
{ messenger: 'Telegram', login: '@stepanov_ss' }
|
|||
|
|
],
|
|||
|
|
registrationDate: '2022-06-15',
|
|||
|
|
hrData: {
|
|||
|
|
passportData: {
|
|||
|
|
series: '4511',
|
|||
|
|
number: '567890',
|
|||
|
|
issuedBy: 'ОУФМС России по г. Москве',
|
|||
|
|
issuedDate: '2011-11-18',
|
|||
|
|
registrationAddress: 'г. Москва, ул. Новая, д. 8, кв. 15'
|
|||
|
|
},
|
|||
|
|
laborBook: {
|
|||
|
|
number: 'ТК-567890',
|
|||
|
|
entries: [
|
|||
|
|
{ date: '2022-06-15', organization: 'ООО "УК Дружба"', position: 'Сантехник' }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_CANDIDATES: Candidate[] = [
|
|||
|
|
{ id: 'c1', name: 'Новиков Д.Д.', position: 'Мастер участка', stage: 'interview', phone: '+7 999 000-00-01' },
|
|||
|
|
{ id: 'c2', name: 'Козлов Е.Е.', position: 'Сварщик', stage: 'new', phone: '+7 999 000-00-02' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_VACANCIES: Vacancy[] = [
|
|||
|
|
{ id: 'v1', position: 'Слесарь-сантехник (4-5 разряд)', department: 'Тех. отдел', status: 'urgent', salary: '55 000 - 65 000 ₽', applicantsCount: 3, postedDate: '2024-05-10', description: 'Техническое обслуживание внутридомовых инженерных систем ГВС, ХВС, отопления и канализации.' },
|
|||
|
|
{ id: 'v2', position: 'Мастер участка', department: 'Эксплуатация', status: 'active', salary: '70 000 ₽', applicantsCount: 12, postedDate: '2024-05-15', description: 'Организация и контроль работы линейного персонала на вверенном участке (8-10 МКД).' },
|
|||
|
|
{ id: 'v3', position: 'Юрист по работе с дебиторской задолженностью', department: 'Юр. отдел', status: 'active', salary: '60 000 ₽', applicantsCount: 8, postedDate: '2024-05-20', description: 'Подготовка приказов, исковых заявлений, представление интересов УК в судах и ФССП.' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_PR_EVENTS: PREvent[] = [
|
|||
|
|
{ id: 'ev1', title: 'День Соседа (Гриль-вечеринка)', date: '2024-06-15', type: 'resident', category: 'holiday', status: 'planned', location: 'ул. Ленина, д.12 (двор)', attendeesCount: 0, budget: 15000 },
|
|||
|
|
{ id: 'ev2', title: 'Эко-субботник "Чистый Участок"', date: '2024-06-08', type: 'resident', category: 'eco', status: 'planned', location: 'пр. Мира, д.8', attendeesCount: 0, budget: 5000 },
|
|||
|
|
{ id: 'ev3', title: 'Квартальный Тимбилдинг (Квиз)', date: '2024-06-20', type: 'internal', category: 'training', status: 'planned', location: 'Офис УК', attendeesCount: 24, budget: 12000 },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_RESIDENT_REPORTS: ResidentReport[] = [
|
|||
|
|
{ id: 'rep1', buildingId: 'b-1', address: 'Тестовый пер., д.55', month: 'Май 2024', status: 'published', stats: { appsDone: 42, budgetSpent: 125000, cleaningQuality: 4.8 } },
|
|||
|
|
{ id: 'rep2', buildingId: 'b-2', address: 'ул. Ленина, д.12', month: 'Май 2024', status: 'draft', stats: { appsDone: 15, budgetSpent: 45000, cleaningQuality: 3.2 } },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_STRATEGIC_GOALS: StrategicGoal[] = [
|
|||
|
|
{ id: 'g1', department: 'production', title: 'Качество и Скорость', description: 'Снизить долю просроченных заявок', currentValue: 8, targetValue: 5, unit: '%', deadline: '30.09.2024' },
|
|||
|
|
{ id: 'g2', department: 'pr', title: 'Лояльность Жителей', description: 'Повысить общий NPS по компании', currentValue: 68, targetValue: 75, unit: '', deadline: '31.12.2024' },
|
|||
|
|
{ id: 'g3', department: 'finance', title: 'Финансовая Эффективность', description: 'Достичь чистой прибыли (мес)', currentValue: 1200000, targetValue: 1500000, unit: '₽', deadline: '31.07.2024' },
|
|||
|
|
{ id: 'g4', department: 'development', title: 'Рост Портфеля', description: 'Подключить новые дома в управление', currentValue: 3, targetValue: 5, unit: 'домов', deadline: '31.12.2024' },
|
|||
|
|
{ id: 'g5', department: 'legal', title: 'Юридическая Сила', description: 'Повысить процент выигранных дел', currentValue: 85, targetValue: 90, unit: '%', deadline: '30.09.2024' },
|
|||
|
|
{ id: 'g6', department: 'hr', title: 'Стабильность Команды', description: 'Снизить текучесть кадров (год)', currentValue: 12, targetValue: 10, unit: '%', deadline: '31.12.2024' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
|
|||
|
|
export const MOCK_FEEDBACK: ResidentFeedback[] = [
|
|||
|
|
{ id: 'f1', buildingId: 'b-1', address: 'Тестовый пер., д.55', date: '2024-05-28', text: 'Очень довольна работой дворника, всегда чисто во дворе. Спасибо!', source: 'Опрос', rating: 10 },
|
|||
|
|
{ id: 'f2', buildingId: 'b-2', address: 'ул. Ленина, д.12', date: '2024-05-27', text: 'Лифт постоянно ломается, уже неделю хожу пешком на 8 этаж. Это просто издевательство.', source: 'Приложение', rating: 1 },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_APPLICATIONS: DomaApplication[] = [
|
|||
|
|
{ id: 12345, number: 'A-12345', status: 'new', description: 'Течь трубы в ванной комнате, сильный напор.', address: 'Тестовый пер., д.55', apartment: '15', clientName: 'Сергеева А.Н.', createdAt: '2024-05-30T10:00:00Z', deadlineAt: '2024-05-30T18:00:00Z' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_OFFICE_REQUESTS: OfficeRequest[] = [
|
|||
|
|
{ id: 'or1', requesterName: 'Иванова М. (HR)', category: 'stationery', itemName: 'Бумага А4 (5 коробок)', date: '2024-06-01', status: 'new', amount: 3500, priority: 'medium' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_OFFICE_INVENTORY: OfficeInventoryItem[] = [
|
|||
|
|
{ id: 'oi1', name: 'Бумага А4 (SvetoCopy)', quantity: 2, unit: 'кор.', minThreshold: 3, lastRestock: '2024-05-10' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_OFFICE_DOCUMENTS: OfficeDocument[] = [
|
|||
|
|
// FIX: Added type property to mock data to match interface and resolve errors in components
|
|||
|
|
{ id: 'doc1', regNumber: 'ВХ-1234', title: 'Требование об уплате налога', correspondent: 'ИФНС №5', date: '2024-06-01', status: 'registered', type: 'incoming', assignedTo: 'Гл. Бухгалтер' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_OFFICE_ASSETS: OfficeAsset[] = [
|
|||
|
|
{ id: 'as1', name: 'MacBook Air M1', type: 'laptop', assignedTo: 'Алексей Петров', purchaseDate: '2023-01-15', condition: 'good', serialNumber: 'C02XXXXX' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
// LEGAL MOCK DATA
|
|||
|
|
export const MOCK_LEGAL_CONTRACTS: LegalContract[] = [
|
|||
|
|
{ id: 'lc1', number: '2024/05-12', type: 'Поставка', counterparty: 'ООО "СтройМаш"', amount: 1500000, status: 'active', startDate: '2024-01-01', endDate: '2024-12-31', autoProlongation: true, manager: 'Петров А.А.', hasDisagreements: false },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_LEGAL_CASES: LegalCourtCase[] = [
|
|||
|
|
{ id: 'case1', caseNumber: 'А40-12345/2024', type: 'arbitration', role: 'plaintiff', subject: 'Взыскание задолженности с ООО "Ромашка"', amount: 450000, status: 'litigation', nextHearingDate: '2024-06-25', judge: 'Иванова М.С.' },
|
|||
|
|
{ id: 'case2', caseNumber: '2-1234/2024', type: 'debt_recovery', role: 'plaintiff', subject: 'Взыскание за ЖКУ', debtorName: 'Козлов Е.Е.', address: 'ул. Ленина, 12, кв. 45', amount: 85000, status: 'litigation', nextHearingDate: '2024-06-12', judge: 'Петров В.В.' },
|
|||
|
|
{ id: 'case3', caseNumber: '2-5566/2023', type: 'debt_recovery', role: 'plaintiff', subject: 'Взыскание за ЖКУ', debtorName: 'Сидорова А.М.', address: 'пр. Мира, 8, кв. 101', amount: 120000, recoveredAmount: 45000, amountAtBailiffs: 15000, status: 'enforcement', fsspStatus: 'Арест счетов', fsspLastActionDate: '2024-05-10', bailiffName: 'Успенский С.В.', judge: 'Михайлова Е.Н.' },
|
|||
|
|
{ id: 'case4', caseNumber: 'пр-778', type: 'debt_recovery', role: 'plaintiff', subject: 'Претензия по задолженности', debtorName: 'Иванов С.С.', address: 'Заречная, 44, кв. 12', amount: 35000, status: 'pre_trial' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
export const MOCK_LEGAL_COUNTERPARTIES: LegalCounterparty[] = [
|
|||
|
|
{ id: 'cp1', name: 'ООО "СтройМаш"', inn: '7701234567', status: 'active', riskLevel: 'low', checkedDate: '2024-05-20' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
// MOCK данные модуля развития удалены - теперь используются данные из БД через API
|
|||
|
|
// Данные загружаются через backendApi.getDevelopmentPipeline(), getDevelopmentOSS(), и т.д.
|
|||
|
|
|
|||
|
|
// Helper to create elements
|
|||
|
|
const createElement = (id: string, name: string) => ({
|
|||
|
|
id,
|
|||
|
|
name,
|
|||
|
|
generalStatus: 'NOT_SELECTED' as const,
|
|||
|
|
electroStatus: 'NOT_SELECTED' as const,
|
|||
|
|
weldingStatus: 'NOT_SELECTED' as const,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const createEntranceSections = (prefix: string): EntranceSection[] => [
|
|||
|
|
{
|
|||
|
|
id: `${prefix}-floors`,
|
|||
|
|
title: 'Этажи',
|
|||
|
|
elements: [
|
|||
|
|
createElement(`${prefix}-fl-1`, 'Напольное покрытие'),
|
|||
|
|
createElement(`${prefix}-fl-2`, 'Освещение'),
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
const createCommonSections = (prefix: string): EntranceSection[] => [
|
|||
|
|
{
|
|||
|
|
id: `${prefix}-roof`,
|
|||
|
|
title: 'Кровля',
|
|||
|
|
elements: [
|
|||
|
|
createElement(`${prefix}-roof-1`, 'Покрытие'),
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
const createEntrance = (num: number, bId: string) => ({
|
|||
|
|
id: `${bId}-ent-${num}`,
|
|||
|
|
number: num,
|
|||
|
|
floors: 10,
|
|||
|
|
liftsCount: 1,
|
|||
|
|
hasBasement: 'NOT_SELECTED' as const,
|
|||
|
|
hasTechFloor: 'NOT_SELECTED' as const,
|
|||
|
|
hasAttic: 'NOT_SELECTED' as const,
|
|||
|
|
hasParking: 'NOT_SELECTED' as const,
|
|||
|
|
hasMansard: 'NOT_SELECTED' as const,
|
|||
|
|
entranceGroupsCount: 1,
|
|||
|
|
sections: createEntranceSections(`${bId}-ent-${num}`)
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Helper: Generate Readings History
|
|||
|
|
const generateReadingsHistory = (baseValue: number): MeterReading[] => {
|
|||
|
|
const readings: MeterReading[] = [];
|
|||
|
|
let currentValue = baseValue;
|
|||
|
|
const today = new Date();
|
|||
|
|
for (let i = 0; i < 12; i++) {
|
|||
|
|
const date = new Date(today.getFullYear(), today.getMonth() - i, 20);
|
|||
|
|
const consumption = Math.floor(Math.random() * 20) + 5;
|
|||
|
|
readings.push({
|
|||
|
|
date: date.toISOString().split('T')[0],
|
|||
|
|
value: currentValue,
|
|||
|
|
consumption: consumption,
|
|||
|
|
source: 'app'
|
|||
|
|
});
|
|||
|
|
currentValue -= consumption;
|
|||
|
|
}
|
|||
|
|
return readings;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Helper to create mock personal accounts
|
|||
|
|
const createMockAccounts = (buildingId: string, aptCount: number): PersonalAccount[] => {
|
|||
|
|
const accounts: PersonalAccount[] = [];
|
|||
|
|
const types: Array<'apartment' | 'parking' | 'storage' | 'office'> = ['apartment', 'parking', 'storage', 'office'];
|
|||
|
|
const sentiments: Array<'negative' | 'toxic' | 'positive' | 'loyal' | 'neutral'> = ['negative', 'toxic', 'positive', 'loyal', 'neutral'];
|
|||
|
|
|
|||
|
|
for (let i = 1; i <= aptCount; i++) {
|
|||
|
|
const areaTotal = Math.floor(40 + Math.random() * 60);
|
|||
|
|
const accountType = i <= aptCount * 0.8 ? 'apartment' : types[Math.floor(Math.random() * types.length)];
|
|||
|
|
const hasProfile = Math.random() > 0.3; // 70% имеют профиль
|
|||
|
|
|
|||
|
|
accounts.push({
|
|||
|
|
id: `${buildingId}-acc-${i}`,
|
|||
|
|
accountNumber: `${buildingId.replace('b-', '')}00${i}`,
|
|||
|
|
apartmentNumber: i.toString(),
|
|||
|
|
type: accountType,
|
|||
|
|
floor: Math.ceil(i/4),
|
|||
|
|
owners: [{
|
|||
|
|
fullName: 'Иванов И.И.',
|
|||
|
|
phone: '+7 900 000-00-00',
|
|||
|
|
residentProfile: i % 3 === 0 ? {
|
|||
|
|
sentiment: sentiments[Math.floor(Math.random() * sentiments.length)],
|
|||
|
|
birthday: `198${Math.floor(Math.random() * 10)}-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
|
|||
|
|
email: `owner${i}@example.com`,
|
|||
|
|
preferredContactMethod: 'phone' as any,
|
|||
|
|
} : undefined
|
|||
|
|
}],
|
|||
|
|
registered: i % 2 === 0 ? [
|
|||
|
|
{ id: `reg-${i}-1`, fullName: 'Петрова А.А.', phone: '+7 900 111-11-11', email: `registered${i}@example.com` },
|
|||
|
|
{ id: `reg-${i}-2`, fullName: 'Петров П.П.', phone: '+7 900 111-11-12' },
|
|||
|
|
] : [],
|
|||
|
|
areaTotal: areaTotal,
|
|||
|
|
areaLiving: accountType === 'apartment' ? Math.floor(areaTotal * 0.7) : 0,
|
|||
|
|
areaNonLiving: accountType === 'apartment' ? Math.floor(areaTotal * 0.3) : areaTotal,
|
|||
|
|
meters: accountType === 'apartment' ? [
|
|||
|
|
{ id: `m-${i}-1`, type: 'ХВС', make: 'Бетар', number: `BC-${i}321`, lastVerification: '2022-05-10', nextVerification: '2026-05-10', readings: generateReadingsHistory(150) },
|
|||
|
|
] : [],
|
|||
|
|
isMeterInstallationFeasible: accountType === 'apartment',
|
|||
|
|
premiseNotes: i % 7 === 0 ? 'Требуется косметический ремонт' : undefined
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
return accounts;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const createBuilding = (id: string, districtId: string, address: string, img: string, npsScore: number): Building => ({
|
|||
|
|
id,
|
|||
|
|
districtId,
|
|||
|
|
imageUrl: img,
|
|||
|
|
nps: npsScore,
|
|||
|
|
passport: {
|
|||
|
|
address,
|
|||
|
|
apartmentsCount: 160,
|
|||
|
|
general: {
|
|||
|
|
address: address,
|
|||
|
|
fiasCode: '8c5b2444-70a0-4932-980c-0e78548135f3',
|
|||
|
|
constructionYear: 1988,
|
|||
|
|
commissionYear: 1989,
|
|||
|
|
seriesType: '1-447С-37',
|
|||
|
|
floors: 10,
|
|||
|
|
undergroundFloors: 1,
|
|||
|
|
totalArea: 5400,
|
|||
|
|
livingArea: 4800,
|
|||
|
|
nonLivingArea: 200,
|
|||
|
|
commonArea: 400,
|
|||
|
|
cadastralNumberBuild: '77:01:0001001:1000',
|
|||
|
|
cadastralNumberLand: '77:01:0001001:25',
|
|||
|
|
},
|
|||
|
|
construction: {
|
|||
|
|
foundationType: 'Ленточный',
|
|||
|
|
foundationMaterial: 'Железобетон',
|
|||
|
|
wallMaterial: 'Кирпич силикатный',
|
|||
|
|
floorMaterial: 'Железобетонные плиты',
|
|||
|
|
roofType: 'Плоская',
|
|||
|
|
roofMaterial: 'Мягкая рулонная кровля',
|
|||
|
|
roofArea: 850,
|
|||
|
|
facadeType: 'Оштукатуренный',
|
|||
|
|
facadeInsulation: false,
|
|||
|
|
windowType: 'ПВХ (частично)',
|
|||
|
|
},
|
|||
|
|
engineering: {
|
|||
|
|
heatingType: 'Центральное',
|
|||
|
|
heatingWiring: 'Верхняя',
|
|||
|
|
hasITP: true,
|
|||
|
|
waterSupplyMaterial: 'Сталь оцинкованная',
|
|||
|
|
waterSupplyType: 'Циркуляционная',
|
|||
|
|
sewerMaterial: 'Чугун',
|
|||
|
|
electricityEntries: 2,
|
|||
|
|
hasVRU: true,
|
|||
|
|
gasType: 'Нет',
|
|||
|
|
ventilationType: 'Естественная',
|
|||
|
|
},
|
|||
|
|
meters: [
|
|||
|
|
{ resource: 'Heat', hasMeter: true, model: 'ВКТ-7', number: '123456', lastVerification: '2023-09-01', nextVerification: '2027-09-01' },
|
|||
|
|
{ resource: 'Water', hasMeter: true, model: 'Взлет ТСР-М', number: '987654', lastVerification: '2022-05-15', nextVerification: '2026-05-15' },
|
|||
|
|
{ resource: 'Electricity', hasMeter: true, model: 'Меркурий 230', number: '555444', lastVerification: '2020-11-20', nextVerification: '2030-11-20' },
|
|||
|
|
{ resource: 'Gas', hasMeter: false },
|
|||
|
|
],
|
|||
|
|
lifts: [
|
|||
|
|
{ count: 1, type: 'Пассажирский', capacity: 400, speed: 1.0, installYear: 2015, factoryNumber: 'KMZ-1001' },
|
|||
|
|
],
|
|||
|
|
land: {
|
|||
|
|
area: 1200,
|
|||
|
|
hasPlayground: true,
|
|||
|
|
hasSportsGround: false,
|
|||
|
|
hasParking: true,
|
|||
|
|
hasFencing: true,
|
|||
|
|
hasContainerSite: true,
|
|||
|
|
},
|
|||
|
|
management: {
|
|||
|
|
contractDate: '2020-01-01',
|
|||
|
|
contractNumber: 'У-55/2020',
|
|||
|
|
servicesList: ['Содержание жилья', 'Текущий ремонт', 'Управление', 'Вывоз ТБО'],
|
|||
|
|
tariffMaintenance: 35.50,
|
|||
|
|
serviceContracts: [
|
|||
|
|
{ id: 'sc1', serviceType: 'Водоснабжение (РСО)', providerName: 'АО Водоканал', contractNumber: 'В-100/22', contractDate: '2022-01-15' },
|
|||
|
|
{ id: 'sc2', serviceType: 'Тех. обслуживание лифтов', providerName: 'ООО ЛифтСервис', contractNumber: 'Л-55/23', contractDate: '2023-03-10', expiryDate: '2025-03-10' },
|
|||
|
|
{ id: 'sc3', serviceType: 'Видеонаблюдение', providerName: 'Безопасный Город', contractNumber: 'ВН-12', contractDate: '2024-01-01' },
|
|||
|
|
{ id: 'sc4', serviceType: 'Интернет (МОП)', providerName: 'Ростелеком', contractNumber: 'РТ-9988', contractDate: '2021-06-05' },
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
staff: [{ id: 's1', role: 'Главный инженер', company: 'ООО «Дружба»', name: 'Иванов И.И.' }],
|
|||
|
|
entrances: [1, 2].map(n => createEntrance(n, id)),
|
|||
|
|
commonSections: createCommonSections(id),
|
|||
|
|
accounts: createMockAccounts(id, 10),
|
|||
|
|
financials: {
|
|||
|
|
balance: 450000,
|
|||
|
|
debt: 85000,
|
|||
|
|
collectionRate: 94,
|
|||
|
|
topDebtors: [
|
|||
|
|
{ apartment: '15', amount: 45000, months: 6, status: 'new' },
|
|||
|
|
],
|
|||
|
|
invoices: [
|
|||
|
|
{ id: 'inv1', buildingId: id, address: address, contractorName: 'ООО "ЛифтСервис"', serviceName: 'ТО Лифтов', amount: 25000, date: '2024-05-20', status: 'approved', priority: 'high', closingDocsReceived: false },
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
requests: { new: 2, inProgress: 4, overdue: 0 },
|
|||
|
|
inspectionHistory: [
|
|||
|
|
{ id: 'act-1', number: '124-ОС', date: '2024-05-15', inspector: 'Иванов И.И.', type: 'scheduled_spring', status: 'completed', issuesCount: 2 },
|
|||
|
|
],
|
|||
|
|
tasks: [
|
|||
|
|
{
|
|||
|
|
id: 't1',
|
|||
|
|
title: 'Замена лампочек',
|
|||
|
|
deadline: new Date('2024-05-20').toISOString(),
|
|||
|
|
status: 'new',
|
|||
|
|
priority: 'medium',
|
|||
|
|
createdAt: new Date().toISOString(),
|
|||
|
|
updatedAt: new Date().toISOString(),
|
|||
|
|
buildingId: ''
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
annualPlan: [
|
|||
|
|
{ id: 'p1', year: 2024, month: 'Май', workName: 'Промывка системы отопления', status: 'current', progress: 45, estimatedCost: 45000 },
|
|||
|
|
],
|
|||
|
|
inventory: [
|
|||
|
|
{ id: 'inv-1', name: 'Перфоратор Bosch', category: 'tool', quantity: 1, unit: 'шт.', lastCheck: '2024-05-01' },
|
|||
|
|
],
|
|||
|
|
writeOffHistory: [],
|
|||
|
|
residents: [
|
|||
|
|
{ id: 'r1', name: 'Марья Ивановна', role: 'chairman', apartment: '45', mood: 'angry', lastContact: 'Вчера' },
|
|||
|
|
],
|
|||
|
|
reports: [
|
|||
|
|
{ id: 'rep1', month: 'Ноябрь 2023', status: 'ready' },
|
|||
|
|
],
|
|||
|
|
isDirty: false
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
export const MOCK_BUILDINGS: Building[] = [];
|
|||
|
|
|
|||
|
|
export const NAV_ITEMS = [
|
|||
|
|
{ id: 'dashboard', label: 'Сводка', icon: LayoutDashboard },
|
|||
|
|
{ id: 'objects', label: 'Участки', icon: Map },
|
|||
|
|
{ id: 'requests', label: 'Заявки', icon: Wrench },
|
|||
|
|
{ id: 'office', label: 'Офис', icon: Building2 },
|
|||
|
|
{ id: 'pr', label: 'PR и NPS', icon: Megaphone },
|
|||
|
|
{ id: 'finance', label: 'Финансы', icon: Banknote },
|
|||
|
|
{ id: 'legal', label: 'Юр. отдел', icon: Scale },
|
|||
|
|
{ id: 'development', label: 'Развитие', icon: Briefcase },
|
|||
|
|
{ id: 'hr', label: 'Кадры', icon: UsersRound },
|
|||
|
|
{ id: 'admin', label: 'Панель управления', icon: Settings },
|
|||
|
|
];
|