Calculation type
Runs an admin-authored raw SQL query, with brace-delimited placeholders substituted from the context, against the customer database and sets the resulting scalar as the base allowed amount, either once per non-ignored charge or once for account totals depending on Level.
Level==Charge: for i=1..NumCharges-1, skip IgnoreCharge'd lines; build {Codes} as MakeCodesText(charge.Codes) CONCATENATED WITH the account-row's codes (zeroChargeCodes), {ProviderID} as charge.ProviderID falling back to charge[0].ProviderID if null, plus {Facility}/{Insurance}/{BillType}/{ServiceDate}/{Units}/{Charged}/{Allowed} substituted from that charge/context; execute calc.Query; if a row is returned and column 0 is non-null, detail.SetBase(amount). Empty result set or a NULL column 0 both silently leave the charge unset (no error). Level==Account: charged/allowed are SUMMED over non-ignored charges i=1..N-1, but Units/ProviderID/BillType/Codes come only from charge[0] (not aggregated); execute once; if a row is returned: NULL column 0 THROWS; otherwise Details[0].SetBase(amount), and every non-ignored charge i>=1 is zeroed (Adjust(0) if already Calculated, else SetBase(0)). If the query returns zero rows at all (no Read()), the whole account-level branch is a silent no-op -- no throw, no SetBase.
| Key | Meaning |
|---|---|
| Level | CalculationApplicationLevel (Account or Charge); controls whether the query runs per-charge or once for the whole account; defaults to Charge. |
| Query | Raw SQL text with brace-delimited placeholders {Allowed}{BillType}{Charged}{Codes}{Facility}{Units}{Insurance}{ProviderID}{ServiceDate}; must return an Amount scalar in column 0. Defaults to a comment-only stub (SqlCalculation.DefaultQuery). |
Gotchas
(1) In Charge-level mode {Codes} is not just that charge's own codes -- the account-row's (charge[0]) codes are silently appended to every per-charge query, with no separator between the two MakeCodesText() outputs. (2) An empty result set (zero rows) is treated identically to 'skip this charge/account' in BOTH levels -- only an explicit NULL scalar in a returned row throws (Account level) or is silently skipped (Charge level); a query with a bad WHERE clause that simply matches nothing produces no error at all. (3) Account-level {ProviderID}/{BillType}/{Units}/{Codes} come from charge[0] only, not aggregated/summed the way {Charged}/{Allowed} are -- a reimplementer who assumes all placeholders are account totals will get the wrong Units/Codes/BillType. (4) SqlException with Class 15 or 16 (T-SQL syntax/permission-class errors) is intercepted at the dispatch site and rethrown as SqlCalculationSyntaxException carrying the FeeLogic key and calc.Name -- other exception types (including other SqlException classes) propagate unmodified. (5) This SqlExpressionCalculation/SqlCalculation lineage is unrelated to the separate ChargeLevelSqlCalculation/ChargeLevelSqlCalculator/generator-driven mechanism (dispatch case at CalculationEngine.cs:703) used for Medicare RVU/ASC/Anesthesia/DME/Drug/Lab -- same 'SQL' naming, different code paths entirely.
class · /home/cary/src/mdc/MdClarity/MDClarity/MDClarityCore/Backend/CustomerDataModel.cs:786
calculator · /home/cary/src/mdc/MdClarity/MDClarity/MDClarityCore/Backend/CalculationEngine.cs:1210 (private method CalculateSqlAmount)
dispatch · /home/cary/src/mdc/MdClarity/MDClarity/MDClarityCore/Backend/CalculationEngine.cs:678-698 (case SqlExpressionCalculation sqlExpression: ... CalculateSqlAmount(sqlExpression, context);) inside ApplyBaseCalculation, wrapped in a Stopwatch + try/catch that rethrows SqlException with Class 15 or 16 as SqlCalculationSyntaxException with extra FeeLogic/calc-name context
CONFIRMED