Scenarios and outcomes
This page outlines the different matching scenarios we support and what they lead to.
Residual handling
A residual is the leftover difference between the bank movement and the documents matched against it, defined as the transaction total minus the matched-document total (txTotal − docTotal). A positive residual means the bank received/paid more than the documents account for; a negative residual means less. When a match is materialized, Atlar resolves the residual through a fixed precedence — each step only runs if the previous one has not already fully explained the gap.
1. Included transaction charges. If the bank reports charges that were deducted from the transaction (Charges flagged as INCLUDED), they are aggregated per transaction and booked as a journal entry against the GL account configured on the BANK_FEE posting rule. This represents fees the bank withheld from the gross amount, so the document can still be settled in full.
2. Residual-driven creation templates. Any residual still remaining is offered to creation templates triggered by its sign — ON_POSITIVE_RESIDUAL or ON_NEGATIVE_RESIDUAL. These let you explain the residual with a configured document, for example a credit memo absorbing an under-payment or an over-payment document for an excess receipt.
3. Tolerance fallback. If no template handled the leftover, the residual (after charges and any fixed-amount ALWAYS-template lines) is checked against the posting rule selected by its direction and whether the match is cross-currency. The rule is accepted only if the residual is within that rule's ThresholdBasisPoints:
| Cross-currency | Residual sign | Posting rule | Outcome within threshold |
|---|---|---|---|
| Yes | Positive | FX_GAIN | Accepted silently; no journal entry booked |
| Yes | Negative | FX_LOSS | Accepted silently; no journal entry booked |
| No | Positive | OVERPAYMENT | An unapplied payment is emitted against the matched counterparty |
| No | Negative | BANK_FEE | A balancing journal entry is booked against the rule's GL account |
Only BANK_FEE posts to a configured GL account; FX_GAIN, FX_LOSS, and OVERPAYMENT are threshold-only or counterparty-driven and do not require one. | |||
Hard failures. If the applicable posting rule is missing, or the residual exceeds the rule's ThresholdBasisPoints, the match cannot be materialized and is rejected at match-create time (with AmountMismatch). The configuration must be corrected before the match can complete — Atlar never silently books an unexplained difference. |
Currency and exchange-rate handling
Three currencies matter for any match: the document currency (what the invoice or payment is denominated in), the bank account currency (what the transaction actually settled in), and the GL entity's base currency (the subsidiary's reporting currency). A match is cross-currency whenever these don't line up in a way that requires conversion, and Atlar's job is to decide whether an exchange rate is needed, what that rate is, and where to record it.
When an exchange rate is involved
ERP systems only support cross-currency settlement from an account denominated in the base currency. That constraint produces a fixed set of allowed combinations:
| Document currency | Bank currency | Base currency | Outcome |
|---|---|---|---|
| EUR | EUR | EUR | Exact match; no FX rate |
| GBP | GBP | EUR | Exact match; no FX rate (same instructed currency settles in itself) |
| GBP | EUR | EUR | Cross-currency; matched within tolerance and the document is patched with an FX rate |
| EUR | GBP | EUR | Not allowed (foreign account cannot settle the base currency) |
| USD | GBP | EUR | Not allowed (two foreign currencies) |
| A leg that settles in its own currency carries no exchange rate even when the subsidiary's base currency differs — the ERP handles that translation itself. |
How the rate is determined
When a match is materialized, document amounts must be expressed in the bank currency to compute the residual. Atlar selects the rate through a fixed precedence:
1. Transaction-provided rate. If the bank transaction carries a usable currencyExchange (both currencies set and different), the document's instructed amount is converted using that rate. This is the primary path and the rate the bank reported is the one used. When that quote is coarsely rounded, it may be refined — see Rate sharpening below.
2. Base-amount agreement (fallback). If no transaction rate is available and the match is not MANUAL, Atlar checks whether the sum of the documents' baseAmount exactly equals the bank transaction total. If it does, documents are valued by their baseAmount — the ERP and bank already agree on the base-currency figure, so no rate needs to be derived. Each outgoing document still carries its own currencyExchange as ERP metadata.
3. Totals-derived rate (MANUAL only). For manually created matches, when no transaction rate is present Atlar may derive a rate from the document and transaction totals. If none of these apply — for example a baseAmount is present but does not exactly match the transaction total — the fee-versus-FX difference is ambiguous and the match is rejected with AmountMismatch. The same rejection occurs when documents lack a usable baseAmount in the bank currency and no transaction rate exists.
No-document transfers
For transfers between the customer's own accounts with no ERP document, the rate is sourced from the bank movements themselves, in this order:
- Bank-provided rate on a leg — if either the sending or receiving leg carries an explicit rate, that rate is used and recorded on that leg.
- Derived from the two amounts — otherwise the rate is implied by the sending and receiving amounts.
- Rounding sharpened — when the residual is purely bank-rate rounding, the rate is sharpened to the precision implied by the amounts rather than booking a spurious over-payment (see below).
Rate sharpening (rounded bank quotes)
Banks usually quote an exchange rate at coarse precision (often two decimals, e.g. 1.15). Re-applying that rounded rate in the reverse direction can lose a minor unit — 10,000.00 GBP × 1.15 = 11,500.00 EUR, but the movement net of charges was actually 11,511.50 EUR, implying 1.15115. Left alone, that gap looks like a residual (a spurious over-payment or fee). Rate sharpening replaces the rounded quote with the precise rate implied by the amounts, so the match balances exactly and no bogus residual document is booked. Sharpening only ever refines the bank's own quote — it never fabricates a rate to absorb a genuine difference. It is applied under strict guards:
- A bank rate must already exist. The transaction must carry an FX quote; sharpening never runs when there is no bank rate to refine (so it cannot stand in for the totals-derivation path, which remains
MANUAL-only). - The quote must be rounded. Integer rates (zero fractional digits) are skipped — there is nothing to sharpen.
- The gap must be within the rounding budget. The residual must be small enough to be explained purely by the quote's precision; anything larger is treated as a real residual and left to normal residual handling.
- The precise rate must round back to the quote. The rate derived from the amounts, rounded to the bank quote's number of decimals, must equal the quoted rate. This proves it is the same rate at higher precision, not a different one.
- The residual must go to exactly zero. The match is re-valued with the sharpened rate and only adopted if the remaining difference is exactly nil. When all guards pass, the sharpened rate supersedes the bank quote and is the rate stamped on the resulting document or transfer leg:
- Document-backed matches — the created payment (or patched instruction) carries the sharpened rate instead of the bank's per-transaction quote.
- No-document transfers — the rate is derived from the converting leg's booked and instructed amounts, using the gross that actually crossed (booked minus fee on a sending leg, booked plus fee on a receiving leg), and stamped on that foreign leg so the clearing account nets to zero in the base currency.
Where the rate is recorded
The exchange rate is attached to the converting side of the match — the document or journal leg that is not already in the settlement currency:
- Document-backed matches — the created payment (or patched instruction document) carries the FX rate.
- Intra-/intercompany transfers — only the leg whose bank account differs from the settlement currency carries a
currencyExchange; the leg already in the settlement currency carries none.
Scenarios
The scenarios below show how Atlar materializes a confirmed reconciliation match into accounting documents, and how those land in NetSuite. Unless noted, the GL entity's base currency is EUR and GBP is the foreign currency (cross-currency settlement is only possible from a base-currency account); amounts are signed by direction (+ inbound, − outbound). In the Documents column, a SOURCE document (e.g. an invoice) causes a new payment to be created and applied, an INSTRUCTION document (e.g. an existing payment or journal entry) is patched with the transaction's date and any FX rate, and None means a creation template defines the entry. The Residual column explains any gap between the bank movement and the documents, resolved in order: included charges, then residual-driven creation templates, then a tolerance fallback (bank fee, over-payment, or absorbed FX difference).
| # | Scenario | Documents | Transaction(s) | Residual | Result in Atlar | Result in NetSuite |
|---|---|---|---|---|---|---|
| Exact matches (no residual) | ||||||
| 1 | Interest credit matched against no document | None | Inbound EUR +25.00 | None — creation template defines the entry | Journal entry created: debit bank account, credit interest income account. | Journal entry created: debit bank account, credit interest income account. |
| 2 | Outbound bank service charge matched against no document | None | Outbound EUR −5.00 | None — creation template defines the entry | Journal entry created: credit bank account, debit bank fee account. | Journal entry created: credit bank account, debit bank fee account. |
| 3 | Customer invoice matched exactly | Customer invoice (SOURCE) EUR +100.00 | Inbound EUR +100.00 | None (exact match) | Payment created, applied to invoice. | Customer payment created, applied to invoice. |
| 4 | Customer invoice in GBP matched exactly against GBP bank transaction | Customer invoice (SOURCE) GBP +100.00 (EUR 113.00 base) | Inbound GBP +100.00 | None (exact match — same instructed currency, no FX needed) | Payment created in GBP, applied to invoice. | Customer payment created in GBP, applied to invoice. |
| 5 | Vendor invoice matched exactly | Vendor invoice (SOURCE) EUR −75.00 | Outbound EUR −75.00 | None (exact match) | Payment created, applied to invoice. | Bill payment created, applied to bill. |
| 6 | Customer payment matched exactly | Customer payment (INSTRUCTION) EUR +100.00 | Inbound EUR +100.00 | None (exact match) | Existing payment patched with transaction date. | Customer payment patched with transaction date. |
| 7 | Undeposited customer payment matched against bank deposit | Customer payment (SOURCE) EUR +100.00 posted against Undeposited Funds transit account | Inbound EUR +100.00 | None (exact match) | Payment created, applied to source payment document. | Deposit created, moving funds from Undeposited Funds to bank account. |
| 8 | Vendor payment matched exactly | Vendor payment (INSTRUCTION) EUR −75.00 | Outbound EUR −75.00 | None (exact match) | Existing payment patched with transaction date. | Bill payment patched with transaction date. |
| 9 | Journal entry matched against transaction | Journal entry (INSTRUCTION) EUR +25.00 with bank line | Inbound EUR +25.00 | None (exact match) | Existing journal entry patched with transaction date. | Journal entry patched with transaction date. |
| 10 | Customer credit memo matched against transaction | Customer credit memo (SOURCE) EUR −25.00 | Outbound EUR −25.00 | None (exact match, sign inverted) | Payment created with negative amount, applied to credit memo. | N/A — customer refund requires a Refund Method. |
| 11 | Customer refund matched against transaction | Customer payment (INSTRUCTION) EUR −25.00 | Outbound EUR −25.00 | None (exact match) | Existing payment patched with transaction date. | Customer refund patched with transaction date. |
| Same-currency residuals | ||||||
| 12 | Customer invoice greater than transaction — bank fee on charges field | Customer invoice (SOURCE) EUR +100.00 | Inbound EUR +98.00 (with EUR 2.00 included charge) | Bank fee (charges field) explains EUR 2.00 residual | Payment created for full EUR 100.00 applied to invoice + journal entry for EUR 2.00 bank fee. | Customer payment created, applied to invoice with full EUR 100.00. Journal entry created debiting Reconciliation Configuration's bank fee account. |
| 13 | Transaction greater than vendor invoice — bank fee on charges field | Vendor invoice (SOURCE) EUR −75.00 | Outbound EUR −75.15 (with EUR 0.15 included charge) | Bank fee (charges field) explains EUR 0.15 residual | Payment created for EUR −75.00 applied to invoice + journal entry for EUR 0.15 bank fee. | Bill payment created, applied to bill with full EUR 75.00. Journal entry created debiting Reconciliation Configuration's bank fee account. |
| 14 | Customer invoice greater than transaction — creation template explains residual (e.g. credit memo) | Customer invoice (SOURCE) EUR +100.00 | Inbound EUR +90.00 | EUR 10.00 underpayment — creation template (credit memo) absorbs residual | Payment created for EUR 90.00 applied to invoice + credit memo created for EUR 10.00. | ⚠️ Pending implementation. Customer payment created, applied to invoice with EUR 90.00. Credit memo created, applied to invoice with EUR 10.00. |
| 15 | Transaction greater than vendor invoice — creation template explains residual (e.g. journal entry) | Vendor invoice (SOURCE) EUR −100.00 | Outbound EUR −110.00 | EUR 10.00 overpayment — creation template (journal entry) absorbs residual | Payment created for EUR −100.00 applied to invoice + journal entry created for EUR 10.00. | Bill payment created, applied to bill with EUR 100.00. Journal entry created for EUR 10.00. |
| 16 | Transaction greater than customer invoice — creation template explains residual (e.g. overpayment payment) | Customer invoice (SOURCE) EUR +100.00 | Inbound EUR +110.00 | EUR 10.00 overpayment — creation template (payment) absorbs residual | Payment created for EUR 100.00 applied to invoice + customer deposit created for EUR 10.00. | ⚠️ Pending implementation. Customer payment created, applied to invoice with EUR 100.00. Unapplied customer payment of EUR 10.00 created. |
| 17 | Transaction greater than customer invoice — residual within overpayment tolerance | Customer invoice (SOURCE) EUR +100.00 | Inbound EUR +110.00 | EUR 10.00 overpayment within tolerance | Payment created for EUR 100.00 applied to invoice + overpayment payment for EUR 10.00. | Customer payment created, applied to invoice with EUR 100.00. Customer deposit of EUR 10.00 created. |
| 18 | Customer invoice greater than transaction — residual within bank fee tolerance | Customer invoice (SOURCE) EUR +100.00 | Inbound EUR +99.00 | EUR 1.00 residual within bank fee tolerance — treated as fee | Payment created for full EUR 100.00 applied to invoice + journal entry for EUR 1.00 bank fee. | Customer payment created, applied to invoice with full EUR 100.00. Journal entry created debiting Reconciliation Configuration's bank fee account. |
| 19 | Transaction greater than vendor invoice — residual within overpayment tolerance | Vendor invoice (SOURCE) EUR −100.00 | Outbound EUR −110.00 | EUR 10.00 residual within tolerance — treated as overpayment (ambiguous between fee and overpayment; optimistically treated as overpayment) | Payment created for EUR −100.00 applied to invoice + vendor prepayment payment for EUR −10.00. | Bill payment created, applied to bill with EUR 100.00. Vendor prepayment created for EUR 10.00. |
| Multi-document and multi-transaction cardinality | ||||||
| 20 | One transaction pays multiple customer invoices | Three customer invoices (SOURCE) EUR +100.00 / +120.00 / +80.00 | Inbound EUR +300.00 | None (exact match across all invoices) | One payment per invoice created (3 payments), each applied to its invoice. | One customer payment created per invoice. |
| 21 | One transaction pays multiple vendor invoices | Three vendor invoices (SOURCE) EUR −100.00 / −120.00 / −80.00 | Outbound EUR −300.00 | None (exact match across all invoices) | One payment per invoice created (3 payments), each applied to its invoice. | One bill payment created per bill. |
| 22 | Two transactions settle one customer invoice | Customer invoice (SOURCE) EUR +250.00 | Inbound EUR +150.00 + Inbound EUR +100.00 | None (transactions sum to invoice amount) | One payment per transaction created (2 payments), both applied to the same invoice. | One customer payment created per transaction, applied to the same invoice. |
| 23 | Two transactions settle one vendor invoice | Vendor invoice (SOURCE) EUR −250.00 | Outbound EUR −150.00 + Outbound EUR −100.00 | None (transactions sum to invoice amount) | One payment per transaction created (2 payments), both applied to the same invoice. | One bill payment created per transaction, applied to the same bill. |
| 24 | One payment instruction settled by multiple bank movements | Vendor payment (INSTRUCTION) EUR −300.00 | Multiple outbound EUR movements summing to EUR −300.00 | None (transactions collectively settle instruction) | Existing payment patched with transaction date. | Multiple transactions give no unambiguous date to patch, so the document keeps its own date. |
| 25 | Batch payment run debits bank once, covers multiple payment instructions | Three vendor payment instructions (INSTRUCTION) EUR −100.00 / −120.00 / −80.00 | Single outbound EUR −300.00 | None | Each instruction patched with transaction date (3 patches). | Bill payments patched with transaction date. |
| 26 | Mixed instruction and source — payment instruction plus the invoice it pays | Vendor payment (INSTRUCTION) EUR −50.00 + Vendor invoice (SOURCE) EUR −50.00 | Single outbound EUR −100.00 | None | Existing payment instruction patched with transaction date + new payment created applied to invoice. | Bill payment patched with transaction date + bill payment created, applied to bill. |
| Cross-currency (explicit exchange rate) | ||||||
| 27 | Customer invoice differs from transaction — explicit exchange rate explains residual | Customer invoice (SOURCE) GBP +100.00 | Inbound EUR +115.00 with explicit GBP/EUR 1.15 rate | FX difference explained by exchange rate | Payment created in GBP 100.00 with FX rate attached, applied to invoice. | Customer payment created with FX rate reported on transaction, applied to invoice. |
| 28 | Vendor invoice differs from transaction — explicit exchange rate explains residual | Vendor invoice (SOURCE) GBP −100.00 | Outbound EUR −115.00 with explicit GBP/EUR 1.15 rate | FX difference explained by exchange rate | Payment created in GBP −100.00 with FX rate attached, applied to invoice. | Bill payment created with FX rate reported on transaction, applied to bill. |
| 29 | Customer payment differs from transaction — explicit exchange rate explains residual | Customer payment (INSTRUCTION) GBP +100.00 | Inbound EUR +115.00 with explicit GBP/EUR 1.15 rate | FX difference explained by exchange rate | Existing payment patched with transaction date and FX rate. | Customer payment patched with transaction date and FX rate. |
| 30 | Vendor payment differs from transaction — explicit exchange rate explains residual | Vendor payment (INSTRUCTION) GBP −100.00 | Outbound EUR −115.00 with explicit GBP/EUR 1.15 rate | FX difference explained by exchange rate | Existing payment patched with transaction date and FX rate. | Bill payment patched with transaction date and FX rate. |
| 31 | Transaction greater than vendor invoice — residual is bank-rate rounding, rate sharpened | Vendor invoice (SOURCE) GBP −10,000.00 | Outbound EUR −11511.5 with GBP/EUR 1.15 rate | Residual is bank-rate rounding — rate sharpened to 1.15115, no overpayment booked | Payment created in GBP −10,000.00 with sharpened FX rate. | Bill payment created with a deduced rate; the rate reported by the bank is assumed to be rounded. |
| Intracompany transfers | ||||||
| 32 | Intracompany transfer, same currency, no documents | None | Outbound EUR −100.00 (sending) + Inbound EUR +100.00 (receiving) | None | Two journal entries created: one per leg, each with bank + clearing lines. | Two journal entries created, balanced against the specified clearing account. |
| 33 | Intracompany cross-currency transfer, no documents | None | Outbound EUR −115.00 (sending) + Inbound GBP +100.00 (receiving) | None — FX rate derived from the two amounts | Two journal entries created: sending leg in EUR, receiving leg in GBP with FX rate attached. | Two journal entries created, balanced against the specified clearing account. |
| 34 | Intracompany transfer matched with existing journal entry | Intracompany journal entry (INSTRUCTION) EUR | Outbound EUR −100.00 + Inbound EUR +100.00 | None (exact match) | Existing journal entry patched with transaction date. | Journal entry patched with sending transaction date. |
| 35 | Intracompany transfer — single receiving leg reconciled with its journal entry, same currency | Intracompany journal entry (INSTRUCTION) GBP | Inbound GBP +100.00 | None (same currency, FX not refreshed) | Existing journal entry patched with transaction date. | Journal entry patched with transaction date. |
| 36 | Intracompany transfer — single sending leg reconciled with its journal entry, cross-currency | Intracompany journal entry (INSTRUCTION) GBP | Outbound GBP −100.00 (EUR base entity) | FX rate applied | Existing journal entry patched with transaction date and FX rate. | Journal entry patched with transaction date and FX rate. |
| 37 | Intracompany cross-currency transfer matched with existing TRANSFER document | Transfer document (INSTRUCTION) GBP | Outbound GBP −100.00 (sending, EUR base) + Inbound EUR +115.00 (receiving) | None — rate taken from converting (sending) leg | Existing transfer document patched with FX rate. | ⚠️ Not supported. NetSuite does not allow API operations on transfers; this is a no-op. |
| 38 | Intracompany cross-currency transfer, no documents — FX difference absorbed into derived rate | None | Outbound EUR −115.00 + Inbound GBP +100.00 (amounts imply rate) | Small FX difference absorbed into derived rate | Two journal entries created with derived FX rate. | Two journal entries created, each balancing a clearing account. Derived FX rate put on receiving leg. |
| 39 | Intracompany cross-currency transfer, no documents — bank rate from receiving leg | None | Outbound EUR −115.00 + Inbound GBP +100.00 (bank-provided rate on receiving leg) | None — rate taken from receiving leg | Two journal entries created with receiving-leg FX rate. | Two journal entries created, each balancing a clearing account. Reported FX rate put on receiving leg. |
| 40 | Intracompany cross-currency transfer, no documents — bank rate from sending leg | None | Outbound EUR −115.00 (bank-provided rate on sending leg) + Inbound GBP +100.00 | None — rate taken from sending leg | Two journal entries created with sending-leg FX rate. | Two journal entries created, each balancing a clearing account. Reported FX rate put on sending leg. |
| 41 | Intracompany cross-currency transfer, no documents — foreign account sends to base account | None | Outbound GBP −100.00 (foreign account) + Inbound EUR +115.00 (base account) | None — rate taken from sending leg | Two journal entries created: sending leg in GBP with FX rate, receiving leg in EUR. | Two journal entries created, each balancing a clearing account. Reported FX rate put on sending leg. |
| 42 | Intracompany transfer, no documents, creation template adds extra line (e.g. bank fee) | None | Outbound EUR −100.00 (sending) + Inbound EUR +99.00 (receiving) | Bank fee via creation template additional line | Two journal entries created: additional line on sending leg. | Two journal entries created, each balancing a clearing account. Sending leg with an additional fee line. |
| Intercompany transfers | ||||||
| 43 | Intercompany transfer, same currency, no documents | None | Outbound EUR −100.00 (entity A) + Inbound EUR +100.00 (entity B) | None — auto-balanced at ERP | Two journal entries created, one per entity; bank lines auto-balanced against IC AR/AP at ERP. | Advanced Intercompany Journal created, auto-balanced by NetSuite. |
| 44 | Intercompany cross-currency transfer, no documents | None | Outbound EUR −115.00 (entity A) + Inbound GBP +100.00 (entity B) | None — FX rate derived | Two journal entries created with FX rate. | Advanced Intercompany Journal created with FX rate on the line belonging to subsidiary A, auto-balanced by NetSuite. |
| 45 | Intercompany transfer, creation-template fee line on sending side, no bank rate | None | Outbound EUR −100.00 (entity A) + Inbound EUR +99.00 (entity B) | EUR 1.00 fee added via creation template | Two journal entries created with an explicit fee line on the sending side. | Advanced Intercompany Journal created with fee line belonging to subsidiary A, auto-balanced by NetSuite. |
| 46 | Intercompany transfer, creation-template fee line on receiving side, no bank rate | None | Outbound EUR −100.00 (entity A) + Inbound EUR +99.00 (entity B) | EUR 1.00 fee added via creation template | Two journal entries created with an explicit fee line on the receiving side. | Advanced Intercompany Journal created with fee line belonging to subsidiary B, auto-balanced by NetSuite. |
| 47 | Intercompany transfer matched with IC journal, both subs EUR, both accounts EUR | Intercompany journal entry pair (INSTRUCTION) EUR | Outbound EUR + Inbound EUR | None (exact match) | Both journal entries patched with transaction date. | Advanced Intercompany Journal patched with sending transaction date. |
| 48 | Intercompany transfer matched with IC journal, both subs EUR, receiver account GBP | Intercompany journal entry pair (INSTRUCTION) | Outbound EUR + Inbound GBP | FX rate attached on sending leg | Both journal entries patched; FX rate applied to sending leg. | Advanced Intercompany Journal created with FX rate on the line belonging to subsidiary A, auto-balanced by NetSuite. |
| 49 | Intercompany transfer matched with IC journal, both subs EUR, both accounts GBP | Intercompany journal entry pair (INSTRUCTION) GBP | Outbound GBP + Inbound GBP | None (same currency across accounts, no FX attached) | Both journal entries patched with transaction date. | Advanced Intercompany Journal patched with sending transaction date. |
| 50 | Intercompany transfer matched with IC journal, receiver sub GBP, both accounts GBP | Intercompany journal entry pair (INSTRUCTION) GBP | Outbound GBP + Inbound GBP | None | Both journal entries patched with transaction date. | Advanced Intercompany Journal patched with sending transaction date. |
| 51 | Intercompany transfer no documents, receiver sub GBP, both accounts GBP | None | Outbound GBP + Inbound GBP | None — GBP account settles in GBP, no FX rate attached | Two journal entries created; no FX rate on the EUR-base/GBP-account leg. | Advanced Intercompany Journal created, without any reported FX rate. |
Updated about 3 hours ago
