Back to Articles|Published on November 2, 2026|29 min read

Cirra AI Article

Why Salesforce Currency Totals Disagree: Trace the Rate First

Why Salesforce currency totals disagree: a Winter '27 rate-path matrix, a reconciliation sheet on one synthetic opportunity, row versus aggregate SOQL, and when to document or fix in 2026.

By Cirra

Why Salesforce Currency Totals Disagree: Trace the Rate First

Summary

  1. 01Join the record ID sets before comparing converted totals. Different records indicate a scope problem; matching records shift the investigation to target currency, rates and rounding.
  2. 02Map each output to its target currency, rate type and date selector. Different conversion contracts can produce different totals without a data error.
  3. 03Row-level SOQL converts to the user's currency, while aggregates with GROUP BY or HAVING return the org default currency. The aggregate rate path remains unknown until tested.
  4. 04For opportunity data under ACM, the close date selects the dated rate. Moving that date across a rate start can change the converted amount without changing the source amount.
  5. 05Document the rate path before intervening. Correct mismatched filters or display context, and put any scoped configuration proposal through sandbox testing and review.
  6. 06The reconciliation sheet uses fictional rates and expected values only. No sandbox experiment was performed, and forecasts under ACM, dashboards and historical trending remain unknown.
Inside this article
  1. 01Executive Summary
  2. 02Introduction and Background
  3. 03Step 1: Capture Both Outputs Precisely
  4. 04Step 2: Map Each Output's Conversion Contract
  5. 05Step 3: Dated Rates, SOQL Output and Historical Trending
  6. 06Step 4: Deciding the Intervention and Documenting It
  7. 07Data Analysis and Evidence: A Reconciliation Sheet on One Synthetic Opportunity
  8. 08Implications and Future Directions
  9. 09Frequently Asked Questions (FAQs)
  10. 10Conclusion

Executive Summary

When two Salesforce outputs show different converted totals for the same deal, the first question is not "which number is right" but "which rate path produced each number". A multi-currency org stores each record's amount in its own currency, and every converted figure is a function of a source currency, a target currency, a rate, and a rule for choosing that rate. Salesforce's own Trailhead material describes the baseline: a corporate currency set by the admin, rates entered relative to that corporate currency, and a personal currency for each user [1]. Without Advanced Currency Management (ACM), Trailhead states that all conversions within opportunities, forecasts, and other amounts use the current conversion rate, and that previous conversion rates are not stored [1].

ACM changes this for a defined set of objects. Trailhead describes it as covering currency fields on opportunities and opportunity products, with rates managed by start date [1]. The SOQL reference adds that with ACM enabled, dated exchange rates are used for opportunities, opportunity line items, and opportunity history, and that the rate chosen corresponds to a date field such as the opportunity close date [2]. Everything outside that scope, such as custom objects and formula fields, is where practitioners report static-rate behavior, so a "converted" figure built on those surfaces can legitimately differ from an opportunity report [3] [4].

Row-level and aggregate SOQL are separate contracts. The documented row function converts to the user's currency, while aggregate results in queries with GROUP BY or HAVING come back in the org's default currency and cannot be wrapped in the conversion function [2]. A report total, a row export, and an aggregate query can therefore differ with no data error at all.

This report provides a rate-path matrix (Table 1), a decision matrix (Table 2), and a reconciliation sheet built on one synthetic opportunity with fictional rates (Table 3). Two limits apply. First, no sandbox experiment was run for this article, so every test is a plan, not a result. Second, behaviour that only the Salesforce Help pages document is labelled unknown here rather than asserted. The recommended action is to document the rate path first, correct only mismatched filters and display context, and treat any rate or ACM change as a separately reviewed change [1].

120,000.00EUR source amount on the synthetic opportunity, using fictional rates
3,030.31USD gap between rounded static and dated results in the fictional example
33.48Sum of three rounded rows in the fictional rounding example
33.47Total rounded after summing unrounded conversions in the fictional example

Introduction and Background

Admins and revenue operations owners meet this problem in a familiar form: a dashboard says one number, a report says another, and an exported row set sums to a third. The temptation is to open Setup and adjust exchange rates until a screenshot matches. That is the wrong first move. Salesforce stores static rates as a single set that applies to all currency fields in the org [1], and saving new static rates re-values existing amounts [1]. A rate edit made to fix one report therefore moves every other report that uses the same rate.

Scope. This is Salesforce administration, not accounting policy or currency trading. The article covers why converted totals differ across a standard Opportunity report, a dashboard built on it, a forecast, a formula field, and SOQL exports. It is written as of 2026-11-02. None of the pages quoted here states a release in which these behaviors were introduced, so nothing below implies a change in any particular release. The test record for the plan is: report type Opportunities (standard), queried object Opportunity, and API version to be recorded from the sandbox at test time, because this article does not cite a Salesforce release note for the Winter '27 API version.

