# Implementation example This section gives a step-by-step example for fetching debt invoice data, related invoices, spaces, contracts, and optional files, then writing payments or events. ### Step 1: Debt invoices (starting point) **Option A** — by attested date (e.g. last 1 day). **Option B** — by known IDs. **Endpoint:** [GET /accounting/debt/debtinvoice/list/](/apis/accounting) **Option A:** ``` GET .../accounting/debt/debtinvoice/list/?_page=1&_page_size=500&attested_date__gte=2025-01-15 ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **attested_date__gte** — Only debt invoices attested on or after this date (e.g. 2025-01-15) **Option B:** ``` GET .../accounting/debt/debtinvoice/list/?_page=1&_page_size=500&id__in=, ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **id__in** — Comma-separated debt invoice IDs ### Step 2: Related invoice data Build the set of invoice IDs from the debt invoices' `invoice` field. **Endpoint:** [GET list for accounting.invoice](/apis/accounting) ``` GET .../accounting/invoice/list/?_page=1&_page_size=500&id__in=, ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **id__in** — Comma-separated invoice IDs from debt invoices (step 1) ### Step 3: Invoice recipients **Endpoint:** [GET list for accounting.invoicerecipient](/apis/accounting) ``` GET .../accounting/invoicerecipient/list/?_page=1&_page_size=500&invoice__in=, ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **invoice__in** — Comma-separated invoice IDs from step 1 ### Step 4 (optional): Debt invoice events **Endpoint:** [GET list for accounting.debtinvoiceevent](/apis/accounting) ``` GET .../accounting/debtinvoiceevent/list/?_page=1&_page_size=500&debt_invoice__in=, ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **debt_invoice__in** — Comma-separated debt invoice IDs from step 1 ### Step 5 (optional): Tenants and sub-tenants Collect tenant IDs from the recipients, then fetch [accounts.tenant](/apis/accounts). If needed, do the same for sub-tenants. **Endpoint:** [GET list for accounts.tenant](/apis/accounts) ``` GET .../accounts/tenant/list/?_page=1&_page_size=500&id__in=, ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **id__in** — Comma-separated tenant IDs from recipients (step 3) ### Step 6 (optional): Invoice PDF files **Endpoint:** List endpoint for [accounting.invoicerelatedpdffile](/apis/accounting) (see API Reference). ``` GET .../accounting/invoicerelatedpdffile/list/?_page=1&_page_size=500&invoice__in=, ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **invoice__in** — Comma-separated invoice IDs from step 1 ### Step 7: Space and contract data From each [accounting.invoice](/apis/accounting), use `originates_from_content_type` and `originates_from_object_id` to build a map of contract IDs per content type. From the contracts, collect space IDs and fetch spaces. **Endpoint:** List endpoint for the contract type (e.g. [contracts.apartmentcontract](/apis/contracts)). ``` GET .../contracts/apartmentcontract/list/?_page=1&_page_size=500&id__in=, ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **id__in** — Comma-separated contract IDs from invoices (originates_from_object_id) **Endpoint:** List endpoint for the space type (e.g. [objects.apartment](/apis/objects)). ``` GET .../objects/apartment/list/?_page=1&_page_size=500&id__in=, ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **id__in** — Comma-separated space IDs from contracts ### Step 8 (optional): Contract-related files **SignedContractDocument** (imported, not signed in Pigello). **SignableDocument** (signed in Pigello). For SignableDocument file data, **GET** `/documents/signing/signabledocument//document_data/`. The response may contain a URL to a file (often a ZIP with the main PDF, attachment PDFs, and metadata). Unzip to get the main PDF or other content. **Endpoint:** List endpoint for [contracts.signedcontractdocument](/apis/contracts). ``` GET .../contracts/signedcontractdocument/list//?_page=1&_page_size=500&object_id__in=, ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **object_id__in** — Comma-separated contract IDs from step 7 Example `content-type`: `contracts.apartmentcontract`. **Endpoint:** List endpoint for [documents.signabledocument](/apis/documents). ``` GET .../documents/signing/signabledocument/list//?_page=1&_page_size=500&object_id__in=,&signed_time__isnull=false ``` **Query parameters:** - **_page** — Page number (e.g. 1) - **_page_size** — Page size (e.g. 500) - **object_id__in** — Comma-separated contract IDs from step 7 - **signed_time__isnull** — `false` to only include signed documents ## Data writing - **Payments:** bulk upsert via POST to the [invoice payments list](/apis/accounting) endpoint. - **Debt invoices:** bulk upsert via POST to the [debt invoices list](/apis/accounting) endpoint (e.g. to annul). - **Debt invoice events:** bulk upsert via POST to the [debt invoice events list](/apis/accounting) endpoint to communicate progress to the customer. This section gives the same flow using the **Pigello Python SDK**. Use **`APIUserAgentSession`** from `pigello_sdk.session` with your integration credentials. See [Python SDK — Session](/tools/sdks/#session-authentication). ### Step 1: Debt invoices (starting point) **Option A** — by attested date. **Option B** — by known IDs. ```python from pigello_sdk.entities.accounting.debtinvoice import Debtinvoice # Option A: by attested date since_date = date.today() - timedelta(days=1) di_query = Debtinvoice.get_query_helper(session) di_query.add_filters([FilterInstruction("attested_date", FILTER_OPERATIONS.GTE, since_date)]) di_query.set_pagination(page_size=500, page=1) debt_invoices = di_query.collect_query().instances # Option B: by known IDs # di_query.add_filters([FilterInstruction("id", FILTER_OPERATIONS.IN, [id1, id2])]) debt_invoice_ids = [di.id for di in debt_invoices if di.id] ``` ### Step 2: Related invoice data Build the set of invoice IDs from the debt invoices' `invoice` field ```python from pigello_sdk.entities.accounting.invoice import Invoice invoice_ids = list({di.invoice.id for di in debt_invoices if di.invoice and di.invoice.id}) inv_query = Invoice.get_query_helper(session) inv_query.add_filters([FilterInstruction("id", FILTER_OPERATIONS.IN, invoice_ids)]) inv_query.set_pagination(page_size=500, page=1) invoices = inv_query.collect_query().instances ``` ### Step 3: Invoice recipients Use `Invoicerecipient` and filter by `invoice__in` with the invoice IDs from step 2. ```python from pigello_sdk.entities.accounting.invoicerecipient import Invoicerecipient ir_query = Invoicerecipient.get_query_helper(session) ir_query.add_filters([FilterInstruction("invoice", FILTER_OPERATIONS.IN, invoice_ids)]) ir_query.set_pagination(page_size=500, page=1) recipients = ir_query.collect_query().instances ``` ### Step 4 (optional): Debt invoice events Use `Debtinvoiceevent` and filter by `debt_invoice__in` with debt invoice IDs from step 1. ```python from pigello_sdk.entities.accounting.debtinvoiceevent import Debtinvoiceevent die_query = Debtinvoiceevent.get_query_helper(session) die_query.add_filters([FilterInstruction("debt_invoice", FILTER_OPERATIONS.IN, debt_invoice_ids)]) die_query.set_pagination(page_size=500, page=1) debt_invoice_events = die_query.collect_query().instances ``` ### Step 5 (optional): Tenants and sub-tenants Collect tenant IDs from the recipients, then fetch [accounts.tenant](/apis/accounts). ```python from pigello_sdk.entities.accounts.tenant import Tenant tenant_ids = list({r.tenant.id for r in recipients if r.tenant and r.tenant.id}) t_query = Tenant.get_query_helper(session) t_query.add_filters([FilterInstruction("id", FILTER_OPERATIONS.IN, tenant_ids)]) t_query.set_pagination(page_size=500, page=1) tenants = t_query.collect_query().instances ``` ### Step 6 (optional): Invoice PDF files Use `Invoicerelatedpdffile` and filter by `invoice__in` with invoice IDs from step 2. ```python from pigello_sdk.entities.accounting.invoicerelatedpdffile import Invoicerelatedpdffile pdf_query = Invoicerelatedpdffile.get_query_helper(session) pdf_query.add_filters([FilterInstruction("invoice", FILTER_OPERATIONS.IN, invoice_ids)]) pdf_query.set_pagination(page_size=500, page=1) pdf_files = pdf_query.collect_query().instances ``` ### Step 7: Space and contract data From each [accounting.invoice](/apis/accounting), use `originates_from_object_id` (and content type) to build contract IDs. Then fetch contracts and spaces. ```python from pigello_sdk.entities.contracts.apartmentcontract import Apartmentcontract from pigello_sdk.entities.objects.apartment import Apartment # eg. if we only do it for apartment-contracts APARTMENT_CONTRACT_CT = "contracts.apartmentcontract" contract_ids = list({inv.originates_from_object_id for inv in invoices if inv.originates_from_object_id and inv.originates_from_content_type and inv.originates_from_content_type.id == APARTMENT_CONTRACT_CT}) ac_query = Apartmentcontract.get_query_helper(session) ac_query.add_filters([FilterInstruction("id", FILTER_OPERATIONS.IN, contract_ids)]) ac_query.set_pagination(page_size=500, page=1) contracts = ac_query.collect_query().instances contracts.resolve_unresolved_relations(restrict_to_field_names=["space"]) spaces = {item.space for item in contracts if item.space} ``` ### Step 8 (optional): Contract-related files **SignedContractDocument** and **SignableDocument** for the contracts from step 7. Use `Signedcontractdocument` and `Signabledocument` with filter `object_id__in` (contract IDs). The API may require content-type in the path; see API Reference. SDK entities: `pigello_sdk.entities.contracts.signedcontractdocument`, `pigello_sdk.entities.documents.signabledocument`. ```python from pigello_sdk.entities.contracts.signedcontractdocument import Signedcontractdocument from pigello_sdk.entities.documents.signabledocument import Signabledocument scd_query = Signedcontractdocument.get_query_helper(session) scd_query.add_filters([FilterInstruction("object_id", FILTER_OPERATIONS.IN, contract_ids)]) scd_query.set_pagination(page_size=500, page=1) # list-endpoint requires a content-type (for what connection type the document has) # sdk requires to define that explicitly when performing the query # this example assumes we have a set of contract_ids beloning to apartment-contracts signed_docs = scd_query.collect_query("signedcontractdocument/list/contracts.apartmentcontract/").instances ``` ## Data writing (SDK) Use `bulk.EntitiesList(session, list)` and `.save()` for bulk upsert. - **Payments:** Build `Invoicepayment` instances (or load and update), put in `EntitiesList(session, list)`, call `.save()`. - **Debt invoices:** Same for `Debtinvoice` (e.g. set `annulled=True`). - **Debt invoice events:** Same for `Debtinvoiceevent`. ```python from pigello_sdk.entities.accounting.invoicepayment import Invoicepayment # Example: create or update payment entities, then bulk save payments_list = bulk.EntitiesList(session, [payment1, payment2, ...]) payments_list.save() ``` For more on the SDK, see the [Python SDK](/tools/sdks/) documentation.