Skip to content

ETA Document Flow

Egyptian Tax Authority (ETA) documents share one policy: EtaActionPolicy in the shared library. The same rules disable Actions in Blazor (EtaActionGate / EtaActionMenuItem) and reject illegal calls on the API.

This guide documents implemented behavior for:

  • E-Invoices — sent invoices (Direction = Sent, Kind = Invoice)
  • E-Received Invoices — inbound supplier invoices (Direction = Received, Kind = Invoice)
  • E-Receipts — sent receipts (Kind = Receipt; use return, not cancel)

Parent hub: Target Document Flow.

  • Draft / Validated / Queued
  • Submitted
  • Valid
  • Invalid / Rejected
  • Cancelled / Returned

#Status catalog

Statuses are stored as strings on the document and mapped to EtaDocumentStatus.

Status Invoices Receipts Meaning
Draft Yes Yes Editable local draft
Validated Yes Yes Passed local/pre-ETA validation
Queued Yes Accepted offline; waiting to submit
Submitted Yes Yes Sent; awaiting authority result
Valid Yes Yes Accepted by ETA
Invalid Yes Yes Refused by ETA; fix and resubmit
Rejected Yes Yes* Counterparty refused (invoice-centric)
Cancelled Yes Issuer cancelled at ETA
Returned Yes Fully reversed by return receipt

* Receipts do not use recipient Reject / Decline Cancellation; reverse with Create Return Or Cancel Receipt.

#Lifecycle overview

Core path — prepare, submit, ETA result

flowchart TB
  subgraph Prepare["1 - Prepare"]
    direction TB
    Draft[Draft]
    Validated[Validated]
    Queued[Queued - receipts]
    Draft -->|Validate| Validated
  end

  subgraph Authority["2 - Authority"]
    Submitted[Submitted]
  end

  subgraph Result["3 - Result"]
    direction TB
    Valid[Valid]
    Invalid[Invalid]
  end

  Start((Create)) --> Draft
  Draft -->|Submit| Submitted
  Validated -->|Submit| Submitted
  Queued -->|Submit| Submitted
  Submitted -->|ETA accept| Valid
  Submitted -->|ETA refuse| Invalid
  Draft -.->|Submit refused| Invalid
  Validated -.->|Submit refused| Invalid
  Invalid -->|Edit| Draft
  Invalid -->|Resubmit| Submitted

  class Start egkStart
  class Draft,Validated,Queued egkDraft
  class Submitted egkActive
  class Valid egkSuccess
  class Invalid egkError

Terminal paths from Valid — cancel, reject, or return

flowchart TB
  Valid[Valid]
  Valid -->|Cancel on ETA| Cancelled[Cancelled]
  Valid -->|Reject invoice| Rejected[Rejected]
  Valid -->|Create return| Returned[Returned]
  Cancelled --> DoneNode((Done))
  Rejected --> DoneNode
  Returned --> DoneNode

  class Valid egkSuccess
  class Cancelled,Rejected,Returned egkTerminal
  class DoneNode egkStart

#Direction split (invoices)

ETA gives each side one reversal verb. Receipts use Create Return Or Cancel Receipt, not Cancel On Eta.

Issuer vs recipient reversal actions

flowchart TB
  subgraph Issuer["Issuer - E-Invoices"]
    direction TB
    S1[Valid] -->|Cancel on ETA| S2[Cancelled]
    S1 -->|Decline rejection| S3[Reinstate / clear pending]
  end
  subgraph Recipient["Recipient - E-Received Invoices"]
    direction TB
    R1[Valid] -->|Reject invoice| R2[Rejected]
    R1 -->|Decline cancellation| R3[Reinstate / clear pending]
  end

  class S1,R1 egkSuccess
  class S2,R2 egkTerminal
  class S3,R3 egkActive
Verb (UI label) Who Policy action
Cancel On Eta Issuer Cancel
Decline Rejection Issuer DeclineRejection
Reject Invoice Recipient Reject
Decline Cancellation Recipient DeclineCancellation
Create Return Or Cancel Receipt Receipt issuer IssueReturn
Create Credit Note Invoice issuer IssueCreditNote

#Action availability matrix

Legend: Y = allowed when other flags permit · = never for this kind/direction · C = conditional (see notes)

Sent e-invoice matrix
Action (UI) Draft Validated Submitted Valid Invalid Rejected Cancelled
Edit / Delete / Line Items Y Y Y
Validate Y Y Y
Submit Y Y Y
Sync Status
Cancel On Eta
Decline Rejection
Create Credit Note C⁴
Duplicate Y Y Y Y Y Y Y
Eta Pdf

¹ Requires ETA document UUID (HasEtaUuid).
² Valid only; blocked if pending cancellation, pending rejection, or reversal window closed.
³ Requires pending rejection or status Rejected/Cancelled per decline rules; blocked if already declined, no rejection, wrong direction, or decline window closed while still Valid.
Valid only and not fully credited; no cancellation deadline (credit note remains available after the cancel window).

Received e-invoice & e-receipt matrices

#Received e-invoice

Action (UI) Valid Other statuses
Reject Invoice C⁵ Denied (not submitted / wrong status / already reversed)
Decline Cancellation C⁶ See decline rules
Sync / Eta Pdf
Submit / Cancel / Credit Note Sender-only or N/A

Valid only; within rejection window; no pending rejection.
⁶ Pending cancellation or status Cancelled; receiver only; one decline; window rules as in policy.

#E-receipt

