{"id":21623025,"url":"https://github.com/pandatecham/be-lib-commission-calculator","last_synced_at":"2026-04-19T19:33:52.583Z","repository":{"id":204921630,"uuid":"711339732","full_name":"PandaTechAM/be-lib-commission-calculator","owner":"PandaTechAM","description":"Commission calculation helper nugget package","archived":false,"fork":false,"pushed_at":"2026-02-28T14:57:05.000Z","size":203,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"development","last_synced_at":"2026-02-28T16:56:44.719Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PandaTechAM.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-10-29T00:08:28.000Z","updated_at":"2026-02-28T14:56:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"535e28f7-0e08-41a5-9284-b1dc9b0ac7c9","html_url":"https://github.com/PandaTechAM/be-lib-commission-calculator","commit_stats":null,"previous_names":["pandatecham/be-lib-commission-calculator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/PandaTechAM/be-lib-commission-calculator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-commission-calculator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-commission-calculator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-commission-calculator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-commission-calculator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PandaTechAM","download_url":"https://codeload.github.com/PandaTechAM/be-lib-commission-calculator/tar.gz/refs/heads/development","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-commission-calculator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32020695,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T00:11:17.709Z","updated_at":"2026-04-19T19:33:52.574Z","avatar_url":"https://github.com/PandaTechAM.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pandatech.CommissionCalculator\n\nHigh-performance commission calculation engine for .NET 8+ supporting proportional and absolute commission models with tiered ranges, min/max constraints, and automatic validation.\n\n## Installation\n\n```bash\ndotnet add package Pandatech.CommissionCalculator\n```\n\n## Quick Start\n\n### Define Commission Rule\n\n```csharp\nusing CommissionCalculator.DTO;\n\nvar rule = new CommissionRule\n{\n    CalculationType = CalculationType.Proportional,\n    DecimalPlace = 4,\n    CommissionRangeConfigs = new List\u003cCommissionRangeConfigs\u003e\n    {\n        new()\n        {\n            RangeStart = 0,\n            RangeEnd = 500,\n            Type = CommissionType.FlatRate,\n            CommissionAmount = 25,\n            MinCommission = 0,\n            MaxCommission = 0\n        },\n        new()\n        {\n            RangeStart = 500,\n            RangeEnd = 1000,\n            Type = CommissionType.Percentage,\n            CommissionAmount = 0.1m,\n            MinCommission = 70,\n            MaxCommission = 90\n        },\n        new()\n        {\n            RangeStart = 1000,\n            RangeEnd = 10000,\n            Type = CommissionType.Percentage,\n            CommissionAmount = 0.2m,\n            MinCommission = 250,\n            MaxCommission = 1500\n        },\n        new()\n        {\n            RangeStart = 10000,\n            RangeEnd = 0, // 0 = infinity\n            Type = CommissionType.FlatRate,\n            CommissionAmount = 2000,\n            MinCommission = 0,\n            MaxCommission = 0\n        }\n    }\n};\n```\n\n### Calculate Commission\n\n**Standard (principal-based):**\n\n```csharp\ndecimal principal = 1000m;\ndecimal commission = Commission.ComputeCommission(principal, rule);\n// Result: 25 (flat) + 70 (min enforced) = 95\n```\n\n**Selector-based (different selection and application values):**\n\n```csharp\ndecimal orderPrice = 2000m;     // Amount to calculate commission on\ndecimal ticketCount = 3m;       // Value to select the range\n\n// Select range based on ticketCount, apply commission to orderPrice\ndecimal commission = Commission.ComputeCommission(orderPrice, ticketCount, rule);\n```\n\n**Use case:** When the value that determines which range to use (e.g., ticket quantity) differs from the amount you calculate commission on (e.g., order total).\n\n## Calculation Types\n\n### Proportional (Tiered)\n\nCommission accumulates across tiers as the amount increases:\n\n```csharp\nvar proportional = new CommissionRule\n{\n    CalculationType = CalculationType.Proportional,\n    CommissionRangeConfigs = new List\u003cCommissionRangeConfigs\u003e\n    {\n        new() { RangeStart = 0, RangeEnd = 100, Type = CommissionType.Percentage, CommissionAmount = 0.05m },\n        new() { RangeStart = 100, RangeEnd = 0, Type = CommissionType.Percentage, CommissionAmount = 0.03m }\n    }\n};\n\n// For $200:\n// - First $100: $100 * 5% = $5\n// - Next $100: $100 * 3% = $3\n// Total: $8\n```\n\n### Absolute (Flat per tier)\n\nOnly the matching tier's commission applies:\n\n```csharp\nvar absolute = new CommissionRule\n{\n    CalculationType = CalculationType.Absolute,\n    CommissionRangeConfigs = new List\u003cCommissionRangeConfigs\u003e\n    {\n        new() { RangeStart = 0, RangeEnd = 100, Type = CommissionType.FlatRate, CommissionAmount = 10 },\n        new() { RangeStart = 100, RangeEnd = 0, Type = CommissionType.FlatRate, CommissionAmount = 25 }\n    }\n};\n\n// For $200: $25 (uses second tier only)\n```\n\n## Range Configuration\n\n### CommissionRangeConfigs Properties\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `RangeStart` | decimal | Start of range (inclusive) |\n| `RangeEnd` | decimal | End of range (exclusive), **0 = infinity** |\n| `Type` | CommissionType | `FlatRate` or `Percentage` |\n| `CommissionAmount` | decimal | Commission value (flat amount or percentage like 0.1 for 10%) |\n| `MinCommission` | decimal | Minimum commission for this range |\n| `MaxCommission` | decimal | Maximum commission for this range, **0 = infinity** |\n\n### CommissionType\n\n- **FlatRate**: Returns `CommissionAmount` directly (min/max ignored)\n- **Percentage**: Calculates `principal × CommissionAmount`, clamped by min/max\n\n### Percentage Limits\n\nFor safety, percentage commissions are limited to ±1000%:\n\n```csharp\n// ✅ Valid: 10% = 0.1\nCommissionAmount = 0.1m\n\n// ❌ Invalid: 1500% = 15 (throws exception)\nCommissionAmount = 15m\n```\n\n## Validation\n\n### Automatic Validation\n\nValidation occurs automatically on first use:\n\n```csharp\ndecimal commission = Commission.ComputeCommission(1000m, rule);\n// Validates rule, caches normalized version, computes result\n```\n\n### Manual Validation\n\n```csharp\nbool isValid = Commission.ValidateRule(rule);\n```\n\n### Validation Rules\n\n✅ **Required:**\n- At least one range starting at 0\n- Ranges must be contiguous (no gaps)\n- Ranges must cover [0, ∞)\n- `MaxCommission ≥ MinCommission` (when MaxCommission ≠ 0)\n\n❌ **Forbidden:**\n- Overlapping ranges\n- Gaps in coverage\n- Equal `RangeStart` and `RangeEnd` (except single range: both 0)\n- Percentage commission outside ±1000% (±10 as decimal)\n\n## DateTime Overlap Checker\n\nUtility for validating commission period overlaps:\n\n```csharp\nusing CommissionCalculator.Helper;\nusing CommissionCalculator.DTO;\n\nvar period1 = new List\u003cDateTimePair\u003e\n{\n    new(new DateTime(2024, 1, 1), new DateTime(2024, 1, 10))\n};\n\nvar period2 = new List\u003cDateTimePair\u003e\n{\n    new(new DateTime(2024, 1, 5), new DateTime(2024, 1, 15))\n};\n\nbool hasOverlap = DateTimeOverlapChecker.HasOverlap(period1, period2);\n// Result: true\n```\n\n## Performance\n\n- **5+ million calculations/second** (after initial validation/normalization)\n- **Zero allocations** per calculation (after cache hit)\n- **Binary search** for range lookup: O(log n)\n- **Prefix sum optimization** for proportional calculations\n- **ConditionalWeakTable** caching of normalized rules\n\n**Performance characteristics:**\n```\nFirst calculation: ~50μs (validation + normalization + computation)\nSubsequent calculations: ~200ns (cache hit + binary search + math)\nMemory: ~1KB per cached rule\n```\n\n## Advanced Usage\n\n### Single Range (Flat Commission)\n\n```csharp\nvar flatRule = new CommissionRule\n{\n    CalculationType = CalculationType.Absolute,\n    CommissionRangeConfigs = new List\u003cCommissionRangeConfigs\u003e\n    {\n        new()\n        {\n            RangeStart = 0,\n            RangeEnd = 0, // Special case: both 0 for single range\n            Type = CommissionType.FlatRate,\n            CommissionAmount = 50,\n            MinCommission = 0,\n            MaxCommission = 0\n        }\n    }\n};\n\n// Any amount: $50 commission\n```\n\n### Progressive Percentage with Caps\n\n```csharp\nvar capped = new CommissionRule\n{\n    CalculationType = CalculationType.Proportional,\n    CommissionRangeConfigs = new List\u003cCommissionRangeConfigs\u003e\n    {\n        new()\n        {\n            RangeStart = 0,\n            RangeEnd = 1000,\n            Type = CommissionType.Percentage,\n            CommissionAmount = 0.05m,\n            MinCommission = 10,   // At least $10\n            MaxCommission = 50    // No more than $50 per tier\n        },\n        new()\n        {\n            RangeStart = 1000,\n            RangeEnd = 0,\n            Type = CommissionType.Percentage,\n            CommissionAmount = 0.02m,\n            MinCommission = 20,\n            MaxCommission = 0     // Unlimited on second tier\n        }\n    }\n};\n```\n\n### Selector-Based Example\n\n```csharp\n// Event ticketing: commission based on ticket count, applied to total price\nvar ticketRule = new CommissionRule\n{\n    CalculationType = CalculationType.Absolute, // Required for selector-based\n    CommissionRangeConfigs = new List\u003cCommissionRangeConfigs\u003e\n    {\n        new() { RangeStart = 0, RangeEnd = 10, Type = CommissionType.Percentage, CommissionAmount = 0.1m },\n        new() { RangeStart = 10, RangeEnd = 0, Type = CommissionType.Percentage, CommissionAmount = 0.05m }\n    }\n};\n\ndecimal orderTotal = 500m;\ndecimal ticketsSold = 15m;\n\n// Uses second range (15 tickets), applies 5% to $500 order\ndecimal commission = Commission.ComputeCommission(orderTotal, ticketsSold, ticketRule);\n// Result: $25\n```\n\n## Conventions\n\n- **Infinity as 0**: Set `RangeEnd = 0` or `MaxCommission = 0` to represent ∞\n- **Complete coverage**: Rules must cover [0, ∞) with no gaps\n- **Exclusive end**: `RangeEnd` is exclusive (range is [Start, End))\n- **Decimal precision**: Use `DecimalPlace` to control rounding (default: 4)\n\n## Common Patterns\n\n### Affiliate Marketing\n\n```csharp\n// Higher commission for higher sales\nCalculationType = CalculationType.Absolute\nRanges:\n  $0-$1000: 5%\n  $1000-$5000: 7%\n  $5000+: 10%\n```\n\n### Payment Processing\n\n```csharp\n// Tiered fees that accumulate\nCalculationType = CalculationType.Proportional\nRanges:\n  $0-$10,000: 2.9% + $0.30 min\n  $10,000+: 1.5%\n```\n\n### Broker Fees\n\n```csharp\n// Fixed fee per transaction tier\nCalculationType = CalculationType.Absolute\nRanges:\n  $0-$10,000: $9.99\n  $10,000-$100,000: $19.99\n  $100,000+: $49.99\n```\n\n## License\n\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpandatecham%2Fbe-lib-commission-calculator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpandatecham%2Fbe-lib-commission-calculator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpandatecham%2Fbe-lib-commission-calculator/lists"}