Vocabulary. The corporate currency is the currency of the org's headquarters, set by an admin. A static rate is one rate per currency; Trailhead describes the Edit Rates screen as managing static exchange rates between active and inactive currencies. A dated rate maps a rate to a start date, and the first dated set is created from the existing static rates and stays valid until another set is defined [1]. Each user also has a personal currency, which Trailhead says is the default currency in quotas, forecasts, opportunities, quotes and reports [1]. Multiple currencies cannot be switched off once enabled, per Trailhead's module [1], which is why configuration changes need approval. Adobe's documentation uses two labels for the resulting setups: Simple Currency, meaning multiple currencies with a static conversion rate per currency [5], and Advanced Currency, meaning different conversion rates for different time periods [5]. One practitioner source adds that dated exchange rates are optional [3].

What the report provides.

  • Rate-path matrix (Table 1): which surface uses which rate type and date selector, with a verification status per row.
  • Decision matrix (Table 2): symptom, likely cause, correct action, and the action to avoid.
  • Reconciliation sheet (Table 3): one synthetic opportunity, fictional rates, expected values and blank columns for actual output and residual.
  • Test plans: boundary tests for close dates, untested SOQL templates, and a verification branch for historical trending.

Role of AI assistance. An AI client with read access can inventory report definitions, field types and configured rates, and match outputs by record ID. It cannot supply historical exchange rates, and it should never be asked to. Rates in the worked example below are fictional. A narrated explanation is not evidence; a spreadsheet tied to exported rates is.

Figure 01
Trace the rate before deciding the intervention
  1. 01Capture both outputs

    Record IDs, amounts, currencies, filters, display context, time context and the reporting surface for each output.

  2. 02Join record IDs

    Compare the ID sets first. If they differ, resolve the scope discrepancy before analysing rates.

  3. 03Map the conversion contract

    Identify each surface's target currency, rate type and date selector, retaining unknowns where evidence is missing.

  4. 04Rebuild expected values

    Use exported static and dated rates, confirm rate direction, and calculate expected values with an explicit rounding mode.

  5. 05Decide and document

    Choose documentation, a filter or display correction, or a scoped configuration proposal for sandbox testing and approval.

Step 1: Capture Both Outputs Precisely

Diagnosis starts by proving that the two outputs describe the same records. Many apparent currency discrepancies are filter or grouping discrepancies. Capture the following for each output before comparing any converted amount:

  • Record IDs: the exact set of Opportunity IDs in each output, exported with the 18-character ID so the sets can be joined.
  • Amount and currency: the record's own Amount and CurrencyIsoCode. A practitioner write-up states that the Amount column always shows the value in the opportunity's own currency [6].
  • Converted column: whether the output uses the Amount (converted) column, which the same write-up says shows the value in the viewing user's currency [6].
  • Report type and filters: report type name, every filter, and any currency ISO code filter.
  • Display context: the report or display currency, and the running user's personal currency.
  • Time context: the as-of timestamp, close date, grouping and any date bucket.
  • Surface: report, dashboard component, forecast, formula field, or SOQL (row or aggregate).

Join before you convert. Compare ID sets first. If the sets differ, the discrepancy is a scope problem and no rate analysis is needed. If the sets match and the amounts are in the same record currencies, the remaining difference is in the target currency, the rate, or the rounding.

The running-user trap. Because personal currency is a per-user setting that drives default currency in reports [1], two people can open the same saved report and see different converted figures. When a discrepancy is reported by two people, record each person's personal currency before anything else. Deactivating a currency that is set as a user's personal currency resets that user to the corporate currency, which can silently change what that user sees.

A narrated explanation is not evidence; a spreadsheet tied to exported rates is.

Step 2: Map Each Output's Conversion Contract

Each reporting surface has a conversion contract: a target currency, a rate type, and a date selector. Table 1 below maps the surfaces that most often disagree. Every row names its source and its verification status. Where no Salesforce primary source is cited for a row, the cell says unknown and does not guess.

Table 1: Rate-path matrix (no org tested)