Action (UI) Draft / Validated / Queued / Invalid Submitted Valid Returned
Edit / Delete Y
Validate / Submit Y
Create Return Or Cancel Receipt C⁷
Cancel On Eta — (receipts use return)
Duplicate Y Y Y Y

Valid and not fully returned.

#Decision trees

#When is Cancel On Eta enabled?

Cancel On Eta — policy gates

flowchart TB
  A[Cancel On Eta] --> B{Kind = Invoice?}
  B -->|No| X1[Denied - use return]
  B -->|Yes| C{Direction = Sent?}
  C -->|No| X2[Denied - sender only]
  C -->|Yes| D{Pending cancellation?}
  D -->|Yes| X3[Denied - already requested]
  D -->|No| E{Pending rejection?}
  E -->|Yes| X4[Denied - rejection pending]
  E -->|No| F{Status = Valid?}
  F -->|No| X5[Denied - not Valid]
  F -->|Yes| G{Reversal window closed?}
  G -->|Yes| X6[Denied - window closed]
  G -->|No| OK[Allowed]

  class A egkActive
  class B,C,D,E,F,G egkDecision
  class OK egkSuccess
  class X1,X2,X3,X4,X5,X6 egkError

#When is Decline Rejection enabled?

Decline Rejection — policy gates

flowchart TB
  A[Decline Rejection] --> B{Invoice + Sent?}
  B -->|No| X1[Denied - wrong kind]
  B -->|Yes| C{Has ETA UUID?}
  C -->|No| X2[Denied - not submitted]
  C -->|Yes| D{Already declined?}
  D -->|Yes| X3[Denied - already declined]
  D -->|No| E{Pending rejection or Rejected?}
  E -->|No| X4[Denied - no rejection]
  E -->|Yes| F{Status}
  F -->|Valid| G{Decline window closed?}
  G -->|Yes| X5[Denied - window closed]
  G -->|No| OK[Allowed]
  F -->|Rejected or Cancelled| OK
  F -->|Other| X4

  class A egkActive
  class B,C,D,E,F,G egkDecision
  class OK egkSuccess
  class X1,X2,X3,X4,X5 egkError

#After-action UI behavior (ETA screens)

Step Behavior
1 Action runs through API (/{id}/validate, /submit, /cancel, /decline-rejection, /reject, /decline-cancellation, /return, /sync-status, …)
2 ETA actions stay disabled for the round trip and the refresh that follows, so nothing can be launched against a row already known to be out of date
3 The row and the status counters above it are re-read from the server on every outcome — accepted, refused, or failed
4 If composer/details open: refetch invoice/receipt/received invoice by id
5 Gate(row, action) / DeclineRejectionGate / DeclineCancellationGate re-run on the new StatusId, UUID, and ETA date flags
6 A multi-row selection is re-pointed at the reloaded rows, so bulk buttons gate on the new statuses; rows the reload no longer returns drop out of the selection
7 Disabled items remain visible with localized denial tooltips

A refused action refreshes the same as an accepted one. A refusal usually means the document had already moved on — cancelled by someone else, or past its window — which is exactly the case where the row on screen is the stale thing that offered the action. A refused submission also still writes to the document: the reason ETA gave, and the attempt in the audit trail. So the screen after a refusal shows the authority's current answer rather than the state you clicked from, and no manual refresh is needed to find out what is still possible.

Validate is included in this, despite the read-only name: a draft that passes validation is promoted to Validated and saved, which changes what the Actions menu should offer.

EntityTable CanUpdateEntityFunc / CanDeleteEntityFunc also call EtaActionPolicy so built-in Edit/Delete match the Actions menu.

#Scenario catalog

Scenario Resulting status / flags User next step
Create Draft Edit lines, Validate, Submit
Validate success Often Validated Submit
Submit success Submitted then sync to Valid / Invalid Sync Status if needed
ETA invalid Invalid Edit, Validate, Submit
Cancel accepted Pending cancel → Cancelled Decline not available to issuer
Reject accepted Pending reject → Rejected Issuer may Decline Rejection inside window
Decline Rejection success Pending cleared; document reinstated Continue as Valid
Decline Cancellation success Pending cleared; document reinstated Recipient keeps invoice
Full credit note Source stays Valid; FullyCredited Credit note action disabled
Full return Source → Returned or FullyReturned Return action disabled
Duplicate New Draft Unrelated to source lock

#Sequence: submit sent invoice

Submit path — gate → API → ETA → UI sync

sequenceDiagram
  autonumber
  participant UI as Invoices grid
  participant Gate as EtaActionGate
  participant API as Invoice API
  participant Svc as Submission service
  participant ETA as Tax authority
  participant DB as Database

  UI->>Gate: Evaluate Submit
  Gate-->>UI: Allow or deny + tooltip
  UI->>API: POST /{id}/submit
  API->>Svc: SubmitInvoiceToEta
  Svc->>DB: Read invoice
  Svc->>ETA: Submit document
  ETA-->>Svc: UUID / validation result
  Svc->>DB: Persist StatusId + UUID
  API-->>UI: Outcome
  UI->>UI: Reload grid + re-gate Actions

#Denial reasons (tooltips)

Denial keys resolve through the module localizer. Examples:

  • Action Denied Locked By Eta
  • Action Denied Already Submitted
  • Action Denied Only Valid Can Be Cancelled
  • Action Denied Cancellation Already Requested
  • Action Denied Decline Window Closed
  • Action Denied Decline Rejection Is Sender Only
  • Action Denied Decline Cancellation Is Receiver Only
  • Action Denied Receipts Use Return

Reconnecting to the server…

Please wait, or reload the page.