Skip to content

Revenues

Revenues provide a simplified entry form for recording company income. Each revenue is linked to a revenue category, a receiving account, and optionally a tax rate, cost center, and business partner. When approved, the system automatically creates a balanced journal entry. Cancellation reverses the journal entry.

Purpose

  • Record revenue transactions with a streamlined single-entry form
  • Auto-calculate tax amounts when a tax rate is assigned
  • Auto-generate document numbers via the sequence service
  • Create journal entries automatically on approval
  • Reverse journal entries on cancellation
  • Support filtering and reporting by category, partner, branch, and date range

Entity Attributes

Revenue

FieldTypeDescription
idbigintPrimary key
company_idbigintFK to companies
branch_idbigint?FK to branches
document_numberstringAuto-generated sequence number (e.g., REV-2026-0001)
datedateRevenue date
revenue_category_idbigintFK to transaction_categories (type=revenue)
descriptionstringEnglish description
description_arstring?Arabic description
amountdecimal(12,3)Base revenue amount (before tax)
tax_rate_idbigint?FK to tax_rates
tax_amountdecimal(12,3)Auto-calculated tax amount
total_amountdecimal(12,3)amount + tax_amount
payment_methodenumcash, check, bank_transfer, card, mixed
receiving_account_idbigintFK to accounts (cash or bank GL account receiving funds)
bank_account_idbigint?FK to bank_accounts (required for check/bank_transfer)
check_numberstring?Check number (if payment by check)
cost_center_idbigint?FK to cost_centers
partner_idbigint?FK to business_partners
statusenumdraft, approved, cancelled
journal_entry_idbigint?FK to journal_entries (set on approval)
notestext?Additional notes
created_bybigintFK to users
approved_bybigint?FK to users
approved_atdatetime?Approval timestamp
created_attimestampCreation timestamp
updated_attimestampLast update timestamp
deleted_attimestamp?Soft-delete timestamp

Relationships

Lifecycle

API Endpoints

MethodPathDescription
GET/api/accounting/revenuesList revenues (paginated)
POST/api/accounting/revenuesCreate a new revenue (draft)
GET/api/accounting/revenues/{id}Get a single revenue
PUT/api/accounting/revenues/{id}Update a revenue (draft only)
DELETE/api/accounting/revenues/{id}Soft-delete a revenue (draft only)
POST/api/accounting/revenues/{id}/approveApprove and create journal entry
POST/api/accounting/revenues/{id}/cancelCancel and reverse journal entry

Query Parameters

ParameterTypeRequiredDescription
statusstringNoFilter by status: draft, approved, cancelled
revenue_category_idintegerNoFilter by revenue category
partner_idintegerNoFilter by business partner
branch_idintegerNoFilter by branch
date_fromdateNoFilter revenues on or after this date
date_todateNoFilter revenues on or before this date
pageintegerNoPage number (25 per page)

Request/Response Examples

Create Revenue

Request POST /api/accounting/revenues

bash
curl -X POST https://moon-erp.test/api/accounting/revenues \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "date": "2026-02-23",
    "revenue_category_id": 3,
    "description": "Consulting service fee",
    "description_ar": "رسوم خدمات استشارية",
    "amount": "5000.000",
    "payment_method": "bank_transfer",
    "receiving_account_id": 15,
    "bank_account_id": 1,
    "tax_rate_id": 1,
    "cost_center_id": 1,
    "partner_id": 8,
    "branch_id": 1,
    "notes": "Project Alpha consulting"
  }'
