From 40805e02225fe949c7fd0f08a93f0bd70b19f82d Mon Sep 17 00:00:00 2001 From: metacube Date: Thu, 4 Jun 2026 10:42:11 +0200 Subject: [PATCH] Simplify finance dashboard overview --- .../Components/Pages/ManagementCockpit.razor | 158 ++++++++++- .../SageSpainFinalExportPackage.zip | Bin 3727 -> 5391 bytes .../SageSpainFinalExportPackage/README.txt | 70 +++++ .../Run-SpainExportAndUpload.ps1 | 72 +++++ ...PAIN_RCLONE_UPLOAD_ANLEITUNG_2026-06-03.md | 258 ++++++++++++++++++ ...GE_SPAIN_RCLONE_UPLOAD_GUIDE_2026-06-03.md | 258 ++++++++++++++++++ 6 files changed, 815 insertions(+), 1 deletion(-) create mode 100644 TrafagSalesExporter/SageSpainFinalExportPackage/Run-SpainExportAndUpload.ps1 create mode 100644 TrafagSalesExporter/docs/SAGE_SPAIN_RCLONE_UPLOAD_ANLEITUNG_2026-06-03.md create mode 100644 TrafagSalesExporter/docs/SAGE_SPAIN_RCLONE_UPLOAD_GUIDE_2026-06-03.md diff --git a/TrafagSalesExporter/Components/Pages/ManagementCockpit.razor b/TrafagSalesExporter/Components/Pages/ManagementCockpit.razor index 7423136..b3d9dc8 100644 --- a/TrafagSalesExporter/Components/Pages/ManagementCockpit.razor +++ b/TrafagSalesExporter/Components/Pages/ManagementCockpit.razor @@ -48,7 +48,123 @@ @if (_financeResult is not null) { - + + + + + + @T("Net Sales Actual", "Net sales actual") + @FormatValue(_financeResult.NetSalesActual, _financeResult.DisplayCurrency) + @($"{_financeResult.Filter.Year}") + + + + + @T("Laender OK", "Countries OK") + @_financeResult.CountryRows.Count(row => row.Status == "OK").ToString("N0") + @T("Soll/Ist ohne Abweichung", "Actual/reference without deviation") + + + + + @T("Zu pruefen", "To check") + @_financeResult.CountryRows.Count(row => row.Status == "Pruefen").ToString("N0") + @T("Abweichung oder offene Regel", "Deviation or open rule") + + + + + @T("Datenstandorte", "Data sites") + @_financeResult.DataStatusRows.Count(row => row.IsActive).ToString("N0") + @T("aktive Quellen", "active sources") + + + + + + + + @T("Finance-Freigabe je Land", "Finance approval by country") + + + @T("Status", "Status") + @T("Land", "Country") + @T("Ist", "Actual") + @T("Soll", "Reference") + @T("Differenz", "Difference") + @T("Datenstand", "Data status") + @T("Hinweis", "Note") + + + @context.Status + @FormatCountryWithFlag(context.CountryKey) + @FormatValue(context.NetSalesActual, context.Currency) + @FormatNullableValue(context.ReferenceValue, context.Currency) + @FormatNullableValue(context.Difference, context.Currency) + @BuildDataStatusText(context) + @BuildQuickFinanceNote(context) + + + + + + + @T("Letzter Datenstand je Standort", "Latest data status by site") + + + @T("Aktiv", "Active") + @T("Land", "Country") + TSC + @T("Quelle", "Source") + @T("Zentrale Zeilen", "Central rows") + @T("Letzter Export", "Latest export") + @T("Status", "Status") + @T("Manual Import", "Manual import") + + + + + + @context.Land + @context.Tsc + @context.SourceSystem + @context.RowCount.ToString("N0") + @FormatDateTime(context.LatestExportAt) + @(string.IsNullOrWhiteSpace(context.LatestExportStatus) ? "-" : context.LatestExportStatus) + @FormatManualImportStatus(context) + + + + + + + @T("Sparten-Abdeckung nach Land", "Division coverage by country") + + + @T("Land", "Country") + TSC + @T("Gesamtumsatz", "Total sales") + @T("Zugeordnet", "Assigned") + @T("Nicht im Stamm", "Not in master") + @T("Abdeckung", "Coverage") + + + @FormatCountryWithFlag(context.CountryKey) + @context.Tsc + @FormatValue(context.TotalValue, context.Currency) + @FormatValue(context.AssignedValue, context.Currency) + @FormatValue(context.MissingReferenceValue, context.Currency) + @FormatPercent(context.AssignedValuePercent) + + + + + + + + + @@ -867,6 +983,8 @@ + + } @code { @@ -917,6 +1035,7 @@ private bool _analyzing; private bool _analyzingCentral; private bool _analyzingFinance; + private int _activeOverviewTabIndex; private int _activeFinanceTabIndex; private int _activeDivisionTabIndex; private string _productFinanceGroupLevel = ProductFinanceGroupLevels.Hierarchy; @@ -928,6 +1047,8 @@ protected override void OnParametersSet() { + _activeOverviewTabIndex = string.IsNullOrWhiteSpace(Section) ? 0 : 1; + if (string.Equals(Section, "division", StringComparison.OrdinalIgnoreCase)) { _activeFinanceTabIndex = ManagementFinanceTabIndexes.Division; @@ -1193,6 +1314,41 @@ return "kein Pfad"; } + private string BuildDataStatusText(ManagementFinanceCountryStatusRow countryRow) + { + if (_financeResult is null) + return "-"; + + var tscs = countryRow.Tscs + .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) + .ToHashSet(StringComparer.OrdinalIgnoreCase); + var matchingRows = _financeResult.DataStatusRows + .Where(row => row.Land.Equals(countryRow.CountryKey, StringComparison.OrdinalIgnoreCase) || + tscs.Contains(row.Tsc)) + .OrderByDescending(row => row.LatestExportAt ?? row.LatestStoredAtUtc ?? DateTime.MinValue) + .ToList(); + + var latest = matchingRows.FirstOrDefault(); + if (latest is null) + return "-"; + + var date = latest.LatestExportAt ?? latest.LatestStoredAtUtc; + var status = string.IsNullOrWhiteSpace(latest.LatestExportStatus) ? latest.SourceSystem : latest.LatestExportStatus; + return $"{status} / {FormatDateTime(date)}"; + } + + private string BuildQuickFinanceNote(ManagementFinanceCountryStatusRow row) + { + if (!row.ReferenceValue.HasValue) + return T("Kein Sollwert gepflegt.", "No reference value maintained."); + if (row.Status == "OK") + return T("Freigabefaehig.", "Ready for approval."); + if (row.Difference.HasValue) + return T("Abweichung pruefen.", "Check deviation."); + + return T("Pruefen.", "Check."); + } + private static Color StatusColor(string status) => status switch { "OK" => Color.Success, diff --git a/TrafagSalesExporter/SageSpainFinalExportPackage.zip b/TrafagSalesExporter/SageSpainFinalExportPackage.zip index 8b313b3a4d81ec2a59b9fb57468a75b42f678f78..3ab4b20ff01bad17527e6af58f940e12988739e1 100644 GIT binary patch delta 2472 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 diff --git a/TrafagSalesExporter/SageSpainFinalExportPackage/README.txt b/TrafagSalesExporter/SageSpainFinalExportPackage/README.txt index 6c6816f..97d4173 100644 --- a/TrafagSalesExporter/SageSpainFinalExportPackage/README.txt +++ b/TrafagSalesExporter/SageSpainFinalExportPackage/README.txt @@ -46,3 +46,73 @@ Default source: If the SQL instance or database name differs: .\Export-SageSpainSalesCsv.ps1 -ServerInstance "localhost" -Database "Sage" -ExportMode Full -Year 2025 + + +Automatic upload to SharePoint with rclone +========================================== + +Target SharePoint folder: + +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Shared%20Documents/Import/Finance/Spanien + +Decoded folder path: + +Shared Documents/Import/Finance/Spanien + +Recommended rclone setup on the Spain Sage server: + +1. Install rclone. +2. Run: + +rclone config + +3. Create a new remote for the SharePoint document library. + +Recommended remote name: + +trafag-bi + +The remote should point to the document library root "Shared Documents" of: + +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform + +Then this target path is used by the wrapper script: + +trafag-bi:Import/Finance/Spanien + +Test rclone: + +rclone lsd trafag-bi: +rclone lsd trafag-bi:"Import/Finance" +rclone lsd trafag-bi:"Import/Finance/Spanien" + +Run daily range export and upload, default window yesterday until today: + +.\Run-SpainExportAndUpload.ps1 + +Explicit range: + +.\Run-SpainExportAndUpload.ps1 -ExportMode Range -DateFilter LineRegistrationDate -FromDate "2026-06-02" -ToDate "2026-06-03" + +Full export and upload: + +.\Run-SpainExportAndUpload.ps1 -ExportMode Full -Year 2025 + +If the rclone remote has another name: + +.\Run-SpainExportAndUpload.ps1 -RcloneRemote "YOUR_REMOTE_NAME" + +If rclone.exe is not in PATH: + +.\Run-SpainExportAndUpload.ps1 -RcloneExe "C:\Tools\rclone\rclone.exe" + +Suggested Windows Task Scheduler command: + +powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Trafag\SageSpain\Run-SpainExportAndUpload.ps1 + +Important: + +- The export script only reads SQL Server data. +- rclone only uploads the generated CSV and matching summary file. +- For daily deltas use ExportMode Range with DateFilter LineRegistrationDate. +- ToDate is exclusive. diff --git a/TrafagSalesExporter/SageSpainFinalExportPackage/Run-SpainExportAndUpload.ps1 b/TrafagSalesExporter/SageSpainFinalExportPackage/Run-SpainExportAndUpload.ps1 new file mode 100644 index 0000000..7b5f715 --- /dev/null +++ b/TrafagSalesExporter/SageSpainFinalExportPackage/Run-SpainExportAndUpload.ps1 @@ -0,0 +1,72 @@ +param( + [string]$ServerInstance = "localhost", + [string]$Database = "Sage", + [ValidateSet("Full", "Range")] + [string]$ExportMode = "Range", + [ValidateSet("InvoiceDate", "LineRegistrationDate")] + [string]$DateFilter = "LineRegistrationDate", + [int]$Year = 2025, + [datetime]$FromDate = (Get-Date).Date.AddDays(-1), + [datetime]$ToDate = (Get-Date).Date, + [string]$BaseDirectory = "C:\Trafag\SageSpain", + [string]$RcloneExe = "rclone", + [string]$RcloneRemote = "trafag-bi", + [string]$RcloneTarget = "Import/Finance/Spanien" +) + +$ErrorActionPreference = "Stop" + +$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path +$exportScript = Join-Path $scriptDirectory "Export-SageSpainSalesCsv.ps1" +if (-not (Test-Path -LiteralPath $exportScript)) { + throw "Export script not found: $exportScript" +} + +$outputDirectory = Join-Path $BaseDirectory "out" +$logDirectory = Join-Path $BaseDirectory "logs" +New-Item -ItemType Directory -Force -Path $outputDirectory, $logDirectory | Out-Null + +$exportArgs = @( + "-ServerInstance", $ServerInstance, + "-Database", $Database, + "-ExportMode", $ExportMode, + "-DateFilter", $DateFilter, + "-Year", $Year, + "-OutputDirectory", $outputDirectory +) + +if ($ExportMode -eq "Range") { + $exportArgs += @( + "-FromDate", $FromDate.ToString("yyyy-MM-dd"), + "-ToDate", $ToDate.ToString("yyyy-MM-dd") + ) +} + +& $exportScript @exportArgs +if ($LASTEXITCODE -ne 0) { + throw "Spain Sage export failed with exit code $LASTEXITCODE" +} + +$latestRun = Get-ChildItem -LiteralPath $outputDirectory -Directory | + Sort-Object LastWriteTime -Descending | + Select-Object -First 1 +if ($null -eq $latestRun) { + throw "No export run directory found in $outputDirectory" +} + +$rcloneLog = Join-Path $logDirectory ("rclone-spain-" + (Get-Date -Format "yyyyMMdd") + ".log") +$target = "${RcloneRemote}:$RcloneTarget" + +& $RcloneExe copy $latestRun.FullName $target ` + --include "*.csv" ` + --include "*_summary.txt" ` + --log-file $rcloneLog ` + --log-level INFO +if ($LASTEXITCODE -ne 0) { + throw "rclone upload failed with exit code $LASTEXITCODE" +} + +Write-Host "Spain export and upload finished." +Write-Host "Local export: $($latestRun.FullName)" +Write-Host "SharePoint target: $target" +Write-Host "rclone log: $rcloneLog" diff --git a/TrafagSalesExporter/docs/SAGE_SPAIN_RCLONE_UPLOAD_ANLEITUNG_2026-06-03.md b/TrafagSalesExporter/docs/SAGE_SPAIN_RCLONE_UPLOAD_ANLEITUNG_2026-06-03.md new file mode 100644 index 0000000..f126f5e --- /dev/null +++ b/TrafagSalesExporter/docs/SAGE_SPAIN_RCLONE_UPLOAD_ANLEITUNG_2026-06-03.md @@ -0,0 +1,258 @@ +# Sage Spanien Rclone Upload Anleitung + +Stand: 2026-06-03 + +Ziel: Der Sage-Server in Spanien erzeugt die Sales-CSV lokal und lädt die Datei danach automatisch in den SharePoint-Ordner fuer den Dashboard-Import. + +## Zielordner + +SharePoint URL: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Shared%20Documents/Import/Finance/Spanien +``` + +Technischer Ordner: + +```text +Shared Documents/Import/Finance/Spanien +``` + +Empfohlener rclone-Zielpfad: + +```text +trafag-bi:Import/Finance/Spanien +``` + +Dabei zeigt `trafag-bi` auf die Dokumentbibliothek `Shared Documents` der SharePoint-Site: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform +``` + +## Benötigte Dateien Auf Dem Spanien-Server + +Empfohlener Ordner: + +```text +C:\Trafag\SageSpain +``` + +Dateien: + +```text +Export-SageSpainSalesCsv.ps1 +Run-SpainExportAndUpload.ps1 +``` + +Die Dateien liegen im Paket: + +```text +SageSpainFinalExportPackage.zip +``` + +## rclone Installieren + +Falls `winget` vorhanden ist: + +```powershell +winget install Rclone.Rclone +``` + +Alternativ rclone ZIP manuell installieren, z.B. nach: + +```text +C:\Tools\rclone\rclone.exe +``` + +Danach testen: + +```powershell +rclone version +``` + +Falls `rclone` nicht im PATH ist, später den vollständigen Pfad verwenden: + +```powershell +C:\Tools\rclone\rclone.exe version +``` + +## rclone Remote Einrichten + +Auf dem Spanien-Server: + +```powershell +rclone config +``` + +Empfohlene Eingaben: + +```text +n +name> trafag-bi +Storage> onedrive +``` + +Danach Microsoft Login durchführen. + +Wichtig: + +- Site: `WorldwideBIPlatform` +- Dokumentbibliothek: `Shared Documents` +- Der rclone-Remote `trafag-bi` soll auf die Dokumentbibliothek `Shared Documents` zeigen. + +## rclone Testen + +```powershell +rclone lsd trafag-bi: +rclone lsd trafag-bi:"Import" +rclone lsd trafag-bi:"Import/Finance" +rclone lsd trafag-bi:"Import/Finance/Spanien" +``` + +Wenn der letzte Befehl den Ordner ohne Fehler zeigt, ist der Zielpfad korrekt. + +## Manueller Export Ohne Upload + +Full Export 2025: + +```powershell +Set-ExecutionPolicy -Scope Process Bypass +cd C:\Trafag\SageSpain +.\Export-SageSpainSalesCsv.ps1 -ExportMode Full -Year 2025 -OutputDirectory C:\Trafag\SageSpain\out +``` + +Delta/Range Export: + +```powershell +Set-ExecutionPolicy -Scope Process Bypass +cd C:\Trafag\SageSpain +.\Export-SageSpainSalesCsv.ps1 -ExportMode Range -DateFilter LineRegistrationDate -FromDate "2026-06-02" -ToDate "2026-06-03" -OutputDirectory C:\Trafag\SageSpain\out +``` + +Hinweis: + +- `ToDate` ist exklusiv. +- Der Zeitraum `"2026-06-02"` bis `"2026-06-03"` exportiert den 2. Juni. +- Für tägliche Deltas ist `LineRegistrationDate` sinnvoll, weil neue oder geänderte Zeilen nach Registrierungsdatum kommen. + +## Export Und Upload Zusammen Starten + +Standard: täglicher Delta-Lauf, gestern bis heute: + +```powershell +Set-ExecutionPolicy -Scope Process Bypass +cd C:\Trafag\SageSpain +.\Run-SpainExportAndUpload.ps1 +``` + +Expliziter Zeitraum: + +```powershell +.\Run-SpainExportAndUpload.ps1 -ExportMode Range -DateFilter LineRegistrationDate -FromDate "2026-06-02" -ToDate "2026-06-03" +``` + +Full Export mit Upload: + +```powershell +.\Run-SpainExportAndUpload.ps1 -ExportMode Full -Year 2025 +``` + +Wenn rclone nicht im PATH ist: + +```powershell +.\Run-SpainExportAndUpload.ps1 -RcloneExe "C:\Tools\rclone\rclone.exe" +``` + +Wenn der rclone-Remote anders heisst: + +```powershell +.\Run-SpainExportAndUpload.ps1 -RcloneRemote "MEIN_REMOTE_NAME" +``` + +## Was Wird Hochgeladen? + +Das Wrapper-Script lädt aus dem neuesten Exportordner: + +```text +*.csv +*_summary.txt +``` + +Ziel: + +```text +trafag-bi:Import/Finance/Spanien +``` + +Das Script ändert keine Daten in Sage und keine Daten in SQL Server. + +## Windows Task Scheduler + +Empfohlener täglicher Lauf, z.B. 02:00 Uhr: + +```powershell +$action = New-ScheduledTaskAction ` + -Execute "powershell.exe" ` + -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Trafag\SageSpain\Run-SpainExportAndUpload.ps1" + +$trigger = New-ScheduledTaskTrigger -Daily -At 02:00 + +Register-ScheduledTask ` + -TaskName "Trafag Spain Sage Export Upload" ` + -Action $action ` + -Trigger $trigger ` + -Description "Exports Sage Spain sales CSV and uploads it to SharePoint via rclone" +``` + +Wenn rclone nicht im PATH ist: + +```powershell +$action = New-ScheduledTaskAction ` + -Execute "powershell.exe" ` + -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Trafag\SageSpain\Run-SpainExportAndUpload.ps1 -RcloneExe C:\Tools\rclone\rclone.exe" +``` + +## Kontrolle Nach Dem Lauf + +Lokal: + +```powershell +Get-ChildItem C:\Trafag\SageSpain\out -Directory | Sort-Object LastWriteTime -Descending | Select-Object -First 1 +Get-ChildItem C:\Trafag\SageSpain\logs +``` + +SharePoint: + +```powershell +rclone ls trafag-bi:"Import/Finance/Spanien" +``` + +Im Browser prüfen: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Shared%20Documents/Import/Finance/Spanien +``` + +## Fehlerbilder + +`rclone: command not found` + +- rclone ist nicht im PATH. +- Lösung: `-RcloneExe "C:\Tools\rclone\rclone.exe"` verwenden. + +`directory not found` + +- Remote zeigt nicht auf `Shared Documents` oder Zielordner ist anders. +- Mit `rclone lsd trafag-bi:` und `rclone lsd trafag-bi:"Import/Finance"` prüfen. + +`Access denied` + +- Microsoft Login oder SharePoint-Berechtigung fehlt. +- Der Windows-User des geplanten Tasks muss Zugriff auf rclone-Konfiguration und SharePoint haben. + +Leere Delta-Datei: + +- Zeitraum prüfen. +- `ToDate` ist exklusiv. +- Bei täglichem Lauf für gestern bis heute ist das korrekt. diff --git a/TrafagSalesExporter/docs/SAGE_SPAIN_RCLONE_UPLOAD_GUIDE_2026-06-03.md b/TrafagSalesExporter/docs/SAGE_SPAIN_RCLONE_UPLOAD_GUIDE_2026-06-03.md new file mode 100644 index 0000000..9892969 --- /dev/null +++ b/TrafagSalesExporter/docs/SAGE_SPAIN_RCLONE_UPLOAD_GUIDE_2026-06-03.md @@ -0,0 +1,258 @@ +# Sage Spain Rclone Upload Guide + +Status: 2026-06-03 + +Purpose: The Sage server in Spain creates the sales CSV locally and then automatically uploads the file to the SharePoint folder used by the dashboard import. + +## Target Folder + +SharePoint URL: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Shared%20Documents/Import/Finance/Spanien +``` + +Technical folder: + +```text +Shared Documents/Import/Finance/Spanien +``` + +Recommended rclone target path: + +```text +trafag-bi:Import/Finance/Spanien +``` + +The rclone remote `trafag-bi` should point to the `Shared Documents` document library of this SharePoint site: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform +``` + +## Required Files On The Spain Server + +Recommended folder: + +```text +C:\Trafag\SageSpain +``` + +Required files: + +```text +Export-SageSpainSalesCsv.ps1 +Run-SpainExportAndUpload.ps1 +``` + +The files are included in: + +```text +SageSpainFinalExportPackage.zip +``` + +## Install rclone + +If `winget` is available: + +```powershell +winget install Rclone.Rclone +``` + +Alternatively, install the rclone ZIP manually, for example to: + +```text +C:\Tools\rclone\rclone.exe +``` + +Test the installation: + +```powershell +rclone version +``` + +If `rclone` is not in the PATH, use the full path later: + +```powershell +C:\Tools\rclone\rclone.exe version +``` + +## Configure The rclone Remote + +On the Spain server: + +```powershell +rclone config +``` + +Recommended input: + +```text +n +name> trafag-bi +Storage> onedrive +``` + +Then complete the Microsoft login. + +Important: + +- Site: `WorldwideBIPlatform` +- Document library: `Shared Documents` +- The rclone remote `trafag-bi` should point to the document library `Shared Documents`. + +## Test rclone + +```powershell +rclone lsd trafag-bi: +rclone lsd trafag-bi:"Import" +rclone lsd trafag-bi:"Import/Finance" +rclone lsd trafag-bi:"Import/Finance/Spanien" +``` + +If the last command lists the folder without an error, the target path is correct. + +## Manual Export Without Upload + +Full export for 2025: + +```powershell +Set-ExecutionPolicy -Scope Process Bypass +cd C:\Trafag\SageSpain +.\Export-SageSpainSalesCsv.ps1 -ExportMode Full -Year 2025 -OutputDirectory C:\Trafag\SageSpain\out +``` + +Delta/range export: + +```powershell +Set-ExecutionPolicy -Scope Process Bypass +cd C:\Trafag\SageSpain +.\Export-SageSpainSalesCsv.ps1 -ExportMode Range -DateFilter LineRegistrationDate -FromDate "2026-06-02" -ToDate "2026-06-03" -OutputDirectory C:\Trafag\SageSpain\out +``` + +Notes: + +- `ToDate` is exclusive. +- The range `"2026-06-02"` to `"2026-06-03"` exports June 2. +- For daily delta exports, `LineRegistrationDate` is recommended because it captures newly registered or changed lines. + +## Run Export And Upload Together + +Default: daily delta run, yesterday until today: + +```powershell +Set-ExecutionPolicy -Scope Process Bypass +cd C:\Trafag\SageSpain +.\Run-SpainExportAndUpload.ps1 +``` + +Explicit date range: + +```powershell +.\Run-SpainExportAndUpload.ps1 -ExportMode Range -DateFilter LineRegistrationDate -FromDate "2026-06-02" -ToDate "2026-06-03" +``` + +Full export with upload: + +```powershell +.\Run-SpainExportAndUpload.ps1 -ExportMode Full -Year 2025 +``` + +If rclone is not in the PATH: + +```powershell +.\Run-SpainExportAndUpload.ps1 -RcloneExe "C:\Tools\rclone\rclone.exe" +``` + +If the rclone remote has another name: + +```powershell +.\Run-SpainExportAndUpload.ps1 -RcloneRemote "YOUR_REMOTE_NAME" +``` + +## What Gets Uploaded? + +The wrapper script uploads these files from the newest export folder: + +```text +*.csv +*_summary.txt +``` + +Target: + +```text +trafag-bi:Import/Finance/Spanien +``` + +The script does not change any data in Sage or SQL Server. + +## Windows Task Scheduler + +Recommended daily run, for example at 02:00: + +```powershell +$action = New-ScheduledTaskAction ` + -Execute "powershell.exe" ` + -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Trafag\SageSpain\Run-SpainExportAndUpload.ps1" + +$trigger = New-ScheduledTaskTrigger -Daily -At 02:00 + +Register-ScheduledTask ` + -TaskName "Trafag Spain Sage Export Upload" ` + -Action $action ` + -Trigger $trigger ` + -Description "Exports Sage Spain sales CSV and uploads it to SharePoint via rclone" +``` + +If rclone is not in the PATH: + +```powershell +$action = New-ScheduledTaskAction ` + -Execute "powershell.exe" ` + -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Trafag\SageSpain\Run-SpainExportAndUpload.ps1 -RcloneExe C:\Tools\rclone\rclone.exe" +``` + +## Check After The Run + +Local output: + +```powershell +Get-ChildItem C:\Trafag\SageSpain\out -Directory | Sort-Object LastWriteTime -Descending | Select-Object -First 1 +Get-ChildItem C:\Trafag\SageSpain\logs +``` + +SharePoint via rclone: + +```powershell +rclone ls trafag-bi:"Import/Finance/Spanien" +``` + +Browser check: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Shared%20Documents/Import/Finance/Spanien +``` + +## Common Issues + +`rclone: command not found` + +- rclone is not in the PATH. +- Use `-RcloneExe "C:\Tools\rclone\rclone.exe"`. + +`directory not found` + +- The remote may not point to `Shared Documents`, or the target folder may be different. +- Check with `rclone lsd trafag-bi:` and `rclone lsd trafag-bi:"Import/Finance"`. + +`Access denied` + +- Microsoft login or SharePoint permissions are missing. +- The Windows user running the scheduled task must have access to the rclone configuration and to SharePoint. + +Empty delta file: + +- Check the date range. +- `ToDate` is exclusive. +- For a daily run, yesterday until today is correct.