feat: edit mode + steal price entry

This commit is contained in:
2026-05-20 11:17:50 +02:00
parent 9a43ea96e4
commit a3fb217949
7 changed files with 2182 additions and 82 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.pi*

View File

@@ -0,0 +1,531 @@
{
"surcharges": {
"304": {
"month": "Apr. 2026",
"value": 2663
},
"316": {
"month": "Apr. 2026",
"value": 4591
},
"444": {
"month": "Apr. 2026",
"value": 2817
}
},
"history": [
{
"m": "Jan 2021",
"y": 2021,
"ss": 620,
"lz304": 1910,
"lz316": 2722,
"lz444": 1253
},
{
"m": "Feb 2021",
"y": 2021,
"ss": 817,
"lz304": 2064,
"lz316": 2905,
"lz444": 1366
},
{
"m": "Mrz 2021",
"y": 2021,
"ss": 848,
"lz304": 2222,
"lz316": 3146,
"lz444": 1480
},
{
"m": "Apr 2021",
"y": 2021,
"ss": 998,
"lz304": 2224,
"lz316": 3181,
"lz444": 1609
},
{
"m": "Mai 2021",
"y": 2021,
"ss": 1164,
"lz304": 2146,
"lz316": 3054,
"lz444": 1589
},
{
"m": "Jun 2021",
"y": 2021,
"ss": 1274,
"lz304": 2226,
"lz316": 3193,
"lz444": 1636
},
{
"m": "Jul 2021",
"y": 2021,
"ss": 1282,
"lz304": 2281,
"lz316": 3482,
"lz444": 1868
},
{
"m": "Aug 2021",
"y": 2021,
"ss": 1286,
"lz304": 2429,
"lz316": 3829,
"lz444": 2078
},
{
"m": "Sep 2021",
"y": 2021,
"ss": 1278,
"lz304": 2599,
"lz316": 4020,
"lz444": 2153
},
{
"m": "Okt 2021",
"y": 2021,
"ss": 1218,
"lz304": 2628,
"lz316": 4109,
"lz444": 2212
},
{
"m": "Nov 2021",
"y": 2021,
"ss": 1133,
"lz304": 2624,
"lz316": 4060,
"lz444": 2195
},
{
"m": "Dez 2021",
"y": 2021,
"ss": 1083,
"lz304": 2770,
"lz316": 4256,
"lz444": 2279
},
{
"m": "Jan 2022",
"y": 2022,
"ss": 1054,
"lz304": 2905,
"lz316": 4403,
"lz444": 2347
},
{
"m": "Feb 2022",
"y": 2022,
"ss": 1057,
"lz304": 2971,
"lz316": 4510,
"lz444": 2335
},
{
"m": "Mrz 2022",
"y": 2022,
"ss": 1266,
"lz304": 3192,
"lz316": 4794,
"lz444": 2347
},
{
"m": "Apr 2022",
"y": 2022,
"ss": 1446,
"lz304": 3899,
"lz316": 5734,
"lz444": 2516
},
{
"m": "Mai 2022",
"y": 2022,
"ss": 1247,
"lz304": 4614,
"lz316": 6671,
"lz444": 2761
},
{
"m": "Jun 2022",
"y": 2022,
"ss": 1022,
"lz304": 3852,
"lz316": 5674,
"lz444": 2810
},
{
"m": "Jul 2022",
"y": 2022,
"ss": 933,
"lz304": 3770,
"lz316": 5534,
"lz444": 2618
},
{
"m": "Aug 2022",
"y": 2022,
"ss": 895,
"lz304": 3277,
"lz316": 4916,
"lz444": 2495
},
{
"m": "Sep 2022",
"y": 2022,
"ss": 866,
"lz304": 3101,
"lz316": 4612,
"lz444": 2333
},
{
"m": "Okt 2022",
"y": 2022,
"ss": 843,
"lz304": 3174,
"lz316": 4801,
"lz444": 2465
},
{
"m": "Nov 2022",
"y": 2022,
"ss": 766,
"lz304": 3211,
"lz316": 5020,
"lz444": 2570
},
{
"m": "Dez 2022",
"y": 2022,
"ss": 731,
"lz304": 3224,
"lz316": 5076,
"lz444": 2478
},
{
"m": "Jan 2023",
"y": 2023,
"ss": 799,
"lz304": 3502,
"lz316": 5608,
"lz444": 2580
},
{
"m": "Feb 2023",
"y": 2023,
"ss": 861,
"lz304": 3587,
"lz316": 6100,
"lz444": 2939
},
{
"m": "Mrz 2023",
"y": 2023,
"ss": 916,
"lz304": 3484,
"lz316": 6566,
"lz444": 3499
},
{
"m": "Apr 2023",
"y": 2023,
"ss": 953,
"lz304": 3174,
"lz316": 6048,
"lz444": 3485
},
{
"m": "Mai 2023",
"y": 2023,
"ss": 902,
"lz304": 3031,
"lz316": 5048,
"lz444": 2778
},
{
"m": "Jun 2023",
"y": 2023,
"ss": 800,
"lz304": 3007,
"lz316": 4862,
"lz444": 2628
},
{
"m": "Jul 2023",
"y": 2023,
"ss": 772,
"lz304": 2858,
"lz316": 4657,
"lz444": 2640
},
{
"m": "Aug 2023",
"y": 2023,
"ss": 756,
"lz304": 2651,
"lz316": 4392,
"lz444": 2519
},
{
"m": "Sep 2023",
"y": 2023,
"ss": 747,
"lz304": 2629,
"lz316": 4465,
"lz444": 2543
},
{
"m": "Okt 2023",
"y": 2023,
"ss": 720,
"lz304": 2640,
"lz316": 4507,
"lz444": 2629
},
{
"m": "Nov 2023",
"y": 2023,
"ss": 729,
"lz304": 2573,
"lz316": 4334,
"lz444": 2599
},
{
"m": "Dez 2023",
"y": 2023,
"ss": 769,
"lz304": 2466,
"lz316": 4048,
"lz444": 2452
},
{
"m": "Jan 2024",
"y": 2024,
"ss": 803,
"lz304": 2384,
"lz316": 3793,
"lz444": 2339
},
{
"m": "Feb 2024",
"y": 2024,
"ss": 834,
"lz304": 2341,
"lz316": 3890,
"lz444": 2459
},
{
"m": "Mrz 2024",
"y": 2024,
"ss": 801,
"lz304": 2424,
"lz316": 3962,
"lz444": 2458
},
{
"m": "Apr 2024",
"y": 2024,
"ss": 747,
"lz304": 2543,
"lz316": 4159,
"lz444": 2461
},
{
"m": "Mai 2024",
"y": 2024,
"ss": 739,
"lz304": 2594,
"lz316": 4200,
"lz444": 2495
},
{
"m": "Jun 2024",
"y": 2024,
"ss": 738,
"lz304": 2776,
"lz316": 4505,
"lz444": 2574
},
{
"m": "Jul 2024",
"y": 2024,
"ss": 736,
"lz304": 2752,
"lz316": 4578,
"lz444": 2654
},
{
"m": "Aug 2024",
"y": 2024,
"ss": 724,
"lz304": 2547,
"lz316": 4297,
"lz444": 2651
},
{
"m": "Sep 2024",
"y": 2024,
"ss": 695,
"lz304": 2418,
"lz316": 4044,
"lz444": 2555
},
{
"m": "Okt 2024",
"y": 2024,
"ss": 647,
"lz304": 2385,
"lz316": 3989,
"lz444": 2506
},
{
"m": "Nov 2024",
"y": 2024,
"ss": 662,
"lz304": 2514,
"lz316": 4156,
"lz444": 2534
},
{
"m": "Dez 2024",
"y": 2024,
"ss": 666,
"lz304": 2477,
"lz316": 4135,
"lz444": 2623
},
{
"m": "Jan 2025",
"y": 2025,
"ss": 668,
"lz304": 2538,
"lz316": 4205,
"lz444": 2659
},
{
"m": "Feb 2025",
"y": 2025,
"ss": 690,
"lz304": 2542,
"lz316": 4226,
"lz444": 2686
},
{
"m": "Mrz 2025",
"y": 2025,
"ss": 720,
"lz304": 2522,
"lz316": 4181,
"lz444": 2652
},
{
"m": "Apr 2025",
"y": 2025,
"ss": 734,
"lz304": 2510,
"lz316": 4144,
"lz444": 2602
},
{
"m": "Mai 2025",
"y": 2025,
"ss": 730,
"lz304": 2382,
"lz316": 3916,
"lz444": 2502
},
{
"m": "Jun 2025",
"y": 2025,
"ss": 705,
"lz304": 2280,
"lz316": 3748,
"lz444": 2386
},
{
"m": "Jul 2025",
"y": 2025,
"ss": 657,
"lz304": 2243,
"lz316": 3751,
"lz444": 2437
},
{
"m": "Aug 2025",
"y": 2025,
"ss": 660,
"lz304": 2201,
"lz316": 3708,
"lz444": 2433
},
{
"m": "Sep 2025",
"y": 2025,
"ss": 668,
"lz304": 2260,
"lz316": 3841,
"lz444": 2510
},
{
"m": "Okt 2025",
"y": 2025,
"ss": 670,
"lz304": 2261,
"lz316": 3927,
"lz444": 2572
},
{
"m": "Nov 2025",
"y": 2025,
"ss": 703,
"lz304": 2297,
"lz316": 3936,
"lz444": 2550
},
{
"m": "Dez 2025",
"y": 2025,
"ss": 715,
"lz304": 2322,
"lz316": 3943,
"lz444": 2552
},
{
"m": "Jan 2026",
"y": 2026,
"ss": 727,
"lz304": 2303,
"lz316": 3815,
"lz444": 2478
},
{
"m": "Feb 2026",
"y": 2026,
"ss": 755,
"lz304": 2541,
"lz316": 4179,
"lz444": 2522
},
{
"m": "Mrz 2026",
"y": 2026,
"ss": 792,
"lz304": 2571,
"lz316": 4367,
"lz444": 2637
},
{
"m": "Apr 2026",
"y": 2026,
"ss": 813,
"lz304": 2663,
"lz316": 4591,
"lz444": 2817
}
],
"baseSS": 727
}

