Calculation type

FlatPercentOfCharges

Applies a flat percentage (with optional rule-based multiplier overrides) directly to charges' billed amounts, with no fee schedule lookup; the account-level total is always computed from the account's own AmountCharged when Level==Account, while the per-charge loop only controls whether individual charge lines get zeroed (Account) or independently priced (Charge).

732
uses
27
customers
Base
category
Varies (configurable)
applies at

What it computes

If calc.Level==Account: Details[0].SetBase(ApplyMultipliers(calc, Charges[0].AmountCharged, Charges[0], Details[0]), calc) runs unconditionally before the per-charge loop (skipped entirely when Level==Charge). Then for i in 1..NumCharges: if !IgnoreCharge(calc,charge,ctx) && (!CustomOnly || charge.IsCustom) && charge.AmountCharged != 0: if Level==Account, detail.SetBase(0, calc); else (Level==Charge) detail.SetBase(ApplyMultipliers(calc, charge.AmountCharged, charge, detail), calc). Charges failing that combined filter are left completely untouched (not zeroed, not priced) at either Level. ApplyMultipliers: matched RuleMultipliers rule's Multiplier, else DefaultMultiplier=Percentage/100 (default 1.0); Math.Round decimal AwayFromZero, 2dp.

Parameters

KeyMeaning
PercentageDecimal, default 100. Feeds DefaultMultiplier = Percentage/100 used when no RuleMultipliers rule matches.
CustomOnlyBoolean; when true, only charges where charge.IsCustom is true participate in the per-charge zeroing/pricing step below the account-level line.
LevelCalculationApplicationLevel (Account or Charge), defaults to Charge in the constructor; at Account level the account-level Details[0] is always set from Charges[0] and qualifying charge lines are zeroed; at Charge level Details[0] is never touched by this calculation and each qualifying charge is priced independently.
RuleMultipliersList of IMultiplierRule; matching rule's Multiplier overrides the Percentage-derived DefaultMultiplier for that charge (IHasRuleMultipliers).

Gotchas

Draft's original claim that 'every charge-level detail is zeroed' at Account level is wrong: zeroing is gated on the SAME three conditions (IgnoreCharge, CustomOnly, AmountCharged!=0) that gate Charge-level pricing — a charge failing any of those keeps whatever amount it already had from a prior calculation, it is not reset to 0. Separately, the account-level Details[0] write at the top of the method is unconditional on Level==Account — it runs even if every individual charge line is later excluded from the zeroing loop, so Details[0] can end up priced from Charges[0].AmountCharged while some charge-level details are stale nonzero leftovers from an earlier Base calculation, producing an inflated combined total. Zero-dollar charges (AmountCharged==0) are always skipped from the charge loop at both Levels.

In the source

class · /home/cary/src/mdc/MdClarity/MDClarity/MDClarityCore/Backend/CustomerDataModel.cs:689
dispatch · /home/cary/src/mdc/MdClarity/MDClarity/MDClarityCore/Backend/CalculationEngine.cs:656

CORRECTED — verified against CalculateFlatPercentOfCharges (CalculationEngine.cs:1121-1147). The draft's formula/notes stated the zeroing was unconditional ('every charge-level detail is zeroed'); the code gates it on IgnoreCharge && (!CustomOnly||IsCustom) && AmountCharged!=0, matching critique.md's finding. Rewrote formula and gotchas to reflect the actual conditional logic and the fact that Details[0] is set unconditionally on Level==Account, independent of the per-charge filter.