Add Activepieces integration for workflow automation

- Add Activepieces fork with SmoothSchedule custom piece
- Create integrations app with Activepieces service layer
- Add embed token endpoint for iframe integration
- Create Automations page with embedded workflow builder
- Add sidebar visibility fix for embed mode
- Add list inactive customers endpoint to Public API
- Include SmoothSchedule triggers: event created/updated/cancelled
- Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,18 @@
{
"extends": ["../../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@@ -0,0 +1,7 @@
# pieces-xero
This library was generated with [Nx](https://nx.dev).
## Running lint
Run `nx lint pieces-xero` to execute the lint via [ESLint](https://eslint.org/).

View File

@@ -0,0 +1,4 @@
{
"name": "@activepieces/piece-xero",
"version": "0.5.6"
}

View File

@@ -0,0 +1,51 @@
{
"name": "pieces-xero",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/pieces/community/xero/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": [
"{options.outputPath}"
],
"options": {
"outputPath": "dist/packages/pieces/community/xero",
"tsConfig": "packages/pieces/community/xero/tsconfig.lib.json",
"packageJson": "packages/pieces/community/xero/package.json",
"main": "packages/pieces/community/xero/src/index.ts",
"assets": [
"packages/pieces/community/xero/*.md",
{
"input": "packages/pieces/community/xero/src/i18n",
"output": "./src/i18n",
"glob": "**/!(i18n.json)"
}
],
"buildableProjectDepsInPackageJsonType": "dependencies",
"updateBuildableProjectDepsInPackageJson": true
},
"dependsOn": [
"^build",
"prebuild"
]
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": [
"{options.outputFile}"
]
},
"prebuild": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/pieces/community/xero",
"command": "bun install --no-save --silent"
},
"dependsOn": [
"^build"
]
}
},
"tags": []
}

View File

@@ -0,0 +1,320 @@
{
"Beautiful accounting software": "Schöne Buchhaltungssoftware",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Melde dich bei Xero an.\n 2. Gehe zum [Entwicklerportal](https://developer.xero.com/app/manage/).\n 3. Klicken Sie auf die App, die Sie integrieren möchten.\n Klicken Sie auf der linken Seite auf `Konfiguration`.\n Geben Sie Ihre `Umleitungsurl` ein.\n 6. Kopiere die `Client Id` und `Client Secret`.\n ",
"Create or Update Contact": "Kontakt erstellen oder aktualisieren",
"Create or Update Invoice": "Rechnung erstellen oder aktualisieren",
"Allocate Credit Note to Invoice": "Gutschrift für Rechnung zuweisen",
"Create Bank Transfer": "Überweisung erstellen",
"Create New Quote Draft": "Neuen Angebotsentwurf erstellen",
"Send Sales Invoice by Email": "Verkaufsrechnung per E-Mail senden",
"Create Bill": "Rechnung erstellen",
"Create Payment": "Zahlung erstellen",
"Create Purchase Order": "Bestellung erstellen",
"Update Purchase Order": "Bestellung aktualisieren",
"Upload Attachment": "Anhang hochladen",
"Add Items to Existing Sales Invoice": "Artikel zur bestehenden Verkaufsrechnung hinzufügen",
"Create Credit Note": "Credit-Notiz erstellen",
"Create Inventory Item": "Inventarartikel erstellen",
"Create Project": "Projekt erstellen",
"Update Sales Invoice": "Verkaufs-Rechnung aktualisieren",
"Create Repeating Sales Invoice": "Wiederkehrende Verkaufs-Rechnung erstellen",
"Find Contact": "Kontakt finden",
"Find Invoice": "Rechnung finden",
"Find Item": "Element finden",
"Find Purchase Order": "Bestellauftrag finden",
"Custom API Call": "Eigener API-Aufruf",
"Create Xero Contact": "Xero-Kontakt erstellen",
"Create Xero Invoice": "Xero Rechnung erstellen",
"Allocates a credit note to a specific invoice.": "Verteilt eine Gutschrift auf eine bestimmte Rechnung.",
"Transfers money between two bank accounts in Xero.": "Überweist Geld zwischen zwei Bankkonten in Xero.",
"Creates a new draft quote.": "Erstellt einen neuen Angebotsentwurf.",
"Sends a sales invoice via email to a contact.": "Sendet eine Verkaufsrechnung per E-Mail an einen Kontakt.",
"Creates a new bill (Accounts Payable).": "Erstellt eine neue Rechnung (Kunden zahlbar).",
"Applies a payment to an invoice.": "Wendet eine Zahlung auf eine Rechnung an.",
"Creates a new purchase order for a contact.": "Erstellt eine neue Einkaufsbestellung für einen Kontakt.",
"Updates details of an existing purchase order.": "Aktualisiert Details zu einer bestehenden Bestellung.",
"Uploads an attachment to a specific Xero resource.": "Lädt einen Anhang auf eine bestimmte Xero-Ressource.",
"Adds line items to an existing sales invoice (ACCREC).": "Fügt Linienartikel zu einer bestehenden Verkaufsrechnung (ACCREC) hinzu.",
"Creates a new credit note for a contact.": "Erstellt eine neue Gutschrift für einen Kontakt.",
"Creates a new inventory item in Xero.": "Erstellt einen neuen Inventarartikel in Xero.",
"Creates a new project for a contact.": "Erstellt ein neues Projekt für einen Kontakt.",
"Updates details of an existing sales invoice (ACCREC).": "Aktualisiert Details einer bestehenden Verkaufsrechnung (ACCREC).",
"Creates a repeating sales invoice (Accounts Receivable).": "Erstellt eine wiederkehrende Verkaufsrechnung (Konten anforderbar).",
"Finds a contact by name or account number (or SearchTerm).": "Findet einen Kontakt mit Namen oder Kontonummer (oder SearchTerm).",
"Finds an invoice by number or reference.": "Findet eine Rechnung nach Nummer oder Referenz.",
"Finds an item by name or code.": "Findet ein Element nach Namen oder Code.",
"Finds a purchase order by given parameters.": "Findet eine Bestellung nach angegebenen Parametern.",
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
"Organization": "Organisation",
"Contact ID": "Kontakt-ID",
"Contact Name": "Kontaktname",
"Contact Email": "Kontakt-E-Mail",
"Invoice": "Rechnung",
"Contact": "Kontakt",
"Line Item": "Zeilenelement",
"Date Prepared": "Datum vorbereitet",
"Due Date": "Fälligkeitsdatum",
"Invoice Reference": "Rechnungsreferenz",
"Status": "Status",
"Credit Note": "Gutschrift",
"Amount": "Betrag",
"Allocation Date": "Allokationsdatum",
"Bank Account": "Bankkonto",
"Transfer Date": "Überweisungsdatum",
"Reference": "Referenz",
"From Is Reconciled": "Von ist vereinbar",
"To Is Reconciled": "Um ist vereinbar",
"Date": "Datum",
"Expiry Date": "Expiry Date",
"Line Amount Types": "Zeilentypen",
"Quote Number": "Angebotsnummer",
"Title": "Titel",
"Summary": "Summary",
"Terms": "Begriffe",
"Sales Invoice (Sendable)": "Verkaufsrechnung (Endbar)",
"Bill Number (Reference)": "Rechnungsnummer (Referenz)",
"Invoice (Authorised)": "Rechnung (autorisiert)",
"Payment Date": "Zahlungsdatum",
"Is Reconciled": "Ist versöhnt",
"Delivery Date": "Lieferdatum",
"Purchase Order Number": "Bestellnummer",
"Branding Theme": "Branding Thema",
"Delivery Address": "Lieferadresse",
"Attention To": "Aufmerksamkeit an",
"Telephone": "Telefon",
"Delivery Instructions": "Lieferanleitung",
"Expected Arrival Date": "Erwartetes Anreisedatum",
"Purchase Order": "Bestellung",
"Mark as Sent to Contact": "Als Gesendet markieren",
"Expected Arrival Date (YYYY-MM-DD)": "Erwartetes Anreisedatum (JJJJ-MM-TT)",
"Resource Type": "Ressourcentyp",
"Resource": "Ressource",
"File": "Datei",
"File Name (override)": "Dateiname (überschreiben)",
"Content Type": "Inhaltstyp",
"Include with Online Invoice": "Mit Online-Rechnung einbeziehen",
"Allow AUTHORISED invoices": "Erlaube AUTHORISIERTE Rechnungen",
"New Line Items": "Neue Zeilenelemente",
"Type": "Typ",
"Credit Note Number": "Credit-Notiznummer",
"Reference (ACCRECCREDIT only)": "Referenz (nur AKCRECCREDIT)",
"Currency Code": "Währungscode",
"Line Items": "Zeilenelemente",
"Item Code": "Artikelcode",
"Name": "Name",
"Sales Description": "Verkaufsbeschreibung",
"Purchase Description": "Kaufbeschreibung",
"Is Sold": "Verkauft",
"Is Purchased": "Ist gekauft",
"Sales Details": "Verkaufsdetails",
"Account": "Konto",
"Purchase Details": "Einkaufsdetails",
"Project Name": "Projekt Name",
"Deadline (UTC ISO-8601)": "Frist (UTC ISO-8601)",
"Estimate Amount": "Geschätzter Betrag",
"Sales Invoice (Editable)": "Verkaufsrechnung (Verfügbar)",
"Due Date (YYYY-MM-DD)": "Fälligkeitsdatum (JJJJ-MM-TT)",
"Invoice Number": "Rechnungsnummer",
"Source URL": "Quell-URL",
"Replace All Line Items": "Alle Zeilenelemente ersetzen",
"Line Items (updates/additions)": "Zeilenelemente (Updates/Zusätze)",
"Schedule Period": "Zeitplanperiode",
"Schedule Unit": "Einheit planen",
"Due Date (number)": "Fälligkeitsdatum (Nummer)",
"Due Date Type": "Enddatumstyp",
"Start Date (YYYY-MM-DD)": "Startdatum (JJJJ-MM-TD)",
"End Date (YYYY-MM-DD)": "Enddatum (JJJJ-MM-TT)",
"Currency": "Währung",
"Approved For Sending": "Zum Senden genehmigt",
"Send Copy": "Kopie senden",
"Mark As Sent": "Als Gesendet markieren",
"Include PDF": "PDF einschließen",
"Search By": "Suche nach",
"Value": "Wert",
"Include Archived": "Archiviert einbeziehen",
"Summary Only (faster, lighter)": "Nur Zusammenfassung (schneller, leichter)",
"Page": "Seite",
"Type Filter": "Typ Filter",
"Order (optional)": "Bestellung (optional)",
"Statuses": "Statuses",
"Date From (YYYY-MM-DD)": "Datum ab (JJJJ-MM-TD)",
"Date To (YYYY-MM-DD)": "Datum bis (JJJJ-MM-TT)",
"Order (e.g., Date DESC)": "Bestellung (z. B. Datum DESC)",
"Page Size (1-1000)": "Seitengröße (1-1000)",
"Method": "Methode",
"Headers": "Kopfzeilen",
"Query Parameters": "Abfrageparameter",
"Body": "Körper",
"Response is Binary ?": "Antwort ist binär?",
"No Error on Failure": "Kein Fehler bei Fehler",
"Timeout (in seconds)": "Timeout (in Sekunden)",
"ID of the contact to create invoice for.": "ID des Kontakts, für den Rechnung erstellt werden soll.",
"Contact name, in full.": "Kontaktname vollständig.",
"Email address of the contact.": "E-Mail-Adresse des Kontakts.",
"Select an invoice": "Rechnung auswählen",
"Select a contact": "Kontakt auswählen",
"Invoice line items": "Rechnungslinie Elemente",
"Date the invoice was created. Format example: 2019-03-11": "Datum der Rechnung wurde erstellt. Format Beispiel: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "Enddatum der Rechnung. Format-Beispiel: 2019-03-11",
"Reference number of the Invoice": "Referenznummer der Rechnung",
"Invoice Status": "Rechnungsstatus",
"Select a credit note to allocate from": "Wähle eine Gutschrift für die Zuweisung aus",
"The amount of the credit to allocate.": "Der Betrag des zu verteilenden Guthabens.",
"Date of allocation. Format: YYYY-MM-DD. Optional.": "Datum der Zuordnung. Format: JJJJ-MM-TT. Optional.",
"Select a bank account": "Wählen Sie ein Bankkonto",
"Amount to transfer. Currencies must match between accounts.": "Betrag für die Überweisung. Währungen müssen zwischen Konten übereinstimmen.",
"YYYY-MM-DD. Defaults to today if not provided.": "JJJJ-MM-TT. Standardmäßig auf heute, wenn nicht bereitgestellt.",
"Reference for the transfer.": "Referenz für die Übertragung.",
"Mark source account transaction as reconciled.": "Quellkonto Transaktion als ausgeglichen.",
"Mark destination account transaction as reconciled.": "Zielkontotransaktion als ausgeglichen.",
"Date the quote was issued (YYYY-MM-DD).": "Datum der Ausgabe des Kostenvoranschlags (JJJJ-MM-TD).",
"Date the quote expires (YYYY-MM-DD).": "Ablaufdatum des Angebots (YYY-MM-DD).",
"At minimum, provide a Description.": "Geben Sie mindestens eine Beschreibung an.",
"Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).": "Wählen Sie eine Verkaufsrechnung mit einem gültigen Status für das Versenden von E-Mails (SUBMITTED, AUTHORISIERT oder PAID).",
"Date the bill was issued (YYYY-MM-DD). Optional.": "Datum der Ausgabe der Rechnung (JJJJ-MM-TT) Optional.",
"Date the bill is due (YYYY-MM-DD). Optional.": "Rechnungsdatum (JJJJ-MM-TT) ist optional.",
"Select an authorised invoice (sales or bill) to apply payment to.": "Wählen Sie eine autorisierte Rechnung (Verkauf oder Rechnung) aus, an die die Zahlung erfolgen soll.",
"Payment amount (must be <= amount due).": "Zahlungsbetrag (muss <= Betrag fällig sein).",
"YYYY-MM-DD.": "JJJJ-MM-TT.",
"Mark payment as reconciled (optional).": "Zahlung als ausgeglichen markieren (optional).",
"Date the purchase order was issued (YYYY-MM-DD). Optional.": "Datum der Bestellung (YYY-MM-DD). Optional.",
"Date goods are to be delivered (YYYY-MM-DD). Optional.": "Datum der Lieferung (YYY-MM-DD). Optional.",
"Select a branding theme": "Branding Thema auswählen",
"YYYY-MM-DD. Optional.": "JJJJ-MM-TT. Optional.",
"Select a purchase order to update": "Bestellung zum Aktualisieren auswählen",
"The Xero resource to attach the file to.": "Die Xero-Ressource, an die die Datei angehängt wird.",
"Select the specific resource to attach the file to.": "Wählen Sie die spezifische Ressource aus, an die die Datei angefügt werden soll.",
"The file to upload. Max 10MB per Xero limits.": "Die hochzuladende Datei. Maximal 10MB pro Xero.",
"Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *": "Optionaler Dateiname in Xero. Vermeiden Sie Zeichen: < > : \" / \\ | ? *",
"MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.": "MIME Typ der Datei (z.B. image/png). Falls nicht gesetzt, wird die Datei auf application/octet-stream voreingestellt.",
"Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.": "Nur anwendbar auf ACCREC Rechnungen und ACCREC Kreditnoten. Fügt IncludeOnline=true Anfrageparameter hinzu.",
"Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Aktivieren Sie das Hinzufügen von Artikeln zu AUTHORISED Rechnungen (Xero erlaubt begrenzte Aktualisierungen für bezahlte/teilbezahlte ACCREC).",
"Add one or more line items. At minimum, each line needs a Description.": "Fügen Sie ein oder mehrere Zeilenelemente hinzu. Mindestens jede Zeile benötigt eine Beschreibung.",
"Select an account": "Wählen Sie ein Konto",
"Example: 2017-04-23T18:25:43.511Z": "Beispiel: 2017-04-23T18:25:43.511Z",
"Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Aktivieren Sie Updates für AUTHORISED Rechnungen (Xero erlaubt begrenzte Updates für bezahlte/Teilbezahlte ACCREC).",
"Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.": "Wählen Sie eine Verkaufsrechnung (ACCREC) mit DRAFT oder SUBMITTED-Status.",
"If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.": "Wenn aktiviert, bleiben nur die zur Verfügung gestellten line_items erhalten. Wenn deaktiviert, werden wir mit den aktuellen Zeilen zusammenführen, indem wir die passende LineItemID aktualisieren und neue Elemente anhängen.",
"Integer period (e.g., 1 every week, 2 every month).": "Integer Zeitraum (z. B. 1 jede Woche, 2 pro Monat).",
"Day number used with due date type (e.g., 20, 31).": "Verwendete Tagesnummer mit Enddatumstyp (z. B. 20, 31).",
"Select a currency code": "Währungscode auswählen",
"Name, Account Number, or Search Term depending on Search By.": "Name, Kontonummer oder Suchbegriff, abhängig von Suchbegriff.",
"Recommended for broad searches (Search Term). Excludes heavy fields.": "Empfohlen für eine breite Suche (Suchbegriff). Ausschliesst schwere Felder aus.",
"Pagination page (optional).": "Paginierungsseite (optional).",
"Invoice Number, Reference, or Search Term.": "Rechnungsnummer, Referenz oder Suchbegriff.",
"Item Code or Name (exact match).": "Artikelcode oder Name (exakte Übereinstimmung).",
"e.g. Name or Name DESC": "z.B. Name oder Name DESC",
"Number, Reference or ID depending on Search By.": "Nummer, Referenz oder ID abhängig von der Suche nach.",
"Authorization headers are injected automatically from your connection.": "Autorisierungs-Header werden automatisch von Ihrer Verbindung injiziert.",
"Enable for files like PDFs, images, etc..": "Aktivieren für Dateien wie PDFs, Bilder, etc..",
"Draft": "Entwurf",
"Submitted": "Eingereicht",
"Authorised": "Autorisiert",
"Deleted": "Gelöscht",
"Voided": "Storniert",
"Exclusive": "Exklusiv",
"Inclusive": "Inklusiv",
"NoTax": "NoTax",
"Billed": "Abgerechnet",
"Quote": "Zitat",
"Bank Transfer": "Banküberweisung",
"Bank Transaction": "Banktransaktion",
"Manual Journal": "Manuelles Journal",
"Receipt": "Beleg",
"Repeating Invoice": "Wiederholende Rechnung",
"Accounts Receivable Credit (ACCRECCREDIT)": "Rechnungsgutschrift (ACCRECCREDIT)",
"Accounts Payable Credit (ACCPAYCREDIT)": "Konto Zahlbares Guthaben (ACCPAYCREDIT)",
"Weekly": "Wöchentlich",
"Monthly": "Monatlich",
"Name (exact match)": "Name (exakter Treffer)",
"Account Number (exact match)": "Kontonummer (exakte Übereinstimmung)",
"Search Term (broad search)": "Suchbegriff (breite Suche)",
"Invoice Number (exact)": "Rechnungsnummer (genau)",
"Reference (exact)": "Referenz (genau)",
"Search Term (InvoiceNumber/Reference)": "Suchbegriff (Rechnungsnummer/Referenz)",
"Sales Invoice (ACCREC)": "Verkaufsrechnung (ACCREC)",
"Bill (ACCPAY)": "Rechnung (ACCPAY)",
"Code (exact)": "Code (genau)",
"Name (exact)": "Name (genau)",
"Purchase Order Number (exact)": "Bestellnummer (genau)",
"Purchase Order ID (GUID)": "Bestell-ID (GUID)",
"GET": "ERHALTEN",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "LÖSCHEN",
"HEAD": "HEAD",
"New Contact": "Neuer Kontakt",
"New or Updated Contact": "Neuer oder aktualisierter Kontakt",
"New Sales Invoice": "Neue Verkaufsrechnung",
"Updated Sales Invoice": "Verkaufs-Rechnung aktualisiert",
"New Bank Transaction": "Neue Banktransaktion",
"New Payment": "Neue Zahlung",
"New Purchase Order": "Neue Bestellung",
"New Reconciled Payment": "Neue ausgeglichene Zahlung",
"Updated Quote": "Aktualisiertes Angebot",
"New Bill": "Neue Rechnung",
"New Credit Note": "Neue Gutschrift",
"New Project": "Neues Projekt",
"New Quote": "Neues Angebot",
"Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.": "Feuert ab, wenn Xero ein neuer Kontakt hinzugefügt wird (via Xero Webhooks). Konfigurieren Sie den Webhook im Xero Developer Portal um auf diese URL zu verweisen.",
"Fires when a contact is created or updated (via Xero webhooks).": "Feuert ab, wenn ein Kontakt erstellt oder aktualisiert wird (über Xero Webhooks).",
"Fires when a new sales invoice (Accounts Receivable) is created.": "Feuer, wenn eine neue Verkaufsrechnung erstellt wird (Konten einlösbar).",
"Fires when an existing sales invoice (Accounts Receivable) is updated.": "Feuer, wenn eine bestehende Verkaufsrechnung (Konten anforderbar) aktualisiert wird.",
"Fires when a new bank transaction is created.": "Feuert ab, wenn eine neue Banktransaktion erstellt wird.",
"Fires when a payment is received.": "Feuert ab, wenn eine Zahlung empfangen wird.",
"Fires when a new purchase order is created or enters a specific status for the first time.": "Feuert ab, wenn eine neue Bestellung erstellt wird oder zum ersten Mal einen bestimmten Status erreicht.",
"Fires when a payment is reconciled for the first time.": "Feuer, wenn eine Zahlung zum ersten Mal versöhnt wird.",
"Fires when a quote is created or updated.": "Feuert ab, wenn ein Zitat erstellt oder aktualisiert wird.",
"Fires when a new bill (Accounts Payable) is added.": "Feuer, wenn eine neue Rechnung (Konto zahlbar) hinzugefügt wird.",
"Fires when a new credit note is created.": "Feuert ab, wenn eine neue Gutschrift erstellt wird.",
"Fires when a new project is created.": "Feuert ab, wenn ein neues Projekt erstellt wird.",
"Fires when a new quote is created.": "Feuert ab, wenn ein neues Zitat erstellt wird.",
"Markdown": "Markdown",
"Webhook Key": "Webhook-Schlüssel",
"Fetch Full Contact": "Volle Kontakte abrufen",
"Fetch Full Invoice": "Gesamte Rechnung abrufen",
"Types": "Typen",
"Bank Account Code": "Bankkonto Code",
"Payment Types": "Zahlungsarten",
"Filter by Status (optional)": "Nach Status filtern (optional)",
"First-time Status (optional)": "Erstmaliger Status (optional)",
"Quote Number (partial match)": "Angebotsnummer (Teiltreffen)",
"Expiry Date From (YYYY-MM-DD)": "Ablaufdatum (JJJJ-MM-TT)",
"Expiry Date To (YYYY-MM-DD)": "Ablaufdatum (JJJJ-MM-TT)",
"Statuses (optional)": "Status (optional)",
"Summary Only (lighter, faster)": "Nur Zusammenfassung (leichter, schneller)",
"States (optional)": "Staaten (optional)",
"Page Size (1-500)": "Page Size (1-500)",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nUm diesen Trigger zu verwenden, konfigurieren Sie manuell einen Xero Webhook für Ihre App:\n\n. Gehen Sie zu Xero Developer > Meine Apps > [Ihre App] > Webhooks.\n2. Wählen Sie die Kontaktkategorie.\n3. Setze die Delivery URL auf:\n\n\n```text\n{{webhookUrl}}\n```\n4. Klicken Sie auf Speichern, und klicken Sie dann auf \"Absicht zum Empfangen bestätigen\".\n5. Kopieren Sie den Webhook Key von der Webhooks Seite und fügen Sie ihn in das Feld Webhook Key ein.\n6. Optionale Organisations-ID (Tenant-ID) so einstellen, dass nur Ereignisse aus einer bestimmten Org akzeptiert werden. \n\n Anmerkungen:\n- Keep this trigger enabled so the URL remains active.\n- Wir verifizieren Xero's x-xero-signature Header mit Ihrem Webhook Key.\n ",
"From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.": "Vom Xero Entwicklerportal > Ihre App > Webhooks. Wird verwendet, um x-xero-Signatur zu überprüfen.",
"If enabled, fetches the full contact from Xero using the Resource URL.": "Falls aktiviert, holt Xero den vollen Kontakt mit der Ressourcen-URL.",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nUm diesen Trigger zu verwenden, konfigurieren Sie manuell einen Xero Webhook für Ihre App:\n\n. Gehen Sie zu Xero Developer > Meine Apps > [Ihre App] > Webhooks.\n2. Wählen Sie die Rechnungskategorie aus.\n3. Setze die Delivery URL auf:\n\n\n```text\n{{webhookUrl}}\n```\n4. Klicken Sie auf Speichern, und klicken Sie dann auf \"Absicht zum Empfangen bestätigen\".\n5. Kopieren Sie den Webhook Key von der Webhooks Seite und fügen Sie ihn in das Feld Webhook Key ein.\n6. Optionale Organisations-ID (Tenant-ID) so einstellen, dass nur Ereignisse aus einer bestimmten Org akzeptiert werden. \n\n Anmerkungen:\n- Keep this trigger enabled so the URL remains active.\n- Wir verifizieren Xero's x-xero-signature Header mit Ihrem Webhook Key.\n ",
"Fetch the full invoice and ensure Type is ACCREC (recommended).": "Rufen Sie die vollständige Rechnung ab und stellen Sie sicher, Typ ist ACCREC (empfohlen).",
"Also fire when a purchase order enters this status for the first time (since enabling).": "Auch feuern, wenn eine Bestellung zum ersten Mal in diesen Status eintritt (seit Aktivierung).",
"RECEIVE": "EMPFANG",
"SPEND": "SPENDE",
"RECEIVE-OVERPAYMENT": "EMPFANGEN ÜBERLEBEN",
"SPEND-OVERPAYMENT": "SPEND-ÜBERZAHLUNG",
"RECEIVE-PREPAYMENT": "EMPFANG PREPAYMENT",
"SPEND-PREPAYMENT": "SPEND-PREPAYMENT",
"RECEIVE-TRANSFER": "REZEIVE-TRANSFER",
"SPEND-TRANSFER": "SPEND-TRANSFER",
"AUTHORISED": "AUTHORISIERT",
"DELETED": "LÖSCHT",
"ACCRECPAYMENT (Received on Sales Invoice)": "ACCRECPAYMENT (auf Verkaufsrechnung erhalten)",
"ACCPAYPAYMENT (Paid on Bill)": "ACCPAYPAYMENT (Paid on Bill)",
"DRAFT": "DRAFT",
"SUBMITTED": "SUBMITTET",
"BILLED": "BILDT",
"SENT": "SEND",
"ACCEPTED": "AKZEPTIERT",
"DECLINED": "ENTFERNT",
"INVOICED": "INVOICIERT",
"PAID": "ZAHL",
"VOIDED": "ABSTIMMUNGEN",
"ACCRECCREDIT (Sales Credit)": "ACCRECCREDIT (Verkaufskredit)",
"ACCPAYCREDIT (Supplier Credit)": "ACCPAYCREDIT (Lieferantenkredit)",
"INPROGRESS": "INPROGRESS",
"CLOSED": "GESCHLOST"
}

View File

@@ -0,0 +1,320 @@
{
"Beautiful accounting software": "Hermoso software de contabilidad",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Inicie sesión en Xero.\n 2. Ve a [Portal de desarrollador](https://developer.xero.com/app/manage/).\n 3. Haz clic en la aplicación que quieras integrar.\n 4. A la izquierda, haga clic en `Configuración`.\n 5. Introduzca su `url de redirección`.\n 6. Copia el `ID del cliente` y el `Código del cliente`.\n ",
"Create or Update Contact": "Crear o actualizar contacto",
"Create or Update Invoice": "Crear o actualizar factura",
"Allocate Credit Note to Invoice": "Asignar nota de crédito a la factura",
"Create Bank Transfer": "Crear transferencia bancaria",
"Create New Quote Draft": "Crear nuevo borrador de presupuesto",
"Send Sales Invoice by Email": "Enviar factura de ventas por correo electrónico",
"Create Bill": "Crear factura",
"Create Payment": "Crear Pago",
"Create Purchase Order": "Crear orden de compra",
"Update Purchase Order": "Actualizar orden de compra",
"Upload Attachment": "Subir adjunto",
"Add Items to Existing Sales Invoice": "Añadir artículos a la factura de ventas existente",
"Create Credit Note": "Crear nota de crédito",
"Create Inventory Item": "Crear elemento de inventario",
"Create Project": "Crear proyecto",
"Update Sales Invoice": "Actualizar factura de ventas",
"Create Repeating Sales Invoice": "Crear nueva factura de ventas",
"Find Contact": "Encontrar contacto",
"Find Invoice": "Buscar factura",
"Find Item": "Buscar artículo",
"Find Purchase Order": "Buscar orden de compra",
"Custom API Call": "Llamada API personalizada",
"Create Xero Contact": "Crear contacto Xero",
"Create Xero Invoice": "Crear Factura Xero",
"Allocates a credit note to a specific invoice.": "Asigna una nota de crédito a una factura específica.",
"Transfers money between two bank accounts in Xero.": "Transfiere dinero entre dos cuentas bancarias en Xero.",
"Creates a new draft quote.": "Crea un nuevo proyecto de cita.",
"Sends a sales invoice via email to a contact.": "Envía una factura de venta por correo electrónico a un contacto.",
"Creates a new bill (Accounts Payable).": "Crea una nueva factura (Cuentas a Pagar).",
"Applies a payment to an invoice.": "Se aplica un pago a una factura.",
"Creates a new purchase order for a contact.": "Crea una nueva orden de compra para un contacto.",
"Updates details of an existing purchase order.": "Actualiza los detalles de una orden de compra existente.",
"Uploads an attachment to a specific Xero resource.": "Sube un archivo adjunto a un recurso Xero específico.",
"Adds line items to an existing sales invoice (ACCREC).": "Añade artículos de línea a una factura de ventas existente (ACCREC).",
"Creates a new credit note for a contact.": "Crea una nueva nota de crédito para un contacto.",
"Creates a new inventory item in Xero.": "Crea un nuevo elemento de inventario en Xero.",
"Creates a new project for a contact.": "Crea un nuevo proyecto para un contacto.",
"Updates details of an existing sales invoice (ACCREC).": "Actualiza los detalles de una factura de ventas existente (ACCREC).",
"Creates a repeating sales invoice (Accounts Receivable).": "Crea una factura de venta repetida (Cuentas a cobrar).",
"Finds a contact by name or account number (or SearchTerm).": "Encuentra un contacto por nombre o número de cuenta (o Términos de búsqueda).",
"Finds an invoice by number or reference.": "Encuentra una factura por número o referencia.",
"Finds an item by name or code.": "Encuentra un elemento por nombre o código.",
"Finds a purchase order by given parameters.": "Encuentra una orden de compra por parámetros determinados.",
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
"Organization": "Organización",
"Contact ID": "ID de contacto",
"Contact Name": "Nombre de contacto",
"Contact Email": "Email de contacto",
"Invoice": "Factura",
"Contact": "Contacto",
"Line Item": "Ítem línea",
"Date Prepared": "Fecha Preparada",
"Due Date": "Fecha de fin",
"Invoice Reference": "Referencia de factura",
"Status": "Estado",
"Credit Note": "Nota de crédito",
"Amount": "Cantidad",
"Allocation Date": "Fecha de adjudicación",
"Bank Account": "Cuenta bancaria",
"Transfer Date": "Fecha de transferencia",
"Reference": "Referencia",
"From Is Reconciled": "De Es Reconocido",
"To Is Reconciled": "A Está Reconocido",
"Date": "Fecha",
"Expiry Date": "Expiry Date",
"Line Amount Types": "Tipos de cantidad de línea",
"Quote Number": "Número de cotización",
"Title": "Título",
"Summary": "Summary",
"Terms": "Términos",
"Sales Invoice (Sendable)": "Factura de ventas (Enviable)",
"Bill Number (Reference)": "Número de factura (referencia)",
"Invoice (Authorised)": "Factura (autorizada)",
"Payment Date": "Fecha de pago",
"Is Reconciled": "Está re-coneccionado",
"Delivery Date": "Fecha de entrega",
"Purchase Order Number": "Número de orden de compra",
"Branding Theme": "Tema de marca",
"Delivery Address": "Dirección de entrega",
"Attention To": "Atención a",
"Telephone": "Teléfono",
"Delivery Instructions": "Instrucciones de entrega",
"Expected Arrival Date": "Fecha de llegada esperada",
"Purchase Order": "Orden de compra",
"Mark as Sent to Contact": "Marcar como enviado al contacto",
"Expected Arrival Date (YYYY-MM-DD)": "Fecha de llegada esperada (YYY-MM-DD)",
"Resource Type": "Tipo de recurso",
"Resource": "Recurso",
"File": "Archivo",
"File Name (override)": "Nombre del archivo (anular)",
"Content Type": "Tipo de contenido",
"Include with Online Invoice": "Incluye con factura online",
"Allow AUTHORISED invoices": "Permitir facturas AUTHORISED",
"New Line Items": "Nuevos elementos de línea",
"Type": "Tipo",
"Credit Note Number": "Número de nota de crédito",
"Reference (ACCRECCREDIT only)": "Referencia (sólo ACCRECCREDIT)",
"Currency Code": "Código de moneda",
"Line Items": "Ítems de línea",
"Item Code": "Código del artículo",
"Name": "Nombre",
"Sales Description": "Descripción de ventas",
"Purchase Description": "Descripción de compra",
"Is Sold": "Se vende",
"Is Purchased": "Está comprado",
"Sales Details": "Detalles de ventas",
"Account": "Cuenta",
"Purchase Details": "Detalles de compra",
"Project Name": "Nombre del proyecto",
"Deadline (UTC ISO-8601)": "Fecha límite (UTC ISO-8601)",
"Estimate Amount": "Cantidad estimada",
"Sales Invoice (Editable)": "Factura de ventas (editable)",
"Due Date (YYYY-MM-DD)": "Fecha de vencimiento (AAA-MM-DD)",
"Invoice Number": "Número de factura",
"Source URL": "URL de origen",
"Replace All Line Items": "Reemplazar todos los elementos de línea",
"Line Items (updates/additions)": "Ítems de línea (actualizaciones/añadidos)",
"Schedule Period": "Periodo de Programación",
"Schedule Unit": "Programar unidad",
"Due Date (number)": "Fecha límite (número)",
"Due Date Type": "Tipo de fecha límite",
"Start Date (YYYY-MM-DD)": "Fecha de inicio (AAA-MM-DD)",
"End Date (YYYY-MM-DD)": "Fecha de fin (AAA-MM-DD)",
"Currency": "Moneda",
"Approved For Sending": "Aprobado para enviar",
"Send Copy": "Enviar copia",
"Mark As Sent": "Marcar como enviado",
"Include PDF": "Incluye PDF",
"Search By": "Buscar por",
"Value": "Valor",
"Include Archived": "Incluye Archivado",
"Summary Only (faster, lighter)": "Sólo resumen (más rápido, más ligero)",
"Page": "Pgina",
"Type Filter": "Filtro de tipo",
"Order (optional)": "Orden (opcional)",
"Statuses": "Statuses",
"Date From (YYYY-MM-DD)": "Fecha desde (YYYY-MM-DD)",
"Date To (YYYY-MM-DD)": "Fecha hasta (AAA-MM-DD)",
"Order (e.g., Date DESC)": "Orden (por ejemplo, fecha DESC)",
"Page Size (1-1000)": "Tamaño de página (1-1000)",
"Method": "Método",
"Headers": "Encabezados",
"Query Parameters": "Parámetros de consulta",
"Body": "Cuerpo",
"Response is Binary ?": "¿Respuesta es binaria?",
"No Error on Failure": "No hay ningún error en fallo",
"Timeout (in seconds)": "Tiempo de espera (en segundos)",
"ID of the contact to create invoice for.": "ID del contacto para crear la factura.",
"Contact name, in full.": "Nombre de contacto, completo.",
"Email address of the contact.": "Dirección de correo electrónico del contacto.",
"Select an invoice": "Seleccione una factura",
"Select a contact": "Seleccione un contacto",
"Invoice line items": "Elementos de línea de factura",
"Date the invoice was created. Format example: 2019-03-11": "Fecha de creación de la factura. Ejemplo: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "Fecha límite de la factura. Ejemplo: 2019-03-11",
"Reference number of the Invoice": "Número de referencia de la factura",
"Invoice Status": "Estado de la factura",
"Select a credit note to allocate from": "Seleccione una nota de crédito de la que asignar",
"The amount of the credit to allocate.": "La cantidad del crédito a asignar.",
"Date of allocation. Format: YYYY-MM-DD. Optional.": "Fecha de asignación. Formato: AAA-MM-DD. Opcional.",
"Select a bank account": "Seleccione una cuenta bancaria",
"Amount to transfer. Currencies must match between accounts.": "Cantidad a transferir. Las monedas deben coincidir entre cuentas.",
"YYYY-MM-DD. Defaults to today if not provided.": "AAA-MM-DD. Por defecto hoy si no se proporciona.",
"Reference for the transfer.": "Referencia para la transferencia.",
"Mark source account transaction as reconciled.": "Marcar la transacción de la cuenta fuente como reconciliada.",
"Mark destination account transaction as reconciled.": "Marcar transacción de cuenta de destino como reconciliada.",
"Date the quote was issued (YYYY-MM-DD).": "Fecha de emisión de la cotización (AAY-MM-DD).",
"Date the quote expires (YYYY-MM-DD).": "Fecha de expiración del presupuesto (AAA-MM-DD).",
"At minimum, provide a Description.": "Como mínimo, proporcione una descripción.",
"Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).": "Seleccione una factura de venta con un estado válido para el envío de correo electrónico (SUBMITTED, AUTORISED, o PAID).",
"Date the bill was issued (YYYY-MM-DD). Optional.": "Fecha de emisión de la factura (AAA-MM-DD). Opcional.",
"Date the bill is due (YYYY-MM-DD). Optional.": "Fecha de vencimiento de la factura (AAA-MM-DD). Opcional.",
"Select an authorised invoice (sales or bill) to apply payment to.": "Seleccione una factura autorizada (venta o factura) a la que aplicar el pago.",
"Payment amount (must be <= amount due).": "Monto del pago (debe ser <= monto debido).",
"YYYY-MM-DD.": "AAA-MM-DD.",
"Mark payment as reconciled (optional).": "Marcar pago como conciliado (opcional).",
"Date the purchase order was issued (YYYY-MM-DD). Optional.": "Fecha de emisión de la orden de compra (AAA-MM-DD). Opcional.",
"Date goods are to be delivered (YYYY-MM-DD). Optional.": "Los artículos de fecha se entregarán (AAA-MM-DD). Opcional.",
"Select a branding theme": "Seleccione un tema de marca",
"YYYY-MM-DD. Optional.": "AAA-MM-DD. Opcional.",
"Select a purchase order to update": "Seleccione una orden de compra para actualizar",
"The Xero resource to attach the file to.": "El recurso Xero al que adjuntar el archivo.",
"Select the specific resource to attach the file to.": "Seleccione el recurso específico al que adjuntar el archivo.",
"The file to upload. Max 10MB per Xero limits.": "El archivo a cargar. Máximo 10MB por Xero límites.",
"Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *": "Nombre de archivo opcional a usar en Xero. Evita caracteres: < > : \" / \\ | ? *",
"MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.": "Tipo MIME del archivo (por ej., imagen/png). Si no se establece, será inferior o predeterminado a la aplicación/octet-stream.",
"Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.": "Sólo aplicable a las facturas ACCREC y notas de crédito ACCREC. Añade IncludeOnline=parámetro de consulta verdadera.",
"Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Habilitar añadir elementos a las facturas AUTORISADAS (Xero permite actualizaciones limitadas para ACCREC pagado/parcial).",
"Add one or more line items. At minimum, each line needs a Description.": "Añada uno o más elementos de línea. Como mínimo, cada línea necesita una descripción.",
"Select an account": "Seleccione una cuenta",
"Example: 2017-04-23T18:25:43.511Z": "Ejemplo: 2017-04-23T18:25:43.511Z",
"Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Habilitar actualizaciones para facturas AUTORISADAS (Xero permite actualizaciones limitadas para ACCREC pagado/parcial).",
"Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.": "Seleccione una factura de ventas (ACCREC) con estado DRAFT o SUBMITTADO.",
"If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.": "Si se activa, sólo los elementos de línea proporcionados permanecerán. Si se deshabilita, se fusionarán con las líneas actuales actualizando el LineItemID y añadiendo nuevos elementos.",
"Integer period (e.g., 1 every week, 2 every month).": "Período entero (por ej., 1 cada semana, 2 cada mes).",
"Day number used with due date type (e.g., 20, 31).": "Número de día utilizado con el tipo de fecha de vencimiento (por ej., 20, 31).",
"Select a currency code": "Seleccione un código de moneda",
"Name, Account Number, or Search Term depending on Search By.": "Nombre, número de cuenta o búsqueda de términos, dependiendo de la búsqueda por.",
"Recommended for broad searches (Search Term). Excludes heavy fields.": "Recomendado para búsquedas amplias (término de búsqueda). Excluye campos pesados.",
"Pagination page (optional).": "Página de paginación (opcional).",
"Invoice Number, Reference, or Search Term.": "Número de factura, referencia o término de búsqueda.",
"Item Code or Name (exact match).": "Código o nombre del artículo (coincidencia exacta).",
"e.g. Name or Name DESC": "ej. Nombre o Nombre DESC",
"Number, Reference or ID depending on Search By.": "Número, referencia o ID dependiendo de la búsqueda por.",
"Authorization headers are injected automatically from your connection.": "Las cabeceras de autorización se inyectan automáticamente desde tu conexión.",
"Enable for files like PDFs, images, etc..": "Activar para archivos como PDFs, imágenes, etc.",
"Draft": "Borrador",
"Submitted": "Enviado",
"Authorised": "Autorizado",
"Deleted": "Eliminado",
"Voided": "Vacío",
"Exclusive": "Exclusivo",
"Inclusive": "Inclusivo",
"NoTax": "NoTax",
"Billed": "Facturado",
"Quote": "Cotización",
"Bank Transfer": "Transferencia bancaria",
"Bank Transaction": "Transacción bancaria",
"Manual Journal": "Diario manual",
"Receipt": "Recibo",
"Repeating Invoice": "Repetir factura",
"Accounts Receivable Credit (ACCRECCREDIT)": "Crédito a cobrar cuentas (ACCRECCREDIT)",
"Accounts Payable Credit (ACCPAYCREDIT)": "Crédito a pagar cuentas (ACCPAYCREDIT)",
"Weekly": "Semanal",
"Monthly": "Mensual",
"Name (exact match)": "Nombre (coincidencia exacta)",
"Account Number (exact match)": "Número de cuenta (coincidencia exacta)",
"Search Term (broad search)": "Buscar término (búsqueda amplia)",
"Invoice Number (exact)": "Número de factura (exacto)",
"Reference (exact)": "Referencia (exacto)",
"Search Term (InvoiceNumber/Reference)": "Buscar término (InvoiceNumber/referencia)",
"Sales Invoice (ACCREC)": "Factura de ventas (ACCREC)",
"Bill (ACCPAY)": "Factura (ACCPAY)",
"Code (exact)": "Código (exacto)",
"Name (exact)": "Nombre (exacto)",
"Purchase Order Number (exact)": "Número de orden de compra (exacto)",
"Purchase Order ID (GUID)": "ID de orden de compra (GUID)",
"GET": "RECOGER",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "BORRAR",
"HEAD": "LIMPIO",
"New Contact": "Nuevo contacto",
"New or Updated Contact": "Contacto nuevo o actualizado",
"New Sales Invoice": "Nueva factura de ventas",
"Updated Sales Invoice": "Factura de ventas actualizada",
"New Bank Transaction": "Nueva transacción bancaria",
"New Payment": "Nuevo pago",
"New Purchase Order": "Nueva orden de compra",
"New Reconciled Payment": "Nuevo Pago Reconocido",
"Updated Quote": "Cotización actualizada",
"New Bill": "Nueva factura",
"New Credit Note": "Nueva nota de crédito",
"New Project": "Nuevo proyecto",
"New Quote": "Nuevo presupuesto",
"Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.": "Se activa cuando se añade un nuevo contacto a Xero (a través de webhooks Xero). Configura el webhook en el portal de Xero Developer para apuntar a esta URL.",
"Fires when a contact is created or updated (via Xero webhooks).": "Dispara cuando un contacto es creado o actualizado (a través de webhooks Xero).",
"Fires when a new sales invoice (Accounts Receivable) is created.": "Se desencadena cuando se crea una nueva factura de ventas (Cuadro de clientes).",
"Fires when an existing sales invoice (Accounts Receivable) is updated.": "Dispara cuando se actualiza una factura de ventas existente (Receptor de clientes).",
"Fires when a new bank transaction is created.": "Dispara cuando se crea una nueva transacción bancaria.",
"Fires when a payment is received.": "Dispara cuando un pago es recibido.",
"Fires when a new purchase order is created or enters a specific status for the first time.": "Dispara cuando se crea una nueva orden de compra o entra en un estado específico por primera vez.",
"Fires when a payment is reconciled for the first time.": "Dispara cuando un pago se reconcilia por primera vez.",
"Fires when a quote is created or updated.": "Se activa cuando se crea o actualiza una cotización.",
"Fires when a new bill (Accounts Payable) is added.": "Inicia cuando se agrega una nueva factura (Cuentas a Pagar).",
"Fires when a new credit note is created.": "Dispara cuando se crea una nueva nota de crédito.",
"Fires when a new project is created.": "Dispara cuando se crea un nuevo proyecto.",
"Fires when a new quote is created.": "Dispara cuando se crea una nueva comilla.",
"Markdown": "Markdown",
"Webhook Key": "Clave Webhook",
"Fetch Full Contact": "Recuperar contacto completo",
"Fetch Full Invoice": "Recuperar factura completa",
"Types": "Tipos",
"Bank Account Code": "Código de cuenta bancaria",
"Payment Types": "Tipos de pago",
"Filter by Status (optional)": "Filtrar por Estado (opcional)",
"First-time Status (optional)": "Estado de primer tiempo (opcional)",
"Quote Number (partial match)": "Número de cotización (coincidencia parcial)",
"Expiry Date From (YYYY-MM-DD)": "Fecha de caducidad desde (AAA-MM-DD)",
"Expiry Date To (YYYY-MM-DD)": "Fecha de vencimiento (AAA-MM-DD)",
"Statuses (optional)": "Estados (opcional)",
"Summary Only (lighter, faster)": "Sólo resumen (más ligero, más rápido)",
"States (optional)": "Estados (opcional)",
"Page Size (1-500)": "Page Size (1-500)",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.": "Desde el portal de Xero Developer > Tu aplicación > Webhooks. Utilizado para verificar la firma x-xero.",
"If enabled, fetches the full contact from Xero using the Resource URL.": "Si está activado, obtiene el contacto completo de Xero usando la URL de Recursos.",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"Fetch the full invoice and ensure Type is ACCREC (recommended).": "Obtener la factura completa y asegurarse de que Type es ACCREC (recomendado).",
"Also fire when a purchase order enters this status for the first time (since enabling).": "También dispara cuando una orden de compra entra en este estado por primera vez (desde que se activa).",
"RECEIVE": "RECIBIR",
"SPEND": "ESPENDIR",
"RECEIVE-OVERPAYMENT": "RESPONSABILIDAD RECIBLE",
"SPEND-OVERPAYMENT": "RESPONSABILIDAD",
"RECEIVE-PREPAYMENT": "PREPREPAYMENTE REECEIVO",
"SPEND-PREPAYMENT": "PENDIENTE-PREPAYMENTE",
"RECEIVE-TRANSFER": "RECEIVE-TRANSFER",
"SPEND-TRANSFER": "ESPEND-TRANSFER",
"AUTHORISED": "AUTORIZADO",
"DELETED": "ELIMINADO",
"ACCRECPAYMENT (Received on Sales Invoice)": "ACCRECPAYMENT (Recibido por factura de ventas)",
"ACCPAYPAYMENT (Paid on Bill)": "ACCPAYPAYMENT (Paid on Bill)",
"DRAFT": "DRAFT",
"SUBMITTED": "SUBMITADO",
"BILLED": "RECOGIDO",
"SENT": "Enviado",
"ACCEPTED": "ACEPTADO",
"DECLINED": "DELLÍNEO",
"INVOICED": "INVOCIADO",
"PAID": "PÁDIO",
"VOIDED": "VOIDO",
"ACCRECCREDIT (Sales Credit)": "ACCRECCREDIT (Crédito de venta)",
"ACCPAYCREDIT (Supplier Credit)": "ACCPAYCREDIT (Crédito de Proveedores)",
"INPROGRESS": "INPROGRESO",
"CLOSED": "CERRADO"
}

View File

@@ -0,0 +1,320 @@
{
"Beautiful accounting software": "Magnifique logiciel de comptabilité",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ",
"Create or Update Contact": "Créer ou mettre à jour le contact",
"Create or Update Invoice": "Créer ou mettre à jour la facture",
"Allocate Credit Note to Invoice": "Attribuer un avoir à la facture",
"Create Bank Transfer": "Créer un virement bancaire",
"Create New Quote Draft": "Créer un nouveau brouillon de devis",
"Send Sales Invoice by Email": "Envoyer une facture de vente par e-mail",
"Create Bill": "Créer une facture",
"Create Payment": "Créer un paiement",
"Create Purchase Order": "Créer un bon de commande",
"Update Purchase Order": "Mettre à jour le bon de commande",
"Upload Attachment": "Charger une pièce jointe",
"Add Items to Existing Sales Invoice": "Ajouter des articles à la facture de vente existante",
"Create Credit Note": "Créer un avoir",
"Create Inventory Item": "Créer un article d'inventaire",
"Create Project": "Créer un projet",
"Update Sales Invoice": "Mettre à jour la facture de vente",
"Create Repeating Sales Invoice": "Créer une facture de vente répétée",
"Find Contact": "Trouver un contact",
"Find Invoice": "Trouver une facture",
"Find Item": "Trouver un objet",
"Find Purchase Order": "Trouver un bon de commande",
"Custom API Call": "Appel d'API personnalisé",
"Create Xero Contact": "Créer un contact Xero",
"Create Xero Invoice": "Créer une facture Xero",
"Allocates a credit note to a specific invoice.": "Affecte un avoir à une facture spécifique.",
"Transfers money between two bank accounts in Xero.": "Transfère de l'argent entre deux comptes bancaires à Xero.",
"Creates a new draft quote.": "Crée un nouveau devis brouillon.",
"Sends a sales invoice via email to a contact.": "Envoie une facture de vente par e-mail à un contact.",
"Creates a new bill (Accounts Payable).": "Crée une nouvelle facture (Comptes Payables).",
"Applies a payment to an invoice.": "Applique un paiement à une facture.",
"Creates a new purchase order for a contact.": "Crée un nouveau bon de commande pour un contact.",
"Updates details of an existing purchase order.": "Met à jour les détails d'un bon de commande existant.",
"Uploads an attachment to a specific Xero resource.": "Téléverse une pièce jointe à une ressource spécifique de Xero.",
"Adds line items to an existing sales invoice (ACCREC).": "Ajoute des articles de ligne à une facture de vente existante (ACCRE).",
"Creates a new credit note for a contact.": "Crée un nouvel avoir pour un contact.",
"Creates a new inventory item in Xero.": "Crée un nouvel élément d'inventaire dans Xero.",
"Creates a new project for a contact.": "Crée un nouveau projet pour un contact.",
"Updates details of an existing sales invoice (ACCREC).": "Met à jour les détails d'une facture de vente existante (ACCRE).",
"Creates a repeating sales invoice (Accounts Receivable).": "Crée une facture de vente récurrente (Compte destinataire).",
"Finds a contact by name or account number (or SearchTerm).": "Trouve un contact par nom ou numéro de compte (ou SearchTerm).",
"Finds an invoice by number or reference.": "Trouve une facture par numéro ou référence.",
"Finds an item by name or code.": "Trouve un élément par nom ou code.",
"Finds a purchase order by given parameters.": "Trouve un bon de commande par paramètres donnés.",
"Make a custom API call to a specific endpoint": "Passer un appel API personnalisé à un endpoint spécifique",
"Organization": "Organisation",
"Contact ID": "ID du contact",
"Contact Name": "Nom du contact",
"Contact Email": "Courriel du contact",
"Invoice": "Facture",
"Contact": "Contacter",
"Line Item": "Élément de ligne",
"Date Prepared": "Date de préparation",
"Due Date": "Date de fin",
"Invoice Reference": "Référence de la facture",
"Status": "Statut",
"Credit Note": "Avoir",
"Amount": "Montant",
"Allocation Date": "Date d'allocation",
"Bank Account": "Compte bancaire",
"Transfer Date": "Date de transfert",
"Reference": "Référence",
"From Is Reconciled": "Depuis est rapproché",
"To Is Reconciled": "Est rapproché",
"Date": "Date",
"Expiry Date": "Expiry Date",
"Line Amount Types": "Types de montant de ligne",
"Quote Number": "Numéro du devis",
"Title": "Titre de la page",
"Summary": "Résumé",
"Terms": "Conditions générales de vente",
"Sales Invoice (Sendable)": "Facture de vente (Envoyable)",
"Bill Number (Reference)": "Numéro de facture (référence)",
"Invoice (Authorised)": "Facture (autorisée)",
"Payment Date": "Date de paiement",
"Is Reconciled": "Est rapproché",
"Delivery Date": "Date de livraison",
"Purchase Order Number": "Numéro de bon de commande",
"Branding Theme": "Thème de la marque",
"Delivery Address": "Adresse de livraison",
"Attention To": "Attention à",
"Telephone": "Téléphone",
"Delivery Instructions": "Instructions de livraison",
"Expected Arrival Date": "Date d'arrivée prévue",
"Purchase Order": "Bon de commande",
"Mark as Sent to Contact": "Marquer comme envoyé au contact",
"Expected Arrival Date (YYYY-MM-DD)": "Date d'arrivée prévue (AAAA-MM-JJ)",
"Resource Type": "Type de ressource",
"Resource": "Ressource",
"File": "Ficher",
"File Name (override)": "Nom du fichier (substitution)",
"Content Type": "Type de contenu",
"Include with Online Invoice": "Inclure avec la facture en ligne",
"Allow AUTHORISED invoices": "Autoriser les factures AUTORISées",
"New Line Items": "Nouvelles lignes",
"Type": "Type de texte",
"Credit Note Number": "Numéro d''avoir",
"Reference (ACCRECCREDIT only)": "Référence (ACCRECCREDIT uniquement)",
"Currency Code": "Code de la devise",
"Line Items": "Lignes",
"Item Code": "Code de larticle",
"Name": "Nom",
"Sales Description": "Description des ventes",
"Purchase Description": "Description de l'achat",
"Is Sold": "Est vendu",
"Is Purchased": "Est acheté",
"Sales Details": "Détails de la vente",
"Account": "Compte client",
"Purchase Details": "Détails de l'achat",
"Project Name": "Project Name",
"Deadline (UTC ISO-8601)": "Date limite (UTC ISO-8601)",
"Estimate Amount": "Montant estimé",
"Sales Invoice (Editable)": "Facture de vente (modifiable)",
"Due Date (YYYY-MM-DD)": "Date d'échéance (AAAAA-MM-JJ)",
"Invoice Number": "Numéro de facture",
"Source URL": "URL de la source",
"Replace All Line Items": "Remplacer tous les éléments de la ligne",
"Line Items (updates/additions)": "Lignes (mises à jour/ajouts)",
"Schedule Period": "Planifier la période",
"Schedule Unit": "Unité de planification",
"Due Date (number)": "Date d'échéance (nombre)",
"Due Date Type": "Type d'échéance",
"Start Date (YYYY-MM-DD)": "Date de début (AAAAA-MM-JJ)",
"End Date (YYYY-MM-DD)": "Date de fin (AAAAA-MM-JJ)",
"Currency": "Devise",
"Approved For Sending": "Approuvé pour l'envoi",
"Send Copy": "Envoyer une copie",
"Mark As Sent": "Marquer comme envoyé",
"Include PDF": "Inclure le PDF",
"Search By": "Rechercher par",
"Value": "Valeur",
"Include Archived": "Inclure les archives",
"Summary Only (faster, lighter)": "Résumé seulement (plus rapide, plus léger)",
"Page": "Page",
"Type Filter": "Filtre de type",
"Order (optional)": "Commande (optionnelle)",
"Statuses": "Statuses",
"Date From (YYYY-MM-DD)": "Date de (AAAA-MM-JJ)",
"Date To (YYYY-MM-DD)": "Date de (AAAA-MM-JJ)",
"Order (e.g., Date DESC)": "Commande (p. ex., date de désignation)",
"Page Size (1-1000)": "Taille de la page (1-1000)",
"Method": "Méthode",
"Headers": "En-têtes",
"Query Parameters": "Paramètres de requête",
"Body": "Corps",
"Response is Binary ?": "La réponse est Binaire ?",
"No Error on Failure": "Aucune erreur en cas d'échec",
"Timeout (in seconds)": "Délai d'expiration (en secondes)",
"ID of the contact to create invoice for.": "ID du contact pour lequel créer une facture.",
"Contact name, in full.": "Nom du contact dans son intégralité.",
"Email address of the contact.": "Adresse e-mail du contact.",
"Select an invoice": "Sélectionnez une facture",
"Select a contact": "Sélectionnez un contact",
"Invoice line items": "Éléments de la ligne de facture",
"Date the invoice was created. Format example: 2019-03-11": "Date de création de la facture. Exemple de format: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "Date d'échéance de la facture. Exemple de format: 2019-03-11",
"Reference number of the Invoice": "Numéro de référence de la facture",
"Invoice Status": "Statut de la facture",
"Select a credit note to allocate from": "Sélectionnez un avoir à allouer à partir de",
"The amount of the credit to allocate.": "Le montant du crédit à attribuer.",
"Date of allocation. Format: YYYY-MM-DD. Optional.": "Date d'attribution. Format : AAAA-MM-JJ. Optionnel.",
"Select a bank account": "Sélectionnez un compte bancaire",
"Amount to transfer. Currencies must match between accounts.": "Montant à transférer. Les devises doivent correspondre entre les comptes.",
"YYYY-MM-DD. Defaults to today if not provided.": "AAAA-MM-JJ. Par défaut si elle n'est pas fournie.",
"Reference for the transfer.": "Référence pour le transfert.",
"Mark source account transaction as reconciled.": "Marquer la transaction du compte source comme rapprochée.",
"Mark destination account transaction as reconciled.": "Marquer la transaction du compte de destination comme rapprochée.",
"Date the quote was issued (YYYY-MM-DD).": "Date d'émission du devis (AAAA-MM-JJ).",
"Date the quote expires (YYYY-MM-DD).": "Date d'expiration du devis (AAAA-MM-JJ).",
"At minimum, provide a Description.": "Au minimum, fournir une description.",
"Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).": "Sélectionnez une facture de vente avec un statut valide pour l'envoi d'e-mail (SUBMIT, AUTORISÉ ou PAID).",
"Date the bill was issued (YYYY-MM-DD). Optional.": "Date d'émission de la facture (AAAA-MM-JJ). Optionnelle.",
"Date the bill is due (YYYY-MM-DD). Optional.": "Date d'échéance de la facture (AAAA-MM-JJ). Optionnelle.",
"Select an authorised invoice (sales or bill) to apply payment to.": "Sélectionnez une facture autorisée (ventes ou factures) à laquelle appliquer le paiement.",
"Payment amount (must be <= amount due).": "Montant du paiement (doit être <= montant dû).",
"YYYY-MM-DD.": "AAAA-MM-JJ.",
"Mark payment as reconciled (optional).": "Marquer le paiement comme rapproché (optionnel).",
"Date the purchase order was issued (YYYY-MM-DD). Optional.": "Date d'émission du bon de commande (AAAA-MM-JJ). Optionnel.",
"Date goods are to be delivered (YYYY-MM-DD). Optional.": "Date de livraison des marchandises (AAAA-MM-JJ). Optionnelle.",
"Select a branding theme": "Sélectionnez un thème de marque",
"YYYY-MM-DD. Optional.": "AAAA-MM-JJ. Optionnel.",
"Select a purchase order to update": "Sélectionnez un bon de commande à mettre à jour",
"The Xero resource to attach the file to.": "La ressource Xero à laquelle attacher le fichier.",
"Select the specific resource to attach the file to.": "Sélectionnez la ressource spécifique à laquelle attacher le fichier.",
"The file to upload. Max 10MB per Xero limits.": "Le fichier à télécharger. Maximum 10 Mo par Xero limites.",
"Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *": "Nom du fichier optionnel à utiliser dans Xero. Évitez les caractères: < > : \" / \\ | ? *",
"MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.": "Type MIME du fichier (par exemple, image/png). Si non défini, sera déduit ou par défaut à application/octet-stream.",
"Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.": "Ne s'applique qu'aux factures ACCREC et aux avoirs ACCREC. Ajoute IncludeOnline=true paramètre de requête.",
"Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Activer l'ajout d'éléments aux factures AUTORISÉES (Xero permet des mises à jour limitées pour l'ACCEC payé/partielle).",
"Add one or more line items. At minimum, each line needs a Description.": "Ajouter un ou plusieurs éléments de ligne. Au minimum, chaque ligne a besoin d'une description.",
"Select an account": "Sélectionnez un compte",
"Example: 2017-04-23T18:25:43.511Z": "Exemple: 2017-04-23T18:25:43.511Z",
"Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Activer les mises à jour pour les factures AUTORISÉES (Xero permet des mises à jour limitées pour les factures payées/partielles).",
"Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.": "Sélectionnez une facture de vente (ACCREC) avec le statut DRAFT ou Envoyé.",
"If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.": "Si activé, seuls les éléments ligne fournis resteront. Si désactivé, nous fusionnerons avec les lignes en cours en mettant à jour LineItemID correspondant et en ajoutant de nouveaux éléments.",
"Integer period (e.g., 1 every week, 2 every month).": "Période entière (par exemple, 1 chaque semaine, 2 chaque mois).",
"Day number used with due date type (e.g., 20, 31).": "Numéro de jour utilisé avec le type de date d'échéance (par exemple, 20, 31).",
"Select a currency code": "Sélectionnez un code de devise",
"Name, Account Number, or Search Term depending on Search By.": "Nom, numéro de compte ou terme de recherche selon la recherche par.",
"Recommended for broad searches (Search Term). Excludes heavy fields.": "Recommandé pour les recherches étendues (terme de recherche). Exclut les champs lourds.",
"Pagination page (optional).": "Page de pagination (facultatif).",
"Invoice Number, Reference, or Search Term.": "Numéro de facture, référence ou terme de recherche.",
"Item Code or Name (exact match).": "Code ou nom de larticle (correspondance exacte).",
"e.g. Name or Name DESC": "par exemple Nom ou Nom DESC",
"Number, Reference or ID depending on Search By.": "Numéro, Référence ou ID en fonction de la recherche par.",
"Authorization headers are injected automatically from your connection.": "Les en-têtes d'autorisation sont injectés automatiquement à partir de votre connexion.",
"Enable for files like PDFs, images, etc..": "Activer pour les fichiers comme les PDFs, les images, etc.",
"Draft": "Brouillon",
"Submitted": "Soumis",
"Authorised": "Autorisé",
"Deleted": "Supprimé",
"Voided": "Annulé",
"Exclusive": "Exclusif",
"Inclusive": "Inclus",
"NoTax": "NoTax",
"Billed": "Facturé",
"Quote": "Devis",
"Bank Transfer": "Virement bancaire",
"Bank Transaction": "Transaction bancaire",
"Manual Journal": "Journal manuel",
"Receipt": "Reçu",
"Repeating Invoice": "Facture répétée",
"Accounts Receivable Credit (ACCRECCREDIT)": "Crédit créditeur des comptes clients (ACCRECCREDIT)",
"Accounts Payable Credit (ACCPAYCREDIT)": "Crédit des comptes fournisseurs (ACCPAYCREDIT)",
"Weekly": "Hebdomadaire",
"Monthly": "Mensuel",
"Name (exact match)": "Nom (correspondance exacte)",
"Account Number (exact match)": "Numéro de compte (correspondance exacte)",
"Search Term (broad search)": "Terme de recherche (recherche large)",
"Invoice Number (exact)": "Numéro de facture (exact)",
"Reference (exact)": "Référence (exacte)",
"Search Term (InvoiceNumber/Reference)": "Terme de recherche (numéro de facture/référence)",
"Sales Invoice (ACCREC)": "Facture de vente (ACCREC)",
"Bill (ACCPAY)": "Facture (ACCPAY)",
"Code (exact)": "Code (exact)",
"Name (exact)": "Nom (exact)",
"Purchase Order Number (exact)": "Numéro de bon de commande (exact)",
"Purchase Order ID (GUID)": "ID du bon de commande (GUID)",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Contact": "Nouveau contact",
"New or Updated Contact": "Contact nouveau ou mis à jour",
"New Sales Invoice": "Nouvelle facture de vente",
"Updated Sales Invoice": "Facture de vente mise à jour",
"New Bank Transaction": "Nouvelle transaction bancaire",
"New Payment": "Nouveau paiement",
"New Purchase Order": "Nouvel ordre d'achat",
"New Reconciled Payment": "Nouveau paiement rapproché",
"Updated Quote": "Devis mis à jour",
"New Bill": "Nouvelle facture",
"New Credit Note": "Nouvel avoir",
"New Project": "Nouveau projet",
"New Quote": "Nouveau devis",
"Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.": "Se déclenche lorsqu'un nouveau contact est ajouté à Xero (via Xero webhooks). Configurer le webhook dans le portail Xero Developer pour pointer vers cette URL.",
"Fires when a contact is created or updated (via Xero webhooks).": "Déclenche lorsqu'un contact est créé ou mis à jour (via Xero webhooks).",
"Fires when a new sales invoice (Accounts Receivable) is created.": "Déclenche quand une nouvelle facture de vente (Compte client) est créée.",
"Fires when an existing sales invoice (Accounts Receivable) is updated.": "Déclenche lorsqu'une facture de vente existante (Compte client) est mise à jour.",
"Fires when a new bank transaction is created.": "Tire quand une nouvelle transaction bancaire est créée.",
"Fires when a payment is received.": "Se déclenche lorsqu'un paiement est reçu.",
"Fires when a new purchase order is created or enters a specific status for the first time.": "Tire quand un nouveau bon de commande est créé ou entre dans un statut spécifique pour la première fois.",
"Fires when a payment is reconciled for the first time.": "Se déclenche lorsqu'un paiement est rapproché pour la première fois.",
"Fires when a quote is created or updated.": "Tire quand un devis est créé ou mis à jour.",
"Fires when a new bill (Accounts Payable) is added.": "Déclenche lorsqu'une nouvelle facture (Comptes Payables) est ajoutée.",
"Fires when a new credit note is created.": "Tire quand un nouvel avoir est créé.",
"Fires when a new project is created.": "Se déclenche lorsqu'un nouveau projet est créé.",
"Fires when a new quote is created.": "Tire quand un nouveau guillemet est créé.",
"Markdown": "Markdown",
"Webhook Key": "Clé Webhook",
"Fetch Full Contact": "Récupérer le contact complet",
"Fetch Full Invoice": "Récupérer la facture complète",
"Types": "Types de fichiers",
"Bank Account Code": "Code du compte bancaire",
"Payment Types": "Types de paiement",
"Filter by Status (optional)": "Filtrer par statut (optionnel)",
"First-time Status (optional)": "Statut de la première fois (facultatif)",
"Quote Number (partial match)": "Numéro du devis (correspondance partielle)",
"Expiry Date From (YYYY-MM-DD)": "Date d'expiration du (AAAA-MM-JJ)",
"Expiry Date To (YYYY-MM-DD)": "Date d'expiration (AAAA-MM-JJ)",
"Statuses (optional)": "Statuts (facultatif)",
"Summary Only (lighter, faster)": "Résumé seulement (plus léger, plus rapide)",
"States (optional)": "États (facultatif)",
"Page Size (1-500)": "Page Size (1-500)",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.": "Depuis le portail Xero Developer > Votre application > Webhooks. Utilisé pour vérifier la signature x-xéro.",
"If enabled, fetches the full contact from Xero using the Resource URL.": "Si activé, récupère le contact complet de Xero en utilisant l'URL de la ressource.",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"Fetch the full invoice and ensure Type is ACCREC (recommended).": "Récupérez la facture complète et assurez-vous que Type est ACCREC (recommandé).",
"Also fire when a purchase order enters this status for the first time (since enabling).": "Également tirer quand un bon de commande entre dans ce statut pour la première fois (depuis l'activation).",
"RECEIVE": "RECEVOIR",
"SPEND": "EFFACER",
"RECEIVE-OVERPAYMENT": "RÉCUPÉRATION DE RÉCUPÉRATION",
"SPEND-OVERPAYMENT": "PAIEMENT SPÉCIAL",
"RECEIVE-PREPAYMENT": "PRÉPAIEMENT DE RECEVATION",
"SPEND-PREPAYMENT": "PRÉPAIEMENT SPÉCIAL",
"RECEIVE-TRANSFER": "TRANSFERT DE RECEVATION",
"SPEND-TRANSFER": "TRANSFERT SPÉCIAL",
"AUTHORISED": "AUTORISÉ",
"DELETED": "SUPPRIMER",
"ACCRECPAYMENT (Received on Sales Invoice)": "ACCREGISATION (Reçu sur la facture de vente)",
"ACCPAYPAYMENT (Paid on Bill)": "ACCPAIEMENT (payé sur la facture)",
"DRAFT": "DRAFT",
"SUBMITTED": "ENVOYÉ",
"BILLED": "FACTURÉ",
"SENT": "Envoyé",
"ACCEPTED": "ACCEPTÉ",
"DECLINED": "DÉCLINÉ",
"INVOICED": "ENVOYÉ",
"PAID": "PAYÉ",
"VOIDED": "VOISÉ",
"ACCRECCREDIT (Sales Credit)": "ACCRECCREDIT (Crédit des ventes)",
"ACCPAYCREDIT (Supplier Credit)": "ACCPAYCREDIT (Crédit Fournisseur)",
"INPROGRESS": "INSTRESSE",
"CLOSED": "FERMÉ"
}

View File

@@ -0,0 +1,320 @@
{
"Beautiful accounting software": "美しい会計ソフトウェア",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ",
"Create or Update Contact": "連絡先を作成または更新",
"Create or Update Invoice": "請求書を作成または更新",
"Allocate Credit Note to Invoice": "クレジットノートを請求書に割り当てる",
"Create Bank Transfer": "銀行振込を作成",
"Create New Quote Draft": "新しい見積書下書きを作成",
"Send Sales Invoice by Email": "販売請求書を電子メールで送信",
"Create Bill": "請求書を作成",
"Create Payment": "支払いを作成",
"Create Purchase Order": "注文書の作成",
"Update Purchase Order": "注文書を更新",
"Upload Attachment": "添付ファイルをアップロード",
"Add Items to Existing Sales Invoice": "既存の販売請求書に商品を追加",
"Create Credit Note": "クレジットノートを作成",
"Create Inventory Item": "インベントリアイテムを作成",
"Create Project": "プロジェクトを作成",
"Update Sales Invoice": "販売請求書を更新",
"Create Repeating Sales Invoice": "繰り返し請求書を作成",
"Find Contact": "連絡先を探す",
"Find Invoice": "請求書を検索",
"Find Item": "アイテムを検索",
"Find Purchase Order": "注文書を検索",
"Custom API Call": "カスタムAPI通話",
"Create Xero Contact": "Xeroの連絡先を作成",
"Create Xero Invoice": "Xero請求書を作成",
"Allocates a credit note to a specific invoice.": "特定の請求書にクレジットノートを割り当てます。",
"Transfers money between two bank accounts in Xero.": "Xeroの2つの銀行口座間でお金を送金します。",
"Creates a new draft quote.": "新しい下書き見積もりを作成します。",
"Sends a sales invoice via email to a contact.": "営業請求書をメールで連絡先に送信します。",
"Creates a new bill (Accounts Payable).": "新しい請求書 (支払い可能な勘定科目) を作成します。",
"Applies a payment to an invoice.": "請求書に支払いを適用します。",
"Creates a new purchase order for a contact.": "連絡先の新しい発注書を作成します。",
"Updates details of an existing purchase order.": "既存の注文書の詳細を更新します。",
"Uploads an attachment to a specific Xero resource.": "特定の Xero リソースへの添付ファイルをアップロードします。",
"Adds line items to an existing sales invoice (ACCREC).": "既存の販売請求書 (ACCREC) に行項目を追加します。",
"Creates a new credit note for a contact.": "連絡先に新しいクレジットノートを作成します。",
"Creates a new inventory item in Xero.": "Xeroで新しいインベントリアイテムを作成します。",
"Creates a new project for a contact.": "連絡先の新しいプロジェクトを作成します。",
"Updates details of an existing sales invoice (ACCREC).": "既存の販売請求書(ACCREC)の詳細を更新します。",
"Creates a repeating sales invoice (Accounts Receivable).": "営業請求書(Accounts Receivable)を繰り返し作成します。",
"Finds a contact by name or account number (or SearchTerm).": "名前または口座番号(またはSearchTerm)で連絡先を検索します。",
"Finds an invoice by number or reference.": "数字または参照で請求書を検索します。",
"Finds an item by name or code.": "名前またはコードで項目を検索します。",
"Finds a purchase order by given parameters.": "指定されたパラメータで発注を検索します。",
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
"Organization": "組織",
"Contact ID": "連絡先ID",
"Contact Name": "連絡先名",
"Contact Email": "連絡先メールアドレス",
"Invoice": "請求書",
"Contact": "お問い合わせ",
"Line Item": "行項目",
"Date Prepared": "準備された日付",
"Due Date": "締切日",
"Invoice Reference": "請求書の参照",
"Status": "ステータス",
"Credit Note": "クレジットノート",
"Amount": "金額",
"Allocation Date": "割当日",
"Bank Account": "銀行",
"Transfer Date": "転送日",
"Reference": "参照",
"From Is Reconciled": "From Is Reconciled",
"To Is Reconciled": "To は調整されました",
"Date": "日付",
"Expiry Date": "Expiry Date",
"Line Amount Types": "行数の種類",
"Quote Number": "見積書番号",
"Title": "タイトル",
"Summary": "Summary",
"Terms": "利用規約",
"Sales Invoice (Sendable)": "請求書(送信可能)",
"Bill Number (Reference)": "請求書番号 (参考)",
"Invoice (Authorised)": "請求書(承認済み)",
"Payment Date": "支払日",
"Is Reconciled": "調整済み",
"Delivery Date": "納品日",
"Purchase Order Number": "発注番号",
"Branding Theme": "ブランディングのテーマ",
"Delivery Address": "配送先住所",
"Attention To": "注目先",
"Telephone": "電話",
"Delivery Instructions": "配送方法",
"Expected Arrival Date": "到着予定日",
"Purchase Order": "Purchase Order",
"Mark as Sent to Contact": "連絡先に送信済みとしてマーク",
"Expected Arrival Date (YYYY-MM-DD)": "到着予定日 (YYYY-MM-DD)",
"Resource Type": "リソースタイプ",
"Resource": "リソース",
"File": "ファイル",
"File Name (override)": "ファイル名 (上書き)",
"Content Type": "コンテンツタイプ",
"Include with Online Invoice": "オンライン請求書を含める",
"Allow AUTHORISED invoices": "承認済みの請求書を許可",
"New Line Items": "新しい行項目",
"Type": "タイプ",
"Credit Note Number": "クレジットノート番号",
"Reference (ACCRECCREDIT only)": "参照ACCRECCREDITのみ",
"Currency Code": "通貨コード",
"Line Items": "行の項目",
"Item Code": "アイテムコード",
"Name": "Name",
"Sales Description": "販売の説明",
"Purchase Description": "購入の説明",
"Is Sold": "売却済み",
"Is Purchased": "購入済み",
"Sales Details": "販売詳細",
"Account": "アカウント",
"Purchase Details": "購入詳細",
"Project Name": "プロジェクト名",
"Deadline (UTC ISO-8601)": "締切日 (UTC ISO-8601)",
"Estimate Amount": "推定金額",
"Sales Invoice (Editable)": "販売請求書(編集可能)",
"Due Date (YYYY-MM-DD)": "締切日 (YYYY-MM-DD)",
"Invoice Number": "請求書番号",
"Source URL": "ソースURL",
"Replace All Line Items": "すべての行アイテムを置き換え",
"Line Items (updates/additions)": "行アイテム(更新/追加)",
"Schedule Period": "予定期間",
"Schedule Unit": "単位をスケジュールする",
"Due Date (number)": "締切日 (数値)",
"Due Date Type": "締切日の種類",
"Start Date (YYYY-MM-DD)": "開始日 (YYYY-MM-DD)",
"End Date (YYYY-MM-DD)": "終了日 (YYYY-MM-DD)",
"Currency": "通貨",
"Approved For Sending": "送信を承認しました",
"Send Copy": "コピーを送信",
"Mark As Sent": "送信済みにする",
"Include PDF": "PDFを含める",
"Search By": "検索",
"Value": "値",
"Include Archived": "アーカイブを含める",
"Summary Only (faster, lighter)": "サマリーのみ (より速く、軽く)",
"Page": "ページ",
"Type Filter": "フィルタタイプ",
"Order (optional)": "注文 (オプション)",
"Statuses": "Statuses",
"Date From (YYYY-MM-DD)": "日付 (YYYY-MM-DD)",
"Date To (YYYY-MM-DD)": "終了日時 (YYYY-MM-DD)",
"Order (e.g., Date DESC)": "注文(例、日付の降順)",
"Page Size (1-1000)": "ページサイズ (1-1000)",
"Method": "方法",
"Headers": "ヘッダー",
"Query Parameters": "クエリパラメータ",
"Body": "本文",
"Response is Binary ?": "応答はバイナリですか?",
"No Error on Failure": "失敗時にエラーはありません",
"Timeout (in seconds)": "タイムアウト(秒)",
"ID of the contact to create invoice for.": "請求書を作成する連絡先のID。",
"Contact name, in full.": "連絡先名は全て入力されています。",
"Email address of the contact.": "連絡先のメールアドレス。",
"Select an invoice": "請求書を選択",
"Select a contact": "連絡先を選択",
"Invoice line items": "請求書明細の項目",
"Date the invoice was created. Format example: 2019-03-11": "請求書が作成された日付。フォーマット例: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "期日は請求書です。フォーマット例: 2019-03-11",
"Reference number of the Invoice": "請求書の参照番号",
"Invoice Status": "請求ステータス",
"Select a credit note to allocate from": "から割り当てるクレジットノートを選択してください",
"The amount of the credit to allocate.": "割り当てるクレジットの量",
"Date of allocation. Format: YYYY-MM-DD. Optional.": "割り当て日付。形式: YYYY-MM-DD オプション。",
"Select a bank account": "銀行口座を選択",
"Amount to transfer. Currencies must match between accounts.": "送金額。口座間で通貨と一致する必要があります。",
"YYYY-MM-DD. Defaults to today if not provided.": "YYYY-MM-DD. デフォルトは、指定されていない場合、今日になります。",
"Reference for the transfer.": "転送の参照。",
"Mark source account transaction as reconciled.": "ソース口座取引を調整済みとしてマークします。",
"Mark destination account transaction as reconciled.": "宛先口座取引を調整済みとしてマークします。",
"Date the quote was issued (YYYY-MM-DD).": "引用符が発行された日 (YYYY-MM-DD)",
"Date the quote expires (YYYY-MM-DD).": "見積もりの有効期限(YYYY-MM-DD)が切れます。",
"At minimum, provide a Description.": "最低でも説明を入力してください。",
"Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).": "メール送信の有効なステータスを持つ販売請求書を選択します (SUBMITTED、AUTHORISED、または PAID)。",
"Date the bill was issued (YYYY-MM-DD). Optional.": "請求書が発行された日付 (YYYY-MM-DD). オプション.",
"Date the bill is due (YYYY-MM-DD). Optional.": "請求書の締切日時YYYY-MM-DD。任意。",
"Select an authorised invoice (sales or bill) to apply payment to.": "支払いを適用する承認済みの請求書(売上または請求書)を選択します。",
"Payment amount (must be <= amount due).": "支払い金額(未満の金額でなければなりません)",
"YYYY-MM-DD.": "YYYY-MM-DD。",
"Mark payment as reconciled (optional).": "支払いを調整済みにする (オプション)。",
"Date the purchase order was issued (YYYY-MM-DD). Optional.": "発注日(YYYY-MM-DD) オプション。",
"Date goods are to be delivered (YYYY-MM-DD). Optional.": "日付グッズが配信されます (YYYY-MM-DD). オプション.",
"Select a branding theme": "ブランドテーマを選択",
"YYYY-MM-DD. Optional.": "YYYY-MM-DD オプション。",
"Select a purchase order to update": "更新する注文書を選択してください",
"The Xero resource to attach the file to.": "ファイルを添付する Xero リソース。",
"Select the specific resource to attach the file to.": "ファイルを添付する特定のリソースを選択します。",
"The file to upload. Max 10MB per Xero limits.": "アップロードするファイル。Xero上限あたり最大10MB。",
"Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *": "Xeroで使用する任意のファイル名です。文字は避けてください: < > : \" / \\ | ? *",
"MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.": "ファイルの MIME タイプ (例: image/png) が設定されていない場合は、application/octet-stream に推定されます。",
"Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.": "ACCRECの請求書とACCRECクレジットートにのみ適用されます。IncludeOnline=trueクエリパラメータを追加します。",
"Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "自動請求書に項目を追加することを有効にします(Xeroは有料/一部支払いACCRECの更新が制限されます)。",
"Add one or more line items. At minimum, each line needs a Description.": "1 つまたは複数の行項目を追加します。最小では、各行には説明が必要です。",
"Select an account": "アカウントを選択",
"Example: 2017-04-23T18:25:43.511Z": "例: 2017-04-23T18:25:43.511Z",
"Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "自動請求書の更新を有効にする (Xeroは有料/一部支払いACCRECの更新が制限されます)。",
"Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.": "format@@0 または format@@1 ステータスを持つ販売請求書 (ACCREC) を選択します。",
"If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.": "有効にすると、指定された line_items だけが残ります。無効にすると、一致する LineItemID を更新し、新しいアイテムを追加して、現在の行とマージします。",
"Integer period (e.g., 1 every week, 2 every month).": "整数の期間 (例: 1 週間、2 ヶ月)",
"Day number used with due date type (e.g., 20, 31).": "期日型で使用される日番号20、31",
"Select a currency code": "通貨コードを選択",
"Name, Account Number, or Search Term depending on Search By.": "名前、アカウント番号、または検索による検索語に応じて検索します。",
"Recommended for broad searches (Search Term). Excludes heavy fields.": "幅広い検索(検索条件)におすすめです。重い項目を除外します。",
"Pagination page (optional).": "ページネーションページ (オプション)。",
"Invoice Number, Reference, or Search Term.": "請求書番号、参照または検索条件。",
"Item Code or Name (exact match).": "アイテムコードまたは名前(完全一致)。",
"e.g. Name or Name DESC": "例: Name or Name DESC",
"Number, Reference or ID depending on Search By.": "検索によって番号、参照またはID。",
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
"Draft": "下書き",
"Submitted": "送信済み",
"Authorised": "承認済み",
"Deleted": "削除しました",
"Voided": "無効にしました",
"Exclusive": "専用",
"Inclusive": "Inclusive",
"NoTax": "NoTax",
"Billed": "お支払い",
"Quote": "引用",
"Bank Transfer": "銀行送金",
"Bank Transaction": "銀行取引",
"Manual Journal": "Manual Journal",
"Receipt": "領収書(受領)",
"Repeating Invoice": "繰り返し請求書",
"Accounts Receivable Credit (ACCRECCREDIT)": "Accounts Receivable Credit (ACCRECCREDIT)",
"Accounts Payable Credit (ACCPAYCREDIT)": "Accounts Payable Credit (ACCPAYCREDIT)",
"Weekly": "Weekly",
"Monthly": "月ごと",
"Name (exact match)": "名前 (完全一致)",
"Account Number (exact match)": "口座番号(完全一致)",
"Search Term (broad search)": "検索語(大まかな検索)",
"Invoice Number (exact)": "請求書番号 (正確)",
"Reference (exact)": "参照 (正確)",
"Search Term (InvoiceNumber/Reference)": "検索語(InvoiceNumber/Reference)",
"Sales Invoice (ACCREC)": "請求書ACCREC",
"Bill (ACCPAY)": "ビルACCPAY",
"Code (exact)": "コード (正確)",
"Name (exact)": "名前 (正確)",
"Purchase Order Number (exact)": "発注番号(正確)",
"Purchase Order ID (GUID)": "注文書ID (GUID)",
"GET": "取得",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "削除",
"HEAD": "頭",
"New Contact": "新しい連絡先",
"New or Updated Contact": "新規または更新された連絡先",
"New Sales Invoice": "新しい販売請求書",
"Updated Sales Invoice": "販売請求書を更新しました",
"New Bank Transaction": "新しい銀行取引",
"New Payment": "新しい支払い",
"New Purchase Order": "新規発注書",
"New Reconciled Payment": "新しい支払い照合済みの支払い",
"Updated Quote": "更新された見積書",
"New Bill": "新しい請求書",
"New Credit Note": "新しいクレジットノート",
"New Project": "新規プロジェクト",
"New Quote": "新しい引用",
"Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.": "Xeroに新しい連絡先が追加されたときに発生しますXero webhooks経由。このURLを指すようにXero DeveloperポータルでWebhookを設定します。",
"Fires when a contact is created or updated (via Xero webhooks).": "コンタクトが作成または更新されたときに発生します(Xero Webhookを介して)。",
"Fires when a new sales invoice (Accounts Receivable) is created.": "新しい販売請求書(Accounts Receivable)が作成されたときに発行されます。",
"Fires when an existing sales invoice (Accounts Receivable) is updated.": "既存の販売請求書(Accounts Receivable)が更新されたときに発行されます。",
"Fires when a new bank transaction is created.": "新しい銀行取引が作成されたときに発生します。",
"Fires when a payment is received.": "支払いを受け取ったときに発生します。",
"Fires when a new purchase order is created or enters a specific status for the first time.": "新しい発注書が作成されるか、初めて特定のステータスに入ったときに発行されます。",
"Fires when a payment is reconciled for the first time.": "支払いが初めて調整されたときに発生します。",
"Fires when a quote is created or updated.": "見積もりが作成または更新されたときに発生します。",
"Fires when a new bill (Accounts Payable) is added.": "新しい請求書 (支払い勘定科目) が追加されたときに発生します。",
"Fires when a new credit note is created.": "新しいクレジットノートが作成されると発行されます。",
"Fires when a new project is created.": "新しいプロジェクトが作成されたときに発生します。",
"Fires when a new quote is created.": "新しい見積もりが作成されたときに発生します。",
"Markdown": "Markdown",
"Webhook Key": "Webhookキー",
"Fetch Full Contact": "完全な連絡先を取得",
"Fetch Full Invoice": "完全な請求書を取得",
"Types": "タイプ",
"Bank Account Code": "銀行口座コード",
"Payment Types": "支払いタイプ",
"Filter by Status (optional)": "ステータスでフィルター (オプション)",
"First-time Status (optional)": "最初のステータス(オプション)",
"Quote Number (partial match)": "見積もり番号(部分一致)",
"Expiry Date From (YYYY-MM-DD)": "有効期限 (YYYY-MM-DD)",
"Expiry Date To (YYYY-MM-DD)": "有効期限 (YYYY-MM-DD)",
"Statuses (optional)": "ステータス (オプション)",
"Summary Only (lighter, faster)": "サマリー のみ (軽量、高速)",
"States (optional)": "都道府県(オプション)",
"Page Size (1-500)": "Page Size (1-500)",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.": "Xero Developer portal > Your App > Webhooksから。x-xero-signatureの検証に使用します。",
"If enabled, fetches the full contact from Xero using the Resource URL.": "有効にすると、リソース URL を使用して Xero から完全な連絡先を取得します。",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"Fetch the full invoice and ensure Type is ACCREC (recommended).": "請求書の全額を取得し、タイプがACCREC(推奨)であることを確認します。",
"Also fire when a purchase order enters this status for the first time (since enabling).": "また、(有効になってから)初めて注文がこのステータスに入ったときに発生します。",
"RECEIVE": "受信",
"SPEND": "消費",
"RECEIVE-OVERPAYMENT": "お支払いを再受領する",
"SPEND-OVERPAYMENT": "送金額",
"RECEIVE-PREPAYMENT": "受け取る前払い",
"SPEND-PREPAYMENT": "前払いの設定",
"RECEIVE-TRANSFER": "転送を受け取る",
"SPEND-TRANSFER": "SPEND-TRANSFER",
"AUTHORISED": "承認済み",
"DELETED": "削除",
"ACCRECPAYMENT (Received on Sales Invoice)": "ACCRECPAYMENT販売請求書で受信",
"ACCPAYPAYMENT (Paid on Bill)": "ACCPAYPAYMENT(請求書の支払い)",
"DRAFT": "Draft",
"SUBMITTED": "送信",
"BILLED": "お支払い",
"SENT": "送信済み",
"ACCEPTED": "承認済み",
"DECLINED": "拒否されました",
"INVOICED": "請求済み",
"PAID": "PAID",
"VOIDED": "取り消しました",
"ACCRECCREDIT (Sales Credit)": "ACCRECCREDIT (セール・クレジット)",
"ACCPAYCREDIT (Supplier Credit)": "ACCPAYCREDIT (Supplier Credit)",
"INPROGRESS": "進行状況",
"CLOSED": "閉じる"
}

View File

@@ -0,0 +1,320 @@
{
"Beautiful accounting software": "Prachtige boekhouderssoftware",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Log in op Xero.\n 2. Ga naar [Developer portal](https://developer.xero.com/app/manage/).\n 3. Klik op de App die je wilt integreren.\n 4. Klik links op `Configuration`.\n 5. Voer je `redirect url` in.\n 6. Kopieer de `Client Id` en `Client Secret`.\n ",
"Create or Update Contact": "Maken of bijwerken van contactpersoon",
"Create or Update Invoice": "Factuur maken of bijwerken",
"Allocate Credit Note to Invoice": "Creditnota aan factuur toewijzen",
"Create Bank Transfer": "Maak bankoverschrijving",
"Create New Quote Draft": "Nieuwe offerte concept maken",
"Send Sales Invoice by Email": "Verkoopfactuur per e-mail verzenden",
"Create Bill": "Rekening aanmaken",
"Create Payment": "Betaling aanmaken",
"Create Purchase Order": "Inkooporder aanmaken",
"Update Purchase Order": "Inkooporder bijwerken",
"Upload Attachment": "Bijlage uploaden",
"Add Items to Existing Sales Invoice": "Voeg artikelen toe aan de bestaande verkoopfactuur",
"Create Credit Note": "Creditnota aanmaken",
"Create Inventory Item": "Voorraad item maken",
"Create Project": "Project aanmaken",
"Update Sales Invoice": "Verkoopfactuur bijwerken",
"Create Repeating Sales Invoice": "Herhalende verkoopfactuur aanmaken",
"Find Contact": "Contactpersoon zoeken",
"Find Invoice": "Factuur zoeken",
"Find Item": "Voorwerp zoeken",
"Find Purchase Order": "Vind inkooporder",
"Custom API Call": "Custom API Call",
"Create Xero Contact": "Xero contact aanmaken",
"Create Xero Invoice": "Xero factuur aanmaken",
"Allocates a credit note to a specific invoice.": "Een creditnota toewijzen aan een specifieke factuur.",
"Transfers money between two bank accounts in Xero.": "Overboekt geld tussen twee bankrekeningen in Xero.",
"Creates a new draft quote.": "Maakt een nieuw conceptcitaat aan.",
"Sends a sales invoice via email to a contact.": "Verstuurt een verkoopfactuur per e-mail naar een contactpersoon.",
"Creates a new bill (Accounts Payable).": "Maakt een nieuwe rekening aan (Accounts te betalen).",
"Applies a payment to an invoice.": "Past een betaling toe op een factuur.",
"Creates a new purchase order for a contact.": "Maakt een nieuwe inkooporder voor een contactpersoon aan.",
"Updates details of an existing purchase order.": "Updates details van een bestaande inkooporder",
"Uploads an attachment to a specific Xero resource.": "Upload een bijlage naar een specifieke Xero-bron.",
"Adds line items to an existing sales invoice (ACCREC).": "Voegt regelitems toe aan een bestaande verkoopfactuur (ACCREC).",
"Creates a new credit note for a contact.": "Maakt een nieuwe creditnota voor een contactpersoon aan.",
"Creates a new inventory item in Xero.": "Maakt een nieuw inventaris item in Xero.",
"Creates a new project for a contact.": "Maakt een nieuw project voor een contactpersoon.",
"Updates details of an existing sales invoice (ACCREC).": "Updates details van een bestaande verkoopfactuur (ACCREC).",
"Creates a repeating sales invoice (Accounts Receivable).": "Maakt een herhalende verkoopfactuur aan (Accounts Ontvangbaar).",
"Finds a contact by name or account number (or SearchTerm).": "Vindt een contactpersoon op naam of account nummer (of Zoekterm).",
"Finds an invoice by number or reference.": "Een factuur op nummer of referentie gevonden.",
"Finds an item by name or code.": "Vindt een item op naam of code.",
"Finds a purchase order by given parameters.": "Vindt een inkooporder op basis van deze parameters.",
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
"Organization": "Rekening",
"Contact ID": "Contact ID",
"Contact Name": "Naam contactpersoon",
"Contact Email": "Contact e-mail adres",
"Invoice": "Factuur",
"Contact": "Contactpersoon",
"Line Item": "Regel item",
"Date Prepared": "Datum Voorbereid",
"Due Date": "Inleverdatum",
"Invoice Reference": "Factuur referentie",
"Status": "status",
"Credit Note": "Creditnota",
"Amount": "Hoeveelheid",
"Allocation Date": "Toewijzing datum",
"Bank Account": "Bank rekening",
"Transfer Date": "Overdracht datum",
"Reference": "Referentie",
"From Is Reconciled": "Van Is Gecontroleerd",
"To Is Reconciled": "Naar is verzoend",
"Date": "Datum:",
"Expiry Date": "Expiry Date",
"Line Amount Types": "Regelbedrag types",
"Quote Number": "Offerte Nr",
"Title": "Aanspreektitel",
"Summary": "Summary",
"Terms": "Voorwaarden",
"Sales Invoice (Sendable)": "Verkoopfactuur (endable)",
"Bill Number (Reference)": "Factuurnummer (referentie)",
"Invoice (Authorised)": "Factuur (Geautoriseerd)",
"Payment Date": "Datum betaling",
"Is Reconciled": "Is verzoend",
"Delivery Date": "Datum levering",
"Purchase Order Number": "Inkooporder nummer",
"Branding Theme": "Branding Thema",
"Delivery Address": "Afleveradres adres",
"Attention To": "Aandacht voor",
"Telephone": "Telefoon",
"Delivery Instructions": "Levering instructies",
"Expected Arrival Date": "Verwachte aankomstdatum",
"Purchase Order": "Inkooporder",
"Mark as Sent to Contact": "Markeer als verzonden aan contactpersoon",
"Expected Arrival Date (YYYY-MM-DD)": "Verwachte aankomstdatum (YYYY-MM-DD)",
"Resource Type": "Type bron",
"Resource": "Bron",
"File": "Bestand",
"File Name (override)": "Bestandsnaam (overschrijven)",
"Content Type": "Type inhoud",
"Include with Online Invoice": "Inclusief online factuur",
"Allow AUTHORISED invoices": "AUTHORISED facturen toestaan",
"New Line Items": "Nieuwe regelitems",
"Type": "Type",
"Credit Note Number": "Credit Note Nummer",
"Reference (ACCRECCREDIT only)": "Referentie (ACCRECCREDIT alleen)",
"Currency Code": "Valuta code",
"Line Items": "Posities regel",
"Item Code": "Artikel code",
"Name": "Naam",
"Sales Description": "Omschrijving verkoop",
"Purchase Description": "Aankoop beschrijving",
"Is Sold": "Is verkocht",
"Is Purchased": "Is gekocht",
"Sales Details": "Verkoop Details",
"Account": "Rekening",
"Purchase Details": "Inkoopinformatie details",
"Project Name": "Projectnaam",
"Deadline (UTC ISO-8601)": "Deadline (UTC ISO-8601)",
"Estimate Amount": "Bereken bedrag",
"Sales Invoice (Editable)": "Verkoopfactuur (Editable)",
"Due Date (YYYY-MM-DD)": "Vervaldatum (JJJJ-MM-DD)",
"Invoice Number": "Factuur Nummer",
"Source URL": "Bron URL",
"Replace All Line Items": "Alle regelitems vervangen",
"Line Items (updates/additions)": "Regelitems (updates/aanvullingen)",
"Schedule Period": "Planning periode",
"Schedule Unit": "Eenheid inplannen",
"Due Date (number)": "Uiterste inleverdatum (nummer)",
"Due Date Type": "Uiterste datum type",
"Start Date (YYYY-MM-DD)": "Startdatum (JJJJ-MM-DD)",
"End Date (YYYY-MM-DD)": "Einddatum (JJJJ-MM-DD)",
"Currency": "valuta",
"Approved For Sending": "Goedgekeurd voor verzenden",
"Send Copy": "Kopie verzenden",
"Mark As Sent": "Markeer als verzonden",
"Include PDF": "PDF opnemen",
"Search By": "Zoeken op",
"Value": "Waarde",
"Include Archived": "Gearchiveerd opnemen",
"Summary Only (faster, lighter)": "Alleen samenvatting (sneller, aansteker)",
"Page": "Pagina",
"Type Filter": "Type filter",
"Order (optional)": "Bestelling (optioneel)",
"Statuses": "Statuses",
"Date From (YYYY-MM-DD)": "Datum vanaf (JJJJ-MM-DD)",
"Date To (YYYY-MM-DD)": "Datum tot (JJJJ-MM-DD)",
"Order (e.g., Date DESC)": "Bestelling (bijv. Datum DESC)",
"Page Size (1-1000)": "Paginagrootte (1-1000)",
"Method": "Methode",
"Headers": "Kopteksten",
"Query Parameters": "Query parameters",
"Body": "Lichaam",
"Response is Binary ?": "Antwoord is binair?",
"No Error on Failure": "Geen fout bij fout",
"Timeout (in seconds)": "Time-out (in seconden)",
"ID of the contact to create invoice for.": "ID van de contactpersoon voor het maken van een factuur.",
"Contact name, in full.": "Contact naam is volledig.",
"Email address of the contact.": "E-mailadres van de contactpersoon",
"Select an invoice": "Selecteer een factuur",
"Select a contact": "Selecteer een contactpersoon",
"Invoice line items": "Factuur regelitems",
"Date the invoice was created. Format example: 2019-03-11": "Datum waarop de factuur is aangemaakt. Formaat voorbeeld: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "Vervaldatum van de factuur. Formaat voorbeeld: 2019-03-11",
"Reference number of the Invoice": "Referentienummer van de factuur",
"Invoice Status": "Factuur Status",
"Select a credit note to allocate from": "Selecteer een creditnota van toewijzing",
"The amount of the credit to allocate.": "Het toe te wijzen bedrag van het krediet.",
"Date of allocation. Format: YYYY-MM-DD. Optional.": "Datum van allocatie. Formaat: JJJJ-MM-DD. Optioneel.",
"Select a bank account": "Selecteer een bankrekening",
"Amount to transfer. Currencies must match between accounts.": "Bedrag om over te dragen. Valuta moeten overeenkomen tussen de rekeningen.",
"YYYY-MM-DD. Defaults to today if not provided.": "JJJJ-MM-DD. Wordt vandaag standaard ingesteld als deze niet wordt verstrekt.",
"Reference for the transfer.": "Referentie voor de overdracht.",
"Mark source account transaction as reconciled.": "Markeer transactie als verzoend.",
"Mark destination account transaction as reconciled.": "Bedoelrekening markeren als verzoend.",
"Date the quote was issued (YYYY-MM-DD).": "Datum waarop de offerte werd uitgegeven (YYYY-MM-DDDD).",
"Date the quote expires (YYYY-MM-DD).": "Datum waarop de offerte vervalt (JJJ-MM-DDDD).",
"At minimum, provide a Description.": "Geef ten minste een beschrijving op.",
"Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).": "Selecteer een verkoopfactuur met een geldige status voor het verzenden van e-mail (SUBMITTED, AUTHORISED of PAID).",
"Date the bill was issued (YYYY-MM-DD). Optional.": "Datum waarop het contract werd uitgegeven (YYYY-MM-DDD). Optioneel.",
"Date the bill is due (YYYY-MM-DD). Optional.": "Datum waarop de rekening afloopt (YYYY-MM-DDD). Optioneel.",
"Select an authorised invoice (sales or bill) to apply payment to.": "Selecteer een geautoriseerde factuur (verkoop- of factuur) waarop de betaling van toepassing is.",
"Payment amount (must be <= amount due).": "Betalingsbedrag (moet < = bedrag zijn).",
"YYYY-MM-DD.": "JJJJ-MM-DD.",
"Mark payment as reconciled (optional).": "Markeer betaling als afgestemd (optioneel).",
"Date the purchase order was issued (YYYY-MM-DD). Optional.": "Datum waarop de order werd uitgegeven (YYYY-MM-DDD). Optioneel.",
"Date goods are to be delivered (YYYY-MM-DD). Optional.": "Datum goederen moeten worden geleverd (JJJJ-MM-DDD). Optioneel.",
"Select a branding theme": "Selecteer een branding thema",
"YYYY-MM-DD. Optional.": "JJJJ-MM-DD. Optioneel.",
"Select a purchase order to update": "Selecteer een inkooporder om bij te werken",
"The Xero resource to attach the file to.": "De Xero bron waar het bestand aan toegevoegd wordt.",
"Select the specific resource to attach the file to.": "Selecteer de specifieke bron aan het bestand toe te voegen.",
"The file to upload. Max 10MB per Xero limits.": "Het te uploaden bestand. Maximaal 10MB per Xero limiet.",
"Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *": "Te gebruiken optionele bestandsnaam in Xero. Vermijd tekens: < > : \" / \\ wom? *",
"MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.": "MIME type van het bestand (bijv. afbeelding/png). Indien niet ingesteld, wordt dit doorgebracht of standaard ingesteld op applicatie/octet-stream.",
"Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.": "Alleen van toepassing op ACCREC facturen en ACCREC creditnota's. Voegt IncludeOnline=true query parameter toe.",
"Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Inschakelen om items toe te voegen aan AUTHORISED-facturen (Xero staat beperkte updates voor betaalde / gedeeltelijk betaalde ACCREC) toe.",
"Add one or more line items. At minimum, each line needs a Description.": "Voeg een of meer regelitems toe. Op z'n minst heeft elke regel een omschrijving nodig.",
"Select an account": "Selecteer een account",
"Example: 2017-04-23T18:25:43.511Z": "Voorbeeld: 2017-04-23T18:25:43.511Z",
"Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Inschakelen van updates voor AUTHORISED-facturen (Xero staat beperkte updates toe voor betaalde / gedeeltelijk betaalde ACCREC).",
"Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.": "Selecteer een verkoopfactuur (ACCREC) met DRAFT of SUBMITTED status.",
"If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.": "Indien ingeschakeld, blijven alleen de verstrekte lijn_items over. Indien uitgeschakeld, voegen we samen met de huidige regels door het bijwerken van overeenkomende LineItemID en nieuwe items toe te voegen.",
"Integer period (e.g., 1 every week, 2 every month).": "Gehele periode (bijv. 1 per week, 2 per maand).",
"Day number used with due date type (e.g., 20, 31).": "Dag nummer gebruikt met inleverdatum type (bijv. 20, 31).",
"Select a currency code": "Selecteer een valutacode",
"Name, Account Number, or Search Term depending on Search By.": "Naam, klantnummer, of zoekterm afhankelijk van zoekopdracht.",
"Recommended for broad searches (Search Term). Excludes heavy fields.": "Aanbevolen voor brede zoekopdrachten (hoofdvoorwaarden). Exclusief zware velden.",
"Pagination page (optional).": "Paginering pagina (optioneel).",
"Invoice Number, Reference, or Search Term.": "Factuurnummer, referentie of zoekterm",
"Item Code or Name (exact match).": "Artikelcode of naam (exacte overeenkomst)",
"e.g. Name or Name DESC": "bijv. Naam of DESC-naam",
"Number, Reference or ID depending on Search By.": "Nummer, referentie of ID afhankelijk van zoekopdracht.",
"Authorization headers are injected automatically from your connection.": "Autorisatie headers worden automatisch geïnjecteerd vanuit uw verbinding.",
"Enable for files like PDFs, images, etc..": "Inschakelen voor bestanden zoals PDF's, afbeeldingen etc..",
"Draft": "Concept",
"Submitted": "Verzonden",
"Authorised": "Toegestaan",
"Deleted": "Verwijderd",
"Voided": "Vervallen",
"Exclusive": "Exclusief",
"Inclusive": "Inclusief",
"NoTax": "NoTax",
"Billed": "Gefactureerd",
"Quote": "Offerte",
"Bank Transfer": "Bank overschrijving",
"Bank Transaction": "Bank transactie",
"Manual Journal": "Handmatig dagboek",
"Receipt": "Bon",
"Repeating Invoice": "Herhalende factuur",
"Accounts Receivable Credit (ACCRECCREDIT)": "Ontvangbaar Krediet (ACCRECCREDIT)",
"Accounts Payable Credit (ACCPAYCREDIT)": "Betaalbaar krediet (ACCPAYCREDIT)",
"Weekly": "wekelijks",
"Monthly": "maandelijks",
"Name (exact match)": "Naam (exacte overeenkomst)",
"Account Number (exact match)": "Rekeningnummer (exacte overeenkomst)",
"Search Term (broad search)": "Zoekterm (brede zoekopdracht)",
"Invoice Number (exact)": "Factuurnummer (juist)",
"Reference (exact)": "Referentie (exact)",
"Search Term (InvoiceNumber/Reference)": "Zoekterm (factuurnummer/referentie)",
"Sales Invoice (ACCREC)": "Verkoopfactuur (ACCREC)",
"Bill (ACCPAY)": "Factuur (ACCPAY)",
"Code (exact)": "Code (juist)",
"Name (exact)": "Naam (exact)",
"Purchase Order Number (exact)": "Inkooporder nummer (exact)",
"Purchase Order ID (GUID)": "Inkooporder ID (GUID)",
"GET": "KRIJG",
"POST": "POSTE",
"PATCH": "BEKIJK",
"PUT": "PUT",
"DELETE": "VERWIJDEREN",
"HEAD": "HOOFD",
"New Contact": "Nieuw contactpersoon",
"New or Updated Contact": "Nieuw of bijgewerkt contact",
"New Sales Invoice": "Nieuwe verkoopfactuur",
"Updated Sales Invoice": "Bijgewerkte verkoopfactuur",
"New Bank Transaction": "Nieuwe banktransactie",
"New Payment": "Nieuwe betaling",
"New Purchase Order": "Nieuwe inkooporder",
"New Reconciled Payment": "Nieuwe afgestemde betaling",
"Updated Quote": "Bijgewerkte offerte",
"New Bill": "Nieuwe rekening",
"New Credit Note": "Nieuwe creditnota",
"New Project": "Nieuw project",
"New Quote": "Nieuwe offerte",
"Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.": "Vuurt wanneer een nieuwe contactpersoon is toegevoegd aan Xero (via Xero webhooks). Configureer de webhook in de Xero Developer portal om naar deze URL te verwijzen.",
"Fires when a contact is created or updated (via Xero webhooks).": "Vuurt wanneer een contact wordt aangemaakt of bijgewerkt (via Xero webhooks).",
"Fires when a new sales invoice (Accounts Receivable) is created.": "Vuurt wanneer een nieuwe verkoopfactuur (Accounts Ontvangstbaar) is aangemaakt.",
"Fires when an existing sales invoice (Accounts Receivable) is updated.": "Vuurt wanneer een bestaande verkoopfactuur (Accounts Ontvangstbaar) is bijgewerkt.",
"Fires when a new bank transaction is created.": "Vuurt wanneer een nieuwe banktransactie wordt aangemaakt.",
"Fires when a payment is received.": "Vuurt wanneer een betaling is ontvangen.",
"Fires when a new purchase order is created or enters a specific status for the first time.": "Vuurt wanneer een nieuwe bestelling is gemaakt of een specifieke status voor de eerste keer invoert.",
"Fires when a payment is reconciled for the first time.": "Vuurt wanneer een betaling voor het eerst wordt afgesproken.",
"Fires when a quote is created or updated.": "Vuurt wanneer een offerte wordt aangemaakt of bijgewerkt.",
"Fires when a new bill (Accounts Payable) is added.": "Vuurt wanneer een nieuw contract (Accounts Payable) wordt toegevoegd.",
"Fires when a new credit note is created.": "Vuurt wanneer een nieuwe creditnota wordt aangemaakt.",
"Fires when a new project is created.": "Vuurt wanneer een nieuw project wordt aangemaakt.",
"Fires when a new quote is created.": "Vuurt wanneer een nieuwe offerte wordt gemaakt.",
"Markdown": "Markdown",
"Webhook Key": "Webhook sleutel",
"Fetch Full Contact": "Volledig contact ophalen",
"Fetch Full Invoice": "Volledige factuur ophalen",
"Types": "Typen",
"Bank Account Code": "Code bankrekening",
"Payment Types": "Betalings typen",
"Filter by Status (optional)": "Filter op status (optioneel)",
"First-time Status (optional)": "Eerste tijd status (optioneel)",
"Quote Number (partial match)": "Offertenummer (gedeeltelijke overeenstemming)",
"Expiry Date From (YYYY-MM-DD)": "Vervaldatum vanaf (JJJJ-MM-DD)",
"Expiry Date To (YYYY-MM-DD)": "Verloopdatum tot (JJJJ-MM-DD)",
"Statuses (optional)": "Statussen (optioneel)",
"Summary Only (lighter, faster)": "Alleen samenvatting (lichter, sneller)",
"States (optional)": "Staten (optioneel)",
"Page Size (1-500)": "Page Size (1-500)",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nOm deze trigger te gebruiken, configureer handmatig een Xero webhook voor je app:\n\n. Ga naar Xero Developer > Mijn Apps > [Your App] > Webhooks.\n2. Selecteer de contactpersonencategorie.\n3. Stel de Levering URL in:\n\n\n```text\n{{webhookUrl}}\n```\n4. Klik op opslaan en klik vervolgens op \"Intent om te ontvangen\".\n5. Kopieer de Webhook Key van de Webhooks pagina en plak deze in het onderstaande Webhook sleutelveld.\n6. Optioneel organisatie-ID (Tenant ID) instellen om alleen afspraken van een specifiek orgaan te accepteren. \n\n notities:\n- Houd deze trigger ingeschakeld zodat de URL actief blijft.\n- Wij verifiëren de header Xero's x-xero-handtekening met behulp van uw Webhook Key.\n ",
"From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.": "Van Xero Developer portal > Your App > Webhooks. Gebruikt om x-xero-signatuur te verifiëren.",
"If enabled, fetches the full contact from Xero using the Resource URL.": "Indien ingeschakeld, haalt het volledige contact van Xero via de document URL.",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nOm deze trigger te gebruiken, configureer handmatig een Xero webhook voor je app:\n\n. Ga naar Xero Developer > Mijn Apps > [Your App] > Webhooks.\n2. Selecteer de factuur categorie.\n3. Stel de Levering URL in:\n\n\n```text\n{{webhookUrl}}\n```\n4. Klik op opslaan en klik vervolgens op \"Intent om te ontvangen\".\n5. Kopieer de Webhook Key van de Webhooks pagina en plak deze in het onderstaande Webhook sleutelveld.\n6. Optioneel organisatie-ID (Tenant ID) instellen om alleen afspraken van een specifiek orgaan te accepteren. \n\n notities:\n- Houd deze trigger ingeschakeld zodat de URL actief blijft.\n- Wij verifiëren de header Xero's x-xero-handtekening met behulp van uw Webhook Key.\n ",
"Fetch the full invoice and ensure Type is ACCREC (recommended).": "Ophalen van de volledige factuur en zorg ervoor dat Type ACCREC is (aanbevolen).",
"Also fire when a purchase order enters this status for the first time (since enabling).": "Vuur ook wanneer een inkooporder deze status voor het eerst invoert (sinds aanzetten).",
"RECEIVE": "ONTVANGEN",
"SPEND": "SNELHEID",
"RECEIVE-OVERPAYMENT": "ONTVANGE OVERPAYMENT",
"SPEND-OVERPAYMENT": "SPEND-OVERPAYMENT",
"RECEIVE-PREPAYMENT": "ONTVANGE PREPAYMENT",
"SPEND-PREPAYMENT": "SPEND-PREPAYMENT",
"RECEIVE-TRANSFER": "RECEIVE-TRANSFER",
"SPEND-TRANSFER": "SPEND-TRANSFER",
"AUTHORISED": "AUTHORIESEN",
"DELETED": "VERWIJDERD",
"ACCRECPAYMENT (Received on Sales Invoice)": "ACCRECPAYMENT (Ontvangen op verkoopfactuur)",
"ACCPAYPAYMENT (Paid on Bill)": "ACCPAYPAYMENT (Betaald op bank)",
"DRAFT": "CONCEPT",
"SUBMITTED": "INSCHAKELEN",
"BILLED": "GEFACTUREERD",
"SENT": "VERZONDEN",
"ACCEPTED": "GEACCEPTEERD",
"DECLINED": "VERWIJDEREN",
"INVOICED": "TOEGEVOEGD",
"PAID": "VERBETALING",
"VOIDED": "VORIGD",
"ACCRECCREDIT (Sales Credit)": "ACCRECCREDIT (Vertaal Credit)",
"ACCPAYCREDIT (Supplier Credit)": "ACCPAYCREDIT (Supplier Credit)",
"INPROGRESS": "INPROGRES",
"CLOSED": "GESLOTEN"
}

View File

@@ -0,0 +1,320 @@
{
"Beautiful accounting software": "Belo software de contabilidade",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Entre no Xero.\n 2. Vá para [portal do desenvolvedor](https://developer.xero.com/app/manage/).\n 3. Clique no aplicativo que você deseja integrar.\n 4. À esquerda, clique em `Configuração`.\n 5. Digite a sua `url de redirecionamento`.\n 6. Copie o `Client Id` e o `Client Secret`.\n ",
"Create or Update Contact": "Criar ou atualizar contato",
"Create or Update Invoice": "Criar ou atualizar fatura",
"Allocate Credit Note to Invoice": "Alocar nota de crédito para fatura",
"Create Bank Transfer": "Criar Transferência Bancária",
"Create New Quote Draft": "Criar novo rascunho de orçamento",
"Send Sales Invoice by Email": "Enviar Fatura de Vendas por E-mail",
"Create Bill": "Criar conta",
"Create Payment": "Criar Pagamento",
"Create Purchase Order": "Criar pedido de compra",
"Update Purchase Order": "Atualizar Pedido de Compra",
"Upload Attachment": "Carregar Anexo",
"Add Items to Existing Sales Invoice": "Adicionar itens à Nota Fiscal de Venda Existente",
"Create Credit Note": "Criar Nota De Crédito",
"Create Inventory Item": "Criar Item de Inventário",
"Create Project": "Criar Projeto",
"Update Sales Invoice": "Atualizar Nota Fiscal de Venda",
"Create Repeating Sales Invoice": "Criar Fatura de Venda Recorrente",
"Find Contact": "Localizar contato",
"Find Invoice": "Encontrar fatura",
"Find Item": "Encontrar item",
"Find Purchase Order": "Encontrar pedido de compra",
"Custom API Call": "Chamada de API personalizada",
"Create Xero Contact": "Criar Xero Contato",
"Create Xero Invoice": "Criar Xero Fatura",
"Allocates a credit note to a specific invoice.": "Aloca uma nota de crédito para uma fatura específica.",
"Transfers money between two bank accounts in Xero.": "Transfere dinheiro entre duas contas bancárias em Xero.",
"Creates a new draft quote.": "Cria uma nova citação de rascunho.",
"Sends a sales invoice via email to a contact.": "Envia uma nota fiscal por e-mail para um contato.",
"Creates a new bill (Accounts Payable).": "Cria uma nova conta (Contas a Pagar).",
"Applies a payment to an invoice.": "Aplica um pagamento a uma fatura.",
"Creates a new purchase order for a contact.": "Cria uma nova ordem de compra para um contato.",
"Updates details of an existing purchase order.": "Detalhes da atualização de um pedido de compra existente.",
"Uploads an attachment to a specific Xero resource.": "Carrega um anexo para um recurso Xero específico.",
"Adds line items to an existing sales invoice (ACCREC).": "Adiciona itens de linha a uma fatura de venda existente (ACCREC).",
"Creates a new credit note for a contact.": "Cria uma nova nota de crédito para um contato.",
"Creates a new inventory item in Xero.": "Cria um novo item de inventário no Xero.",
"Creates a new project for a contact.": "Cria um novo projeto para um contato.",
"Updates details of an existing sales invoice (ACCREC).": "Detalhes de atualização de uma fatura de vendas existente (ACCREC).",
"Creates a repeating sales invoice (Accounts Receivable).": "Cria uma fatura de venda repetida (Recebimento de Contas).",
"Finds a contact by name or account number (or SearchTerm).": "Localiza um contato por nome ou número de conta (ou PesquisarTermo).",
"Finds an invoice by number or reference.": "Encontra uma fatura por número ou referência.",
"Finds an item by name or code.": "Encontra um item por nome ou código.",
"Finds a purchase order by given parameters.": "Encontra uma ordem de compra por determinados parâmetros.",
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
"Organization": "Cliente",
"Contact ID": "ID do contato",
"Contact Name": "Nome do contato",
"Contact Email": "E-mail de contato",
"Invoice": "Fatura",
"Contact": "contato",
"Line Item": "Item de Linha",
"Date Prepared": "Data de Preparação",
"Due Date": "Data de vencimento",
"Invoice Reference": "Referência da fatura",
"Status": "Estado",
"Credit Note": "Nota De Crédito",
"Amount": "Quantidade",
"Allocation Date": "Alocar Data",
"Bank Account": "Conta Bancária",
"Transfer Date": "Data de transferência",
"Reference": "Referência",
"From Is Reconciled": "De São Reconciliados",
"To Is Reconciled": "Para Reconciliados",
"Date": "Encontro",
"Expiry Date": "Expiry Date",
"Line Amount Types": "Linha Tipos de Quantidade",
"Quote Number": "No. Cotação",
"Title": "Título",
"Summary": "Summary",
"Terms": "Termos",
"Sales Invoice (Sendable)": "Fatura de Vendas (Enviável)",
"Bill Number (Reference)": "Número de conta (referência)",
"Invoice (Authorised)": "Fatura (autorizado)",
"Payment Date": "Data do pagamento",
"Is Reconciled": "Está Reconciliado",
"Delivery Date": "Data de entrega",
"Purchase Order Number": "Número do pedido",
"Branding Theme": "Tema da Marca",
"Delivery Address": "Endereço de Entrega",
"Attention To": "Atenção a",
"Telephone": "Telefone",
"Delivery Instructions": "Instruções de entrega",
"Expected Arrival Date": "Data Prevista de Chegada",
"Purchase Order": "Pedido Unico",
"Mark as Sent to Contact": "Marcar como Enviado ao Contato",
"Expected Arrival Date (YYYY-MM-DD)": "Data esperada de chegada (AAAA-MM-DD)",
"Resource Type": "Tipo de Recurso",
"Resource": "Recurso",
"File": "Arquivo",
"File Name (override)": "Nome do arquivo (sobrescrito)",
"Content Type": "Tipo de Conteúdo",
"Include with Online Invoice": "Incluir com fatura online",
"Allow AUTHORISED invoices": "Permitir faturas AUTHORISED",
"New Line Items": "Nova linha de itens",
"Type": "tipo",
"Credit Note Number": "Número da nota de crédito",
"Reference (ACCRECCREDIT only)": "Referência (apenas ACCRECCREDIT)",
"Currency Code": "Código da Moeda",
"Line Items": "Itens da linha",
"Item Code": "Código do item",
"Name": "Nome",
"Sales Description": "Descrição de vendas",
"Purchase Description": "Descrição da compra",
"Is Sold": "Está Vendido",
"Is Purchased": "É comprado",
"Sales Details": "Detalhes de Vendas",
"Account": "conta",
"Purchase Details": "Detalhes da compra",
"Project Name": "Nome do Projeto",
"Deadline (UTC ISO-8601)": "Prazo (UTC ISO-8601)",
"Estimate Amount": "Quantidade Estimativa",
"Sales Invoice (Editable)": "Fatura de Vendas (Editável)",
"Due Date (YYYY-MM-DD)": "Data de Vencimento (AAAA-MM-DD)",
"Invoice Number": "Número da fatura",
"Source URL": "URL de origem",
"Replace All Line Items": "Substituir todos os itens da linha",
"Line Items (updates/additions)": "Itens de linha (atualizações/adições)",
"Schedule Period": "Agendar Período",
"Schedule Unit": "Agendar unidade",
"Due Date (number)": "Data de Vencimento (número)",
"Due Date Type": "Data de Vencimento",
"Start Date (YYYY-MM-DD)": "Data de Início (AAAA-MM-DD)",
"End Date (YYYY-MM-DD)": "Data Final (AAAA-MM-DD)",
"Currency": "moeda",
"Approved For Sending": "Aprovado para envio",
"Send Copy": "Enviar cópia",
"Mark As Sent": "Marcar Como Enviada",
"Include PDF": "Incluir PDF",
"Search By": "Pesquisar por",
"Value": "Valor",
"Include Archived": "Incluir Arquivados",
"Summary Only (faster, lighter)": "Resumo apenas (mais rápido, mais leve)",
"Page": "Página",
"Type Filter": "Tipo de Filtro",
"Order (optional)": "Pedido (opcional)",
"Statuses": "Statuses",
"Date From (YYYY-MM-DD)": "Data De (AAAA-MM-DD)",
"Date To (YYYY-MM-DD)": "Data até (AAAA-MM-DD)",
"Order (e.g., Date DESC)": "Pedido (ex. Data DESC)",
"Page Size (1-1000)": "Tamanho da Página (1-1000)",
"Method": "Método",
"Headers": "Cabeçalhos",
"Query Parameters": "Parâmetros da consulta",
"Body": "Conteúdo",
"Response is Binary ?": "A resposta é binária ?",
"No Error on Failure": "Nenhum erro no Failure",
"Timeout (in seconds)": "Tempo limite (em segundos)",
"ID of the contact to create invoice for.": "ID do contato para criar fatura para.",
"Contact name, in full.": "Nome do contato, completo",
"Email address of the contact.": "E-mail do contato.",
"Select an invoice": "Selecione uma fatura",
"Select a contact": "Selecione um contato",
"Invoice line items": "Itens de linha de fatura",
"Date the invoice was created. Format example: 2019-03-11": "Data em que a fatura foi criada. Exemplo de formato: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "Data de vencimento da fatura. Exemplo de formato: 2019-03-11",
"Reference number of the Invoice": "Número de referência da fatura",
"Invoice Status": "Status da fatura",
"Select a credit note to allocate from": "Selecione uma nota de crédito para alocar de",
"The amount of the credit to allocate.": "O montante do crédito a atribuir.",
"Date of allocation. Format: YYYY-MM-DD. Optional.": "Data de alocação. Formato: AAAA-MM-DD. Opcional.",
"Select a bank account": "Selecione uma conta bancária",
"Amount to transfer. Currencies must match between accounts.": "Valor a transferir. Moedas devem corresponder entre contas.",
"YYYY-MM-DD. Defaults to today if not provided.": "AAAA-MM-DD. O padrão é hoje se não for fornecido.",
"Reference for the transfer.": "Referência para a transferência.",
"Mark source account transaction as reconciled.": "Marcar transação da conta de origem como reconciliada.",
"Mark destination account transaction as reconciled.": "Marcar transação de conta de destino como reconciliada.",
"Date the quote was issued (YYYY-MM-DD).": "Data em que a cotação foi emitida (AAAA-MM-DD).",
"Date the quote expires (YYYY-MM-DD).": "Data expira (AAAA-MM-DD).",
"At minimum, provide a Description.": "No mínimo, forneça uma Descrição.",
"Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).": "Selecione uma fatura de vendas com um status válido para o envio de e-mail (SUBMITTED, AUTHORISED, ou PAID).",
"Date the bill was issued (YYYY-MM-DD). Optional.": "Data em que a fatura foi emitida (AAAA-MM-DD). Opcional.",
"Date the bill is due (YYYY-MM-DD). Optional.": "Data em que a fatura é devida (AAAA-MM-DD). Opcional.",
"Select an authorised invoice (sales or bill) to apply payment to.": "Selecione uma fatura autorizada (vendas ou fatura) para aplicar o pagamento.",
"Payment amount (must be <= amount due).": "Valor do pagamento (deve ser <= valor vencido).",
"YYYY-MM-DD.": "AAAA-MM-DD",
"Mark payment as reconciled (optional).": "Marcar pagamento como reconciliado (opcional).",
"Date the purchase order was issued (YYYY-MM-DD). Optional.": "Data em que a ordem de compra foi emitida (AAAA-MM-DD). Opcional.",
"Date goods are to be delivered (YYYY-MM-DD). Optional.": "Os produtos da data devem ser entregues (AAAA-MM-DD). Opcional.",
"Select a branding theme": "Selecione um tema de marca",
"YYYY-MM-DD. Optional.": "AAAA-MM-DD. Opcional.",
"Select a purchase order to update": "Selecione uma ordem de compra para atualizar",
"The Xero resource to attach the file to.": "O recurso Xero para anexar o arquivo.",
"Select the specific resource to attach the file to.": "Selecione o recurso específico para anexar o arquivo.",
"The file to upload. Max 10MB per Xero limits.": "O arquivo a ser enviado. Máximo de 10MB por Xero limites.",
"Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *": "Nome do arquivo opcional a ser usado no Xero. Evite os caracteres: < > : \" / \\ ¶? *",
"MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.": "Tipo MIME do arquivo (por exemplo, imagem/png). Se não for definido, será deduzido ou padrão para aplicação/octet-stream.",
"Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.": "Apenas aplicável para faturas ACCREC e notas de crédito ACCREC. Acrescenta IncludeOnline=verdadeiro parâmetro de consulta.",
"Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Habilitar adição de itens às faturas AUTHORISED (Xero permite atualizações limitadas para ACCREC/parcialmente pago).",
"Add one or more line items. At minimum, each line needs a Description.": "Adicione um ou mais itens de linha. No mínimo, cada linha precisa de uma descrição.",
"Select an account": "Selecione uma conta",
"Example: 2017-04-23T18:25:43.511Z": "Exemplo: 2017-04-23T18:25:43.511Z",
"Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Habilitar atualizações para as faturas AUTHORISED (Xero permite atualizações limitadas para ACCREC/parcialmente pago).",
"Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.": "Selecione uma fatura de venda (ACCREC) com status DRAFT ou ASSINATURA",
"If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.": "Se ativado, somente os itens line_providos permanecerão. Se desativado, vamos nos mesclar com as linhas atuais atualizando a correspondência LineItemID e anexando novos itens.",
"Integer period (e.g., 1 every week, 2 every month).": "Período inteiro (por exemplo, 1 toda semana, 2 a cada mês).",
"Day number used with due date type (e.g., 20, 31).": "Número de dia usado com tipo de data limite (e.g., 20, 31).",
"Select a currency code": "Selecione um código de moeda",
"Name, Account Number, or Search Term depending on Search By.": "Nome, Número de Conta ou Termo de Pesquisa dependendo da Pesquisa Por.",
"Recommended for broad searches (Search Term). Excludes heavy fields.": "Recomendado para pesquisas amplas (Termos do Site). Exclui campos pesados.",
"Pagination page (optional).": "Página de paginação (opcional).",
"Invoice Number, Reference, or Search Term.": "Número da fatura, referência ou termo de pesquisa.",
"Item Code or Name (exact match).": "Código ou Nome do Item (Correspondência).",
"e.g. Name or Name DESC": "ex: Nome ou Nome DESC",
"Number, Reference or ID depending on Search By.": "Número, referência ou ID dependendo da pesquisa por.",
"Authorization headers are injected automatically from your connection.": "Os cabeçalhos de autorização são inseridos automaticamente a partir da sua conexão.",
"Enable for files like PDFs, images, etc..": "Habilitar para arquivos como PDFs, imagens, etc..",
"Draft": "Rascunho",
"Submitted": "Enviado",
"Authorised": "Autorizado",
"Deleted": "Excluído",
"Voided": "Anulado",
"Exclusive": "Exclusivo",
"Inclusive": "Inclusivo",
"NoTax": "NoTax",
"Billed": "Faturado",
"Quote": "Cotação",
"Bank Transfer": "Transferência Bancária",
"Bank Transaction": "Transação Bancária",
"Manual Journal": "Diário Manual",
"Receipt": "Recibo",
"Repeating Invoice": "Fatura Recorrente",
"Accounts Receivable Credit (ACCRECCREDIT)": "Contas a receber crédito (ACCRECCREDIT)",
"Accounts Payable Credit (ACCPAYCREDIT)": "Crédito a pagar pelas contas (ACCPAYCREDIT)",
"Weekly": "Semanalmente",
"Monthly": "Mensual",
"Name (exact match)": "Nome (correspondência exata)",
"Account Number (exact match)": "Número de conta (correspondência exata)",
"Search Term (broad search)": "Termo de pesquisa (pesquisa ampla)",
"Invoice Number (exact)": "Número da fatura (exato)",
"Reference (exact)": "Referência (exata)",
"Search Term (InvoiceNumber/Reference)": "Termo de Pesquisa (Número/Referência)",
"Sales Invoice (ACCREC)": "Fatura de Vendas (ACCREC)",
"Bill (ACCPAY)": "Fatura (ACCPAY)",
"Code (exact)": "Código (exato)",
"Name (exact)": "Nome (exato)",
"Purchase Order Number (exact)": "Número do pedido de compra (exato)",
"Purchase Order ID (GUID)": "ID do pedido de compra (GUID)",
"GET": "OBTER",
"POST": "POSTAR",
"PATCH": "COMPRAR",
"PUT": "COLOCAR",
"DELETE": "EXCLUIR",
"HEAD": "CABEÇA",
"New Contact": "Novo Contato",
"New or Updated Contact": "Contato novo ou atualizado",
"New Sales Invoice": "Novo Pedido de Venda",
"Updated Sales Invoice": "Fatura de Venda Atualizada",
"New Bank Transaction": "Nova transação bancária",
"New Payment": "Novo pagamento",
"New Purchase Order": "Novo Pedido de Compra",
"New Reconciled Payment": "Novo Pagamento Reconciliado",
"Updated Quote": "Cotação atualizada",
"New Bill": "Nova Conta",
"New Credit Note": "Nova Nota De Crédito",
"New Project": "Novo Projeto",
"New Quote": "Nova Cotação",
"Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.": "Atira quando um novo contato é adicionado ao Xero (via Xero webhooks). Configure o webhook no portal Xero Developer para apontar para esta URL.",
"Fires when a contact is created or updated (via Xero webhooks).": "Atira quando um contato é criado ou atualizado (via Xero webhooks).",
"Fires when a new sales invoice (Accounts Receivable) is created.": "Efetua quando uma nova fatura de venda (Contas a receber) é criada.",
"Fires when an existing sales invoice (Accounts Receivable) is updated.": "aciona quando uma fatura de venda existente (Contas a receber) é atualizada.",
"Fires when a new bank transaction is created.": "aciona quando uma nova transação bancária é criada.",
"Fires when a payment is received.": "Emitir quando um pagamento é recebido.",
"Fires when a new purchase order is created or enters a specific status for the first time.": "Atira quando uma nova ordem de compra é criada ou entra em um status específico pela primeira vez.",
"Fires when a payment is reconciled for the first time.": "Efetua quando um pagamento é reconciliado pela primeira vez.",
"Fires when a quote is created or updated.": "Atira quando uma citação é criada ou atualizada.",
"Fires when a new bill (Accounts Payable) is added.": "Efetua quando uma nova conta (Contas a Pagar) é adicionada.",
"Fires when a new credit note is created.": "aciona quando uma nova nota de crédito é criada.",
"Fires when a new project is created.": "aciona quando um novo projeto é criado.",
"Fires when a new quote is created.": "Atira quando uma nova citação é criada.",
"Markdown": "Markdown",
"Webhook Key": "Chave do Webhook",
"Fetch Full Contact": "Buscar Contato Completo",
"Fetch Full Invoice": "Buscar Fatura Completa",
"Types": "Tipo",
"Bank Account Code": "Código da Conta Bancária",
"Payment Types": "Tipos de Pagamento",
"Filter by Status (optional)": "Filtrar por Estado (opcional)",
"First-time Status (optional)": "Estado da primeira vez (opcional)",
"Quote Number (partial match)": "Número de Cotação (correspondência parcial)",
"Expiry Date From (YYYY-MM-DD)": "Data de expiração de (YYYY-MM-DD)",
"Expiry Date To (YYYY-MM-DD)": "Data de Validade (AAAA-MM-DD)",
"Statuses (optional)": "Status (opcional)",
"Summary Only (lighter, faster)": "Resumo apenas (mais leve, mais rápido)",
"States (optional)": "Estados (opcional)",
"Page Size (1-500)": "Page Size (1-500)",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.": "Do portal do desenvolvedor Xero > Seu aplicativo > Webhooks. Usado para verificar x-xero-signature",
"If enabled, fetches the full contact from Xero using the Resource URL.": "Se ativado, obtém o contato completo do Xero usando a URL do Recurso.",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"Fetch the full invoice and ensure Type is ACCREC (recommended).": "Obter a fatura completa e garantir que o tipo é ACCREC (recomendado).",
"Also fire when a purchase order enters this status for the first time (since enabling).": "Também dispara quando um pedido de compra entra neste status pela primeira vez (desde a ativação).",
"RECEIVE": "RECEBER",
"SPEND": "Gastar",
"RECEIVE-OVERPAYMENT": "RECEBIMENTO DE SOBRE",
"SPEND-OVERPAYMENT": "SPEND-OVERPAMENTO",
"RECEIVE-PREPAYMENT": "RECEBIMENTO PREPAGAMENTO",
"SPEND-PREPAYMENT": "PREPAGAMENTO SPEND-PAGAMENTE",
"RECEIVE-TRANSFER": "TRANSFERÊNCIA DE RECEBIDO",
"SPEND-TRANSFER": "SPEND-TRANSFERÊNCIA",
"AUTHORISED": "AUTHORIZADO",
"DELETED": "APAGADO",
"ACCRECPAYMENT (Received on Sales Invoice)": "ACCRECPAYMENT (Recebido na fatura de vendas)",
"ACCPAYPAYMENT (Paid on Bill)": "ACCPAYPYMENT (Ponto na fatura)",
"DRAFT": "RASCUNHO",
"SUBMITTED": "SUBMITIDO",
"BILLED": "COBRADO",
"SENT": "ENVIADO",
"ACCEPTED": "ACEITADO",
"DECLINED": "DECLINADO",
"INVOICED": "FATURADA",
"PAID": "PAGO",
"VOIDED": "VOTAÇÕES",
"ACCRECCREDIT (Sales Credit)": "ACCRECCREDIT (crédito de vendas)",
"ACCPAYCREDIT (Supplier Credit)": "ACCPAYCREDIT (Crédito Suporte)",
"INPROGRESS": "INPROGRESSO",
"CLOSED": "FECHADO"
}

View File

@@ -0,0 +1,319 @@
{
"Xero": "Xero",
"Beautiful accounting software": "Красивые бухгалтерские программы",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ",
"Create or Update Contact": "Создать или обновить контакт",
"Create or Update Invoice": "Создание или обновление счета",
"Allocate Credit Note to Invoice": "Выделить Кредитную Ноту счету",
"Create Bank Transfer": "Создать банковский перевод",
"Create New Quote Draft": "Создать новый проект сметы",
"Send Sales Invoice by Email": "Отправить счет для продаж по электронной почте",
"Create Bill": "Создать счёт",
"Create Payment": "Создать платеж",
"Create Purchase Order": "Создать заказ на покупку",
"Update Purchase Order": "Обновить заказ на покупку",
"Upload Attachment": "Загрузить вложение",
"Add Items to Existing Sales Invoice": "Добавить элементы к существующим счетам продаж",
"Create Credit Note": "Создать Кредит-Ноту",
"Create Inventory Item": "Создать элемент инвентаря",
"Create Project": "Создать проект",
"Update Sales Invoice": "Обновить счет для продаж",
"Create Repeating Sales Invoice": "Создать повторяющийся счет для продаж",
"Find Contact": "Найти контакт",
"Find Invoice": "Найти счет",
"Find Item": "Найти предмет",
"Find Purchase Order": "Найти заказ на покупку",
"Custom API Call": "Пользовательский вызов API",
"Create Xero Contact": "Создать ксерокс контакт",
"Create Xero Invoice": "Создать ксерокс счета",
"Allocates a credit note to a specific invoice.": "Выдает кредитную квитанцию на конкретный счет.",
"Transfers money between two bank accounts in Xero.": "Перевод средств между двумя банковскими счетами в Xero.",
"Creates a new draft quote.": "Создать черновик кавычки.",
"Sends a sales invoice via email to a contact.": "Отправляет счет о продажах по электронной почте контакту.",
"Creates a new bill (Accounts Payable).": "Создает новый счет (счета оплачиваемых счетов).",
"Applies a payment to an invoice.": "Применяет платеж к счету.",
"Creates a new purchase order for a contact.": "Создает новый заказ на покупку контакта.",
"Updates details of an existing purchase order.": "Обновляет детали существующего заказа на покупку.",
"Uploads an attachment to a specific Xero resource.": "Загружает вложение на определенный Ксерокс ресурс.",
"Adds line items to an existing sales invoice (ACCREC).": "Добавляет позиции к существующему счета-фактуре на продажу (ACCREC).",
"Creates a new credit note for a contact.": "Создает новую кредитную квитанцию для контакта.",
"Creates a new inventory item in Xero.": "Создает новый инвентарь в Xero.",
"Creates a new project for a contact.": "Создает новый проект для контакта.",
"Updates details of an existing sales invoice (ACCREC).": "Обновления деталей существующего счета для продаж (ACCREC).",
"Creates a repeating sales invoice (Accounts Receivable).": "Создает повторяющийся счет-фактуру для продаж (дебиторская задолженность).",
"Finds a contact by name or account number (or SearchTerm).": "Поиск контакта по имени или номеру аккаунта (или по запросу).",
"Finds an invoice by number or reference.": "Идет счет-фактура по номеру или ссылке.",
"Finds an item by name or code.": "Поиск товара по названию или коду.",
"Finds a purchase order by given parameters.": "Ищет заказ на покупку по заданным параметрам.",
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
"Organization": "Организация",
"Contact ID": "ID контакта",
"Contact Name": "Имя контакта",
"Contact Email": "Контактный адрес электронной почты",
"Invoice": "Счет",
"Contact": "Контакт",
"Line Item": "Элемент строки",
"Date Prepared": "Дата подготовки",
"Due Date": "Срок сдачи",
"Invoice Reference": "Счет-фактура",
"Status": "Status",
"Credit Note": "Кредит-Нота",
"Amount": "Сумма",
"Allocation Date": "Дата распределения",
"Bank Account": "Банковский счет",
"Transfer Date": "Дата перевода",
"Reference": "Артикул",
"From Is Reconciled": "С сверено",
"To Is Reconciled": "Сверено",
"Date": "Дата",
"Expiry Date": "Expiry Date",
"Line Amount Types": "Типы количества линий",
"Quote Number": "Номер сметы",
"Title": "Заголовок",
"Summary": "Summary",
"Terms": "Условия",
"Sales Invoice (Sendable)": "Счет о продажах (допускается)",
"Bill Number (Reference)": "Номер счета (ссылка)",
"Invoice (Authorised)": "Счет (Авторизованный)",
"Payment Date": "Дата оплаты",
"Is Reconciled": "Сверено",
"Delivery Date": "Дата доставки",
"Purchase Order Number": "Номер заказа на покупку",
"Branding Theme": "Тема бренда",
"Delivery Address": "Адрес доставки",
"Attention To": "Внимание к",
"Telephone": "Телефон",
"Delivery Instructions": "Инструкции по доставке",
"Expected Arrival Date": "Ожидаемая дата прибытия",
"Purchase Order": "Заказ на покупку",
"Mark as Sent to Contact": "Пометить как отправленное контакту",
"Expected Arrival Date (YYYY-MM-DD)": "Ожидаемая дата прибытия (ГГГГ-ММ-ДД)",
"Resource Type": "Тип ресурса",
"Resource": "Ресурс",
"File": "Файл",
"File Name (override)": "Имя файла (переопределить)",
"Content Type": "Тип контента",
"Include with Online Invoice": "Включить с онлайн-счетом",
"Allow AUTHORISED invoices": "Разрешить AUTHORISED счета",
"New Line Items": "Новая строка",
"Type": "Тип",
"Credit Note Number": "Номер Кредитной Ноты",
"Reference (ACCRECCREDIT only)": "Ссылка (только ACCRECCREDIT)",
"Currency Code": "Код валюты",
"Line Items": "Позиции",
"Item Code": "Код товара",
"Name": "Наименование",
"Sales Description": "Описание продаж",
"Purchase Description": "Описание покупки",
"Is Sold": "Продается",
"Is Purchased": "Куплено",
"Sales Details": "Детали продаж",
"Account": "Аккаунт",
"Purchase Details": "Информация о покупке",
"Project Name": "Название проекта",
"Deadline (UTC ISO-8601)": "Срок (UTC ISO-8601)",
"Estimate Amount": "Вычислить сумму",
"Sales Invoice (Editable)": "Счет о продажах (доступный)",
"Due Date (YYYY-MM-DD)": "Срок сдачи (ГГГ-ММ-ДД)",
"Invoice Number": "Номер счёта",
"Source URL": "Исходный URL",
"Replace All Line Items": "Заменить все элементы строки",
"Line Items (updates/additions)": "Элементы строки (обновления/добавления)",
"Schedule Period": "График периода",
"Schedule Unit": "Единица расписания",
"Due Date (number)": "Дата выполнения (число)",
"Due Date Type": "Тип даты платежа",
"Start Date (YYYY-MM-DD)": "Дата начала (ГГГ-ММ-ДД)",
"End Date (YYYY-MM-DD)": "Дата окончания (ГГГГ-ММ-ДД)",
"Currency": "Валюта",
"Approved For Sending": "Одобрен для отправки",
"Send Copy": "Отправить копию",
"Mark As Sent": "Пометить как отправленное",
"Include PDF": "Включить PDF",
"Search By": "Поиск по",
"Value": "Значение",
"Include Archived": "Включать в архив",
"Summary Only (faster, lighter)": "Только резюме (быстрее, легче)",
"Page": "Страница",
"Type Filter": "Фильтр типов",
"Order (optional)": "Заказ (необязательно)",
"Statuses": "Statuses",
"Date From (YYYY-MM-DD)": "Дата С (ГГГ-ММ-ДД)",
"Date To (YYYY-MM-DD)": "Дата До (ГГГГ-ММ-ДД)",
"Order (e.g., Date DESC)": "Заказ (например, Дата DESC)",
"Page Size (1-1000)": "Размер страницы (1-1000)",
"Method": "Метод",
"Headers": "Заголовки",
"Query Parameters": "Параметры запроса",
"Body": "Тело",
"No Error on Failure": "Нет ошибок при ошибке",
"Timeout (in seconds)": "Таймаут (в секундах)",
"ID of the contact to create invoice for.": "ID контакта для создания счета-фактуры.",
"Contact name, in full.": "Имя контакта полностью.",
"Email address of the contact.": "Адрес электронной почты контакта.",
"Select an invoice": "Выберите счет",
"Select a contact": "Выберите контакт",
"Invoice line items": "Элементы счет-фактуры",
"Date the invoice was created. Format example: 2019-03-11": "Дата создания счета. Формат, например: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "Срок сдачи счета. Формат: 2019-03-11",
"Reference number of the Invoice": "Номер счета",
"Invoice Status": "Статус счета",
"Select a credit note to allocate from": "Выберите кредитную квитанцию для распределения",
"The amount of the credit to allocate.": "Сумма кредита для выделения.",
"Date of allocation. Format: YYYY-MM-DD. Optional.": "Дата размещения. Формат: YYYY-MM-DD. Необязательно.",
"Select a bank account": "Выберите банковский счет",
"Amount to transfer. Currencies must match between accounts.": "Сумма для перевода. Валюты должны совпадать между счетами.",
"YYYY-MM-DD. Defaults to today if not provided.": "ГГГГ-ММ-ДД. По умолчанию сегодня если не предусмотрено.",
"Reference for the transfer.": "Ссылка на передачу.",
"Mark source account transaction as reconciled.": "Пометить исходную транзакцию как проверенную.",
"Mark destination account transaction as reconciled.": "Пометить транзакцию по счету назначения как сверенную.",
"Date the quote was issued (YYYY-MM-DD).": "Дата выпуска котировки (ГГГГ-ММ-ДД).",
"Date the quote expires (YYYY-MM-DD).": "Срок действия котировки истекает (ГГГ-ММ-ДД).",
"At minimum, provide a Description.": "Как минимум предоставьте описание.",
"Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).": "Выберите счет-фактуру для продажи с действительным статусом для отправки электронной почты (SUBMITTED, AUTHORISED или PAID).",
"Date the bill was issued (YYYY-MM-DD). Optional.": "Дата выпуска законопроекта (ГГГГ-ММ-ДД).",
"Date the bill is due (YYYY-MM-DD). Optional.": "Дата выставления счета (ГГГГ-ММ-ДД). Необязательно.",
"Select an authorised invoice (sales or bill) to apply payment to.": "Выберите авторизованный счет-фактуру (продажу или счет) для применения платежа.",
"Payment amount (must be <= amount due).": "Сумма платежа (должна быть <= amount due).",
"YYYY-MM-DD.": "ГГГГ-ММ-ДД.",
"Mark payment as reconciled (optional).": "Пометить платеж как сверенный (необязательно).",
"Date the purchase order was issued (YYYY-MM-DD). Optional.": "Дата оформления заказа (YYYYY-MM-DD), опционально.",
"Date goods are to be delivered (YYYY-MM-DD). Optional.": "Дата доставки товара (YYYYY-MM-DD), опционально.",
"Select a branding theme": "Выберите тему оформления",
"YYYY-MM-DD. Optional.": "YYYY-MM-DD. Необязательно.",
"Select a purchase order to update": "Выберите заказ на покупку для обновления",
"The Xero resource to attach the file to.": "Ресурс Xero для прикрепления файла.",
"Select the specific resource to attach the file to.": "Выберите ресурс, к которому будет прикреплен файл.",
"The file to upload. Max 10MB per Xero limits.": "Файл для загрузки. Максимум 10 МБ за лимиты.",
"Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *": "Необязательное имя файла для использования в Xero. Избегайте символов: < > : \" / \\ | ? *",
"MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.": "MIME тип файла (например, image/png). Если не установлено, будет введен или по умолчанию application/octet-stream.",
"Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.": "Применимо только к счетам ACCREC и кредитным нотам ACCREC.",
"Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Включить добавление элементов в счета AUTHORISED (Xero позволяет использовать ограниченные обновления для оплаченных ACCREC).",
"Add one or more line items. At minimum, each line needs a Description.": "Добавьте одну или несколько позиций. Минимум для каждой строки требуется описание.",
"Select an account": "Выберите аккаунт",
"Example: 2017-04-23T18:25:43.511Z": "Пример: 2017-04-23T18:25:43.511Z",
"Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Включить обновления для счетов AUTHORISED (Xero позволяет использовать ограниченные обновления для оплаченных ACCREC).",
"Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.": "Выберите счет-фактуру для продаж (ACCREC) в статусе DRAFT или SUBMITTED.",
"If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.": "Если включено, только предоставленная line_items останется. Если отключена, мы объединим с текущими строками путем обновления соответствия LineItemID и добавления новых элементов.",
"Integer period (e.g., 1 every week, 2 every month).": "Целочисленный период (например, 1 раз в неделю, 2 раза в месяц).",
"Day number used with due date type (e.g., 20, 31).": "Номер дня, используемый с типом установленной даты (например, 20, 31).",
"Select a currency code": "Выберите код валюты",
"Name, Account Number, or Search Term depending on Search By.": "Имя, номер счета или условия поиска в зависимости от поиска.",
"Recommended for broad searches (Search Term). Excludes heavy fields.": "Рекомендуется для широкого поиска (Поиск терминов). Исключает тяжелые поля.",
"Pagination page (optional).": "Страница пагинации (необязательно).",
"Invoice Number, Reference, or Search Term.": "Номер счета, ссылка или условия поиска.",
"Item Code or Name (exact match).": "Код товара или Имя (точное совпадение).",
"e.g. Name or Name DESC": "напр. Name or Name DESC",
"Number, Reference or ID depending on Search By.": "Число, ссылка или ID в зависимости от поиска.",
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
"Draft": "Черновик",
"Submitted": "Отправлено",
"Authorised": "Авторизован",
"Deleted": "Удалено",
"Voided": "Аннулировано",
"Exclusive": "Эксклюзивный",
"Inclusive": "Включающий",
"NoTax": "NoTax",
"Billed": "Оплачено",
"Quote": "Цитата",
"Bank Transfer": "Банковский перевод",
"Bank Transaction": "Банковская транзакция",
"Manual Journal": "Ручной Журнал",
"Receipt": "Квитанция",
"Repeating Invoice": "Повторяющийся счет",
"Accounts Receivable Credit (ACCRECCREDIT)": "Счета дебиторской задолженности (ACCRECCREDIT)",
"Accounts Payable Credit (ACCPAYCREDIT)": "Кредит к счетам (АККПАЙКРЕДИТ)",
"Weekly": "Еженедельно",
"Monthly": "Ежемесячно",
"Name (exact match)": "Имя (точное совпадение)",
"Account Number (exact match)": "Номер счета (точное совпадение)",
"Search Term (broad search)": "Поисковый термин (широкий поиск)",
"Invoice Number (exact)": "Номер счета (точный)",
"Reference (exact)": "Артикул (точно)",
"Search Term (InvoiceNumber/Reference)": "Поиск термина (номер счета/ссылка)",
"Sales Invoice (ACCREC)": "Счет о продажах (ACCREC)",
"Bill (ACCPAY)": "Счет (ACCPAY)",
"Code (exact)": "Код (точно)",
"Name (exact)": "Имя (точное)",
"Purchase Order Number (exact)": "Номер заказа на покупку (точно)",
"Purchase Order ID (GUID)": "ID заказа на покупку (GUID)",
"GET": "ПОЛУЧИТЬ",
"POST": "ПОСТ",
"PATCH": "ПАТЧ",
"PUT": "ПОКУПИТЬ",
"DELETE": "УДАЛИТЬ",
"HEAD": "HEAD",
"New Contact": "Новый контакт",
"New or Updated Contact": "Новый или обновленный контакт",
"New Sales Invoice": "Новый счет для продаж",
"Updated Sales Invoice": "Обновлен счет для продаж",
"New Bank Transaction": "Новая банковская транзакция",
"New Payment": "Новый платеж",
"New Purchase Order": "Новый заказ на покупку",
"New Reconciled Payment": "Новый сверенный платеж",
"Updated Quote": "Обновленные цитаты",
"New Bill": "Новый счет",
"New Credit Note": "Новая Кредитная Нота",
"New Project": "Новый проект",
"New Quote": "Новая цитата",
"Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.": "Застреляет при добавлении нового контакта в Ксеро (через веб-хуки). Настройте веб-хук в портале Xero Developer для указания на этот URL.",
"Fires when a contact is created or updated (via Xero webhooks).": "Стреляет при создании или обновлении контакта (через Xero webhooks).",
"Fires when a new sales invoice (Accounts Receivable) is created.": "Стремит при создании нового счета для продаж (счета дебиторской задолженности).",
"Fires when an existing sales invoice (Accounts Receivable) is updated.": "Выявляет, когда обновляется счет-фактура для продажи (дебиторская задолженность).",
"Fires when a new bank transaction is created.": "Возникает при создании новой банковской транзакции.",
"Fires when a payment is received.": "Возникает при получении платежа.",
"Fires when a new purchase order is created or enters a specific status for the first time.": "Вызывает создание нового заказа или входит в конкретный статус в первый раз.",
"Fires when a payment is reconciled for the first time.": "Возникает, когда платеж выверяется в первый раз.",
"Fires when a quote is created or updated.": "Показывает при создании или обновлении кавычки.",
"Fires when a new bill (Accounts Payable) is added.": "Оказывается при добавлении нового счета (счета оплачиваются).",
"Fires when a new credit note is created.": "Стреляет при создании новой кредитной квитанции.",
"Fires when a new project is created.": "Стреляет при создании нового проекта.",
"Fires when a new quote is created.": "Стреляет при создании новой кавычки.",
"Markdown": "Markdown",
"Webhook Key": "Ключ вебхука",
"Fetch Full Contact": "Получить полный контакт",
"Fetch Full Invoice": "Получить полный счет",
"Types": "Типы",
"Bank Account Code": "Код банковского счета",
"Payment Types": "Типы платежей",
"Filter by Status (optional)": "Фильтр по статусу (опционально)",
"First-time Status (optional)": "Статус первого времени (опционально)",
"Quote Number (partial match)": "Номер сметы (частичное совпадение)",
"Expiry Date From (YYYY-MM-DD)": "Дата окончания срока действия с (ГГГ-ММ-ДД)",
"Expiry Date To (YYYY-MM-DD)": "Дата окончания срока действия (ГГГ-ММ-ДД)",
"Statuses (optional)": "Статусы (опционально)",
"Summary Only (lighter, faster)": "Только резюме (легче, быстрее)",
"States (optional)": "Страны (опционально)",
"Page Size (1-500)": "Page Size (1-500)",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nЧтобы использовать этот триггер, настройте вручную Xero webhook для вашего приложения:\n\n. Перейдите в Ксеро Разработчик > Мои приложения > [Ваше приложение] > Webhooks.\n2. Выберите категорию контактов.\n3. Установите URL доставки в:\n\n\n```text\n{{webhookUrl}}\n```\n4. Нажмите \"Сохранить\", затем нажмите \"Проверить для получения\".\nСкопируйте ключ Webhook со страницы Webhooks и вставьте его в поле Webhook Key ниже.\n6. При необходимости задайте ID организации (ID клиента) принимать только события из определенного органа. \n\n Примечания:\n- Сохраняйте этот триггер, чтобы URL оставался активным.\n- Мы проверяем заголовок x-xero-signature Xero'а, используя ваш ключ Webhook.\n ",
"From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.": "От Ксеро Разработчика > Ваше приложение > Webhooks. Используется для проверки x-xero-подписи.",
"If enabled, fetches the full contact from Xero using the Resource URL.": "Если включено, извлекает полный контакт из ксерокса, используя URL ресурса.",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nЧтобы использовать этот триггер, настройте вручную Xero webhook для вашего приложения:\n\n. Перейдите в Ксеро Разработчик > Мои приложения > [Ваше приложение] > Webhooks.\n2. Выберите категорию счета.\n3. Установите URL доставки в:\n\n\n```text\n{{webhookUrl}}\n```\n4. Нажмите \"Сохранить\", затем нажмите \"Проверить для получения\".\nСкопируйте ключ Webhook со страницы Webhooks и вставьте его в поле Webhook Key ниже.\n6. При необходимости задайте ID организации (ID клиента) принимать только события из определенного органа. \n\n Примечания:\n- Сохраняйте этот триггер, чтобы URL оставался активным.\n- Мы проверяем заголовок x-xero-signature Xero'а, используя ваш ключ Webhook.\n ",
"Fetch the full invoice and ensure Type is ACCREC (recommended).": "Получить полный счет и убедиться, что тип ACCREC (рекомендуется).",
"Also fire when a purchase order enters this status for the first time (since enabling).": "Также огонь при первом входе в этот статус (после включения).",
"RECEIVE": "ПОЛУЧИТЬ",
"SPEND": "ОБРАБОТКА",
"RECEIVE-OVERPAYMENT": "ПОЛУЧЕНИЕ ПОЛУЧЕНИЯ",
"SPEND-OVERPAYMENT": "СПЕЦИАЛЬНАЯ УПРАВЛЕНИЕ",
"RECEIVE-PREPAYMENT": "ПОЛУЧИТЬ ПОЛУЧЕНИЕ",
"SPEND-PREPAYMENT": "СПЕЦИАЛЬНЫЕ ПОДПИСКИ",
"RECEIVE-TRANSFER": "ПОЛУЧИТЬ ПЕРЕВОД",
"SPEND-TRANSFER": "ТРАНСПОРТ",
"AUTHORISED": "АВТОРИЗИРОВАН",
"DELETED": "УДАЛЕНИЕ",
"ACCRECPAYMENT (Received on Sales Invoice)": "ACCRECPAYMENT (Получено при выставлении счета)",
"ACCPAYPAYMENT (Paid on Bill)": "Счёт ACCPAYPAYMENT (оплачивается по счету)",
"DRAFT": "СОЗДАНИЕ",
"SUBMITTED": "ДОБАВЛЕНИЕ",
"BILLED": "Билдио",
"SENT": "Отправлено",
"ACCEPTED": "ПРИНЯТЬ",
"DECLINED": "ОТКЛЮЧЕНО",
"INVOICED": "УВЕДОМЛЕНИЕ",
"PAID": "ПАИД",
"VOIDED": "ПРОДОЛЖЕНО",
"ACCRECCREDIT (Sales Credit)": "ACCRECCREDIT (кредит на продаж)",
"ACCPAYCREDIT (Supplier Credit)": "ACCPAYCREDIT (кредит поставщика)",
"INPROGRESS": "НЕПРОГРЕСС",
"CLOSED": "ЗАКРЫТО"
}

View File

@@ -0,0 +1,320 @@
{
"Beautiful accounting software": "Beautiful accounting software",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ",
"Create or Update Contact": "Create or Update Contact",
"Create or Update Invoice": "Create or Update Invoice",
"Allocate Credit Note to Invoice": "Allocate Credit Note to Invoice",
"Create Bank Transfer": "Create Bank Transfer",
"Create New Quote Draft": "Create New Quote Draft",
"Send Sales Invoice by Email": "Send Sales Invoice by Email",
"Create Bill": "Create Bill",
"Create Payment": "Create Payment",
"Create Purchase Order": "Create Purchase Order",
"Update Purchase Order": "Update Purchase Order",
"Upload Attachment": "Upload Attachment",
"Add Items to Existing Sales Invoice": "Add Items to Existing Sales Invoice",
"Create Credit Note": "Create Credit Note",
"Create Inventory Item": "Create Inventory Item",
"Create Project": "Create Project",
"Update Sales Invoice": "Update Sales Invoice",
"Create Repeating Sales Invoice": "Create Repeating Sales Invoice",
"Find Contact": "Find Contact",
"Find Invoice": "Find Invoice",
"Find Item": "Find Item",
"Find Purchase Order": "Find Purchase Order",
"Custom API Call": "Custom API Call",
"Create Xero Contact": "Create Xero Contact",
"Create Xero Invoice": "Create Xero Invoice",
"Allocates a credit note to a specific invoice.": "Allocates a credit note to a specific invoice.",
"Transfers money between two bank accounts in Xero.": "Transfers money between two bank accounts in Xero.",
"Creates a new draft quote.": "Creates a new draft quote.",
"Sends a sales invoice via email to a contact.": "Sends a sales invoice via email to a contact.",
"Creates a new bill (Accounts Payable).": "Creates a new bill (Accounts Payable).",
"Applies a payment to an invoice.": "Applies a payment to an invoice.",
"Creates a new purchase order for a contact.": "Creates a new purchase order for a contact.",
"Updates details of an existing purchase order.": "Updates details of an existing purchase order.",
"Uploads an attachment to a specific Xero resource.": "Uploads an attachment to a specific Xero resource.",
"Adds line items to an existing sales invoice (ACCREC).": "Adds line items to an existing sales invoice (ACCREC).",
"Creates a new credit note for a contact.": "Creates a new credit note for a contact.",
"Creates a new inventory item in Xero.": "Creates a new inventory item in Xero.",
"Creates a new project for a contact.": "Creates a new project for a contact.",
"Updates details of an existing sales invoice (ACCREC).": "Updates details of an existing sales invoice (ACCREC).",
"Creates a repeating sales invoice (Accounts Receivable).": "Creates a repeating sales invoice (Accounts Receivable).",
"Finds a contact by name or account number (or SearchTerm).": "Finds a contact by name or account number (or SearchTerm).",
"Finds an invoice by number or reference.": "Finds an invoice by number or reference.",
"Finds an item by name or code.": "Finds an item by name or code.",
"Finds a purchase order by given parameters.": "Finds a purchase order by given parameters.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Organization": "Organization",
"Contact ID": "Contact ID",
"Contact Name": "Contact Name",
"Contact Email": "Contact Email",
"Invoice": "Invoice",
"Contact": "Contact",
"Line Item": "Line Item",
"Date Prepared": "Date Prepared",
"Due Date": "Due Date",
"Invoice Reference": "Invoice Reference",
"Status": "Status",
"Credit Note": "Credit Note",
"Amount": "Amount",
"Allocation Date": "Allocation Date",
"Bank Account": "Bank Account",
"Transfer Date": "Transfer Date",
"Reference": "Reference",
"From Is Reconciled": "From Is Reconciled",
"To Is Reconciled": "To Is Reconciled",
"Date": "Date",
"Expiry Date": "Expiry Date",
"Line Amount Types": "Line Amount Types",
"Quote Number": "Quote Number",
"Title": "Title",
"Summary": "Summary",
"Terms": "Terms",
"Sales Invoice (Sendable)": "Sales Invoice (Sendable)",
"Bill Number (Reference)": "Bill Number (Reference)",
"Invoice (Authorised)": "Invoice (Authorised)",
"Payment Date": "Payment Date",
"Is Reconciled": "Is Reconciled",
"Delivery Date": "Delivery Date",
"Purchase Order Number": "Purchase Order Number",
"Branding Theme": "Branding Theme",
"Delivery Address": "Delivery Address",
"Attention To": "Attention To",
"Telephone": "Telephone",
"Delivery Instructions": "Delivery Instructions",
"Expected Arrival Date": "Expected Arrival Date",
"Purchase Order": "Purchase Order",
"Mark as Sent to Contact": "Mark as Sent to Contact",
"Expected Arrival Date (YYYY-MM-DD)": "Expected Arrival Date (YYYY-MM-DD)",
"Resource Type": "Resource Type",
"Resource": "Resource",
"File": "File",
"File Name (override)": "File Name (override)",
"Content Type": "Content Type",
"Include with Online Invoice": "Include with Online Invoice",
"Allow AUTHORISED invoices": "Allow AUTHORISED invoices",
"New Line Items": "New Line Items",
"Type": "Type",
"Credit Note Number": "Credit Note Number",
"Reference (ACCRECCREDIT only)": "Reference (ACCRECCREDIT only)",
"Currency Code": "Currency Code",
"Line Items": "Line Items",
"Item Code": "Item Code",
"Name": "Name",
"Sales Description": "Sales Description",
"Purchase Description": "Purchase Description",
"Is Sold": "Is Sold",
"Is Purchased": "Is Purchased",
"Sales Details": "Sales Details",
"Account": "Account",
"Purchase Details": "Purchase Details",
"Project Name": "Project Name",
"Deadline (UTC ISO-8601)": "Deadline (UTC ISO-8601)",
"Estimate Amount": "Estimate Amount",
"Sales Invoice (Editable)": "Sales Invoice (Editable)",
"Due Date (YYYY-MM-DD)": "Due Date (YYYY-MM-DD)",
"Invoice Number": "Invoice Number",
"Source URL": "Source URL",
"Replace All Line Items": "Replace All Line Items",
"Line Items (updates/additions)": "Line Items (updates/additions)",
"Schedule Period": "Schedule Period",
"Schedule Unit": "Schedule Unit",
"Due Date (number)": "Due Date (number)",
"Due Date Type": "Due Date Type",
"Start Date (YYYY-MM-DD)": "Start Date (YYYY-MM-DD)",
"End Date (YYYY-MM-DD)": "End Date (YYYY-MM-DD)",
"Currency": "Currency",
"Approved For Sending": "Approved For Sending",
"Send Copy": "Send Copy",
"Mark As Sent": "Mark As Sent",
"Include PDF": "Include PDF",
"Search By": "Search By",
"Value": "Value",
"Include Archived": "Include Archived",
"Summary Only (faster, lighter)": "Summary Only (faster, lighter)",
"Page": "Page",
"Type Filter": "Type Filter",
"Order (optional)": "Order (optional)",
"Statuses": "Statuses",
"Date From (YYYY-MM-DD)": "Date From (YYYY-MM-DD)",
"Date To (YYYY-MM-DD)": "Date To (YYYY-MM-DD)",
"Order (e.g., Date DESC)": "Order (e.g., Date DESC)",
"Page Size (1-1000)": "Page Size (1-1000)",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"ID of the contact to create invoice for.": "ID of the contact to create invoice for.",
"Contact name, in full.": "Contact name, in full.",
"Email address of the contact.": "Email address of the contact.",
"Select an invoice": "Select an invoice",
"Select a contact": "Select a contact",
"Invoice line items": "Invoice line items",
"Date the invoice was created. Format example: 2019-03-11": "Date the invoice was created. Format example: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "Due date of the invoice. Format example: 2019-03-11",
"Reference number of the Invoice": "Reference number of the Invoice",
"Invoice Status": "Invoice Status",
"Select a credit note to allocate from": "Select a credit note to allocate from",
"The amount of the credit to allocate.": "The amount of the credit to allocate.",
"Date of allocation. Format: YYYY-MM-DD. Optional.": "Date of allocation. Format: YYYY-MM-DD. Optional.",
"Select a bank account": "Select a bank account",
"Amount to transfer. Currencies must match between accounts.": "Amount to transfer. Currencies must match between accounts.",
"YYYY-MM-DD. Defaults to today if not provided.": "YYYY-MM-DD. Defaults to today if not provided.",
"Reference for the transfer.": "Reference for the transfer.",
"Mark source account transaction as reconciled.": "Mark source account transaction as reconciled.",
"Mark destination account transaction as reconciled.": "Mark destination account transaction as reconciled.",
"Date the quote was issued (YYYY-MM-DD).": "Date the quote was issued (YYYY-MM-DD).",
"Date the quote expires (YYYY-MM-DD).": "Date the quote expires (YYYY-MM-DD).",
"At minimum, provide a Description.": "At minimum, provide a Description.",
"Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).": "Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).",
"Date the bill was issued (YYYY-MM-DD). Optional.": "Date the bill was issued (YYYY-MM-DD). Optional.",
"Date the bill is due (YYYY-MM-DD). Optional.": "Date the bill is due (YYYY-MM-DD). Optional.",
"Select an authorised invoice (sales or bill) to apply payment to.": "Select an authorised invoice (sales or bill) to apply payment to.",
"Payment amount (must be <= amount due).": "Payment amount (must be <= amount due).",
"YYYY-MM-DD.": "YYYY-MM-DD.",
"Mark payment as reconciled (optional).": "Mark payment as reconciled (optional).",
"Date the purchase order was issued (YYYY-MM-DD). Optional.": "Date the purchase order was issued (YYYY-MM-DD). Optional.",
"Date goods are to be delivered (YYYY-MM-DD). Optional.": "Date goods are to be delivered (YYYY-MM-DD). Optional.",
"Select a branding theme": "Select a branding theme",
"YYYY-MM-DD. Optional.": "YYYY-MM-DD. Optional.",
"Select a purchase order to update": "Select a purchase order to update",
"The Xero resource to attach the file to.": "The Xero resource to attach the file to.",
"Select the specific resource to attach the file to.": "Select the specific resource to attach the file to.",
"The file to upload. Max 10MB per Xero limits.": "The file to upload. Max 10MB per Xero limits.",
"Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *": "Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *",
"MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.": "MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.",
"Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.": "Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.",
"Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).",
"Add one or more line items. At minimum, each line needs a Description.": "Add one or more line items. At minimum, each line needs a Description.",
"Select an account": "Select an account",
"Example: 2017-04-23T18:25:43.511Z": "Example: 2017-04-23T18:25:43.511Z",
"Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).",
"Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.": "Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.",
"If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.": "If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.",
"Integer period (e.g., 1 every week, 2 every month).": "Integer period (e.g., 1 every week, 2 every month).",
"Day number used with due date type (e.g., 20, 31).": "Day number used with due date type (e.g., 20, 31).",
"Select a currency code": "Select a currency code",
"Name, Account Number, or Search Term depending on Search By.": "Name, Account Number, or Search Term depending on Search By.",
"Recommended for broad searches (Search Term). Excludes heavy fields.": "Recommended for broad searches (Search Term). Excludes heavy fields.",
"Pagination page (optional).": "Pagination page (optional).",
"Invoice Number, Reference, or Search Term.": "Invoice Number, Reference, or Search Term.",
"Item Code or Name (exact match).": "Item Code or Name (exact match).",
"e.g. Name or Name DESC": "e.g. Name or Name DESC",
"Number, Reference or ID depending on Search By.": "Number, Reference or ID depending on Search By.",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"Draft": "Draft",
"Submitted": "Submitted",
"Authorised": "Authorised",
"Deleted": "Deleted",
"Voided": "Voided",
"Exclusive": "Exclusive",
"Inclusive": "Inclusive",
"NoTax": "NoTax",
"Billed": "Billed",
"Quote": "Quote",
"Bank Transfer": "Bank Transfer",
"Bank Transaction": "Bank Transaction",
"Manual Journal": "Manual Journal",
"Receipt": "Receipt",
"Repeating Invoice": "Repeating Invoice",
"Accounts Receivable Credit (ACCRECCREDIT)": "Accounts Receivable Credit (ACCRECCREDIT)",
"Accounts Payable Credit (ACCPAYCREDIT)": "Accounts Payable Credit (ACCPAYCREDIT)",
"Weekly": "Weekly",
"Monthly": "Monthly",
"Name (exact match)": "Name (exact match)",
"Account Number (exact match)": "Account Number (exact match)",
"Search Term (broad search)": "Search Term (broad search)",
"Invoice Number (exact)": "Invoice Number (exact)",
"Reference (exact)": "Reference (exact)",
"Search Term (InvoiceNumber/Reference)": "Search Term (InvoiceNumber/Reference)",
"Sales Invoice (ACCREC)": "Sales Invoice (ACCREC)",
"Bill (ACCPAY)": "Bill (ACCPAY)",
"Code (exact)": "Code (exact)",
"Name (exact)": "Name (exact)",
"Purchase Order Number (exact)": "Purchase Order Number (exact)",
"Purchase Order ID (GUID)": "Purchase Order ID (GUID)",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Contact": "New Contact",
"New or Updated Contact": "New or Updated Contact",
"New Sales Invoice": "New Sales Invoice",
"Updated Sales Invoice": "Updated Sales Invoice",
"New Bank Transaction": "New Bank Transaction",
"New Payment": "New Payment",
"New Purchase Order": "New Purchase Order",
"New Reconciled Payment": "New Reconciled Payment",
"Updated Quote": "Updated Quote",
"New Bill": "New Bill",
"New Credit Note": "New Credit Note",
"New Project": "New Project",
"New Quote": "New Quote",
"Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.": "Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.",
"Fires when a contact is created or updated (via Xero webhooks).": "Fires when a contact is created or updated (via Xero webhooks).",
"Fires when a new sales invoice (Accounts Receivable) is created.": "Fires when a new sales invoice (Accounts Receivable) is created.",
"Fires when an existing sales invoice (Accounts Receivable) is updated.": "Fires when an existing sales invoice (Accounts Receivable) is updated.",
"Fires when a new bank transaction is created.": "Fires when a new bank transaction is created.",
"Fires when a payment is received.": "Fires when a payment is received.",
"Fires when a new purchase order is created or enters a specific status for the first time.": "Fires when a new purchase order is created or enters a specific status for the first time.",
"Fires when a payment is reconciled for the first time.": "Fires when a payment is reconciled for the first time.",
"Fires when a quote is created or updated.": "Fires when a quote is created or updated.",
"Fires when a new bill (Accounts Payable) is added.": "Fires when a new bill (Accounts Payable) is added.",
"Fires when a new credit note is created.": "Fires when a new credit note is created.",
"Fires when a new project is created.": "Fires when a new project is created.",
"Fires when a new quote is created.": "Fires when a new quote is created.",
"Markdown": "Markdown",
"Webhook Key": "Webhook Key",
"Fetch Full Contact": "Fetch Full Contact",
"Fetch Full Invoice": "Fetch Full Invoice",
"Types": "Types",
"Bank Account Code": "Bank Account Code",
"Payment Types": "Payment Types",
"Filter by Status (optional)": "Filter by Status (optional)",
"First-time Status (optional)": "First-time Status (optional)",
"Quote Number (partial match)": "Quote Number (partial match)",
"Expiry Date From (YYYY-MM-DD)": "Expiry Date From (YYYY-MM-DD)",
"Expiry Date To (YYYY-MM-DD)": "Expiry Date To (YYYY-MM-DD)",
"Statuses (optional)": "Statuses (optional)",
"Summary Only (lighter, faster)": "Summary Only (lighter, faster)",
"States (optional)": "States (optional)",
"Page Size (1-500)": "Page Size (1-500)",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.": "From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.",
"If enabled, fetches the full contact from Xero using the Resource URL.": "If enabled, fetches the full contact from Xero using the Resource URL.",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"Fetch the full invoice and ensure Type is ACCREC (recommended).": "Fetch the full invoice and ensure Type is ACCREC (recommended).",
"Also fire when a purchase order enters this status for the first time (since enabling).": "Also fire when a purchase order enters this status for the first time (since enabling).",
"RECEIVE": "RECEIVE",
"SPEND": "SPEND",
"RECEIVE-OVERPAYMENT": "RECEIVE-OVERPAYMENT",
"SPEND-OVERPAYMENT": "SPEND-OVERPAYMENT",
"RECEIVE-PREPAYMENT": "RECEIVE-PREPAYMENT",
"SPEND-PREPAYMENT": "SPEND-PREPAYMENT",
"RECEIVE-TRANSFER": "RECEIVE-TRANSFER",
"SPEND-TRANSFER": "SPEND-TRANSFER",
"AUTHORISED": "AUTHORISED",
"DELETED": "DELETED",
"ACCRECPAYMENT (Received on Sales Invoice)": "ACCRECPAYMENT (Received on Sales Invoice)",
"ACCPAYPAYMENT (Paid on Bill)": "ACCPAYPAYMENT (Paid on Bill)",
"DRAFT": "DRAFT",
"SUBMITTED": "SUBMITTED",
"BILLED": "BILLED",
"SENT": "SENT",
"ACCEPTED": "ACCEPTED",
"DECLINED": "DECLINED",
"INVOICED": "INVOICED",
"PAID": "PAID",
"VOIDED": "VOIDED",
"ACCRECCREDIT (Sales Credit)": "ACCRECCREDIT (Sales Credit)",
"ACCPAYCREDIT (Supplier Credit)": "ACCPAYCREDIT (Supplier Credit)",
"INPROGRESS": "INPROGRESS",
"CLOSED": "CLOSED"
}

View File

@@ -0,0 +1,48 @@
{
"Xero": "Xero",
"Beautiful accounting software": "Beautiful accounting software",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ",
"Create or Update Contact": "Create or Update Contact",
"Create or Update Invoice": "Create or Update Invoice",
"Custom API Call": "Custom API Call",
"Create Xero Contact": "Create Xero Contact",
"Create Xero Invoice": "Create Xero Invoice",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Organization": "Organization",
"Contact ID": "Contact ID",
"Contact Name": "Contact Name",
"Contact Email": "Contact Email",
"Invoice ID": "Invoice ID",
"Line Item": "Line Item",
"Date Prepared": "Date Prepared",
"Due Date": "Due Date",
"Invoice Reference": "Invoice Reference",
"Status": "Status",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"ID of the contact to create invoice for.": "ID of the contact to create invoice for.",
"Contact name, in full.": "Contact name, in full.",
"Email address of the contact.": "Email address of the contact.",
"ID of the invoice to update": "ID of the invoice to update",
"Invoice line items": "Invoice line items",
"Date the invoice was created. Format example: 2019-03-11": "Date the invoice was created. Format example: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "Due date of the invoice. Format example: 2019-03-11",
"Reference number of the Invoice": "Reference number of the Invoice",
"Invoice Status": "Invoice Status",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"Draft": "Bản nháp",
"Submitted": "Submitted",
"Authorised": "Authorised",
"Deleted": "Deleted",
"Voided": "Voided",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,320 @@
{
"Beautiful accounting software": "Beautiful accounting software",
"\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ": "\n 1. Log in to Xero.\n 2. Go to [Developer portal](https://developer.xero.com/app/manage/).\n 3. Click on the App you want to integrate.\n 4. On the left, click on `Configuration`.\n 5. Enter your `redirect url`.\n 6. Copy the `Client Id` and `Client Secret`.\n ",
"Create or Update Contact": "Create or Update Contact",
"Create or Update Invoice": "Create or Update Invoice",
"Allocate Credit Note to Invoice": "Allocate Credit Note to Invoice",
"Create Bank Transfer": "Create Bank Transfer",
"Create New Quote Draft": "Create New Quote Draft",
"Send Sales Invoice by Email": "Send Sales Invoice by Email",
"Create Bill": "Create Bill",
"Create Payment": "Create Payment",
"Create Purchase Order": "Create Purchase Order",
"Update Purchase Order": "Update Purchase Order",
"Upload Attachment": "Upload Attachment",
"Add Items to Existing Sales Invoice": "Add Items to Existing Sales Invoice",
"Create Credit Note": "Create Credit Note",
"Create Inventory Item": "Create Inventory Item",
"Create Project": "Create Project",
"Update Sales Invoice": "Update Sales Invoice",
"Create Repeating Sales Invoice": "Create Repeating Sales Invoice",
"Find Contact": "Find Contact",
"Find Invoice": "Find Invoice",
"Find Item": "Find Item",
"Find Purchase Order": "Find Purchase Order",
"Custom API Call": "自定义 API 呼叫",
"Create Xero Contact": "Create Xero Contact",
"Create Xero Invoice": "Create Xero Invoice",
"Allocates a credit note to a specific invoice.": "Allocates a credit note to a specific invoice.",
"Transfers money between two bank accounts in Xero.": "Transfers money between two bank accounts in Xero.",
"Creates a new draft quote.": "Creates a new draft quote.",
"Sends a sales invoice via email to a contact.": "Sends a sales invoice via email to a contact.",
"Creates a new bill (Accounts Payable).": "Creates a new bill (Accounts Payable).",
"Applies a payment to an invoice.": "Applies a payment to an invoice.",
"Creates a new purchase order for a contact.": "Creates a new purchase order for a contact.",
"Updates details of an existing purchase order.": "Updates details of an existing purchase order.",
"Uploads an attachment to a specific Xero resource.": "Uploads an attachment to a specific Xero resource.",
"Adds line items to an existing sales invoice (ACCREC).": "Adds line items to an existing sales invoice (ACCREC).",
"Creates a new credit note for a contact.": "Creates a new credit note for a contact.",
"Creates a new inventory item in Xero.": "Creates a new inventory item in Xero.",
"Creates a new project for a contact.": "Creates a new project for a contact.",
"Updates details of an existing sales invoice (ACCREC).": "Updates details of an existing sales invoice (ACCREC).",
"Creates a repeating sales invoice (Accounts Receivable).": "Creates a repeating sales invoice (Accounts Receivable).",
"Finds a contact by name or account number (or SearchTerm).": "Finds a contact by name or account number (or SearchTerm).",
"Finds an invoice by number or reference.": "Finds an invoice by number or reference.",
"Finds an item by name or code.": "Finds an item by name or code.",
"Finds a purchase order by given parameters.": "Finds a purchase order by given parameters.",
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
"Organization": "Organization",
"Contact ID": "Contact ID",
"Contact Name": "Contact Name",
"Contact Email": "Contact Email",
"Invoice": "Invoice",
"Contact": "Contact",
"Line Item": "Line Item",
"Date Prepared": "Date Prepared",
"Due Date": "Due Date",
"Invoice Reference": "Invoice Reference",
"Status": "状态",
"Credit Note": "Credit Note",
"Amount": "Amount",
"Allocation Date": "Allocation Date",
"Bank Account": "Bank Account",
"Transfer Date": "Transfer Date",
"Reference": "Reference",
"From Is Reconciled": "From Is Reconciled",
"To Is Reconciled": "To Is Reconciled",
"Date": "Date",
"Expiry Date": "Expiry Date",
"Line Amount Types": "Line Amount Types",
"Quote Number": "Quote Number",
"Title": "标题",
"Summary": "Summary",
"Terms": "Terms",
"Sales Invoice (Sendable)": "Sales Invoice (Sendable)",
"Bill Number (Reference)": "Bill Number (Reference)",
"Invoice (Authorised)": "Invoice (Authorised)",
"Payment Date": "Payment Date",
"Is Reconciled": "Is Reconciled",
"Delivery Date": "Delivery Date",
"Purchase Order Number": "Purchase Order Number",
"Branding Theme": "Branding Theme",
"Delivery Address": "Delivery Address",
"Attention To": "Attention To",
"Telephone": "Telephone",
"Delivery Instructions": "Delivery Instructions",
"Expected Arrival Date": "Expected Arrival Date",
"Purchase Order": "Purchase Order",
"Mark as Sent to Contact": "Mark as Sent to Contact",
"Expected Arrival Date (YYYY-MM-DD)": "Expected Arrival Date (YYYY-MM-DD)",
"Resource Type": "Resource Type",
"Resource": "资源",
"File": "文件",
"File Name (override)": "File Name (override)",
"Content Type": "Content Type",
"Include with Online Invoice": "Include with Online Invoice",
"Allow AUTHORISED invoices": "Allow AUTHORISED invoices",
"New Line Items": "New Line Items",
"Type": "类型",
"Credit Note Number": "Credit Note Number",
"Reference (ACCRECCREDIT only)": "Reference (ACCRECCREDIT only)",
"Currency Code": "Currency Code",
"Line Items": "Line Items",
"Item Code": "Item Code",
"Name": "名称",
"Sales Description": "Sales Description",
"Purchase Description": "Purchase Description",
"Is Sold": "Is Sold",
"Is Purchased": "Is Purchased",
"Sales Details": "Sales Details",
"Account": "Account",
"Purchase Details": "Purchase Details",
"Project Name": "项目名称",
"Deadline (UTC ISO-8601)": "Deadline (UTC ISO-8601)",
"Estimate Amount": "Estimate Amount",
"Sales Invoice (Editable)": "Sales Invoice (Editable)",
"Due Date (YYYY-MM-DD)": "Due Date (YYYY-MM-DD)",
"Invoice Number": "Invoice Number",
"Source URL": "Source URL",
"Replace All Line Items": "Replace All Line Items",
"Line Items (updates/additions)": "Line Items (updates/additions)",
"Schedule Period": "Schedule Period",
"Schedule Unit": "Schedule Unit",
"Due Date (number)": "Due Date (number)",
"Due Date Type": "Due Date Type",
"Start Date (YYYY-MM-DD)": "Start Date (YYYY-MM-DD)",
"End Date (YYYY-MM-DD)": "End Date (YYYY-MM-DD)",
"Currency": "Currency",
"Approved For Sending": "Approved For Sending",
"Send Copy": "Send Copy",
"Mark As Sent": "Mark As Sent",
"Include PDF": "Include PDF",
"Search By": "Search By",
"Value": "值",
"Include Archived": "Include Archived",
"Summary Only (faster, lighter)": "Summary Only (faster, lighter)",
"Page": "Page",
"Type Filter": "Type Filter",
"Order (optional)": "Order (optional)",
"Statuses": "Statuses",
"Date From (YYYY-MM-DD)": "Date From (YYYY-MM-DD)",
"Date To (YYYY-MM-DD)": "Date To (YYYY-MM-DD)",
"Order (e.g., Date DESC)": "Order (e.g., Date DESC)",
"Page Size (1-1000)": "Page Size (1-1000)",
"Method": "方法",
"Headers": "信头",
"Query Parameters": "查询参数",
"Body": "正文内容",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "失败时没有错误",
"Timeout (in seconds)": "超时(秒)",
"ID of the contact to create invoice for.": "ID of the contact to create invoice for.",
"Contact name, in full.": "Contact name, in full.",
"Email address of the contact.": "Email address of the contact.",
"Select an invoice": "Select an invoice",
"Select a contact": "Select a contact",
"Invoice line items": "Invoice line items",
"Date the invoice was created. Format example: 2019-03-11": "Date the invoice was created. Format example: 2019-03-11",
"Due date of the invoice. Format example: 2019-03-11": "Due date of the invoice. Format example: 2019-03-11",
"Reference number of the Invoice": "Reference number of the Invoice",
"Invoice Status": "Invoice Status",
"Select a credit note to allocate from": "Select a credit note to allocate from",
"The amount of the credit to allocate.": "The amount of the credit to allocate.",
"Date of allocation. Format: YYYY-MM-DD. Optional.": "Date of allocation. Format: YYYY-MM-DD. Optional.",
"Select a bank account": "Select a bank account",
"Amount to transfer. Currencies must match between accounts.": "Amount to transfer. Currencies must match between accounts.",
"YYYY-MM-DD. Defaults to today if not provided.": "YYYY-MM-DD. Defaults to today if not provided.",
"Reference for the transfer.": "Reference for the transfer.",
"Mark source account transaction as reconciled.": "Mark source account transaction as reconciled.",
"Mark destination account transaction as reconciled.": "Mark destination account transaction as reconciled.",
"Date the quote was issued (YYYY-MM-DD).": "Date the quote was issued (YYYY-MM-DD).",
"Date the quote expires (YYYY-MM-DD).": "Date the quote expires (YYYY-MM-DD).",
"At minimum, provide a Description.": "At minimum, provide a Description.",
"Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).": "Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).",
"Date the bill was issued (YYYY-MM-DD). Optional.": "Date the bill was issued (YYYY-MM-DD). Optional.",
"Date the bill is due (YYYY-MM-DD). Optional.": "Date the bill is due (YYYY-MM-DD). Optional.",
"Select an authorised invoice (sales or bill) to apply payment to.": "Select an authorised invoice (sales or bill) to apply payment to.",
"Payment amount (must be <= amount due).": "Payment amount (must be <= amount due).",
"YYYY-MM-DD.": "YYYY-MM-DD.",
"Mark payment as reconciled (optional).": "Mark payment as reconciled (optional).",
"Date the purchase order was issued (YYYY-MM-DD). Optional.": "Date the purchase order was issued (YYYY-MM-DD). Optional.",
"Date goods are to be delivered (YYYY-MM-DD). Optional.": "Date goods are to be delivered (YYYY-MM-DD). Optional.",
"Select a branding theme": "Select a branding theme",
"YYYY-MM-DD. Optional.": "YYYY-MM-DD. Optional.",
"Select a purchase order to update": "Select a purchase order to update",
"The Xero resource to attach the file to.": "The Xero resource to attach the file to.",
"Select the specific resource to attach the file to.": "Select the specific resource to attach the file to.",
"The file to upload. Max 10MB per Xero limits.": "The file to upload. Max 10MB per Xero limits.",
"Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *": "Optional file name to use in Xero. Avoid characters: < > : \" / \\ | ? *",
"MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.": "MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.",
"Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.": "Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.",
"Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).",
"Add one or more line items. At minimum, each line needs a Description.": "Add one or more line items. At minimum, each line needs a Description.",
"Select an account": "Select an account",
"Example: 2017-04-23T18:25:43.511Z": "Example: 2017-04-23T18:25:43.511Z",
"Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).": "Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).",
"Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.": "Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.",
"If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.": "If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.",
"Integer period (e.g., 1 every week, 2 every month).": "Integer period (e.g., 1 every week, 2 every month).",
"Day number used with due date type (e.g., 20, 31).": "Day number used with due date type (e.g., 20, 31).",
"Select a currency code": "Select a currency code",
"Name, Account Number, or Search Term depending on Search By.": "Name, Account Number, or Search Term depending on Search By.",
"Recommended for broad searches (Search Term). Excludes heavy fields.": "Recommended for broad searches (Search Term). Excludes heavy fields.",
"Pagination page (optional).": "Pagination page (optional).",
"Invoice Number, Reference, or Search Term.": "Invoice Number, Reference, or Search Term.",
"Item Code or Name (exact match).": "Item Code or Name (exact match).",
"e.g. Name or Name DESC": "e.g. Name or Name DESC",
"Number, Reference or ID depending on Search By.": "Number, Reference or ID depending on Search By.",
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"Draft": "草稿",
"Submitted": "Submitted",
"Authorised": "Authorised",
"Deleted": "Deleted",
"Voided": "Voided",
"Exclusive": "Exclusive",
"Inclusive": "Inclusive",
"NoTax": "NoTax",
"Billed": "Billed",
"Quote": "Quote",
"Bank Transfer": "Bank Transfer",
"Bank Transaction": "Bank Transaction",
"Manual Journal": "Manual Journal",
"Receipt": "Receipt",
"Repeating Invoice": "Repeating Invoice",
"Accounts Receivable Credit (ACCRECCREDIT)": "Accounts Receivable Credit (ACCRECCREDIT)",
"Accounts Payable Credit (ACCPAYCREDIT)": "Accounts Payable Credit (ACCPAYCREDIT)",
"Weekly": "Weekly",
"Monthly": "Monthly",
"Name (exact match)": "Name (exact match)",
"Account Number (exact match)": "Account Number (exact match)",
"Search Term (broad search)": "Search Term (broad search)",
"Invoice Number (exact)": "Invoice Number (exact)",
"Reference (exact)": "Reference (exact)",
"Search Term (InvoiceNumber/Reference)": "Search Term (InvoiceNumber/Reference)",
"Sales Invoice (ACCREC)": "Sales Invoice (ACCREC)",
"Bill (ACCPAY)": "Bill (ACCPAY)",
"Code (exact)": "Code (exact)",
"Name (exact)": "Name (exact)",
"Purchase Order Number (exact)": "Purchase Order Number (exact)",
"Purchase Order ID (GUID)": "Purchase Order ID (GUID)",
"GET": "获取",
"POST": "帖子",
"PATCH": "PATCH",
"PUT": "弹出",
"DELETE": "删除",
"HEAD": "黑色",
"New Contact": "New Contact",
"New or Updated Contact": "New or Updated Contact",
"New Sales Invoice": "New Sales Invoice",
"Updated Sales Invoice": "Updated Sales Invoice",
"New Bank Transaction": "New Bank Transaction",
"New Payment": "New Payment",
"New Purchase Order": "New Purchase Order",
"New Reconciled Payment": "New Reconciled Payment",
"Updated Quote": "Updated Quote",
"New Bill": "New Bill",
"New Credit Note": "New Credit Note",
"New Project": "新建项目",
"New Quote": "New Quote",
"Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.": "Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.",
"Fires when a contact is created or updated (via Xero webhooks).": "Fires when a contact is created or updated (via Xero webhooks).",
"Fires when a new sales invoice (Accounts Receivable) is created.": "Fires when a new sales invoice (Accounts Receivable) is created.",
"Fires when an existing sales invoice (Accounts Receivable) is updated.": "Fires when an existing sales invoice (Accounts Receivable) is updated.",
"Fires when a new bank transaction is created.": "Fires when a new bank transaction is created.",
"Fires when a payment is received.": "Fires when a payment is received.",
"Fires when a new purchase order is created or enters a specific status for the first time.": "Fires when a new purchase order is created or enters a specific status for the first time.",
"Fires when a payment is reconciled for the first time.": "Fires when a payment is reconciled for the first time.",
"Fires when a quote is created or updated.": "Fires when a quote is created or updated.",
"Fires when a new bill (Accounts Payable) is added.": "Fires when a new bill (Accounts Payable) is added.",
"Fires when a new credit note is created.": "Fires when a new credit note is created.",
"Fires when a new project is created.": "Fires when a new project is created.",
"Fires when a new quote is created.": "Fires when a new quote is created.",
"Markdown": "Markdown",
"Webhook Key": "Webhook Key",
"Fetch Full Contact": "Fetch Full Contact",
"Fetch Full Invoice": "Fetch Full Invoice",
"Types": "Types",
"Bank Account Code": "Bank Account Code",
"Payment Types": "Payment Types",
"Filter by Status (optional)": "Filter by Status (optional)",
"First-time Status (optional)": "First-time Status (optional)",
"Quote Number (partial match)": "Quote Number (partial match)",
"Expiry Date From (YYYY-MM-DD)": "Expiry Date From (YYYY-MM-DD)",
"Expiry Date To (YYYY-MM-DD)": "Expiry Date To (YYYY-MM-DD)",
"Statuses (optional)": "Statuses (optional)",
"Summary Only (lighter, faster)": "Summary Only (lighter, faster)",
"States (optional)": "States (optional)",
"Page Size (1-500)": "Page Size (1-500)",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Contact category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.": "From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.",
"If enabled, fetches the full contact from Xero using the Resource URL.": "If enabled, fetches the full contact from Xero using the Resource URL.",
"\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains": "\nTo use this trigger, manually configure a Xero webhook for your app:\n\n1. Go to Xero Developer > My Apps > [Your App] > Webhooks.\n2. Select the Invoice category.\n3. Set the Delivery URL to:\n\n\n```text\n{{webhookUrl}}\n```\n4. Click Save, then click Validate \"Intent to receive\".\n5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.\n6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.\n\nNotes:\n- Keep this trigger enabled so the URL remains active.\n- We verify Xero's x-xero-signature header using your Webhook Key.\n ",
"Fetch the full invoice and ensure Type is ACCREC (recommended).": "Fetch the full invoice and ensure Type is ACCREC (recommended).",
"Also fire when a purchase order enters this status for the first time (since enabling).": "Also fire when a purchase order enters this status for the first time (since enabling).",
"RECEIVE": "RECEIVE",
"SPEND": "SPEND",
"RECEIVE-OVERPAYMENT": "RECEIVE-OVERPAYMENT",
"SPEND-OVERPAYMENT": "SPEND-OVERPAYMENT",
"RECEIVE-PREPAYMENT": "RECEIVE-PREPAYMENT",
"SPEND-PREPAYMENT": "SPEND-PREPAYMENT",
"RECEIVE-TRANSFER": "RECEIVE-TRANSFER",
"SPEND-TRANSFER": "SPEND-TRANSFER",
"AUTHORISED": "AUTHORISED",
"DELETED": "DELETED",
"ACCRECPAYMENT (Received on Sales Invoice)": "ACCRECPAYMENT (Received on Sales Invoice)",
"ACCPAYPAYMENT (Paid on Bill)": "ACCPAYPAYMENT (Paid on Bill)",
"DRAFT": "DRAFT",
"SUBMITTED": "SUBMITTED",
"BILLED": "BILLED",
"SENT": "SENT",
"ACCEPTED": "ACCEPTED",
"DECLINED": "DECLINED",
"INVOICED": "INVOICED",
"PAID": "PAID",
"VOIDED": "VOIDED",
"ACCRECCREDIT (Sales Credit)": "ACCRECCREDIT (Sales Credit)",
"ACCPAYCREDIT (Supplier Credit)": "ACCPAYCREDIT (Supplier Credit)",
"INPROGRESS": "INPROGRESS",
"CLOSED": "CLOSED"
}

View File

@@ -0,0 +1,125 @@
import { createCustomApiCallAction } from '@activepieces/pieces-common';
import {
OAuth2PropertyValue,
PieceAuth,
createPiece,
} from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { xeroCreateContact } from './lib/actions/create-contact';
import { xeroCreateInvoice } from './lib/actions/create-invoice';
import { xeroAllocateCreditNoteToInvoice } from './lib/actions/allocate-credit-note-to-invoice';
import { xeroCreateBankTransfer } from './lib/actions/create-bank-transfer';
import { xeroCreateQuoteDraft } from './lib/actions/create-quote-draft';
import { xeroSendInvoiceEmail } from './lib/actions/send-invoice-email';
import { xeroCreateBill } from './lib/actions/create-bill';
import { xeroCreatePayment } from './lib/actions/create-payment';
import { xeroCreatePurchaseOrder } from './lib/actions/create-purchase-order';
import { xeroUpdatePurchaseOrder } from './lib/actions/update-purchase-order';
import { xeroUploadAttachment } from './lib/actions/upload-attachment';
import { xeroAddItemsToSalesInvoice } from './lib/actions/add-items-to-sales-invoice';
import { xeroCreateCreditNote } from './lib/actions/create-credit-note';
import { xeroCreateInventoryItem } from './lib/actions/create-inventory-item';
import { xeroCreateProject } from './lib/actions/create-project';
import { xeroUpdateSalesInvoice } from './lib/actions/update-sales-invoice';
import { xeroCreateRepeatingSalesInvoice } from './lib/actions/create-repeating-sales-invoice';
import { xeroFindContact } from './lib/actions/find-contact';
import { xeroFindInvoice } from './lib/actions/find-invoice';
import { xeroFindItem } from './lib/actions/find-item';
import { xeroFindPurchaseOrder } from './lib/actions/find-purchase-order';
import { xeroNewContact } from './lib/triggers/new-contact';
import { xeroNewOrUpdatedContact } from './lib/triggers/new-or-updated-contact';
import { xeroNewSalesInvoice } from './lib/triggers/new-sales-invoice';
import { xeroUpdatedSalesInvoice } from './lib/triggers/updated-sales-invoice';
import { xeroNewBankTransaction } from './lib/triggers/new-bank-transaction';
import { xeroNewPayment } from './lib/triggers/new-payment';
import { xeroNewPurchaseOrder } from './lib/triggers/new-purchase-order';
import { xeroNewReconciledPayment } from './lib/triggers/new-reconciled-payment';
import { xeroUpdatedQuote } from './lib/triggers/updated-quote';
import { xeroNewBill } from './lib/triggers/new-bill';
import { xeroNewCreditNote } from './lib/triggers/new-credit-note';
import { xeroNewProject } from './lib/triggers/new-project';
import { xeroNewQuote } from './lib/triggers/new-quote';
export const xeroAuth = PieceAuth.OAuth2({
description: `
1. Log in to Xero.
2. Go to [Developer portal](https://developer.xero.com/app/manage/).
3. Click on the App you want to integrate.
4. On the left, click on \`Configuration\`.
5. Enter your \`redirect url\`.
6. Copy the \`Client Id\` and \`Client Secret\`.
`,
authUrl: 'https://login.xero.com/identity/connect/authorize',
tokenUrl: 'https://identity.xero.com/connect/token',
required: true,
scope: [
'openid',
'profile',
'email',
'offline_access',
'accounting.contacts',
'accounting.transactions',
'accounting.reports.read',
'accounting.journals.read',
'accounting.budgets.read',
'accounting.attachments',
'accounting.settings',
'projects',
],
});
export const xero = createPiece({
displayName: 'Xero',
description: 'Beautiful accounting software',
minimumSupportedRelease: '0.30.0',
logoUrl: 'https://cdn.activepieces.com/pieces/xero.png',
authors: ['kanarelo', 'kishanprmr', 'MoShizzle', 'khaledmashaly', 'abuaboud', 'thejaachi'],
categories: [PieceCategory.ACCOUNTING],
auth: xeroAuth,
actions: [
xeroCreateContact,
xeroCreateInvoice,
xeroAllocateCreditNoteToInvoice,
xeroCreateBankTransfer,
xeroCreateQuoteDraft,
xeroSendInvoiceEmail,
xeroCreateBill,
xeroCreatePayment,
xeroCreatePurchaseOrder,
xeroUpdatePurchaseOrder,
xeroUploadAttachment,
xeroAddItemsToSalesInvoice,
xeroCreateCreditNote,
xeroCreateInventoryItem,
xeroCreateProject,
xeroUpdateSalesInvoice,
xeroCreateRepeatingSalesInvoice,
xeroFindContact,
xeroFindInvoice,
xeroFindItem,
xeroFindPurchaseOrder,
createCustomApiCallAction({
baseUrl: () => 'https://api.xero.com/api.xro/2.0',
auth: xeroAuth,
authMapping: async (auth) => ({
Authorization: `Bearer ${(auth as OAuth2PropertyValue).access_token}`,
}),
}),
],
triggers: [
xeroNewContact,
xeroNewOrUpdatedContact,
xeroNewSalesInvoice,
xeroUpdatedSalesInvoice,
xeroNewBankTransaction,
xeroNewPayment,
xeroNewPurchaseOrder,
xeroNewReconciledPayment,
xeroUpdatedQuote,
xeroNewBill,
xeroNewCreditNote,
xeroNewProject,
xeroNewQuote,
],
});

View File

@@ -0,0 +1,112 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroAddItemsToSalesInvoice = createAction({
auth: xeroAuth,
name: 'xero_add_items_to_sales_invoice',
displayName: 'Add Items to Existing Sales Invoice',
description: 'Adds line items to an existing sales invoice (ACCREC).',
props: {
tenant_id: props.tenant_id,
invoice_id: props.invoice_id(true),
allow_authorised: Property.Checkbox({
displayName: 'Allow AUTHORISED invoices',
description: 'Enable adding items to AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).',
required: false,
defaultValue: false,
}),
new_line_items: Property.Array({
displayName: 'New Line Items',
required: true,
properties: {
Description: Property.ShortText({ displayName: 'Description', required: true }),
Quantity: Property.Number({ displayName: 'Quantity', required: false }),
UnitAmount: Property.Number({ displayName: 'Unit Amount', required: false }),
AccountCode: Property.ShortText({ displayName: 'Account Code', required: false }),
ItemCode: Property.ShortText({ displayName: 'Item Code', required: false }),
TaxType: Property.ShortText({ displayName: 'Tax Type', required: false }),
DiscountRate: Property.Number({ displayName: 'Discount %', required: false }),
},
}),
},
async run(context) {
const { tenant_id, invoice_id, new_line_items } = context.propsValue as {
tenant_id: string;
invoice_id: string;
new_line_items: Record<string, unknown>[];
};
const getUrl = `https://api.xero.com/api.xro/2.0/Invoices/${invoice_id}`;
const getRequest: HttpRequest = {
method: HttpMethod.GET,
url: getUrl,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: { 'Xero-Tenant-Id': tenant_id },
};
const getResp = await httpClient.sendRequest<any>(getRequest);
if (getResp.status !== 200) {
return getResp;
}
const existingInvoice = getResp.body?.Invoices?.[0];
if (!existingInvoice) {
throw new Error('Invoice not found.');
}
const existingLineItems = (existingInvoice.LineItems || []).map((li: any) => ({
LineItemID: li.LineItemID,
Description: li.Description,
Quantity: li.Quantity,
UnitAmount: li.UnitAmount,
AccountCode: li.AccountCode,
TaxType: li.TaxType,
DiscountRate: li.DiscountRate,
ItemCode: li.ItemCode,
Tracking: li.Tracking,
}));
const mergedLineItems = [
...existingLineItems,
...new_line_items,
];
const postUrl = `https://api.xero.com/api.xro/2.0/Invoices/${invoice_id}`;
const body = {
Invoices: [
{
Type: 'ACCREC',
LineItems: mergedLineItems,
},
],
};
const postRequest: HttpRequest = {
method: HttpMethod.POST,
url: postUrl,
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: { 'Xero-Tenant-Id': tenant_id },
};
const updateResp = await httpClient.sendRequest(postRequest);
if (updateResp.status === 200) {
return updateResp.body;
}
return updateResp;
},
});

View File

@@ -0,0 +1,70 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroAllocateCreditNoteToInvoice = createAction({
auth: xeroAuth,
name: 'xero_allocate_credit_note_to_invoice',
displayName: 'Allocate Credit Note to Invoice',
description: 'Allocates a credit note to a specific invoice.',
props: {
tenant_id: props.tenant_id,
credit_note_id: props.credit_note_id(true),
invoice_id: props.invoice_id(true),
amount: Property.Number({
displayName: 'Amount',
description: 'The amount of the credit to allocate.',
required: true,
}),
date: Property.ShortText({
displayName: 'Allocation Date',
description: 'Date of allocation. Format: YYYY-MM-DD. Optional.',
required: false,
}),
},
async run(context) {
const { tenant_id, credit_note_id, invoice_id, amount, date } =
context.propsValue;
const url = `https://api.xero.com/api.xro/2.0/CreditNotes/${credit_note_id}/Allocations`;
const body: Record<string, unknown> = {
Allocations: [
{
Invoice: {
InvoiceID: invoice_id,
},
Amount: amount,
...(date ? { Date: date } : {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,97 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroCreateBankTransfer = createAction({
auth: xeroAuth,
name: 'xero_create_bank_transfer',
displayName: 'Create Bank Transfer',
description: 'Transfers money between two bank accounts in Xero.',
props: {
tenant_id: props.tenant_id,
from_bank_account_id: props.bank_account_id(true),
to_bank_account_id: props.bank_account_id(true),
amount: Property.Number({
displayName: 'Amount',
description: 'Amount to transfer. Currencies must match between accounts.',
required: true,
}),
date: Property.ShortText({
displayName: 'Transfer Date',
description: 'YYYY-MM-DD. Defaults to today if not provided.',
required: false,
}),
reference: Property.ShortText({
displayName: 'Reference',
description: 'Reference for the transfer.',
required: false,
}),
from_is_reconciled: Property.Checkbox({
displayName: 'From Is Reconciled',
description: 'Mark source account transaction as reconciled.',
required: false,
defaultValue: false,
}),
to_is_reconciled: Property.Checkbox({
displayName: 'To Is Reconciled',
description: 'Mark destination account transaction as reconciled.',
required: false,
defaultValue: false,
}),
},
async run(context) {
const {
tenant_id,
from_bank_account_id,
to_bank_account_id,
amount,
date,
reference,
from_is_reconciled,
to_is_reconciled,
} = context.propsValue;
const url = 'https://api.xero.com/api.xro/2.0/BankTransfers';
const payload: Record<string, unknown> = {
BankTransfers: [
{
FromBankAccount: { AccountID: from_bank_account_id },
ToBankAccount: { AccountID: to_bank_account_id },
Amount: amount,
...(date ? { Date: date } : {}),
...(reference ? { Reference: reference } : {}),
...(from_is_reconciled ? { FromIsReconciled: true } : {}),
...(to_is_reconciled ? { ToIsReconciled: true } : {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.PUT,
url,
body: payload,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,115 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroCreateBill = createAction({
auth: xeroAuth,
name: 'xero_create_bill',
displayName: 'Create Bill',
description: 'Creates a new bill (Accounts Payable).',
props: {
tenant_id: props.tenant_id,
contact_id: props.contact_dropdown(true),
line_item: Property.Object({
displayName: 'Line Item',
description: 'At minimum, provide a Description.',
required: true,
defaultValue: {
Description: 'Goods/Services',
},
}),
date: Property.ShortText({
displayName: 'Date',
description: 'Date the bill was issued (YYYY-MM-DD). Optional.',
required: false,
}),
due_date: Property.ShortText({
displayName: 'Due Date',
description: 'Date the bill is due (YYYY-MM-DD). Optional.',
required: false,
}),
line_amount_types: Property.StaticDropdown({
displayName: 'Line Amount Types',
required: false,
options: {
options: [
{ label: 'Exclusive', value: 'Exclusive' },
{ label: 'Inclusive', value: 'Inclusive' },
{ label: 'NoTax', value: 'NoTax' },
],
},
}),
invoice_number: Property.ShortText({
displayName: 'Bill Number (Reference)',
required: false,
}),
status: Property.StaticDropdown({
displayName: 'Status',
required: false,
options: {
options: [
{ label: 'Draft', value: 'DRAFT' },
{ label: 'Submitted', value: 'SUBMITTED' },
{ label: 'Authorised', value: 'AUTHORISED' },
],
},
defaultValue: 'DRAFT',
}),
},
async run(context) {
const {
tenant_id,
contact_id,
line_item,
date,
due_date,
line_amount_types,
invoice_number,
status,
} = context.propsValue;
const url = 'https://api.xero.com/api.xro/2.0/Invoices';
const payload: Record<string, unknown> = {
Invoices: [
{
Type: 'ACCPAY',
Contact: { ContactID: contact_id },
LineItems: [line_item],
...(date ? { Date: date } : {}),
...(due_date ? { DueDate: due_date } : {}),
...(line_amount_types ? { LineAmountTypes: line_amount_types } : {}),
...(invoice_number ? { InvoiceNumber: invoice_number } : {}),
...(status ? { Status: status } : {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body: payload,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,56 @@
import { createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
import { xeroAuth } from '../..';
export const xeroCreateContact = createAction({
auth: xeroAuth,
name: 'xero_create_contact',
description: 'Create Xero Contact',
displayName: 'Create or Update Contact',
props: {
tenant_id: props.tenant_id,
contact_id: props.contact_id(false),
name: props.contact_name(true),
email: props.contact_email(false),
},
async run(context) {
const { name, email, contact_id, tenant_id } = context.propsValue;
const body = {
Contacts: [
{
Name: name,
EmailAddress: email,
},
],
};
const url = 'https://api.xero.com/api.xro/2.0/Contacts';
const request: HttpRequest = {
method: HttpMethod.POST,
url: contact_id ? `${url}/${contact_id}` : url,
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
console.debug('Contact creation response', result);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,141 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroCreateCreditNote = createAction({
auth: xeroAuth,
name: 'xero_create_credit_note',
displayName: 'Create Credit Note',
description: 'Creates a new credit note for a contact.',
props: {
tenant_id: props.tenant_id,
type: Property.StaticDropdown({
displayName: 'Type',
required: true,
options: {
options: [
{ label: 'Accounts Receivable Credit (ACCRECCREDIT)', value: 'ACCRECCREDIT' },
{ label: 'Accounts Payable Credit (ACCPAYCREDIT)', value: 'ACCPAYCREDIT' },
],
},
defaultValue: 'ACCRECCREDIT',
}),
contact_id: props.contact_dropdown(true),
date: Property.ShortText({
displayName: 'Date',
description: 'YYYY-MM-DD. Defaults to today if not provided.',
required: false,
}),
status: Property.StaticDropdown({
displayName: 'Status',
required: false,
options: {
options: [
{ label: 'Draft', value: 'DRAFT' },
{ label: 'Authorised', value: 'AUTHORISED' },
],
},
defaultValue: 'DRAFT',
}),
line_amount_types: Property.StaticDropdown({
displayName: 'Line Amount Types',
required: false,
options: {
options: [
{ label: 'Exclusive', value: 'Exclusive' },
{ label: 'Inclusive', value: 'Inclusive' },
{ label: 'NoTax', value: 'NoTax' },
],
},
}),
credit_note_number: Property.ShortText({
displayName: 'Credit Note Number',
required: false,
}),
reference: Property.ShortText({
displayName: 'Reference (ACCRECCREDIT only)',
required: false,
}),
currency_code: Property.ShortText({
displayName: 'Currency Code',
required: false,
}),
branding_theme_id: props.branding_theme_id(false),
line_items: Property.Array({
displayName: 'Line Items',
description: 'Add one or more line items. At minimum, each line needs a Description.',
required: false,
properties: {
Description: Property.ShortText({ displayName: 'Description', required: true }),
Quantity: Property.Number({ displayName: 'Quantity', required: false }),
UnitAmount: Property.Number({ displayName: 'Unit Amount', required: false }),
AccountCode: Property.ShortText({ displayName: 'Account Code', required: false }),
ItemCode: Property.ShortText({ displayName: 'Item Code', required: false }),
TaxType: Property.ShortText({ displayName: 'Tax Type', required: false }),
},
}),
},
async run(context) {
const {
tenant_id,
type,
contact_id,
date,
status,
line_amount_types,
credit_note_number,
reference,
currency_code,
branding_theme_id,
line_items,
} = context.propsValue;
const url = 'https://api.xero.com/api.xro/2.0/CreditNotes';
const payload: Record<string, unknown> = {
CreditNotes: [
{
Type: type,
Contact: { ContactID: contact_id },
...(date ? { Date: date } : {}),
...(status ? { Status: status } : {}),
...(line_amount_types ? { LineAmountTypes: line_amount_types } : {}),
...(currency_code ? { CurrencyCode: currency_code } : {}),
...(credit_note_number ? { CreditNoteNumber: credit_note_number } : {}),
...(reference && type === 'ACCRECCREDIT' ? { Reference: reference } : {}),
...(branding_theme_id ? { BrandingThemeID: branding_theme_id } : {}),
...(line_items && Array.isArray(line_items) && line_items.length > 0
? { LineItems: line_items }
: {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body: payload,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,129 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroCreateInventoryItem = createAction({
auth: xeroAuth,
name: 'xero_create_inventory_item',
displayName: 'Create Inventory Item',
description: 'Creates a new inventory item in Xero.',
props: {
tenant_id: props.tenant_id,
code: Property.ShortText({
displayName: 'Item Code',
required: true,
}),
name: Property.ShortText({
displayName: 'Name',
required: false,
}),
description: Property.LongText({
displayName: 'Sales Description',
required: false,
}),
purchase_description: Property.LongText({
displayName: 'Purchase Description',
required: false,
}),
is_sold: Property.Checkbox({
displayName: 'Is Sold',
required: false,
defaultValue: true,
}),
is_purchased: Property.Checkbox({
displayName: 'Is Purchased',
required: false,
defaultValue: true,
}),
sales_details: Property.Object({
displayName: 'Sales Details',
required: false,
defaultValue: {
UnitPrice: 0,
},
}),
sales_account_id: props.account_code(['REVENUE'], false),
purchase_details: Property.Object({
displayName: 'Purchase Details',
required: false,
defaultValue: {
UnitPrice: 0,
},
}),
purchase_account_id: props.account_code(['EXPENSE'], false),
cogs_account_id: props.account_code(['COGS'], false),
inventory_asset_account_id: props.account_code(['INVENTORY'], false),
},
async run(context) {
const {
tenant_id,
code,
name,
description,
purchase_description,
is_sold,
is_purchased,
sales_details,
purchase_details,
sales_account_id,
purchase_account_id,
cogs_account_id,
inventory_asset_account_id,
} = context.propsValue;
const url = 'https://api.xero.com/api.xro/2.0/Items';
const item: Record<string, unknown> = {
Code: code,
...(name ? { Name: name } : {}),
...(typeof is_sold === 'boolean' ? { IsSold: is_sold } : {}),
...(typeof is_purchased === 'boolean' ? { IsPurchased: is_purchased } : {}),
...(description ? { Description: description } : {}),
...(purchase_description ? { PurchaseDescription: purchase_description } : {}),
...(sales_details || sales_account_id
? { SalesDetails: { ...(sales_details ?? {}), ...(sales_account_id ? { AccountID: sales_account_id } : {}) } }
: {}),
...(purchase_details || purchase_account_id || cogs_account_id
? {
PurchaseDetails: {
...(purchase_details ?? {}),
...(purchase_account_id ? { AccountID: purchase_account_id } : {}),
...(cogs_account_id ? { COGSAccountID: cogs_account_id } : {}),
},
}
: {}),
...(inventory_asset_account_id
? { InventoryAssetAccountCode: undefined, InventoryAssetAccountID: inventory_asset_account_id }
: {}),
};
const payload = item;
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body: payload,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,113 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
import dayjs from 'dayjs';
import { xeroAuth } from '../..';
export const xeroCreateInvoice = createAction({
auth: xeroAuth,
name: 'xero_create_invoice',
description: 'Create Xero Invoice',
displayName: 'Create or Update Invoice',
props: {
tenant_id: props.tenant_id,
invoice_id: props.invoice_id(false),
contact_id: props.contact_dropdown(false),
name: props.contact_name(true),
email: props.contact_email(false),
line_item: Property.Object({
displayName: 'Line Item',
description: 'Invoice line items',
required: true,
defaultValue: {
AccountCode: 200,
Quantity: 0,
UnitAmount: 0,
LineAmount: 0,
TaxType: 'NONE',
Description: 'description',
},
}),
date: Property.ShortText({
displayName: 'Date Prepared',
description: 'Date the invoice was created. Format example: 2019-03-11',
required: false,
}),
due_date: Property.ShortText({
displayName: 'Due Date',
description: 'Due date of the invoice. Format example: 2019-03-11',
defaultValue: dayjs().format('YYYY-MM-DD'),
required: true,
}),
reference: Property.ShortText({
displayName: 'Invoice Reference',
description: 'Reference number of the Invoice',
required: false,
}),
status: Property.StaticDropdown({
displayName: 'Status',
description: 'Invoice Status',
required: true,
options: {
options: [
{ label: 'Draft', value: 'DRAFT' },
{ label: 'Submitted', value: 'SUBMITTED' },
{ label: 'Authorised', value: 'AUTHORISED' },
{ label: 'Deleted', value: 'DELETED' },
{ label: 'Voided', value: 'VOIDED' },
],
},
}),
},
async run(context) {
const { invoice_id, contact_id, email, name, tenant_id, ...invoice } =
context.propsValue;
const contact: Record<string, unknown> = { Name: name };
if (email) contact['EmailAddress'] = email;
if (contact_id) contact['ContactID'] = contact_id;
const body = {
Invoices: [
{
Type: 'ACCREC',
Contact: contact,
LineItems: invoice.line_item ? [invoice.line_item] : [],
Date: invoice.date,
DueDate: invoice.due_date,
Reference: invoice.reference,
Status: invoice.status,
},
],
};
const url = 'https://api.xero.com/api.xro/2.0/Invoices';
const request: HttpRequest = {
method: HttpMethod.POST,
url: invoice_id ? `${url}/${invoice_id}` : url,
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
console.debug('Invoice creation response', result);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,81 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroCreatePayment = createAction({
auth: xeroAuth,
name: 'xero_create_payment',
displayName: 'Create Payment',
description: 'Applies a payment to an invoice.',
props: {
tenant_id: props.tenant_id,
invoice_id: props.payable_invoice_id(true),
account_id: props.bank_account_id(true),
amount: Property.Number({
displayName: 'Amount',
description: 'Payment amount (must be <= amount due).',
required: true,
}),
date: Property.ShortText({
displayName: 'Payment Date',
description: 'YYYY-MM-DD.',
required: true,
}),
reference: Property.ShortText({
displayName: 'Reference',
required: false,
}),
is_reconciled: Property.Checkbox({
displayName: 'Is Reconciled',
description: 'Mark payment as reconciled (optional).',
required: false,
defaultValue: false,
}),
},
async run(context) {
const { tenant_id, invoice_id, account_id, amount, date, reference, is_reconciled } =
context.propsValue;
const url = 'https://api.xero.com/api.xro/2.0/Payments';
const payload: Record<string, unknown> = {
Payments: [
{
Invoice: { InvoiceID: invoice_id },
Account: { AccountID: account_id },
Date: date,
Amount: amount,
...(reference ? { Reference: reference } : {}),
...(is_reconciled ? { IsReconciled: true } : {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.PUT,
url,
body: payload,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,68 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroCreateProject = createAction({
auth: xeroAuth,
name: 'xero_create_project',
displayName: 'Create Project',
description: 'Creates a new project for a contact.',
props: {
tenant_id: props.tenant_id,
contact_id: props.contact_dropdown(true),
name: Property.ShortText({
displayName: 'Project Name',
required: true,
}),
deadline_utc: Property.ShortText({
displayName: 'Deadline (UTC ISO-8601)',
description: 'Example: 2017-04-23T18:25:43.511Z',
required: false,
}),
estimate_amount: Property.Number({
displayName: 'Estimate Amount',
required: false,
}),
},
async run(context) {
const { tenant_id, contact_id, name, deadline_utc, estimate_amount } =
context.propsValue;
const url = 'https://api.xero.com/projects.xro/2.0/Projects';
const body: Record<string, unknown> = {
contactId: contact_id,
name,
...(deadline_utc ? { deadlineUtc: deadline_utc } : {}),
...(typeof estimate_amount === 'number' ? { estimateAmount: estimate_amount } : {}),
};
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
'Content-Type': 'application/json',
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200 || result.status === 201) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,156 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroCreatePurchaseOrder = createAction({
auth: xeroAuth,
name: 'xero_create_purchase_order',
displayName: 'Create Purchase Order',
description: 'Creates a new purchase order for a contact.',
props: {
tenant_id: props.tenant_id,
contact_id: props.contact_dropdown(true),
line_item: Property.Object({
displayName: 'Line Item',
description: 'At minimum, provide a Description.',
required: true,
defaultValue: {
Description: 'Item',
},
}),
date: Property.ShortText({
displayName: 'Date',
description: 'Date the purchase order was issued (YYYY-MM-DD). Optional.',
required: false,
}),
delivery_date: Property.ShortText({
displayName: 'Delivery Date',
description: 'Date goods are to be delivered (YYYY-MM-DD). Optional.',
required: false,
}),
line_amount_types: Property.StaticDropdown({
displayName: 'Line Amount Types',
required: false,
options: {
options: [
{ label: 'Exclusive', value: 'Exclusive' },
{ label: 'Inclusive', value: 'Inclusive' },
{ label: 'NoTax', value: 'NoTax' },
],
},
}),
purchase_order_number: Property.ShortText({
displayName: 'Purchase Order Number',
required: false,
}),
reference: Property.ShortText({
displayName: 'Reference',
required: false,
}),
branding_theme_id: props.branding_theme_id(false),
status: Property.StaticDropdown({
displayName: 'Status',
required: false,
options: {
options: [
{ label: 'Draft', value: 'DRAFT' },
{ label: 'Submitted', value: 'SUBMITTED' },
{ label: 'Authorised', value: 'AUTHORISED' },
{ label: 'Billed', value: 'BILLED' },
{ label: 'Deleted', value: 'DELETED' },
],
},
defaultValue: 'DRAFT',
}),
delivery_address: Property.LongText({
displayName: 'Delivery Address',
required: false,
}),
attention_to: Property.ShortText({
displayName: 'Attention To',
required: false,
}),
telephone: Property.ShortText({
displayName: 'Telephone',
required: false,
}),
delivery_instructions: Property.LongText({
displayName: 'Delivery Instructions',
required: false,
}),
expected_arrival_date: Property.ShortText({
displayName: 'Expected Arrival Date',
description: 'YYYY-MM-DD. Optional.',
required: false,
}),
},
async run(context) {
const {
tenant_id,
contact_id,
line_item,
date,
delivery_date,
line_amount_types,
purchase_order_number,
reference,
branding_theme_id,
status,
delivery_address,
attention_to,
telephone,
delivery_instructions,
expected_arrival_date,
} = context.propsValue;
const url = 'https://api.xero.com/api.xro/2.0/PurchaseOrders';
const payload: Record<string, unknown> = {
PurchaseOrders: [
{
Contact: { ContactID: contact_id },
LineItems: [line_item],
...(date ? { Date: date } : {}),
...(delivery_date ? { DeliveryDate: delivery_date } : {}),
...(line_amount_types ? { LineAmountTypes: line_amount_types } : {}),
...(purchase_order_number ? { PurchaseOrderNumber: purchase_order_number } : {}),
...(reference ? { Reference: reference } : {}),
...(branding_theme_id ? { BrandingThemeID: branding_theme_id } : {}),
...(status ? { Status: status } : {}),
...(delivery_address ? { DeliveryAddress: delivery_address } : {}),
...(attention_to ? { AttentionTo: attention_to } : {}),
...(telephone ? { Telephone: telephone } : {}),
...(delivery_instructions ? { DeliveryInstructions: delivery_instructions } : {}),
...(expected_arrival_date ? { ExpectedArrivalDate: expected_arrival_date } : {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body: payload,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,136 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroCreateQuoteDraft = createAction({
auth: xeroAuth,
name: 'xero_create_quote_draft',
displayName: 'Create New Quote Draft',
description: 'Creates a new draft quote.',
props: {
tenant_id: props.tenant_id,
contact_id: props.contact_dropdown(true),
date: Property.ShortText({
displayName: 'Date',
description: 'Date the quote was issued (YYYY-MM-DD).',
required: true,
}),
expiry_date: Property.ShortText({
displayName: 'Expiry Date',
description: 'Date the quote expires (YYYY-MM-DD).',
required: false,
}),
line_item: Property.Object({
displayName: 'Line Item',
description: 'At minimum, provide a Description.',
required: true,
defaultValue: {
Description: 'Consulting services',
},
}),
line_amount_types: Property.StaticDropdown({
displayName: 'Line Amount Types',
required: false,
options: {
options: [
{ label: 'Exclusive', value: 'Exclusive' },
{ label: 'Inclusive', value: 'Inclusive' },
{ label: 'NoTax', value: 'NoTax' },
],
},
}),
reference: Property.ShortText({
displayName: 'Reference',
required: false,
}),
quote_number: Property.ShortText({
displayName: 'Quote Number',
required: false,
}),
title: Property.ShortText({
displayName: 'Title',
required: false,
}),
summary: Property.LongText({
displayName: 'Summary',
required: false,
}),
terms: Property.LongText({
displayName: 'Terms',
required: false,
}),
status: Property.StaticDropdown({
displayName: 'Status',
required: false,
options: {
options: [
{ label: 'Draft', value: 'DRAFT' },
],
},
defaultValue: 'DRAFT',
}),
},
async run(context) {
const {
tenant_id,
contact_id,
date,
expiry_date,
line_item,
line_amount_types,
reference,
quote_number,
title,
summary,
terms,
status,
} = context.propsValue;
const url = 'https://api.xero.com/api.xro/2.0/Quotes';
const payload: Record<string, unknown> = {
Quotes: [
{
Contact: { ContactID: contact_id },
Date: date,
...(expiry_date ? { ExpiryDate: expiry_date } : {}),
LineItems: [line_item],
...(line_amount_types ? { LineAmountTypes: line_amount_types } : {}),
...(reference ? { Reference: reference } : {}),
...(quote_number ? { QuoteNumber: quote_number } : {}),
...(title ? { Title: title } : {}),
...(summary ? { Summary: summary } : {}),
...(terms ? { Terms: terms } : {}),
...(status ? { Status: status } : {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body: payload,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,197 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroCreateRepeatingSalesInvoice = createAction({
auth: xeroAuth,
name: 'xero_create_repeating_sales_invoice',
displayName: 'Create Repeating Sales Invoice',
description: 'Creates a repeating sales invoice (Accounts Receivable).',
props: {
tenant_id: props.tenant_id,
contact_id: props.contact_dropdown(true),
schedule_period: Property.Number({
displayName: 'Schedule Period',
description: 'Integer period (e.g., 1 every week, 2 every month).',
required: true,
}),
schedule_unit: Property.StaticDropdown({
displayName: 'Schedule Unit',
required: true,
options: { options: [
{ label: 'Weekly', value: 'WEEKLY' },
{ label: 'Monthly', value: 'MONTHLY' },
]},
}),
due_date: Property.Number({
displayName: 'Due Date (number)',
description: 'Day number used with due date type (e.g., 20, 31).',
required: true,
}),
due_date_type: Property.Dropdown({
auth: xeroAuth,
displayName: 'Due Date Type',
required: true,
refreshers: ['schedule_unit'],
options: async ({ propsValue, schedule_unit }) => {
const unitRaw = schedule_unit ?? (propsValue as Record<string, any>)?.['schedule_unit'];
const unit = typeof unitRaw === 'string' ? unitRaw : unitRaw?.value;
const all = [
{ label: 'Of Current Month', value: 'OFCURRENTMONTH' },
{ label: 'Of Following Month', value: 'OFFOLLOWINGMONTH' },
{ label: 'Days After Bill Date', value: 'DAYSAFTERBILLDATE' },
{ label: 'Days After Bill Month', value: 'DAYSAFTERBILLMONTH' },
];
let options = all;
if (unit === 'WEEKLY') {
options = all.filter((o) => o.value === 'DAYSAFTERBILLDATE' || o.value === 'OFFOLLOWINGMONTH');
} else if (unit === 'MONTHLY') {
options = all.filter((o) => o.value === 'OFCURRENTMONTH' || o.value === 'OFFOLLOWINGMONTH');
}
return { disabled: false, options };
},
}),
start_date: Property.ShortText({
displayName: 'Start Date (YYYY-MM-DD)',
required: true,
}),
end_date: Property.ShortText({
displayName: 'End Date (YYYY-MM-DD)',
required: false,
}),
line_amount_types: Property.StaticDropdown({
displayName: 'Line Amount Types',
required: true,
options: {
options: [
{ label: 'Exclusive', value: 'Exclusive' },
{ label: 'Inclusive', value: 'Inclusive' },
{ label: 'NoTax', value: 'NoTax' },
],
},
defaultValue: 'Exclusive',
}),
currency_code: props.currency_code(true),
status: Property.StaticDropdown({
displayName: 'Status',
required: true,
options: { options: [
{ label: 'Draft', value: 'DRAFT' },
{ label: 'Authorised', value: 'AUTHORISED' },
]},
defaultValue: 'DRAFT',
}),
reference: Property.ShortText({ displayName: 'Reference', required: false }),
branding_theme_id: props.branding_theme_id(false),
approved_for_sending: Property.Checkbox({ displayName: 'Approved For Sending', required: false, defaultValue: false }),
send_copy: Property.Checkbox({ displayName: 'Send Copy', required: false, defaultValue: false }),
mark_as_sent: Property.Checkbox({ displayName: 'Mark As Sent', required: false, defaultValue: false }),
include_pdf: Property.Checkbox({ displayName: 'Include PDF', required: false, defaultValue: false }),
line_items: Property.Array({
displayName: 'Line Items',
required: true,
properties: {
Description: Property.ShortText({ displayName: 'Description', required: true }),
Quantity: Property.Number({ displayName: 'Quantity', required: false }),
UnitAmount: Property.Number({ displayName: 'Unit Amount', required: false }),
AccountCode: Property.ShortText({ displayName: 'Account Code', required: false }),
ItemCode: Property.ShortText({ displayName: 'Item Code', required: false }),
TaxType: Property.ShortText({ displayName: 'Tax Type', required: false }),
DiscountRate: Property.Number({ displayName: 'Discount %', required: false }),
},
}),
},
async run(context) {
const {
tenant_id,
contact_id,
schedule_period,
schedule_unit,
due_date,
due_date_type,
start_date,
end_date,
line_amount_types,
currency_code,
status,
reference,
branding_theme_id,
approved_for_sending,
send_copy,
mark_as_sent,
include_pdf,
line_items,
} = context.propsValue as any;
const url = 'https://api.xero.com/api.xro/2.0/RepeatingInvoices';
if (
schedule_unit === 'WEEKLY' &&
!['DAYSAFTERBILLDATE', 'OFFOLLOWINGMONTH'].includes(due_date_type)
) {
throw new Error(
'For weekly schedules, Due Date Type must be DAYSAFTERBILLDATE or OFFOLLOWINGMONTH.'
);
}
if (
schedule_unit === 'MONTHLY' &&
!['OFCURRENTMONTH', 'OFFOLLOWINGMONTH'].includes(due_date_type)
) {
throw new Error(
'For monthly schedules, Due Date Type must be OFCURRENTMONTH or OFFOLLOWINGMONTH.'
);
}
const payload = {
RepeatingInvoices: [
{
Type: 'ACCREC',
Contact: { ContactID: contact_id },
Schedule: {
Period: schedule_period,
Unit: schedule_unit,
DueDate: due_date,
DueDateType: due_date_type,
StartDate: start_date,
...(end_date ? { EndDate: end_date } : {}),
},
LineItems: line_items,
LineAmountTypes: line_amount_types,
CurrencyCode: currency_code,
Status: status,
...(reference ? { Reference: reference } : {}),
...(branding_theme_id ? { BrandingThemeID: branding_theme_id } : {}),
...(approved_for_sending ? { ApprovedForSending: true } : {}),
...(send_copy ? { SendCopy: true } : {}),
...(mark_as_sent ? { MarkAsSent: true } : {}),
...(include_pdf ? { IncludePDF: true } : {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body: payload,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: { 'Xero-Tenant-Id': tenant_id },
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,101 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroFindContact = createAction({
auth: xeroAuth,
name: 'xero_find_contact',
displayName: 'Find Contact',
description: 'Finds a contact by name or account number (or SearchTerm).',
props: {
tenant_id: props.tenant_id,
search_by: Property.StaticDropdown({
displayName: 'Search By',
required: true,
options: {
options: [
{ label: 'Name (exact match)', value: 'NAME' },
{ label: 'Account Number (exact match)', value: 'ACCOUNT_NUMBER' },
{ label: 'Search Term (broad search)', value: 'SEARCH_TERM' },
],
},
defaultValue: 'NAME',
}),
value: Property.ShortText({
displayName: 'Value',
description: 'Name, Account Number, or Search Term depending on Search By.',
required: true,
}),
include_archived: Property.Checkbox({
displayName: 'Include Archived',
required: false,
defaultValue: false,
}),
summary_only: Property.Checkbox({
displayName: 'Summary Only (faster, lighter)',
description: 'Recommended for broad searches (Search Term). Excludes heavy fields.',
required: false,
defaultValue: true,
}),
page: Property.Number({
displayName: 'Page',
description: 'Pagination page (optional).',
required: false,
}),
},
async run(context) {
const {
tenant_id,
search_by,
value,
include_archived,
summary_only,
page,
} = context.propsValue as any;
const baseUrl = 'https://api.xero.com/api.xro/2.0/Contacts';
const params: string[] = [];
if (include_archived) params.push('includeArchived=true');
if (summary_only) params.push('summaryOnly=true');
if (page) params.push(`page=${encodeURIComponent(page)}`);
if (search_by === 'SEARCH_TERM') {
params.push(`SearchTerm=${encodeURIComponent(value)}`);
} else if (search_by === 'NAME') {
const where = `Name="${value.replace(/"/g, '\\"')}"`;
params.push(`where=${encodeURIComponent(where)}`);
} else if (search_by === 'ACCOUNT_NUMBER') {
const where = `AccountNumber="${value.replace(/"/g, '\\"')}"`;
params.push(`where=${encodeURIComponent(where)}`);
}
const url = params.length ? `${baseUrl}?${params.join('&')}` : baseUrl;
const request: HttpRequest = {
method: HttpMethod.GET,
url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,101 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroFindInvoice = createAction({
auth: xeroAuth,
name: 'xero_find_invoice',
displayName: 'Find Invoice',
description: 'Finds an invoice by number or reference.',
props: {
tenant_id: props.tenant_id,
search_by: Property.StaticDropdown({
displayName: 'Search By',
required: true,
options: {
options: [
{ label: 'Invoice Number (exact)', value: 'INVOICE_NUMBER' },
{ label: 'Reference (exact)', value: 'REFERENCE' },
{ label: 'Search Term (InvoiceNumber/Reference)', value: 'SEARCH_TERM' },
],
},
defaultValue: 'INVOICE_NUMBER',
}),
value: Property.ShortText({
displayName: 'Value',
description: 'Invoice Number, Reference, or Search Term.',
required: true,
}),
type_filter: Property.StaticDropdown({
displayName: 'Type Filter',
required: false,
options: {
options: [
{ label: 'Sales Invoice (ACCREC)', value: 'ACCREC' },
{ label: 'Bill (ACCPAY)', value: 'ACCPAY' },
],
},
}),
summary_only: Property.Checkbox({
displayName: 'Summary Only (faster, lighter)',
required: false,
defaultValue: true,
}),
page: Property.Number({ displayName: 'Page', required: false }),
},
async run(context) {
const { tenant_id, search_by, value, type_filter, summary_only, page } =
context.propsValue as any;
const baseUrl = 'https://api.xero.com/api.xro/2.0/Invoices';
const params: string[] = [];
if (summary_only) params.push('summaryOnly=true');
if (page) params.push(`page=${encodeURIComponent(page)}`);
// Build where clause
const whereClauses: string[] = [];
if (type_filter) {
whereClauses.push(`Type=="${type_filter}"`);
}
if (search_by === 'INVOICE_NUMBER') {
whereClauses.push(`InvoiceNumber="${value.replace(/"/g, '\\"')}"`);
} else if (search_by === 'REFERENCE') {
whereClauses.push(`Reference="${value.replace(/"/g, '\\"')}"`);
} else if (search_by === 'SEARCH_TERM') {
params.push(`SearchTerm=${encodeURIComponent(value)}`);
}
if (whereClauses.length > 0) {
const where = whereClauses.join(' AND ');
params.push(`where=${encodeURIComponent(where)}`);
}
const url = params.length ? `${baseUrl}?${params.join('&')}` : baseUrl;
const request: HttpRequest = {
method: HttpMethod.GET,
url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: { 'Xero-Tenant-Id': tenant_id },
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,71 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroFindItem = createAction({
auth: xeroAuth,
name: 'xero_find_item',
displayName: 'Find Item',
description: 'Finds an item by name or code.',
props: {
tenant_id: props.tenant_id,
search_by: Property.StaticDropdown({
displayName: 'Search By',
required: true,
options: {
options: [
{ label: 'Code (exact)', value: 'CODE' },
{ label: 'Name (exact)', value: 'NAME' },
],
},
defaultValue: 'CODE',
}),
value: Property.ShortText({
displayName: 'Value',
description: 'Item Code or Name (exact match).',
required: true,
}),
order: Property.ShortText({
displayName: 'Order (optional)',
description: 'e.g. Name or Name DESC',
required: false,
}),
},
async run(context) {
const { tenant_id, search_by, value, order } = context.propsValue as any;
const baseUrl = 'https://api.xero.com/api.xro/2.0/Items';
const whereField = search_by === 'CODE' ? 'Code' : 'Name';
const where = `${whereField}="${String(value).replace(/"/g, '\\"')}"`;
const params: string[] = [`where=${encodeURIComponent(where)}`];
if (order) params.push(`order=${encodeURIComponent(order)}`);
const url = `${baseUrl}?${params.join('&')}`;
const request: HttpRequest = {
method: HttpMethod.GET,
url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,144 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroFindPurchaseOrder = createAction({
auth: xeroAuth,
name: 'xero_find_purchase_order',
displayName: 'Find Purchase Order',
description: 'Finds a purchase order by given parameters.',
props: {
tenant_id: props.tenant_id,
contact_id: props.contact_dropdown(false),
search_by: Property.StaticDropdown({
displayName: 'Search By',
required: true,
options: {
options: [
{ label: 'Purchase Order Number (exact)', value: 'NUMBER' },
{ label: 'Reference (exact)', value: 'REFERENCE' },
{ label: 'Purchase Order ID (GUID)', value: 'ID' },
],
},
defaultValue: 'NUMBER',
}),
value: Property.ShortText({
displayName: 'Value',
description: 'Number, Reference or ID depending on Search By.',
required: true,
}),
statuses: Property.StaticMultiSelectDropdown({
displayName: 'Statuses',
required: false,
options: {
options: [
{ label: 'Draft', value: 'DRAFT' },
{ label: 'Submitted', value: 'SUBMITTED' },
{ label: 'Authorised', value: 'AUTHORISED' },
{ label: 'Billed', value: 'BILLED' },
{ label: 'Deleted', value: 'DELETED' },
],
},
}),
date_from: Property.ShortText({
displayName: 'Date From (YYYY-MM-DD)',
required: false,
}),
date_to: Property.ShortText({
displayName: 'Date To (YYYY-MM-DD)',
required: false,
}),
order: Property.ShortText({ displayName: 'Order (e.g., Date DESC)', required: false }),
page: Property.Number({ displayName: 'Page', required: false }),
page_size: Property.Number({ displayName: 'Page Size (1-1000)', required: false }),
},
async run(context) {
const {
tenant_id,
contact_id,
search_by,
value,
statuses,
date_from,
date_to,
order,
page,
page_size,
} = context.propsValue as any;
const baseUrl = 'https://api.xero.com/api.xro/2.0/PurchaseOrders';
// If searching by ID, use record filter path for efficiency
if (search_by === 'ID') {
const url = `${baseUrl}/${encodeURIComponent(value)}`;
const request: HttpRequest = {
method: HttpMethod.GET,
url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: { 'Xero-Tenant-Id': tenant_id },
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) return result.body;
return result;
}
const params: string[] = [];
if (Array.isArray(statuses) && statuses.length === 1) {
params.push(`status=${encodeURIComponent(statuses[0])}`);
}
if (date_from) params.push(`DateFrom=${encodeURIComponent(date_from)}`);
if (date_to) params.push(`DateTo=${encodeURIComponent(date_to)}`);
if (order) params.push(`order=${encodeURIComponent(order)}`);
if (page) params.push(`page=${encodeURIComponent(page)}`);
if (page_size) params.push(`pageSize=${encodeURIComponent(page_size)}`);
// Equality filter using where for non-ID searches
const whereClauses: string[] = [];
if (search_by === 'NUMBER') {
whereClauses.push(`PurchaseOrderNumber=="${String(value).replace(/"/g, '\\"')}"`);
} else if (search_by === 'REFERENCE') {
whereClauses.push(`Reference=="${String(value).replace(/"/g, '\\"')}"`);
}
if (contact_id) {
whereClauses.push(`Contact.ContactID==guid("${contact_id}")`);
}
if (Array.isArray(statuses) && statuses.length > 1) {
const orStatuses = statuses.map((s: string) => `Status=="${s}"`).join(' OR ');
whereClauses.push(`(${orStatuses})`);
}
if (whereClauses.length > 0) {
params.push(`where=${encodeURIComponent(whereClauses.join(' AND '))}`);
}
const url = params.length ? `${baseUrl}?${params.join('&')}` : baseUrl;
const request: HttpRequest = {
method: HttpMethod.GET,
url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,46 @@
import { createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroSendInvoiceEmail = createAction({
auth: xeroAuth,
name: 'xero_send_invoice_email',
displayName: 'Send Sales Invoice by Email',
description: 'Sends a sales invoice via email to a contact.',
props: {
tenant_id: props.tenant_id,
invoice_id: props.sales_invoice_id(true),
},
async run(context) {
const { tenant_id, invoice_id } = context.propsValue;
const url = `https://api.xero.com/api.xro/2.0/Invoices/${invoice_id}/Email`;
const request: HttpRequest = {
method: HttpMethod.POST,
url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
// Xero returns 204 on success
if (result.status === 204) {
return { success: true };
}
return result;
},
});

View File

@@ -0,0 +1,116 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroUpdatePurchaseOrder = createAction({
auth: xeroAuth,
name: 'xero_update_purchase_order',
displayName: 'Update Purchase Order',
description: 'Updates details of an existing purchase order.',
props: {
tenant_id: props.tenant_id,
purchase_order_id: props.purchase_order_id(true),
status: Property.StaticDropdown({
displayName: 'Status',
required: false,
options: {
options: [
{ label: 'Draft', value: 'DRAFT' },
{ label: 'Submitted', value: 'SUBMITTED' },
{ label: 'Authorised', value: 'AUTHORISED' },
{ label: 'Billed', value: 'BILLED' },
{ label: 'Deleted', value: 'DELETED' },
],
},
}),
sent_to_contact: Property.Checkbox({
displayName: 'Mark as Sent to Contact',
required: false,
defaultValue: false,
}),
delivery_address: Property.LongText({
displayName: 'Delivery Address',
required: false,
}),
attention_to: Property.ShortText({
displayName: 'Attention To',
required: false,
}),
telephone: Property.ShortText({
displayName: 'Telephone',
required: false,
}),
delivery_instructions: Property.LongText({
displayName: 'Delivery Instructions',
required: false,
}),
expected_arrival_date: Property.ShortText({
displayName: 'Expected Arrival Date (YYYY-MM-DD)',
required: false,
}),
},
async run(context) {
const {
tenant_id,
purchase_order_id,
status,
sent_to_contact,
delivery_address,
attention_to,
telephone,
delivery_instructions,
expected_arrival_date,
} = context.propsValue;
const baseUrl = 'https://api.xero.com/api.xro/2.0/PurchaseOrders';
const url = `${baseUrl}/${purchase_order_id}`;
const body: Record<string, unknown> = {
PurchaseOrders: [
{
PurchaseOrderID: purchase_order_id,
...(status ? { Status: status } : {}),
...(typeof sent_to_contact === 'boolean'
? { SentToContact: sent_to_contact }
: {}),
...(delivery_address ? { DeliveryAddress: delivery_address } : {}),
...(attention_to ? { AttentionTo: attention_to } : {}),
...(telephone ? { Telephone: telephone } : {}),
...(delivery_instructions
? { DeliveryInstructions: delivery_instructions }
: {}),
...(expected_arrival_date
? { ExpectedArrivalDate: expected_arrival_date }
: {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,193 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
export const xeroUpdateSalesInvoice = createAction({
auth: xeroAuth,
name: 'xero_update_sales_invoice',
displayName: 'Update Sales Invoice',
description: 'Updates details of an existing sales invoice (ACCREC).',
props: {
tenant_id: props.tenant_id,
allow_authorised: Property.Checkbox({
displayName: 'Allow AUTHORISED invoices',
description:
'Enable updates for AUTHORISED invoices (Xero allows limited updates for paid/part-paid ACCREC).',
required: false,
defaultValue: false,
}),
invoice_id: props.editable_sales_invoice_id(true),
reference: Property.ShortText({ displayName: 'Reference', required: false }),
due_date: Property.ShortText({
displayName: 'Due Date (YYYY-MM-DD)',
required: false,
}),
invoice_number: Property.ShortText({
displayName: 'Invoice Number',
required: false,
}),
branding_theme_id: props.branding_theme_id(false),
url: Property.ShortText({ displayName: 'Source URL', required: false }),
contact_id: props.contact_dropdown(false),
status: Property.StaticDropdown({
displayName: 'Status',
required: false,
options: {
options: [
{ label: 'Draft', value: 'DRAFT' },
{ label: 'Submitted', value: 'SUBMITTED' },
{ label: 'Authorised', value: 'AUTHORISED' },
{ label: 'Voided', value: 'VOIDED' },
{ label: 'Deleted', value: 'DELETED' },
],
},
}),
sent_to_contact: Property.Checkbox({
displayName: 'Mark as Sent to Contact',
required: false,
defaultValue: false,
}),
replace_all_line_items: Property.Checkbox({
displayName: 'Replace All Line Items',
description:
'If enabled, only the provided line_items will remain. If disabled, we will merge with current lines by updating matching LineItemID and appending new items.',
required: false,
defaultValue: false,
}),
line_items: Property.Array({
displayName: 'Line Items (updates/additions)',
required: false,
properties: {
LineItemID: Property.ShortText({ displayName: 'LineItemID', required: false }),
Description: Property.ShortText({ displayName: 'Description', required: false }),
Quantity: Property.Number({ displayName: 'Quantity', required: false }),
UnitAmount: Property.Number({ displayName: 'Unit Amount', required: false }),
AccountCode: Property.ShortText({ displayName: 'Account Code', required: false }),
ItemCode: Property.ShortText({ displayName: 'Item Code', required: false }),
TaxType: Property.ShortText({ displayName: 'Tax Type', required: false }),
DiscountRate: Property.Number({ displayName: 'Discount %', required: false }),
},
}),
},
async run(context) {
const {
tenant_id,
invoice_id,
reference,
due_date,
invoice_number,
branding_theme_id,
url,
contact_id,
status,
sent_to_contact,
replace_all_line_items,
line_items,
} = context.propsValue as any;
const baseUrl = 'https://api.xero.com/api.xro/2.0/Invoices';
let finalLineItems: any[] | undefined = undefined;
if (Array.isArray(line_items) && line_items.length > 0) {
if (replace_all_line_items) {
finalLineItems = line_items;
} else {
// Fetch existing invoice to merge line items safely
const getReq: HttpRequest = {
method: HttpMethod.GET,
url: `${baseUrl}/${invoice_id}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: { 'Xero-Tenant-Id': tenant_id },
};
const getResp = await httpClient.sendRequest<any>(getReq);
if (getResp.status !== 200) {
return getResp;
}
const existing = getResp.body?.Invoices?.[0];
const existingLines: any[] = existing?.LineItems ?? [];
// Map existing by LineItemID for quick update
const idToExisting: Record<string, any> = {};
for (const li of existingLines) {
if (li.LineItemID) idToExisting[li.LineItemID] = li;
}
// Start with existing lines
const merged: any[] = existingLines.map((li) => ({
LineItemID: li.LineItemID,
Description: li.Description,
Quantity: li.Quantity,
UnitAmount: li.UnitAmount,
AccountCode: li.AccountCode,
TaxType: li.TaxType,
DiscountRate: li.DiscountRate,
ItemCode: li.ItemCode,
Tracking: li.Tracking,
}));
// Apply updates and collect new lines
for (const upd of line_items) {
if (upd.LineItemID && idToExisting[upd.LineItemID]) {
const idx = merged.findIndex((m) => m.LineItemID === upd.LineItemID);
if (idx >= 0) {
merged[idx] = { ...merged[idx], ...upd };
}
} else {
// New line (no LineItemID)
merged.push(upd);
}
}
finalLineItems = merged;
}
}
const body: Record<string, unknown> = {
Invoices: [
{
InvoiceID: invoice_id,
Type: 'ACCREC',
...(reference ? { Reference: reference } : {}),
...(due_date ? { DueDate: due_date } : {}),
...(invoice_number ? { InvoiceNumber: invoice_number } : {}),
...(branding_theme_id ? { BrandingThemeID: branding_theme_id } : {}),
...(url ? { Url: url } : {}),
...(contact_id ? { Contact: { ContactID: contact_id } } : {}),
...(status ? { Status: status } : {}),
...(typeof sent_to_contact === 'boolean' ? { SentToContact: sent_to_contact } : {}),
...(finalLineItems ? { LineItems: finalLineItems } : {}),
},
],
};
const request: HttpRequest = {
method: HttpMethod.POST,
url: `${baseUrl}/${invoice_id}`,
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,250 @@
import { Property, createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
import { props } from '../common/props';
type ResourceType =
| 'Invoices'
| 'CreditNotes'
| 'PurchaseOrders'
| 'Quotes'
| 'BankTransfers'
| 'BankTransactions'
| 'Contacts'
| 'Accounts'
| 'ManualJournals'
| 'Receipts'
| 'RepeatingInvoices';
export const xeroUploadAttachment = createAction({
auth: xeroAuth,
name: 'xero_upload_attachment',
displayName: 'Upload Attachment',
description: 'Uploads an attachment to a specific Xero resource.',
props: {
tenant_id: props.tenant_id,
resource_type: Property.StaticDropdown({
displayName: 'Resource Type',
description: 'The Xero resource to attach the file to.',
required: true,
options: {
options: [
{ label: 'Invoice', value: 'Invoices' },
{ label: 'Credit Note', value: 'CreditNotes' },
{ label: 'Purchase Order', value: 'PurchaseOrders' },
{ label: 'Quote', value: 'Quotes' },
{ label: 'Bank Transfer', value: 'BankTransfers' },
{ label: 'Bank Transaction', value: 'BankTransactions' },
{ label: 'Contact', value: 'Contacts' },
{ label: 'Account', value: 'Accounts' },
{ label: 'Manual Journal', value: 'ManualJournals' },
{ label: 'Receipt', value: 'Receipts' },
{ label: 'Repeating Invoice', value: 'RepeatingInvoices' },
],
},
}),
resource_id: Property.Dropdown({
auth: xeroAuth,
displayName: 'Resource',
description: 'Select the specific resource to attach the file to.',
required: true,
refreshers: ['tenant_id', 'resource_type'],
options: async ({ auth, propsValue, tenant_id, resource_type }) => {
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
const rawResourceType = resource_type ?? (propsValue as Record<string, any>)?.['resource_type'];
const resourceType = (typeof rawResourceType === 'string' ? rawResourceType : rawResourceType?.value) as ResourceType | undefined;
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
if (!resourceType)
return {
disabled: true,
options: [],
placeholder: 'Select a Resource Type',
};
const endpointMap: Record<ResourceType, { url: string; arrayKey: string; idKey: string; label: (item: any) => string }> = {
Invoices: {
url: 'https://api.xero.com/api.xro/2.0/Invoices?summaryOnly=true&page=1',
arrayKey: 'Invoices',
idKey: 'InvoiceID',
label: (inv) => [inv.InvoiceNumber || inv.InvoiceID, inv.Contact?.Name, inv.Status].filter(Boolean).join(' • '),
},
CreditNotes: {
url: 'https://api.xero.com/api.xro/2.0/CreditNotes',
arrayKey: 'CreditNotes',
idKey: 'CreditNoteID',
label: (cn) => [cn.CreditNoteNumber || cn.CreditNoteID, cn.Contact?.Name, cn.Type, cn.Status].filter(Boolean).join(' • '),
},
PurchaseOrders: {
url: 'https://api.xero.com/api.xro/2.0/PurchaseOrders?page=1',
arrayKey: 'PurchaseOrders',
idKey: 'PurchaseOrderID',
label: (po) => [po.PurchaseOrderNumber || po.PurchaseOrderID, po.Contact?.Name, po.Status].filter(Boolean).join(' • '),
},
Quotes: {
url: 'https://api.xero.com/api.xro/2.0/Quotes?page=1',
arrayKey: 'Quotes',
idKey: 'QuoteID',
label: (q) => [q.QuoteNumber || q.QuoteID, q.Contact?.Name, q.Status].filter(Boolean).join(' • '),
},
BankTransfers: {
url: 'https://api.xero.com/api.xro/2.0/BankTransfers',
arrayKey: 'BankTransfers',
idKey: 'BankTransferID',
label: (bt) => [bt.BankTransferID, bt.Amount ? `Amount ${bt.Amount}` : undefined].filter(Boolean).join(' • '),
},
BankTransactions: {
url: 'https://api.xero.com/api.xro/2.0/BankTransactions?page=1',
arrayKey: 'BankTransactions',
idKey: 'BankTransactionID',
label: (bt) => [bt.Type, bt.BankTransactionID, bt.Contact?.Name, bt.Amount].filter(Boolean).join(' • '),
},
Contacts: {
url: 'https://api.xero.com/api.xro/2.0/Contacts?summaryOnly=true&page=1',
arrayKey: 'Contacts',
idKey: 'ContactID',
label: (c) => [c.Name, c.EmailAddress].filter(Boolean).join(' • '),
},
Accounts: {
url: 'https://api.xero.com/api.xro/2.0/Accounts',
arrayKey: 'Accounts',
idKey: 'AccountID',
label: (a) => [a.Name || a.Code || a.AccountID, a.Code].filter(Boolean).join(' • '),
},
ManualJournals: {
url: 'https://api.xero.com/api.xro/2.0/ManualJournals?page=1',
arrayKey: 'ManualJournals',
idKey: 'ManualJournalID',
label: (mj) => [mj.ManualJournalID, mj.Date].filter(Boolean).join(' • '),
},
Receipts: {
url: 'https://api.xero.com/api.xro/2.0/Receipts?page=1',
arrayKey: 'Receipts',
idKey: 'ReceiptID',
label: (r) => [r.ReceiptID, r.Date, r.Total].filter(Boolean).join(' • '),
},
RepeatingInvoices: {
url: 'https://api.xero.com/api.xro/2.0/RepeatingInvoices?page=1',
arrayKey: 'RepeatingInvoices',
idKey: 'RepeatingInvoiceID',
label: (ri) => [ri.RepeatingInvoiceID, ri.Status].filter(Boolean).join(' • '),
},
};
const cfg = endpointMap[resourceType as ResourceType];
const request: HttpRequest = {
method: HttpMethod.GET,
url: cfg.url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const items: any[] = result.body?.[cfg.arrayKey] ?? [];
const options = items.slice(0, 100).map((item) => ({
label: cfg.label(item),
value: item[cfg.idKey],
}));
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load resources',
};
},
}),
file: Property.File({
displayName: 'File',
description: 'The file to upload. Max 10MB per Xero limits.',
required: true,
}),
file_name: Property.ShortText({
displayName: 'File Name (override)',
description: 'Optional file name to use in Xero. Avoid characters: < > : " / \\ | ? *',
required: false,
}),
content_type: Property.ShortText({
displayName: 'Content Type',
description: 'MIME type of the file (e.g., image/png). If not set, will be inferred or default to application/octet-stream.',
required: false,
}),
include_online: Property.Checkbox({
displayName: 'Include with Online Invoice',
description: 'Only applicable to ACCREC invoices and ACCREC credit notes. Adds IncludeOnline=true query parameter.',
required: false,
defaultValue: false,
}),
},
async run(context) {
const { tenant_id, resource_type, resource_id, file, file_name, content_type, include_online } =
context.propsValue as {
tenant_id: string;
resource_type: ResourceType;
resource_id: string;
file: { data: any; filename?: string; extension?: string };
file_name?: string;
content_type?: string;
include_online?: boolean;
};
const endpoint = resource_type as string;
const chosenFileName = file_name || file.filename || `attachment${file.extension ? '.' + file.extension : ''}`;
const inferredContentType = content_type || (file.extension ? `application/${file.extension}` : 'application/octet-stream');
const includeOnlineAllowed = resource_type === 'Invoices' || resource_type === 'CreditNotes';
const query = include_online && includeOnlineAllowed ? '?IncludeOnline=true' : '';
const encodedFileName = encodeURIComponent(chosenFileName);
const url = `https://api.xero.com/api.xro/2.0/${endpoint}/${resource_id}/Attachments/${encodedFileName}${query}`;
const request: HttpRequest = {
method: HttpMethod.POST,
url,
body: file.data,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': tenant_id,
'Content-Type': inferredContentType,
Accept: 'application/json',
},
};
const result = await httpClient.sendRequest(request);
if (result.status === 200) {
return result.body;
}
return result;
},
});

View File

@@ -0,0 +1,845 @@
import { OAuth2PropertyValue, Property } from '@activepieces/pieces-framework';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { xeroAuth } from '../..';
export const props = {
tenant_id: Property.Dropdown({
auth: xeroAuth,
displayName: 'Organization',
refreshers: [],
required: true,
options: async ({ auth }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/connections',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
};
const result = await httpClient.sendRequest<
{
id: string;
authEventId: string;
tenantId: string;
tenantType: string;
tenantName: string;
createdDateUtc: string;
updatedDateUtc: string;
}[]
>(request);
if (result.status === 200) {
return {
disabled: false,
options: [
{
label: result.body?.[0].tenantName,
value: result.body?.[0].tenantId,
},
],
};
}
return {
disabled: true,
options: [],
placeholder: 'Error processing tenant_id',
};
},
}),
invoice_id: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Invoice',
description: 'Select an invoice',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Invoices?summaryOnly=true&page=1',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const invoices: any[] = result.body?.Invoices ?? [];
const options = invoices.slice(0, 50).map((inv) => {
const labelParts = [inv.InvoiceNumber || inv.InvoiceID];
if (inv.Contact?.Name) labelParts.push(inv.Contact.Name);
if (inv.Status) labelParts.push(inv.Status);
return {
label: labelParts.filter(Boolean).join(' • '),
value: inv.InvoiceID,
};
});
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load invoices',
};
},
}),
payable_invoice_id: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Invoice (Authorised)',
description: 'Select an authorised invoice (sales or bill) to apply payment to.',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const url =
'https://api.xero.com/api.xro/2.0/Invoices?summaryOnly=true&page=1&Statuses=AUTHORISED';
const request: HttpRequest = {
method: HttpMethod.GET,
url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const invoices: any[] = result.body?.Invoices ?? [];
const options = invoices.slice(0, 50).map((inv) => {
const labelParts = [
inv.Type,
inv.InvoiceNumber || inv.InvoiceID,
inv.Contact?.Name,
inv.AmountDue ? `Due ${inv.AmountDue}` : undefined,
];
return {
label: labelParts.filter(Boolean).join(' • '),
value: inv.InvoiceID,
};
});
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load invoices',
};
},
}),
sales_invoice_id: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Sales Invoice (Sendable)',
description: 'Select a sales invoice with a valid status for sending email (SUBMITTED, AUTHORISED, or PAID).',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const url =
'https://api.xero.com/api.xro/2.0/Invoices?summaryOnly=true&page=1&Statuses=SUBMITTED,AUTHORISED,PAID&where=Type%3d%3d%22ACCREC%22';
const request: HttpRequest = {
method: HttpMethod.GET,
url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const invoices: any[] = result.body?.Invoices ?? [];
const options = invoices.slice(0, 50).map((inv) => {
const labelParts = [inv.InvoiceNumber || inv.InvoiceID];
if (inv.Contact?.Name) labelParts.push(inv.Contact.Name);
if (inv.Status) labelParts.push(inv.Status);
return {
label: labelParts.filter(Boolean).join(' • '),
value: inv.InvoiceID,
};
});
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load sales invoices',
};
},
}),
editable_sales_invoice_id: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Sales Invoice (Editable)',
description: 'Select a sales invoice (ACCREC) with DRAFT or SUBMITTED status.',
required,
refreshers: ['tenant_id', 'allow_authorised'],
options: async ({ auth, propsValue, tenant_id, allow_authorised }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const allowAuthorised = Boolean(
typeof allow_authorised !== 'undefined'
? allow_authorised
: (propsValue as Record<string, unknown>)?.['allow_authorised']
);
const statuses = allowAuthorised
? 'DRAFT,SUBMITTED,AUTHORISED'
: 'DRAFT,SUBMITTED';
const url =
`https://api.xero.com/api.xro/2.0/Invoices?summaryOnly=true&page=1&Statuses=${encodeURIComponent(statuses)}&where=Type%3d%3d%22ACCREC%22`;
const request: HttpRequest = {
method: HttpMethod.GET,
url,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const invoices: any[] = result.body?.Invoices ?? [];
const options = invoices.slice(0, 50).map((inv) => {
const labelParts = [inv.InvoiceNumber || inv.InvoiceID];
if (inv.Contact?.Name) labelParts.push(inv.Contact.Name);
if (inv.Status) labelParts.push(inv.Status);
return {
label: labelParts.filter(Boolean).join(' • '),
value: inv.InvoiceID,
};
});
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load sales invoices',
};
},
}),
credit_note_id: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Credit Note',
description: 'Select a credit note to allocate from',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/CreditNotes',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const creditNotes: any[] = result.body?.CreditNotes ?? [];
const options = creditNotes.slice(0, 50).map((cn) => {
const labelParts = [cn.CreditNoteNumber || cn.CreditNoteID];
if (cn.Contact?.Name) labelParts.push(cn.Contact.Name);
if (cn.Type) labelParts.push(cn.Type);
if (cn.Status) labelParts.push(cn.Status);
return {
label: labelParts.filter(Boolean).join(' • '),
value: cn.CreditNoteID,
};
});
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load credit notes',
};
},
}),
contact_id: (required = false) =>
Property.ShortText({
displayName: 'Contact ID',
description: 'ID of the contact to create invoice for.',
required: required,
}),
contact_dropdown: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Contact',
description: 'Select a contact',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Contacts?summaryOnly=true&page=1',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const contacts: any[] = result.body?.Contacts ?? [];
const options = contacts.slice(0, 100).map((c) => {
const labelParts = [c.Name];
if (c.EmailAddress) labelParts.push(c.EmailAddress);
return {
label: labelParts.filter(Boolean).join(' • '),
value: c.ContactID,
};
});
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load contacts',
};
},
}),
contact_name: (required = false) =>
Property.ShortText({
displayName: 'Contact Name',
description: 'Contact name, in full.',
required: required,
}),
contact_email: (required = false) =>
Property.ShortText({
displayName: 'Contact Email',
description: 'Email address of the contact.',
required: required,
}),
bank_account_id: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Bank Account',
description: 'Select a bank account',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Accounts',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const accounts: any[] = result.body?.Accounts ?? [];
const options = accounts
.filter(
(acc) => acc?.Type === 'BANK' || acc?.EnablePaymentsToAccount === true
)
.slice(0, 100)
.map((acc) => {
const labelParts = [acc.Name || acc.Code || acc.AccountID];
if (acc.Code) labelParts.push(acc.Code);
return {
label: labelParts.filter(Boolean).join(' • '),
value: acc.AccountID,
};
});
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load bank accounts',
};
},
}),
branding_theme_id: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Branding Theme',
description: 'Select a branding theme',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/BrandingThemes',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const themes: any[] = result.body?.BrandingThemes ?? [];
const options = themes.slice(0, 50).map((t) => ({
label: t.Name || t.BrandingThemeID,
value: t.BrandingThemeID,
}));
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load branding themes',
};
},
}),
purchase_order_id: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Purchase Order',
description: 'Select a purchase order to update',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/PurchaseOrders?page=1',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const pos: any[] = result.body?.PurchaseOrders ?? [];
const options = pos.slice(0, 100).map((po) => {
const labelParts = [
po.PurchaseOrderNumber || po.PurchaseOrderID,
po.Contact?.Name,
po.Status,
];
return {
label: labelParts.filter(Boolean).join(' • '),
value: po.PurchaseOrderID,
};
});
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load purchase orders',
};
},
}),
account_code: (allowedTypes: string[], required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Account',
description: 'Select an account',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Accounts',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const accounts: any[] = result.body?.Accounts ?? [];
const options = accounts
.filter((acc) =>
Array.isArray(allowedTypes)
? allowedTypes.includes(acc?.Type)
: true
)
.slice(0, 200)
.map((acc) => {
const labelParts = [acc.Name || acc.Code || acc.AccountID];
if (acc.Code) labelParts.push(acc.Code);
if (acc.Type) labelParts.push(acc.Type);
return {
label: labelParts.filter(Boolean).join(' • '),
value: acc.AccountID,
};
});
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load accounts',
};
},
}),
project_id: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Project',
description: 'Select a project',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/projects.xro/2.0/Projects?page=1',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const projects: any[] = result.body?.items ?? result.body?.Projects ?? [];
const options = projects.slice(0, 200).map((p) => ({
label: p.name || p.projectId,
value: p.projectId,
}));
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load projects',
};
},
}),
currency_code: (required = false) =>
Property.Dropdown({
auth: xeroAuth,
displayName: 'Currency',
description: 'Select a currency code',
required,
refreshers: ['tenant_id'],
options: async ({ auth, propsValue, tenant_id }) => {
if (!auth)
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
const rawTenant = tenant_id ?? (propsValue as Record<string, any>)?.['tenant_id'];
const tenantId: string | undefined =
typeof rawTenant === 'string'
? rawTenant
: rawTenant?.value || rawTenant?.tenantId || rawTenant?.id;
if (!tenantId)
return {
disabled: true,
options: [],
placeholder: 'Select an Organization first',
};
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Currencies',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth as OAuth2PropertyValue).access_token,
},
headers: {
'Xero-Tenant-Id': tenantId,
},
};
const result = await httpClient.sendRequest<Record<string, any>>(request);
if (result.status === 200) {
const currencies: any[] = result.body?.Currencies ?? [];
const options = currencies.slice(0, 300).map((c) => ({
label: `${c.Code}${c.Description ?? ''}`.trim(),
value: c.Code,
}));
return { disabled: false, options };
}
return {
disabled: true,
options: [],
placeholder: 'Unable to load currencies',
};
},
}),
};

View File

@@ -0,0 +1,198 @@
import {
TriggerStrategy,
createTrigger,
PiecePropValueSchema,
Property,
AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import {
DedupeStrategy,
httpClient,
HttpMethod,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
function parseXeroDateToEpoch(dateVal: unknown): number {
if (typeof dateVal === 'string') {
if (dateVal.includes('/Date(')) {
const match = /\/Date\((\d+)/.exec(dateVal);
if (match && match[1]) return Number(match[1]);
}
const t = Date.parse(dateVal);
if (!Number.isNaN(t)) return t;
}
if (typeof dateVal === 'number') return dateVal;
return Date.now();
}
const polling: Polling<
AppConnectionValueForAuthProperty<typeof xeroAuth>,
Record<string, unknown>
> = {
strategy: DedupeStrategy.TIMEBASED,
async items({ auth, lastFetchEpochMS, propsValue }) {
const { access_token } = auth;
const tenantId = propsValue?.['tenant_id'] as string;
const pageSize = (propsValue?.['page_size'] as number) || 200;
const types = (propsValue?.['types'] as string[]) || [];
const statuses = (propsValue?.['statuses'] as string[]) || [];
const contactId = propsValue?.['contact_id'] as string | undefined;
const bankAccountId = propsValue?.['bank_account_id'] as string | undefined;
const bankAccountCode = propsValue?.['bank_account_code'] as string | undefined;
const dateFrom = propsValue?.['date_from'] as string | undefined;
const dateTo = propsValue?.['date_to'] as string | undefined;
const whereClauses: string[] = [];
if (types.length === 1) whereClauses.push(`Type=="${types[0]}"`);
if (contactId) whereClauses.push(`Contact.ContactID==guid("${contactId}")`);
if (statuses.length === 1) whereClauses.push(`Status=="${statuses[0]}"`);
if (statuses.length > 1) whereClauses.push(`(${statuses.map((s) => `Status=="${s}"`).join(' OR ')})`);
if (dateFrom) {
const [y, m, d] = dateFrom.split('-');
whereClauses.push(`Date>=DateTime(${y}, ${m}, ${d})`);
}
if (dateTo) {
const [y, m, d] = dateTo.split('-');
whereClauses.push(`Date<DateTime(${y}, ${m}, ${d})`);
}
if (bankAccountCode) {
whereClauses.push(`BankAccount.Code=="${bankAccountCode.replace(/"/g, '\\"')}"`);
}
const results: any[] = [];
const maxPages = 5;
for (let page = 1; page <= maxPages; page++) {
const queryParams: Record<string, string> = {
page: String(page),
pageSize: String(pageSize),
order: 'UpdatedDateUTC ASC',
};
if (whereClauses.length > 0) {
queryParams['where'] = whereClauses.join(' AND ');
}
const requestHeaders: Record<string, string> = {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
'Xero-Tenant-Id': tenantId,
};
if (lastFetchEpochMS > 0) {
const ifModified = new Date(lastFetchEpochMS).toISOString().slice(0, 19);
requestHeaders['If-Modified-Since'] = ifModified;
}
const resp = await httpClient.sendRequest<Record<string, any>>({
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/BankTransactions',
headers: requestHeaders,
queryParams,
});
if (resp.status !== 200) {
break;
}
const bankTxns: any[] = resp.body?.BankTransactions ?? [];
let filtered = bankTxns;
if (bankAccountId) {
filtered = filtered.filter((t) => t?.BankAccount?.AccountID === bankAccountId);
}
if (bankAccountCode) {
filtered = filtered.filter((t) => t?.BankAccount?.Code === bankAccountCode);
}
for (const t of filtered) {
const epoch = parseXeroDateToEpoch(t.UpdatedDateUTC || t.Date);
results.push({ epochMilliSeconds: epoch, data: t });
}
if (bankTxns.length < pageSize) break;
}
return results;
},
};
export const xeroNewBankTransaction = createTrigger({
auth: xeroAuth,
name: 'xero_new_bank_transaction',
displayName: 'New Bank Transaction',
description: 'Fires when a new bank transaction is created.',
props: {
tenant_id: props.tenant_id,
types: Property.StaticMultiSelectDropdown({
displayName: 'Types',
required: false,
options: {
options: [
{ label: 'RECEIVE', value: 'RECEIVE' },
{ label: 'SPEND', value: 'SPEND' },
{ label: 'RECEIVE-OVERPAYMENT', value: 'RECEIVE-OVERPAYMENT' },
{ label: 'SPEND-OVERPAYMENT', value: 'SPEND-OVERPAYMENT' },
{ label: 'RECEIVE-PREPAYMENT', value: 'RECEIVE-PREPAYMENT' },
{ label: 'SPEND-PREPAYMENT', value: 'SPEND-PREPAYMENT' },
{ label: 'RECEIVE-TRANSFER', value: 'RECEIVE-TRANSFER' },
{ label: 'SPEND-TRANSFER', value: 'SPEND-TRANSFER' },
],
},
}),
statuses: Property.StaticMultiSelectDropdown({
displayName: 'Statuses',
required: false,
options: {
options: [
{ label: 'AUTHORISED', value: 'AUTHORISED' },
{ label: 'DELETED', value: 'DELETED' },
],
},
}),
contact_id: props.contact_dropdown(false),
bank_account_id: props.bank_account_id(false),
bank_account_code: Property.ShortText({ displayName: 'Bank Account Code', required: false }),
date_from: Property.ShortText({ displayName: 'Date From (YYYY-MM-DD)', required: false }),
date_to: Property.ShortText({ displayName: 'Date To (YYYY-MM-DD)', required: false }),
page_size: Property.Number({ displayName: 'Page Size (1-1000)', required: false }),
},
type: TriggerStrategy.POLLING,
async onEnable(context: any) {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async onDisable(context: any) {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async test(context: any) {
return await pollingHelper.test(polling, context);
},
async run(context: any) {
const items = await pollingHelper.poll(polling, context);
// Emit only first-time seen BankTransactionID to approximate "new" semantics
const tenantId = context.propsValue['tenant_id'];
const seenKey = `xero_bank_txn_seen_ids_${tenantId}`;
const seen: string[] = (await context.store.get(seenKey)) || [];
const results: any[] = [];
for (const it of items as any[]) {
const id = it?.BankTransactionID;
if (id && !seen.includes(id)) {
results.push(it);
seen.push(id);
}
}
await context.store.put(seenKey, seen);
return results;
},
sampleData: undefined,
});

View File

@@ -0,0 +1,176 @@
import {
TriggerStrategy,
createTrigger,
PiecePropValueSchema,
Property,
AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import {
DedupeStrategy,
httpClient,
HttpMethod,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
function parseXeroDateToEpoch(dateVal: unknown): number {
if (typeof dateVal === 'string') {
if (dateVal.includes('/Date(')) {
const match = /\/Date\((\d+)/.exec(dateVal);
if (match && match[1]) return Number(match[1]);
}
const t = Date.parse(dateVal);
if (!Number.isNaN(t)) return t;
}
if (typeof dateVal === 'number') return dateVal;
return Date.now();
}
const polling: Polling<
AppConnectionValueForAuthProperty<typeof xeroAuth>,
Record<string, unknown>
> = {
strategy: DedupeStrategy.TIMEBASED,
async items({ auth, lastFetchEpochMS, propsValue }) {
const { access_token } = auth;
const tenantId = propsValue?.['tenant_id'] as string;
const pageSize = (propsValue?.['page_size'] as number) || 200;
const statuses = (propsValue?.['statuses'] as string[]) || [];
const contactId = propsValue?.['contact_id'] as string | undefined;
const dateFrom = propsValue?.['date_from'] as string | undefined;
const dateTo = propsValue?.['date_to'] as string | undefined;
const summaryOnly = Boolean(propsValue?.['summary_only']);
const results: any[] = [];
const maxPages = 5;
for (let page = 1; page <= maxPages; page++) {
const queryParams: Record<string, string> = {
page: String(page),
pageSize: String(pageSize),
order: 'UpdatedDateUTC ASC',
};
if (Array.isArray(statuses) && statuses.length > 0) {
queryParams['Statuses'] = statuses.join(',');
}
if (contactId) {
queryParams['ContactIDs'] = contactId;
}
if (summaryOnly) {
queryParams['summaryOnly'] = 'true';
}
const whereClauses: string[] = ['Type=="ACCPAY"'];
if (dateFrom) {
const [y, m, d] = dateFrom.split('-');
whereClauses.push(`Date>=DateTime(${y}, ${m}, ${d})`);
}
if (dateTo) {
const [y, m, d] = dateTo.split('-');
whereClauses.push(`Date<DateTime(${y}, ${m}, ${d})`);
}
if (whereClauses.length > 0) {
queryParams['where'] = whereClauses.join(' AND ');
}
const headers: Record<string, string> = {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
'Xero-Tenant-Id': tenantId,
};
if (lastFetchEpochMS > 0) {
const ifModified = new Date(lastFetchEpochMS).toISOString().slice(0, 19);
headers['If-Modified-Since'] = ifModified;
}
const resp = await httpClient.sendRequest<Record<string, any>>({
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Invoices',
headers,
queryParams,
});
if (resp.status !== 200) break;
const invoices: any[] = resp.body?.Invoices ?? [];
for (const inv of invoices) {
if (inv?.Type !== 'ACCPAY') continue;
const epoch = parseXeroDateToEpoch(inv.UpdatedDateUTC || inv.Date);
results.push({ epochMilliSeconds: epoch, data: inv });
}
if (invoices.length < pageSize) break;
}
return results;
},
};
export const xeroNewBill = createTrigger({
auth: xeroAuth,
name: 'xero_new_bill',
displayName: 'New Bill',
description: 'Fires when a new bill (Accounts Payable) is added.',
props: {
tenant_id: props.tenant_id,
statuses: Property.StaticMultiSelectDropdown({
displayName: 'Statuses (optional)',
required: false,
options: {
options: [
{ label: 'DRAFT', value: 'DRAFT' },
{ label: 'SUBMITTED', value: 'SUBMITTED' },
{ label: 'AUTHORISED', value: 'AUTHORISED' },
{ label: 'PAID', value: 'PAID' },
{ label: 'VOIDED', value: 'VOIDED' },
{ label: 'DELETED', value: 'DELETED' },
],
},
}),
contact_id: props.contact_dropdown(false),
date_from: Property.ShortText({ displayName: 'Date From (YYYY-MM-DD)', required: false }),
date_to: Property.ShortText({ displayName: 'Date To (YYYY-MM-DD)', required: false }),
summary_only: Property.Checkbox({ displayName: 'Summary Only (lighter, faster)', required: false, defaultValue: true }),
page_size: Property.Number({ displayName: 'Page Size (1-1000)', required: false }),
},
type: TriggerStrategy.POLLING,
async onEnable(context: any) {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async onDisable(context: any) {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async test(context: any) {
return await pollingHelper.test(polling, context);
},
async run(context: any) {
const items = (await pollingHelper.poll(polling, context)) as any[];
const tenantId = context.propsValue['tenant_id'];
const seenKey = `xero_bill_seen_ids_${tenantId}`;
const seen: string[] = (await context.store.get(seenKey)) || [];
const results: any[] = [];
for (const inv of items) {
const id = inv?.InvoiceID as string | undefined;
if (!id) continue;
if (!seen.includes(id)) {
results.push(inv);
seen.push(id);
}
}
await context.store.put(seenKey, seen);
return results;
},
sampleData: undefined,
});

View File

@@ -0,0 +1,133 @@
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import { createHmac } from 'crypto';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
export const xeroNewContact = createTrigger({
auth: xeroAuth,
name: 'xero_new_contact',
displayName: 'New Contact',
description: 'Fires when a new contact is added to Xero (via Xero webhooks). Configure the webhook in Xero Developer portal to point to this URL.',
type: TriggerStrategy.WEBHOOK,
props: {
webhookInstructions: Property.MarkDown({
value: `
To use this trigger, manually configure a Xero webhook for your app:
1. Go to Xero Developer > My Apps > [Your App] > Webhooks.
2. Select the Contact category.
3. Set the Delivery URL to:
\n\n\`\`\`text
{{webhookUrl}}
\`\`\`
4. Click Save, then click Validate "Intent to receive".
5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.
6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.
Notes:
- Keep this trigger enabled so the URL remains active.
- We verify Xero's x-xero-signature header using your Webhook Key.
`,
}),
tenant_id: props.tenant_id,
webhook_key: Property.ShortText({
displayName: 'Webhook Key',
description: 'From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.',
required: true,
}),
fetch_full_contact: Property.Checkbox({
displayName: 'Fetch Full Contact',
description: 'If enabled, fetches the full contact from Xero using the Resource URL.',
required: false,
defaultValue: true,
}),
},
sampleData: {
ContactID: '717f2bfc-c6d4-41fd-b238-3f2f0c0cf777',
Name: 'Sample Contact',
EmailAddress: 'sample@example.com',
},
async onEnable(context: any) {
// Nothing to register programmatically. User must configure webhook in Xero Developer portal.
},
async onDisable(context: any) {
// Nothing to clean up programmatically.
},
async run(context: any) {
const { webhook_key, tenant_id, fetch_full_contact } = context.propsValue as any;
const signatureHeader = context.payload.headers['x-xero-signature'] as string | undefined;
const rawBody = context.payload.rawBody as string | undefined;
if (!signatureHeader || !rawBody) {
return [];
}
// Verify HMAC-SHA256 signature (base64)
const computed = createHmac('sha256', webhook_key).update(rawBody).digest('base64');
if (computed !== signatureHeader) {
return [];
}
const body = context.payload.body as any;
const events: any[] = body?.events ?? [];
if (!Array.isArray(events) || events.length === 0) {
// Intent to receive or empty payload
return [];
}
// Filter to CONTACT CREATE events, optionally by tenant
const filtered = events.filter((e) => {
const isContact = e.eventCategory === 'CONTACT';
const isCreate = e.eventType === 'CREATE';
const tenantOk = tenant_id ? e.tenantId === tenant_id : true;
return isContact && isCreate && tenantOk;
});
if (filtered.length === 0) {
return [];
}
if (!fetch_full_contact) {
return filtered;
}
// Fetch full contact for each event (best-effort)
const results: any[] = [];
for (const ev of filtered) {
try {
const req: HttpRequest = {
method: HttpMethod.GET,
url: ev.resourceUrl,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': ev.tenantId,
Accept: 'application/json',
},
};
const resp = await httpClient.sendRequest<any>(req);
if (resp.status === 200) {
const contact = resp.body?.Contacts?.[0] ?? resp.body;
results.push(contact);
} else {
results.push(ev);
}
} catch {
results.push(ev);
}
}
return results;
},
});

View File

@@ -0,0 +1,180 @@
import {
TriggerStrategy,
createTrigger,
PiecePropValueSchema,
Property,
AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import {
DedupeStrategy,
httpClient,
HttpMethod,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
function parseXeroDateToEpoch(dateVal: unknown): number {
if (typeof dateVal === 'string') {
if (dateVal.includes('/Date(')) {
const match = /\/Date\((\d+)/.exec(dateVal);
if (match && match[1]) return Number(match[1]);
}
const t = Date.parse(dateVal);
if (!Number.isNaN(t)) return t;
}
if (typeof dateVal === 'number') return dateVal;
return Date.now();
}
const polling: Polling<
AppConnectionValueForAuthProperty<typeof xeroAuth>,
Record<string, unknown>
> = {
strategy: DedupeStrategy.TIMEBASED,
async items({ auth, lastFetchEpochMS, propsValue }) {
const { access_token } = auth;
const tenantId = propsValue?.['tenant_id'] as string;
const pageSize = (propsValue?.['page_size'] as number) || 200;
const types = (propsValue?.['types'] as string[]) || [];
const statuses = (propsValue?.['statuses'] as string[]) || [];
const contactId = propsValue?.['contact_id'] as string | undefined;
const reference = propsValue?.['reference'] as string | undefined;
const dateFrom = propsValue?.['date_from'] as string | undefined;
const dateTo = propsValue?.['date_to'] as string | undefined;
const results: any[] = [];
const maxPages = 5;
for (let page = 1; page <= maxPages; page++) {
const queryParams: Record<string, string> = {
page: String(page),
pageSize: String(pageSize),
order: 'UpdatedDateUTC ASC',
};
const whereClauses: string[] = [];
if (types.length === 1) whereClauses.push(`Type=="${types[0]}"`);
if (statuses.length === 1) whereClauses.push(`Status=="${statuses[0]}"`);
if (statuses.length > 1) whereClauses.push(`(${statuses.map((s) => `Status=="${s}"`).join(' OR ')})`);
if (contactId) whereClauses.push(`Contact.ContactID==guid("${contactId}")`);
if (reference) whereClauses.push(`Reference=="${reference.replace(/"/g, '\\"')}"`);
if (dateFrom) {
const [y, m, d] = dateFrom.split('-');
whereClauses.push(`Date>=DateTime(${y}, ${m}, ${d})`);
}
if (dateTo) {
const [y, m, d] = dateTo.split('-');
whereClauses.push(`Date<DateTime(${y}, ${m}, ${d})`);
}
if (whereClauses.length > 0) {
queryParams['where'] = whereClauses.join(' AND ');
}
const headers: Record<string, string> = {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
'Xero-Tenant-Id': tenantId,
};
if (lastFetchEpochMS > 0) {
const ifModified = new Date(lastFetchEpochMS).toISOString().slice(0, 19);
headers['If-Modified-Since'] = ifModified;
}
const resp = await httpClient.sendRequest<Record<string, any>>({
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/CreditNotes',
headers,
queryParams,
});
if (resp.status !== 200) break;
const notes: any[] = resp.body?.CreditNotes ?? [];
for (const cn of notes) {
const epoch = parseXeroDateToEpoch(cn.UpdatedDateUTC || cn.Date);
results.push({ epochMilliSeconds: epoch, data: cn });
}
if (notes.length < pageSize) break;
}
return results;
},
};
export const xeroNewCreditNote = createTrigger({
auth: xeroAuth,
name: 'xero_new_credit_note',
displayName: 'New Credit Note',
description: 'Fires when a new credit note is created.',
props: {
tenant_id: props.tenant_id,
types: Property.StaticMultiSelectDropdown({
displayName: 'Types',
required: false,
options: {
options: [
{ label: 'ACCRECCREDIT (Sales Credit)', value: 'ACCRECCREDIT' },
{ label: 'ACCPAYCREDIT (Supplier Credit)', value: 'ACCPAYCREDIT' },
],
},
}),
statuses: Property.StaticMultiSelectDropdown({
displayName: 'Statuses (optional)',
required: false,
options: {
options: [
{ label: 'DRAFT', value: 'DRAFT' },
{ label: 'AUTHORISED', value: 'AUTHORISED' },
{ label: 'PAID', value: 'PAID' },
{ label: 'VOIDED', value: 'VOIDED' },
],
},
}),
contact_id: props.contact_dropdown(false),
reference: Property.ShortText({ displayName: 'Reference', required: false }),
date_from: Property.ShortText({ displayName: 'Date From (YYYY-MM-DD)', required: false }),
date_to: Property.ShortText({ displayName: 'Date To (YYYY-MM-DD)', required: false }),
page_size: Property.Number({ displayName: 'Page Size (1-1000)', required: false }),
},
type: TriggerStrategy.POLLING,
async onEnable(context: any) {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async onDisable(context: any) {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async test(context: any) {
return await pollingHelper.test(polling, context);
},
async run(context: any) {
const items = (await pollingHelper.poll(polling, context)) as any[];
const tenantId = context.propsValue['tenant_id'];
const seenKey = `xero_credit_note_seen_ids_${tenantId}`;
const seen: string[] = (await context.store.get(seenKey)) || [];
const results: any[] = [];
for (const cn of items) {
const id = cn?.CreditNoteID as string | undefined;
if (!id) continue;
if (!seen.includes(id)) {
results.push(cn);
seen.push(id);
}
}
await context.store.put(seenKey, seen);
return results;
},
sampleData: undefined,
});

View File

@@ -0,0 +1,128 @@
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import { createHmac } from 'crypto';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
export const xeroNewOrUpdatedContact = createTrigger({
auth: xeroAuth,
name: 'xero_new_or_updated_contact',
displayName: 'New or Updated Contact',
description: 'Fires when a contact is created or updated (via Xero webhooks).',
type: TriggerStrategy.WEBHOOK,
props: {
webhookInstructions: Property.MarkDown({
value: `
To use this trigger, manually configure a Xero webhook for your app:
1. Go to Xero Developer > My Apps > [Your App] > Webhooks.
2. Select the Contact category.
3. Set the Delivery URL to:
\n\n\`\`\`text
{{webhookUrl}}
\`\`\`
4. Click Save, then click Validate "Intent to receive".
5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.
6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.
Notes:
- Keep this trigger enabled so the URL remains active.
- We verify Xero's x-xero-signature header using your Webhook Key.
`,
}),
tenant_id: props.tenant_id,
webhook_key: Property.ShortText({
displayName: 'Webhook Key',
description: 'From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.',
required: true,
}),
fetch_full_contact: Property.Checkbox({
displayName: 'Fetch Full Contact',
description: 'If enabled, fetches the full contact from Xero using the Resource URL.',
required: false,
defaultValue: true,
}),
},
sampleData: {
ContactID: '717f2bfc-c6d4-41fd-b238-3f2f0c0cf777',
Name: 'Sample Contact',
EmailAddress: 'sample@example.com',
},
async onEnable() {
// Manual webhook setup by user
},
async onDisable() {
// Manual webhook lifecycle
},
async run(context: any) {
const { webhook_key, tenant_id, fetch_full_contact } = context.propsValue as any;
const signatureHeader = context.payload.headers['x-xero-signature'] as string | undefined;
const rawBody = context.payload.rawBody as string | undefined;
if (!signatureHeader || !rawBody) {
return [];
}
const computed = createHmac('sha256', webhook_key).update(rawBody).digest('base64');
if (computed !== signatureHeader) {
return [];
}
const body = context.payload.body as any;
const events: any[] = body?.events ?? [];
if (!Array.isArray(events) || events.length === 0) {
return [];
}
const filtered = events.filter((e) => {
const isContact = e.eventCategory === 'CONTACT';
const isCreateOrUpdate = e.eventType === 'CREATE' || e.eventType === 'UPDATE';
const tenantOk = tenant_id ? e.tenantId === tenant_id : true;
return isContact && isCreateOrUpdate && tenantOk;
});
if (filtered.length === 0) {
return [];
}
if (!fetch_full_contact) {
return filtered;
}
const results: any[] = [];
for (const ev of filtered) {
try {
const req: HttpRequest = {
method: HttpMethod.GET,
url: ev.resourceUrl,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': ev.tenantId,
Accept: 'application/json',
},
};
const resp = await httpClient.sendRequest<any>(req);
if (resp.status === 200) {
const contact = resp.body?.Contacts?.[0] ?? resp.body;
results.push(contact);
} else {
results.push(ev);
}
} catch {
results.push(ev);
}
}
return results;
},
});

View File

@@ -0,0 +1,179 @@
import {
TriggerStrategy,
createTrigger,
PiecePropValueSchema,
Property,
AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import {
DedupeStrategy,
httpClient,
HttpMethod,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
function parseXeroDateToEpoch(dateVal: unknown): number {
if (typeof dateVal === 'string') {
if (dateVal.includes('/Date(')) {
const match = /\/Date\((\d+)/.exec(dateVal);
if (match && match[1]) return Number(match[1]);
}
const t = Date.parse(dateVal);
if (!Number.isNaN(t)) return t;
}
if (typeof dateVal === 'number') return dateVal;
return Date.now();
}
const polling: Polling<
AppConnectionValueForAuthProperty<typeof xeroAuth>,
Record<string, unknown>
> = {
strategy: DedupeStrategy.TIMEBASED,
async items({ auth, lastFetchEpochMS, propsValue }) {
const { access_token } = auth;
const tenantId = propsValue?.['tenant_id'] as string;
const pageSize = (propsValue?.['page_size'] as number) || 200;
const paymentTypes = (propsValue?.['payment_types'] as string[]) || ['ACCRECPAYMENT'];
const statuses = (propsValue?.['statuses'] as string[]) || ['AUTHORISED'];
const invoiceId = propsValue?.['invoice_id'] as string | undefined;
const reference = propsValue?.['reference'] as string | undefined;
const dateFrom = propsValue?.['date_from'] as string | undefined;
const dateTo = propsValue?.['date_to'] as string | undefined;
const whereClauses: string[] = [];
if (paymentTypes.length === 1) whereClauses.push(`PaymentType=="${paymentTypes[0]}"`);
if (paymentTypes.length > 1)
whereClauses.push(`(${paymentTypes.map((t) => `PaymentType=="${t}"`).join(' OR ')})`);
if (statuses.length === 1) whereClauses.push(`Status=="${statuses[0]}"`);
if (statuses.length > 1) whereClauses.push(`(${statuses.map((s) => `Status=="${s}"`).join(' OR ')})`);
if (invoiceId) whereClauses.push(`Invoice.InvoiceID==guid("${invoiceId}")`);
if (reference) whereClauses.push(`Reference=="${reference.replace(/"/g, '\\"')}"`);
if (dateFrom) {
const [y, m, d] = dateFrom.split('-');
whereClauses.push(`Date>=DateTime(${y}, ${m}, ${d})`);
}
if (dateTo) {
const [y, m, d] = dateTo.split('-');
whereClauses.push(`Date<DateTime(${y}, ${m}, ${d})`);
}
const results: any[] = [];
const maxPages = 5;
for (let page = 1; page <= maxPages; page++) {
const queryParams: Record<string, string> = {
page: String(page),
pageSize: String(pageSize),
order: 'UpdatedDateUTC ASC',
};
if (whereClauses.length > 0) {
queryParams['where'] = whereClauses.join(' AND ');
}
const requestHeaders: Record<string, string> = {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
'Xero-Tenant-Id': tenantId,
};
if (lastFetchEpochMS > 0) {
const ifModified = new Date(lastFetchEpochMS).toISOString().slice(0, 19);
requestHeaders['If-Modified-Since'] = ifModified;
}
const resp = await httpClient.sendRequest<Record<string, any>>({
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Payments',
headers: requestHeaders,
queryParams,
});
if (resp.status !== 200) break;
const items: any[] = resp.body?.Payments ?? [];
for (const p of items) {
const epoch = parseXeroDateToEpoch(p.UpdatedDateUTC || p.Date);
results.push({ epochMilliSeconds: epoch, data: p });
}
if (items.length < pageSize) break;
}
return results;
},
};
export const xeroNewPayment = createTrigger({
auth: xeroAuth,
name: 'xero_new_payment',
displayName: 'New Payment',
description: 'Fires when a payment is received.',
props: {
tenant_id: props.tenant_id,
payment_types: Property.StaticMultiSelectDropdown({
displayName: 'Payment Types',
required: false,
options: {
options: [
{ label: 'ACCRECPAYMENT (Received on Sales Invoice)', value: 'ACCRECPAYMENT' },
{ label: 'ACCPAYPAYMENT (Paid on Bill)', value: 'ACCPAYPAYMENT' },
],
},
defaultValue: ['ACCRECPAYMENT'],
}),
statuses: Property.StaticMultiSelectDropdown({
displayName: 'Statuses',
required: false,
options: { options: [
{ label: 'AUTHORISED', value: 'AUTHORISED' },
{ label: 'DELETED', value: 'DELETED' },
]},
defaultValue: ['AUTHORISED'],
}),
invoice_id: props.invoice_id(false),
reference: Property.ShortText({ displayName: 'Reference', required: false }),
date_from: Property.ShortText({ displayName: 'Date From (YYYY-MM-DD)', required: false }),
date_to: Property.ShortText({ displayName: 'Date To (YYYY-MM-DD)', required: false }),
page_size: Property.Number({ displayName: 'Page Size (1-1000)', required: false }),
},
type: TriggerStrategy.POLLING,
async onEnable(context: any) {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async onDisable(context: any) {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async test(context: any) {
return await pollingHelper.test(polling, context);
},
async run(context: any) {
const items = await pollingHelper.poll(polling, context);
// Emit only first-time seen PaymentID to represent new payments
const tenantId = context.propsValue['tenant_id'];
const seenKey = `xero_payment_seen_ids_${tenantId}`;
const seen: string[] = (await context.store.get(seenKey)) || [];
const results: any[] = [];
for (const it of items as any[]) {
const id = it?.PaymentID;
if (id && !seen.includes(id)) {
results.push(it);
seen.push(id);
}
}
await context.store.put(seenKey, seen);
return results;
},
sampleData: undefined,
});

View File

@@ -0,0 +1,128 @@
import {
TriggerStrategy,
createTrigger,
PiecePropValueSchema,
Property,
AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import {
DedupeStrategy,
httpClient,
HttpMethod,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
const polling: Polling<
AppConnectionValueForAuthProperty<typeof xeroAuth>,
Record<string, unknown>
> = {
strategy: DedupeStrategy.TIMEBASED,
async items({ auth, propsValue }) {
const { access_token } = auth as any;
const tenantId = propsValue?.['tenant_id'] as string;
const pageSize = (propsValue?.['page_size'] as number) || 50;
const contactId = propsValue?.['contact_id'] as string | undefined;
const states = (propsValue?.['states'] as string[]) || [];
const results: any[] = [];
const maxPages = 5;
for (let page = 1; page <= maxPages; page++) {
const queryParams: Record<string, string> = {
page: String(page),
pageSize: String(pageSize),
};
if (contactId) queryParams['contactId'] = contactId;
if (Array.isArray(states) && states.length > 0) {
queryParams['states'] = states.join(',');
}
const resp = await httpClient.sendRequest<Record<string, any>>({
method: HttpMethod.GET,
url: 'https://api.xero.com/projects.xro/2.0/Projects',
headers: {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
'Xero-Tenant-Id': tenantId,
},
queryParams,
});
if (resp.status !== 200) break;
const items: any[] = resp.body?.items ?? [];
for (const it of items) {
results.push({ epochMilliSeconds: Date.now(), data: it });
}
if (items.length < pageSize) break;
}
return results;
},
};
export const xeroNewProject = createTrigger({
auth: xeroAuth,
name: 'xero_new_project',
displayName: 'New Project',
description: 'Fires when a new project is created.',
props: {
tenant_id: props.tenant_id,
contact_id: props.contact_dropdown(false),
states: Property.StaticMultiSelectDropdown({
displayName: 'States (optional)',
required: false,
options: {
options: [
{ label: 'INPROGRESS', value: 'INPROGRESS' },
{ label: 'CLOSED', value: 'CLOSED' },
],
},
}),
page_size: Property.Number({ displayName: 'Page Size (1-500)', required: false }),
},
type: TriggerStrategy.POLLING,
async onEnable(context: any) {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async onDisable(context: any) {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async test(context: any) {
return await pollingHelper.test(polling, context);
},
async run(context: any) {
const items = (await pollingHelper.poll(polling, context)) as any[];
const tenantId = context.propsValue['tenant_id'];
const seenKey = `xero_project_seen_ids_${tenantId}`;
const seen: string[] = (await context.store.get(seenKey)) || [];
const results: any[] = [];
for (const it of items) {
const id = it?.projectId ?? it?.ProjectID ?? it?.data?.projectId;
const data = it?.data ?? it;
const projectId = id as string | undefined;
if (!projectId) continue;
if (!seen.includes(projectId)) {
results.push(data);
seen.push(projectId);
}
}
await context.store.put(seenKey, seen);
return results;
},
sampleData: undefined,
});

View File

@@ -0,0 +1,210 @@
import {
TriggerStrategy,
createTrigger,
PiecePropValueSchema,
Property,
AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import {
DedupeStrategy,
httpClient,
HttpMethod,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
function parseXeroDateToEpoch(dateVal: unknown): number {
if (typeof dateVal === 'string') {
if (dateVal.includes('/Date(')) {
const match = /\/Date\((\d+)/.exec(dateVal);
if (match && match[1]) return Number(match[1]);
}
const t = Date.parse(dateVal);
if (!Number.isNaN(t)) return t;
}
if (typeof dateVal === 'number') return dateVal;
return Date.now();
}
const polling: Polling<
AppConnectionValueForAuthProperty<typeof xeroAuth>,
Record<string, unknown>
> = {
strategy: DedupeStrategy.TIMEBASED,
async items({ auth, lastFetchEpochMS, propsValue }) {
const { access_token } = auth;
const tenantId = propsValue?.['tenant_id'] as string;
const pageSize = (propsValue?.['page_size'] as number) || 200;
const statuses = (propsValue?.['statuses'] as string[]) || [];
const contactId = propsValue?.['contact_id'] as string | undefined;
const dateFrom = propsValue?.['date_from'] as string | undefined;
const dateTo = propsValue?.['date_to'] as string | undefined;
const whereClauses: string[] = [];
if (contactId) whereClauses.push(`Contact.ContactID==guid("${contactId}")`);
if (dateFrom) {
const [y, m, d] = dateFrom.split('-');
whereClauses.push(`Date>=DateTime(${y}, ${m}, ${d})`);
}
if (dateTo) {
const [y, m, d] = dateTo.split('-');
whereClauses.push(`Date<DateTime(${y}, ${m}, ${d})`);
}
if (Array.isArray(statuses) && statuses.length > 1) {
whereClauses.push(`(${statuses.map((s) => `Status=="${s}"`).join(' OR ')})`);
}
const results: any[] = [];
const maxPages = 5;
for (let page = 1; page <= maxPages; page++) {
const queryParams: Record<string, string> = {
page: String(page),
pageSize: String(pageSize),
order: 'UpdatedDateUTC ASC',
};
if (whereClauses.length > 0) {
queryParams['where'] = whereClauses.join(' AND ');
}
// Single status can use the dedicated param for efficiency
if (Array.isArray(statuses) && statuses.length === 1) {
queryParams['status'] = statuses[0];
}
const headers: Record<string, string> = {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
'Xero-Tenant-Id': tenantId,
};
if (lastFetchEpochMS > 0) {
const ifModified = new Date(lastFetchEpochMS).toISOString().slice(0, 19);
headers['If-Modified-Since'] = ifModified;
}
const resp = await httpClient.sendRequest<Record<string, any>>({
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/PurchaseOrders',
headers,
queryParams,
});
if (resp.status !== 200) break;
const pos: any[] = resp.body?.PurchaseOrders ?? [];
for (const po of pos) {
const epoch = parseXeroDateToEpoch(po.UpdatedDateUTC || po.Date);
results.push({ epochMilliSeconds: epoch, data: po });
}
if (pos.length < pageSize) break;
}
return results;
},
};
export const xeroNewPurchaseOrder = createTrigger({
auth: xeroAuth,
name: 'xero_new_purchase_order',
displayName: 'New Purchase Order',
description: 'Fires when a new purchase order is created or enters a specific status for the first time.',
props: {
tenant_id: props.tenant_id,
statuses: Property.StaticMultiSelectDropdown({
displayName: 'Filter by Status (optional)',
required: false,
options: {
options: [
{ label: 'DRAFT', value: 'DRAFT' },
{ label: 'SUBMITTED', value: 'SUBMITTED' },
{ label: 'AUTHORISED', value: 'AUTHORISED' },
{ label: 'BILLED', value: 'BILLED' },
{ label: 'DELETED', value: 'DELETED' },
],
},
}),
first_time_status: Property.StaticDropdown({
displayName: 'First-time Status (optional)',
description: 'Also fire when a purchase order enters this status for the first time (since enabling).',
required: false,
options: {
options: [
{ label: 'DRAFT', value: 'DRAFT' },
{ label: 'SUBMITTED', value: 'SUBMITTED' },
{ label: 'AUTHORISED', value: 'AUTHORISED' },
{ label: 'BILLED', value: 'BILLED' },
{ label: 'DELETED', value: 'DELETED' },
],
},
}),
contact_id: props.contact_dropdown(false),
date_from: Property.ShortText({ displayName: 'Date From (YYYY-MM-DD)', required: false }),
date_to: Property.ShortText({ displayName: 'Date To (YYYY-MM-DD)', required: false }),
page_size: Property.Number({ displayName: 'Page Size (1-1000)', required: false }),
},
type: TriggerStrategy.POLLING,
async onEnable(context: any) {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async onDisable(context: any) {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async test(context: any) {
return await pollingHelper.test(polling, context);
},
async run(context: any) {
const items = (await pollingHelper.poll(polling, context)) as any[];
const tenantId = context.propsValue['tenant_id'];
const firstStatus: string | undefined = context.propsValue['first_time_status'];
const seenIdsKey = `xero_po_seen_ids_${tenantId}`;
const seenIds: string[] = (await context.store.get(seenIdsKey)) || [];
const statusSeenKey = firstStatus ? `xero_po_status_seen_${tenantId}_${firstStatus}` : '';
const statusSeenIds: string[] = firstStatus ? (await context.store.get(statusSeenKey)) || [] : [];
const emittedIds = new Set<string>();
const results: any[] = [];
for (const po of items) {
const id = po?.PurchaseOrderID;
if (!id) continue;
// Emit for brand new purchase orders (first time seen)
if (!seenIds.includes(id)) {
if (!emittedIds.has(id)) {
results.push(po);
emittedIds.add(id);
}
seenIds.push(id);
}
// Emit when entering the specific status for the first time
if (firstStatus && po?.Status === firstStatus && !statusSeenIds.includes(id)) {
if (!emittedIds.has(id)) {
results.push(po);
emittedIds.add(id);
}
statusSeenIds.push(id);
}
}
await context.store.put(seenIdsKey, seenIds);
if (firstStatus) {
await context.store.put(statusSeenKey, statusSeenIds);
}
return results;
},
sampleData: undefined,
});

View File

@@ -0,0 +1,166 @@
import {
TriggerStrategy,
createTrigger,
PiecePropValueSchema,
Property,
AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import {
DedupeStrategy,
httpClient,
HttpMethod,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
function parseXeroDateToEpoch(dateVal: unknown): number {
if (typeof dateVal === 'string') {
if (dateVal.includes('/Date(')) {
const match = /\/Date\((\d+)/.exec(dateVal);
if (match && match[1]) return Number(match[1]);
}
const t = Date.parse(dateVal);
if (!Number.isNaN(t)) return t;
}
if (typeof dateVal === 'number') return dateVal;
return Date.now();
}
const polling: Polling<
AppConnectionValueForAuthProperty<typeof xeroAuth>,
Record<string, unknown>
> = {
strategy: DedupeStrategy.TIMEBASED,
async items({ auth, lastFetchEpochMS, propsValue }) {
const { access_token } = auth;
const tenantId = propsValue?.['tenant_id'] as string;
const pageSize = (propsValue?.['page_size'] as number) || 200;
const statuses = (propsValue?.['statuses'] as string[]) || [];
const contactId = propsValue?.['contact_id'] as string | undefined;
const quoteNumber = propsValue?.['quote_number'] as string | undefined;
const dateFrom = propsValue?.['date_from'] as string | undefined;
const dateTo = propsValue?.['date_to'] as string | undefined;
const expiryFrom = propsValue?.['expiry_date_from'] as string | undefined;
const expiryTo = propsValue?.['expiry_date_to'] as string | undefined;
const results: any[] = [];
const maxPages = 5;
for (let page = 1; page <= maxPages; page++) {
const queryParams: Record<string, string> = {
page: String(page),
pageSize: String(pageSize),
order: 'UpdatedDateUTC ASC',
};
if (Array.isArray(statuses) && statuses.length === 1) {
queryParams['status'] = statuses[0];
}
if (contactId) queryParams['ContactID'] = contactId;
if (quoteNumber) queryParams['QuoteNumber'] = quoteNumber;
if (dateFrom) queryParams['DateFrom'] = dateFrom;
if (dateTo) queryParams['DateTo'] = dateTo;
if (expiryFrom) queryParams['ExpiryDateFrom'] = expiryFrom;
if (expiryTo) queryParams['ExpiryDateTo'] = expiryTo;
const headers: Record<string, string> = {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
'Xero-Tenant-Id': tenantId,
};
if (lastFetchEpochMS > 0) {
const ifModified = new Date(lastFetchEpochMS).toISOString().slice(0, 19);
headers['If-Modified-Since'] = ifModified;
}
const resp = await httpClient.sendRequest<Record<string, any>>({
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Quotes',
headers,
queryParams,
});
if (resp.status !== 200) break;
const quotes: any[] = resp.body?.Quotes ?? [];
for (const q of quotes) {
const epoch = parseXeroDateToEpoch(q.UpdatedDateUTC || q.Date);
results.push({ epochMilliSeconds: epoch, data: q });
}
if (quotes.length < pageSize) break;
}
return results;
},
};
export const xeroNewQuote = createTrigger({
auth: xeroAuth,
name: 'xero_new_quote',
displayName: 'New Quote',
description: 'Fires when a new quote is created.',
props: {
tenant_id: props.tenant_id,
statuses: Property.StaticMultiSelectDropdown({
displayName: 'Filter by Status (optional)',
required: false,
options: {
options: [
{ label: 'DRAFT', value: 'DRAFT' },
{ label: 'SENT', value: 'SENT' },
{ label: 'ACCEPTED', value: 'ACCEPTED' },
{ label: 'DECLINED', value: 'DECLINED' },
{ label: 'INVOICED', value: 'INVOICED' },
{ label: 'DELETED', value: 'DELETED' },
],
},
}),
contact_id: props.contact_dropdown(false),
quote_number: Property.ShortText({ displayName: 'Quote Number (partial match)', required: false }),
date_from: Property.ShortText({ displayName: 'Date From (YYYY-MM-DD)', required: false }),
date_to: Property.ShortText({ displayName: 'Date To (YYYY-MM-DD)', required: false }),
expiry_date_from: Property.ShortText({ displayName: 'Expiry Date From (YYYY-MM-DD)', required: false }),
expiry_date_to: Property.ShortText({ displayName: 'Expiry Date To (YYYY-MM-DD)', required: false }),
page_size: Property.Number({ displayName: 'Page Size (1-1000)', required: false }),
},
type: TriggerStrategy.POLLING,
async onEnable(context: any) {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async onDisable(context: any) {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async test(context: any) {
return await pollingHelper.test(polling, context);
},
async run(context: any) {
const items = (await pollingHelper.poll(polling, context)) as any[];
const tenantId = context.propsValue['tenant_id'];
const seenKey = `xero_quote_seen_ids_${tenantId}`;
const seen: string[] = (await context.store.get(seenKey)) || [];
const results: any[] = [];
for (const q of items) {
const id = q?.QuoteID as string | undefined;
if (!id) continue;
if (!seen.includes(id)) {
results.push(q);
seen.push(id);
}
}
await context.store.put(seenKey, seen);
return results;
},
sampleData: undefined,
});

View File

@@ -0,0 +1,193 @@
import {
TriggerStrategy,
createTrigger,
PiecePropValueSchema,
Property,
AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import {
DedupeStrategy,
httpClient,
HttpMethod,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
function parseXeroDateToEpoch(dateVal: unknown): number {
if (typeof dateVal === 'string') {
if (dateVal.includes('/Date(')) {
const match = /\/Date\((\d+)/.exec(dateVal);
if (match && match[1]) return Number(match[1]);
}
const t = Date.parse(dateVal);
if (!Number.isNaN(t)) return t;
}
if (typeof dateVal === 'number') return dateVal;
return Date.now();
}
const polling: Polling<
AppConnectionValueForAuthProperty<typeof xeroAuth>,
Record<string, unknown>
> = {
strategy: DedupeStrategy.TIMEBASED,
async items({ auth, lastFetchEpochMS, propsValue }) {
const { access_token } = auth;
const tenantId = propsValue?.['tenant_id'] as string;
const pageSize = (propsValue?.['page_size'] as number) || 200;
const paymentTypes = (propsValue?.['payment_types'] as string[]) || ['ACCRECPAYMENT'];
const statuses = (propsValue?.['statuses'] as string[]) || ['AUTHORISED'];
const invoiceId = propsValue?.['invoice_id'] as string | undefined;
const reference = propsValue?.['reference'] as string | undefined;
const dateFrom = propsValue?.['date_from'] as string | undefined;
const dateTo = propsValue?.['date_to'] as string | undefined;
const whereClauses: string[] = [];
if (paymentTypes.length === 1) whereClauses.push(`PaymentType=="${paymentTypes[0]}"`);
if (paymentTypes.length > 1)
whereClauses.push(`(${paymentTypes.map((t) => `PaymentType=="${t}"`).join(' OR ')})`);
if (statuses.length === 1) whereClauses.push(`Status=="${statuses[0]}"`);
if (statuses.length > 1) whereClauses.push(`(${statuses.map((s) => `Status=="${s}"`).join(' OR ')})`);
if (invoiceId) whereClauses.push(`Invoice.InvoiceID==guid("${invoiceId}")`);
if (reference) whereClauses.push(`Reference=="${reference.replace(/"/g, '\\"')}"`);
if (dateFrom) {
const [y, m, d] = dateFrom.split('-');
whereClauses.push(`Date>=DateTime(${y}, ${m}, ${d})`);
}
if (dateTo) {
const [y, m, d] = dateTo.split('-');
whereClauses.push(`Date<DateTime(${y}, ${m}, ${d})`);
}
const results: any[] = [];
const maxPages = 5;
for (let page = 1; page <= maxPages; page++) {
const queryParams: Record<string, string> = {
page: String(page),
pageSize: String(pageSize),
order: 'UpdatedDateUTC ASC',
};
if (whereClauses.length > 0) {
queryParams['where'] = whereClauses.join(' AND ');
}
const requestHeaders: Record<string, string> = {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
'Xero-Tenant-Id': tenantId,
};
if (lastFetchEpochMS > 0) {
const ifModified = new Date(lastFetchEpochMS).toISOString().slice(0, 19);
requestHeaders['If-Modified-Since'] = ifModified;
}
const resp = await httpClient.sendRequest<Record<string, any>>({
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Payments',
headers: requestHeaders,
queryParams,
});
if (resp.status !== 200) break;
const items: any[] = resp.body?.Payments ?? [];
for (const p of items) {
const epoch = parseXeroDateToEpoch(p.UpdatedDateUTC || p.Date);
results.push({ epochMilliSeconds: epoch, data: p });
}
if (items.length < pageSize) break;
}
return results;
},
};
export const xeroNewReconciledPayment = createTrigger({
auth: xeroAuth,
name: 'xero_new_reconciled_payment',
displayName: 'New Reconciled Payment',
description: 'Fires when a payment is reconciled for the first time.',
props: {
tenant_id: props.tenant_id,
payment_types: Property.StaticMultiSelectDropdown({
displayName: 'Payment Types',
required: false,
options: {
options: [
{ label: 'ACCRECPAYMENT (Received on Sales Invoice)', value: 'ACCRECPAYMENT' },
{ label: 'ACCPAYPAYMENT (Paid on Bill)', value: 'ACCPAYPAYMENT' },
],
},
defaultValue: ['ACCRECPAYMENT'],
}),
statuses: Property.StaticMultiSelectDropdown({
displayName: 'Statuses',
required: false,
options: { options: [
{ label: 'AUTHORISED', value: 'AUTHORISED' },
{ label: 'DELETED', value: 'DELETED' },
]},
defaultValue: ['AUTHORISED'],
}),
invoice_id: props.invoice_id(false),
reference: Property.ShortText({ displayName: 'Reference', required: false }),
date_from: Property.ShortText({ displayName: 'Date From (YYYY-MM-DD)', required: false }),
date_to: Property.ShortText({ displayName: 'Date To (YYYY-MM-DD)', required: false }),
page_size: Property.Number({ displayName: 'Page Size (1-1000)', required: false }),
},
type: TriggerStrategy.POLLING,
async onEnable(context: any) {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async onDisable(context: any) {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async test(context: any) {
return await pollingHelper.test(polling, context);
},
async run(context: any) {
const items = (await pollingHelper.poll(polling, context)) as any[];
const tenantId = context.propsValue['tenant_id'];
const seenKey = `xero_payment_reconciled_seen_ids_${tenantId}`;
const seen: string[] = (await context.store.get(seenKey)) || [];
const previousStateKey = `xero_payment_prev_reconciled_state_${tenantId}`;
const prevState: Record<string, boolean> = (await context.store.get(previousStateKey)) || {};
const results: any[] = [];
for (const p of items) {
const id = p?.PaymentID as string | undefined;
if (!id) continue;
const isRec = Boolean(p?.IsReconciled);
const wasRec = Boolean(prevState[id]);
// Fire only when first transitions to reconciled (false -> true)
if (isRec && !wasRec && !seen.includes(id)) {
results.push(p);
seen.push(id);
}
// Track current state for next poll
prevState[id] = isRec;
}
await context.store.put(seenKey, seen);
await context.store.put(previousStateKey, prevState);
return results;
},
sampleData: undefined,
});

View File

@@ -0,0 +1,131 @@
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import { createHmac } from 'crypto';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
export const xeroNewSalesInvoice = createTrigger({
auth: xeroAuth,
name: 'xero_new_sales_invoice',
displayName: 'New Sales Invoice',
description: 'Fires when a new sales invoice (Accounts Receivable) is created.',
type: TriggerStrategy.WEBHOOK,
props: {
webhookInstructions: Property.MarkDown({
value: `
To use this trigger, manually configure a Xero webhook for your app:
1. Go to Xero Developer > My Apps > [Your App] > Webhooks.
2. Select the Invoice category.
3. Set the Delivery URL to:
\n\n\`\`\`text
{{webhookUrl}}
\`\`\`
4. Click Save, then click Validate "Intent to receive".
5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.
6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.
Notes:
- Keep this trigger enabled so the URL remains active.
- We verify Xero's x-xero-signature header using your Webhook Key.
`,
}),
tenant_id: props.tenant_id,
webhook_key: Property.ShortText({
displayName: 'Webhook Key',
description: 'From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.',
required: true,
}),
fetch_full_invoice: Property.Checkbox({
displayName: 'Fetch Full Invoice',
description: 'Fetch the full invoice and ensure Type is ACCREC (recommended).',
required: false,
defaultValue: true,
}),
},
sampleData: {
InvoiceID: '243216c5-369e-4056-ac67-05388f86dc81',
Type: 'ACCREC',
InvoiceNumber: 'INV-0001',
Status: 'AUTHORISED',
},
async onEnable(): Promise<void> {
// Manual webhook setup by user
},
async onDisable(): Promise<void> {
// Manual webhook lifecycle
},
async run(context: any) {
const { webhook_key, tenant_id, fetch_full_invoice } = context.propsValue as any;
const signatureHeader = context.payload.headers['x-xero-signature'] as string | undefined;
const rawBody = context.payload.rawBody as string | undefined;
if (!signatureHeader || !rawBody) {
return [];
}
const computed = createHmac('sha256', webhook_key).update(rawBody).digest('base64');
if (computed !== signatureHeader) {
return [];
}
const body = context.payload.body as any;
const events: any[] = body?.events ?? [];
if (!Array.isArray(events) || events.length === 0) {
return [];
}
// Filter to INVOICE CREATE events (new invoices), optional tenant match
const filtered = events.filter((e) => {
const isInvoice = e.eventCategory === 'INVOICE';
const isCreate = e.eventType === 'CREATE';
const tenantOk = tenant_id ? e.tenantId === tenant_id : true;
return isInvoice && isCreate && tenantOk;
});
if (filtered.length === 0) {
return [];
}
// If not fetching full invoice, we cannot verify ACCREC from event alone; return events
if (!fetch_full_invoice) {
return filtered;
}
// Fetch each invoice and only return ACCREC (sales) invoices
const results: any[] = [];
for (const ev of filtered) {
try {
const req: HttpRequest = {
method: HttpMethod.GET,
url: ev.resourceUrl,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': ev.tenantId,
Accept: 'application/json',
},
};
const resp = await httpClient.sendRequest<any>(req);
if (resp.status === 200) {
const inv = resp.body?.Invoices?.[0] ?? resp.body;
if (inv?.Type === 'ACCREC') {
results.push(inv);
}
}
} catch {
// ignore errors, move on
}
}
return results;
},
});

View File

@@ -0,0 +1,169 @@
import {
TriggerStrategy,
createTrigger,
PiecePropValueSchema,
Property,
AppConnectionValueForAuthProperty,
} from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import {
DedupeStrategy,
httpClient,
HttpMethod,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
function parseXeroDateToEpoch(dateVal: unknown): number {
if (typeof dateVal === 'string') {
if (dateVal.includes('/Date(')) {
const match = /\/Date\((\d+)/.exec(dateVal);
if (match && match[1]) return Number(match[1]);
}
const t = Date.parse(dateVal);
if (!Number.isNaN(t)) return t;
}
if (typeof dateVal === 'number') return dateVal;
return Date.now();
}
const polling: Polling<
AppConnectionValueForAuthProperty<typeof xeroAuth>,
Record<string, unknown>
> = {
strategy: DedupeStrategy.TIMEBASED,
async items({ auth, lastFetchEpochMS, propsValue }) {
const { access_token } = auth;
const tenantId = propsValue?.['tenant_id'] as string;
const pageSize = (propsValue?.['page_size'] as number) || 200;
const statuses = (propsValue?.['statuses'] as string[]) || [];
const contactId = propsValue?.['contact_id'] as string | undefined;
const quoteNumber = propsValue?.['quote_number'] as string | undefined;
const dateFrom = propsValue?.['date_from'] as string | undefined;
const dateTo = propsValue?.['date_to'] as string | undefined;
const expiryFrom = propsValue?.['expiry_date_from'] as string | undefined;
const expiryTo = propsValue?.['expiry_date_to'] as string | undefined;
const results: any[] = [];
const maxPages = 5;
for (let page = 1; page <= maxPages; page++) {
const queryParams: Record<string, string> = {
page: String(page),
pageSize: String(pageSize),
order: 'UpdatedDateUTC ASC',
};
if (Array.isArray(statuses) && statuses.length === 1) {
queryParams['status'] = statuses[0];
}
if (contactId) queryParams['ContactID'] = contactId;
if (quoteNumber) queryParams['QuoteNumber'] = quoteNumber;
if (dateFrom) queryParams['DateFrom'] = dateFrom;
if (dateTo) queryParams['DateTo'] = dateTo;
if (expiryFrom) queryParams['ExpiryDateFrom'] = expiryFrom;
if (expiryTo) queryParams['ExpiryDateTo'] = expiryTo;
const headers: Record<string, string> = {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
'Xero-Tenant-Id': tenantId,
};
if (lastFetchEpochMS > 0) {
const ifModified = new Date(lastFetchEpochMS).toISOString().slice(0, 19);
headers['If-Modified-Since'] = ifModified;
}
const resp = await httpClient.sendRequest<Record<string, any>>({
method: HttpMethod.GET,
url: 'https://api.xero.com/api.xro/2.0/Quotes',
headers,
queryParams,
});
if (resp.status !== 200) break;
const quotes: any[] = resp.body?.Quotes ?? [];
for (const q of quotes) {
const epoch = parseXeroDateToEpoch(q.UpdatedDateUTC || q.Date);
results.push({ epochMilliSeconds: epoch, data: q });
}
if (quotes.length < pageSize) break;
}
return results;
},
};
export const xeroUpdatedQuote = createTrigger({
auth: xeroAuth,
name: 'xero_updated_quote',
displayName: 'Updated Quote',
description: 'Fires when a quote is created or updated.',
props: {
tenant_id: props.tenant_id,
statuses: Property.StaticMultiSelectDropdown({
displayName: 'Filter by Status (optional)',
required: false,
options: {
options: [
{ label: 'DRAFT', value: 'DRAFT' },
{ label: 'SENT', value: 'SENT' },
{ label: 'ACCEPTED', value: 'ACCEPTED' },
{ label: 'DECLINED', value: 'DECLINED' },
{ label: 'INVOICED', value: 'INVOICED' },
{ label: 'DELETED', value: 'DELETED' },
],
},
}),
contact_id: props.contact_dropdown(false),
quote_number: Property.ShortText({ displayName: 'Quote Number (partial match)', required: false }),
date_from: Property.ShortText({ displayName: 'Date From (YYYY-MM-DD)', required: false }),
date_to: Property.ShortText({ displayName: 'Date To (YYYY-MM-DD)', required: false }),
expiry_date_from: Property.ShortText({ displayName: 'Expiry Date From (YYYY-MM-DD)', required: false }),
expiry_date_to: Property.ShortText({ displayName: 'Expiry Date To (YYYY-MM-DD)', required: false }),
page_size: Property.Number({ displayName: 'Page Size (1-1000)', required: false }),
},
type: TriggerStrategy.POLLING,
async onEnable(context: any) {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async onDisable(context: any) {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
async test(context: any) {
return await pollingHelper.test(polling, context);
},
async run(context: any) {
const items = (await pollingHelper.poll(polling, context)) as any[];
const tenantId = context.propsValue['tenant_id'];
const prevMapKey = `xero_quote_prev_updated_${tenantId}`;
const prevMap: Record<string, number> = (await context.store.get(prevMapKey)) || {};
const results: any[] = [];
for (const q of items) {
const id = q?.QuoteID as string | undefined;
if (!id) continue;
const updatedEpoch = parseXeroDateToEpoch(q?.UpdatedDateUTC || q?.Date);
const prevEpoch = prevMap[id] || 0;
if (updatedEpoch > prevEpoch) {
results.push(q);
prevMap[id] = updatedEpoch;
}
}
await context.store.put(prevMapKey, prevMap);
return results;
},
sampleData: undefined,
});

View File

@@ -0,0 +1,130 @@
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework';
import { xeroAuth } from '../..';
import { createHmac } from 'crypto';
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { props } from '../common/props';
export const xeroUpdatedSalesInvoice = createTrigger({
auth: xeroAuth,
name: 'xero_updated_sales_invoice',
displayName: 'Updated Sales Invoice',
description: 'Fires when an existing sales invoice (Accounts Receivable) is updated.',
type: TriggerStrategy.WEBHOOK,
props: {
webhookInstructions: Property.MarkDown({
value: `
To use this trigger, manually configure a Xero webhook for your app:
1. Go to Xero Developer > My Apps > [Your App] > Webhooks.
2. Select the Invoice category.
3. Set the Delivery URL to:
\n\n\`\`\`text
{{webhookUrl}}
\`\`\`
4. Click Save, then click Validate "Intent to receive".
5. Copy the Webhook Key from the Webhooks page and paste it into the Webhook Key field below.
6. Optionally set Organization ID (Tenant ID) to only accept events from a specific org.
Notes:
- Keep this trigger enabled so the URL remains active.
- We verify Xero's x-xero-signature header using your Webhook Key.
`,
}),
tenant_id: props.tenant_id,
webhook_key: Property.ShortText({
displayName: 'Webhook Key',
description: 'From Xero Developer portal > Your App > Webhooks. Used to verify x-xero-signature.',
required: true,
}),
fetch_full_invoice: Property.Checkbox({
displayName: 'Fetch Full Invoice',
description: 'Fetch the full invoice and ensure Type is ACCREC (recommended).',
required: false,
defaultValue: true,
}),
},
sampleData: {
InvoiceID: '243216c5-369e-4056-ac67-05388f86dc81',
Type: 'ACCREC',
InvoiceNumber: 'INV-0001',
Status: 'AUTHORISED',
},
async onEnable(): Promise<void> {
// The user has already enabled the trigger, so we don't need to do anything
},
async onDisable(): Promise<void> {
// The user has already disabled the trigger, so we don't need to do anything
},
async run(context: any) {
const { webhook_key, tenant_id, fetch_full_invoice } = context.propsValue as any;
const signatureHeader = context.payload.headers['x-xero-signature'] as string | undefined;
const rawBody = context.payload.rawBody as string | undefined;
if (!signatureHeader || !rawBody) {
return [];
}
const computed = createHmac('sha256', webhook_key).update(rawBody).digest('base64');
if (computed !== signatureHeader) {
return [];
}
const body = context.payload.body as any;
const events: any[] = body?.events ?? [];
if (!Array.isArray(events) || events.length === 0) {
return [];
}
// Filter to INVOICE UPDATE events, optional tenant match
const filtered = events.filter((e) => {
const isInvoice = e.eventCategory === 'INVOICE';
const isUpdate = e.eventType === 'UPDATE';
const tenantOk = tenant_id ? e.tenantId === tenant_id : true;
return isInvoice && isUpdate && tenantOk;
});
if (filtered.length === 0) {
return [];
}
if (!fetch_full_invoice) {
return filtered;
}
const results: any[] = [];
for (const ev of filtered) {
try {
const req: HttpRequest = {
method: HttpMethod.GET,
url: ev.resourceUrl,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (context.auth as any).access_token,
},
headers: {
'Xero-Tenant-Id': ev.tenantId,
Accept: 'application/json',
},
};
const resp = await httpClient.sendRequest<any>(req);
if (resp.status === 200) {
const inv = resp.body?.Invoices?.[0] ?? resp.body;
if (inv?.Type === 'ACCREC') {
results.push(inv);
}
}
} catch {
// ignore
}
}
return results;
},
});

View File

@@ -0,0 +1,16 @@
{
"extends": "../../../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
],
"compilerOptions": {
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}

View File

@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
"include": ["src/**/*.ts"]
}