Add Expense and Estimate API

This commit is contained in:
trojanh 2020-02-03 17:27:39 +05:30
parent aceccf01d3
commit 9e7ac3c13f
6 changed files with 528 additions and 5 deletions

View file

@ -23,6 +23,16 @@ export const clientOperations = [
value: 'getAll',
description: 'Get data of all clients',
},
{
name: 'Create',
value: 'create',
description: `Create a client`,
},
{
name: 'Update',
value: 'update',
description: `Update a client`,
},
{
name: 'Delete',
value: 'delete',

View file

@ -23,6 +23,16 @@ export const contactOperations = [
value: 'getAll',
description: 'Get data of all contacts',
},
{
name: 'Create',
value: 'create',
description: `Create a contact`,
},
{
name: 'Update',
value: 'update',
description: `Update a contact`,
},
{
name: 'Delete',
value: 'delete',

View file

@ -23,6 +23,16 @@ export const estimateOperations = [
value: 'getAll',
description: 'Get data of all estimates',
},
{
name: 'Create',
value: 'create',
description: `Create a estimate`,
},
{
name: 'Update',
value: 'update',
description: `Update a estimate`,
},
{
name: 'Delete',
value: 'delete',
@ -179,6 +189,215 @@ export const estimateFields = [
},
},
description: 'The ID of the estimate want to delete.',
}
},
/* -------------------------------------------------------------------------- */
/* invoice:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'client_id',
name: 'client_id',
type: 'string',
displayOptions: {
show: {
operation: [
'create',
],
resource,
},
},
default: '',
required: true,
description: 'The ID of the client this estimate belongs to.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'create',
],
resource,
},
},
default: {},
options: [
{
displayName: 'Number',
name: 'number',
type: 'string',
default: '',
description: 'If no value is set, the number will be automatically generated.'
},
{
displayName: 'Purchase Order',
name: 'purchase_order',
type: 'string',
default: '',
description: 'The purchase order number.'
},
{
displayName: 'Tax',
name: 'tax',
type: 'string',
default: '',
description: 'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.'
},
{
displayName: 'Tax2',
name: 'tax2',
type: 'string',
default: '',
description: 'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.'
},
{
displayName: 'Discount',
name: 'over_budget_notification_percentage',
type: 'string',
default: '',
description: 'This percentage is subtracted from the subtotal. Example: use 10.0 for 10.0%.'
},
{
displayName: 'Subject',
name: 'subject',
type: 'string',
default: '',
description: 'The estimate subject.'
},
{
displayName: 'Currency',
name: 'currency',
type: 'string',
default: '',
description: 'The currency used by the estimate. If not provided, the clients currency will be used. See a list of supported currencies'
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Any additional notes to include on the estimate.'
},
{
displayName: 'Issue Date',
name: 'issue_date',
type: 'dateTime',
default: '',
description: 'Date the invoice was issued. Defaults to todays date.'
},
],
},
/* -------------------------------------------------------------------------- */
/* invoice:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Invoice Id',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'update',
],
resource,
},
},
description: 'The ID of the invoice want to update.',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'update',
],
resource,
},
},
default: {},
options: [
{
displayName: 'client_id',
name: 'client_id',
type: 'string',
default: '',
description: 'The ID of the retainer associated with this invoice..',
},
{
displayName: 'Number',
name: 'number',
type: 'string',
default: '',
description: 'If no value is set, the number will be automatically generated.'
},
{
displayName: 'Purchase Order',
name: 'purchase_order',
type: 'string',
default: '',
description: 'The purchase order number.'
},
{
displayName: 'Tax',
name: 'tax',
type: 'string',
default: '',
description: 'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.'
},
{
displayName: 'Tax2',
name: 'tax2',
type: 'string',
default: '',
description: 'This percentage is applied to the subtotal, including line items and discounts. Example: use 10.0 for 10.0%.'
},
{
displayName: 'Discount',
name: 'over_budget_notification_percentage',
type: 'string',
default: '',
description: 'This percentage is subtracted from the subtotal. Example: use 10.0 for 10.0%.'
},
{
displayName: 'Subject',
name: 'subject',
type: 'string',
default: '',
description: 'The estimate subject.'
},
{
displayName: 'Currency',
name: 'currency',
type: 'string',
default: '',
description: 'The currency used by the estimate. If not provided, the clients currency will be used. See a list of supported currencies'
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Any additional notes to include on the estimate.'
},
{
displayName: 'Issue Date',
name: 'issue_date',
type: 'dateTime',
default: '',
description: 'Date the invoice was issued. Defaults to todays date.'
},
],
},
] as INodeProperties[];

View file

@ -1,6 +1,6 @@
import { INodeProperties } from "n8n-workflow";
const resource = [ 'invoices' ];
const resource = [ 'expenses' ];
export const expenseOperations = [
{
@ -23,6 +23,16 @@ export const expenseOperations = [
value: 'getAll',
description: 'Get data of all expenses',
},
{
name: 'Create',
value: 'create',
description: `Create a expense`,
},
{
name: 'Update',
value: 'update',
description: `Update a expense`,
},
{
name: 'Delete',
value: 'delete',
@ -193,6 +203,205 @@ export const expenseFields = [
},
},
description: 'The ID of the expense you want to delete.',
}
},
/* -------------------------------------------------------------------------- */
/* expense:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Project Id',
name: 'project_id',
type: 'string',
displayOptions: {
show: {
operation: [
'create',
],
resource,
},
},
default: '',
required: true,
description: 'The ID of the project associated with this expense.',
},
{
displayName: 'Expense Category Id',
name: 'expense_category_id',
type: 'string',
displayOptions: {
show: {
operation: [
'create',
],
resource,
},
},
default: '',
required: true,
description: 'The ID of the expense category this expense is being tracked against.',
},
{
displayName: 'Spent Date',
name: 'spent_date',
type: 'dateTime',
displayOptions: {
show: {
operation: [
'create',
],
resource,
},
},
default: '',
required: true,
description: 'Date the expense occurred.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'create',
],
resource,
},
},
default: {},
options: [
{
displayName: 'User Id',
name: 'user_id',
type: 'boolean',
default: true,
description: 'The ID of the user associated with this expense. Defaults to the ID of the currently authenticated user.'
},
{
displayName: 'Units',
name: 'units',
type: 'string',
default: '',
description: 'The quantity of units to use in calculating the total_cost of the expense.'
},
{
displayName: 'Total Cost',
name: 'total_cost',
type: 'string',
default: '',
description: 'The total amount of the expense.'
},
{
displayName: 'Billable',
name: 'billable',
type: 'string',
default: '',
description: 'Whether this expense is billable or not. Defaults to true.'
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes about the expense.'
},
],
},
/* -------------------------------------------------------------------------- */
/* invoice:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Invoice Id',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'update',
],
resource,
},
},
description: 'The ID of the invoice want to update.',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'update',
],
resource,
},
},
default: {},
options: [
{
displayName: 'Project Id',
name: 'project_id',
type: 'string',
default: '',
description: 'The ID of the project associated with this expense.',
},
{
displayName: 'Expense Category Id',
name: 'expense_category_id',
type: 'string',
default: '',
description: 'The ID of the expense category this expense is being tracked against.',
},
{
displayName: 'Spent Date',
name: 'spent_date',
type: 'dateTime',
default: '',
description: 'Date the expense occurred.',
},
{
displayName: 'User Id',
name: 'user_id',
type: 'boolean',
default: true,
description: 'The ID of the user associated with this expense. Defaults to the ID of the currently authenticated user.'
},
{
displayName: 'Units',
name: 'units',
type: 'string',
default: '',
description: 'The quantity of units to use in calculating the total_cost of the expense.'
},
{
displayName: 'Total Cost',
name: 'total_cost',
type: 'string',
default: '',
description: 'The total amount of the expense.'
},
{
displayName: 'Billable',
name: 'billable',
type: 'string',
default: '',
description: 'Whether this expense is billable or not. Defaults to true.'
},
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes about the expense.'
},
],
},
] as INodeProperties[];

View file

@ -649,7 +649,41 @@ export class Harvest implements INodeType {
const responseData: IDataObject[] = await getAllResource.call(this, resource, i);
returnData.push.apply(returnData, responseData);
} else if (operation === 'delete') {
} else if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
endpoint = resource;
body.project_id = this.getNodeParameter('project_id', i) as string;
body.expense_category_id = this.getNodeParameter('expense_category_id', i) as string;
body.spent_date = this.getNodeParameter('spent_date', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
Object.assign(body, additionalFields);
const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
returnData.push(responseData);
} else if (operation === 'update') {
// ----------------------------------
// createByDuration
// ----------------------------------
requestMethod = 'PATCH';
const id = this.getNodeParameter('id', i) as string;
endpoint = `${resource}/${id}`;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
Object.assign(qs, updateFields);
const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
returnData.push(responseData);
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------
@ -685,7 +719,38 @@ export class Harvest implements INodeType {
const responseData: IDataObject[] = await getAllResource.call(this, resource, i);
returnData.push.apply(returnData, responseData);
} else if (operation === 'delete') {
} else if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
endpoint = resource;
body.client_id = this.getNodeParameter('client_id', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
Object.assign(body, additionalFields);
const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
returnData.push(responseData);
} else if (operation === 'update') {
// ----------------------------------
// createByDuration
// ----------------------------------
requestMethod = 'PATCH';
const id = this.getNodeParameter('id', i) as string;
endpoint = `${resource}/${id}`;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
Object.assign(qs, updateFields);
const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body);
returnData.push(responseData);
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------

View file

@ -23,6 +23,16 @@ export const invoiceOperations = [
value: 'getAll',
description: 'Get data of all invoices',
},
{
name: 'Create',
value: 'create',
description: `Create a invoice`,
},
{
name: 'Update',
value: 'update',
description: `Update a invoice`,
},
{
name: 'Delete',
value: 'delete',