feat: Add start date and completion date fields to project model and forms

This commit is contained in:
2026-01-22 20:22:27 +01:00
parent 3d2065d8fb
commit d49bea8f15
6 changed files with 69 additions and 10 deletions

View File

@@ -17,7 +17,9 @@ function exportProjectsToExcel() {
'Adres': project.address || '', 'Adres': project.address || '',
'Działka': project.plot || '', 'Działka': project.plot || '',
'WP': project.wp || '', 'WP': project.wp || '',
'Data zakończenia': project.finish_date || '' 'Data wpływu': project.start_date || '',
'Termin zakończenia': project.finish_date || '',
'Data odbioru': project.completion_date || ''
}); });
return acc; return acc;
}, {}); }, {});

View File

@@ -15,7 +15,9 @@ const sampleProjects = [
unit: 'Unit A', unit: 'Unit A',
city: 'Warszawa', city: 'Warszawa',
investment_number: 'INV-2025-001', investment_number: 'INV-2025-001',
start_date: '2025-01-15',
finish_date: '2025-06-30', finish_date: '2025-06-30',
completion_date: null,
wp: 'WP-001', wp: 'WP-001',
contact: 'Jan Kowalski, tel. 123-456-789', contact: 'Jan Kowalski, tel. 123-456-789',
notes: 'Modern residential building with 50 apartments', notes: 'Modern residential building with 50 apartments',
@@ -32,7 +34,9 @@ const sampleProjects = [
unit: 'Unit B', unit: 'Unit B',
city: 'Warszawa', city: 'Warszawa',
investment_number: 'INV-2025-002', investment_number: 'INV-2025-002',
start_date: '2025-02-01',
finish_date: '2025-09-15', finish_date: '2025-09-15',
completion_date: null,
wp: 'WP-002', wp: 'WP-002',
contact: 'Anna Nowak, tel. 987-654-321', contact: 'Anna Nowak, tel. 987-654-321',
notes: 'Commercial office space, 10 floors', notes: 'Commercial office space, 10 floors',
@@ -49,7 +53,9 @@ const sampleProjects = [
unit: 'Unit C', unit: 'Unit C',
city: 'Kraków', city: 'Kraków',
investment_number: 'INV-2025-003', investment_number: 'INV-2025-003',
start_date: '2025-01-10',
finish_date: '2025-12-20', finish_date: '2025-12-20',
completion_date: null,
wp: 'WP-003', wp: 'WP-003',
contact: 'Piotr Wiśniewski, tel. 555-123-456', contact: 'Piotr Wiśniewski, tel. 555-123-456',
notes: 'Large shopping center with parking', notes: 'Large shopping center with parking',
@@ -66,7 +72,9 @@ const sampleProjects = [
unit: 'Unit D', unit: 'Unit D',
city: 'Łódź', city: 'Łódź',
investment_number: 'INV-2025-004', investment_number: 'INV-2025-004',
start_date: '2024-11-01',
finish_date: '2025-08-10', finish_date: '2025-08-10',
completion_date: '2025-08-05',
wp: 'WP-004', wp: 'WP-004',
contact: 'Maria Lewandowska, tel. 444-789-012', contact: 'Maria Lewandowska, tel. 444-789-012',
notes: 'Logistics warehouse facility', notes: 'Logistics warehouse facility',
@@ -83,7 +91,9 @@ const sampleProjects = [
unit: 'Unit E', unit: 'Unit E',
city: 'Gdańsk', city: 'Gdańsk',
investment_number: 'INV-2025-005', investment_number: 'INV-2025-005',
start_date: '2025-01-20',
finish_date: '2025-11-05', finish_date: '2025-11-05',
completion_date: null,
wp: 'WP-005', wp: 'WP-005',
contact: 'Tomasz Malinowski, tel. 333-456-789', contact: 'Tomasz Malinowski, tel. 333-456-789',
notes: 'Luxury hotel with conference facilities', notes: 'Luxury hotel with conference facilities',
@@ -100,7 +110,9 @@ const sampleProjects = [
unit: 'Unit F', unit: 'Unit F',
city: 'Poznań', city: 'Poznań',
investment_number: 'INV-2025-006', investment_number: 'INV-2025-006',
start_date: '2025-02-10',
finish_date: '2025-07-20', finish_date: '2025-07-20',
completion_date: null,
wp: 'WP-006', wp: 'WP-006',
contact: 'Ewa Dombrowska, tel. 222-333-444', contact: 'Ewa Dombrowska, tel. 222-333-444',
notes: 'Modern educational facility with sports complex', notes: 'Modern educational facility with sports complex',
@@ -117,7 +129,9 @@ const sampleProjects = [
unit: 'Unit G', unit: 'Unit G',
city: 'Wrocław', city: 'Wrocław',
investment_number: 'INV-2025-007', investment_number: 'INV-2025-007',
start_date: '2024-12-15',
finish_date: '2025-10-30', finish_date: '2025-10-30',
completion_date: null,
wp: 'WP-007', wp: 'WP-007',
contact: 'Dr. Marek Szymankowski, tel. 111-222-333', contact: 'Dr. Marek Szymankowski, tel. 111-222-333',
notes: 'Specialized medical center with emergency department', notes: 'Specialized medical center with emergency department',
@@ -134,7 +148,9 @@ const sampleProjects = [
unit: 'Unit H', unit: 'Unit H',
city: 'Szczecin', city: 'Szczecin',
investment_number: 'INV-2025-008', investment_number: 'INV-2025-008',
start_date: '2024-09-01',
finish_date: '2025-05-15', finish_date: '2025-05-15',
completion_date: '2025-05-12',
wp: 'WP-008', wp: 'WP-008',
contact: 'Katarzyna Wojcik, tel. 999-888-777', contact: 'Katarzyna Wojcik, tel. 999-888-777',
notes: 'Multi-purpose sports stadium with seating for 20,000', notes: 'Multi-purpose sports stadium with seating for 20,000',
@@ -151,7 +167,9 @@ const sampleProjects = [
unit: 'Unit I', unit: 'Unit I',
city: 'Lublin', city: 'Lublin',
investment_number: 'INV-2025-009', investment_number: 'INV-2025-009',
start_date: '2025-01-05',
finish_date: '2025-08-25', finish_date: '2025-08-25',
completion_date: null,
wp: 'WP-009', wp: 'WP-009',
contact: 'Prof. Andrzej Kowalewski, tel. 777-666-555', contact: 'Prof. Andrzej Kowalewski, tel. 777-666-555',
notes: 'Modern library with digital archives and community spaces', notes: 'Modern library with digital archives and community spaces',
@@ -174,9 +192,9 @@ sampleProjects.forEach((projectData, index) => {
const result = db.prepare(` const result = db.prepare(`
INSERT INTO projects ( INSERT INTO projects (
contract_id, project_name, project_number, address, plot, district, unit, city, contract_id, project_name, project_number, address, plot, district, unit, city,
investment_number, finish_date, wp, contact, notes, coordinates, investment_number, start_date, finish_date, completion_date, wp, contact, notes, coordinates,
project_type, project_status, created_at, updated_at project_type, project_status, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
`).run( `).run(
projectData.contract_id, projectData.contract_id,
projectData.project_name, projectData.project_name,
@@ -187,7 +205,9 @@ sampleProjects.forEach((projectData, index) => {
projectData.unit, projectData.unit,
projectData.city, projectData.city,
projectData.investment_number, projectData.investment_number,
projectData.start_date,
projectData.finish_date, projectData.finish_date,
projectData.completion_date,
projectData.wp, projectData.wp,
projectData.contact, projectData.contact,
projectData.notes, projectData.notes,

View File

@@ -463,7 +463,17 @@ export default function ProjectViewPage() {
<p className="text-gray-900 font-medium"> <p className="text-gray-900 font-medium">
{project.unit || "N/A"} {project.unit || "N/A"}
</p> </p>
</div>{" "} </div>
{project.start_date && (
<div>
<span className="text-sm font-medium text-gray-500 block mb-1">
Data wpływu
</span>
<p className="text-gray-900 font-medium">
{formatDate(project.start_date)}
</p>
</div>
)}
<FieldWithHistory <FieldWithHistory
tableName="projects" tableName="projects"
recordId={project.project_id} recordId={project.project_id}
@@ -474,7 +484,7 @@ export default function ProjectViewPage() {
{project.completion_date && ( {project.completion_date && (
<div> <div>
<span className="text-sm font-medium text-gray-500 block mb-1"> <span className="text-sm font-medium text-gray-500 block mb-1">
Data zakończenia projektu Data odbioru
</span> </span>
<p className="text-gray-900 font-medium"> <p className="text-gray-900 font-medium">
{formatDate(project.completion_date)} {formatDate(project.completion_date)}

View File

@@ -22,6 +22,7 @@ const ProjectForm = forwardRef(function ProjectForm({ initialData = null }, ref)
unit: "", unit: "",
city: "", city: "",
investment_number: "", investment_number: "",
start_date: "",
finish_date: "", finish_date: "",
completion_date: "", completion_date: "",
wp: "", wp: "",
@@ -63,6 +64,7 @@ const ProjectForm = forwardRef(function ProjectForm({ initialData = null }, ref)
unit: "", unit: "",
city: "", city: "",
investment_number: "", investment_number: "",
start_date: "",
finish_date: "", finish_date: "",
completion_date: "", completion_date: "",
wp: "", wp: "",
@@ -78,6 +80,9 @@ const ProjectForm = forwardRef(function ProjectForm({ initialData = null }, ref)
assigned_to: initialData.assigned_to || "", assigned_to: initialData.assigned_to || "",
wartosc_zlecenia: initialData.wartosc_zlecenia || "", wartosc_zlecenia: initialData.wartosc_zlecenia || "",
// Format dates for input if they exist // Format dates for input if they exist
start_date: initialData.start_date
? formatDateForInput(initialData.start_date)
: "",
finish_date: initialData.finish_date finish_date: initialData.finish_date
? formatDateForInput(initialData.finish_date) ? formatDateForInput(initialData.finish_date)
: "", : "",
@@ -292,7 +297,19 @@ const ProjectForm = forwardRef(function ProjectForm({ initialData = null }, ref)
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-2"> <label className="block text-sm font-medium text-gray-700 mb-2">
{t('projects.finishDate')} Data wpływu
</label>
<Input
type="date"
name="start_date"
value={formatDateForInput(form.start_date)}
onChange={handleChange}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Termin zakończenia
</label> </label>
<Input <Input
type="date" type="date"
@@ -304,7 +321,7 @@ const ProjectForm = forwardRef(function ProjectForm({ initialData = null }, ref)
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-2"> <label className="block text-sm font-medium text-gray-700 mb-2">
Data zakończenia projektu Data odbioru
</label> </label>
<Input <Input
type="date" type="date"

View File

@@ -289,6 +289,14 @@ export default function initializeDatabase() {
// Column already exists, ignore error // Column already exists, ignore error
} }
try {
db.exec(`
ALTER TABLE projects ADD COLUMN start_date TEXT;
`);
} catch (e) {
// Column already exists, ignore error
}
// Migration: Update task status system - add 'not_started' status // Migration: Update task status system - add 'not_started' status
// DISABLED: This migration was running on every init and converting legitimate // DISABLED: This migration was running on every init and converting legitimate
// 'pending' tasks back to 'not_started'. The initial migration has been completed. // 'pending' tasks back to 'not_started'. The initial migration has been completed.

View File

@@ -75,9 +75,9 @@ export function createProject(data, userId = null) {
const stmt = db.prepare(` const stmt = db.prepare(`
INSERT INTO projects ( INSERT INTO projects (
contract_id, project_name, project_number, address, plot, district, unit, city, investment_number, finish_date, completion_date, contract_id, project_name, project_number, address, plot, district, unit, city, investment_number, start_date, finish_date, completion_date,
wp, contact, notes, wartosc_zlecenia, project_type, project_status, coordinates, created_by, assigned_to, created_at, updated_at wp, contact, notes, wartosc_zlecenia, project_type, project_status, coordinates, created_by, assigned_to, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now', 'localtime'), datetime('now', 'localtime')) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now', 'localtime'), datetime('now', 'localtime'))
`); `);
const result = stmt.run( const result = stmt.run(
@@ -90,6 +90,7 @@ export function createProject(data, userId = null) {
data.unit, data.unit,
data.city, data.city,
data.investment_number, data.investment_number,
data.start_date || null,
data.finish_date, data.finish_date,
data.completion_date, data.completion_date,
data.wp, data.wp,
@@ -110,7 +111,7 @@ export function updateProject(id, data, userId = null) {
const stmt = db.prepare(` const stmt = db.prepare(`
UPDATE projects SET UPDATE projects SET
contract_id = ?, project_name = ?, project_number = ?, address = ?, plot = ?, district = ?, unit = ?, city = ?, contract_id = ?, project_name = ?, project_number = ?, address = ?, plot = ?, district = ?, unit = ?, city = ?,
investment_number = ?, finish_date = ?, completion_date = ?, wp = ?, contact = ?, notes = ?, wartosc_zlecenia = ?, project_type = ?, project_status = ?, investment_number = ?, start_date = ?, finish_date = ?, completion_date = ?, wp = ?, contact = ?, notes = ?, wartosc_zlecenia = ?, project_type = ?, project_status = ?,
coordinates = ?, assigned_to = ?, updated_at = CURRENT_TIMESTAMP coordinates = ?, assigned_to = ?, updated_at = CURRENT_TIMESTAMP
WHERE project_id = ? WHERE project_id = ?
`); `);
@@ -124,6 +125,7 @@ export function updateProject(id, data, userId = null) {
data.unit, data.unit,
data.city, data.city,
data.investment_number, data.investment_number,
data.start_date || null,
data.finish_date, data.finish_date,
data.completion_date, data.completion_date,
data.wp, data.wp,