Initial commit MKD fixes
This commit is contained in:
272
services/storageService.ts
Executable file
272
services/storageService.ts
Executable file
@@ -0,0 +1,272 @@
|
||||
|
||||
import { Building, District } from "../types";
|
||||
import { MOCK_BUILDINGS, MOCK_DISTRICTS } from "../constants";
|
||||
|
||||
const DB_KEY_BUILDINGS = 'mkd_buildings_v2';
|
||||
const DB_KEY_DISTRICTS = 'mkd_districts_v2';
|
||||
const DB_KEY_GLOBAL_PASSPORT_FIELDS = 'mkd_global_passport_fields';
|
||||
|
||||
export const storageService = {
|
||||
// --- DISTRICTS ---
|
||||
getDistricts: (): District[] => {
|
||||
try {
|
||||
const stored = localStorage.getItem(DB_KEY_DISTRICTS);
|
||||
if (stored) {
|
||||
const parsed = JSON.parse(stored);
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
}
|
||||
return [];
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
saveDistrict: (district: District): void => {
|
||||
const all = storageService.getDistricts();
|
||||
const index = all.findIndex(d => d.id === district.id);
|
||||
let newAll;
|
||||
if (index >= 0) {
|
||||
newAll = [...all];
|
||||
newAll[index] = district;
|
||||
} else {
|
||||
newAll = [...all, district];
|
||||
}
|
||||
localStorage.setItem(DB_KEY_DISTRICTS, JSON.stringify(newAll));
|
||||
},
|
||||
|
||||
createDistrict: (data: Omit<District, 'id'>): District => {
|
||||
const newDistrict: District = {
|
||||
...data,
|
||||
id: `d-${Date.now()}`
|
||||
};
|
||||
storageService.saveDistrict(newDistrict);
|
||||
return newDistrict;
|
||||
},
|
||||
|
||||
deleteDistrict: (id: string): void => {
|
||||
const all = storageService.getDistricts();
|
||||
const newAll = all.filter(d => d.id !== id);
|
||||
localStorage.setItem(DB_KEY_DISTRICTS, JSON.stringify(newAll));
|
||||
},
|
||||
|
||||
// --- BUILDINGS ---
|
||||
getAllBuildings: (): Building[] => {
|
||||
try {
|
||||
const stored = localStorage.getItem(DB_KEY_BUILDINGS);
|
||||
if (stored) {
|
||||
const parsed = JSON.parse(stored);
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
}
|
||||
return [];
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
getBuildingsByDistrict: (districtId: string): Building[] => {
|
||||
const all = storageService.getAllBuildings();
|
||||
return all.filter(b => b.districtId === districtId);
|
||||
},
|
||||
|
||||
getBuildingById: (id: string): Building | undefined => {
|
||||
const all = storageService.getAllBuildings();
|
||||
return all.find(b => b.id === id);
|
||||
},
|
||||
|
||||
saveBuildingData: (updatedBuilding: Building): void => {
|
||||
try {
|
||||
const all = storageService.getAllBuildings();
|
||||
const index = all.findIndex(b => b.id === updatedBuilding.id);
|
||||
const toSave = {
|
||||
...updatedBuilding,
|
||||
isDirty: true,
|
||||
lastSync: Date.now()
|
||||
};
|
||||
let newAll;
|
||||
if (index >= 0) {
|
||||
newAll = [...all];
|
||||
newAll[index] = toSave;
|
||||
} else {
|
||||
newAll = [...all, toSave];
|
||||
}
|
||||
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(newAll));
|
||||
} catch (e) {
|
||||
console.error("Failed to save to storage", e);
|
||||
}
|
||||
},
|
||||
|
||||
createBuilding: (data: Partial<Building> & { address: string, districtId: string }): Building => {
|
||||
const id = `b-${Date.now()}`;
|
||||
const newBuilding: Building = {
|
||||
id,
|
||||
districtId: data.districtId,
|
||||
imageUrl: data.imageUrl || 'https://picsum.photos/800/600',
|
||||
nps: 0,
|
||||
passport: {
|
||||
address: data.address,
|
||||
apartmentsCount: 0,
|
||||
general: {
|
||||
address: data.address,
|
||||
fiasCode: '',
|
||||
constructionYear: new Date().getFullYear(),
|
||||
commissionYear: new Date().getFullYear(),
|
||||
seriesType: 'Индивидуальный',
|
||||
floors: 1,
|
||||
undergroundFloors: 0,
|
||||
totalArea: 0,
|
||||
livingArea: 0,
|
||||
nonLivingArea: 0,
|
||||
commonArea: 0,
|
||||
cadastralNumberBuild: '',
|
||||
cadastralNumberLand: ''
|
||||
},
|
||||
construction: { foundationType: '', foundationMaterial: '', wallMaterial: '', floorMaterial: '', roofType: '', roofMaterial: '', roofArea: 0, facadeType: '', facadeInsulation: false, windowType: '' },
|
||||
engineering: { heatingType: '', heatingWiring: '', hasITP: false, waterSupplyMaterial: '', waterSupplyType: '', sewerMaterial: '', electricityEntries: 1, hasVRU: false, gasType: '', ventilationType: '' },
|
||||
odpu: { customFields: {} },
|
||||
meters: [],
|
||||
lifts: [],
|
||||
land: { area: 0, hasPlayground: false, hasSportsGround: false, hasParking: false, hasFencing: false, hasContainerSite: false },
|
||||
management: {
|
||||
contractDate: '',
|
||||
contractNumber: '',
|
||||
servicesList: [],
|
||||
tariffMaintenance: 0,
|
||||
reserveFund: 5.00, // Значение по умолчанию 5%
|
||||
serviceContracts: [] // Initialize empty array
|
||||
},
|
||||
...data.passport
|
||||
},
|
||||
staff: [],
|
||||
entrances: [],
|
||||
commonSections: [],
|
||||
accounts: [],
|
||||
financials: { balance: 0, debt: 0, collectionRate: 0, topDebtors: [], invoices: [] },
|
||||
requests: { new: 0, inProgress: 0, overdue: 0 },
|
||||
inspectionHistory: [],
|
||||
tasks: [],
|
||||
annualPlan: [],
|
||||
inventory: [],
|
||||
writeOffHistory: [],
|
||||
residents: [],
|
||||
reports: [],
|
||||
isDirty: true,
|
||||
...data
|
||||
};
|
||||
storageService.saveBuildingData(newBuilding);
|
||||
return newBuilding;
|
||||
},
|
||||
|
||||
deleteBuilding: (id: string): void => {
|
||||
const all = storageService.getAllBuildings();
|
||||
const newAll = all.filter(b => b.id !== id);
|
||||
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(newAll));
|
||||
},
|
||||
|
||||
syncWithServer: async (): Promise<boolean> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
const all = storageService.getAllBuildings();
|
||||
const cleaned = all.map(b => ({ ...b, isDirty: false }));
|
||||
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(cleaned));
|
||||
resolve(true);
|
||||
}, 1500);
|
||||
});
|
||||
},
|
||||
clearLocal: () => {
|
||||
localStorage.removeItem(DB_KEY_BUILDINGS);
|
||||
localStorage.removeItem(DB_KEY_DISTRICTS);
|
||||
},
|
||||
|
||||
// --- GLOBAL PASSPORT FIELDS (для всех домов) ---
|
||||
getGlobalPassportFields: (): { [section: string]: { [fieldName: string]: { value: any; type: string; files?: string[] } } } => {
|
||||
try {
|
||||
const stored = localStorage.getItem(DB_KEY_GLOBAL_PASSPORT_FIELDS);
|
||||
if (stored) return JSON.parse(stored);
|
||||
return {};
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
|
||||
saveGlobalPassportField: (section: 'general' | 'construction' | 'engineering' | 'odpu' | 'land' | 'management', fieldName: string, fieldType: 'text' | 'number' | 'checkbox'): void => {
|
||||
const globalFields = storageService.getGlobalPassportFields();
|
||||
if (!globalFields[section]) {
|
||||
globalFields[section] = {};
|
||||
}
|
||||
const defaultValue = fieldType === 'number' ? 0 : fieldType === 'checkbox' ? false : '';
|
||||
globalFields[section][fieldName] = {
|
||||
value: defaultValue,
|
||||
type: fieldType,
|
||||
files: []
|
||||
};
|
||||
localStorage.setItem(DB_KEY_GLOBAL_PASSPORT_FIELDS, JSON.stringify(globalFields));
|
||||
|
||||
// Применяем это поле ко всем домам
|
||||
const allBuildings = storageService.getAllBuildings();
|
||||
allBuildings.forEach(building => {
|
||||
const sectionData = building.passport[section] as any;
|
||||
const customFields = { ...(sectionData.customFields || {}) };
|
||||
if (!customFields[fieldName]) {
|
||||
customFields[fieldName] = {
|
||||
value: defaultValue,
|
||||
type: fieldType,
|
||||
files: []
|
||||
};
|
||||
const updatedSection = { ...sectionData, customFields };
|
||||
building.passport[section] = updatedSection as any;
|
||||
}
|
||||
});
|
||||
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(allBuildings));
|
||||
},
|
||||
|
||||
updateGlobalPassportField: (section: 'general' | 'construction' | 'engineering' | 'odpu' | 'land' | 'management', fieldName: string, value: any, files?: string[]): void => {
|
||||
const globalFields = storageService.getGlobalPassportFields();
|
||||
if (globalFields[section] && globalFields[section][fieldName]) {
|
||||
globalFields[section][fieldName].value = value;
|
||||
if (files !== undefined) {
|
||||
globalFields[section][fieldName].files = files;
|
||||
}
|
||||
localStorage.setItem(DB_KEY_GLOBAL_PASSPORT_FIELDS, JSON.stringify(globalFields));
|
||||
|
||||
// Обновляем это поле во всех домах
|
||||
const allBuildings = storageService.getAllBuildings();
|
||||
allBuildings.forEach(building => {
|
||||
const sectionData = building.passport[section] as any;
|
||||
const customFields = { ...(sectionData.customFields || {}) };
|
||||
if (customFields[fieldName]) {
|
||||
customFields[fieldName].value = value;
|
||||
if (files !== undefined) {
|
||||
customFields[fieldName].files = files;
|
||||
}
|
||||
const updatedSection = { ...sectionData, customFields };
|
||||
building.passport[section] = updatedSection as any;
|
||||
}
|
||||
});
|
||||
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(allBuildings));
|
||||
}
|
||||
},
|
||||
|
||||
deleteGlobalPassportField: (section: 'general' | 'construction' | 'engineering' | 'odpu' | 'land' | 'management', fieldName: string): void => {
|
||||
const globalFields = storageService.getGlobalPassportFields();
|
||||
if (globalFields[section] && globalFields[section][fieldName]) {
|
||||
delete globalFields[section][fieldName];
|
||||
if (Object.keys(globalFields[section]).length === 0) {
|
||||
delete globalFields[section];
|
||||
}
|
||||
localStorage.setItem(DB_KEY_GLOBAL_PASSPORT_FIELDS, JSON.stringify(globalFields));
|
||||
|
||||
// Удаляем это поле из всех домов
|
||||
const allBuildings = storageService.getAllBuildings();
|
||||
allBuildings.forEach(building => {
|
||||
const sectionData = building.passport[section] as any;
|
||||
const customFields = { ...(sectionData.customFields || {}) };
|
||||
if (customFields[fieldName]) {
|
||||
delete customFields[fieldName];
|
||||
const updatedSection = { ...sectionData, customFields };
|
||||
building.passport[section] = updatedSection as any;
|
||||
}
|
||||
});
|
||||
localStorage.setItem(DB_KEY_BUILDINGS, JSON.stringify(allBuildings));
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user