Simplify finance dashboard overview
This commit is contained in:
@@ -48,7 +48,123 @@
|
||||
|
||||
@if (_financeResult is not null)
|
||||
{
|
||||
<MudTabs Elevation="1" Rounded="false" PanelClass="pt-4" @bind-ActivePanelIndex="_activeFinanceTabIndex">
|
||||
<MudTabs Elevation="1" Rounded="false" PanelClass="pt-4" @bind-ActivePanelIndex="_activeOverviewTabIndex">
|
||||
<MudTabPanel Text="@T("Schnelluebersicht", "Quick overview")" Icon="@Icons.Material.Filled.Speed">
|
||||
<MudGrid Class="mb-4">
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudPaper Class="pa-4" Elevation="1">
|
||||
<MudText Typo="Typo.caption">@T("Net Sales Actual", "Net sales actual")</MudText>
|
||||
<MudText Typo="Typo.h5">@FormatValue(_financeResult.NetSalesActual, _financeResult.DisplayCurrency)</MudText>
|
||||
<MudText Typo="Typo.body2">@($"{_financeResult.Filter.Year}")</MudText>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudPaper Class="pa-4" Elevation="1">
|
||||
<MudText Typo="Typo.caption">@T("Laender OK", "Countries OK")</MudText>
|
||||
<MudText Typo="Typo.h5">@_financeResult.CountryRows.Count(row => row.Status == "OK").ToString("N0")</MudText>
|
||||
<MudText Typo="Typo.body2">@T("Soll/Ist ohne Abweichung", "Actual/reference without deviation")</MudText>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudPaper Class="pa-4" Elevation="1">
|
||||
<MudText Typo="Typo.caption">@T("Zu pruefen", "To check")</MudText>
|
||||
<MudText Typo="Typo.h5">@_financeResult.CountryRows.Count(row => row.Status == "Pruefen").ToString("N0")</MudText>
|
||||
<MudText Typo="Typo.body2">@T("Abweichung oder offene Regel", "Deviation or open rule")</MudText>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudPaper Class="pa-4" Elevation="1">
|
||||
<MudText Typo="Typo.caption">@T("Datenstandorte", "Data sites")</MudText>
|
||||
<MudText Typo="Typo.h5">@_financeResult.DataStatusRows.Count(row => row.IsActive).ToString("N0")</MudText>
|
||||
<MudText Typo="Typo.body2">@T("aktive Quellen", "active sources")</MudText>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
|
||||
<MudTabs Elevation="0" Rounded="false" PanelClass="pt-4">
|
||||
<MudTabPanel Text="@T("Freigabe", "Approval")" Icon="@Icons.Material.Filled.FactCheck">
|
||||
<MudPaper Class="pa-4" Elevation="1">
|
||||
<MudText Typo="Typo.h6" Class="mb-2">@T("Finance-Freigabe je Land", "Finance approval by country")</MudText>
|
||||
<MudTable Items="_financeResult.CountryRows" Dense Hover Striped>
|
||||
<HeaderContent>
|
||||
<MudTh>@T("Status", "Status")</MudTh>
|
||||
<MudTh>@T("Land", "Country")</MudTh>
|
||||
<MudTh>@T("Ist", "Actual")</MudTh>
|
||||
<MudTh>@T("Soll", "Reference")</MudTh>
|
||||
<MudTh>@T("Differenz", "Difference")</MudTh>
|
||||
<MudTh>@T("Datenstand", "Data status")</MudTh>
|
||||
<MudTh>@T("Hinweis", "Note")</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
<MudTd><MudChip T="string" Size="Size.Small" Color="@StatusColor(context.Status)" Variant="Variant.Filled">@context.Status</MudChip></MudTd>
|
||||
<MudTd>@FormatCountryWithFlag(context.CountryKey)</MudTd>
|
||||
<MudTd>@FormatValue(context.NetSalesActual, context.Currency)</MudTd>
|
||||
<MudTd>@FormatNullableValue(context.ReferenceValue, context.Currency)</MudTd>
|
||||
<MudTd>@FormatNullableValue(context.Difference, context.Currency)</MudTd>
|
||||
<MudTd>@BuildDataStatusText(context)</MudTd>
|
||||
<MudTd>@BuildQuickFinanceNote(context)</MudTd>
|
||||
</RowTemplate>
|
||||
</MudTable>
|
||||
</MudPaper>
|
||||
</MudTabPanel>
|
||||
<MudTabPanel Text="@T("Datenstand", "Data status")" Icon="@Icons.Material.Filled.Storage">
|
||||
<MudPaper Class="pa-4" Elevation="1">
|
||||
<MudText Typo="Typo.h6" Class="mb-2">@T("Letzter Datenstand je Standort", "Latest data status by site")</MudText>
|
||||
<MudTable Items="_financeResult.DataStatusRows" Dense Hover Striped>
|
||||
<HeaderContent>
|
||||
<MudTh>@T("Aktiv", "Active")</MudTh>
|
||||
<MudTh>@T("Land", "Country")</MudTh>
|
||||
<MudTh>TSC</MudTh>
|
||||
<MudTh>@T("Quelle", "Source")</MudTh>
|
||||
<MudTh>@T("Zentrale Zeilen", "Central rows")</MudTh>
|
||||
<MudTh>@T("Letzter Export", "Latest export")</MudTh>
|
||||
<MudTh>@T("Status", "Status")</MudTh>
|
||||
<MudTh>@T("Manual Import", "Manual import")</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
<MudTd>
|
||||
<MudIcon Icon="@(context.IsActive ? Icons.Material.Filled.CheckCircle : Icons.Material.Filled.Cancel)"
|
||||
Color="@(context.IsActive ? Color.Success : Color.Default)" Size="Size.Small" />
|
||||
</MudTd>
|
||||
<MudTd>@context.Land</MudTd>
|
||||
<MudTd>@context.Tsc</MudTd>
|
||||
<MudTd>@context.SourceSystem</MudTd>
|
||||
<MudTd>@context.RowCount.ToString("N0")</MudTd>
|
||||
<MudTd>@FormatDateTime(context.LatestExportAt)</MudTd>
|
||||
<MudTd>@(string.IsNullOrWhiteSpace(context.LatestExportStatus) ? "-" : context.LatestExportStatus)</MudTd>
|
||||
<MudTd>@FormatManualImportStatus(context)</MudTd>
|
||||
</RowTemplate>
|
||||
</MudTable>
|
||||
</MudPaper>
|
||||
</MudTabPanel>
|
||||
<MudTabPanel Text="@T("Sparten", "Divisions")" Icon="@Icons.Material.Filled.AccountTree">
|
||||
<MudPaper Class="pa-4" Elevation="1">
|
||||
<MudText Typo="Typo.h6" Class="mb-2">@T("Sparten-Abdeckung nach Land", "Division coverage by country")</MudText>
|
||||
<MudTable Items="_financeResult.ProductFinanceCountryRows" Dense Hover Striped>
|
||||
<HeaderContent>
|
||||
<MudTh>@T("Land", "Country")</MudTh>
|
||||
<MudTh>TSC</MudTh>
|
||||
<MudTh>@T("Gesamtumsatz", "Total sales")</MudTh>
|
||||
<MudTh>@T("Zugeordnet", "Assigned")</MudTh>
|
||||
<MudTh>@T("Nicht im Stamm", "Not in master")</MudTh>
|
||||
<MudTh>@T("Abdeckung", "Coverage")</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
<MudTd>@FormatCountryWithFlag(context.CountryKey)</MudTd>
|
||||
<MudTd>@context.Tsc</MudTd>
|
||||
<MudTd>@FormatValue(context.TotalValue, context.Currency)</MudTd>
|
||||
<MudTd>@FormatValue(context.AssignedValue, context.Currency)</MudTd>
|
||||
<MudTd>@FormatValue(context.MissingReferenceValue, context.Currency)</MudTd>
|
||||
<MudTd>@FormatPercent(context.AssignedValuePercent)</MudTd>
|
||||
</RowTemplate>
|
||||
</MudTable>
|
||||
</MudPaper>
|
||||
</MudTabPanel>
|
||||
</MudTabs>
|
||||
</MudTabPanel>
|
||||
|
||||
<MudTabPanel Text="@T("Experten", "Experts")" Icon="@Icons.Material.Filled.Tune">
|
||||
<MudTabs Elevation="0" Rounded="false" PanelClass="pt-4" @bind-ActivePanelIndex="_activeFinanceTabIndex">
|
||||
<MudTabPanel Text="@T("Finance Summary", "Finance summary")" Icon="@Icons.Material.Filled.Dashboard">
|
||||
<MudGrid Class="mb-4">
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
@@ -867,6 +983,8 @@
|
||||
|
||||
</MudTabPanel>
|
||||
</MudTabs>
|
||||
</MudTabPanel>
|
||||
</MudTabs>
|
||||
}
|
||||
|
||||
@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,
|
||||
|
||||
Binary file not shown.
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user