Files
Christoph Schwörer f045b99a25 Codebasis als Dateien ins Arbeitsrepo statt als Gitlink
QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142)
getrackt, ohne .gitmodules und ohne erreichbares Remote. Der
Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar
gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege
der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen.

Umstellung:
- Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert
  (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6)
- Gitlink aus dem Index entfernt
- Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB

Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte
bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
2026-08-26 07:43:51 +02:00

77 lines
3.4 KiB
C#

using CentronSoftware.Centron.Controls.PositionGrid.Helpers;
using CentronSoftware.Centron.Controls.PositionGrid.Interfaces;
namespace Centron.Tests.Controls.PositionGrid
{
/// <summary>
/// Tests for the Reverse-Charge threshold (Bagatellgrenze) calculation. Reproduces the
/// scenario from Ticket 163492: informative/alternative positions must not be counted
/// against the threshold, only Standard/Cargo positions do.
/// </summary>
public class ReverseChargeThresholdCalculatorTests
{
[Fact]
public void CalculateThresholdRelevantTotal_ExcludesInformativeAndAlternativePositions()
{
// Ticket 163492 scenario: two Standard positions (3000 + 1999 = 4999) plus one
// informative and two alternative positions (each 3000). Only the Standard net
// total (4999) is relevant for the threshold.
var positions = new (bool isReverseCharge, ReceiptArticlePositionKind kind, decimal totalPrice)[]
{
(true, ReceiptArticlePositionKind.Default, 3000m),
(true, ReceiptArticlePositionKind.Default, 1999m),
(true, ReceiptArticlePositionKind.Informative, 3000m),
(true, ReceiptArticlePositionKind.Alternative, 3000m),
(true, ReceiptArticlePositionKind.Alternative, 3000m),
};
var total = ReverseChargeThresholdCalculator.CalculateThresholdRelevantTotal(positions);
Assert.Equal(4999m, total);
}
[Fact]
public void CalculateThresholdRelevantTotal_IncludesCargoPositions()
{
var positions = new (bool isReverseCharge, ReceiptArticlePositionKind kind, decimal totalPrice)[]
{
(true, ReceiptArticlePositionKind.Default, 2500m),
(true, ReceiptArticlePositionKind.Cargo, 100m),
};
var total = ReverseChargeThresholdCalculator.CalculateThresholdRelevantTotal(positions);
Assert.Equal(2600m, total);
}
[Fact]
public void CalculateThresholdRelevantTotal_IgnoresNonReverseChargePositions()
{
var positions = new (bool isReverseCharge, ReceiptArticlePositionKind kind, decimal totalPrice)[]
{
(true, ReceiptArticlePositionKind.Default, 3000m),
(false, ReceiptArticlePositionKind.Default, 5000m),
};
var total = ReverseChargeThresholdCalculator.CalculateThresholdRelevantTotal(positions);
Assert.Equal(3000m, total);
}
[Theory]
[InlineData(ReceiptArticlePositionKind.Default, true)]
[InlineData(ReceiptArticlePositionKind.Cargo, true)]
[InlineData(ReceiptArticlePositionKind.Alternative, false)]
[InlineData(ReceiptArticlePositionKind.Optional, false)]
[InlineData(ReceiptArticlePositionKind.Informative, false)]
[InlineData(ReceiptArticlePositionKind.OnDemand, false)]
[InlineData(ReceiptArticlePositionKind.OnEffort, false)]
[InlineData(ReceiptArticlePositionKind.NoService, false)]
[InlineData(ReceiptArticlePositionKind.NoServiceOptional, false)]
public void CountsTowardNetTotal_MatchesNetTotalGroupingRules(ReceiptArticlePositionKind kind, bool expected)
{
Assert.Equal(expected, ReverseChargeThresholdCalculator.CountsTowardNetTotal(kind));
}
}
}