From 695d8c65450de01ad657989d511d00d19df3652d Mon Sep 17 00:00:00 2001 From: Jukka Lampikoski Date: Tue, 10 Mar 2026 00:21:31 +0200 Subject: [PATCH] Add multiple connections per customer, contract period, and layout redesign - Refactor data model: each customer now has a liittymat array (auto-migration from old format) - Add sopimuskausi (1/12/24/36 kk) and alkupvm fields per connection - Form supports adding/removing multiple connection rows per company - Add "use same as installation address" checkbox for billing address - Move stat cards to compact sidebar on the right - Place search bar above customer table Co-Authored-By: Claude Opus 4.6 --- api.php | 65 ++++++++-- index.html | 198 ++++++++++++++-------------- script.js | 369 +++++++++++++++++++++++++++++++++++++++-------------- style.css | 305 +++++++++++++++++++++++++++++++------------ 4 files changed, 650 insertions(+), 287 deletions(-) diff --git a/api.php b/api.php index ff8c60d..c81c91b 100644 --- a/api.php +++ b/api.php @@ -27,7 +27,29 @@ function requireAuth() { function loadCustomers(): array { $data = file_get_contents(DATA_FILE); - return json_decode($data, true) ?: []; + $customers = json_decode($data, true) ?: []; + // Migroi vanha data: jos asiakkaalla ei ole liittymat-arrayta, luo se + $migrated = false; + foreach ($customers as &$c) { + if (!isset($c['liittymat'])) { + $c['liittymat'] = [[ + 'asennusosoite' => $c['asennusosoite'] ?? '', + 'postinumero' => $c['postinumero'] ?? '', + 'kaupunki' => $c['kaupunki'] ?? '', + 'liittymanopeus' => $c['liittymanopeus'] ?? '', + 'hinta' => floatval($c['hinta'] ?? 0), + 'sopimuskausi' => '', + 'alkupvm' => '', + ]]; + unset($c['asennusosoite'], $c['postinumero'], $c['kaupunki'], $c['liittymanopeus'], $c['hinta']); + $migrated = true; + } + } + unset($c); + if ($migrated) { + file_put_contents(DATA_FILE, json_encode($customers, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); + } + return $customers; } function saveCustomers(array $customers): void { @@ -86,14 +108,24 @@ switch ($action) { if ($method === 'POST') { $input = json_decode(file_get_contents('php://input'), true); $customers = loadCustomers(); + $liittymat = []; + foreach (($input['liittymat'] ?? []) as $l) { + $liittymat[] = [ + 'asennusosoite' => trim($l['asennusosoite'] ?? ''), + 'postinumero' => trim($l['postinumero'] ?? ''), + 'kaupunki' => trim($l['kaupunki'] ?? ''), + 'liittymanopeus' => trim($l['liittymanopeus'] ?? ''), + 'hinta' => floatval($l['hinta'] ?? 0), + 'sopimuskausi' => trim($l['sopimuskausi'] ?? ''), + 'alkupvm' => trim($l['alkupvm'] ?? ''), + ]; + } + if (empty($liittymat)) { + $liittymat[] = ['asennusosoite' => '', 'postinumero' => '', 'kaupunki' => '', 'liittymanopeus' => '', 'hinta' => 0, 'sopimuskausi' => '', 'alkupvm' => '']; + } $customer = [ 'id' => generateId(), 'yritys' => trim($input['yritys'] ?? ''), - 'asennusosoite' => trim($input['asennusosoite'] ?? ''), - 'postinumero' => trim($input['postinumero'] ?? ''), - 'kaupunki' => trim($input['kaupunki'] ?? ''), - 'liittymanopeus' => trim($input['liittymanopeus'] ?? ''), - 'hinta' => floatval($input['hinta'] ?? 0), 'yhteyshenkilö' => trim($input['yhteyshenkilö'] ?? ''), 'puhelin' => trim($input['puhelin'] ?? ''), 'sahkoposti' => trim($input['sahkoposti'] ?? ''), @@ -105,6 +137,7 @@ switch ($action) { 'elaskuvalittaja' => trim($input['elaskuvalittaja'] ?? ''), 'ytunnus' => trim($input['ytunnus'] ?? ''), 'lisatiedot' => trim($input['lisatiedot'] ?? ''), + 'liittymat' => $liittymat, 'luotu' => date('Y-m-d H:i:s'), ]; if (empty($customer['yritys'])) { @@ -128,11 +161,6 @@ switch ($action) { foreach ($customers as &$c) { if ($c['id'] === $id) { $c['yritys'] = trim($input['yritys'] ?? $c['yritys']); - $c['asennusosoite'] = trim($input['asennusosoite'] ?? $c['asennusosoite']); - $c['postinumero'] = trim($input['postinumero'] ?? ($c['postinumero'] ?? '')); - $c['kaupunki'] = trim($input['kaupunki'] ?? ($c['kaupunki'] ?? '')); - $c['liittymanopeus'] = trim($input['liittymanopeus'] ?? $c['liittymanopeus']); - $c['hinta'] = floatval($input['hinta'] ?? $c['hinta']); $c['yhteyshenkilö'] = trim($input['yhteyshenkilö'] ?? $c['yhteyshenkilö']); $c['puhelin'] = trim($input['puhelin'] ?? $c['puhelin']); $c['sahkoposti'] = trim($input['sahkoposti'] ?? $c['sahkoposti']); @@ -144,6 +172,21 @@ switch ($action) { $c['elaskuvalittaja'] = trim($input['elaskuvalittaja'] ?? ($c['elaskuvalittaja'] ?? '')); $c['ytunnus'] = trim($input['ytunnus'] ?? $c['ytunnus']); $c['lisatiedot'] = trim($input['lisatiedot'] ?? $c['lisatiedot']); + if (isset($input['liittymat'])) { + $liittymat = []; + foreach ($input['liittymat'] as $l) { + $liittymat[] = [ + 'asennusosoite' => trim($l['asennusosoite'] ?? ''), + 'postinumero' => trim($l['postinumero'] ?? ''), + 'kaupunki' => trim($l['kaupunki'] ?? ''), + 'liittymanopeus' => trim($l['liittymanopeus'] ?? ''), + 'hinta' => floatval($l['hinta'] ?? 0), + 'sopimuskausi' => trim($l['sopimuskausi'] ?? ''), + 'alkupvm' => trim($l['alkupvm'] ?? ''), + ]; + } + $c['liittymat'] = $liittymat; + } $c['muokattu'] = date('Y-m-d H:i:s'); $found = true; echo json_encode($c); diff --git a/index.html b/index.html index 135bf88..0e3f1bd 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@