View File

@@ -0,0 +1,531 @@
{
"surcharges": {
"304": {
"month": "Apr. 2026",
"value": 2663
},
"316": {
"month": "Apr. 2026",
"value": 4591
},
"444": {
"month": "Apr. 2026",
"value": 2817
}
},
"history": [
{
"m": "Jan 2021",
"y": 2021,
"ss": 620,
"lz304": 1910,
"lz316": 2722,
"lz444": 1253
},
{
"m": "Feb 2021",
"y": 2021,
"ss": 817,
"lz304": 2064,
"lz316": 2905,
"lz444": 1366
},
{
"m": "Mrz 2021",
"y": 2021,
"ss": 848,
"lz304": 2222,
"lz316": 3146,
"lz444": 1480
},
{
"m": "Apr 2021",
"y": 2021,
"ss": 998,
"lz304": 2224,
"lz316": 3181,
"lz444": 1609
},
{
"m": "Mai 2021",
"y": 2021,
"ss": 1164,
"lz304": 2146,
"lz316": 3054,
"lz444": 1589
},
{
"m": "Jun 2021",
"y": 2021,
"ss": 1274,
"lz304": 2226,
"lz316": 3193,
"lz444": 1636
},
{
"m": "Jul 2021",
"y": 2021,
"ss": 1282,
"lz304": 2281,
"lz316": 3482,
"lz444": 1868
},
{
"m": "Aug 2021",
"y": 2021,
"ss": 1286,
"lz304": 2429,
"lz316": 3829,
"lz444": 2078
},
{
"m": "Sep 2021",
"y": 2021,
"ss": 1278,
"lz304": 2599,
"lz316": 4020,
"lz444": 2153
},
{
"m": "Okt 2021",
"y": 2021,
"ss": 1218,
"lz304": 2628,
"lz316": 4109,
"lz444": 2212
},
{
"m": "Nov 2021",
"y": 2021,
"ss": 1133,
"lz304": 2624,
"lz316": 4060,
"lz444": 2195
},
{
"m": "Dez 2021",
"y": 2021,
"ss": 1083,
"lz304": 2770,
"lz316": 4256,
"lz444": 2279
},
{
"m": "Jan 2022",
"y": 2022,
"ss": 1054,
"lz304": 2905,
"lz316": 4403,
"lz444": 2347
},
{
"m": "Feb 2022",
"y": 2022,
"ss": 1057,
"lz304": 2971,
"lz316": 4510,
"lz444": 2335
},
{
"m": "Mrz 2022",
"y": 2022,
"ss": 1266,
"lz304": 3192,
"lz316": 4794,
"lz444": 2347
},
{
"m": "Apr 2022",
"y": 2022,
"ss": 1446,
"lz304": 3899,
"lz316": 5734,
"lz444": 2516
},
{
"m": "Mai 2022",
"y": 2022,
"ss": 1247,
"lz304": 4614,
"lz316": 6671,
"lz444": 2761
},
{
"m": "Jun 2022",
"y": 2022,
"ss": 1022,
"lz304": 3852,
"lz316": 5674,
"lz444": 2810
},
{
"m": "Jul 2022",
"y": 2022,
"ss": 933,
"lz304": 3770,
"lz316": 5534,
"lz444": 2618
},
{
"m": "Aug 2022",
"y": 2022,
"ss": 895,
"lz304": 3277,
"lz316": 4916,
"lz444": 2495
},
{
"m": "Sep 2022",
"y": 2022,
"ss": 866,
"lz304": 3101,
"lz316": 4612,
"lz444": 2333
},
{
"m": "Okt 2022",
"y": 2022,
"ss": 843,
"lz304": 3174,
"lz316": 4801,
"lz444": 2465
},
{
"m": "Nov 2022",
"y": 2022,
"ss": 766,
"lz304": 3211,
"lz316": 5020,
"lz444": 2570
},
{
"m": "Dez 2022",
"y": 2022,
"ss": 731,
"lz304": 3224,
"lz316": 5076,
"lz444": 2478
},
{
"m": "Jan 2023",
"y": 2023,
"ss": 799,
"lz304": 3502,
"lz316": 5608,
"lz444": 2580
},
{
"m": "Feb 2023",
"y": 2023,
"ss": 861,
"lz304": 3587,
"lz316": 6100,
"lz444": 2939
},
{
"m": "Mrz 2023",
"y": 2023,
"ss": 916,
"lz304": 3484,
"lz316": 6566,
"lz444": 3499
},
{
"m": "Apr 2023",
"y": 2023,
"ss": 953,
"lz304": 3174,
"lz316": 6048,
"lz444": 3485
},
{
"m": "Mai 2023",
"y": 2023,
"ss": 902,
"lz304": 3031,
"lz316": 5048,
"lz444": 2778
},
{
"m": "Jun 2023",
"y": 2023,
"ss": 800,
"lz304": 3007,
"lz316": 4862,
"lz444": 2628
},
{
"m": "Jul 2023",
"y": 2023,
"ss": 772,
"lz304": 2858,
"lz316": 4657,
"lz444": 2640
},
{
"m": "Aug 2023",
"y": 2023,
"ss": 756,
"lz304": 2651,
"lz316": 4392,
"lz444": 2519
},
{
"m": "Sep 2023",
"y": 2023,
"ss": 747,
"lz304": 2629,
"lz316": 4465,
"lz444": 2543
},
{
"m": "Okt 2023",
"y": 2023,
"ss": 720,
"lz304": 2640,
"lz316": 4507,
"lz444": 2629
},
{
"m": "Nov 2023",
"y": 2023,
"ss": 729,
"lz304": 2573,
"lz316": 4334,
"lz444": 2599
},
{
"m": "Dez 2023",
"y": 2023,
"ss": 769,
"lz304": 2466,
"lz316": 4048,
"lz444": 2452
},
{
"m": "Jan 2024",
"y": 2024,
"ss": 803,
"lz304": 2384,
"lz316": 3793,
"lz444": 2339
},
{
"m": "Feb 2024",
"y": 2024,
"ss": 834,
"lz304": 2341,
"lz316": 3890,
"lz444": 2459
},
{
"m": "Mrz 2024",
"y": 2024,
"ss": 801,
"lz304": 2424,
"lz316": 3962,
"lz444": 2458
},
{
"m": "Apr 2024",
"y": 2024,
"ss": 747,
"lz304": 2543,
"lz316": 4159,
"lz444": 2461
},
{
"m": "Mai 2024",
"y": 2024,
"ss": 739,
"lz304": 2594,
"lz316": 4200,
"lz444": 2495
},
{
"m": "Jun 2024",
"y": 2024,
"ss": 738,
"lz304": 2776,
"lz316": 4505,
"lz444": 2574
},
{
"m": "Jul 2024",
"y": 2024,
"ss": 736,
"lz304": 2752,
"lz316": 4578,
"lz444": 2654
},
{
"m": "Aug 2024",
"y": 2024,
"ss": 724,
"lz304": 2547,
"lz316": 4297,
"lz444": 2651
},
{
"m": "Sep 2024",
"y": 2024,
"ss": 695,
"lz304": 2418,
"lz316": 4044,
"lz444": 2555
},
{
"m": "Okt 2024",
"y": 2024,
"ss": 647,
"lz304": 2385,
"lz316": 3989,
"lz444": 2506
},
{
"m": "Nov 2024",
"y": 2024,
"ss": 662,
"lz304": 2514,
"lz316": 4156,
"lz444": 2534
},
{
"m": "Dez 2024",
"y": 2024,
"ss": 666,
"lz304": 2477,
"lz316": 4135,
"lz444": 2623
},
{
"m": "Jan 2025",
"y": 2025,
"ss": 668,
"lz304": 2538,
"lz316": 4205,
"lz444": 2659
},
{
"m": "Feb 2025",
"y": 2025,
"ss": 690,
"lz304": 2542,
"lz316": 4226,
"lz444": 2686
},
{
"m": "Mrz 2025",
"y": 2025,
"ss": 720,
"lz304": 2522,
"lz316": 4181,
"lz444": 2652
},
{
"m": "Apr 2025",
"y": 2025,
"ss": 734,
"lz304": 2510,
"lz316": 4144,
"lz444": 2602
},
{
"m": "Mai 2025",
"y": 2025,
"ss": 730,
"lz304": 2382,
"lz316": 3916,
"lz444": 2502
},
{
"m": "Jun 2025",
"y": 2025,
"ss": 705,
"lz304": 2280,
"lz316": 3748,
"lz444": 2386
},
{
"m": "Jul 2025",
"y": 2025,
"ss": 657,
"lz304": 2243,
"lz316": 3751,
"lz444": 2437
},
{
"m": "Aug 2025",
"y": 2025,
"ss": 660,
"lz304": 2201,
"lz316": 3708,
"lz444": 2433
},
{
"m": "Sep 2025",
"y": 2025,
"ss": 668,
"lz304": 2260,
"lz316": 3841,
"lz444": 2510
},
{
"m": "Okt 2025",
"y": 2025,
"ss": 670,
"lz304": 2261,
"lz316": 3927,
"lz444": 2572
},
{
"m": "Nov 2025",
"y": 2025,
"ss": 703,
"lz304": 2297,
"lz316": 3936,
"lz444": 2550
},
{
"m": "Dez 2025",
"y": 2025,
"ss": 715,
"lz304": 2322,
"lz316": 3943,
"lz444": 2552
},
{
"m": "Jan 2026",
"y": 2026,
"ss": 350,
"lz304": 1000,
"lz316": 1500,
"lz444": 2478
},
{
"m": "Feb 2026",
"y": 2026,
"ss": 755,
"lz304": 2541,
"lz316": 4179,
"lz444": 2522
},
{
"m": "Mrz 2026",
"y": 2026,
"ss": 792,
"lz304": 2571,
"lz316": 4367,
"lz444": 2637
},
{
"m": "Apr 2026",
"y": 2026,
"ss": 813,
"lz304": 2663,
"lz316": 4591,
"lz444": 2817
}
],
"baseSS": 727
}