SurfaceObject / fieldOutput currencyRate typeDate selectorEvidence and status
Standard Opportunity report, converted columnOpportunity Amount (converted)Viewing user's currency [6]Dated when ACM is on [3]Opportunity close date [3]Practitioner sources, tier 3 and 4. Help cross-check pending. Verify in sandbox.
Standard Opportunity report, record columnOpportunity AmountRecord's own currency [6]None (no conversion)Not applicablePractitioner source. Low risk.
SOQL row queryconvertCurrency(Amount) on OpportunityUser's currency [2]Dated if ACM enabled [2]A date field such as CloseDate [2]Official SOQL reference. Test per API version.
SOQL on an org without ACMAny currency fieldUser's currencyStatic: most recent entered [2]NoneOfficial SOQL reference.
SOQL aggregate with GROUP BY or HAVINGSUM(), MAX() on currencyOrg default currency [2]Unknown: the page does not say which rateUnknownOfficial page gives currency only. Rate path unknown until tested.
Formula fieldCURRENCYRATE() or currency formulasFormula's own contextStatic [3] [7]NoneTier 3 and 4 sources agree; an ISV states formulas cannot reference dated rates [8]. Help cross-check pending.
Custom object currency fieldAny non-opportunity objectViewing user's currencyStatic, per a consultancy write-up [4]NoneConsistent with Trailhead's ACM scope. Verify.
ForecastForecast amountsUser's personal currency by defaultUnknown with ACM onUnknownTrailhead covers only the non-ACM case. Mark unknown.
Opportunity history in SOQLOpportunityHistory currency fieldsUser's currencyDated if ACM enabled [2]Matching date fieldOfficial SOQL reference.
Historical trending reportFields labelled HistoricalUnknownUnknownUnknownSee the verification branch below.
Dashboard componentSource report's columnsUnknown (running user's context not captured)Same as source reportSame as source reportUnknown. Test with two running users.
Third-party app calculationsVendor formula fieldsVendor-definedVendor states it ignores dated rates [8]NoneVendor's own documentation.

Table 1 shows that a "converted amount" is not one thing. The same Opportunity can be converted at a dated rate in a standard report, at a static rate in a formula, and at a rate that the documentation does not name in an aggregate query. Two surfaces disagreeing is, in this table's terms, the expected outcome whenever they sit on different rows. A discrepancy is only a candidate defect when two outputs sit on the same row and still differ.

The table also marks what is not known. The Trailhead module explains the non-ACM case: all conversions within opportunities, forecasts, and other amounts use the current conversion rate. A third-party explainer repeats the non-ACM rule in a parenthetical: without ACM, conversions use the current rate [9]. The module does not say what forecasts do once ACM is on, and this article does not cite the Help considerations page. That row stays unknown, and so do dashboards and historical trending, until a test says otherwise.

Reading the ACM scope. Trailhead states that ACM covers currency fields on opportunities and opportunity products. The SOQL reference lists opportunities, opportunity line items, and opportunity history. An ISV's documentation shows how the formula boundary surfaces in practice: for customers with ACM it converts revenue amounts using the flat rates defined in the basic currency tab [8], because its touchpoints use formula fields to calculate revenue [8]. A consultancy write-up adds that reports on custom object currency fields change whenever the exchange rate updates [4], and a practitioner article reports a long-standing IdeaExchange request for CURRENCYRATE() to read dated rates [7]. The object list above is not exhaustive: Salesforce's Help guide on advanced currency management may list further related objects and static-rate exceptions, which the table does not reproduce. Read that Help guide in full before relying on any row for forecasts, dashboards or historical trending.

Step 3: Dated Rates, SOQL Output and Historical Trending

Dated Rate Selection and the Close Date

For opportunity data under ACM, the date that selects the rate is the close date. Trailhead's project makes this concrete: the reader edits the close date on a euro opportunity and sees the converted amount change [10], because the new exchange rate is being used [10]. The SOQL reference states the same rule for queries: the conversion uses the rate that corresponds to a given field, for example the close date.

What the documentation establishes.

  • Start dates, not end dates: dated rates are managed by start date [10].
  • First set: enabling ACM turns existing rates into the first dated set, valid until another set is defined.
  • Selector: close date for opportunities, per the SOQL reference and a practitioner example where the converted column follows the opportunity close date [3].