dart
final response = await http.post(
  Uri.parse('https://moon-erp.test/api/accounting/revenues'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
  body: jsonEncode({
    'date': '2026-02-23',
    'revenue_category_id': 3,
    'description': 'Consulting service fee',
    'description_ar': 'رسوم خدمات استشارية',
    'amount': '5000.000',
    'payment_method': 'bank_transfer',
    'receiving_account_id': 15,
    'bank_account_id': 1,
    'tax_rate_id': 1,
    'cost_center_id': 1,
    'partner_id': 8,
    'branch_id': 1,
    'notes': 'Project Alpha consulting',
  }),
);

Response 201 Created

json
{
  "data": {
    "id": 1,
    "company_id": 1,
    "branch_id": 1,
    "document_number": "REV-2026-0001",
    "date": "2026-02-23",
    "revenue_category_id": 3,
    "expense_category": {
      "id": 3,
      "code": "REV-CONSULT",
      "name": "Consulting Revenue",
      "name_ar": "إيرادات الاستشارات"
    },
    "description": "Consulting service fee",
    "description_ar": "رسوم خدمات استشارية",
    "amount": "5000.000",
    "tax_rate_id": 1,
    "tax_rate": {
      "id": 1,
      "name": "VAT 5%",
      "rate": "5.0000"
    },
    "tax_amount": "250.000",
    "total_amount": "5250.000",
    "payment_method": "bank_transfer",
    "payment_method_label": "Bank Transfer",
    "receiving_account_id": 15,
    "receiving_account": {
      "id": 15,
      "code": "1201001",
      "name": "NBK Main Account"
    },
    "bank_account_id": 1,
    "check_number": null,
    "cost_center_id": 1,
    "partner_id": 8,
    "partner": {
      "id": 8,
      "name": "Al Safat Trading",
      "name_ar": "شركة الصفاة التجارية"
    },
    "status": "draft",
    "status_label": "Draft",
    "journal_entry_id": null,
    "notes": "Project Alpha consulting",
    "created_by": 1,
    "approved_by": null,
    "approved_at": null,
    "created_at": "2026-02-23T10:00:00.000000Z",
    "updated_at": "2026-02-23T10:00:00.000000Z"
  }
}

Approve Revenue

Request POST /api/accounting/revenues/1/approve

Response 200 OK

json
{
  "data": {
    "id": 1,
    "document_number": "REV-2026-0001",
    "status": "approved",
    "status_label": "Approved",
    "journal_entry_id": 43,
    "approved_by": 1,
    "approved_at": "2026-02-23T11:00:00.000000Z"
  }
}

List Revenues

Request GET /api/accounting/revenues?status=approved&date_from=2026-01-01&date_to=2026-12-31

Response 200 OK

json
{
  "data": [
    {
      "id": 1,
      "document_number": "REV-2026-0001",
      "date": "2026-02-23",
      "revenue_category": {
        "id": 3,
        "name": "إيرادات الاستشارات"
      },
      "amount": "5000.000",
      "tax_amount": "250.000",
      "total_amount": "5250.000",
      "payment_method": "bank_transfer",
      "receiving_account": {
        "id": 15,
        "code": "1201001",
        "name": "NBK Main Account"
      },
      "partner": {
        "id": 8,
        "name": "شركة الصفاة التجارية"
      },
      "status": "approved"
    }
  ],
  "links": { "first": "...", "last": "...", "prev": null, "next": null },
  "meta": { "current_page": 1, "last_page": 1, "per_page": 25, "total": 1 }
}

Generated Journal Entry

When a revenue is approved, the system creates a posted journal entry:

LineAccountDebitCreditDescription
1Receiving account (e.g., NBK Main Account)5,250.000--Total received
2Revenue category GL account (e.g., Consulting Revenue)--5,000.000Revenue amount
3Tax Payable account (from tax rate)--250.000Tax amount (if applicable)

Business Rules

RuleDescription
Draft-only editsRevenues can only be updated or deleted while in draft status
Auto document numberdocument_number is auto-generated via the sequence service on creation
Tax auto-calculationIf tax_rate_id is provided, tax_amount = amount * rate / 100 and total_amount = amount + tax_amount
Tax recalculationOn update, tax is recalculated if amount or tax_rate_id changes
Approval creates JEApproving a draft revenue creates a posted journal entry and sets approved_by and approved_at
Cancel reverses JECancelling an approved revenue reverses the associated journal entry
Company scopedAll revenues are filtered by the authenticated user's company
Bank details requiredbank_account_id is required when payment_method is check or bank_transfer

Permissions

PermissionDescription
accounting.revenues.viewView revenues
accounting.revenues.createCreate new revenues
accounting.revenues.updateUpdate draft revenues
accounting.revenues.approveApprove draft revenues
accounting.revenues.cancelCancel approved revenues

Moon ERP API Documentation