Simplify finance dashboard overview
This commit is contained in:
@@ -48,7 +48,123 @@
|
|||||||
|
|
||||||
@if (_financeResult is not null)
|
@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">
|
<MudTabPanel Text="@T("Finance Summary", "Finance summary")" Icon="@Icons.Material.Filled.Dashboard">
|
||||||
<MudGrid Class="mb-4">
|
<MudGrid Class="mb-4">
|
||||||
<MudItem xs="12" sm="6" md="3">
|
<MudItem xs="12" sm="6" md="3">
|
||||||
@@ -867,6 +983,8 @@
|
|||||||
|
|
||||||
</MudTabPanel>
|
</MudTabPanel>
|
||||||
</MudTabs>
|
</MudTabs>
|
||||||
|
</MudTabPanel>
|
||||||
|
</MudTabs>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
@@ -917,6 +1035,7 @@
|
|||||||
private bool _analyzing;
|
private bool _analyzing;
|
||||||
private bool _analyzingCentral;
|
private bool _analyzingCentral;
|
||||||
private bool _analyzingFinance;
|
private bool _analyzingFinance;
|
||||||
|
private int _activeOverviewTabIndex;
|
||||||
private int _activeFinanceTabIndex;
|
private int _activeFinanceTabIndex;
|
||||||
private int _activeDivisionTabIndex;
|
private int _activeDivisionTabIndex;
|
||||||
private string _productFinanceGroupLevel = ProductFinanceGroupLevels.Hierarchy;
|
private string _productFinanceGroupLevel = ProductFinanceGroupLevels.Hierarchy;
|
||||||
@@ -928,6 +1047,8 @@
|
|||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
|
_activeOverviewTabIndex = string.IsNullOrWhiteSpace(Section) ? 0 : 1;
|
||||||
|
|
||||||
if (string.Equals(Section, "division", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(Section, "division", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
_activeFinanceTabIndex = ManagementFinanceTabIndexes.Division;
|
_activeFinanceTabIndex = ManagementFinanceTabIndexes.Division;
|
||||||
@@ -1193,6 +1314,41 @@
|
|||||||
return "kein Pfad";
|
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
|
private static Color StatusColor(string status) => status switch
|
||||||
{
|
{
|
||||||
"OK" => Color.Success,
|
"OK" => Color.Success,
|
||||||
|
|||||||
Binary file not shown.
@@ -46,3 +46,73 @@ Default source:
|
|||||||
If the SQL instance or database name differs:
|
If the SQL instance or database name differs:
|
||||||
|
|
||||||
.\Export-SageSpainSalesCsv.ps1 -ServerInstance "localhost" -Database "Sage" -ExportMode Full -Year 2025
|
.\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