diff --git a/csharp/App/Backend/Controller.cs b/csharp/App/Backend/Controller.cs index 9b027c78d..c6ebfbe72 100644 --- a/csharp/App/Backend/Controller.cs +++ b/csharp/App/Backend/Controller.cs @@ -2864,4 +2864,24 @@ public class Controller : ControllerBase } } + [HttpGet(nameof(GetChecklistSummary))] + public ActionResult> GetChecklistSummary(Token authToken) + { + var user = Db.GetSession(authToken)?.User; + if (user is null || user.UserType != 2) return Unauthorized(); + + var summaries = Db.ChecklistItems + .ToList() + .GroupBy(c => c.InstallationId) + .Select(g => new + { + installationId = g.Key, + done = g.Count(c => c.Status == (Int32)ChecklistStatus.Done), + total = g.Count() + }) + .ToList(); + + return Ok(summaries); + } + } diff --git a/csharp/App/Backend/DataTypes/ChecklistStepDefinitions.cs b/csharp/App/Backend/DataTypes/ChecklistStepDefinitions.cs index feeb8c432..794ef0481 100644 --- a/csharp/App/Backend/DataTypes/ChecklistStepDefinitions.cs +++ b/csharp/App/Backend/DataTypes/ChecklistStepDefinitions.cs @@ -15,30 +15,30 @@ public static class ChecklistStepDefinitions new( 5, "Information tab filled out (customer, serials, VPN)", """ [ - {"text":"Customer information (email, address)","checked":false}, - {"text":"Installation information (external EMS, grid provider, data collection)","checked":false}, - {"text":"Battery serial number","checked":false}, - {"text":"Inverter serial number","checked":false}, - {"text":"Data logger serial number","checked":false}, - {"text":"VPN details","checked":false} + {"text":"checklistStep5Sub1","checked":false}, + {"text":"checklistStep5Sub2","checked":false}, + {"text":"checklistStep5Sub3","checked":false}, + {"text":"checklistStep5Sub4","checked":false}, + {"text":"checklistStep5Sub5","checked":false}, + {"text":"checklistStep5Sub6","checked":false} ] """), new( 6, "Installation configured and tested electrically / hardware-wise at Vebo", """ [ - {"text":"Inverter firmware and configuration verified","checked":false}, - {"text":"Battery firmware and configuration verified","checked":false}, - {"text":"Internet for gateway configured","checked":false}, - {"text":"Communication cable between gateway and inverter correct","checked":false} + {"text":"checklistStep6Sub1","checked":false}, + {"text":"checklistStep6Sub2","checked":false}, + {"text":"checklistStep6Sub3","checked":false}, + {"text":"checklistStep6Sub4","checked":false} ] """), new( 7, "Installation tested software-wise at Vebo", """ [ - {"text":"S3 bucket number and key credentials copied from Information tab into config.json","checked":false}, - {"text":"Product ID configured in config.json","checked":false}, - {"text":"USB ID configured in config.json","checked":false}, - {"text":"Inverter data reading from inverter tested","checked":false} + {"text":"checklistStep7Sub1","checked":false}, + {"text":"checklistStep7Sub2","checked":false}, + {"text":"checklistStep7Sub3","checked":false}, + {"text":"checklistStep7Sub4","checked":false} ] """), new( 8, "Installation delivered to customer site", NoSubtasks), diff --git a/csharp/App/Backend/Database/Db.cs b/csharp/App/Backend/Database/Db.cs index 5735b88a8..2271d074e 100644 --- a/csharp/App/Backend/Database/Db.cs +++ b/csharp/App/Backend/Database/Db.cs @@ -109,6 +109,33 @@ public static partial class Db Connection.Execute("UPDATE User SET Name = 'inesco energy Master Admin' WHERE Name = 'InnovEnergy Master Admin'"); Connection.Execute("UPDATE User SET Name = 'inesco energy Master Admin' WHERE Name = 'inesco Energy Master Admin'"); + // One-time migration: rewrite early-seeded English subtask text to translation keys so the + // frontend can localize them. Idempotent: rows already containing keys match nothing. + var subtaskTextToKey = new (String Old, String Key)[] + { + ("Customer information (email, address)", "checklistStep5Sub1"), + ("Installation information (external EMS, grid provider, data collection)", "checklistStep5Sub2"), + ("Installation information (external EMS, network provider, data collection)", "checklistStep5Sub2"), + ("Battery serial number", "checklistStep5Sub3"), + ("Inverter serial number", "checklistStep5Sub4"), + ("Data logger serial number", "checklistStep5Sub5"), + ("VPN details", "checklistStep5Sub6"), + ("Inverter firmware and configuration verified", "checklistStep6Sub1"), + ("Battery firmware and configuration verified", "checklistStep6Sub2"), + ("Internet for gateway configured", "checklistStep6Sub3"), + ("Communication cable between gateway and inverter correct", "checklistStep6Sub4"), + ("S3 bucket number and key credentials copied from Information tab into config.json","checklistStep7Sub1"), + ("Product ID configured in config.json", "checklistStep7Sub2"), + ("USB ID configured in config.json", "checklistStep7Sub3"), + ("Inverter data reading from inverter tested", "checklistStep7Sub4") + }; + foreach (var (oldText, key) in subtaskTextToKey) + { + Connection.Execute( + "UPDATE ChecklistItem SET Subtasks = REPLACE(Subtasks, ?, ?) WHERE Subtasks LIKE ?", + $"\"{oldText}\"", $"\"{key}\"", $"%\"{oldText}\"%"); + } + //UpdateKeys(); CleanupSessions().SupressAwaitWarning(); DeleteSnapshots().SupressAwaitWarning(); diff --git a/typescript/frontend-marios2/src/content/dashboards/Checklist/ChecklistStepRow.tsx b/typescript/frontend-marios2/src/content/dashboards/Checklist/ChecklistStepRow.tsx index a7225224d..08620c719 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Checklist/ChecklistStepRow.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Checklist/ChecklistStepRow.tsx @@ -144,7 +144,12 @@ function ChecklistStepRow({ item, adminUsers, onUpdate, onNotify }: Props) { - {item.stepTitle} + + {intl.formatMessage({ + id: `checklistStep${item.stepNumber}`, + defaultMessage: item.stepTitle + })} + {subtasks.length > 0 && ( <> 0 && subtasksOpen && ( - + {subtasks.map((s, i) => ( handleSubtaskToggle(i)} /> } - label={{s.text}} - sx={{ display: 'block', ml: 0 }} + label={ + + {intl.formatMessage({ id: s.text, defaultMessage: s.text })} + + } + sx={{ ml: 0 }} /> ))} diff --git a/typescript/frontend-marios2/src/content/dashboards/Checklist/SetupProgress.tsx b/typescript/frontend-marios2/src/content/dashboards/Checklist/SetupProgress.tsx new file mode 100644 index 000000000..f53cc00eb --- /dev/null +++ b/typescript/frontend-marios2/src/content/dashboards/Checklist/SetupProgress.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { Box, LinearProgress, Tooltip, Typography } from '@mui/material'; +import { FormattedMessage, useIntl } from 'react-intl'; + +interface Props { + done: number | null; + total: number | null; +} + +function phaseId(done: number, total: number): string { + if (total === 0) return 'checklistPhaseEmpty'; + if (done >= total) return 'checklistPhaseComplete'; + if (done <= 5) return 'checklistPhasePreparation'; + if (done <= 12) return 'checklistPhaseOnSite'; + return 'checklistPhaseHandover'; +} + +function SetupProgress({ done, total }: Props) { + const intl = useIntl(); + + if (done === null || total === null || total === 0) { + return ( + + -- + + ); + } + + const percent = Math.round((done / total) * 100); + const color = percent >= 100 ? 'success' : percent > 0 ? 'warning' : 'inherit'; + + const tooltip = intl.formatMessage({ + id: phaseId(done, total), + defaultMessage: 'Progress' + }); + + return ( + + + + + + + {done}/{total} + + + + ); +} + +export default SetupProgress; diff --git a/typescript/frontend-marios2/src/content/dashboards/Installations/FlatInstallationView.tsx b/typescript/frontend-marios2/src/content/dashboards/Installations/FlatInstallationView.tsx index 20d5b621a..c31a40c23 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Installations/FlatInstallationView.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Installations/FlatInstallationView.tsx @@ -27,6 +27,14 @@ import { useLocation, useNavigate } from 'react-router-dom'; import routes from '../../../Resources/routes.json'; import { ProductIdContext } from '../../../contexts/ProductIdContextProvider'; import SearchTwoToneIcon from '@mui/icons-material/SearchTwoTone'; +import { UserContext } from 'src/contexts/userContext'; +import { UserType } from 'src/interfaces/UserTypes'; +import axiosConfig from 'src/Resources/axiosConfig'; +import { + CHECKLIST_ENABLED_PRODUCTS, + ChecklistSummary +} from 'src/interfaces/ChecklistTypes'; +import SetupProgress from '../Checklist/SetupProgress'; interface FlatInstallationViewProps { installations: I_Installation[]; @@ -46,6 +54,28 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { const [searchTerm, setSearchTerm] = useState(''); const [sortByStatus, setSortByStatus] = useState('All Installations'); const [sortByAction, setSortByAction] = useState('All Installations'); + const { currentUser } = useContext(UserContext); + const showChecklistColumn = + currentUser?.userType === UserType.admin && + CHECKLIST_ENABLED_PRODUCTS.has(product ?? -1); + const [progressMap, setProgressMap] = useState>( + new Map() + ); + + useEffect(() => { + if (!showChecklistColumn) return; + axiosConfig + .get('/GetChecklistSummary') + .then((res) => { + if (!Array.isArray(res.data)) return; + const map = new Map(); + res.data.forEach((s: ChecklistSummary) => { + map.set(s.installationId, s); + }); + setProgressMap(map); + }) + .catch(() => setProgressMap(new Map())); + }, [showChecklistColumn]); const HoverableTableRow = styled(TableRow)(({ theme }) => ({ cursor: 'pointer', @@ -315,6 +345,14 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { + {showChecklistColumn && ( + + + + )} @@ -461,6 +499,19 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { )} + {showChecklistColumn && ( + + {(() => { + const summary = progressMap.get(installation.id); + return ( + + ); + })()} + + )} ); })} diff --git a/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/FlatInstallationView.tsx b/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/FlatInstallationView.tsx index fe4139668..14b831484 100644 --- a/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/FlatInstallationView.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/FlatInstallationView.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState } from 'react'; +import React, { useContext, useEffect, useMemo, useState } from 'react'; import { Card, CircularProgress, @@ -20,6 +20,14 @@ import routes from '../../../Resources/routes.json'; import CancelIcon from '@mui/icons-material/Cancel'; import BuildIcon from '@mui/icons-material/Build'; import { getDeviceTypeName } from '../Information/installationSetupUtils'; +import { UserContext } from 'src/contexts/userContext'; +import { UserType } from 'src/interfaces/UserTypes'; +import axiosConfig from 'src/Resources/axiosConfig'; +import { + CHECKLIST_ENABLED_PRODUCTS, + ChecklistSummary +} from 'src/interfaces/ChecklistTypes'; +import SetupProgress from '../Checklist/SetupProgress'; interface FlatInstallationViewProps { installations: I_Installation[]; @@ -32,6 +40,29 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { const currentLocation = useLocation(); const baseRoute = props.product === 5 ? routes.sodistorepro_installations : routes.sodiohome_installations; + const { currentUser } = useContext(UserContext); + const showChecklistColumn = + currentUser?.userType === UserType.admin && + CHECKLIST_ENABLED_PRODUCTS.has(props.product ?? -1); + const [progressMap, setProgressMap] = useState>( + new Map() + ); + + useEffect(() => { + if (!showChecklistColumn) return; + axiosConfig + .get('/GetChecklistSummary') + .then((res) => { + if (!Array.isArray(res.data)) return; + const map = new Map(); + res.data.forEach((s: ChecklistSummary) => { + map.set(s.installationId, s); + }); + setProgressMap(map); + }) + .catch(() => setProgressMap(new Map())); + }, [showChecklistColumn]); + const sortedInstallations = useMemo(() => { return [...props.installations].sort((a, b) => { // Data-collection-disabled installations sink below everything (even offline). @@ -118,6 +149,14 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { + {showChecklistColumn && ( + + + + )} @@ -282,6 +321,19 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { )} + {showChecklistColumn && ( + + {(() => { + const summary = progressMap.get(installation.id); + return ( + + ); + })()} + + )} ); })} diff --git a/typescript/frontend-marios2/src/interfaces/ChecklistTypes.tsx b/typescript/frontend-marios2/src/interfaces/ChecklistTypes.tsx index 7cc733128..a6c10246b 100644 --- a/typescript/frontend-marios2/src/interfaces/ChecklistTypes.tsx +++ b/typescript/frontend-marios2/src/interfaces/ChecklistTypes.tsx @@ -25,6 +25,12 @@ export type ChecklistItem = { export const CHECKLIST_ENABLED_PRODUCTS: ReadonlySet = new Set([2, 4, 5]); +export type ChecklistSummary = { + installationId: number; + done: number; + total: number; +}; + export function parseSubtasks(raw: string | null | undefined): ChecklistSubtask[] { if (!raw) return []; try { diff --git a/typescript/frontend-marios2/src/lang/de.json b/typescript/frontend-marios2/src/lang/de.json index dffa34395..9877e583e 100644 --- a/typescript/frontend-marios2/src/lang/de.json +++ b/typescript/frontend-marios2/src/lang/de.json @@ -712,5 +712,41 @@ "checklistCommentsPlaceholder": "Notizen, Kontaktinformationen, Beobachtungen…", "checklistEmailSent": "E-Mail an {name} gesendet", "checklistEmailFailed": "E-Mail-Versand fehlgeschlagen — bitte erneut versuchen", - "checklistSaveFailed": "Änderung konnte nicht gespeichert werden" + "checklistSaveFailed": "Änderung konnte nicht gespeichert werden", + "checklistStep1": "Auftrag erstellt, Kunden- und Partnerinformationen im CRM erfasst", + "checklistStep2": "Hardware bei Vebo zusammengebaut", + "checklistStep3": "Installation auf Monitor unter korrektem Produkt und Ordner erstellt", + "checklistStep4": "Gateway-SD-Karte konfiguriert, VPN und Gateway-Name registriert", + "checklistStep5": "Informations-Tab ausgefüllt (Kunde, Seriennummern, VPN)", + "checklistStep6": "Installation bei Vebo elektrisch/hardwareseitig konfiguriert und getestet", + "checklistStep7": "Installation bei Vebo softwareseitig getestet", + "checklistStep8": "Installation am Kundenstandort ausgeliefert", + "checklistStep9": "Installation ans Netz angeschlossen", + "checklistStep10": "Hardware vor Ort verifiziert", + "checklistStep11": "Software vor Ort verifiziert", + "checklistStep12": "Installation online auf Monitor", + "checklistStep13": "Kunde über Monitor-Konto und Reports informiert", + "checklistStep14": "Benutzerkonto mit richtigen Ordnern und Zugriffen erstellt", + "checklistStep15": "Kundennachverfolgung abgeschlossen, Feedback eingeholt", + "checklistStep16": "Weitere Anliegen werden über das Ticket-System verfolgt", + "checklistStep5Sub1": "Kundeninformationen (E-Mail, Adresse)", + "checklistStep5Sub2": "Installationsinformationen (externes EMS, Stromanbieter, Datenerfassung)", + "checklistStep5Sub3": "Batterie-Seriennummer", + "checklistStep5Sub4": "Wechselrichter-Seriennummer", + "checklistStep5Sub5": "Datenlogger-Seriennummer", + "checklistStep5Sub6": "VPN", + "checklistStep6Sub1": "Wechselrichter-Firmware und Konfiguration geprüft", + "checklistStep6Sub2": "Batterie-Firmware und Konfiguration geprüft", + "checklistStep6Sub3": "Internet für Gateway konfiguriert", + "checklistStep6Sub4": "Kommunikationskabel zwischen Gateway und Wechselrichter korrekt", + "checklistStep7Sub1": "S3-Bucket-Nummer und Schlüssel-Credentials aus Informations-Tab in config.json übernommen", + "checklistStep7Sub2": "Produkt-ID in config.json konfiguriert", + "checklistStep7Sub3": "USB-ID in config.json konfiguriert", + "checklistStep7Sub4": "Datenlesung vom Wechselrichter getestet", + "setupProgress": "Setup-Fortschritt", + "checklistPhaseEmpty": "Nicht gestartet", + "checklistPhasePreparation": "Vorbereitung", + "checklistPhaseOnSite": "Vor Ort", + "checklistPhaseHandover": "Kundenübergabe", + "checklistPhaseComplete": "Abgeschlossen" } \ No newline at end of file diff --git a/typescript/frontend-marios2/src/lang/en.json b/typescript/frontend-marios2/src/lang/en.json index 4fe5e7d2d..b15816902 100644 --- a/typescript/frontend-marios2/src/lang/en.json +++ b/typescript/frontend-marios2/src/lang/en.json @@ -460,5 +460,41 @@ "checklistCommentsPlaceholder": "Notes, contact info, observations…", "checklistEmailSent": "Email sent to {name}", "checklistEmailFailed": "Failed to send email — try again", - "checklistSaveFailed": "Failed to save change" + "checklistSaveFailed": "Failed to save change", + "checklistStep1": "Order created, customer and partner info recorded in CRM", + "checklistStep2": "Hardware assembled at Vebo", + "checklistStep3": "Installation created on Monitor under correct product and folder", + "checklistStep4": "Gateway SD card configured, VPN and gateway name registered", + "checklistStep5": "Information tab filled out (customer, serials, VPN)", + "checklistStep6": "Installation configured and tested electrically / hardware-wise at Vebo", + "checklistStep7": "Installation tested software-wise at Vebo", + "checklistStep8": "Installation delivered to customer site", + "checklistStep9": "Installation connected to grid", + "checklistStep10": "Hardware verified on site", + "checklistStep11": "Software verified on site", + "checklistStep12": "Installation online on Monitor", + "checklistStep13": "Customer informed about Monitor account and reports", + "checklistStep14": "User account created with correct folders and access", + "checklistStep15": "Customer follow-up completed, feedback collected", + "checklistStep16": "Further issues tracked via Ticket system", + "checklistStep5Sub1": "Customer information (email, address)", + "checklistStep5Sub2": "Installation information (external EMS, grid provider, data collection)", + "checklistStep5Sub3": "Battery serial number", + "checklistStep5Sub4": "Inverter serial number", + "checklistStep5Sub5": "Data logger serial number", + "checklistStep5Sub6": "VPN", + "checklistStep6Sub1": "Inverter firmware and configuration verified", + "checklistStep6Sub2": "Battery firmware and configuration verified", + "checklistStep6Sub3": "Internet for gateway configured", + "checklistStep6Sub4": "Communication cable between gateway and inverter correct", + "checklistStep7Sub1": "S3 bucket number and key credentials copied from Information tab into config.json", + "checklistStep7Sub2": "Product ID configured in config.json", + "checklistStep7Sub3": "USB ID configured in config.json", + "checklistStep7Sub4": "Inverter data reading from inverter tested", + "setupProgress": "Setup Progress", + "checklistPhaseEmpty": "Not started", + "checklistPhasePreparation": "Preparation", + "checklistPhaseOnSite": "On-site", + "checklistPhaseHandover": "Customer handover", + "checklistPhaseComplete": "Complete" } diff --git a/typescript/frontend-marios2/src/lang/fr.json b/typescript/frontend-marios2/src/lang/fr.json index 90fbd10b4..a8e3c19d3 100644 --- a/typescript/frontend-marios2/src/lang/fr.json +++ b/typescript/frontend-marios2/src/lang/fr.json @@ -712,5 +712,41 @@ "checklistCommentsPlaceholder": "Notes, coordonnées, observations…", "checklistEmailSent": "E-mail envoyé à {name}", "checklistEmailFailed": "Échec de l'envoi — veuillez réessayer", - "checklistSaveFailed": "Échec de l'enregistrement" + "checklistSaveFailed": "Échec de l'enregistrement", + "checklistStep1": "Commande créée, informations client et partenaire enregistrées dans le CRM", + "checklistStep2": "Matériel assemblé chez Vebo", + "checklistStep3": "Installation créée sur Monitor sous le bon produit et dossier", + "checklistStep4": "Carte SD du gateway configurée, VPN et nom du gateway enregistrés", + "checklistStep5": "Onglet Informations rempli (client, numéros de série, VPN)", + "checklistStep6": "Installation configurée et testée électriquement/matériel chez Vebo", + "checklistStep7": "Installation testée côté logiciel chez Vebo", + "checklistStep8": "Installation livrée sur le site du client", + "checklistStep9": "Installation raccordée au réseau", + "checklistStep10": "Matériel vérifié sur site", + "checklistStep11": "Logiciel vérifié sur site", + "checklistStep12": "Installation en ligne sur Monitor", + "checklistStep13": "Client informé du compte Monitor et des rapports", + "checklistStep14": "Compte utilisateur créé avec les dossiers et accès corrects", + "checklistStep15": "Suivi client effectué, retour recueilli", + "checklistStep16": "Problèmes ultérieurs suivis via le système de tickets", + "checklistStep5Sub1": "Informations client (e-mail, adresse)", + "checklistStep5Sub2": "Informations d'installation (EMS externe, fournisseur réseau, collecte de données)", + "checklistStep5Sub3": "Numéro de série de la batterie", + "checklistStep5Sub4": "Numéro de série de l'onduleur", + "checklistStep5Sub5": "Numéro de série de l'enregistreur de données", + "checklistStep5Sub6": "VPN", + "checklistStep6Sub1": "Firmware et configuration de l'onduleur vérifiés", + "checklistStep6Sub2": "Firmware et configuration de la batterie vérifiés", + "checklistStep6Sub3": "Internet pour le gateway configuré", + "checklistStep6Sub4": "Câble de communication entre gateway et onduleur correct", + "checklistStep7Sub1": "Numéro de bucket S3 et identifiants copiés depuis l'onglet Informations dans config.json", + "checklistStep7Sub2": "ID produit configuré dans config.json", + "checklistStep7Sub3": "ID USB configuré dans config.json", + "checklistStep7Sub4": "Lecture des données de l'onduleur testée", + "setupProgress": "Progression installation", + "checklistPhaseEmpty": "Non commencé", + "checklistPhasePreparation": "Préparation", + "checklistPhaseOnSite": "Sur site", + "checklistPhaseHandover": "Transfert client", + "checklistPhaseComplete": "Terminé" } \ No newline at end of file diff --git a/typescript/frontend-marios2/src/lang/it.json b/typescript/frontend-marios2/src/lang/it.json index 93bf6f2cb..9f44df140 100644 --- a/typescript/frontend-marios2/src/lang/it.json +++ b/typescript/frontend-marios2/src/lang/it.json @@ -712,5 +712,41 @@ "checklistCommentsPlaceholder": "Note, contatti, osservazioni…", "checklistEmailSent": "E-mail inviata a {name}", "checklistEmailFailed": "Invio e-mail non riuscito — riprovare", - "checklistSaveFailed": "Salvataggio non riuscito" + "checklistSaveFailed": "Salvataggio non riuscito", + "checklistStep1": "Ordine creato, informazioni cliente e partner registrate nel CRM", + "checklistStep2": "Hardware assemblato presso Vebo", + "checklistStep3": "Installazione creata su Monitor sotto il prodotto e la cartella corretti", + "checklistStep4": "Scheda SD del gateway configurata, VPN e nome gateway registrati", + "checklistStep5": "Scheda Informazioni compilata (cliente, seriali, VPN)", + "checklistStep6": "Installazione configurata e testata elettricamente/hardware presso Vebo", + "checklistStep7": "Installazione testata a livello software presso Vebo", + "checklistStep8": "Installazione consegnata presso il sito del cliente", + "checklistStep9": "Installazione collegata alla rete", + "checklistStep10": "Hardware verificato in sito", + "checklistStep11": "Software verificato in sito", + "checklistStep12": "Installazione online su Monitor", + "checklistStep13": "Cliente informato su account Monitor e report", + "checklistStep14": "Account utente creato con cartelle e accessi corretti", + "checklistStep15": "Follow-up cliente completato, feedback raccolto", + "checklistStep16": "Ulteriori problemi tracciati tramite il sistema di ticket", + "checklistStep5Sub1": "Informazioni cliente (e-mail, indirizzo)", + "checklistStep5Sub2": "Informazioni installazione (EMS esterno, fornitore di rete, raccolta dati)", + "checklistStep5Sub3": "Numero di serie batteria", + "checklistStep5Sub4": "Numero di serie inverter", + "checklistStep5Sub5": "Numero di serie data logger", + "checklistStep5Sub6": "VPN", + "checklistStep6Sub1": "Firmware e configurazione inverter verificati", + "checklistStep6Sub2": "Firmware e configurazione batteria verificati", + "checklistStep6Sub3": "Internet per gateway configurato", + "checklistStep6Sub4": "Cavo di comunicazione tra gateway e inverter corretto", + "checklistStep7Sub1": "Numero bucket S3 e credenziali copiati dalla scheda Informazioni in config.json", + "checklistStep7Sub2": "ID prodotto configurato in config.json", + "checklistStep7Sub3": "ID USB configurato in config.json", + "checklistStep7Sub4": "Lettura dati inverter testata", + "setupProgress": "Avanzamento installazione", + "checklistPhaseEmpty": "Non avviato", + "checklistPhasePreparation": "Preparazione", + "checklistPhaseOnSite": "In sito", + "checklistPhaseHandover": "Consegna cliente", + "checklistPhaseComplete": "Completato" }