What the documentation does not establish in the sources read here. The exact treatment of the boundary day (inclusive start, or off by one in a user's time zone), what happens when a rate set does not cover a date, and how a stored converted amount behaves after a later rate edit. Those are test items, not facts.

Do not promise immutability. A trade-press roundup says a closed-won converted amount is "fixed for that date" [11]. That is true only to the extent that the inputs stay fixed. The inputs are the close date, the dated rate table, the output context, and the field. If any of them changes later, the figure can change. The roundup is also dated: its page metadata shows a 2024-04-30 modification, and it introduces the features without giving a reconciliation procedure [11]. Where a pipeline process edits close dates, the converted amount follows the new date. For this reason the regression checklist at the end of this report includes a close-date change.

Boundary test design (sandbox only). Create one synthetic opportunity in a fictional currency pair. Set three dated rate rows in the sandbox. Move the close date through the day before a rate start, the start day, and the day after, and record each converted amount. The test answers the boundary question with evidence from your own org, at your own API version. The sandbox should be a copy of the production rate configuration, or the test says nothing about production.

Report Totals Versus Row SOQL and Aggregate SOQL

A SOQL export is not a report. The SOQL reference defines convertCurrency() in the SELECT clause as the way to convert currency fields to the user's currency, and it requires that the org have multiple currencies enabled. When ACM is on, the function uses dated exchange rates for opportunities, opportunity line items, and opportunity history. When ACM is off, the most recent conversion rate entered is used.

Aggregates are a different contract. The same page says that a query containing GROUP BY or HAVING returns aggregate currency data in the org's default currency, and that the result of an aggregate function cannot be converted into the user's currency by calling convertCurrency(). A user whose personal currency is not the org default therefore sees one currency from a row export and another from an aggregate query of the same records.

Filtering has its own trap. In a WHERE clause, convertCurrency() returns an error [2]. To compare against an amount in a particular currency, the documented syntax uses an ISO code, which must be enabled and active in the org [2]. If the ISO code is omitted, the numeric value is compared without regard to currency [2], and an IN list cannot mix coded and uncoded values. A filter that omits the code can therefore include or exclude records in a way that looks like a conversion problem but is a scope problem. Ordering is always based on the converted value, as in reports [2].

Untested snippet templates. The snippets below are templates to be run in a sandbox. They were not executed for this article, and the API version used must be recorded beside the result.

-- Row-level: user-currency conversion, record currency, close date
SELECT Id, CloseDate, CurrencyIsoCode, Amount, convertCurrency(Amount)
FROM Opportunity
WHERE Id IN ('<synthetic id 1>', '<synthetic id 2>')

-- Aggregate: documented to return currency data in the org default currency
SELECT CurrencyIsoCode, SUM(Amount)
FROM Opportunity
WHERE CloseDate = THIS_QUARTER
GROUP BY CurrencyIsoCode

What the aggregate test must answer. The documentation says aggregate currency data is in the org default currency. It does not say, on the page read here, whether a query grouped by CurrencyIsoCode returns each group's native sum or a converted figure, nor which rate (dated or static) applies. Run the query with two currencies, compare the output to the row-level exports summed in a spreadsheet, and write the answer as a fact about your org and API version, not as a general rule.

Formatting is separate from conversion. The FORMAT() function formats currencies according to the user's locale. A formatted string is not a different amount; do not reconcile formatted text against numeric columns.

The Historical Trending Verification Branch

Historical trending is the least settled surface in this topic. Salesforce Help content on historical trending reports may state that fields labelled Historical use static rates, but this article has not verified that wording and does not treat it as a settled rule for ACM orgs.

There is also an apparent tension that only a test can resolve. The SOQL reference says that, with ACM enabled, dated rates apply to opportunity history when converting through convertCurrency. If the Help wording noted above applies, both statements can be true, because a SOQL query on a history object and a historical trending report are different surfaces. They can also interact in ways nobody has documented in the sources read here.

Verification procedure.

  • Record settings: whether multiple currencies and ACM are enabled, and the corporate currency.
  • List columns: the exact Historical and non-Historical currency columns in the test report, with the report type name.
  • Set two rate regimes: a static rate that differs from the dated rate for the test close date, so the two outcomes are distinguishable.
  • Compare: compute both expected values from the exported rates, then compare each column.
  • Escalate if unclear: if the results contradict the Help text, ask Salesforce Support to clarify and label the case unknown until the answer arrives.

Unresolved cases belong in the ticket as unknown. They do not belong in a footnote that reads like a conclusion.

Figure 02
Row SOQL and aggregate SOQL have different contracts
Row SOQLUser currency
  • Use convertCurrency() in SELECT to convert currency fields to the user's currency; multiple currencies must be enabled.
  • With ACM on, dated rates apply to opportunities, opportunity line items and opportunity history. With ACM off, the most recent entered rate applies.
Aggregate SOQLOrg default currency
  • Queries with GROUP BY or HAVING return aggregate currency data in the org default currency; convertCurrency() cannot convert the aggregate result to user currency.
  • The cited documentation does not establish the rate path or whether grouping by CurrencyIsoCode returns native sums or converted figures. Test both in the org.

The SOQL snippets are untested templates. Record the API version beside sandbox results and compare outputs in one currency.

Step 4: Deciding the Intervention and Documenting It

After the contract mapping, there are three possible outcomes. Table 2 below lists each symptom, the likely cause, and the right action. The principle is to change the narrowest thing that explains the gap.

Table 2: Decision matrix

SymptomLikely cause (to confirm)ActionDo not
ID sets differ between outputsFilter, report type, or grouping mismatchAlign filters and report type; re-runTouch rates
Same IDs, different totals for two peopleDifferent personal currencyDocument the running-user currency; align display currencyEdit shared rates
Report total differs from a formula-based totalDated rate in report, static in formulaDocument the semantics; if a dated result is required, propose a reviewed alternativeRewrite the formula before the rate path is proven
Row SOQL sum differs from aggregate SOQLUser currency versus org default currencyCompare in one currency; document the contractWrap the aggregate in a conversion function
Total moved after a close-date editDifferent dated rate selectedRecord both dates; explain the intervalRevert the date to "match" a screenshot
Total moved after a rate editStatic rate change re-values amountsReview the change record and approvalsRe-edit rates ad hoc
Historical trending differs from live reportUnknownRun the verification branch; label unknownPresent as settled

Table 2 makes the choice explicit. Most rows end in documentation or a display fix, not a configuration change. Where a scoped change is warranted, for example a custom reporting field that captures a dated conversion at a defined event, it should go through a sandbox, a written test plan, and approval, like any other schema change.

Two actions to avoid. First, do not toggle multiple currencies or ACM to make one report match. Trailhead notes that the standard rate control impacts current and closed deals, and a configuration change at that level is org-wide. Second, do not revise dated rates for the same purpose. Dated rates are shared data; editing them moves every opportunity whose close date falls in the interval.

Another trap: rates that look unchanged but are not the same. Trailhead's note that deactivating a currency does not alter amounts in items that use that currency is useful here: an inactive currency can still appear in historical records, so a currency list that looks complete may not describe every record. Include inactive currencies when the rates are exported.

The Ticket Package and Regression Checklist

Attach three things to the reporting ticket: the expected calculation (the filled Table 3), the actual output (screenshots plus exported rows), and the unresolved assumptions (every unknown cell from Table 1). A reviewer can then see which conclusions are evidence and which are inference.

Ticket template.

  • Records: the Opportunity ID list and the join result.
  • Contexts: each output's report type, filters, display currency, running user's personal currency, and as-of time.
  • Settings: multiple currencies and ACM status, corporate currency, active currencies, API version and release, sandbox or production.
  • Rates: exported static and dated rate rows with start dates and the direction check.
  • Calculation: unrounded expected value, rounded expected value, actual value, residual.
  • Decision: document, fix display, or propose a scoped change for review.
  • Unknowns: any row of Table 1 still unknown.

Regression checklist for rate updates and close-date changes.

  • Before a rate update: export the dated and static rate tables, and re-run Table 3 for the synthetic record.
  • After a rate update: re-run the same cases; any change should match the edited interval.
  • Close-date change: move the synthetic record's close date across a rate start; the output must follow the new date.
  • Roll-ups and formulas: re-check every surface marked static or unknown in Table 1.
  • Historical trending: repeat the verification branch after any ACM setting change.
  • Two-user check: open the same report as two users with different personal currencies.
  • Aggregate versus row: rerun the pair of SOQL snippets above and confirm the contract has not changed at the new API version.

Data Analysis and Evidence: A Reconciliation Sheet on One Synthetic Opportunity

The sheet below uses a synthetic opportunity and fictional rates. None of the rates is market data, benchmark data, or an accounting record. They are placed in the example so the arithmetic can be checked. In a real exercise, replace them with rates exported from your own sandbox.

Convention. Salesforce documentation describes rates as entered relative to the corporate currency. If each rate is defined as units of that currency per one unit of corporate currency, with the corporate currency at 1, then the cross conversion is converted = source amount / source rate x target rate. Do not apply this formula until you confirm the direction against exported rates. Other platforms define direction differently, so the convention cannot be assumed: HubSpot, for example, documents a rate that converts the new currency to the company currency [12], while Microsoft Dataverse defines an exchange rate between a transaction currency and the base currency [13]. HubSpot also documents point-in-time semantics: open deals use the latest rate [12], while closed deals use the rate in effect at the specified close date [12]. That is a product-specific rule, and it should not be read across to Salesforce.

Public rate series add more conventions. The European Central Bank quotes all currencies against the euro as base currency (Source: www.ecb.europa.eu), and it states that using its reference rates for transaction purposes is strongly discouraged (Source: www.ecb.europa.eu). The US Federal Reserve H.10 release publishes daily rates of exchange of major currencies against the US dollar [14], defined as noon buying rates in New York [14]. Dynamics 365 Finance documents a cross rate as a rate entered to translate directly between two currencies without translating through USD [15], and the ECB framework uses a euro cross rate calculated from a rate against a major currency (Source: www.ecb.europa.eu). The lesson for the sheet is narrow: base currency, direction and date vary by source, so rates copied from a public series must pass a direction check, and none was used in this report.

Fictional configuration. Corporate currency: USD (rate 1.0000). Static rates (units per 1 USD): EUR 0.8800, GBP 0.7600. Dated EUR rate: 0.9000 from 2026-01-01, 0.8500 from 2026-04-01. Dated GBP rate: 0.7500 from 2026-01-01, 0.7200 from 2026-04-01. Synthetic opportunity SYN-001: Amount EUR 120,000.00.

Table 3 below shows the expected values under each path. The expected values were computed with exact decimal arithmetic before rounding, then rounded half up to two places for display.

Table 3: Reconciliation sheet (all rates fictional; expected values only, no actual org output)

CaseSource amount and ISOTarget ISORate pathEffective intervalExpected, unroundedExpected, 2 dpActual (fill in)Residual
AEUR 120,000.00USDDated EUR 0.9000, close date 2026-03-152026-01-01 to 2026-03-31133,333.3333133,333.33blankblank
BEUR 120,000.00USDStatic EUR 0.8800Not date-based136,363.6364136,363.64blankblank
CEUR 120,000.00GBPDated EUR 0.9000, GBP 0.7500, close 2026-03-152026-01-01 to 2026-03-31100,000.0000100,000.00blankblank
DEUR 120,000.00GBPStatic EUR 0.8800, GBP 0.7600Not date-based103,636.3636103,636.36blankblank
EEUR 120,000.00USDDated EUR 0.8500, close date moved to 2026-04-01From 2026-04-01141,176.4706141,176.47blankblank
FEUR 120,000.00GBPDated EUR 0.8500, GBP 0.7200, close 2026-04-02From 2026-04-01101,647.0588101,647.06blankblank

Table 3 is read column by column. Cases A and B show a 3,030.31 USD gap between the rounded values (136,363.64 minus 133,333.33) produced only by choosing static over dated rates, with no data error. Cases C and D show the same split through a EUR to GBP cross conversion. Cases E and F show that moving the close date across a rate start changes the answer even though the source amount and currency did not change.

Three readings of the sheet are worth fixing in advance:

  • Same row, different value: a candidate defect, worth a ticket after the ID join is confirmed.
  • Value equals another row's expected value: a rate-path difference, so document the contract.
  • Difference of a cent or two only: a rounding observation, so record the rounding mode and the step.

The "Actual" and "Residual" columns are deliberately blank. Filling them in is the sandbox exercise. A residual is actual minus expected. Compare before rounding where the output exposes enough precision, then at the output's displayed precision, and record both. No universal tolerance applies: a residual of zero at displayed precision and a non-zero residual before rounding is a rounding observation, and a residual that matches another row's expected value is a rate-path observation.

Rounding is its own variable. Consider three line amounts of EUR 10.04 at the fictional 0.9000 rate. Each converts to 11.1556 before rounding, 11.16 after. Three rounded rows sum to 33.48. The unrounded total is 33.4667, which rounds to 33.47. The one-cent difference appears with no rate error and no configuration problem. Which rounding Salesforce applies at which step is not established by the sources read here, so the rounding step in each surface should be treated as a test item. Binary floating point prevents reliable equality testing and differences can accumulate [16], which is why decimal arithmetic is preferred in accounting applications [16]. Spreadsheets add their own variables: Excel stores about 15 significant digits [17], attributes that to IEEE 754 [17], and offers the ROUND function, which rounds a number to a specified number of digits [18], and a "precision as displayed" option to compensate [17]. The latter forces each number to be its displayed value [17]. Python's decimal module represents decimal numbers exactly [16] and defaults to round-half-even, where ties go to the nearest even integer [16], unlike round-half-up, where ties go away from zero [16]. Google Sheets rounds a digit of 5 or greater up [19]. A reconciliation sheet should state its rounding mode explicitly.

Currency precision. ISO 4217 is the international standard for currency codes, represented numerically and alphabetically [20], and it records whether a currency divides into 100 or 1000 subunits [20]. SIX Financial Information AG acts as the secretariat of the maintenance agency [20], describes itself as the official maintenance agency [21], and its data includes minor unit information [21]. Decimal places differ by currency, so a "two decimals" assumption is itself a test item for JPY or other currencies you enable.

Implications and Future Directions

A reusable pattern. The reconciliation sheet is useful beyond currency. Any converted or derived field (tax, units, scored values) can be treated as a contract with an input, a rule, a context and an output. Writing the contract down first prevents the "fix" from becoming the next incident.

Where AI assistance fits. Read-only AI assistance is well suited to the collection stage: inventorying accessible report definitions, field types and configured rates, matching outputs by stable IDs, and flagging mismatched contexts. It must not supply invented historical exchange rates, silently change the corporate currency, or describe an estimate as an accounting record. An assistant connected to Salesforce does not replace sandboxes, change control or review. A human should verify rate selection and formulas in a spreadsheet; a narrated explanation is not evidence.

Watch items. Four items should be re-read at each release: the Help considerations page for the ACM scope; the SOQL reference for aggregate behavior; the Help article on historical trending, whose wording on static versus dated rates should be confirmed; and the object reference for the rate objects. Those re-reads are the main way to raise the status of the unknown cells.

Limits of this report. No sandbox experiment, org-level change, or financial benchmark was performed. Some sources are practitioner blogs rather than Salesforce documentation, and are labelled as such. Search demand for this topic is small and could not be measured precisely; no traffic or ranking claim is made.

Frequently Asked Questions (FAQs)

Why do Salesforce currency totals disagree? Because each surface has its own conversion contract: target currency, rate type, and date selector. A standard Opportunity report, a formula, an aggregate query and a forecast are different contracts, as Table 1 sets out.

Why don't my Salesforce report currency totals match a data export? Check the ID sets first. Then check whether the export used the record's own Amount or a converted column, and whether the SOQL was row-level or aggregate.

Why does a multi-currency report show wrong totals for one user? The user's personal currency is the default currency in reports. Compare personal currencies before suspecting data.

What is the difference between dated exchange rates and conversion rates? Static conversion rates are one set that applies to all currency fields in the org. Dated rates map a rate to a start date and, per the sources read here, apply to a defined set of opportunity-related fields.

How can an ACM report differ from a formula? One source states that a formula built on CURRENCYRATE() uses the standard exchange rate while the converted column follows the close date. A vendor's documentation says formulas cannot reference dated rates.

Is the converted amount different from the Amount field? Yes. The Amount column shows the record currency and the converted column shows the viewing user's currency, according to one practitioner write-up.

Why does the dashboard differ from the report? Not established in the sources read here. Treat the dashboard as unknown, run it as two users, and compare to the source report.

Which rate does a given opportunity use? For an ACM org, the rate that corresponds to the close date. Without ACM, the most recent rate.

How do I audit exchange rates? Export static and dated rate rows with start dates, check direction against the corporate-currency convention, and rebuild the expected values in a spreadsheet with an explicit rounding mode.

Conclusion

Currency totals in Salesforce disagree when outputs sit on different rate paths: static versus dated, user currency versus org default currency, record currency versus converted column, or the same path viewed by users with different personal currencies. Documented sources support several rows of the rate-path matrix: opportunity data under ACM follows the close date, row SOQL converts to the user's currency, aggregate SOQL returns the org default currency, and static rate edits re-value existing amounts. Other rows remain unknown, namely forecasts under ACM, dashboards, and historical trending.

The practical order of work is fixed: capture both outputs, join on record IDs, map each contract, compute the expected values from exported rates, and only then decide. In most cases the correct intervention is a filter or display correction or a documented explanation. A scoped configuration proposal belongs in a sandbox with approval. Altering multi-currency settings or dated rates to make one screenshot match is the one step the evidence here does not support.

External Sources (21)

About

Cirra AI

About Cirra AI

Cirra AI is a software company dedicated to reinventing Salesforce administration through AI-powered tooling built on the Model Context Protocol (MCP). From its headquarters in Silicon Valley, the team has built the first commercial MCP server for Salesforce administration—a hosted service that lets any MCP-compatible AI tool (Claude, ChatGPT, Cursor, and others) connect to a Salesforce org and execute admin tasks through natural language. The product gives Salesforce administrators, revenue-operations teams, and consulting partners the ability to implement configuration changes in minutes instead of hours, while respecting org permissions and maintaining full auditability. Cirra AI's mission is to "let humans focus on design and strategy while software handles the clicks." To achieve that, the company develops two complementary product lines: Salesforce Admin MCP Server – A fully hosted MCP endpoint that connects any AI tool to Salesforce in minutes via OAuth. Administrators describe what they need in plain English—create custom objects and fields, configure page layouts, manage permission sets, build flows, provision users, generate documentation—and the MCP server translates those instructions into standard Salesforce Metadata and Tooling API calls, bounded by the user's existing permissions. No local infrastructure or custom code is required: sign up, authenticate, copy the MCP URL into your AI tool, and start working. Salesforce Skills Library – An open-source collection of domain-specific skills (available at skills.cirra.ai) that supercharge AI assistants with deep Salesforce expertise. Skills cover Apex development with 150-point scoring, Flow creation and validation with 110-point scoring, Lightning Web Component development with the PICKLES architecture methodology, metadata operations, permission auditing, data and SOQL operations, org-wide health audits, architecture diagramming, and Kugamon CPQ management. The skills are installable as a single plugin for Claude Cowork, Claude Code, and OpenAI Codex, or as individual skill files for Claude web, desktop, and ChatGPT. They enable AI assistants to perform complex, multi-step Salesforce tasks independently—run a comprehensive org audit, fix issues flagged in the report, generate field descriptions at scale—without prompt-by-prompt hand-holding. Together, these products address three chronic pain points in the Salesforce ecosystem: (1) the high cost of manual administration and repetitive setup-menu navigation, (2) the backlog created by scarce expert capacity, and (3) the risk of inconsistent, undocumented changes. Early adopter feedback shows time-on-task reductions of 70–90 percent for routine configuration work.

Leadership

Cirra AI was founded in 2024 by Jelle van Geuns, a Dutch-born engineer, serial entrepreneur, and veteran of the Salesforce ecosystem with over 14 years of platform experience. Before Cirra, Jelle bootstrapped Decisions on Demand, an AppExchange ISV whose rules-based lead-routing engine is used by multiple Fortune 500 companies. Under his leadership the firm reached seven-figure ARR without external funding, demonstrating a combination of deep technical innovation and pragmatic go-to-market execution. Jelle began his career at ILOG (later IBM), where he managed global solution-delivery teams and developed expertise in enterprise optimisation and AI-driven decisioning. He holds an M.Sc. in Computer Science from Delft University of Technology and speaks frequently on AI-assisted administration, MCP integration patterns, and human-in-the-loop automation at Salesforce community events and podcasts. The leadership team includes Jeff Bajayo (VP Sales), a seasoned Salesforce and SaaS professional with over a decade of experience, and Latrice Barnett (Advisor, Marketing), who brings 10+ years of partnership and ecosystem marketing expertise from the Salesforce ecosystem.

Why Cirra AI Matters

MCP-native architecture – Rather than building a proprietary agent UI, Cirra embraces the Model Context Protocol as a universal connector, letting customers use the AI tool they already prefer—Claude, ChatGPT, Cursor, or any future MCP-compatible client—while Cirra handles the Salesforce integration layer. Deep vertical focus – The Skills Library encodes thousands of Salesforce best-practice patterns, scoring rubrics, and validation scripts that generic AI assistants lack. This domain intelligence produces higher-quality, more reliable outputs for Apex, Flows, LWC, permissions, and metadata operations than general-purpose prompting alone. Enterprise-grade security – The platform uses OAuth authentication, encrypted endpoints, and inherits the connected user's Salesforce permission model. Cirra never stores Salesforce credentials, and all actions are logged for auditability—critical requirements for regulated industries adopting AI tooling. Works for admins and partners alike – Individual administrators use Cirra to eliminate setup-menu drudgery and respond faster to business requests. Consulting firms use it to scale senior-level expertise across delivery teams, enabling more projects delivered at higher quality and lower cost through improved documentation and test coverage. Accessible to non-developers – Anyone with a paid Claude or ChatGPT subscription can install the skills and connect the MCP server. No coding, no complex integrations—just sign up and start working.

Future Outlook

Cirra AI continues to expand its capabilities with the upcoming Admin Agent (launching June 2026), which will bring fully autonomous multi-step task execution to Salesforce administration. The company is also extending platform compatibility to additional AI marketplaces and broadening its skills library to cover more Salesforce clouds and use cases. By combining open standards, domain-specific intelligence, and a relentless focus on the admin experience, Cirra AI is building the de-facto AI integration layer for Salesforce administration.

Disclaimer

This document is provided for informational purposes only. No representations or warranties are made regarding the accuracy, completeness, or reliability of its contents. Any use of this information is at your own risk. Cirra AI shall not be liable for any damages arising from the use of this document. This content was generated with assistance from artificial intelligence tools, which may contain errors or inaccuracies. Readers should verify critical information independently. All product names, trademarks, and registered trademarks mentioned are property of their respective owners and are used for identification purposes only. Use of these names does not imply endorsement. This document does not constitute professional or legal advice. For specific guidance related to your needs, please consult qualified professionals.