Skip to content

Add missing response fields across models (per OpenAPI spec) #33

Description

@TimEvci

Summary

Several models are missing fields that the Moneybird API returns, so those values are silently dropped (the base model is configured with extra="ignore"). This was found by diffing each model against the official OpenAPI response schemas. Below is a per-entity checklist of the missing response fields, with the type each field has in the spec so implementation is mechanical.

Type conventions used below (taken from the spec's shared definitions):

  • timestamp = string, date-time → suggest str | None
  • identifier = string|integer matching ^\d+$ → suggest matching the codebase's identifier convention (see the separate "standardize identifier typing" issue); shown as int | str | None below
  • Amount/total fields are strings in the API (e.g. "119.79"), not numbers.

Nested collections (events, notes, attachments, time_entries) are lower priority and can be added as loosely-typed list[dict[str, Any]] or skipped; the scalar fields are the higher-value gaps.

ExternalSalesInvoice (largest gap)

moneysnake/external_sales_invoice.py is missing the entire read-back surface:

  • state: str | None (spec: string)
  • created_at: str | None, updated_at: str | None (timestamps)
  • paid_at: str | None (spec: string|null)
  • entry_number: int | None (spec: integer)
  • origin: str | None (spec: string|null)
  • marked_dubious_on: str | None, marked_uncollectible_on: str | None (spec: string|null)
  • tax_totals: list[dict[str, Any]] (spec: array of tax_subtotal objects; SalesInvoice already types this field the same way)
  • total_paid: str | None, total_unpaid: str | None, total_unpaid_base: str | None (spec: string)
  • total_price_excl_tax: str | None, total_price_excl_tax_base: str | None (spec: string)
  • total_price_incl_tax: str | None, total_price_incl_tax_base: str | None (spec: string)

(version is covered by a separate issue.)

Contact

moneysnake/contact.py is missing:

  • email: str | None (spec: string|null)
  • created_at: str | None, updated_at: str | None (timestamps)
  • archived: bool | None (spec: boolean)
  • tax_number_valid: bool | None (spec: boolean|null)
  • tax_number_validated_at: str | None (spec: string|null)
  • sales_invoices_url: str | None (spec: string)

(version is covered by a separate issue.) Note: type and from_checkout on the model are request-only params, not part of the response schema — worth a comment but not a bug.

Payment

moneysnake/payment.py is missing:

  • created_at: str | None, updated_at: str | None (timestamps)
  • user_id: int | str | None (identifier)
  • invoice_type: str | None (spec: string, e.g. "SalesInvoice")
  • credit_invoice_id: int | str | None (identifier, nullable)
  • linked_payment_id: int | str | None (identifier, nullable)
  • payment_transaction_id: int | str | None (identifier, nullable)

SalesInvoice

moneysnake/sales_invoice.py is missing scalars:

  • original_sales_invoice_id: int | str | None (identifier, nullable)
  • public_view_code_expires_at: str | None (spec: string|null)

(Nested contact, contact_person, attachments, events, notes, time_entries optional.)

Document (PurchaseInvoice / Receipt)

moneysnake/document.py is missing:

  • fiscal_allocations: list[dict[str, Any]] (spec: array of fiscal_allocation objects)
  • administration_id: int | str | None (identifier)
  • (optional) attachments, events, notes as list[dict[str, Any]]

FinancialMutation

moneysnake/financial_mutation.py is missing:

  • settlement_state: str | None (spec: string)

Detail line items

The *DetailsAttribute classes drop read-back fields returned by the API (fine to omit from write payloads, but they disappear on read):

  • amount_decimal: str | None (spec: string|null)
  • total_price_excl_tax_with_discount: str | None, total_price_excl_tax_with_discount_base: str | None (spec: number serialized as string, e.g. "99.0")
  • created_at: str | None, updated_at: str | None (spec: string|null)
  • tax_report_reference: list[str] | None (spec: array of string|null)
  • mandatory_tax_text: str | None (spec: string|null)

Verification

  • The repo's tests/conftest.py fixtures already carry full spec-shaped responses (e.g. contact_data includes email, archived, version, sales_invoices_url) — extend the model tests to assert these fields survive a round-trip instead of being dropped.

Note

Many of these are shared across entities (administration_id, created_at, updated_at, version). It may be cleaner to introduce a small shared base for those common read-only fields rather than re-adding them per model — this pairs well with the mixin/base extraction tracked in the related refactor issues.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions