Commit b33ee70f authored by Marco Schmiedel's avatar Marco Schmiedel

fix

parent 1c2bec6c
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
"fileId": "01509001-bd4e-4462-93ad-dc5066fd729a", "fileId": "01509001-bd4e-4462-93ad-dc5066fd729a",
"originalPath": "work/models/deal_deal.py", "originalPath": "work/models/deal_deal.py",
"currentPath": "work/models/deal_deal.py", "currentPath": "work/models/deal_deal.py",
"hash": "40213041f5335d16b58dfc6a335038f521462e1985a09402f11c9b7c7fcdc031", "hash": "9da2fe790f15a0af014b268d0c61ac9019677446a8485c06617cba055bd197a2",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1750323591197, "lastCheckedTimestamp": 1750323591197,
"lastFileModificationTimestamp": 1750322900297.3425, "lastFileModificationTimestamp": 1750322900297.3425,
"flaggedForCopy": false "flaggedForCopy": false,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "0c371de0-5973-4ab4-928c-cf5415012cc8", "fileId": "0c371de0-5973-4ab4-928c-cf5415012cc8",
"originalPath": "work/commands/setStaticOptionPrices.py", "originalPath": "work/commands/setStaticOptionPrices.py",
"currentPath": "work/commands/setStaticOptionPrices.py", "currentPath": "work/commands/setStaticOptionPrices.py",
"hash": "e6128d9a59cf3b14986ec7a96cf891e67dd77e7b50029fe6321f7625b32bd0b7", "hash": "39a6cba051f6bcab655516b8d6d44fc2793465b855e0569047034a6fe3aa4b02",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1750323678836, "lastCheckedTimestamp": 1750323678836,
"lastFileModificationTimestamp": 1750323672008.4895 "lastFileModificationTimestamp": 1750323672008.4895,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "12a942d7-6f13-4c57-9f5c-1c6fd3baaf21", "fileId": "12a942d7-6f13-4c57-9f5c-1c6fd3baaf21",
"originalPath": "work/manager/OpenAiManager.py", "originalPath": "work/manager/OpenAiManager.py",
"currentPath": "work/manager/OpenAiManager.py", "currentPath": "work/manager/OpenAiManager.py",
"hash": "a5d54b395c9edf435ee5ec0a2f3637058b54bab058827175487268f4dc07304a", "hash": "2ad8278a6ba8e93251b09bd0efc02d7913f2cfe9bb84cd0f445af6cde4120b35",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -13,5 +13,6 @@ ...@@ -13,5 +13,6 @@
} }
], ],
"lastCheckedTimestamp": 1745314592645, "lastCheckedTimestamp": 1745314592645,
"lastFileModificationTimestamp": 1745314218432.6475 "lastFileModificationTimestamp": 1745314218432.6475,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "1d59cc86-7b89-484d-a6da-2e1563612c68", "fileId": "1d59cc86-7b89-484d-a6da-2e1563612c68",
"originalPath": "work/routes/EeccxRouter.py", "originalPath": "work/routes/EeccxRouter.py",
"currentPath": "work/routes/EeccxRouter.py", "currentPath": "work/routes/EeccxRouter.py",
"hash": "8566d61ad12b99cc94f281143a84d6d225f597157b53856200f1de0455f1c0c6", "hash": "b8a4783ce72999f5453b233248bbc571f6ec2b529bcf6c4cf9f37678197eefaf",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1747123614326, "lastCheckedTimestamp": 1747123614326,
"lastFileModificationTimestamp": 1747074419978.3298 "lastFileModificationTimestamp": 1747074419978.3298,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "1e5daa93-a29c-4db7-98ac-3457b779f0d1", "fileId": "1e5daa93-a29c-4db7-98ac-3457b779f0d1",
"originalPath": "work/manager/S3Manager.py", "originalPath": "work/manager/S3Manager.py",
"currentPath": "work/manager/S3Manager.py", "currentPath": "work/manager/S3Manager.py",
"hash": "3626bb3b00d9142ba6d471dfdd2d7a0f54d72afca4b908843c9cf6d483d66754", "hash": "241e131975edd0ada6588604c95a7e0e6047f3595229a73f3ef49aa4133a12a7",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -13,5 +13,6 @@ ...@@ -13,5 +13,6 @@
} }
], ],
"lastCheckedTimestamp": 1745314595210, "lastCheckedTimestamp": 1745314595210,
"lastFileModificationTimestamp": 1745314341957.45 "lastFileModificationTimestamp": 1745314341957.45,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "22983490-9c01-4bd1-8649-dfe87c659225", "fileId": "22983490-9c01-4bd1-8649-dfe87c659225",
"originalPath": "work/config/MauiConfig.py", "originalPath": "work/config/MauiConfig.py",
"currentPath": "work/config/MauiConfig.py", "currentPath": "work/config/MauiConfig.py",
"hash": "08c57a67f7a74d7b702b572da3cd912bf4603ee97e9495a6be2ce60b73beab20", "hash": "36c6c906e8d5b2ce7d02f05331c3d2298b11941dd4a4f33b66440fd8f12600f6",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -10,8 +10,14 @@ ...@@ -10,8 +10,14 @@
"commentId": "3bc16f5e-4032-44a8-9012-4b632849ba50", "commentId": "3bc16f5e-4032-44a8-9012-4b632849ba50",
"text": "This data is currently stored statically and should be dynamically linked to the Docker container at the appropriate time.", "text": "This data is currently stored statically and should be dynamically linked to the Docker container at the appropriate time.",
"timestamp": 1744614418809 "timestamp": 1744614418809
},
{
"commentId": "0363a6af-471a-40cd-bc35-392d95212e88",
"text": "Ive stored new credentials for Maui (BCS Mobile GmbH).",
"timestamp": 1750663392646
} }
], ],
"lastCheckedTimestamp": 1747070436322, "lastCheckedTimestamp": 1750663398674,
"lastFileModificationTimestamp": 1747043388546.054 "lastFileModificationTimestamp": 1750662187654.694,
"hash_version": 2
} }
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
"fileId": "24784b38-54dc-4000-9d2a-f59082ebbc1c", "fileId": "24784b38-54dc-4000-9d2a-f59082ebbc1c",
"originalPath": "work/models/base_base.py", "originalPath": "work/models/base_base.py",
"currentPath": "work/models/base_base.py", "currentPath": "work/models/base_base.py",
"hash": "4b4953aec18780e96b30745c6e4806eb9b5c19a1bf015ceb3465e38f85062b5c", "hash": "c3f749b6cf0c99c490d1794be696279fea595a13a290dbfa9bd37e7fbc63ab0e",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1746694072323, "lastCheckedTimestamp": 1746694072323,
"lastFileModificationTimestamp": 1746694051656.7517, "lastFileModificationTimestamp": 1746694051656.7517,
"flaggedForCopy": false "flaggedForCopy": false,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "36e791b4-e235-42f6-ac61-8560f1762892", "fileId": "36e791b4-e235-42f6-ac61-8560f1762892",
"originalPath": "work/workbench/Workbench.mwb", "originalPath": "work/workbench/Workbench.mwb",
"currentPath": "work/workbench/Workbench.mwb", "currentPath": "work/workbench/Workbench.mwb",
"hash": "66d7321a70d23c6704bde73d00b3102358f5942df6617b1c1f83a0d1e56d322b", "hash": "0dc0d859ab183836151c074d746ac1ed0a17694595b9bfaafdaf51a10e065f69",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -10,8 +10,14 @@ ...@@ -10,8 +10,14 @@
"commentId": "9eaabff2-a6a7-4fc9-b57e-c47dc019890e", "commentId": "9eaabff2-a6a7-4fc9-b57e-c47dc019890e",
"text": "All green for now...", "text": "All green for now...",
"timestamp": 1746693753181 "timestamp": 1746693753181
},
{
"commentId": "cd68b2fe-2e97-4ebc-8bae-7510cad302ce",
"text": "Ive added a table for \"aiprice\".",
"timestamp": 1750664915668
} }
], ],
"lastCheckedTimestamp": 1750328592721, "lastCheckedTimestamp": 1750664905274,
"lastFileModificationTimestamp": 1750322693600.0522 "lastFileModificationTimestamp": 1750664896661.1187,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "38da158f-ad91-433f-8b7b-60ff4949d7ff", "fileId": "38da158f-ad91-433f-8b7b-60ff4949d7ff",
"originalPath": "work/config/_CronConfig.txt", "originalPath": "work/config/_CronConfig.txt",
"currentPath": "work/config/_CronConfig.txt", "currentPath": "work/config/_CronConfig.txt",
"hash": "5c11b0a57b7cb9981914397ca2c49d10ef10e6802c70caa91fffa53098c1add7", "hash": "174ef9fe04e4d6aebb38573991945d535ec049a7e3069a8c033cd8e7ee30820e",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1749816820741, "lastCheckedTimestamp": 1749816820741,
"lastFileModificationTimestamp": 1749816813585.9177 "lastFileModificationTimestamp": 1749816813585.9177,
"hash_version": 2
} }
{
"fileId": "46451bbf-8578-4f75-a530-356f5e1ea6b0",
"originalPath": "work/models/aiprice_aipr.py",
"currentPath": "work/models/aiprice_aipr.py",
"hash": "75d354be20f32adc2814b2eec54a9e0ccbe07e64f64dc1e156ce92a0ad59b173",
"hash_version": 2,
"docContent": "<p><br></p>",
"checkedStatus": "done",
"comments": [],
"lastCheckedTimestamp": 1750682737351,
"lastFileModificationTimestamp": 1750665075024.6191
}
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "48126029-3c3e-4372-9f3e-1e8b9686114e", "fileId": "48126029-3c3e-4372-9f3e-1e8b9686114e",
"originalPath": "work/commands/importCacheToDatabase.py", "originalPath": "work/commands/importCacheToDatabase.py",
"currentPath": "work/commands/importCacheToDatabase.py", "currentPath": "work/commands/importCacheToDatabase.py",
"hash": "3c19dde87c665d72591ff9391a0dd6ec28218002116df06b22217a09d2a73e27", "hash": "35d56b9bc420e57388faa4e15e12cde381048f016b40307c4ed7f829e9aac7e4",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1747070815750, "lastCheckedTimestamp": 1747070815750,
"lastFileModificationTimestamp": 1747070802673.0312 "lastFileModificationTimestamp": 1747070802673.0312,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "4c784f14-4710-4694-bf73-f5665baab43f", "fileId": "4c784f14-4710-4694-bf73-f5665baab43f",
"originalPath": "work/cron.sh", "originalPath": "work/cron.sh",
"currentPath": "work/cron.sh", "currentPath": "work/cron.sh",
"hash": "8950b2d4895462785979d16bc1db8830ed40cca30d60a680df360f731b95baa9", "hash": "c5c101dc99dd0db0e38179ea54cb6dc96ae91a48717cb479d06463747195354d",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -13,5 +13,6 @@ ...@@ -13,5 +13,6 @@
} }
], ],
"lastCheckedTimestamp": 1747070016564, "lastCheckedTimestamp": 1747070016564,
"lastFileModificationTimestamp": 1747070003854.197 "lastFileModificationTimestamp": 1747070003854.197,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "58307c8c-416a-4c24-adc9-7ed6324d1f8a", "fileId": "58307c8c-416a-4c24-adc9-7ed6324d1f8a",
"originalPath": "work/manager/WebManager.py", "originalPath": "work/manager/WebManager.py",
"currentPath": "work/manager/WebManager.py", "currentPath": "work/manager/WebManager.py",
"hash": "a0a065203ba1c85cb820f87483fae6404cdacc88c703f135b42bcee608e09bad", "hash": "b2151aa7c5fa9b2be45a84efe525564af3f731ee2e144953312a7f230e23877c",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1748952745993, "lastCheckedTimestamp": 1748952745993,
"lastFileModificationTimestamp": 1748948322859.7175 "lastFileModificationTimestamp": 1748948322859.7175,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "5d19e01b-5fd7-4215-8da7-6b0a95956727", "fileId": "5d19e01b-5fd7-4215-8da7-6b0a95956727",
"originalPath": "work/models/_system.py", "originalPath": "work/models/_system.py",
"currentPath": "work/models/_system.py", "currentPath": "work/models/_system.py",
"hash": "86d0b6279cb483585f66646c598db95bbda853070ef80a5b05218826dea61299", "hash": "00359256fec909b1a815d2d1fb0ec6ed3564b36cdf005f284b6dfd47df053648",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1744626235100, "lastCheckedTimestamp": 1744626235100,
"lastFileModificationTimestamp": 1744625929875.2092 "lastFileModificationTimestamp": 1744625929875.2092,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "5f874bee-40e2-4b9a-b102-f0b6d643a840", "fileId": "5f874bee-40e2-4b9a-b102-f0b6d643a840",
"originalPath": "work/commands/downloadDataFromMaui.py", "originalPath": "work/commands/downloadDataFromMaui.py",
"currentPath": "work/commands/downloadDataFromMaui.py", "currentPath": "work/commands/downloadDataFromMaui.py",
"hash": "7bf05e24539e6b6cc9b9abf1c3103aee2e4419c1dd5c2a8fadd2d825947b951f", "hash": "3e1df1c401fbd00595912583ee4d4d2bb45364f81daca29113db874515eee0a0",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1750323681845, "lastCheckedTimestamp": 1750323681845,
"lastFileModificationTimestamp": 1750323366660.076 "lastFileModificationTimestamp": 1750323366660.076,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "62aea232-2549-437e-b5a9-72cb2aa92d16", "fileId": "62aea232-2549-437e-b5a9-72cb2aa92d16",
"originalPath": "work/commands/calculateTarifDetailsWithGpt.py", "originalPath": "work/commands/calculateTarifDetailsWithGpt.py",
"currentPath": "work/commands/calculateTarifDetailsWithGpt.py", "currentPath": "work/commands/calculateTarifDetailsWithGpt.py",
"hash": "9161246779e6b04e4ae512afe91cfae14ad7e9fc28395d42f54627e3b70a25b0", "hash": "6de592dae63250612a453932e1e344699a550e4438c16813d54ba4bf2a13c785",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1747071244862, "lastCheckedTimestamp": 1747071244862,
"lastFileModificationTimestamp": 1747071237273.2832 "lastFileModificationTimestamp": 1747071237273.2832,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "647ff9a8-a56f-486e-ba2a-8ff77e4514d4", "fileId": "647ff9a8-a56f-486e-ba2a-8ff77e4514d4",
"originalPath": "work/Dockerfile", "originalPath": "work/Dockerfile",
"currentPath": "work/Dockerfile", "currentPath": "work/Dockerfile",
"hash": "7d986675138b37a5ad1f01c7a7201d1aa409f2b4557afe5f2fd590ebde55e3ce", "hash": "1ac9ea4b26667c2f0761212959a8f5809b217ab5920d09b03c1be85d20ab1527",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -13,5 +13,6 @@ ...@@ -13,5 +13,6 @@
} }
], ],
"lastCheckedTimestamp": 1748952742075, "lastCheckedTimestamp": 1748952742075,
"lastFileModificationTimestamp": 1748952688396.303 "lastFileModificationTimestamp": 1748952688396.303,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "766dc461-001e-4901-8faf-263820ad96cd", "fileId": "766dc461-001e-4901-8faf-263820ad96cd",
"originalPath": "work/manager/MysqlManager.py", "originalPath": "work/manager/MysqlManager.py",
"currentPath": "work/manager/MysqlManager.py", "currentPath": "work/manager/MysqlManager.py",
"hash": "9a9ca8572ad133ef4a191b7082ffb025d979f84dce2109ff5be33108cb807652", "hash": "507731324dd71fbbd7e093a054515a91aa279b567248e1c0cc67f986bd321932",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -14,5 +14,6 @@ ...@@ -14,5 +14,6 @@
], ],
"lastCheckedTimestamp": 1747070649128, "lastCheckedTimestamp": 1747070649128,
"lastFileModificationTimestamp": 1747070643843.446, "lastFileModificationTimestamp": 1747070643843.446,
"flaggedForCopy": false "flaggedForCopy": false,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "78db1316-a768-4c1f-b15c-7a408444a030", "fileId": "78db1316-a768-4c1f-b15c-7a408444a030",
"originalPath": "work/routes/HealtCheckRouter.py", "originalPath": "work/routes/HealtCheckRouter.py",
"currentPath": "work/routes/HealtCheckRouter.py", "currentPath": "work/routes/HealtCheckRouter.py",
"hash": "965774cdb8edb7b68ec0341e4d122765853c5fa82b5432df2843234c25874f3d", "hash": "bfbad62c9c194c675e4462f616bde373c9fa1b71e2e90eb9eb372171ffa7e38d",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1747070215651, "lastCheckedTimestamp": 1747070215651,
"lastFileModificationTimestamp": 1747070210301.3403 "lastFileModificationTimestamp": 1747070210301.3403,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "7a3a246b-fc0e-4c80-b748-96b941efab5c", "fileId": "7a3a246b-fc0e-4c80-b748-96b941efab5c",
"originalPath": "work/config/AWSConfig.py", "originalPath": "work/config/AWSConfig.py",
"currentPath": "work/config/AWSConfig.py", "currentPath": "work/config/AWSConfig.py",
"hash": "29bc59fd6ecbf98aa7efcfa3ef371bb912ac144f077895c279bb80ba150ee734", "hash": "89fcc1961f370e863030d6fba724d41b392d0b311f7ddad989764059488e505b",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -13,5 +13,6 @@ ...@@ -13,5 +13,6 @@
} }
], ],
"lastCheckedTimestamp": 1747070433793, "lastCheckedTimestamp": 1747070433793,
"lastFileModificationTimestamp": 1747042244230.3608 "lastFileModificationTimestamp": 1747042244230.3608,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "8c1b7b54-86c0-453c-839c-95390d883819", "fileId": "8c1b7b54-86c0-453c-839c-95390d883819",
"originalPath": "work/commands/uploadCacheToAwsS3.py", "originalPath": "work/commands/uploadCacheToAwsS3.py",
"currentPath": "work/commands/uploadCacheToAwsS3.py", "currentPath": "work/commands/uploadCacheToAwsS3.py",
"hash": "158bb6839fc011bfeb8ab54d335f897c629228f2169844f2f6118f803b80c64f", "hash": "4c972fa8de12b095edb942fc260533235001e5b7a508a4e058e28f45340ebc59",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1747070735035, "lastCheckedTimestamp": 1750663401713,
"lastFileModificationTimestamp": 1747070723183.9927 "lastFileModificationTimestamp": 1750662226645.7258,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "986eeb57-8634-4f40-a4ea-a2eae9d87e71", "fileId": "986eeb57-8634-4f40-a4ea-a2eae9d87e71",
"originalPath": "work/readme.md", "originalPath": "work/readme.md",
"currentPath": "work/README.md", "currentPath": "work/README.md",
"hash": "4d543d075a22bd2b13008dcc7a1cf518a3df29bbf1b1ab516eb69a2df778aaf9", "hash": "4f572de1efd35b429b45d9932e8ffa93153c9b0a421c7afec99b4af109aa87d1",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
"timestamp": 1747069658074 "timestamp": 1747069658074
} }
], ],
"lastCheckedTimestamp": 1748952738060, "lastCheckedTimestamp": 1750683280697,
"lastFileModificationTimestamp": 1748952727853.0393 "lastFileModificationTimestamp": 1750683272808.5942,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "b71a7bf5-594a-4ac1-9113-25158c35bcb4", "fileId": "b71a7bf5-594a-4ac1-9113-25158c35bcb4",
"originalPath": "work/models/token_toke.py", "originalPath": "work/models/token_toke.py",
"currentPath": "work/models/token_toke.py", "currentPath": "work/models/token_toke.py",
"hash": "609e9fec7718b6125d047c7a8c7029b7d0cd2b95df889334914ce058091176bd", "hash": "ee6718c04763632568d0383e01eac2b824fce448ffe196642c096d145eac0e46",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1747070070388, "lastCheckedTimestamp": 1747070070388,
"lastFileModificationTimestamp": 1747068898597.5894 "lastFileModificationTimestamp": 1747068898597.5894,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "caf03c7b-60d8-4a77-ac21-0eccabeae4a2", "fileId": "caf03c7b-60d8-4a77-ac21-0eccabeae4a2",
"originalPath": "work/boot.sh", "originalPath": "work/boot.sh",
"currentPath": "work/boot.sh", "currentPath": "work/boot.sh",
"hash": "9d08025500b916fe294de7aa8b533c29e02743c714022415ae9274e066c4fa6a", "hash": "4ee8683a91fa79f963829494164088ea9440a08871ba63b9b55829b0d24b2bd8",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -13,5 +13,6 @@ ...@@ -13,5 +13,6 @@
} }
], ],
"lastCheckedTimestamp": 1747070094947, "lastCheckedTimestamp": 1747070094947,
"lastFileModificationTimestamp": 1747070086824.1516 "lastFileModificationTimestamp": 1747070086824.1516,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "d470fd53-8f95-47d0-a63b-5851586c0eda", "fileId": "d470fd53-8f95-47d0-a63b-5851586c0eda",
"originalPath": "work/manager/SeleniumManager.py", "originalPath": "work/manager/SeleniumManager.py",
"currentPath": "work/manager/SeleniumManager.py", "currentPath": "work/manager/SeleniumManager.py",
"hash": "f29307970d124e55c7066e71ddf682f55e043d4f925195bdf320ff9da1311e27", "hash": "5a25594874c12b7e4d91ff92d1657ac68c4a0a20a722a5f8eca3d73709882828",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -13,5 +13,6 @@ ...@@ -13,5 +13,6 @@
} }
], ],
"lastCheckedTimestamp": 1745314597597, "lastCheckedTimestamp": 1745314597597,
"lastFileModificationTimestamp": 1745314531223.019 "lastFileModificationTimestamp": 1745314531223.019,
"hash_version": 2
} }
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
"fileId": "e146d34c-9d63-4ea0-b8b8-5f8d503f34f6", "fileId": "e146d34c-9d63-4ea0-b8b8-5f8d503f34f6",
"originalPath": "work/models/option_opti.py", "originalPath": "work/models/option_opti.py",
"currentPath": "work/models/option_opti.py", "currentPath": "work/models/option_opti.py",
"hash": "af00a2687f2ac9ea0285e96ec70320ea2a3bf3ed4359b2850b1b1273c236e7ce", "hash": "84a0aacc57e826a9133f8f3d2905d22a268403bfd76b8d5f706c5aeccfeb9f19",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1750323587708, "lastCheckedTimestamp": 1750323587708,
"lastFileModificationTimestamp": 1750322895612.6667, "lastFileModificationTimestamp": 1750322895612.6667,
"flaggedForCopy": false "flaggedForCopy": false,
"hash_version": 2
} }
{
"fileId": "e3281330-5559-49da-9434-bf3cccd4ddae",
"originalPath": "work/commands/calculateAiPrices.py",
"currentPath": "work/commands/calculateAiPrices.py",
"hash": "343345985f2e8153b4e9e6a7efa0479c3938e68080388f23e537609f14cafded",
"hash_version": 2,
"docContent": "<p><br></p>",
"checkedStatus": "todo",
"comments": [
{
"commentId": "1d5f60af-fe8c-46f1-8a99-806b835d8ed6",
"text": "Maybe not stable... Need to run this a few weeks on prod...",
"timestamp": 1750682733287
}
],
"lastCheckedTimestamp": 1750682714405,
"lastFileModificationTimestamp": 1750681385737.0137
}
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "e4ffba94-a5e6-40d2-a63e-5bfa60e3d719", "fileId": "e4ffba94-a5e6-40d2-a63e-5bfa60e3d719",
"originalPath": "work/routes/BaseRouter.py", "originalPath": "work/routes/BaseRouter.py",
"currentPath": "work/routes/BaseRouter.py", "currentPath": "work/routes/BaseRouter.py",
"hash": "e8f5cd3137261214985789cc7e328848d9ff379525c706b9acf6ee7a6ea3adec", "hash": "b6427a939c47e33834697736552c6c460a6de1c4fc7558fc9fa20e365eda24c7",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1747070513561, "lastCheckedTimestamp": 1750682740904,
"lastFileModificationTimestamp": 1747070506645.0361 "lastFileModificationTimestamp": 1750681918026.2954,
"hash_version": 2
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
"fileId": "ec1eb8b3-9fc0-4593-ac37-e51f7c643f1d", "fileId": "ec1eb8b3-9fc0-4593-ac37-e51f7c643f1d",
"originalPath": "work/routes/FreenetUploadRouter.py", "originalPath": "work/routes/FreenetUploadRouter.py",
"currentPath": "work/routes/FreenetUploadRouter.py", "currentPath": "work/routes/FreenetUploadRouter.py",
"hash": "d101612a37ead90042f21152be5b3d1ff924ea26d2e4e16b459aa5a623d321b1", "hash": "d7f57b60a739591d31522c98253c07d260df9b8843db30de6dbd92ef2b7ba892",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [], "comments": [],
"lastCheckedTimestamp": 1748953027802, "lastCheckedTimestamp": 1748953027802,
"lastFileModificationTimestamp": 1748952926381.2961 "lastFileModificationTimestamp": 1748952926381.2961,
"hash_version": 2
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"fileId": "f645f6dc-6831-4020-a6ae-8b5a572eed54", "fileId": "f645f6dc-6831-4020-a6ae-8b5a572eed54",
"originalPath": "work/config/OpenAiConfig.py", "originalPath": "work/config/OpenAiConfig.py",
"currentPath": "work/config/OpenAiConfig.py", "currentPath": "work/config/OpenAiConfig.py",
"hash": "50c0f7d96f9ea76aa069a0a24137e898dbd4fc3c4af867565c90468981bf6ff5", "hash": "ba76f61e2a34340076f21f52e130e549b759e65b36cca7cd0e56ed81eeb4d331",
"docContent": "<p><br></p>", "docContent": "<p><br></p>",
"checkedStatus": "done", "checkedStatus": "done",
"comments": [ "comments": [
...@@ -13,5 +13,6 @@ ...@@ -13,5 +13,6 @@
} }
], ],
"lastCheckedTimestamp": 1747070442728, "lastCheckedTimestamp": 1747070442728,
"lastFileModificationTimestamp": 1746437070245.503 "lastFileModificationTimestamp": 1746437070245.503,
"hash_version": 2
} }
import sys
sys.path.append("..")
import logging
import json
import re
from sqlalchemy.orm import Session
from sqlalchemy import or_
from manager.MysqlManager import MysqlManager
from manager.OpenAiManager import OpenAiManager
from models.base_base import BaseBase # HINZUGEFÜGT: Fehlender Import
from models.deal_deal import DealDeal
from models.option_opti import OptionOpti
from models.aiprice_aipr import AipriceAipr
# Konfiguriert ein einfaches Logging, um den Skriptverlauf zu sehen.
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s: %(message)s")
def get_validated_response(gpt_manager: OpenAiManager, name: str) -> dict | None:
"""Sendet eine Anfrage an GPT und validiert die JSON-Antwort auf Konsistenz."""
prompt = """
# Teil 1 – Aufgabe
- Wir analysieren gemeinsam Mobilfunk-Optionen. Beachte diesen Kontext während der Aufgabe.
- Dieser Prompt ist in **drei** Teile unterteilt.
- **Teil 1** erklärt dir die Aufgabe.
- **Teil 2** zeigt dir Beispiele, damit du die Entscheidungs­logik lernst.
- **Teil 3** ist die eigentliche Prüfung und kontrolliert, ob du Teil 2 verstanden hast.
- In Teil 3 erwarte ich **nur** ein JSON-Objekt im unten definierten Format – keine Zusatztexte.
- Teil 2 ist reine Referenz; seine Inhalte dürfen **nicht** in die Prüf­antwort kopiert werden.
- Standard-JSON (alle Defaultwerte):
{
"discount_euro_brutto": 0, fixer €-Rabatt (NEGATIV = Preisnachlass, 0 = keiner)
"discount_percent": 0, Prozent-Rabatt (NEGATIV = Preisnachlass, 0 = keiner)
"discount_months": 0, Dauer des Rabatts in Monaten; 0 = unbefristet ODER kein Rabatt
"provision_netto": 0, >0 Händler erhält Vergütung, <0 Händler verzichtet
"connection_fee_brutto": null -x Kunde zahlt AP, 0 AP frei, +x Einmalbonus, null keine Angabe
}
-----
Teil 2 - Beispiele:
/* 10 € Rabatt auf MGP dauerhaft, 140 € Sonderbonus */
{
"discount_euro_brutto": -10, // −10 € fixer Monatsrabatt für den Kunden
"discount_percent": 0, // kein Prozent-Rabatt genannt
"discount_months": 0, // 0 ⇒ Rabatt gilt unbefristet (lifetime)
"provision_netto": 140, // +140 € Sondervergütung an den Händler
"connection_fee_brutto": null // Anschlusspreis wird im Text nicht erwähnt
}
/* 10 € Rabatt auf MGP lifetime, 10 € Sonderbonus, Anschlusspeis frei */
{
"discount_euro_brutto": -10, // −10 € fixer Monatsrabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // lifetime ⇒ unbegrenzt
"provision_netto": 10, // +10 € Sondervergütung an den Händler
"connection_fee_brutto": 0 // 0 € ⇒ Anschlusspreis (AP) ist frei
}
/* 10 € Rabatt auf Monatsgrundpreis lifetime, Anschlusspreis frei, 10 € Sonderbonus */
{
"discount_euro_brutto": -10, // −10 € fixer Rabatt pro Monat
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // lifetime ⇒ Rabatt ohne Befristung
"provision_netto": 10, // +10 € Sondervergütung an den Händler
"connection_fee_brutto": 0 // AP frei (0 €)
}
/* 10 € Sonderbonus */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt vorhanden
"discount_percent": 0, // kein Prozent-Rabatt vorhanden
"discount_months": 0, // kein Rabatt ⇒ 0
"provision_netto": 10, // +10 € Sondervergütung an den Händler
"connection_fee_brutto": null // kein Hinweis auf Anschlusspreis
}
/* 100 € Sonderbonus */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt im Text erwähnt
"discount_percent": 0, // kein Prozent-Rabatt vorhanden
"discount_months": 0, // 0 ⇒ es gibt überhaupt keinen Rabatt
"provision_netto": 100, // +100 € Sondervergütung an den Händler
"connection_fee_brutto": null // Anschlusspreis (AP) wird nicht erwähnt
}
/* 12 × 2 € Rabatt auf MGP, 30 € Vergütungsverzicht */
{
"discount_euro_brutto": -2, // −2 € Rabatt je Monat für den Kunden
"discount_percent": 0, // kein Prozent-Rabatt genannt
"discount_months": 12, // Rabatt läuft 12 Monate (12×)
"provision_netto": -30, // −30 €: Händler verzichtet auf Provision
"connection_fee_brutto": null // Anschlusspreis wird nicht erwähnt
}
/* 120 € Sonderbonus */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt vorhanden
"discount_percent": 0, // kein Prozent-Rabatt vorhanden
"discount_months": 0, // 0 ⇒ kein Rabatt
"provision_netto": 120, // +120 € Sondervergütung an den Händler
"connection_fee_brutto": null // kein Anschlusspreis im Text erwähnt
}
/* 24 × 10 € Rabatt auf MGP, 210 € Sonderbonus */
{
"discount_euro_brutto": -10, // −10 € fixer Monatsrabatt für den Kunden
"discount_percent": 0, // kein Prozent-Rabatt genannt
"discount_months": 24, // Rabatt gilt 24 Monate (24 ×)
"provision_netto": 210, // +210 € Sondervergütung an den Händler
"connection_fee_brutto": null // Anschlusspreis wird im Text nicht erwähnt
}
/* 24 × 10 % Rabatt auf MGP, 65 € Sonderbonus */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt
"discount_percent": -10, // −10 % Rabatt je Monat
"discount_months": 24, // Rabatt läuft 24 Monate
"provision_netto": 65, // +65 € Sondervergütung für den Händler
"connection_fee_brutto": null // kein Anschlusspreis-Hinweis
}
/* 24 × 10 % Rabatt auf MGP, 0 € Sonderbonus, 0 € Vergütungsverzicht */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt
"discount_percent": -10, // −10 % monatlicher Rabatt
"discount_months": 24, // 24 Monate Rabattdauer
"provision_netto": 0, // weder Bonus noch Verzicht (0 €)
"connection_fee_brutto": null // Anschlusspreis nicht erwähnt
}
/* 24 × 23 € Rabatt auf MGP, Entfall Smartphone-10-Option lifetime, 0 € Anschlusspreis, 270 € Vergütungsverzicht */
{
"discount_euro_brutto": -23, // −23 € fixer Monatsrabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 24, // Rabatt gilt 24 Monate
"provision_netto": -270, // −270 €: Händler verzichtet auf Vergütung
"connection_fee_brutto": 0 // 0 € ⇒ Anschlusspreis ist vollständig frei
}
/* 24 × 28 € Rabatt auf MGP, Entfall Smartphone-10-Option lifetime, 20 € Rabatt auf den Anschlusspreis, 370 € Vergütungsverzicht */
{
"discount_euro_brutto": -28, // −28 € fixer Monatsrabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 24, // 24-monatige Rabattdauer
"provision_netto": -370, // −370 €: Händlerverzicht auf Provision
"connection_fee_brutto": -20 // 20 Euro Rabatt auf AP
}
/* 24 × 35 € Rabatt auf MGP, Entfall Smartphone-10-Option lifetime, 20 € Rabatt auf Anschlusspreis, 410 € Vergütungsverzicht */
{
"discount_euro_brutto": -35, // −35 € Monatsrabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 24, // Rabatt gilt 24 Monate
"provision_netto": -410, // −410 € Händlerverzicht
"connection_fee_brutto": -20 // 20 Euro Rabatt auf AP
}
/* 24 × 5 € Rabatt auf MGP, 0 € Vergütungsverzicht, 0 € Sonderbonus */
{
"discount_euro_brutto": -5, // −5 € fixer Monatsrabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 24, // Rabatt läuft 24 Monate
"provision_netto": 0, // weder Bonus noch Verzicht
"connection_fee_brutto": null // Anschlusspreis wird nicht erwähnt
}
/* 5 € Rabatt auf Monatsgrundpreis dauerhaft, 80 € Sonderbonus */
{
"discount_euro_brutto": -5, // −5 € fixer Monatsrabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // 0 ⇒ Rabatt gilt unbefristet (dauerhaft)
"provision_netto": 80, // +80 € Sondervergütung an den Händler
"connection_fee_brutto": null // Anschlusspreis wird nicht erwähnt
}
/* 5 € Rabatt lifetime, 20 € Sonderbonus */
{
"discount_euro_brutto": -5, // −5 € fixer Monatsrabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // lifetime ⇒ unbegrenzt
"provision_netto": 20, // +20 € Sondervergütung an den Händler
"connection_fee_brutto": null // kein Hinweis auf Anschlusspreis
}
/* A3480785 mit 1 GB LTE und 25 Mbit/s, 100 Minuten und 100 SMS / 19,99 EUR Anschlusspreis / 30 EUR Sondervergütung */
{
"discount_euro_brutto": 0, // kein Monatsrabatt genannt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // kein Rabatt ⇒ 0
"provision_netto": 30, // +30 € Sondervergütung an den Händler
"connection_fee_brutto": -19.99 // Kunde erhält 19.99 auf Anschlusspreis
}
/* A3480821 mit 5 GB LTE und 50 Mbit/s / 19,99 EUR Anschlusspreis / 35 EUR Sondervergütung */
{
"discount_euro_brutto": 0, // kein Monatsrabatt vorhanden
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // kein Rabatt ⇒ 0
"provision_netto": 35, // +35 € Sondervergütung an den Händler
"connection_fee_brutto": -19.99 Kunde erhält 19.99 auf Anschlusspreis
}
/* A3480869 mit 1 GB LTE und 25 Mbit/s, 100 Minuten und 100 SMS / 0 EUR Anschlusspreis / 15 EUR Sondervergütung */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // kein Rabatt ⇒ 0
"provision_netto": 15, // +15 € Sondervergütung an den Händler
"connection_fee_brutto": 0 // 0 € ⇒ Anschlusspreis ist frei
}
/* Cashback Fachhandel | VP: 100 Euro Cashback */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt (Cashback ist kein Rabatt auf MGP)
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // kein laufender Rabatt ⇒ 0
"provision_netto": -84, // Cashback kostet dem Händler Geld (connection_fee_brutto/1.19)
"connection_fee_brutto": -100 // -100 € einmalige Auszahlung an den Kunden
}
/* Cashback Fachhandel | VP: 120 Euro Cashback */
{
"discount_euro_brutto": 0,
"discount_percent": 0,
"discount_months": 0,
"provision_netto": -101, // Cashback kostet dem Händler Geld (connection_fee_brutto/1.19)
"connection_fee_brutto": -120 // -120 € einmalige Auszahlung an den Kunden
}
/* Cashback Fachhandel | VP: 50 Euro Cashback */
{
"discount_euro_brutto": 0,
"discount_percent": 0,
"discount_months": 0,
"provision_netto": -42, // Cashback kostet dem Händler Geld (connection_fee_brutto/1.19)
"connection_fee_brutto": -50 // -50 € einmalige Auszahlung an den Kunden
}
/* Cashback Fachhandel | VP: 60 Euro Cashback */
{
"discount_euro_brutto": 0,
"discount_percent": 0,
"discount_months": 0,
"provision_netto": -50, // Cashback kostet dem Händler Geld (connection_fee_brutto/1.19)
"connection_fee_brutto": -60 // -60 € einmalige Auszahlung an den Kunden
}
/* Aktionsguthaben VP | 192 EUR Aktionsguthaben VP (12 Monate gültig) */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // 0 ⇒ es handelt sich nicht um einen laufenden Rabatt
"provision_netto": -161, // Aktionsguthaben kostet dem Händler Geld (connection_fee_brutto/1.19)
"connection_fee_brutto": -192 // -192 € einmalige Auszahlung an den Kunden
}
/* Aktionsguthaben VP | 216 EUR Aktionsguthaben VP (12 Monate gültig) */
{
"discount_euro_brutto": 0,
"discount_percent": 0,
"discount_months": 0, // Aktionsguthaben kostet dem Händler Geld (connection_fee_brutto/1.19)
"connection_fee_brutto": -216 // -216 € Einmalguthaben für den Kunden
}
/* Aktionsguthaben VP | 24 EUR Aktionsguthaben VP (12 Monate gültig) */
{
"discount_euro_brutto": 0,
"discount_percent": 0,
"discount_months": 0,
"provision_netto": -20, // Aktionsguthaben kostet dem Händler Geld (connection_fee_brutto/1.19)
"connection_fee_brutto": -24 // -24 € Einmalguthaben für den Kunden
}
/* Aktionsguthaben VP | 240 EUR Aktionsguthaben VP (12 Monate gültig) */
{
"discount_euro_brutto": 0,
"discount_percent": 0,
"discount_months": 0,
"provision_netto": -202, // Aktionsguthaben kostet dem Händler Geld (connection_fee_brutto/1.19)
"connection_fee_brutto": -240 // -240 € Einmalguthaben für den Kunden
}
/* A4169522 mit 80 GB (5G) und 50 Mbit/s / 19,99 EUR Anschlusspreis / Aktion: 24x5 EUR Rabatt auf Monatsgrundpreis / 40 EUR Sonderbonus */
{
"discount_euro_brutto": -5, // −5 € fixer Monatsrabatt (24-mal)
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 24, // Rabattdauer 24 Monate
"provision_netto": 40, // +40 € Sondervergütung für den Händler
"connection_fee_brutto": -19.99 // Kunde bekommt 19,99 € Anschlusspreis
}
/* A4169540 mit 100 GB (5G) und 50 Mbit/s / 0 EUR Anschlusspreis / 205 EUR Sondervergütung */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // kein Rabatt ⇒ 0
"provision_netto": 205, // +205 € Sondervergütung an den Händler
"connection_fee_brutto": 0 // 0 € ⇒ Anschlusspreis frei
}
/* A4169549 mit 40 GB (5G) und 50 Mbit/s / 0 EUR Anschlusspreis / Aktion: 24x5 EUR Rabatt auf Monatsgrundpreis / 15 EUR Vergütungsverzicht */
{
"discount_euro_brutto": -5, // −5 € fixer Monatsrabatt (24-mal)
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 24, // Rabatt gilt 24 Monate
"provision_netto": -15, // −15 €: Händler verzichtet auf Provision
"connection_fee_brutto": 0 // Anschlusspreis frei
}
/* A4169564 mit 70 GB (5G) und 50 Mbit/s / Laufzeit 1 Monat / 0 EUR Anschlusspreis / 30 EUR Sondervergütung */
{
"discount_euro_brutto": 0, // kein fixer Euro-Rabatt
"discount_percent": 0, // kein Prozent-Rabatt
"discount_months": 0, // kein Rabatt (1-Monats-Tarif, aber ohne Rabatt)
"provision_netto": 30, // +30 € Sondervergütung an den Händler
"connection_fee_brutto": 0 // 0 € Anschlusspreis
}
-----
Teil 3 - Prüfung:
""" + f"{name}"
expected_keys = [
"discount_euro_brutto",
"discount_percent",
"discount_months",
"provision_netto",
"connection_fee_brutto",
]
last_response = None
# GEÄNDERT: Schleife für bis zu 10 Versuche, um eine konsistente Antwort zu erhalten
for attempt in range(1, 11):
logging.info(f"-> GPT-Versuch {attempt}/10 für '{name}'...")
try:
raw_response = gpt_manager.chat(prompt, model="gpt-4.1")
# Bereinige und parse die JSON-Antwort
if raw_response.strip().startswith("```"):
cleaned_response = re.sub(r"```[\w]*", "", raw_response).strip()
else:
cleaned_response = raw_response
data = json.loads(cleaned_response)
# Prüfe, ob die Struktur der Antwort korrekt ist
if isinstance(data, dict) and all(key in data for key in expected_keys):
# Prüfe, ob die Antwort mit der letzten übereinstimmt
if data == last_response:
logging.info(f"-> Konsistente Antwort für '{name}' in Versuch {attempt} erhalten. Daten sind gültig.")
return data
else:
# Speichere die erste gültige Antwort und fordere eine zweite zur Bestätigung an
last_response = data
logging.warning(f"-> Gültige, aber noch nicht bestätigte Antwort in Versuch {attempt} für '{name}'. Nächster Versuch zur Verifizierung.")
else:
logging.warning(f"-> Ungültige Datenstruktur in Versuch {attempt} für '{name}'.")
last_response = None # Setze zurück, da die Kette unterbrochen ist
except Exception as e:
logging.error(f"-> Fehler in Versuch {attempt} für '{name}': {e}")
last_response = None # Setze bei Fehler zurück
logging.error(f"-> Konnte nach 10 Versuchen keine zwei aufeinanderfolgenden, identischen Antworten für '{name}' erhalten.")
return None
def sync_names_to_aiprice(session: Session):
"""PROZESS 1: Synchronisiert eindeutige Namen in die aiprice_aipr Tabelle."""
logging.info("Starte Prozess 1: Synchronisiere Namen.")
# Lade existierende Keys, um Duplikate zu vermeiden
existing_keys = {key for key, in session.query(AipriceAipr.key_aipr)}
# Schlüsselwörter, die für den Import berücksichtigt werden sollen
include_keywords = [
"%Sonderbonus%",
"%Vergütungsverzicht%",
"%Sondervergütung%",
"%Cashback%",
"%Vergütungverzicht%",
"%Aktionsguthaben%",
"%Anschlusspreis%",
"%Monatsgrundpreis%",
]
# Erstelle eine Liste von 'like'-Bedingungen für die Filterung
deal_conditions = [DealDeal.name_deal.like(keyword) for keyword in include_keywords]
option_conditions = [OptionOpti.name_opti.like(keyword) for keyword in include_keywords]
# Lade eindeutige Namen aus den Quelltabellen und wende die Einschlussfilter an
deals = session.query(DealDeal.name_deal).distinct().filter(
DealDeal.name_deal != "",
or_(*deal_conditions)
).all()
options = session.query(OptionOpti.name_opti).distinct().filter(
OptionOpti.price_opti == 0,
OptionOpti.name_opti != "",
or_(*option_conditions)
).all()
# Kombiniere und erstelle neue Einträge
new_entries = []
for name, category in [(d[0], 'deal') for d in deals] + [(o[0], 'opti') for o in options]:
if name not in existing_keys:
new_entries.append(AipriceAipr(key_aipr=name, category_aipr=category))
existing_keys.add(name) # Verhindert doppeltes Hinzufügen im selben Lauf
if new_entries:
session.add_all(new_entries)
session.commit()
logging.info(f"{len(new_entries)} neue Einträge gespeichert.")
else:
logging.info("Keine neuen Einträge zum Synchronisieren gefunden.")
logging.info("Prozess 1 abgeschlossen.")
def enrich_aiprice_with_gpt(session: Session):
"""PROZESS 2: Reichert Einträge ohne response_aipr sofort einzeln an."""
logging.info("Starte Prozess 2: Reichere Daten mit GPT an.")
gpt_manager = OpenAiManager()
# Verarbeite nur Einträge, bei denen die Antwort noch fehlt
items_to_process = session.query(AipriceAipr).filter(AipriceAipr.response_aipr.is_(None)).all()
if not items_to_process:
logging.info("Keine Einträge zur Anreicherung gefunden.")
return
logging.info(f"{len(items_to_process)} Einträge werden verarbeitet.")
for item in items_to_process:
validated_data = get_validated_response(gpt_manager, item.key_aipr)
# Speichere sofort, wenn die Daten gültig sind
if validated_data:
item.response_aipr = validated_data
try:
session.commit()
logging.info(f"Eintrag für '{item.key_aipr}' erfolgreich gespeichert.")
except Exception as e:
logging.error(f"Fehler beim Speichern von '{item.key_aipr}': {e}")
session.rollback()
logging.info("Prozess 2 abgeschlossen.")
# --- Hauptausführung ---
if __name__ == "__main__":
logging.info("=== Starte kombinierte Ausführung: sync & enrich ===")
db_session = MysqlManager().getSession()
sync_names_to_aiprice(db_session)
enrich_aiprice_with_gpt(db_session)
import sys
sys.path.append("..")
import logging
from sqlalchemy import text
from manager.MysqlManager import MysqlManager
# Logging configuration as in your template for clear status messages.
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s: %(message)s"
)
# List of all static SQL update commands to be executed.
# The condition "and provision1_opti = 0" ensures that each command
# is executed successfully only once.
sql_updates = [
# Category 1: Discounts on the connection fee
'update option_opti set provision1_opti = -8 where providercode_opti = "O3150922" and provision1_opti = 0;',
'update option_opti set provision1_opti = -33.61 where providercode_opti = "O3150921" and provision1_opti = 0;',
# Category 2: Promotional credit
'update option_opti set provision1_opti = -20.17 where providercode_opti = "O3120740" and provision1_opti = 0;',
'update option_opti set provision1_opti = -20.17 where providercode_opti = "O3120741" and provision1_opti = 0;',
'update option_opti set provision1_opti = -40.34 where providercode_opti = "O3120743" and provision1_opti = 0;',
'update option_opti set provision1_opti = -40.34 where providercode_opti = "O3120744" and provision1_opti = 0;',
'update option_opti set provision1_opti = -50.42 where providercode_opti = "O3132971" and provision1_opti = 0;',
'update option_opti set provision1_opti = -50.42 where providercode_opti = "O3132972" and provision1_opti = 0;',
'update option_opti set provision1_opti = -60.50 where providercode_opti = "O3120748" and provision1_opti = 0;',
'update option_opti set provision1_opti = -60.50 where providercode_opti = "O3120749" and provision1_opti = 0;',
'update option_opti set provision1_opti = -80.67 where providercode_opti = "O3120753" and provision1_opti = 0;',
'update option_opti set provision1_opti = -80.67 where providercode_opti = "O3120754" and provision1_opti = 0;',
'update option_opti set provision1_opti = -100.84 where providercode_opti = "O3120756" and provision1_opti = 0;',
'update option_opti set provision1_opti = -100.84 where providercode_opti = "O3120757" and provision1_opti = 0;',
'update option_opti set provision1_opti = -121.01 where providercode_opti = "O3132974" and provision1_opti = 0;',
'update option_opti set provision1_opti = -121.01 where providercode_opti = "O3132975" and provision1_opti = 0;',
'update option_opti set provision1_opti = -141.18 where providercode_opti = "O3132977" and provision1_opti = 0;',
'update option_opti set provision1_opti = -141.18 where providercode_opti = "O3132978" and provision1_opti = 0;',
'update option_opti set provision1_opti = -161.34 where providercode_opti = "O3132980" and provision1_opti = 0;',
'update option_opti set provision1_opti = -161.34 where providercode_opti = "O3132981" and provision1_opti = 0;',
'update option_opti set provision1_opti = -181.51 where providercode_opti = "O3132983" and provision1_opti = 0;',
'update option_opti set provision1_opti = -181.51 where providercode_opti = "O3132984" and provision1_opti = 0;',
'update option_opti set provision1_opti = -201.68 where providercode_opti = "O3120759" and provision1_opti = 0;',
'update option_opti set provision1_opti = -201.68 where providercode_opti = "O3120760" and provision1_opti = 0;',
# Category 3: Tariff discounts
'UPDATE option_opti SET provision1_opti = -20 WHERE providercode_opti = "O3357017" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -40 WHERE providercode_opti = "O3357018" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -40 WHERE providercode_opti = "O3708586" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -40 WHERE providercode_opti = "O3708556" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -60 WHERE providercode_opti = "O3357019" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -80 WHERE providercode_opti = "O3357020" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -100 WHERE providercode_opti = "O3708583" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -100 WHERE providercode_opti = "O3708553" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -100 WHERE providercode_opti = "O3357021" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -120 WHERE providercode_opti = "O3357022" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -140 WHERE providercode_opti = "O3357023" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -140 WHERE providercode_opti = "O3708580" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -140 WHERE providercode_opti = "O3708550" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -160 WHERE providercode_opti = "O3357024" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -180 WHERE providercode_opti = "O3357025" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -200 WHERE providercode_opti = "O3708577" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -200 WHERE providercode_opti = "O3357026" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -200 WHERE providercode_opti = "O3708547" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -240 WHERE providercode_opti = "O3708574" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -240 WHERE providercode_opti = "O3708544" AND provision1_opti = 0;',
# Category 4: Cashback
'UPDATE option_opti SET provision1_opti = -35 WHERE providercode_opti = "O3501314" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -45 WHERE providercode_opti = "O3501311" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -75 WHERE providercode_opti = "O3501308" AND provision1_opti = 0;',
'UPDATE option_opti SET provision1_opti = -90 WHERE providercode_opti = "O3501305" AND provision1_opti = 0;'
]
# The "mysql" variable establishes the connection to the database.
mysql = MysqlManager()
# The "session" variable retrieves the SQLAlchemy session for all database operations.
session = mysql.getSession()
logging.info("Starting static provision updates...")
updated_count = 0
total_count = len(sql_updates)
try:
# Loop through all SQL commands and execute them one by one.
for i, query in enumerate(sql_updates):
# session.execute() with text() is the standard way to safely execute raw SQL.
result = session.execute(text(query))
# result.rowcount indicates how many rows were affected by the UPDATE.
# This is useful for logging to see if a change has occurred.
if result.rowcount > 0:
updated_count += result.rowcount
logging.info(f"Query {i+1}/{total_count}: {result.rowcount} row(s) updated.")
# If all commands have run without error, the changes are committed.
session.commit()
logging.info(f"All {total_count} updates processed successfully. A total of {updated_count} rows were changed.")
except Exception as e:
# In case of an error, the entire transaction is rolled back to avoid inconsistent data.
logging.error(f"An error occurred: {e}")
logging.error("The transaction is being rolled back.")
session.rollback()
finally:
# The session is closed in any case to release the connection.
session.close()
logging.info("Database session closed.")
\ No newline at end of file
...@@ -4,7 +4,7 @@ MYSQL_PASSWORD = "floz09sx3dTyx144gy" ...@@ -4,7 +4,7 @@ MYSQL_PASSWORD = "floz09sx3dTyx144gy"
MYSQL_DATABASE = "itmax_tarifs" MYSQL_DATABASE = "itmax_tarifs"
MYSQL_PORT = 3306 MYSQL_PORT = 3306
USE_SSH_TUNNEL = False USE_SSH_TUNNEL = True
SSH_HOST = "jumphost.bugsmasher.online" SSH_HOST = "jumphost.bugsmasher.online"
SSH_PORT = 22 SSH_PORT = 22
SSH_USERNAME = "root" SSH_USERNAME = "root"
......
...@@ -10,5 +10,5 @@ ...@@ -10,5 +10,5 @@
# STEP 4 - GENERATE TARIF-DETAILS WITH GPT # STEP 4 - GENERATE TARIF-DETAILS WITH GPT
0 5 * * * /maui/cron.sh calculateTarifDetailsWithGpt.py 0 5 * * * /maui/cron.sh calculateTarifDetailsWithGpt.py
# STEP 5 - STATIC LINK OPTION PRICES WITH GPT # STEP 5 - GENERATE AI PRICES WITH GPT
30 5 * * * /maui/cron.sh setStaticOptionPrices.py 30 5 * * * /maui/cron.sh calculateAiPrices.py
from sqlalchemy import Column, Integer, String, DateTime, func
from sqlalchemy.dialects.mysql import JSON
from models._system import Base
class AipriceAipr(Base):
__tablename__ = 'aiprice_aipr'
__table_args__ = {'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}
id_aipr = Column(
Integer,
primary_key=True,
autoincrement=True
)
category_aipr = Column(
String(255),
nullable=False
)
key_aipr = Column(
String(255),
nullable=False,
unique=True
)
response_aipr = Column(
JSON
)
created_aipr = Column(
DateTime,
nullable=False,
server_default=func.now()
)
...@@ -8,6 +8,7 @@ https://s3.eu-central-1.amazonaws.com/monosnap.bugsmasher.online/marcoschmiedel/ ...@@ -8,6 +8,7 @@ https://s3.eu-central-1.amazonaws.com/monosnap.bugsmasher.online/marcoschmiedel/
https://s3.eu-central-1.amazonaws.com/monosnap.bugsmasher.online/marcoschmiedel/2025-05-13+API-Tutorial.mp4 https://s3.eu-central-1.amazonaws.com/monosnap.bugsmasher.online/marcoschmiedel/2025-05-13+API-Tutorial.mp4
https://s3.eu-central-1.amazonaws.com/monosnap.bugsmasher.online/marcoschmiedel/2024-05-13.m4v https://s3.eu-central-1.amazonaws.com/monosnap.bugsmasher.online/marcoschmiedel/2024-05-13.m4v
https://s3.eu-central-1.amazonaws.com/monosnap.bugsmasher.online/marcoschmiedel/2025-06-03.m4v https://s3.eu-central-1.amazonaws.com/monosnap.bugsmasher.online/marcoschmiedel/2025-06-03.m4v
https://s3.eu-central-1.amazonaws.com/monosnap.bugsmasher.online/marcoschmiedel/2025-06-23.m4v
## JupyterLab ## JupyterLab
......
...@@ -8,6 +8,7 @@ from manager.MysqlManager import MysqlManager ...@@ -8,6 +8,7 @@ from manager.MysqlManager import MysqlManager
from models.base_base import BaseBase from models.base_base import BaseBase
from models.deal_deal import DealDeal from models.deal_deal import DealDeal
from models.option_opti import OptionOpti from models.option_opti import OptionOpti
from models.aiprice_aipr import AipriceAipr
# The blueprint instance is created with the module name stripped of dots so # The blueprint instance is created with the module name stripped of dots so
# registering it never triggers a ValueError. # registering it never triggers a ValueError.
...@@ -35,14 +36,36 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non ...@@ -35,14 +36,36 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non
.all() .all()
) )
# This comprehension converts the SQLAlchemy deal objects into plain Python dictionaries ready for JSON serialization. # This query loads every option that belongs to the current base object.
deals: List[Dict[str, Any]] = [ opti_records: List[OptionOpti] = (
{ session.query(OptionOpti)
.filter_by(base_opti=base_record.id_base)
.all()
)
# This set collects all deal and option names to fetch their corresponding AI prices in a single query.
names_to_lookup = {d.name_deal for d in deal_records if d.name_deal} | {o.name_opti for o in opti_records if o.name_opti}
# This dictionary maps a name (key_aipr) to its AI-identified price JSON object.
aiprice_map: Dict[str, Any] = {}
if names_to_lookup:
aiprice_results = session.query(AipriceAipr).filter(AipriceAipr.key_aipr.in_(names_to_lookup)).all()
aiprice_map = {r.key_aipr: r.response_aipr for r in aiprice_results}
# This expression copies the JSON details column or uses an empty dictionary when the column is NULL.
details_data: Dict[str, Any] = (
base_record.details_base.copy()
if base_record.details_base else {}
)
# This list will hold the processed deals.
deals: List[Dict[str, Any]] = []
for d in deal_records:
deal_dict = {
"id": d.id_deal, "id": d.id_deal,
"providercode": d.providercode_deal, "providercode": d.providercode_deal,
"name": d.name_deal, "name": d.name_deal,
"alias": d.alias_deal, "alias": d.alias_deal,
"price": float(d.price_deal),
"starts": d.starts_deal.isoformat() if d.starts_deal else None, "starts": d.starts_deal.isoformat() if d.starts_deal else None,
"stops": d.stops_deal.isoformat() if d.stops_deal else None, "stops": d.stops_deal.isoformat() if d.stops_deal else None,
"provision1": float(d.provision1_deal), "provision1": float(d.provision1_deal),
...@@ -52,15 +75,40 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non ...@@ -52,15 +75,40 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non
"created": d.created_deal.isoformat() if d.created_deal else None, "created": d.created_deal.isoformat() if d.created_deal else None,
"updated": d.updated_deal.isoformat() if d.updated_deal else None, "updated": d.updated_deal.isoformat() if d.updated_deal else None,
} }
for d in deal_records
]
# This query loads every option that belongs to the current base object. ai_params = aiprice_map.get(d.name_deal)
opti_records: List[OptionOpti] = ( if ai_params:
session.query(OptionOpti) processed_params = ai_params.copy()
.filter_by(base_opti=base_record.id_base)
.all() # KORRIGIERT: Prüft auf < 0, da Rabatte als negative Prozentzahlen von der KI geliefert werden.
) discount_percent = processed_params.pop('discount_percent', 0) or 0
if discount_percent < 0:
base_monthly_brutto = details_data.get('pricing_monthly_initial_eur_brutto', 0) or 0
processed_params['discount_euro_brutto'] = round((base_monthly_brutto / 100) * discount_percent, 4)
# If connection_fee_brutto is null, set to 0
if processed_params.get('connection_fee_brutto') is None:
processed_params['connection_fee_brutto'] = 0
# Calculate connection_fee_netto
if processed_params.get('connection_fee_brutto') is not None:
fee_brutto = processed_params['connection_fee_brutto']
processed_params['connection_fee_netto'] = round(fee_brutto / 1.19, 4)
# Calculate discount_euro_netto from discount_euro_brutto
if processed_params.get('discount_euro_brutto') is not None:
discount_brutto = processed_params['discount_euro_brutto']
processed_params['discount_euro_netto'] = round(discount_brutto / 1.19, 4)
# Rename provision_netto to provision2_ai_check
if 'provision_netto' in processed_params:
processed_params['provision2_ai_check'] = processed_params.pop('provision_netto')
deal_dict['ai_parameters'] = processed_params
else:
deal_dict['ai_parameters'] = None
deals.append(deal_dict)
# The two collections below hold option nodes and category nodes so we can easily assemble the option hierarchy. # The two collections below hold option nodes and category nodes so we can easily assemble the option hierarchy.
option_nodes: List[Tuple[Dict[str, Any], str | None]] = [] option_nodes: List[Tuple[Dict[str, Any], str | None]] = []
...@@ -68,14 +116,11 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non ...@@ -68,14 +116,11 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non
# This loop converts each option database record into a node dictionary and remembers its parent relationship. # This loop converts each option database record into a node dictionary and remembers its parent relationship.
for o in opti_records: for o in opti_records:
# The node dictionary contains all option attributes plus a list for potential child options.
node: Dict[str, Any] = { node: Dict[str, Any] = {
"id": o.id_opti, "id": o.id_opti,
"providercode": o.providercode_opti, "providercode": o.providercode_opti,
"name": o.name_opti, "name": o.name_opti,
"alias": o.alias_opti, "alias": o.alias_opti,
"price": float(o.price_opti),
"starts": o.starts_opti.isoformat() if o.starts_opti else None, "starts": o.starts_opti.isoformat() if o.starts_opti else None,
"stops": o.stops_opti.isoformat() if o.stops_opti else None, "stops": o.stops_opti.isoformat() if o.stops_opti else None,
"provision1": float(o.provision1_opti), "provision1": float(o.provision1_opti),
...@@ -87,6 +132,41 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non ...@@ -87,6 +132,41 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non
"items": [], "items": [],
} }
ai_params = aiprice_map.get(o.name_opti)
if ai_params:
processed_params = ai_params.copy()
# Rename provision_netto to provision1_ai_check
if 'provision_netto' in processed_params:
processed_params['provision1_ai_check'] = processed_params.pop('provision_netto')
# KORRIGIERT: Prüft auf < 0, da Rabatte als negative Prozentzahlen von der KI geliefert werden.
discount_percent = processed_params.pop('discount_percent', 0) or 0
if discount_percent < 0:
base_monthly_brutto = details_data.get('pricing_monthly_initial_eur_brutto', 0) or 0
processed_params['discount_euro_brutto'] = round((base_monthly_brutto / 100) * discount_percent, 4)
# If connection_fee_brutto is 0, use negative base value
if processed_params.get('connection_fee_brutto') == 0:
base_connection_fee = details_data.get('pricing_connection_fee_eur_brutto')
if base_connection_fee is not None:
processed_params['connection_fee_brutto'] = base_connection_fee * -1
# Calculate connection_fee_netto
if processed_params.get('connection_fee_brutto') is not None:
fee_brutto = processed_params['connection_fee_brutto']
processed_params['connection_fee_netto'] = round(fee_brutto / 1.19, 4)
# Calculate discount_euro_netto from discount_euro_brutto
if processed_params.get('discount_euro_brutto') is not None:
discount_brutto = processed_params['discount_euro_brutto']
processed_params['discount_euro_netto'] = round(discount_brutto / 1.19, 4)
node['ai_parameters'] = processed_params
else:
# If no AI parameters are found, use the original price field.
node['price'] = float(o.price_opti)
# This conditional branch stores nodes whose provider code begins with “G” so children can later be attached to them. # This conditional branch stores nodes whose provider code begins with “G” so children can later be attached to them.
if o.providercode_opti.startswith("G"): if o.providercode_opti.startswith("G"):
category_nodes[o.providercode_opti] = node category_nodes[o.providercode_opti] = node
...@@ -132,12 +212,6 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non ...@@ -132,12 +212,6 @@ def _build_base_response(session: Session, base_id: int) -> Dict[str, Any] | Non
"updated": base_record.updated_base.isoformat() if base_record.updated_base else None, "updated": base_record.updated_base.isoformat() if base_record.updated_base else None,
} }
# This expression copies the JSON details column or uses an empty dictionary when the column is NULL.
details_data: Dict[str, Any] = (
base_record.details_base.copy()
if base_record.details_base else {}
)
# This line removes the internal tariff_name helper key so it can be returned as a dedicated attribute. # This line removes the internal tariff_name helper key so it can be returned as a dedicated attribute.
ai_identified_name = details_data.pop("tariff_name", None) ai_identified_name = details_data.pop("tariff_name", None)
......
No preview for this file type
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment