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 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 00:21:31 +02:00
parent c648c9311c
commit 695d8c6545
4 changed files with 650 additions and 287 deletions

65
api.php
View File

@@ -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);