Calculation type

MultipleProcedureAdjustment

Reduces the allowed amount of charges whose fee-schedule rollup code is in a configured BaseCodes list, applying a rank-ordered percentage-per-unit schedule across the affected charges, with optional interaction rules that share an adjustment-index slot with charges already touched by a bilateral, multi-endoscopy, or multi-radiology adjustment.

303
uses
13
customers
Adjustment
category
Charge
applies at

What it computes

affected = charges (i=1..NumCharges-1) not IgnoreCharge'd whose rollup code (via IMultipleProcedureScheduleRepo) is in adjustment.BaseCodes; a charge already carrying a MultipleEndoscopyAdjustment/MedicareMultipleEndoscopyAdjustment marker is excluded from `affected` entirely unless UseAdditionalMultiEndoscopyRules is true. affected = GetChargeOrder(affected, SortBy) (per-unit Amount/Units, AmountCharged/Units, or PEAmount, descending; if UseAdditionalMultiEndoscopyRules and any affected charge has an endo marker, ranking instead uses an endoscopy-base-code-aggregated context). adjustedIndex starts at 0; for each affected charge, x = detail.Amount/charge.Units (or detail.Amount if Units==0); for each of charge.Units: chargeAdjustmentIndex = adjustedIndex, then overridden by GetBilateralAdjustmentIndex/GetEndoAdjustmentIndex/GetRadAdjustmentIndex (in that priority order, each gated by its Use*Rules flag AND a matching adjustment-type marker already present on detail.Adjustments) to reuse a previously-assigned index for a paired/grouped charge; p = Percentages[chargeAdjustmentIndex]/100 if in bounds else the last-set p carries over; s += MoneyMath.Multiply(x, p); adjustedIndex increments only if chargeAdjustmentIndex was NOT overridden (i.e. == the pre-override adjustedIndex). detail.Adjust(s, adjustment) if s != detail.Amount.

Parameters

KeyMeaning
ScheduleTypeFee/rollup schedule (via IMultipleProcedureScheduleRepo.GetCodeScheduleRecords) whose per-charge rollup Code is matched against BaseCodes.
SortBySortChargesBy enum (default AmountAllowed) ranking affected charges by per-unit amount, via the shared CalculationEngine.GetChargeOrder helper.
BaseCodesList of rollup codes (default "2") a charge's schedule rollup Code must match to be affected.
PercentagesOrdered percentage list applied by the running adjustedIndex counter across all affected charges' units combined; index beyond list length reuses the last-assigned p.
ExclusionCodesList of DimensionMember codes intended to exclude charges carrying them; CONFIRMED DEAD: the `continue` inside the inner foreach-over-mods loop (MultipleProcedureAdjustmentCalculator.cs:125-131) only advances to the next modifier, never skips the outer charge, so this list has zero effect on the affected set.
UseAdditionalBilateralRulesIf true and detail.Adjustments already contains a MedicareBilateralSurgeryAdjustment or BilateralSurgeryV2Adjustment marker, pairs LT/RT-modifier charges of the same procedure code to share one adjustment index (Ch.12 40.6.C.16).
UseAdditionalMultiEndoscopyRulesIf true, charges already carrying a MultipleEndoscopyAdjustment/MedicareMultipleEndoscopyAdjustment marker are (a) kept in the affected set instead of being excluded, (b) ranked using an endoscopy-base-code-aggregated context, and (c) share one adjustment index per endoscopy base code via a code->index dictionary (Ch.12 40.6.C.14).
UseAdditionalMultiRadRulesIf true and detail.Adjustments already contains a MultipleRadiologyAdjustment/MedicareMultipleRadiologyAdjustment marker, pairs TC/26-modifier charges of the same procedure code to share one adjustment index (Ch.12 40.6.C.19).

Gotchas

1) The ExclusionCodes loop is inert dead code (see key_attrs) - configuring it has no effect. 2) When UseAdditionalMultiEndoscopyRules is false (the default), any charge that already has an endo-adjustment marker is dropped from `affected` entirely - a hard exclusion, not just an unpaired inclusion; the bilateral/rad flags have no equivalent exclusion at the affected-set level, only at the index-reuse level, so the three flags behave asymmetrically. 3) adjustedIndex only advances when chargeAdjustmentIndex was left unmodified; when an interaction rule redirects it to a previously-used index, the counter freezes for that unit so the NEXT genuinely-new unit reuses the frozen slot rather than the position it would have reached normally - a naive per-unit-increment reimplementation will misassign percentages after the first paired/grouped unit. 4) The interaction flags only do anything if the paired adjustment type already ran and wrote its CalculationType name into detail.Adjustments earlier in the adjustment pipeline; running this adjustment out of order silently degrades it to the non-interaction behavior with no error. 5) MoneyMath.Multiply(decimal,double) rounds via Math.Round(double,2) (double-precision, effectively banker's rounding on the cast), summed per unit - differs from the decimal/AwayFromZero rounding used in base-calculation multiplier logic elsewhere in the engine.

In the source

class · /home/cary/src/mdc/MdClarity/MDClarity/MDClarityCore/Backend/PricingEngine/Adjustments/MultipleProcedureAdjustment.cs:8
calculator · /home/cary/src/mdc/MdClarity/MDClarity/MDClarityCore/Backend/PricingEngine/Adjustments/Calculators/MultipleProcedureAdjustmentCalculator.cs:11
dispatch · /home/cary/src/mdc/MdClarity/MDClarity/MDClarityCore/Backend/CalculationEngine.cs:760-764

CORRECTED - the draft's formula and key_attrs were substantively accurate (confirmed by re-reading MultipleProcedureAdjustment.cs and MultipleProcedureAdjustmentCalculator.cs in full), but its own critique correctly flagged the interaction-flag description as a hand-wave; I added the specific index-freeze semantics, the endoscopy-only hard-exclusion asymmetry, and confirmed the ExclusionCodes dead-code finding against the exact line range.