diff --git a/flows.yaml b/flows.yaml index 5a1524d9..f65aee5d 100644 --- a/flows.yaml +++ b/flows.yaml @@ -4716,6 +4716,7 @@ integrations: output: Contact sync_type: incremental endpoint: GET /xero/contacts + version: 1.0.0 accounts: description: > Fetches all accounts in Xero (chart of accounts). Incremental sync, @@ -4725,6 +4726,7 @@ integrations: output: Account sync_type: incremental endpoint: GET /xero/accounts + version: 1.0.0 items: description: > Fetches all items in Xero. Incremental sync, does not detect deletes, @@ -4736,6 +4738,7 @@ integrations: output: Item sync_type: incremental endpoint: GET /xero/items + version: 1.0.0 invoices: description: | Fetches all invoices in Xero. Incremental sync. @@ -4744,6 +4747,7 @@ integrations: output: Invoice sync_type: incremental endpoint: GET /xero/invoices + version: 1.0.0 payments: description: | Fetches all payments in Xero. Incremental sync. @@ -4752,6 +4756,7 @@ integrations: output: Payment sync_type: incremental endpoint: GET /xero/payments + version: 1.0.0 actions: create-contact: description: | @@ -4761,6 +4766,7 @@ integrations: scopes: accounting.contacts output: ContactActionResponse endpoint: POST /xero/contacts + version: 1.0.0 update-contact: description: > Updates one or multiple contacts in Xero. Only fields that are passed @@ -4770,6 +4776,7 @@ integrations: scopes: accounting.contacts output: ContactActionResponse endpoint: PUT /xero/contacts + version: 1.0.0 create-invoice: description: | Creates one or more invoices in Xero. @@ -4778,7 +4785,7 @@ integrations: scopes: accounting.transactions output: InvoiceActionResponse endpoint: POST /xero/invoices - version: 1.0.0 + version: 1.0.1 update-invoice: description: | Updates one or more invoices in Xero. To delete an invoice @@ -4789,7 +4796,7 @@ integrations: scopes: accounting.transactions output: InvoiceActionResponse endpoint: PUT /xero/invoices - version: 1.0.0 + version: 1.0.1 create-credit-note: description: | Creates one or more credit notes in Xero. @@ -4798,6 +4805,7 @@ integrations: scopes: accounting.transactions output: CreditNoteActionResponse endpoint: POST /xero/creditnotes + version: 1.0.0 update-credit-note: description: | Updates one or more credit notes in Xero. @@ -4805,6 +4813,7 @@ integrations: scopes: accounting.transactions output: CreditNoteActionResponse endpoint: PUT /xero/creditnotes + version: 1.0.0 create-payment: description: | Creates one or more payments in Xero. @@ -4813,6 +4822,7 @@ integrations: input: CreatePayment[] output: PaymentActionResponse endpoint: POST /xero/payments + version: 1.0.0 create-item: description: | Creates one or more items in Xero. @@ -4821,6 +4831,7 @@ integrations: input: Item[] output: ItemActionResponse endpoint: POST /xero/items + version: 1.0.0 update-item: description: | Updates one or more items in Xero. @@ -4828,6 +4839,7 @@ integrations: input: Item[] output: ItemActionResponse endpoint: PUT /xero/items + version: 1.0.0 models: ActionErrorResponse: message: string @@ -4848,9 +4860,9 @@ integrations: Contact: name: string id: string - external_id?: string + external_id: string | null email: string | null - tax_number?: string | null + tax_number: string | null address_line_1?: string | null address_line_2?: string | null city: string | null @@ -4862,9 +4874,9 @@ integrations: FailedContact: name: string id: string - external_id?: string + external_id: string | null email: string | null - tax_number?: string | null + tax_number: string | null address_line_1?: string | null address_line_2?: string | null city: string | null @@ -5050,12 +5062,12 @@ integrations: external_contact_id: string status: string number: string - is_taxable: boolean - tax_rate_id: string - tax_rate: number + is_taxable?: boolean + tax_rate_id?: string + tax_rate?: number currency: string reference: string - issuing_date: date + issuing_date: date | null fees: CreditNoteFee[] CreditNoteFee: item_id: string @@ -5073,12 +5085,12 @@ integrations: external_contact_id: string status: string number: string - is_taxable: boolean - tax_rate_id: string - tax_rate: number + is_taxable?: boolean + tax_rate_id?: string + tax_rate?: number currency: string reference: string - issuing_date: date + issuing_date: date | null fees: CreditNoteFee[] validation_errors: any[] CreditNoteActionResponse: diff --git a/globals.d.ts b/globals.d.ts index 0332930f..084b7e46 100644 --- a/globals.d.ts +++ b/globals.d.ts @@ -1,7 +1,7 @@ export {}; declare global { - var vitest: { - NangoSyncMock: new (config: { name: string; Model: string }) => any; - }; + var vitest: { + NangoSyncMock: new (config: { name: string; Model: string }) => any; + }; } diff --git a/integrations/xero/fixtures/credit-note.json b/integrations/xero/fixtures/credit-note.json new file mode 100644 index 00000000..d3ae111a --- /dev/null +++ b/integrations/xero/fixtures/credit-note.json @@ -0,0 +1,27 @@ +[ + { + "id": "12345", + "type": "ACCPAYCREDIT", + "external_contact_id": "e1f8418e-a946-4013-80f6-ef52bb88f920", + "status": "DRAFT", + "number": "CN001", + "is_taxable": true, + "tax_rate_id": "TR001", + "tax_rate": 0.15, + "reference": "Invoice123", + "issuing_date": "2024-07-31", + "fees": [ + { + "item_id": "ea10a915-3787-4c37-9ff7-ab33cc6b35f3", + "item_code": "item-1", + "description": "Consulting services", + "units": 10, + "precise_unit_amount": 100.0, + "account_code": "4000", + "account_external_id": "acc_123", + "amount_cents": 100000, + "taxes_amount_cents": 15000 + } + ] + } +] diff --git a/integrations/xero/fixtures/item.json b/integrations/xero/fixtures/item.json new file mode 100644 index 00000000..d4287bb5 --- /dev/null +++ b/integrations/xero/fixtures/item.json @@ -0,0 +1,5 @@ +[ + { + "item_code": "item-2" + } +] diff --git a/integrations/xero/mappers/to-contact.ts b/integrations/xero/mappers/to-contact.ts index a17a9a2d..49e240bd 100644 --- a/integrations/xero/mappers/to-contact.ts +++ b/integrations/xero/mappers/to-contact.ts @@ -16,20 +16,22 @@ export function toContact(xeroContact: XeroContact): Contact { : `${defaultPhone.PhoneAreaCode}${defaultPhone.PhoneNumber}`; } - return { + const contact: Contact = { id: xeroContact.ContactID, name: xeroContact.Name, - external_id: xeroContact.ContactNumber, - tax_number: xeroContact.TaxNumber, + external_id: xeroContact.ContactNumber || null, + tax_number: xeroContact.TaxNumber || null, email: xeroContact.EmailAddress, - address_line_1: streetAddress?.AddressLine1, - address_line_2: streetAddress?.AddressLine2, - city: streetAddress?.City, - zip: streetAddress?.PostalCode, - country: streetAddress?.Country, - state: streetAddress?.Region, + address_line_1: streetAddress?.AddressLine1 || null, + address_line_2: streetAddress?.AddressLine2 || null, + city: streetAddress?.City || null, + zip: streetAddress?.PostalCode || null, + country: streetAddress?.Country || null, + state: streetAddress?.Region || null, phone: formattedPhoneNumber - } as Contact; + }; + + return contact; } export function toXeroContact(contact: Contact | CreateContact): XeroContact { diff --git a/integrations/xero/mappers/to-credit-note.ts b/integrations/xero/mappers/to-credit-note.ts index e68ac376..f4301d62 100644 --- a/integrations/xero/mappers/to-credit-note.ts +++ b/integrations/xero/mappers/to-credit-note.ts @@ -1,8 +1,9 @@ import type { FailedCreditNote, CreditNote, CreditNoteFee } from '../../models'; +import type { CreditNote as XeroCreditNote } from '../types'; import { parseDate } from '../utils.js'; -export function toCreditNote(xeroCreditNote: any): CreditNote { - return { +export function toCreditNote(xeroCreditNote: XeroCreditNote): CreditNote { + const creditNote: CreditNote = { id: xeroCreditNote.CreditNoteID, type: xeroCreditNote.Type, external_contact_id: xeroCreditNote.Contact.ContactID, @@ -12,11 +13,13 @@ export function toCreditNote(xeroCreditNote: any): CreditNote { reference: xeroCreditNote.Reference, issuing_date: xeroCreditNote.Date ? parseDate(xeroCreditNote.Date) : null, fees: xeroCreditNote.LineItems.map(toCreditNoteItem) - } as CreditNote; + }; + + return creditNote; } function toCreditNoteItem(xeroCreditNoteItem: any): CreditNoteFee { - return { + const creditNoteItem: CreditNoteFee = { item_id: xeroCreditNoteItem.LineItemID, item_code: xeroCreditNoteItem.ItemCode, description: xeroCreditNoteItem.Description, @@ -26,11 +29,16 @@ function toCreditNoteItem(xeroCreditNoteItem: any): CreditNoteFee { account_external_id: xeroCreditNoteItem.AccountId, amount_cents: parseFloat(xeroCreditNoteItem.LineAmount) * 100, // Amounts in xero are not in cents taxes_amount_cents: parseFloat(xeroCreditNoteItem.TaxAmount) * 100 // Amounts in xero are not in cents - } as CreditNoteFee; + }; + + return creditNoteItem; } -export function toFailedCreditNote(xeroCreditNote: any): FailedCreditNote { - const failedCreditNote = toCreditNote(xeroCreditNote) as FailedCreditNote; - failedCreditNote.validation_errors = xeroCreditNote.ValidationErrors; - return failedCreditNote; +export function toFailedCreditNote(xeroCreditNote: XeroCreditNote): FailedCreditNote { + const failedCreditNote = toCreditNote(xeroCreditNote); + const failedCreditNoteWithValidationErrors: FailedCreditNote = { + ...failedCreditNote, + validation_errors: xeroCreditNote?.ValidationErrors || [] + }; + return failedCreditNoteWithValidationErrors; } diff --git a/integrations/xero/mappers/to-item.ts b/integrations/xero/mappers/to-item.ts index 0d81e175..c00b4d1d 100644 --- a/integrations/xero/mappers/to-item.ts +++ b/integrations/xero/mappers/to-item.ts @@ -1,13 +1,16 @@ import type { FailedItem, Item } from '../../models'; +import type { Item as XeroItem } from '../types'; -export function toItem(xeroItem: any): Item { - return { +export function toItem(xeroItem: XeroItem): Item { + const item: Item = { id: xeroItem.ItemID, item_code: xeroItem.Code, - name: xeroItem.Name, - description: xeroItem.Description, - account_code: xeroItem.SalesDetails ? xeroItem.SalesDetails.AccountCode : null - } as Item; + name: xeroItem.Name || xeroItem.Code, + description: xeroItem.Description || null, + account_code: xeroItem.SalesDetails ? xeroItem.SalesDetails['AccountCode'] : null + }; + + return item; } export function toXeroItem(item: Item) { @@ -36,8 +39,9 @@ export function toXeroItem(item: Item) { return xeroItem; } -export function toFailedItem(xeroItem: any): FailedItem { - const failedItem = toItem(xeroItem) as FailedItem; - failedItem.validation_errors = xeroItem.ValidationErrors; - return failedItem; +export function toFailedItem(xeroItem: XeroItem): FailedItem { + return { + ...toItem(xeroItem), + validation_errors: xeroItem?.ValidationErrors || [] + }; } diff --git a/integrations/xero/mocks/accounts/batchDelete.json b/integrations/xero/mocks/accounts/batchDelete.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/integrations/xero/mocks/accounts/batchDelete.json @@ -0,0 +1 @@ +[] diff --git a/integrations/xero/mocks/accounts/batchSave.json b/integrations/xero/mocks/accounts/batchSave.json new file mode 100644 index 00000000..64777e98 --- /dev/null +++ b/integrations/xero/mocks/accounts/batchSave.json @@ -0,0 +1,650 @@ +[ + { + "id": "30ff270c-8b39-4eb3-9960-24ae430c33b7", + "code": "497", + "name": "Bank Revaluations", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "Bank account revaluations due for foreign exchange rate changes", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.FOR", + "reporting_code_name": "Foreign currency gains and losses" + }, + { + "id": "53b19303-260a-4761-a8da-7a8db4fab016", + "code": "498", + "name": "Unrealised Currency Gains", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "Unrealised currency gains on outstanding items", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.FOR.UGL", + "reporting_code_name": "Unrealised foreign currency gains and losses" + }, + { + "id": "fa5dd3c5-52ac-4180-9b29-cbe3b074503b", + "code": "499", + "name": "Realised Currency Gains", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "Gains or losses made due to currency exchange rate changes", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.FOR.RGL", + "reporting_code_name": "Realised foreign currency gains and losses" + }, + { + "id": "8b2b2367-2d57-47a2-a826-a296b45fbb1c", + "code": "200", + "name": "Sales", + "type": "REVENUE", + "tax_type": "OUTPUT", + "description": "Income from any normal business activity", + "class": "REVENUE", + "bank_account_type": "NONE", + "reporting_code": "REV.TRA.GOO", + "reporting_code_name": "Sale of goods" + }, + { + "id": "70bb5ae4-d23b-46e5-b0ad-71d2843eef83", + "code": "260", + "name": "Other Revenue", + "type": "REVENUE", + "tax_type": "OUTPUT", + "description": "Any other income that does not relate to normal business activities and is not recurring", + "class": "REVENUE", + "bank_account_type": "", + "reporting_code": "REV.OTH", + "reporting_code_name": "Other Revenue" + }, + { + "id": "bffa539a-6a3f-4149-95d9-4ed9c5c69c7d", + "code": "270", + "name": "Interest Income", + "type": "REVENUE", + "tax_type": "NONE", + "description": "Interest income", + "class": "REVENUE", + "bank_account_type": "", + "reporting_code": "REV.INV.INT", + "reporting_code_name": "Interest" + }, + { + "id": "780d0375-0f63-4bb2-97ef-9f4e2e22baa9", + "code": "310", + "name": "Cost of Goods Sold", + "type": "DIRECTCOSTS", + "tax_type": "INPUT", + "description": "Cost of goods sold by the business", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.COS", + "reporting_code_name": "Cost of goods sold" + }, + { + "id": "7a2f8b09-3ad1-4cfe-9f29-9802cbacb7b3", + "code": "400", + "name": "Advertising", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred for advertising while trying to increase sales", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "ed924a15-7827-49a2-9dc9-288f4132a9b4", + "code": "404", + "name": "Bank Fees", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "Fees charged by your bank for transactions regarding your bank account(s).", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "96a68a74-d240-4331-bece-60fdeefff6d3", + "code": "408", + "name": "Cleaning", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred for cleaning business property.", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "e604400e-27be-4093-b875-a999023d7a45", + "code": "412", + "name": "Consulting & Accounting", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses related to paying consultants", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.LEG", + "reporting_code_name": "Professional and consulting fees" + }, + { + "id": "a103757f-37be-4dbc-9fd6-b249f261ab15", + "code": "416", + "name": "Depreciation", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "The amount of the asset's cost (based on the useful life) that was consumed during the period", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.DEP", + "reporting_code_name": "Depreciation" + }, + { + "id": "a63c7f54-9c52-4b19-bc0d-dd6bcc3ec9ba", + "code": "420", + "name": "Entertainment", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "Expenses paid by company for the business but are not deductable for income tax purposes.", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.ENT", + "reporting_code_name": "Entertainment" + }, + { + "id": "c2c1362c-5d0a-4884-9ea1-8abb06cd5fd0", + "code": "425", + "name": "Freight & Courier", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred on courier & freight costs", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "e70749bc-478e-4c90-bb10-d78b7ff57a5f", + "code": "429", + "name": "General Expenses", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "General expenses related to the running of the business.", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "23f029c6-68e6-4b52-a213-aba0d9a03862", + "code": "433", + "name": "Insurance", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred for insuring the business' assets", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.INS", + "reporting_code_name": "Insurance" + }, + { + "id": "ba326a82-1348-4e84-8c77-0e13ff3de6f4", + "code": "437", + "name": "Interest Expense", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "Any interest expenses paid to your tax authority, business bank accounts or credit card accounts.", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.INT", + "reporting_code_name": "Interest and finance charges" + }, + { + "id": "2dc70e01-6166-493f-8edb-cf56bd547edf", + "code": "441", + "name": "Legal expenses", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred on any legal matters", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.LEG", + "reporting_code_name": "Professional and consulting fees" + }, + { + "id": "72b54078-3d11-48ba-ac78-6183605a7732", + "code": "445", + "name": "Light, Power, Heating", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred for lighting, powering or heating the premises", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "f7a5d92f-79f5-45e7-bf4f-bb7512814cce", + "code": "449", + "name": "Motor Vehicle Expenses", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred on the running of company motor vehicles", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.VEH", + "reporting_code_name": "Vehicle expenses" + }, + { + "id": "1f056de8-fc55-4394-b945-58871388f03c", + "code": "453", + "name": "Office Expenses", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "General expenses related to the running of the business office.", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "90349379-e652-4f55-acdc-652af214e3f5", + "code": "461", + "name": "Printing & Stationery", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred by the entity as a result of printing and stationery", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "aaa6f160-b576-4f98-9014-41c87d19240b", + "code": "469", + "name": "Rent", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "The payment to lease a building or area.", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.REN", + "reporting_code_name": "Rental and lease payments" + }, + { + "id": "c0eac3a6-efbf-4efa-aad6-cd726f7da8ff", + "code": "473", + "name": "Repairs and Maintenance", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred on a damaged or run down asset that will bring the asset back to its original condition.", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.REP", + "reporting_code_name": "Repairs and maintenance" + }, + { + "id": "2cef7c59-c4cb-4306-865f-0b92fe499b22", + "code": "477", + "name": "Wages and Salaries", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "Payment to employees in exchange for their resources", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.EMP", + "reporting_code_name": "Employment costs" + }, + { + "id": "58301bd8-f438-45aa-855b-559b48d3b21c", + "code": "478", + "name": "Superannuation", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "Superannuation contributions", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.EMP.SUP", + "reporting_code_name": "Superannuation expenses" + }, + { + "id": "baa8751f-49fe-4e38-a961-68f2b6833147", + "code": "485", + "name": "Subscriptions", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "E.g. Magazines, professional bodies", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "08f4bd86-93d5-4335-8deb-41e2d11bd2db", + "code": "489", + "name": "Telephone & Internet", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenditure incurred from any business-related phone calls, phone lines, or internet connections", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP", + "reporting_code_name": "Expense" + }, + { + "id": "5c1b26b0-b2e7-4d00-9bbd-864f4cdf09de", + "code": "493", + "name": "Travel - National", + "type": "EXPENSE", + "tax_type": "INPUT", + "description": "Expenses incurred from domestic travel which has a business purpose", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.TRA", + "reporting_code_name": "Travel and accommodation" + }, + { + "id": "eb6bdb55-62f7-46c6-b55c-98aaf1c98c87", + "code": "494", + "name": "Travel - International", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "Expenses incurred from international travel which has a business purpose", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.TRA", + "reporting_code_name": "Travel and accommodation" + }, + { + "id": "ed68261d-b004-4b7b-8bcd-57e9661a5248", + "code": "505", + "name": "Income Tax Expense", + "type": "EXPENSE", + "tax_type": "NONE", + "description": "A percentage of total earnings paid to the government.", + "class": "EXPENSE", + "bank_account_type": "", + "reporting_code": "EXP.INC", + "reporting_code_name": "Income tax expense" + }, + { + "id": "8f3a00eb-bda9-4048-97ca-13c5ea10554c", + "code": "610", + "name": "Accounts Receivable", + "type": "CURRENT", + "tax_type": "NONE", + "description": "Outstanding invoices the company has issued out to the client but has not yet received in cash at balance date.", + "class": "ASSET", + "bank_account_type": "", + "reporting_code": "ASS.CUR.REC.TRA", + "reporting_code_name": "Trade receivables" + }, + { + "id": "61dae2d8-25b8-40d5-9593-0fd045f0ec59", + "code": "620", + "name": "Prepayments", + "type": "CURRENT", + "tax_type": "NONE", + "description": "An expenditure that has been paid for in advance.", + "class": "ASSET", + "bank_account_type": "", + "reporting_code": "ASS.CUR.REC.PRE", + "reporting_code_name": "Prepayments" + }, + { + "id": "dd173235-0570-44d8-970c-663c4436f27f", + "code": "630", + "name": "Inventory", + "type": "INVENTORY", + "tax_type": "NONE", + "description": "Value of tracked items for resale.", + "class": "ASSET", + "bank_account_type": "", + "reporting_code": "ASS.CUR.INY", + "reporting_code_name": "Inventories" + }, + { + "id": "c021c904-2ad5-4110-8c68-31053ab71329", + "code": "710", + "name": "Office Equipment", + "type": "FIXED", + "tax_type": "INPUT", + "description": "Office equipment that is owned and controlled by the business", + "class": "ASSET", + "bank_account_type": "", + "reporting_code": "ASS.NCA.FIX.OWN.PLA", + "reporting_code_name": "Plant and Machinery owned" + }, + { + "id": "049d5a1b-4138-4d80-83bd-a18900b8ea7a", + "code": "711", + "name": "Less Accumulated Depreciation on Office Equipment", + "type": "FIXED", + "tax_type": "NONE", + "description": "The total amount of office equipment cost that has been consumed by the entity (based on the useful life)", + "class": "ASSET", + "bank_account_type": "", + "reporting_code": "ASS.NCA.FIX.OWN.PLA.ACC", + "reporting_code_name": "Accumulated depreciation - plant and machinery owned" + }, + { + "id": "d8dfb8f9-13f6-454e-844f-9f0127b09594", + "code": "720", + "name": "Computer Equipment", + "type": "FIXED", + "tax_type": "INPUT", + "description": "Computer equipment that is owned and controlled by the business", + "class": "ASSET", + "bank_account_type": "", + "reporting_code": "ASS.NCA.FIX.OWN.PLA", + "reporting_code_name": "Plant and Machinery owned" + }, + { + "id": "d74556fb-7f89-4898-878e-16b45a78c91f", + "code": "721", + "name": "Less Accumulated Depreciation on Computer Equipment", + "type": "FIXED", + "tax_type": "NONE", + "description": "The total amount of computer equipment cost that has been consumed by the business (based on the useful life)", + "class": "ASSET", + "bank_account_type": "", + "reporting_code": "ASS.NCA.FIX.OWN.PLA.ACC", + "reporting_code_name": "Accumulated depreciation - plant and machinery owned" + }, + { + "id": "4ee01bbd-57aa-49ec-9d54-64b5763b8972", + "code": "800", + "name": "Accounts Payable", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "Outstanding invoices the company has received from suppliers but has not yet paid at balance date", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR.PAY.TRA", + "reporting_code_name": "Trade payables" + }, + { + "id": "f5bdf363-2517-4a66-a55c-9fd5727de3dd", + "code": "801", + "name": "Unpaid Expense Claims", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "Expense claims typically made by employees/shareholder employees still outstanding.", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR.PAY.EMP", + "reporting_code_name": "Employee entitlements (wages, annual leave, etc)" + }, + { + "id": "cbfff9ac-9c80-4d8d-961a-9c7ee32e5a1e", + "code": "803", + "name": "Wages Payable", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "Xero automatically updates this account for payroll entries created using Payroll and will store the payroll amount to be paid to the employee for the pay run. This account enables you to maintain separate accounts for employee Wages Payable amounts and Accounts Payable amounts", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR.PAY.EMP", + "reporting_code_name": "Employee entitlements (wages, annual leave, etc)" + }, + { + "id": "2488f6f0-3842-4f64-9890-7e5bb3801378", + "code": "820", + "name": "Sales Tax", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "The balance in this account represents Sales Tax owing to or from your tax authority. At the end of the tax period, it is this account that should be used to code against either the 'refunds from' or 'payments to' your tax authority that will appear on the bank statement. Xero has been designed to use only one sales tax account to track sales taxes on income and expenses, so there is no need to add any new sales tax accounts to Xero.", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR.TAX.VAT", + "reporting_code_name": "Value added tax" + }, + { + "id": "88002ad4-e7f9-4a8e-bb9a-5e22e9800957", + "code": "825", + "name": "Employee Tax Payable", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "The amount of tax that has been deducted from wages or salaries paid to employes and is due to be paid", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR.PAY.PAY", + "reporting_code_name": "PAYE" + }, + { + "id": "fc6932c7-ec5c-4195-a022-41cb165b0220", + "code": "826", + "name": "Superannuation Payable", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "The amount of superannuation that is due to be paid", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR.PAY.EMP", + "reporting_code_name": "Employee entitlements (wages, annual leave, etc)" + }, + { + "id": "a38268a3-ca10-4d99-a7f1-243917d3d728", + "code": "830", + "name": "Income Tax Payable", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "The amount of income tax that is due to be paid, also resident withholding tax paid on interest received.", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR.TAX.INC", + "reporting_code_name": "Income tax" + }, + { + "id": "ce60c71e-6eeb-4264-8421-027cc978f31d", + "code": "840", + "name": "Historical Adjustment", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "For accountant adjustments", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR", + "reporting_code_name": "Current liabilities" + }, + { + "id": "aed0023f-c5e6-469b-90d4-78837f594e5b", + "code": "850", + "name": "Suspense", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "An entry that allows an unknown transaction to be entered, so the accounts can still be worked on in balance and the entry can be dealt with later.", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR", + "reporting_code_name": "Current liabilities" + }, + { + "id": "e4e2cc1f-6064-4bcf-a7a9-3e6f8c9f746a", + "code": "860", + "name": "Rounding", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "An adjustment entry to allow for rounding", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR", + "reporting_code_name": "Current liabilities" + }, + { + "id": "12be2f75-d5cb-4ccd-9c9a-402e7cbefe40", + "code": "877", + "name": "Tracking Transfers", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "Transfers between tracking categories", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.CUR", + "reporting_code_name": "Current liabilities" + }, + { + "id": "f9f3ff8c-43db-4fe9-9d9c-4da35dfa3171", + "code": "880", + "name": "Owner A Drawings", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "Withdrawals by the owners", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "EQU.DRA", + "reporting_code_name": "Owners/partners drawings" + }, + { + "id": "22aa82e1-c51e-4226-bb82-cf0ade30bf26", + "code": "881", + "name": "Owner A Funds Introduced", + "type": "CURRLIAB", + "tax_type": "NONE", + "description": "Funds contributed by the owner", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "EQU.ADV", + "reporting_code_name": "Owners/partners funds introduced" + }, + { + "id": "78a462bc-c058-4ad4-b5fc-2869662a0eec", + "code": "900", + "name": "Loan", + "type": "TERMLIAB", + "tax_type": "NONE", + "description": "Money that has been borrowed from a creditor", + "class": "LIABILITY", + "bank_account_type": "", + "reporting_code": "LIA.NCL.LOA", + "reporting_code_name": "Loans (non current)" + }, + { + "id": "436d1cbd-92c9-42bf-8e9e-5f4eb0d80e95", + "code": "960", + "name": "Retained Earnings", + "type": "EQUITY", + "tax_type": "NONE", + "description": "Do not Use", + "class": "EQUITY", + "bank_account_type": "", + "reporting_code": "EQU.RET", + "reporting_code_name": "Retained earnings" + }, + { + "id": "3b9aa899-000d-418f-a510-03e9c982c909", + "code": "970", + "name": "Owner A Share Capital", + "type": "EQUITY", + "tax_type": "NONE", + "description": "The value of shares purchased by the shareholders", + "class": "EQUITY", + "bank_account_type": "", + "reporting_code": "EQU.SHA", + "reporting_code_name": "Share capital" + } +] diff --git a/integrations/xero/mocks/contacts/batchDelete.json b/integrations/xero/mocks/contacts/batchDelete.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/integrations/xero/mocks/contacts/batchDelete.json @@ -0,0 +1 @@ +[] diff --git a/integrations/xero/mocks/contacts/batchSave.json b/integrations/xero/mocks/contacts/batchSave.json new file mode 100644 index 00000000..d9885b2f --- /dev/null +++ b/integrations/xero/mocks/contacts/batchSave.json @@ -0,0 +1,30 @@ +[ + { + "id": "e1f8418e-a946-4013-80f6-ef52bb88f920", + "name": "XEro Test", + "external_id": null, + "tax_number": null, + "email": "foo@gmail.com", + "address_line_1": null, + "address_line_2": null, + "city": null, + "zip": null, + "country": null, + "state": null, + "phone": null + }, + { + "id": "15c526df-25da-413d-aad3-50d2b351a9c8", + "name": "My Supplier", + "external_id": null, + "tax_number": null, + "email": "who@gmail.com", + "address_line_1": null, + "address_line_2": null, + "city": null, + "zip": null, + "country": null, + "state": null, + "phone": "+5557774848" + } +] diff --git a/integrations/xero/mocks/invoices/batchDelete.json b/integrations/xero/mocks/invoices/batchDelete.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/integrations/xero/mocks/invoices/batchDelete.json @@ -0,0 +1 @@ +[] diff --git a/integrations/xero/mocks/invoices/batchSave.json b/integrations/xero/mocks/invoices/batchSave.json new file mode 100644 index 00000000..22c11edf --- /dev/null +++ b/integrations/xero/mocks/invoices/batchSave.json @@ -0,0 +1,45 @@ +[ + { + "id": "cadcbf72-b336-4380-be51-f46a6be0d3ef", + "type": "ACCPAY", + "external_contact_id": "15c526df-25da-413d-aad3-50d2b351a9c8", + "status": "DRAFT", + "issuing_date": "2024-09-27T00:00:00.000Z", + "payment_due_date": null, + "currency": "ILS", + "purchase_order": null, + "fees": [ + { + "item_id": "81c1aef8-18b1-4bbc-b22d-3917a0f1664b", + "description": "yes", + "units": null, + "precise_unit_amount": null, + "amount_cents": null, + "taxes_amount_cents": null + } + ] + }, + { + "id": "d1b1093e-b542-46b0-8017-564c0c30b005", + "type": "ACCREC", + "external_contact_id": "e1f8418e-a946-4013-80f6-ef52bb88f920", + "status": "AUTHORISED", + "issuing_date": "2024-09-27T00:00:00.000Z", + "payment_due_date": "2024-10-04T00:00:00.000Z", + "number": "INV-0001", + "currency": "ILS", + "purchase_order": null, + "fees": [ + { + "item_id": "bb537b0a-c9b5-4929-82c6-431de4e0d8ee", + "item_code": "item-1", + "description": "expensive item", + "units": 1, + "precise_unit_amount": 12, + "account_code": "200", + "amount_cents": 1200, + "taxes_amount_cents": null + } + ] + } +] diff --git a/integrations/xero/mocks/items/batchDelete.json b/integrations/xero/mocks/items/batchDelete.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/integrations/xero/mocks/items/batchDelete.json @@ -0,0 +1 @@ +[] diff --git a/integrations/xero/mocks/items/batchSave.json b/integrations/xero/mocks/items/batchSave.json new file mode 100644 index 00000000..1ed39ebc --- /dev/null +++ b/integrations/xero/mocks/items/batchSave.json @@ -0,0 +1,14 @@ +[ + { + "id": "ea10a915-3787-4c37-9ff7-ab33cc6b35f3", + "item_code": "item-1", + "name": "item-1", + "description": null + }, + { + "id": "2f3f08aa-5cc5-4e6d-8ef7-655dd02a6f92", + "item_code": "item-2", + "name": "item-2", + "description": null + } +] diff --git a/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Accounts.json b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Accounts.json new file mode 100644 index 00000000..4a96e419 --- /dev/null +++ b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Accounts.json @@ -0,0 +1,1034 @@ +{ + "Id": "3531fde5-f3c3-406d-b6c7-722ae27161aa", + "Status": "OK", + "ProviderName": "Nango Prod", + "DateTimeUTC": "/Date(1727424089378)/", + "Accounts": [ + { + "AccountID": "30ff270c-8b39-4eb3-9960-24ae430c33b7", + "Code": "497", + "Name": "Bank Revaluations", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "Bank account revaluations due for foreign exchange rate changes", + "Class": "EXPENSE", + "SystemAccount": "BANKCURRENCYGAIN", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.FOR", + "ReportingCodeName": "Foreign currency gains and losses", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1725956559780+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "53b19303-260a-4761-a8da-7a8db4fab016", + "Code": "498", + "Name": "Unrealised Currency Gains", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "Unrealised currency gains on outstanding items", + "Class": "EXPENSE", + "SystemAccount": "UNREALISEDCURRENCYGAIN", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.FOR.UGL", + "ReportingCodeName": "Unrealised foreign currency gains and losses", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1725956559780+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "fa5dd3c5-52ac-4180-9b29-cbe3b074503b", + "Code": "499", + "Name": "Realised Currency Gains", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "Gains or losses made due to currency exchange rate changes", + "Class": "EXPENSE", + "SystemAccount": "REALISEDCURRENCYGAIN", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.FOR.RGL", + "ReportingCodeName": "Realised foreign currency gains and losses", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1725956559780+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "8b2b2367-2d57-47a2-a826-a296b45fbb1c", + "Code": "200", + "Name": "Sales", + "Status": "ACTIVE", + "Type": "REVENUE", + "TaxType": "OUTPUT", + "Description": "Income from any normal business activity", + "Class": "REVENUE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "NONE", + "ReportingCode": "REV.TRA.GOO", + "ReportingCodeName": "Sale of goods", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "70bb5ae4-d23b-46e5-b0ad-71d2843eef83", + "Code": "260", + "Name": "Other Revenue", + "Status": "ACTIVE", + "Type": "REVENUE", + "TaxType": "OUTPUT", + "Description": "Any other income that does not relate to normal business activities and is not recurring", + "Class": "REVENUE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "REV.OTH", + "ReportingCodeName": "Other Revenue", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "bffa539a-6a3f-4149-95d9-4ed9c5c69c7d", + "Code": "270", + "Name": "Interest Income", + "Status": "ACTIVE", + "Type": "REVENUE", + "TaxType": "NONE", + "Description": "Interest income", + "Class": "REVENUE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "REV.INV.INT", + "ReportingCodeName": "Interest", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "780d0375-0f63-4bb2-97ef-9f4e2e22baa9", + "Code": "310", + "Name": "Cost of Goods Sold", + "Status": "ACTIVE", + "Type": "DIRECTCOSTS", + "TaxType": "INPUT", + "Description": "Cost of goods sold by the business", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.COS", + "ReportingCodeName": "Cost of goods sold", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "7a2f8b09-3ad1-4cfe-9f29-9802cbacb7b3", + "Code": "400", + "Name": "Advertising", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred for advertising while trying to increase sales", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "ed924a15-7827-49a2-9dc9-288f4132a9b4", + "Code": "404", + "Name": "Bank Fees", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "Fees charged by your bank for transactions regarding your bank account(s).", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "96a68a74-d240-4331-bece-60fdeefff6d3", + "Code": "408", + "Name": "Cleaning", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred for cleaning business property.", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "e604400e-27be-4093-b875-a999023d7a45", + "Code": "412", + "Name": "Consulting & Accounting", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses related to paying consultants", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.LEG", + "ReportingCodeName": "Professional and consulting fees", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "a103757f-37be-4dbc-9fd6-b249f261ab15", + "Code": "416", + "Name": "Depreciation", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "The amount of the asset's cost (based on the useful life) that was consumed during the period", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.DEP", + "ReportingCodeName": "Depreciation", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "a63c7f54-9c52-4b19-bc0d-dd6bcc3ec9ba", + "Code": "420", + "Name": "Entertainment", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "Expenses paid by company for the business but are not deductable for income tax purposes.", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.ENT", + "ReportingCodeName": "Entertainment", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "c2c1362c-5d0a-4884-9ea1-8abb06cd5fd0", + "Code": "425", + "Name": "Freight & Courier", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred on courier & freight costs", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "e70749bc-478e-4c90-bb10-d78b7ff57a5f", + "Code": "429", + "Name": "General Expenses", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "General expenses related to the running of the business.", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "23f029c6-68e6-4b52-a213-aba0d9a03862", + "Code": "433", + "Name": "Insurance", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred for insuring the business' assets", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.INS", + "ReportingCodeName": "Insurance", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "ba326a82-1348-4e84-8c77-0e13ff3de6f4", + "Code": "437", + "Name": "Interest Expense", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "Any interest expenses paid to your tax authority, business bank accounts or credit card accounts.", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.INT", + "ReportingCodeName": "Interest and finance charges", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "2dc70e01-6166-493f-8edb-cf56bd547edf", + "Code": "441", + "Name": "Legal expenses", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred on any legal matters", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.LEG", + "ReportingCodeName": "Professional and consulting fees", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "72b54078-3d11-48ba-ac78-6183605a7732", + "Code": "445", + "Name": "Light, Power, Heating", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred for lighting, powering or heating the premises", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "f7a5d92f-79f5-45e7-bf4f-bb7512814cce", + "Code": "449", + "Name": "Motor Vehicle Expenses", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred on the running of company motor vehicles", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.VEH", + "ReportingCodeName": "Vehicle expenses", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "1f056de8-fc55-4394-b945-58871388f03c", + "Code": "453", + "Name": "Office Expenses", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "General expenses related to the running of the business office.", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "90349379-e652-4f55-acdc-652af214e3f5", + "Code": "461", + "Name": "Printing & Stationery", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred by the entity as a result of printing and stationery", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "aaa6f160-b576-4f98-9014-41c87d19240b", + "Code": "469", + "Name": "Rent", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "The payment to lease a building or area.", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.REN", + "ReportingCodeName": "Rental and lease payments", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "c0eac3a6-efbf-4efa-aad6-cd726f7da8ff", + "Code": "473", + "Name": "Repairs and Maintenance", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred on a damaged or run down asset that will bring the asset back to its original condition.", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.REP", + "ReportingCodeName": "Repairs and maintenance", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "2cef7c59-c4cb-4306-865f-0b92fe499b22", + "Code": "477", + "Name": "Wages and Salaries", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "Payment to employees in exchange for their resources", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.EMP", + "ReportingCodeName": "Employment costs", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "58301bd8-f438-45aa-855b-559b48d3b21c", + "Code": "478", + "Name": "Superannuation", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "Superannuation contributions", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.EMP.SUP", + "ReportingCodeName": "Superannuation expenses", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "baa8751f-49fe-4e38-a961-68f2b6833147", + "Code": "485", + "Name": "Subscriptions", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "E.g. Magazines, professional bodies", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "08f4bd86-93d5-4335-8deb-41e2d11bd2db", + "Code": "489", + "Name": "Telephone & Internet", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenditure incurred from any business-related phone calls, phone lines, or internet connections", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP", + "ReportingCodeName": "Expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "5c1b26b0-b2e7-4d00-9bbd-864f4cdf09de", + "Code": "493", + "Name": "Travel - National", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "INPUT", + "Description": "Expenses incurred from domestic travel which has a business purpose", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.TRA", + "ReportingCodeName": "Travel and accommodation", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "eb6bdb55-62f7-46c6-b55c-98aaf1c98c87", + "Code": "494", + "Name": "Travel - International", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "Expenses incurred from international travel which has a business purpose", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.TRA", + "ReportingCodeName": "Travel and accommodation", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "ed68261d-b004-4b7b-8bcd-57e9661a5248", + "Code": "505", + "Name": "Income Tax Expense", + "Status": "ACTIVE", + "Type": "EXPENSE", + "TaxType": "NONE", + "Description": "A percentage of total earnings paid to the government.", + "Class": "EXPENSE", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EXP.INC", + "ReportingCodeName": "Income tax expense", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "8f3a00eb-bda9-4048-97ca-13c5ea10554c", + "Code": "610", + "Name": "Accounts Receivable", + "Status": "ACTIVE", + "Type": "CURRENT", + "TaxType": "NONE", + "Description": "Outstanding invoices the company has issued out to the client but has not yet received in cash at balance date.", + "Class": "ASSET", + "SystemAccount": "DEBTORS", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "ASS.CUR.REC.TRA", + "ReportingCodeName": "Trade receivables", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "61dae2d8-25b8-40d5-9593-0fd045f0ec59", + "Code": "620", + "Name": "Prepayments", + "Status": "ACTIVE", + "Type": "CURRENT", + "TaxType": "NONE", + "Description": "An expenditure that has been paid for in advance.", + "Class": "ASSET", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "ASS.CUR.REC.PRE", + "ReportingCodeName": "Prepayments", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "dd173235-0570-44d8-970c-663c4436f27f", + "Code": "630", + "Name": "Inventory", + "Status": "ACTIVE", + "Type": "INVENTORY", + "TaxType": "NONE", + "Description": "Value of tracked items for resale.", + "Class": "ASSET", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "ASS.CUR.INY", + "ReportingCodeName": "Inventories", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "c021c904-2ad5-4110-8c68-31053ab71329", + "Code": "710", + "Name": "Office Equipment", + "Status": "ACTIVE", + "Type": "FIXED", + "TaxType": "INPUT", + "Description": "Office equipment that is owned and controlled by the business", + "Class": "ASSET", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "ASS.NCA.FIX.OWN.PLA", + "ReportingCodeName": "Plant and Machinery owned", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "049d5a1b-4138-4d80-83bd-a18900b8ea7a", + "Code": "711", + "Name": "Less Accumulated Depreciation on Office Equipment", + "Status": "ACTIVE", + "Type": "FIXED", + "TaxType": "NONE", + "Description": "The total amount of office equipment cost that has been consumed by the entity (based on the useful life)", + "Class": "ASSET", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "ASS.NCA.FIX.OWN.PLA.ACC", + "ReportingCodeName": "Accumulated depreciation - plant and machinery owned", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "d8dfb8f9-13f6-454e-844f-9f0127b09594", + "Code": "720", + "Name": "Computer Equipment", + "Status": "ACTIVE", + "Type": "FIXED", + "TaxType": "INPUT", + "Description": "Computer equipment that is owned and controlled by the business", + "Class": "ASSET", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "ASS.NCA.FIX.OWN.PLA", + "ReportingCodeName": "Plant and Machinery owned", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "d74556fb-7f89-4898-878e-16b45a78c91f", + "Code": "721", + "Name": "Less Accumulated Depreciation on Computer Equipment", + "Status": "ACTIVE", + "Type": "FIXED", + "TaxType": "NONE", + "Description": "The total amount of computer equipment cost that has been consumed by the business (based on the useful life)", + "Class": "ASSET", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "ASS.NCA.FIX.OWN.PLA.ACC", + "ReportingCodeName": "Accumulated depreciation - plant and machinery owned", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "4ee01bbd-57aa-49ec-9d54-64b5763b8972", + "Code": "800", + "Name": "Accounts Payable", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "Outstanding invoices the company has received from suppliers but has not yet paid at balance date", + "Class": "LIABILITY", + "SystemAccount": "CREDITORS", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR.PAY.TRA", + "ReportingCodeName": "Trade payables", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "f5bdf363-2517-4a66-a55c-9fd5727de3dd", + "Code": "801", + "Name": "Unpaid Expense Claims", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "Expense claims typically made by employees/shareholder employees still outstanding.", + "Class": "LIABILITY", + "SystemAccount": "UNPAIDEXPCLM", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR.PAY.EMP", + "ReportingCodeName": "Employee entitlements (wages, annual leave, etc)", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "cbfff9ac-9c80-4d8d-961a-9c7ee32e5a1e", + "Code": "803", + "Name": "Wages Payable", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "Xero automatically updates this account for payroll entries created using Payroll and will store the payroll amount to be paid to the employee for the pay run. This account enables you to maintain separate accounts for employee Wages Payable amounts and Accounts Payable amounts", + "Class": "LIABILITY", + "SystemAccount": "WAGEPAYABLES", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR.PAY.EMP", + "ReportingCodeName": "Employee entitlements (wages, annual leave, etc)", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "2488f6f0-3842-4f64-9890-7e5bb3801378", + "Code": "820", + "Name": "Sales Tax", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "The balance in this account represents Sales Tax owing to or from your tax authority. At the end of the tax period, it is this account that should be used to code against either the 'refunds from' or 'payments to' your tax authority that will appear on the bank statement. Xero has been designed to use only one sales tax account to track sales taxes on income and expenses, so there is no need to add any new sales tax accounts to Xero.", + "Class": "LIABILITY", + "SystemAccount": "GST", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR.TAX.VAT", + "ReportingCodeName": "Value added tax", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "88002ad4-e7f9-4a8e-bb9a-5e22e9800957", + "Code": "825", + "Name": "Employee Tax Payable", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "The amount of tax that has been deducted from wages or salaries paid to employes and is due to be paid", + "Class": "LIABILITY", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR.PAY.PAY", + "ReportingCodeName": "PAYE", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "fc6932c7-ec5c-4195-a022-41cb165b0220", + "Code": "826", + "Name": "Superannuation Payable", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "The amount of superannuation that is due to be paid", + "Class": "LIABILITY", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR.PAY.EMP", + "ReportingCodeName": "Employee entitlements (wages, annual leave, etc)", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "a38268a3-ca10-4d99-a7f1-243917d3d728", + "Code": "830", + "Name": "Income Tax Payable", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "The amount of income tax that is due to be paid, also resident withholding tax paid on interest received.", + "Class": "LIABILITY", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR.TAX.INC", + "ReportingCodeName": "Income tax", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "ce60c71e-6eeb-4264-8421-027cc978f31d", + "Code": "840", + "Name": "Historical Adjustment", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "For accountant adjustments", + "Class": "LIABILITY", + "SystemAccount": "HISTORICAL", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR", + "ReportingCodeName": "Current liabilities", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "aed0023f-c5e6-469b-90d4-78837f594e5b", + "Code": "850", + "Name": "Suspense", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "An entry that allows an unknown transaction to be entered, so the accounts can still be worked on in balance and the entry can be dealt with later.", + "Class": "LIABILITY", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR", + "ReportingCodeName": "Current liabilities", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "e4e2cc1f-6064-4bcf-a7a9-3e6f8c9f746a", + "Code": "860", + "Name": "Rounding", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "An adjustment entry to allow for rounding", + "Class": "LIABILITY", + "SystemAccount": "ROUNDING", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR", + "ReportingCodeName": "Current liabilities", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "12be2f75-d5cb-4ccd-9c9a-402e7cbefe40", + "Code": "877", + "Name": "Tracking Transfers", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "Transfers between tracking categories", + "Class": "LIABILITY", + "SystemAccount": "TRACKINGTRANSFERS", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.CUR", + "ReportingCodeName": "Current liabilities", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "f9f3ff8c-43db-4fe9-9d9c-4da35dfa3171", + "Code": "880", + "Name": "Owner A Drawings", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "Withdrawals by the owners", + "Class": "LIABILITY", + "SystemAccount": "", + "EnablePaymentsToAccount": true, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EQU.DRA", + "ReportingCodeName": "Owners/partners drawings", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "22aa82e1-c51e-4226-bb82-cf0ade30bf26", + "Code": "881", + "Name": "Owner A Funds Introduced", + "Status": "ACTIVE", + "Type": "CURRLIAB", + "TaxType": "NONE", + "Description": "Funds contributed by the owner", + "Class": "LIABILITY", + "SystemAccount": "", + "EnablePaymentsToAccount": true, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EQU.ADV", + "ReportingCodeName": "Owners/partners funds introduced", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "78a462bc-c058-4ad4-b5fc-2869662a0eec", + "Code": "900", + "Name": "Loan", + "Status": "ACTIVE", + "Type": "TERMLIAB", + "TaxType": "NONE", + "Description": "Money that has been borrowed from a creditor", + "Class": "LIABILITY", + "SystemAccount": "", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "LIA.NCL.LOA", + "ReportingCodeName": "Loans (non current)", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "436d1cbd-92c9-42bf-8e9e-5f4eb0d80e95", + "Code": "960", + "Name": "Retained Earnings", + "Status": "ACTIVE", + "Type": "EQUITY", + "TaxType": "NONE", + "Description": "Do not Use", + "Class": "EQUITY", + "SystemAccount": "RETAINEDEARNINGS", + "EnablePaymentsToAccount": false, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EQU.RET", + "ReportingCodeName": "Retained earnings", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + }, + { + "AccountID": "3b9aa899-000d-418f-a510-03e9c982c909", + "Code": "970", + "Name": "Owner A Share Capital", + "Status": "ACTIVE", + "Type": "EQUITY", + "TaxType": "NONE", + "Description": "The value of shares purchased by the shareholders", + "Class": "EQUITY", + "SystemAccount": "", + "EnablePaymentsToAccount": true, + "ShowInExpenseClaims": false, + "BankAccountType": "", + "ReportingCode": "EQU.SHA", + "ReportingCodeName": "Share capital", + "HasAttachments": false, + "UpdatedDateUTC": "/Date(1710275008927+0000)/", + "AddToWatchlist": false + } + ] +} diff --git a/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Contacts.json b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Contacts.json new file mode 100644 index 00000000..d5ac4e38 --- /dev/null +++ b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Contacts.json @@ -0,0 +1,104 @@ +{ + "Id": "30f0b8a8-485f-4f86-a558-1eee04547ad7", + "Status": "OK", + "ProviderName": "Nango Prod", + "DateTimeUTC": "/Date(1727434428790)/", + "pagination": { + "page": 1, + "pageSize": 100, + "pageCount": 1, + "itemCount": 2 + }, + "Contacts": [ + { + "ContactID": "e1f8418e-a946-4013-80f6-ef52bb88f920", + "AccountNumber": "1233", + "ContactStatus": "ACTIVE", + "Name": "XEro Test", + "FirstName": "Mike", + "LastName": "Jones", + "EmailAddress": "foo@gmail.com", + "Addresses": [ + { + "AddressType": "POBOX" + }, + { + "AddressType": "STREET" + } + ], + "Phones": [ + { + "PhoneType": "DDI" + }, + { + "PhoneType": "DEFAULT" + }, + { + "PhoneType": "FAX" + }, + { + "PhoneType": "MOBILE" + } + ], + "UpdatedDateUTC": "/Date(1727423941333+0000)/", + "ContactGroups": [], + "IsSupplier": true, + "IsCustomer": true, + "Balances": { + "AccountsReceivable": { + "Outstanding": 11.99, + "Overdue": 0 + }, + "AccountsPayable": { + "Outstanding": 0, + "Overdue": 0 + } + }, + "ContactPersons": [], + "HasAttachments": false, + "HasValidationErrors": false + }, + { + "ContactID": "15c526df-25da-413d-aad3-50d2b351a9c8", + "AccountNumber": "343234", + "ContactStatus": "ACTIVE", + "Name": "My Supplier", + "FirstName": "Who", + "LastName": "Dat", + "EmailAddress": "who@gmail.com", + "Addresses": [ + { + "AddressType": "POBOX" + }, + { + "AddressType": "STREET" + } + ], + "Phones": [ + { + "PhoneType": "DDI" + }, + { + "PhoneType": "DEFAULT", + "PhoneNumber": "4848", + "PhoneAreaCode": "777", + "PhoneCountryCode": "555" + }, + { + "PhoneType": "FAX" + }, + { + "PhoneType": "MOBILE" + } + ], + "UpdatedDateUTC": "/Date(1727424030103+0000)/", + "ContactGroups": [], + "IsSupplier": true, + "IsCustomer": false, + "Website": "nango.dev.test.com", + "ContactPersons": [], + "HasAttachments": false, + "HasValidationErrors": false + } + ] +} diff --git a/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Invoices.json b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Invoices.json new file mode 100644 index 00000000..43c68cdc --- /dev/null +++ b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Invoices.json @@ -0,0 +1,126 @@ +{ + "Id": "595b031b-ac95-4a9d-b5b7-9877e42122c9", + "Status": "OK", + "ProviderName": "Nango Prod", + "DateTimeUTC": "/Date(1727425854646)/", + "pagination": { + "page": 1, + "pageSize": 100, + "pageCount": 1, + "itemCount": 2 + }, + "Invoices": [ + { + "Type": "ACCPAY", + "InvoiceID": "cadcbf72-b336-4380-be51-f46a6be0d3ef", + "Reference": "", + "Payments": [], + "CreditNotes": [], + "Prepayments": [], + "Overpayments": [], + "AmountDue": 0, + "AmountPaid": 0, + "AmountCredited": 0, + "CurrencyRate": 1, + "IsDiscounted": false, + "HasAttachments": false, + "InvoiceAddresses": [], + "HasErrors": false, + "InvoicePaymentServices": [], + "Contact": { + "ContactID": "15c526df-25da-413d-aad3-50d2b351a9c8", + "Name": "My Supplier", + "Addresses": [], + "Phones": [], + "ContactGroups": [], + "ContactPersons": [], + "HasValidationErrors": false + }, + "DateString": "2024-09-27T00:00:00", + "Date": "/Date(1727395200000+0000)/", + "Status": "DRAFT", + "LineAmountTypes": "Exclusive", + "LineItems": [ + { + "Description": "yes", + "Tracking": [], + "LineItemID": "81c1aef8-18b1-4bbc-b22d-3917a0f1664b" + } + ], + "SubTotal": 0, + "TotalTax": 0, + "Total": 0, + "UpdatedDateUTC": "/Date(1727424969817+0000)/", + "CurrencyCode": "ILS" + }, + { + "Type": "ACCREC", + "InvoiceID": "d1b1093e-b542-46b0-8017-564c0c30b005", + "InvoiceNumber": "INV-0001", + "Reference": "", + "Payments": [ + { + "PaymentID": "4cc047a8-4749-4fc5-9878-c27883708bd5", + "Date": "/Date(1483228800000+0000)/", + "Amount": 0.01, + "CurrencyRate": 1, + "HasAccount": false, + "HasValidationErrors": false + } + ], + "CreditNotes": [], + "Prepayments": [], + "Overpayments": [], + "AmountDue": 11.99, + "AmountPaid": 0.01, + "AmountCredited": 0, + "SentToContact": false, + "CurrencyRate": 1, + "IsDiscounted": false, + "HasAttachments": false, + "InvoiceAddresses": [], + "HasErrors": false, + "InvoicePaymentServices": [], + "Contact": { + "ContactID": "e1f8418e-a946-4013-80f6-ef52bb88f920", + "Name": "XEro Test", + "Addresses": [], + "Phones": [], + "ContactGroups": [], + "ContactPersons": [], + "HasValidationErrors": false + }, + "DateString": "2024-09-27T00:00:00", + "Date": "/Date(1727395200000+0000)/", + "DueDateString": "2024-10-04T00:00:00", + "DueDate": "/Date(1728000000000+0000)/", + "BrandingThemeID": "839f8833-b139-4eab-8c40-72a9aa1af521", + "Status": "AUTHORISED", + "LineAmountTypes": "Exclusive", + "LineItems": [ + { + "ItemCode": "item-1", + "Description": "expensive item", + "UnitAmount": 12, + "TaxType": "OUTPUT", + "TaxAmount": 0, + "LineAmount": 12, + "AccountCode": "200", + "Item": { + "ItemID": "ea10a915-3787-4c37-9ff7-ab33cc6b35f3", + "Code": "item-1" + }, + "Tracking": [], + "Quantity": 1, + "LineItemID": "bb537b0a-c9b5-4929-82c6-431de4e0d8ee", + "AccountID": "8b2b2367-2d57-47a2-a826-a296b45fbb1c" + } + ], + "SubTotal": 12, + "TotalTax": 0, + "Total": 12, + "UpdatedDateUTC": "/Date(1727425840500+0000)/", + "CurrencyCode": "ILS" + } + ] +} diff --git a/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Items.json b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Items.json new file mode 100644 index 00000000..38f35097 --- /dev/null +++ b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Items.json @@ -0,0 +1,28 @@ +{ + "Id": "ef8e06b5-b19d-44a4-975c-3e4fc14c4643", + "Status": "OK", + "ProviderName": "Nango Prod", + "DateTimeUTC": "/Date(1727434445046)/", + "Items": [ + { + "ItemID": "ea10a915-3787-4c37-9ff7-ab33cc6b35f3", + "Code": "item-1", + "UpdatedDateUTC": "/Date(1727424652683+0000)/", + "PurchaseDetails": {}, + "SalesDetails": {}, + "IsTrackedAsInventory": false, + "IsSold": true, + "IsPurchased": true + }, + { + "ItemID": "2f3f08aa-5cc5-4e6d-8ef7-655dd02a6f92", + "Code": "item-2", + "UpdatedDateUTC": "/Date(1727430104260+0000)/", + "PurchaseDetails": {}, + "SalesDetails": {}, + "IsTrackedAsInventory": false, + "IsSold": true, + "IsPurchased": true + } + ] +} diff --git a/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Payments.json b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Payments.json new file mode 100644 index 00000000..82859ce8 --- /dev/null +++ b/integrations/xero/mocks/nango/get/proxy/api.xro/2.0/Payments.json @@ -0,0 +1,54 @@ +{ + "Id": "9045bd0f-0662-4157-82c3-ebc65787e082", + "Status": "OK", + "ProviderName": "Nango Prod", + "DateTimeUTC": "/Date(1727425866553)/", + "pagination": { + "page": 1, + "pageSize": 100, + "pageCount": 1, + "itemCount": 1 + }, + "Payments": [ + { + "PaymentID": "4cc047a8-4749-4fc5-9878-c27883708bd5", + "Date": "/Date(1483228800000+0000)/", + "BankAmount": 0.01, + "Amount": 0.01, + "CurrencyRate": 1, + "PaymentType": "ACCRECPAYMENT", + "Status": "AUTHORISED", + "UpdatedDateUTC": "/Date(1727425840517+0000)/", + "HasAccount": true, + "IsReconciled": false, + "Account": { + "AccountID": "11364b86-dce6-4f77-8b62-437b7760c605" + }, + "Invoice": { + "Type": "ACCREC", + "InvoiceID": "d1b1093e-b542-46b0-8017-564c0c30b005", + "InvoiceNumber": "INV-0001", + "Payments": [], + "CreditNotes": [], + "Prepayments": [], + "Overpayments": [], + "IsDiscounted": false, + "InvoiceAddresses": [], + "HasErrors": false, + "InvoicePaymentServices": [], + "Contact": { + "ContactID": "e1f8418e-a946-4013-80f6-ef52bb88f920", + "Name": "XEro Test", + "Addresses": [], + "Phones": [], + "ContactGroups": [], + "ContactPersons": [], + "HasValidationErrors": false + }, + "LineItems": [], + "CurrencyCode": "ILS" + }, + "HasValidationErrors": false + } + ] +} diff --git a/integrations/xero/mocks/nango/getConnection.json b/integrations/xero/mocks/nango/getConnection.json new file mode 100644 index 00000000..a8fce210 --- /dev/null +++ b/integrations/xero/mocks/nango/getConnection.json @@ -0,0 +1,6 @@ +{ + "metadata": null, + "connection_config": { + "tenant_id": "49acbbb0-5589-45fa-a7fc-733184e4f27a" + } +} diff --git a/integrations/xero/mocks/nango/getMetadata.json b/integrations/xero/mocks/nango/getMetadata.json new file mode 100644 index 00000000..19765bd5 --- /dev/null +++ b/integrations/xero/mocks/nango/getMetadata.json @@ -0,0 +1 @@ +null diff --git a/integrations/xero/mocks/nango/post/proxy/api.xro/2.0/CreditNotes.json b/integrations/xero/mocks/nango/post/proxy/api.xro/2.0/CreditNotes.json new file mode 100644 index 00000000..0d579a1d --- /dev/null +++ b/integrations/xero/mocks/nango/post/proxy/api.xro/2.0/CreditNotes.json @@ -0,0 +1,87 @@ +{ + "Id": "a19d7e31-3613-42e3-b079-c577787d532a", + "Status": "OK", + "ProviderName": "Nango Prod", + "DateTimeUTC": "/Date(1727428638477)/", + "CreditNotes": [ + { + "CreditNoteID": "3a266323-f5df-4eba-a07d-716b298d0569", + "CreditNoteNumber": "CN001", + "Payments": [], + "ID": "3a266323-f5df-4eba-a07d-716b298d0569", + "HasErrors": false, + "CurrencyRate": 1, + "Type": "ACCPAYCREDIT", + "Reference": "Invoice123", + "RemainingCredit": 1150, + "Allocations": [], + "Contact": { + "ContactID": "e1f8418e-a946-4013-80f6-ef52bb88f920", + "AccountNumber": "1233", + "ContactStatus": "ACTIVE", + "Name": "XEro Test", + "FirstName": "Mike", + "LastName": "Jones", + "EmailAddress": "foo@gmail.com", + "Addresses": [ + { + "AddressType": "POBOX" + }, + { + "AddressType": "STREET" + } + ], + "Phones": [ + { + "PhoneType": "DEFAULT" + }, + { + "PhoneType": "DDI" + }, + { + "PhoneType": "FAX" + }, + { + "PhoneType": "MOBILE" + } + ], + "UpdatedDateUTC": "/Date(1727423941333+0000)/", + "ContactGroups": [], + "ContactPersons": [], + "HasValidationErrors": false + }, + "DateString": "2024-07-31T00:00:00", + "Date": "/Date(1722384000000+0000)/", + "Status": "DRAFT", + "LineAmountTypes": "Exclusive", + "LineItems": [ + { + "ItemCode": "item-1", + "Description": "Consulting services", + "UnitAmount": 100, + "TaxAmount": 150, + "LineAmount": 1000, + "Item": { + "ItemID": "ea10a915-3787-4c37-9ff7-ab33cc6b35f3", + "Code": "item-1" + }, + "Tracking": [], + "Quantity": 10, + "LineItemID": "6009f27a-aec3-4568-ae7b-0ebf32bafc67", + "ValidationErrors": [] + } + ], + "SubTotal": 1000, + "TotalTax": 150, + "Total": 1150, + "UpdatedDateUTC": "/Date(1727428638417+0000)/", + "CurrencyCode": "ILS", + "StatusAttributeString": "WARNING", + "Warnings": [ + { + "Message": "Account code '4000' has been removed as it does not match a recognised account." + } + ] + } + ] +} diff --git a/integrations/xero/mocks/nango/post/proxy/api.xro/2.0/Invoices.json b/integrations/xero/mocks/nango/post/proxy/api.xro/2.0/Invoices.json new file mode 100644 index 00000000..8b0ce65c --- /dev/null +++ b/integrations/xero/mocks/nango/post/proxy/api.xro/2.0/Invoices.json @@ -0,0 +1,83 @@ +{ + "Id": "2719f781-7aa5-4daa-b25b-d917f1f7f45e", + "Status": "OK", + "ProviderName": "Nango Prod", + "DateTimeUTC": "/Date(1727424969895)/", + "Invoices": [ + { + "Type": "ACCPAY", + "InvoiceID": "cadcbf72-b336-4380-be51-f46a6be0d3ef", + "Reference": "", + "Prepayments": [], + "Overpayments": [], + "AmountDue": 0, + "AmountPaid": 0, + "SentToContact": false, + "CurrencyRate": 1, + "IsDiscounted": false, + "HasErrors": false, + "InvoicePaymentServices": [], + "Contact": { + "ContactID": "15c526df-25da-413d-aad3-50d2b351a9c8", + "AccountNumber": "343234", + "ContactStatus": "ACTIVE", + "Name": "My Supplier", + "FirstName": "Who", + "LastName": "Dat", + "EmailAddress": "who@gmail.com", + "Addresses": [ + { + "AddressType": "POBOX" + }, + { + "AddressType": "STREET" + } + ], + "Phones": [ + { + "PhoneType": "DEFAULT", + "PhoneNumber": "4848", + "PhoneAreaCode": "777", + "PhoneCountryCode": "555" + }, + { + "PhoneType": "DDI" + }, + { + "PhoneType": "FAX" + }, + { + "PhoneType": "MOBILE" + } + ], + "UpdatedDateUTC": "/Date(1727424030103+0000)/", + "ContactGroups": [], + "IsSupplier": true, + "IsCustomer": false, + "Website": "nango.dev.test.com", + "SalesTrackingCategories": [], + "PurchasesTrackingCategories": [], + "ContactPersons": [], + "HasValidationErrors": false + }, + "DateString": "2024-09-27T00:00:00", + "Date": "/Date(1727395200000+0000)/", + "Status": "DRAFT", + "LineAmountTypes": "Exclusive", + "LineItems": [ + { + "Description": "yes", + "Tracking": [], + "LineItemID": "81c1aef8-18b1-4bbc-b22d-3917a0f1664b", + "ValidationErrors": [] + } + ], + "SubTotal": 0, + "TotalTax": 0, + "Total": 0, + "UpdatedDateUTC": "/Date(1727424969817+0000)/", + "CurrencyCode": "ILS", + "StatusAttributeString": "OK" + } + ] +} diff --git a/integrations/xero/mocks/nango/post/proxy/api.xro/2.0/Items.json b/integrations/xero/mocks/nango/post/proxy/api.xro/2.0/Items.json new file mode 100644 index 00000000..2f5d13e1 --- /dev/null +++ b/integrations/xero/mocks/nango/post/proxy/api.xro/2.0/Items.json @@ -0,0 +1,20 @@ +{ + "Id": "4b63a6db-8910-483e-b8f1-9dc08c78ffa8", + "Status": "OK", + "ProviderName": "Nango Prod", + "DateTimeUTC": "/Date(1727424652681)/", + "Items": [ + { + "ItemID": "ea10a915-3787-4c37-9ff7-ab33cc6b35f3", + "Code": "item-1", + "UpdatedDateUTC": "/Date(1727424652682)/", + "PurchaseDetails": {}, + "SalesDetails": {}, + "IsTrackedAsInventory": false, + "IsSold": true, + "IsPurchased": true, + "StatusAttributeString": "OK", + "ValidationErrors": [] + } + ] +} diff --git a/integrations/xero/mocks/nango/put/proxy/api.xro/2.0/Payments.json b/integrations/xero/mocks/nango/put/proxy/api.xro/2.0/Payments.json new file mode 100644 index 00000000..e0a0bf4e --- /dev/null +++ b/integrations/xero/mocks/nango/put/proxy/api.xro/2.0/Payments.json @@ -0,0 +1,84 @@ +{ + "Id": "f94a30e0-e776-4f10-b8c1-f7570f5153f8", + "Status": "OK", + "ProviderName": "Nango Prod", + "DateTimeUTC": "/Date(1727425840563)/", + "Payments": [ + { + "PaymentID": "4cc047a8-4749-4fc5-9878-c27883708bd5", + "Date": "/Date(1483228800000+0000)/", + "BankAmount": 0.01, + "Amount": 0.01, + "CurrencyRate": 1, + "PaymentType": "ACCRECPAYMENT", + "Status": "AUTHORISED", + "UpdatedDateUTC": "/Date(1727425840500+0000)/", + "HasAccount": true, + "IsReconciled": false, + "Account": { + "AccountID": "11364b86-dce6-4f77-8b62-437b7760c605", + "Name": "Test account" + }, + "Invoice": { + "Type": "ACCREC", + "InvoiceID": "d1b1093e-b542-46b0-8017-564c0c30b005", + "InvoiceNumber": "INV-0001", + "Reference": "", + "Prepayments": [], + "Overpayments": [], + "AmountDue": 11.99, + "AmountPaid": 0.01, + "SentToContact": false, + "CurrencyRate": 1, + "IsDiscounted": false, + "HasErrors": false, + "InvoicePaymentServices": [], + "Contact": { + "ContactID": "e1f8418e-a946-4013-80f6-ef52bb88f920", + "Name": "XEro Test", + "ContactPersons": [], + "HasValidationErrors": false + }, + "DateString": "2024-09-27T00:00:00", + "Date": "/Date(1727395200000+0000)/", + "DueDateString": "2024-10-04T00:00:00", + "DueDate": "/Date(1728000000000+0000)/", + "BrandingThemeID": "839f8833-b139-4eab-8c40-72a9aa1af521", + "Status": "AUTHORISED", + "LineAmountTypes": "Exclusive", + "LineItems": [ + { + "ItemCode": "item-1", + "Description": "expensive item", + "UnitAmount": 12, + "TaxType": "OUTPUT", + "TaxAmount": 0, + "LineAmount": 12, + "AccountCode": "200", + "Item": { + "ItemID": "ea10a915-3787-4c37-9ff7-ab33cc6b35f3", + "Code": "item-1" + }, + "Tracking": [], + "Quantity": 1, + "LineItemID": "bb537b0a-c9b5-4929-82c6-431de4e0d8ee", + "AccountID": "8b2b2367-2d57-47a2-a826-a296b45fbb1c", + "ValidationErrors": [] + } + ], + "SubTotal": 12, + "TotalTax": 0, + "Total": 12, + "UpdatedDateUTC": "/Date(1727425840500+0000)/", + "CurrencyCode": "ILS" + }, + "HasValidationErrors": false, + "StatusAttributeString": "WARNING", + "Warnings": [ + { + "Message": "The payment date is prior to the invoice date." + } + ] + } + ] +} diff --git a/integrations/xero/mocks/payments/batchDelete.json b/integrations/xero/mocks/payments/batchDelete.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/integrations/xero/mocks/payments/batchDelete.json @@ -0,0 +1 @@ +[] diff --git a/integrations/xero/mocks/payments/batchSave.json b/integrations/xero/mocks/payments/batchSave.json new file mode 100644 index 00000000..1ce7abc9 --- /dev/null +++ b/integrations/xero/mocks/payments/batchSave.json @@ -0,0 +1,11 @@ +[ + { + "id": "4cc047a8-4749-4fc5-9878-c27883708bd5", + "status": "AUTHORISED", + "invoice_id": "d1b1093e-b542-46b0-8017-564c0c30b005", + "credit_note_id": null, + "account_id": "11364b86-dce6-4f77-8b62-437b7760c605", + "date": "2017-01-01T00:00:00.000Z", + "amount_cents": 1 + } +] diff --git a/integrations/xero/nango.yaml b/integrations/xero/nango.yaml index cb294b0e..2674bc30 100644 --- a/integrations/xero/nango.yaml +++ b/integrations/xero/nango.yaml @@ -9,6 +9,7 @@ integrations: output: Contact sync_type: incremental endpoint: GET /xero/contacts + version: 1.0.0 accounts: description: | Fetches all accounts in Xero (chart of accounts). Incremental sync, detects deletes, metadata is not required. @@ -17,6 +18,7 @@ integrations: output: Account sync_type: incremental endpoint: GET /xero/accounts + version: 1.0.0 items: description: | Fetches all items in Xero. Incremental sync, does not detect deletes, metadata is not @@ -26,6 +28,7 @@ integrations: output: Item sync_type: incremental endpoint: GET /xero/items + version: 1.0.0 invoices: description: | Fetches all invoices in Xero. Incremental sync. @@ -34,6 +37,7 @@ integrations: output: Invoice sync_type: incremental endpoint: GET /xero/invoices + version: 1.0.0 payments: description: | Fetches all payments in Xero. Incremental sync. @@ -42,6 +46,7 @@ integrations: output: Payment sync_type: incremental endpoint: GET /xero/payments + version: 1.0.0 actions: create-contact: description: | @@ -51,6 +56,7 @@ integrations: scopes: accounting.contacts output: ContactActionResponse endpoint: POST /xero/contacts + version: 1.0.0 update-contact: description: > Updates one or multiple contacts in Xero. @@ -61,6 +67,7 @@ integrations: scopes: accounting.contacts output: ContactActionResponse endpoint: PUT /xero/contacts + version: 1.0.0 create-invoice: description: | Creates one or more invoices in Xero. @@ -69,7 +76,7 @@ integrations: scopes: accounting.transactions output: InvoiceActionResponse endpoint: POST /xero/invoices - version: 1.0.0 + version: 1.0.1 update-invoice: description: | Updates one or more invoices in Xero. To delete an invoice @@ -80,7 +87,7 @@ integrations: scopes: accounting.transactions output: InvoiceActionResponse endpoint: PUT /xero/invoices - version: 1.0.0 + version: 1.0.1 create-credit-note: description: | Creates one or more credit notes in Xero. @@ -89,6 +96,7 @@ integrations: scopes: accounting.transactions output: CreditNoteActionResponse endpoint: POST /xero/creditnotes + version: 1.0.0 update-credit-note: description: | Updates one or more credit notes in Xero. @@ -96,6 +104,7 @@ integrations: scopes: accounting.transactions output: CreditNoteActionResponse endpoint: PUT /xero/creditnotes + version: 1.0.0 create-payment: description: | Creates one or more payments in Xero. @@ -104,6 +113,7 @@ integrations: input: CreatePayment[] output: PaymentActionResponse endpoint: POST /xero/payments + version: 1.0.0 create-item: description: | Creates one or more items in Xero. @@ -112,6 +122,7 @@ integrations: input: Item[] output: ItemActionResponse endpoint: POST /xero/items + version: 1.0.0 update-item: description: | Updates one or more items in Xero. @@ -119,6 +130,7 @@ integrations: input: Item[] output: ItemActionResponse endpoint: PUT /xero/items + version: 1.0.0 models: ActionErrorResponse: @@ -140,9 +152,9 @@ models: Contact: __extends: BaseContact id: string - external_id?: string + external_id: string | null email: string | null - tax_number?: string | null + tax_number: string | null address_line_1?: string | null address_line_2?: string | null city: string | null @@ -284,12 +296,12 @@ models: external_contact_id: string status: string number: string - is_taxable: boolean - tax_rate_id: string - tax_rate: number + is_taxable?: boolean + tax_rate_id?: string + tax_rate?: number currency: string reference: string - issuing_date: date + issuing_date: date | null fees: CreditNoteFee[] CreditNoteFee: item_id: string diff --git a/integrations/xero/tests/xero-accounts.test.ts b/integrations/xero/tests/xero-accounts.test.ts new file mode 100644 index 00000000..a30709c5 --- /dev/null +++ b/integrations/xero/tests/xero-accounts.test.ts @@ -0,0 +1,27 @@ +import { vi, expect, it, describe } from "vitest"; +import type { NangoSync } from "../models.js"; + +import fetchData from "../syncs/accounts.js"; + +describe("xero accounts tests", () => { + const nangoMock = new global.vitest.NangoSyncMock({ + dirname: __dirname, + name: "accounts", + Model: "Account" + }); + it("should get, map correctly the data and batchSave the result", async () => { + await fetchData(nangoMock); + + const batchSaveData = await nangoMock.getBatchSaveData(); + expect(nangoMock.batchSave).toHaveBeenCalledWith(batchSaveData, "Account"); + }); + + it('should get, map correctly the data and batchDelete the result', async () => { + await fetchData(nangoMock); + + const batchDeleteData = await nangoMock.getBatchDeleteData(); + if (batchDeleteData && batchDeleteData.length > 0) { + expect(nangoMock.batchDelete).toHaveBeenCalledWith(batchDeleteData, "Account"); + } + }); +}); diff --git a/integrations/xero/tests/xero-contacts.test.ts b/integrations/xero/tests/xero-contacts.test.ts new file mode 100644 index 00000000..cde6a2ea --- /dev/null +++ b/integrations/xero/tests/xero-contacts.test.ts @@ -0,0 +1,27 @@ +import { vi, expect, it, describe } from "vitest"; +import type { NangoSync } from "../models.js"; + +import fetchData from "../syncs/contacts.js"; + +describe("xero contacts tests", () => { + const nangoMock = new global.vitest.NangoSyncMock({ + dirname: __dirname, + name: "contacts", + Model: "Contact" + }); + it("should get, map correctly the data and batchSave the result", async () => { + await fetchData(nangoMock); + + const batchSaveData = await nangoMock.getBatchSaveData(); + expect(nangoMock.batchSave).toHaveBeenCalledWith(batchSaveData, "Contact"); + }); + + it('should get, map correctly the data and batchDelete the result', async () => { + await fetchData(nangoMock); + + const batchDeleteData = await nangoMock.getBatchDeleteData(); + if (batchDeleteData && batchDeleteData.length > 0) { + expect(nangoMock.batchDelete).toHaveBeenCalledWith(batchDeleteData, "Contact"); + } + }); +}); diff --git a/integrations/xero/tests/xero-invoices.test.ts b/integrations/xero/tests/xero-invoices.test.ts new file mode 100644 index 00000000..136694f2 --- /dev/null +++ b/integrations/xero/tests/xero-invoices.test.ts @@ -0,0 +1,27 @@ +import { vi, expect, it, describe } from "vitest"; +import type { NangoSync } from "../models.js"; + +import fetchData from "../syncs/invoices.js"; + +describe("xero invoices tests", () => { + const nangoMock = new global.vitest.NangoSyncMock({ + dirname: __dirname, + name: "invoices", + Model: "Invoice" + }); + it("should get, map correctly the data and batchSave the result", async () => { + await fetchData(nangoMock); + + const batchSaveData = await nangoMock.getBatchSaveData(); + expect(nangoMock.batchSave).toHaveBeenCalledWith(batchSaveData, "Invoice"); + }); + + it('should get, map correctly the data and batchDelete the result', async () => { + await fetchData(nangoMock); + + const batchDeleteData = await nangoMock.getBatchDeleteData(); + if (batchDeleteData && batchDeleteData.length > 0) { + expect(nangoMock.batchDelete).toHaveBeenCalledWith(batchDeleteData, "Invoice"); + } + }); +}); diff --git a/integrations/xero/tests/xero-items.test.ts b/integrations/xero/tests/xero-items.test.ts new file mode 100644 index 00000000..f0d93c67 --- /dev/null +++ b/integrations/xero/tests/xero-items.test.ts @@ -0,0 +1,27 @@ +import { vi, expect, it, describe } from "vitest"; +import type { NangoSync } from "../models.js"; + +import fetchData from "../syncs/items.js"; + +describe("xero items tests", () => { + const nangoMock = new global.vitest.NangoSyncMock({ + dirname: __dirname, + name: "items", + Model: "Item" + }); + it("should get, map correctly the data and batchSave the result", async () => { + await fetchData(nangoMock); + + const batchSaveData = await nangoMock.getBatchSaveData(); + expect(nangoMock.batchSave).toHaveBeenCalledWith(batchSaveData, "Item"); + }); + + it('should get, map correctly the data and batchDelete the result', async () => { + await fetchData(nangoMock); + + const batchDeleteData = await nangoMock.getBatchDeleteData(); + if (batchDeleteData && batchDeleteData.length > 0) { + expect(nangoMock.batchDelete).toHaveBeenCalledWith(batchDeleteData, "Item"); + } + }); +}); diff --git a/integrations/xero/tests/xero-payments.test.ts b/integrations/xero/tests/xero-payments.test.ts new file mode 100644 index 00000000..6351c2f4 --- /dev/null +++ b/integrations/xero/tests/xero-payments.test.ts @@ -0,0 +1,27 @@ +import { vi, expect, it, describe } from "vitest"; +import type { NangoSync } from "../models.js"; + +import fetchData from "../syncs/payments.js"; + +describe("xero payments tests", () => { + const nangoMock = new global.vitest.NangoSyncMock({ + dirname: __dirname, + name: "payments", + Model: "Payment" + }); + it("should get, map correctly the data and batchSave the result", async () => { + await fetchData(nangoMock); + + const batchSaveData = await nangoMock.getBatchSaveData(); + expect(nangoMock.batchSave).toHaveBeenCalledWith(batchSaveData, "Payment"); + }); + + it('should get, map correctly the data and batchDelete the result', async () => { + await fetchData(nangoMock); + + const batchDeleteData = await nangoMock.getBatchDeleteData(); + if (batchDeleteData && batchDeleteData.length > 0) { + expect(nangoMock.batchDelete).toHaveBeenCalledWith(batchDeleteData, "Payment"); + } + }); +}); diff --git a/integrations/xero/types.ts b/integrations/xero/types.ts index 6df43734..e58b10c1 100644 --- a/integrations/xero/types.ts +++ b/integrations/xero/types.ts @@ -114,3 +114,49 @@ export interface Payment { CreditNoteID: string; }; } + +interface Warning { + Message: string; +} + +export interface CreditNote { + CreditNoteID: string; + CreditNoteNumber: string; + Payments: any[]; + ID: string; + HasErrors: boolean; + CurrencyRate: number; + Type: string; + Reference: string; + RemainingCredit: number; + Allocations: any[]; + Contact: Contact; + DateString: string; + Date: string; + Status: string; + LineAmountTypes: string; + LineItems: LineItem[]; + SubTotal: number; + TotalTax: number; + Total: number; + UpdatedDateUTC: string; + CurrencyCode: string; + StatusAttributeString: string; + Warnings: Warning[]; + ValidationErrors?: string[]; +} + +export interface Item { + ItemID: string; + Code: string; + UpdatedDateUTC: string; // Consider converting this to a Date object if needed + PurchaseDetails: Record; // Adjust as per the actual structure of PurchaseDetails + SalesDetails: Record; // Adjust as per the actual structure of SalesDetails + Name?: string; + Description?: string; + IsTrackedAsInventory: boolean; + IsSold: boolean; + IsPurchased: boolean; + StatusAttributeString: string; + ValidationErrors: string[]; // Specify the structure of ValidationErrors if known +} diff --git a/package-lock.json b/package-lock.json index f9264c2b..5c8651c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "husky": "8.0.3", "js-yaml": "4.1.0", "lint-staged": "15.2.9", - "nango": "^0.42.12", + "nango": "^0.42.13", "onchange": "7.1.0", "tsx": "^4.19.0", "typescript": "5.3.3", @@ -2155,9 +2155,9 @@ "dev": true }, "node_modules/@nangohq/nango-yaml": { - "version": "0.42.12", - "resolved": "https://registry.npmjs.org/@nangohq/nango-yaml/-/nango-yaml-0.42.12.tgz", - "integrity": "sha512-IXg6G6iZclJbDud7W5+rA3ntiycseeiTeKT9K08ybMGWYvuRN+9PhUiUkz7fyGIi6F0Liz+3/SKYAdzmgzZNng==", + "version": "0.42.13", + "resolved": "https://registry.npmjs.org/@nangohq/nango-yaml/-/nango-yaml-0.42.13.tgz", + "integrity": "sha512-z+Tw9CiyQSHylVg7lmgUVmahhIt3TdamgZerafvBsYth9ky/AR4i5CXStjDRN8CZvIkhkqCLP1t0FBDIxqtU8g==", "dev": true, "dependencies": { "js-yaml": "^4.1.0", @@ -2174,9 +2174,9 @@ } }, "node_modules/@nangohq/node": { - "version": "0.42.12", - "resolved": "https://registry.npmjs.org/@nangohq/node/-/node-0.42.12.tgz", - "integrity": "sha512-dVGbItAh6bk4YM0sQOYBsyx392IRusxpaC72Vqk9to7WTOZw4a9dRZQKL0BtZ+vh1bUAwSZICloFbBYAfsObdA==", + "version": "0.42.13", + "resolved": "https://registry.npmjs.org/@nangohq/node/-/node-0.42.13.tgz", + "integrity": "sha512-L/xRhJrmQZ40jxNa07oBU74MnvpZ8BKscmFtR1plU/b4oMSbYj2UwbwavsbceUnqQItO1pnRadjfNKMulCeZpw==", "dev": true, "dependencies": { "axios": "^1.7.4" @@ -2186,9 +2186,9 @@ } }, "node_modules/@nangohq/shared": { - "version": "0.42.12", - "resolved": "https://registry.npmjs.org/@nangohq/shared/-/shared-0.42.12.tgz", - "integrity": "sha512-AZ19nySq7KUMLWHae64dBd6lhwYk+8MDE5cqGFbrE5VXgThdHBGNapHHmPZmDtEBGzVBIwRFF12DRhlOG8dllQ==", + "version": "0.42.13", + "resolved": "https://registry.npmjs.org/@nangohq/shared/-/shared-0.42.13.tgz", + "integrity": "sha512-CdYPMOd20xcoW41ygTJ+4Ps5GdGQhLdq1yZH0yWksvDkiWLbvGs2p1NWKz5LRb7bTBNV6xogMy3qtKrhSwPlMg==", "bundleDependencies": [ "@nangohq/utils", "@nangohq/database" @@ -2199,8 +2199,8 @@ "@datadog/datadog-api-client": "1.26.0", "@hapi/boom": "^10.0.1", "@nangohq/database": "file:vendor/nangohq-database-1.0.0.tgz", - "@nangohq/nango-yaml": "^0.42.12", - "@nangohq/node": "^0.42.12", + "@nangohq/nango-yaml": "^0.42.13", + "@nangohq/node": "^0.42.13", "@nangohq/utils": "file:vendor/nangohq-utils-1.0.0.tgz", "@sentry/node": "^7.106.0", "ajv": "^8.12.0", @@ -5553,16 +5553,16 @@ } }, "node_modules/@smithy/core": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.5.tgz", - "integrity": "sha512-Z0qlPXgZ0pouYgnu/cZTEYeRAvniiKZmVl4wIbZHX/nEMHkMDV9ao6KFArsU9KndE0TuhL149xcRx45wfw1YCA==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.6.tgz", + "integrity": "sha512-6lQQp99hnyuNNIzeTYSzCUXJHwvvFLY7hfdFGSJM95tjRDJGfzWYFRBXPaM9766LiiTsQ561KErtbufzUFSYUg==", "dev": true, "dependencies": { "@smithy/middleware-endpoint": "^3.1.3", - "@smithy/middleware-retry": "^3.0.20", + "@smithy/middleware-retry": "^3.0.21", "@smithy/middleware-serde": "^3.0.6", "@smithy/protocol-http": "^4.1.3", - "@smithy/smithy-client": "^3.3.4", + "@smithy/smithy-client": "^3.3.5", "@smithy/types": "^3.4.2", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-middleware": "^3.0.6", @@ -5776,15 +5776,15 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.20.tgz", - "integrity": "sha512-HELCOVwYw5hFDBm69d+LmmGjBCjWnwp/t7SJiHmp+c4u9vgfIaCjdSeIdnlOsLrr5ic5jGTJXvJFUQnd987b/g==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.21.tgz", + "integrity": "sha512-/h0fElV95LekVVEJuSw+aI11S1Y3zIUwBc6h9ZbUv43Gl2weXsbQwjLoet6j/Qtb0phfrSxS6pNg6FqgJOWZkA==", "dev": true, "dependencies": { "@smithy/node-config-provider": "^3.1.7", "@smithy/protocol-http": "^4.1.3", "@smithy/service-error-classification": "^3.0.6", - "@smithy/smithy-client": "^3.3.4", + "@smithy/smithy-client": "^3.3.5", "@smithy/types": "^3.4.2", "@smithy/util-middleware": "^3.0.6", "@smithy/util-retry": "^3.0.6", @@ -5950,9 +5950,9 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.3.4.tgz", - "integrity": "sha512-NKw/2XxOW/Rg3rzB90HxsmGok5oS6vRzJgMh/JN4BHaOQQ4q5OuX999GmOGxEp730wbpIXIowfKZmIMXkG4v0Q==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.3.5.tgz", + "integrity": "sha512-7IZi8J3Dr9n3tX+lcpmJ/5tCYIqoXdblFBaPuv0SEKZFRpCxE+TqIWL6I3t7jLlk9TWu3JSvEZAhtjB9yvB+zA==", "dev": true, "dependencies": { "@smithy/middleware-endpoint": "^3.1.3", @@ -6050,13 +6050,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.20.tgz", - "integrity": "sha512-HpYmCpEThQJpCKzwzrGrklhdegRfuXI9keHRrHidbyEMliCdgic6t38MikJeZEkdIcEMhO1g95HIYMzjUzB+xg==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.21.tgz", + "integrity": "sha512-M/FhTBk4c/SsB91dD/M4gMGfJO7z/qJaM9+XQQIqBOf4qzZYMExnP7R4VdGwxxH8IKMGW+8F0I4rNtVRrcfPoA==", "dev": true, "dependencies": { "@smithy/property-provider": "^3.1.6", - "@smithy/smithy-client": "^3.3.4", + "@smithy/smithy-client": "^3.3.5", "@smithy/types": "^3.4.2", "bowser": "^2.11.0", "tslib": "^2.6.2" @@ -6066,16 +6066,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.20.tgz", - "integrity": "sha512-atdsHNtAX0rwTvRRGsrONU0C0XzapH6tI8T1y/OReOvWN7uBwXqqWRft6m8egU2DgeReU0xqT3PHdGCe5VRaaQ==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.21.tgz", + "integrity": "sha512-NiLinPvF86U3S2Pdx/ycqd4bnY5dmFSPNL5KYRwbNjqQFS09M5Wzqk8BNk61/47xCYz1X/6KeiSk9qgYPTtuDw==", "dev": true, "dependencies": { "@smithy/config-resolver": "^3.0.8", "@smithy/credential-provider-imds": "^3.2.3", "@smithy/node-config-provider": "^3.1.7", "@smithy/property-provider": "^3.1.6", - "@smithy/smithy-client": "^3.3.4", + "@smithy/smithy-client": "^3.3.5", "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, @@ -7199,9 +7199,9 @@ } }, "node_modules/b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", "dev": true }, "node_modules/balanced-match": { @@ -7211,9 +7211,9 @@ "dev": true }, "node_modules/bare-events": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", - "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", + "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", "dev": true, "optional": true }, @@ -9550,9 +9550,9 @@ } }, "node_modules/import-in-the-middle": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.0.tgz", - "integrity": "sha512-5DimNQGoe0pLUHbR9qK84iWaWjjbsxiqXnw6Qz64+azRgleqv9k2kTt5fw7QsOpmaGYtuxxursnPPsnTKEx10Q==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.1.tgz", + "integrity": "sha512-lGdg70ECFGv/OHQXL/IPhcxkFPeQ7YA4zborlA54XHVr58oM50QNxItRiayHMqj1MspC5Y9zaHf+QHod/gq7Ug==", "dev": true, "dependencies": { "acorn": "^8.8.2", @@ -10778,16 +10778,16 @@ } }, "node_modules/nango": { - "version": "0.42.12", - "resolved": "https://registry.npmjs.org/nango/-/nango-0.42.12.tgz", - "integrity": "sha512-h9TTDRXbZkJXptBck4KdV/if3QHtQ/AvjosZ1ggHhayM6anPEG3PmzIVRYDojjaKQrEqhpoPLyA0XCst+3XFFw==", + "version": "0.42.13", + "resolved": "https://registry.npmjs.org/nango/-/nango-0.42.13.tgz", + "integrity": "sha512-OUK9ZhdkuPBGUtZY+TSVVLOwiyv5VNNUVFdJVSlgdn3/Rx8ftQqeVKzzlx+sJ3P2A4sJoQ85uykWyOV36vq1Ew==", "dev": true, "dependencies": { "@babel/parser": "^7.22.5", "@babel/traverse": "^7.22.5", "@babel/types": "^7.22.5", - "@nangohq/nango-yaml": "^0.42.12", - "@nangohq/shared": "^0.42.12", + "@nangohq/nango-yaml": "^0.42.13", + "@nangohq/shared": "^0.42.13", "@swc/core": "^1.5.25", "ajv": "^8.12.0", "ajv-errors": "^3.0.0", diff --git a/package.json b/package.json index b8399b50..cddb9da9 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "lint": "eslint . --ext .ts", "fix": "eslint . --ext .ts --fix", - "move:integrations": "bash scripts/move-all-to-nango-integration-directories.bash", + "move:integrations": "bash scripts/move-all-to-nango-integration-directories.bash $npm_config_integration", "undo:move:integrations": "bash scripts/undo-move-to-nango-directories.bash", "lint-moved-integrations": "npm run move:integrations && npm run lint && npm run undo:move:integrations", "compile": "bash scripts/compile-all-templates.bash && npm run undo:move:integrations", @@ -31,7 +31,7 @@ "husky": "8.0.3", "js-yaml": "4.1.0", "lint-staged": "15.2.9", - "nango": "^0.42.12", + "nango": "^0.42.13", "onchange": "7.1.0", "tsx": "^4.19.0", "typescript": "5.3.3", diff --git a/scripts/move-all-to-nango-integration-directories.bash b/scripts/move-all-to-nango-integration-directories.bash index f4d827d3..6cbaf5e2 100755 --- a/scripts/move-all-to-nango-integration-directories.bash +++ b/scripts/move-all-to-nango-integration-directories.bash @@ -8,19 +8,40 @@ popd () { command popd "$@" > /dev/null } +# Check if npm_config_integration is set +if [ -n "$npm_config_integration" ]; then + integrations=("$npm_config_integration/") +else + cd integrations + integrations=(*/) + cd .. +fi + cd integrations -for d in */ ; do + +for d in "${integrations[@]}" ; do integration=$(echo $d | sed 's/\///g') - mkdir -p $integration/nango-integrations/$integration - # copy everything except the nango-integrations directory - rsync -av --exclude='nango-integrations' $integration/ $integration/nango-integrations/$integration --quiet + # Check if the integration directory exists (in case of single integration) + if [ ! -d "$integration" ]; then + echo "Integration directory $integration does not exist. Skipping..." + continue + fi + + mkdir -p "$integration/nango-integrations/$integration" + + # Copy everything except the nango-integrations directory + rsync -av --exclude='nango-integrations' "$integration/" "$integration/nango-integrations/$integration" --quiet - pushd $integration/nango-integrations - mv $integration/nango.yaml . + pushd "$integration/nango-integrations" + + mv "$integration/nango.yaml" . # Move the nango.yaml file to the correct location + + # Generate nango integration npx nango generate + popd - # delete everything except the nango-integrations directory - find $integration/* -maxdepth 0 -name 'nango-integrations' -prune -o -exec rm -rf {} + + # Delete everything except the nango-integrations directory + find "$integration"/* -maxdepth 0 -name 'nango-integrations' -prune -o -exec rm -rf {} + done diff --git a/scripts/tests/generate-tests.ts b/scripts/tests/generate-tests.ts index f8a22f27..2732d4e8 100644 --- a/scripts/tests/generate-tests.ts +++ b/scripts/tests/generate-tests.ts @@ -28,7 +28,7 @@ function generateSyncTest(integration: string, syncName: string, modelName: stri } = { integration, syncName, - modelName, + modelName }; console.log(`Data: ${JSON.stringify(data, null, 2)}`); diff --git a/vitest.setup.ts b/vitest.setup.ts index ccddd2d5..9a05bbd8 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -35,7 +35,6 @@ export class NangoSyncMock { this.patch = vi.fn(this.proxyPatchData.bind(this)); this.put = vi.fn(this.proxyPutData.bind(this)); this.delete = vi.fn(this.proxyDeleteData.bind(this)); - } private async getMockFile(fileName: string) { @@ -69,7 +68,7 @@ export class NangoSyncMock { return data; } - private async * getProxyPaginateData(args: any) { + private async *getProxyPaginateData(args: any) { const { endpoint: rawEndpoint, method = 'get', paginate } = args; const endpoint = rawEndpoint.startsWith('/') ? rawEndpoint.slice(1) : rawEndpoint; const data = await this.getMockFile(`nango/${method.toLowerCase()}/proxy/${endpoint}`); @@ -93,7 +92,7 @@ export class NangoSyncMock { const endpoint = rawEndpoint.startsWith('/') ? rawEndpoint.slice(1) : rawEndpoint; const data = await this.getMockFile(`nango/get/proxy/${endpoint}`); - return data; + return { data }; } private async proxyPostData(args: any) { @@ -101,7 +100,7 @@ export class NangoSyncMock { const endpoint = rawEndpoint.startsWith('/') ? rawEndpoint.slice(1) : rawEndpoint; const data = await this.getMockFile(`nango/post/proxy/${endpoint}`); - return data; + return { data }; } private async proxyPatchData(args: any) { @@ -109,7 +108,7 @@ export class NangoSyncMock { const endpoint = rawEndpoint.startsWith('/') ? rawEndpoint.slice(1) : rawEndpoint; const data = await this.getMockFile(`nango/patch/proxy/${endpoint}`); - return data; + return { data }; } private async proxyPutData(args: any) { @@ -117,7 +116,7 @@ export class NangoSyncMock { const endpoint = rawEndpoint.startsWith('/') ? rawEndpoint.slice(1) : rawEndpoint; const data = await this.getMockFile(`nango/put/proxy/${endpoint}`); - return data; + return { data }; } private async proxyDeleteData(args: any) { @@ -125,7 +124,7 @@ export class NangoSyncMock { const endpoint = rawEndpoint.startsWith('/') ? rawEndpoint.slice(1) : rawEndpoint; const data = await this.getMockFile(`nango/delete/proxy/${endpoint}`); - return data; + return { data }; } }