View File

@@ -0,0 +1,531 @@
{
"surcharges": {
"304": {
"month": "Apr. 2026",
"value": 2663
},
"316": {
"month": "Apr. 2026",
"value": 4591
},
"444": {
"month": "Apr. 2026",
"value": 2817
}
},
"history": [
{
"m": "Jan 2021",
"y": 2021,
"ss": 620,
"lz304": 1910,
"lz316": 2722,
"lz444": 1253
},
{
"m": "Feb 2021",
"y": 2021,
"ss": 817,
"lz304": 2064,
"lz316": 2905,
"lz444": 1366
},
{
"m": "Mrz 2021",
"y": 2021,
"ss": 848,
"lz304": 2222,
"lz316": 3146,
"lz444": 1480
},
{
"m": "Apr 2021",
"y": 2021,
"ss": 998,
"lz304": 2224,
"lz316": 3181,
"lz444": 1609
},
{
"m": "Mai 2021",
"y": 2021,
"ss": 1164,
"lz304": 2146,
"lz316": 3054,
"lz444": 1589
},
{
"m": "Jun 2021",
"y": 2021,
"ss": 1274,
"lz304": 2226,
"lz316": 3193,
"lz444": 1636
},
{
"m": "Jul 2021",
"y": 2021,
"ss": 1282,
"lz304": 2281,
"lz316": 3482,
"lz444": 1868
},
{
"m": "Aug 2021",
"y": 2021,
"ss": 1286,
"lz304": 2429,
"lz316": 3829,
"lz444": 2078
},
{
"m": "Sep 2021",
"y": 2021,
"ss": 1278,
"lz304": 2599,
"lz316": 4020,
"lz444": 2153
},
{
"m": "Okt 2021",
"y": 2021,
"ss": 1218,
"lz304": 2628,
"lz316": 4109,
"lz444": 2212
},
{
"m": "Nov 2021",
"y": 2021,
"ss": 1133,
"lz304": 2624,
"lz316": 4060,
"lz444": 2195
},
{
"m": "Dez 2021",
"y": 2021,
"ss": 1083,
"lz304": 2770,
"lz316": 4256,
"lz444": 2279
},
{
"m": "Jan 2022",
"y": 2022,
"ss": 1054,
"lz304": 2905,
"lz316": 4403,
"lz444": 2347
},
{
"m": "Feb 2022",
"y": 2022,
"ss": 1057,
"lz304": 2971,
"lz316": 4510,
"lz444": 2335
},
{
"m": "Mrz 2022",
"y": 2022,
"ss": 1266,
"lz304": 3192,
"lz316": 4794,
"lz444": 2347
},
{
"m": "Apr 2022",
"y": 2022,
"ss": 1446,
"lz304": 3899,
"lz316": 5734,
"lz444": 2516
},
{
"m": "Mai 2022",
"y": 2022,
"ss": 1247,
"lz304": 4614,
"lz316": 6671,
"lz444": 2761
},
{
"m": "Jun 2022",
"y": 2022,
"ss": 1022,
"lz304": 3852,
"lz316": 5674,
"lz444": 2810
},
{
"m": "Jul 2022",
"y": 2022,
"ss": 933,
"lz304": 3770,
"lz316": 5534,
"lz444": 2618
},
{
"m": "Aug 2022",
"y": 2022,
"ss": 895,
"lz304": 3277,
"lz316": 4916,
"lz444": 2495
},
{
"m": "Sep 2022",
"y": 2022,
"ss": 866,
"lz304": 3101,
"lz316": 4612,
"lz444": 2333
},
{
"m": "Okt 2022",
"y": 2022,
"ss": 843,
"lz304": 3174,
"lz316": 4801,
"lz444": 2465
},
{
"m": "Nov 2022",
"y": 2022,
"ss": 766,
"lz304": 3211,
"lz316": 5020,
"lz444": 2570
},
{
"m": "Dez 2022",
"y": 2022,
"ss": 731,
"lz304": 3224,
"lz316": 5076,
"lz444": 2478
},
{
"m": "Jan 2023",
"y": 2023,
"ss": 799,
"lz304": 3502,
"lz316": 5608,
"lz444": 2580
},
{
"m": "Feb 2023",
"y": 2023,
"ss": 861,
"lz304": 3587,
"lz316": 6100,
"lz444": 2939
},
{
"m": "Mrz 2023",
"y": 2023,
"ss": 916,
"lz304": 3484,
"lz316": 6566,
"lz444": 3499
},
{
"m": "Apr 2023",
"y": 2023,
"ss": 953,
"lz304": 3174,
"lz316": 6048,
"lz444": 3485
},
{
"m": "Mai 2023",
"y": 2023,
"ss": 902,
"lz304": 3031,
"lz316": 5048,
"lz444": 2778
},
{
"m": "Jun 2023",
"y": 2023,
"ss": 800,
"lz304": 3007,
"lz316": 4862,
"lz444": 2628
},
{
"m": "Jul 2023",
"y": 2023,
"ss": 772,
"lz304": 2858,
"lz316": 4657,
"lz444": 2640
},
{
"m": "Aug 2023",
"y": 2023,
"ss": 756,
"lz304": 2651,
"lz316": 4392,
"lz444": 2519
},
{
"m": "Sep 2023",
"y": 2023,
"ss": 747,
"lz304": 2629,
"lz316": 4465,
"lz444": 2543
},
{
"m": "Okt 2023",
"y": 2023,
"ss": 720,
"lz304": 2640,
"lz316": 4507,
"lz444": 2629
},
{
"m": "Nov 2023",
"y": 2023,
"ss": 729,
"lz304": 2573,
"lz316": 4334,
"lz444": 2599
},
{
"m": "Dez 2023",
"y": 2023,
"ss": 769,
"lz304": 2466,
"lz316": 4048,
"lz444": 2452
},
{
"m": "Jan 2024",
"y": 2024,
"ss": 803,
"lz304": 2384,
"lz316": 3793,
"lz444": 2339
},
{
"m": "Feb 2024",
"y": 2024,
"ss": 834,
"lz304": 2341,
"lz316": 3890,
"lz444": 2459
},
{
"m": "Mrz 2024",
"y": 2024,
"ss": 801,
"lz304": 2424,
"lz316": 3962,
"lz444": 2458
},
{
"m": "Apr 2024",
"y": 2024,
"ss": 747,
"lz304": 2543,
"lz316": 4159,
"lz444": 2461
},
{
"m": "Mai 2024",
"y": 2024,
"ss": 739,
"lz304": 2594,
"lz316": 4200,
"lz444": 2495
},
{
"m": "Jun 2024",
"y": 2024,
"ss": 738,
"lz304": 2776,
"lz316": 4505,
"lz444": 2574
},
{
"m": "Jul 2024",
"y": 2024,
"ss": 736,
"lz304": 2752,
"lz316": 4578,
"lz444": 2654
},
{
"m": "Aug 2024",
"y": 2024,
"ss": 724,
"lz304": 2547,
"lz316": 4297,
"lz444": 2651
},
{
"m": "Sep 2024",
"y": 2024,
"ss": 695,
"lz304": 2418,
"lz316": 4044,
"lz444": 2555
},
{
"m": "Okt 2024",
"y": 2024,
"ss": 647,
"lz304": 2385,
"lz316": 3989,
"lz444": 2506
},
{
"m": "Nov 2024",
"y": 2024,
"ss": 662,
"lz304": 2514,
"lz316": 4156,
"lz444": 2534
},
{
"m": "Dez 2024",
"y": 2024,
"ss": 666,
"lz304": 2477,
"lz316": 4135,
"lz444": 2623
},
{
"m": "Jan 2025",
"y": 2025,
"ss": 668,
"lz304": 2538,
"lz316": 4205,
"lz444": 2659
},
{
"m": "Feb 2025",
"y": 2025,
"ss": 690,
"lz304": 2542,
"lz316": 4226,
"lz444": 2686
},
{
"m": "Mrz 2025",
"y": 2025,
"ss": 720,
"lz304": 2522,
"lz316": 4181,
"lz444": 2652
},
{
"m": "Apr 2025",
"y": 2025,
"ss": 734,
"lz304": 2510,
"lz316": 4144,
"lz444": 2602
},
{
"m": "Mai 2025",
"y": 2025,
"ss": 730,
"lz304": 2382,
"lz316": 3916,
"lz444": 2502
},
{
"m": "Jun 2025",
"y": 2025,
"ss": 705,
"lz304": 2280,
"lz316": 3748,
"lz444": 2386
},
{
"m": "Jul 2025",
"y": 2025,
"ss": 657,
"lz304": 2243,
"lz316": 3751,
"lz444": 2437
},
{
"m": "Aug 2025",
"y": 2025,
"ss": 660,
"lz304": 2201,
"lz316": 3708,
"lz444": 2433
},
{
"m": "Sep 2025",
"y": 2025,
"ss": 668,
"lz304": 2260,
"lz316": 3841,
"lz444": 2510
},
{
"m": "Okt 2025",
"y": 2025,
"ss": 670,
"lz304": 2261,
"lz316": 3927,
"lz444": 2572
},
{
"m": "Nov 2025",
"y": 2025,
"ss": 703,
"lz304": 2297,
"lz316": 3936,
"lz444": 2550
},
{
"m": "Dez 2025",
"y": 2025,
"ss": 715,
"lz304": 2322,
"lz316": 3943,
"lz444": 2552
},
{
"m": "Jan 2026",
"y": 2026,
"ss": 727,
"lz304": 2303,
"lz316": 3815,
"lz444": 200
},
{
"m": "Feb 2026",
"y": 2026,
"ss": 755,
"lz304": 2541,
"lz316": 4179,
"lz444": 2522
},
{
"m": "Mrz 2026",
"y": 2026,
"ss": 792,
"lz304": 2571,
"lz316": 4367,
"lz444": 2637
},
{
"m": "Apr 2026",
"y": 2026,
"ss": 813,
"lz304": 2663,
"lz316": 4591,
"lz444": 2817
}
],
"baseSS": 727
}

126
data.json
View File

@@ -25,7 +25,7 @@
{
"m": "Feb 2021",
"y": 2021,
"ss": 650,
"ss": 817,
"lz304": 2064,
"lz316": 2905,
"lz444": 1366
@@ -33,7 +33,7 @@
{
"m": "Mrz 2021",
"y": 2021,
"ss": 700,
"ss": 848,
"lz304": 2222,
"lz316": 3146,
"lz444": 1480
@@ -41,7 +41,7 @@
{
"m": "Apr 2021",
"y": 2021,
"ss": 760,
"ss": 998,
"lz304": 2224,
"lz316": 3181,
"lz444": 1609
@@ -49,7 +49,7 @@
{
"m": "Mai 2021",
"y": 2021,
"ss": 810,
"ss": 1164,
"lz304": 2146,
"lz316": 3054,
"lz444": 1589
@@ -57,7 +57,7 @@
{
"m": "Jun 2021",
"y": 2021,
"ss": 870,
"ss": 1274,
"lz304": 2226,
"lz316": 3193,
"lz444": 1636
@@ -65,7 +65,7 @@
{
"m": "Jul 2021",
"y": 2021,
"ss": 920,
"ss": 1282,
"lz304": 2281,
"lz316": 3482,
"lz444": 1868
@@ -73,7 +73,7 @@
{
"m": "Aug 2021",
"y": 2021,
"ss": 960,
"ss": 1286,
"lz304": 2429,
"lz316": 3829,
"lz444": 2078
@@ -81,7 +81,7 @@
{
"m": "Sep 2021",
"y": 2021,
"ss": 1000,
"ss": 1278,
"lz304": 2599,
"lz316": 4020,
"lz444": 2153
@@ -89,7 +89,7 @@
{
"m": "Okt 2021",
"y": 2021,
"ss": 1050,
"ss": 1218,
"lz304": 2628,
"lz316": 4109,
"lz444": 2212
@@ -97,7 +97,7 @@
{
"m": "Nov 2021",
"y": 2021,
"ss": 1080,
"ss": 1133,
"lz304": 2624,
"lz316": 4060,
"lz444": 2195
@@ -105,7 +105,7 @@
{
"m": "Dez 2021",
"y": 2021,
"ss": 1100,
"ss": 1083,
"lz304": 2770,
"lz316": 4256,
"lz444": 2279
@@ -113,7 +113,7 @@
{
"m": "Jan 2022",
"y": 2022,
"ss": 1150,
"ss": 1054,
"lz304": 2905,
"lz316": 4403,
"lz444": 2347
@@ -121,7 +121,7 @@
{
"m": "Feb 2022",
"y": 2022,
"ss": 1280,
"ss": 1057,
"lz304": 2971,
"lz316": 4510,
"lz444": 2335
@@ -129,7 +129,7 @@
{
"m": "Mrz 2022",
"y": 2022,
"ss": 1380,
"ss": 1266,
"lz304": 3192,
"lz316": 4794,
"lz444": 2347
@@ -137,7 +137,7 @@
{
"m": "Apr 2022",
"y": 2022,
"ss": 1300,
"ss": 1446,
"lz304": 3899,
"lz316": 5734,
"lz444": 2516
@@ -145,7 +145,7 @@
{
"m": "Mai 2022",
"y": 2022,
"ss": 1150,
"ss": 1247,
"lz304": 4614,
"lz316": 6671,
"lz444": 2761
@@ -153,7 +153,7 @@
{
"m": "Jun 2022",
"y": 2022,
"ss": 1000,
"ss": 1022,
"lz304": 3852,
"lz316": 5674,
"lz444": 2810
@@ -161,7 +161,7 @@
{
"m": "Jul 2022",
"y": 2022,
"ss": 880,
"ss": 933,
"lz304": 3770,
"lz316": 5534,
"lz444": 2618
@@ -169,7 +169,7 @@
{
"m": "Aug 2022",
"y": 2022,
"ss": 820,
"ss": 895,
"lz304": 3277,
"lz316": 4916,
"lz444": 2495
@@ -177,7 +177,7 @@
{
"m": "Sep 2022",
"y": 2022,
"ss": 790,
"ss": 866,
"lz304": 3101,
"lz316": 4612,
"lz444": 2333
@@ -185,7 +185,7 @@
{
"m": "Okt 2022",
"y": 2022,
"ss": 760,
"ss": 843,
"lz304": 3174,
"lz316": 4801,
"lz444": 2465
@@ -193,7 +193,7 @@
{
"m": "Nov 2022",
"y": 2022,
"ss": 740,
"ss": 766,
"lz304": 3211,
"lz316": 5020,
"lz444": 2570
@@ -201,7 +201,7 @@
{
"m": "Dez 2022",
"y": 2022,
"ss": 715,
"ss": 731,
"lz304": 3224,
"lz316": 5076,
"lz444": 2478
@@ -209,7 +209,7 @@
{
"m": "Jan 2023",
"y": 2023,
"ss": 700,
"ss": 799,
"lz304": 3502,
"lz316": 5608,
"lz444": 2580
@@ -217,7 +217,7 @@
{
"m": "Feb 2023",
"y": 2023,
"ss": 730,
"ss": 861,
"lz304": 3587,
"lz316": 6100,
"lz444": 2939
@@ -225,7 +225,7 @@
{
"m": "Mrz 2023",
"y": 2023,
"ss": 770,
"ss": 916,
"lz304": 3484,
"lz316": 6566,
"lz444": 3499
@@ -233,7 +233,7 @@
{
"m": "Apr 2023",
"y": 2023,
"ss": 810,
"ss": 953,
"lz304": 3174,
"lz316": 6048,
"lz444": 3485
@@ -241,7 +241,7 @@
{
"m": "Mai 2023",
"y": 2023,
"ss": 855,
"ss": 902,
"lz304": 3031,
"lz316": 5048,
"lz444": 2778
@@ -249,7 +249,7 @@
{
"m": "Jun 2023",
"y": 2023,
"ss": 845,
"ss": 800,
"lz304": 3007,
"lz316": 4862,
"lz444": 2628
@@ -257,7 +257,7 @@
{
"m": "Jul 2023",
"y": 2023,
"ss": 810,
"ss": 772,
"lz304": 2858,
"lz316": 4657,
"lz444": 2640
@@ -265,7 +265,7 @@
{
"m": "Aug 2023",
"y": 2023,
"ss": 785,
"ss": 756,
"lz304": 2651,
"lz316": 4392,
"lz444": 2519
@@ -273,7 +273,7 @@
{
"m": "Sep 2023",
"y": 2023,
"ss": 755,
"ss": 747,
"lz304": 2629,
"lz316": 4465,
"lz444": 2543
@@ -281,7 +281,7 @@
{
"m": "Okt 2023",
"y": 2023,
"ss": 730,
"ss": 720,
"lz304": 2640,
"lz316": 4507,
"lz444": 2629
@@ -289,7 +289,7 @@
{
"m": "Nov 2023",
"y": 2023,
"ss": 710,
"ss": 729,
"lz304": 2573,
"lz316": 4334,
"lz444": 2599
@@ -297,7 +297,7 @@
{
"m": "Dez 2023",
"y": 2023,
"ss": 700,
"ss": 769,
"lz304": 2466,
"lz316": 4048,
"lz444": 2452
@@ -305,7 +305,7 @@
{
"m": "Jan 2024",
"y": 2024,
"ss": 730,
"ss": 803,
"lz304": 2384,
"lz316": 3793,
"lz444": 2339
@@ -313,7 +313,7 @@
{
"m": "Feb 2024",
"y": 2024,
"ss": 755,
"ss": 834,
"lz304": 2341,
"lz316": 3890,
"lz444": 2459
@@ -321,7 +321,7 @@
{
"m": "Mrz 2024",
"y": 2024,
"ss": 770,
"ss": 801,
"lz304": 2424,
"lz316": 3962,
"lz444": 2458
@@ -329,7 +329,7 @@
{
"m": "Apr 2024",
"y": 2024,
"ss": 750,
"ss": 747,
"lz304": 2543,
"lz316": 4159,
"lz444": 2461
@@ -337,7 +337,7 @@
{
"m": "Mai 2024",
"y": 2024,
"ss": 735,
"ss": 739,
"lz304": 2594,
"lz316": 4200,
"lz444": 2495
@@ -345,7 +345,7 @@
{
"m": "Jun 2024",
"y": 2024,
"ss": 715,
"ss": 738,
"lz304": 2776,
"lz316": 4505,
"lz444": 2574
@@ -353,7 +353,7 @@
{
"m": "Jul 2024",
"y": 2024,
"ss": 705,
"ss": 736,
"lz304": 2752,
"lz316": 4578,
"lz444": 2654
@@ -361,7 +361,7 @@
{
"m": "Aug 2024",
"y": 2024,
"ss": 695,
"ss": 724,
"lz304": 2547,
"lz316": 4297,
"lz444": 2651
@@ -369,7 +369,7 @@
{
"m": "Sep 2024",
"y": 2024,
"ss": 680,
"ss": 695,
"lz304": 2418,
"lz316": 4044,
"lz444": 2555
@@ -377,7 +377,7 @@
{
"m": "Okt 2024",
"y": 2024,
"ss": 670,
"ss": 647,
"lz304": 2385,
"lz316": 3989,
"lz444": 2506
@@ -385,7 +385,7 @@
{
"m": "Nov 2024",
"y": 2024,
"ss": 675,
"ss": 662,
"lz304": 2514,
"lz316": 4156,
"lz444": 2534
@@ -393,7 +393,7 @@
{
"m": "Dez 2024",
"y": 2024,
"ss": 720,
"ss": 666,
"lz304": 2477,
"lz316": 4135,
"lz444": 2623
@@ -401,7 +401,7 @@
{
"m": "Jan 2025",
"y": 2025,
"ss": 730,
"ss": 668,
"lz304": 2538,
"lz316": 4205,
"lz444": 2659
@@ -409,7 +409,7 @@
{
"m": "Feb 2025",
"y": 2025,
"ss": 730,
"ss": 690,
"lz304": 2542,
"lz316": 4226,
"lz444": 2686
@@ -425,7 +425,7 @@
{
"m": "Apr 2025",
"y": 2025,
"ss": 715,
"ss": 734,
"lz304": 2510,
"lz316": 4144,
"lz444": 2602
@@ -433,7 +433,7 @@
{
"m": "Mai 2025",
"y": 2025,
"ss": 705,
"ss": 730,
"lz304": 2382,
"lz316": 3916,
"lz444": 2502
@@ -441,7 +441,7 @@
{
"m": "Jun 2025",
"y": 2025,
"ss": 700,
"ss": 705,
"lz304": 2280,
"lz316": 3748,
"lz444": 2386
@@ -449,7 +449,7 @@
{
"m": "Jul 2025",
"y": 2025,
"ss": 695,
"ss": 657,
"lz304": 2243,
"lz316": 3751,
"lz444": 2437
@@ -457,7 +457,7 @@
{
"m": "Aug 2025",
"y": 2025,
"ss": 690,
"ss": 660,
"lz304": 2201,
"lz316": 3708,
"lz444": 2433
@@ -465,7 +465,7 @@
{
"m": "Sep 2025",
"y": 2025,
"ss": 685,
"ss": 668,
"lz304": 2260,
"lz316": 3841,
"lz444": 2510
@@ -473,7 +473,7 @@
{
"m": "Okt 2025",
"y": 2025,
"ss": 685,
"ss": 670,
"lz304": 2261,
"lz316": 3927,
"lz444": 2572
@@ -481,7 +481,7 @@
{
"m": "Nov 2025",
"y": 2025,
"ss": 692,
"ss": 703,
"lz304": 2297,
"lz316": 3936,
"lz444": 2550
@@ -489,7 +489,7 @@
{
"m": "Dez 2025",
"y": 2025,
"ss": 720,
"ss": 715,
"lz304": 2322,
"lz316": 3943,
"lz444": 2552
@@ -497,7 +497,7 @@
{
"m": "Jan 2026",
"y": 2026,
"ss": 780,
"ss": 727,
"lz304": 2303,
"lz316": 3815,
"lz444": 2478
@@ -505,7 +505,7 @@
{
"m": "Feb 2026",
"y": 2026,
"ss": null,
"ss": 755,
"lz304": 2541,
"lz316": 4179,
"lz444": 2522
@@ -513,7 +513,7 @@
{
"m": "Mrz 2026",
"y": 2026,
"ss": null,
"ss": 792,
"lz304": 2571,
"lz316": 4367,
"lz444": 2637
@@ -521,11 +521,11 @@
{
"m": "Apr 2026",
"y": 2026,
"ss": null,
"ss": 813,
"lz304": 2663,
"lz316": 4591,
"lz444": 2817
}
],
"baseSS": 780
"baseSS": 727
}

View File

@@ -122,6 +122,51 @@
};
}
function getSaveMonth(surcharges, editMode, editMonth) {
if (editMode) return editMonth;
return (
surcharges["316"]?.month ||
surcharges["304"]?.month ||
surcharges["444"]?.month ||
""
);
}
function cloneSurcharges(surcharges) {
return {
"304": {
...(surcharges["304"] || EMPTY_SURCHARGES["304"]),
},
"316": {
...(surcharges["316"] || EMPTY_SURCHARGES["316"]),
},
"444": {
...(surcharges["444"] || EMPTY_SURCHARGES["444"]),
},
};
}
function shouldUseEditedCurrentValues(
editMode,
editMonth,
editSnapshot,
) {
if (!editMode || !editSnapshot) return true;
return (
getSaveMonth(editSnapshot.surcharges, false, "") ===
editMonth
);
}
function buildSaveEntry(surcharges, baseSS, saveMonth) {
const entry = buildHistoryEntry(surcharges, baseSS);
return {
...entry,
m: saveMonth,
y: monthToYear(saveMonth),
};
}
function upsertHistory(history, entry) {
if (!entry.m) return history;
const idx = history.findIndex((d) => d.m === entry.m);
@@ -877,6 +922,10 @@
finalIdx: true,
});
const [editMode, setEditMode] = useState(false);
const [editMonth, setEditMonth] = useState("");
const [editSnapshot, setEditSnapshot] = useState(null);
useEffect(() => {
fetch(DATA_URL, { cache: "no-store" })
.then((res) => {
@@ -910,11 +959,16 @@
const updSC = (id, field, val) =>
setSurcharges((prev) => ({
...prev,
[id]: { ...(prev[id] || EMPTY_SURCHARGES[id]), [field]: val },
[id]: {
...(prev[id] || EMPTY_SURCHARGES[id]),
[field]: val,
},
}));
const downloadData = (data) => {
const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
const blob = new Blob([JSON.stringify(data, null, 2)], {
type: "application/json",
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
@@ -923,12 +977,73 @@
URL.revokeObjectURL(url);
};
const saveData = async () => {
const entry = buildHistoryEntry(surcharges, baseSS);
const openEditMode = (month) => {
const entry = history.find((d) => d.m === month);
if (!entry) return;
if (!editSnapshot) {
setEditSnapshot({
baseSS: Number.isFinite(Number(baseSS))
? Number(baseSS)
: 0,
surcharges: cloneSurcharges(surcharges),
});
}
setEditMode(true);
setEditMonth(month);
setBaseSS(entry.ss != null ? entry.ss : 0);
setSurcharges({
"304": { month, value: entry.lz304 || 0 },
"316": { month, value: entry.lz316 || 0 },
"444": { month, value: entry.lz444 || 0 },
});
};
const finishEditMode = () => {
setEditMode(false);
setEditMonth("");
setEditSnapshot(null);
};
const startNewEntryMode = () => {
if (editSnapshot) {
setBaseSS(editSnapshot.baseSS);
setSurcharges(editSnapshot.surcharges);
}
finishEditMode();
};
const handleSaveData = async () => {
const saveMonth = getSaveMonth(
surcharges,
editMode,
editMonth,
);
const entry = buildSaveEntry(surcharges, baseSS, saveMonth);
const nextHistory = upsertHistory(history, entry);
const nextData = { surcharges, history: nextHistory, baseSS: Number(baseSS) || 0 };
const normalizedBaseSS = Number.isFinite(Number(baseSS))
? Number(baseSS)
: 0;
const useEditedCurrentValues = shouldUseEditedCurrentValues(
editMode,
editMonth,
editSnapshot,
);
const currentBaseSS = useEditedCurrentValues
? normalizedBaseSS
: editSnapshot.baseSS;
const currentSurcharges = useEditedCurrentValues
? surcharges
: editSnapshot.surcharges;
const nextData = {
surcharges: currentSurcharges,
history: nextHistory,
baseSS: currentBaseSS,
};
setBaseSS(currentBaseSS);
setSurcharges(currentSurcharges);
setHistory(nextHistory);
setSaveStatus("Speichere …");
try {
const res = await fetch("/api/data", {
method: "POST",
@@ -938,10 +1053,17 @@
if (!res.ok) throw new Error(`HTTP ${res.status}`);
setSaveStatus("Gespeichert in data.json.");
} catch (err) {
console.warn("Direktes Speichern nicht möglich, JSON wird heruntergeladen", err);
console.warn(
"Direktes Speichern nicht möglich, JSON wird heruntergeladen",
err,
);
downloadData(nextData);
setSaveStatus("Kein Schreibzugriff im statischen Browser-Modus. data.json wurde heruntergeladen; bitte Datei im Projekt ersetzen.");
setSaveStatus(
"Kein Schreibzugriff im statischen Browser-Modus. data.json wurde heruntergeladen; bitte Datei im Projekt ersetzen.",
);
}
finishEditMode();
};
const chartData = THICKNESSES.map((t) => ({
@@ -1066,6 +1188,7 @@
["methodology", "∑ Methodik"],
["surcharge", "◈ Legierungszuschlag"],
];
const historyMonthOptions = [...history].reverse();
return (
<div
@@ -2326,6 +2449,156 @@
paddingTop: 16,
}}
>
<div
style={{
display: "grid",
gridTemplateColumns:
"1.2fr 1fr",
gap: 12,
marginBottom: 12,
}}
>
<div
style={{
background: S2,
border: `1px solid ${BD}`,
padding: "10px 12px",
}}
>
<label style={lbl}>
Bestehenden Eintrag bearbeiten
</label>
<select
value={
editMode
? editMonth
: ""
}
onChange={(e) => {
const month =
e.target
.value;
if (!month) {
startNewEntryMode();
return;
}
openEditMode(
month,
);
}}
style={field}
>
<option value="">
Neuer Eintrag
</option>
{historyMonthOptions.map(
(entry) => (
<option
key={
entry.m
}
value={
entry.m
}
>
{
entry.m
}
</option>
),
)}
</select>
<div style={hint}>
Bestehende Monate
korrigieren oder neue
Werte erfassen
</div>
</div>
<div
style={{
background: S2,
border: `1px solid ${BD}`,
padding: "10px 12px",
}}
>
<label style={lbl}>
Basis Edelstahlpreis
(/t)
</label>
<input
type="number"
step="10"
value={baseSS}
onChange={(e) =>
setBaseSS(
parseFloat(
e
.target
.value,
) || 0,
)
}
style={field}
/>
<div style={hint}>
Wird in Verlauf als
Basispreis (ss)
gespeichert
</div>
</div>
</div>
{editMode && (
<div
style={{
display: "flex",
justifyContent:
"space-between",
alignItems:
"center",
gap: 12,
flexWrap: "wrap",
marginBottom: 12,
background: `${R}10`,
borderLeft: `3px solid ${R}`,
padding: "10px 12px",
}}
>
<div
style={{
color: TF,
fontSize:
"0.72rem",
fontWeight: 700,
}}
>
Bearbeitung: {editMonth}
</div>
<button
type="button"
onClick={
startNewEntryMode
}
style={{
background: "transparent",
border: `1px solid ${BD}`,
color: TH,
padding:
"6px 10px",
cursor: "pointer",
fontSize:
"0.64rem",
letterSpacing:
"0.08em",
textTransform:
"uppercase",
}}
>
Neuen Eintrag erfassen
</button>
</div>
)}
<div
style={{
fontSize: "0.58rem",
@@ -2336,9 +2609,9 @@
marginBottom: 12,
}}
>
Aktuellen Monat eintragen
wird sofort im Rechner
übernommen
{editMode
? "Korrigierte Monatswerte speichern"
: "Aktuellen Monat eintragen → wird sofort im Rechner übernommen"}
</div>
<div
style={{
@@ -2404,7 +2677,12 @@
value={
(surcharges[
g.id
] || EMPTY_SURCHARGES[g.id]).month
] ||
EMPTY_SURCHARGES[
g
.id
])
.month
}
onChange={(
e,
@@ -2441,7 +2719,12 @@
value={
(surcharges[
g.id
] || EMPTY_SURCHARGES[g.id]).value
] ||
EMPTY_SURCHARGES[
g
.id
])
.value
}
onChange={(
e,
@@ -2478,7 +2761,7 @@
>
<button
type="button"
onClick={saveData}
onClick={handleSaveData}
style={{
background: R,
color: "#fff",
@@ -2495,12 +2778,18 @@
</button>
<span
style={{
color: saveStatus.startsWith("Gespeichert") ? "#059669" : TH,
fontSize: "0.66rem",
color: saveStatus.startsWith(
"Gespeichert",
)
? "#059669"
: TH,
fontSize:
"0.66rem",
lineHeight: 1.6,
}}
>
{saveStatus || "Speichert den aktuellen Monat auch im Verlauf."}
{saveStatus ||
"Speichert den aktuellen Monat auch im Verlauf."}
</span>
</div>
</div>
@@ -2550,9 +2839,9 @@
ablesen (/t)
</li>
<li>
Im Tab oben Monat + Zuschlag
für alle drei Güten
eintragen
Im Tab oben Basispreis,
Monat + Zuschlag für alle
drei Güten eintragen
</li>
<li>
Button

217
tests/helpers.test.js Normal file
View File

@@ -0,0 +1,217 @@
const test = require("node:test");
const assert = require("node:assert/strict");
function monthToYear(month) {
const match = String(month || "").match(/(20\d{2})/);
return match ? Number(match[1]) : new Date().getFullYear();
}
function buildHistoryEntry(surcharges, baseSS) {
const month =
surcharges["316"]?.month ||
surcharges["304"]?.month ||
surcharges["444"]?.month ||
"";
return {
m: month,
y: monthToYear(month),
ss: Number.isFinite(Number(baseSS)) ? Number(baseSS) : null,
lz304: Number(surcharges["304"]?.value) || 0,
lz316: Number(surcharges["316"]?.value) || 0,
lz444: Number(surcharges["444"]?.value) || 0,
};
}
function getSaveMonth(surcharges, editMode, editMonth) {
if (editMode) return editMonth;
return (
surcharges["316"]?.month ||
surcharges["304"]?.month ||
surcharges["444"]?.month ||
""
);
}
function cloneSurcharges(surcharges) {
return {
304: {
...(surcharges["304"] || { month: "", value: 0 }),
},
316: {
...(surcharges["316"] || { month: "", value: 0 }),
},
444: {
...(surcharges["444"] || { month: "", value: 0 }),
},
};
}
function shouldUseEditedCurrentValues(editMode, editMonth, editSnapshot) {
if (!editMode || !editSnapshot) return true;
return getSaveMonth(editSnapshot.surcharges, false, "") === editMonth;
}
function buildSaveEntry(surcharges, baseSS, saveMonth) {
const entry = buildHistoryEntry(surcharges, baseSS);
return {
...entry,
m: saveMonth,
y: monthToYear(saveMonth),
};
}
function upsertHistory(history, entry) {
if (!entry.m) return history;
const existingIndex = history.findIndex(
(historyEntry) => historyEntry.m === entry.m,
);
if (existingIndex >= 0) {
const nextHistory = [...history];
nextHistory[existingIndex] = { ...nextHistory[existingIndex], ...entry };
return nextHistory;
}
return [...history, entry];
}
test("monthToYear extracts year", () => {
assert.equal(monthToYear("Apr. 2026"), 2026);
assert.equal(monthToYear("Jan 2025"), 2025);
});
test("buildSaveEntry persists base price and surcharge values", () => {
const surcharges = {
304: { month: "Apr. 2026", value: 2663 },
316: { month: "Apr. 2026", value: 4591 },
444: { month: "Apr. 2026", value: 2817 },
};
const entry = buildSaveEntry(surcharges, 813, "Apr. 2026");
assert.equal(entry.m, "Apr. 2026");
assert.equal(entry.y, 2026);
assert.equal(entry.ss, 813);
assert.equal(entry.lz304, 2663);
assert.equal(entry.lz316, 4591);
assert.equal(entry.lz444, 2817);
});
test("buildSaveEntry uses explicit save month", () => {
const surcharges = {
304: { month: "Apr. 2026", value: 2663 },
316: { month: "Apr. 2026", value: 4591 },
444: { month: "Apr. 2026", value: 2817 },
};
const entry = buildSaveEntry(surcharges, 755, "Feb 2026");
assert.equal(entry.m, "Feb 2026");
assert.equal(entry.y, 2026);
assert.equal(entry.ss, 755);
assert.equal(entry.lz316, 4591);
});
test("shouldUseEditedCurrentValues returns false for older month edit", () => {
const editSnapshot = {
baseSS: 813,
surcharges: cloneSurcharges({
304: { month: "Apr. 2026", value: 2663 },
316: { month: "Apr. 2026", value: 4591 },
444: { month: "Apr. 2026", value: 2817 },
}),
};
assert.equal(
shouldUseEditedCurrentValues(true, "Feb 2026", editSnapshot),
false,
);
});
test("shouldUseEditedCurrentValues returns true for current month edit", () => {
const editSnapshot = {
baseSS: 813,
surcharges: cloneSurcharges({
304: { month: "Apr. 2026", value: 2663 },
316: { month: "Apr. 2026", value: 4591 },
444: { month: "Apr. 2026", value: 2817 },
}),
};
assert.equal(
shouldUseEditedCurrentValues(true, "Apr. 2026", editSnapshot),
true,
);
});
test("shouldUseEditedCurrentValues returns true outside edit mode", () => {
const editSnapshot = {
baseSS: 813,
surcharges: cloneSurcharges({
304: { month: "Apr. 2026", value: 2663 },
316: { month: "Apr. 2026", value: 4591 },
444: { month: "Apr. 2026", value: 2817 },
}),
};
assert.equal(
shouldUseEditedCurrentValues(false, "Feb 2026", editSnapshot),
true,
);
});
test("upsertHistory appends entry for new month", () => {
const history = [
{ m: "Feb 2026", y: 2026, ss: 755, lz304: 2541, lz316: 4179, lz444: 2522 },
{ m: "Mrz 2026", y: 2026, ss: 792, lz304: 2571, lz316: 4367, lz444: 2637 },
];
const entry = {
m: "Apr 2026",
y: 2026,
ss: 813,
lz304: 2663,
lz316: 4591,
lz444: 2817,
};
const result = upsertHistory(history, entry);
assert.equal(result.length, 3);
assert.equal(result[2].m, "Apr 2026");
});
test("upsertHistory updates existing month without duplicate", () => {
const history = [
{ m: "Feb 2026", y: 2026, ss: 755, lz304: 2541, lz316: 4179, lz444: 2522 },
{ m: "Mrz 2026", y: 2026, ss: 792, lz304: 2571, lz316: 4367, lz444: 2637 },
];
const entry = {
m: "Mrz 2026",
ss: 800,
lz304: 2600,
lz316: 4400,
lz444: 2650,
};
const result = upsertHistory(history, entry);
assert.equal(result.length, 2);
assert.equal(result[1].m, "Mrz 2026");
assert.equal(result[1].y, 2026);
assert.equal(result[1].ss, 800);
assert.equal(result[1].lz444, 2650);
});
test("upsertHistory keeps history unchanged for missing month", () => {
const history = [
{ m: "Feb 2026", y: 2026, ss: 755, lz304: 2541, lz316: 4179, lz444: 2522 },
];
const result = upsertHistory(history, { m: "", ss: 700 });
assert.deepEqual(result, history);
});