Skip to content

Commit 77c67da

Browse files
committed
Create Contact action
1 parent af548b2 commit 77c67da

File tree

3 files changed

+342
-1
lines changed

3 files changed

+342
-1
lines changed
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
import { ConfigurationError } from "@pipedream/platform";
2+
import app from "../../sage_accounting.app.mjs";
3+
import {
4+
CREDIT_TERMS_OPTIONS, LOCALE_OPTIONS,
5+
} from "../../common/constants.mjs";
6+
7+
export default {
8+
key: "sage_accounting-create-contact",
9+
name: "Create Contact",
10+
description: "Creates a new contact in Sage Accounting. [See the documentation](https://developer.sage.com/accounting/reference/contacts/#tag/Contacts/operation/postContacts)",
11+
version: "0.0.1",
12+
type: "action",
13+
props: {
14+
app,
15+
name: {
16+
type: "string",
17+
label: "Name",
18+
description: "The contact's full name or business name",
19+
},
20+
contactTypeIds: {
21+
propDefinition: [
22+
app,
23+
"contactTypeIds",
24+
],
25+
},
26+
reference: {
27+
type: "string",
28+
label: "Reference",
29+
description: "Unique reference for the contact",
30+
optional: true,
31+
},
32+
taxNumber: {
33+
type: "string",
34+
label: "Tax Number",
35+
description: "The VAT registration number of the contact. The format will be validated.",
36+
optional: true,
37+
},
38+
notes: {
39+
type: "string",
40+
label: "Notes",
41+
description: "The notes for the contact",
42+
optional: true,
43+
},
44+
locale: {
45+
type: "string",
46+
label: "Locale",
47+
description: "The locale for the contact",
48+
optional: true,
49+
options: LOCALE_OPTIONS,
50+
},
51+
creditLimit: {
52+
type: "string",
53+
label: "Credit Limit",
54+
description: "Custom credit limit amount for the contact (not applicable to Start)",
55+
optional: true,
56+
},
57+
creditDays: {
58+
type: "integer",
59+
label: "Credit Days",
60+
description: "Custom credit days for the contact (0-365 days)",
61+
optional: true,
62+
min: 0,
63+
max: 365,
64+
},
65+
creditTerms: {
66+
type: "string",
67+
label: "Credit Terms",
68+
description: "Credit terms options determine how invoice due dates are calculated",
69+
optional: true,
70+
options: CREDIT_TERMS_OPTIONS,
71+
},
72+
creditTermsAndConditions: {
73+
type: "string",
74+
label: "Credit Terms and Conditions",
75+
description: "Custom terms and conditions for the contact (Customers only)",
76+
optional: true,
77+
},
78+
currencyId: {
79+
propDefinition: [
80+
app,
81+
"currencyId",
82+
],
83+
},
84+
auxReference: {
85+
type: "string",
86+
label: "Auxiliary Reference",
87+
description: "Auxiliary reference. Used for German 'Kreditorennummer' and 'Debitorennummer'",
88+
optional: true,
89+
},
90+
registeredNumber: {
91+
type: "string",
92+
label: "Registered Number",
93+
description: "The registered number of the contact's business (German 'Steuernummer')",
94+
optional: true,
95+
},
96+
taxCalculation: {
97+
type: "string",
98+
label: "Tax Calculation",
99+
description: "Tax calculation method (France: tax treatment for Vendors, Spain: Recargo de Equivalencia for Customers, UK: domestic reverse charge)",
100+
optional: true,
101+
},
102+
auxiliaryAccount: {
103+
type: "string",
104+
label: "Auxiliary Account",
105+
description: "Auxiliary account - used when auxiliary accounting is enabled (Spain and France only)",
106+
optional: true,
107+
},
108+
destinationVatBlocking: {
109+
type: "boolean",
110+
label: "Destination VAT Blocking",
111+
description: "Identifies if a contact should be blocked due to destination VAT",
112+
optional: true,
113+
},
114+
defaultSalesLedgerAccountId: {
115+
type: "string",
116+
label: "Default Sales Ledger Account ID",
117+
description: "The ID of the default sales ledger account for the contact",
118+
optional: true,
119+
},
120+
defaultSalesTaxRateId: {
121+
type: "string",
122+
label: "Default Sales Tax Rate ID",
123+
description: "The ID of the default sales tax rate for the contact",
124+
optional: true,
125+
},
126+
defaultPurchaseLedgerAccountId: {
127+
type: "string",
128+
label: "Default Purchase Ledger Account ID",
129+
description: "The ID of the default purchase ledger account for the contact",
130+
optional: true,
131+
},
132+
productSalesPriceTypeId: {
133+
type: "string",
134+
label: "Product Sales Price Type ID",
135+
description: "The ID of the product sales price type for the contact",
136+
optional: true,
137+
},
138+
sourceGuid: {
139+
type: "string",
140+
label: "Source GUID",
141+
description: "The GUID of the source for the contact",
142+
optional: true,
143+
},
144+
},
145+
async run({ $ }) {
146+
if (!this.name) {
147+
throw new ConfigurationError("Name is required");
148+
}
149+
if (!this.contactTypeIds || this.contactTypeIds.length === 0) {
150+
throw new ConfigurationError("At least one Contact Type ID is required");
151+
}
152+
153+
const response = await this.app.createContact({
154+
$,
155+
data: {
156+
name: this.name,
157+
contact_type_ids: this.contactTypeIds,
158+
reference: this.reference,
159+
default_sales_ledger_account_id: this.defaultSalesLedgerAccountId,
160+
default_sales_tax_rate_id: this.defaultSalesTaxRateId,
161+
default_purchase_ledger_account_id: this.defaultPurchaseLedgerAccountId,
162+
tax_number: this.taxNumber,
163+
notes: this.notes,
164+
locale: this.locale,
165+
credit_limit: this.creditLimit,
166+
credit_days: this.creditDays,
167+
credit_terms: this.creditTerms,
168+
credit_terms_and_conditions: this.creditTermsAndConditions,
169+
product_sales_price_type_id: this.productSalesPriceTypeId,
170+
source_guid: this.sourceGuid,
171+
currency_id: this.currencyId,
172+
aux_reference: this.auxReference,
173+
registered_number: this.registeredNumber,
174+
tax_calculation: this.taxCalculation,
175+
auxiliary_account: this.auxiliaryAccount,
176+
destination_vat_blocking: this.destinationVatBlocking,
177+
},
178+
});
179+
180+
$.export("$summary", `Successfully created contact: ${response.name || response.displayed_as}`);
181+
return response;
182+
},
183+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
export const CREDIT_TERMS_OPTIONS = [
2+
{
3+
label: "Month End Invoice",
4+
value: "month_end_invoice",
5+
},
6+
{
7+
label: "Date From Invoice",
8+
value: "date_from_invoice",
9+
},
10+
{
11+
label: "Immediate Invoice",
12+
value: "immediate_invoice",
13+
},
14+
{
15+
label: "Month End Payment",
16+
value: "month_end_payment",
17+
},
18+
{
19+
label: "Date From Payment",
20+
value: "date_from_payment",
21+
},
22+
{
23+
label: "Immediate Payment",
24+
value: "immediate_payment",
25+
},
26+
];
27+
28+
export const LOCALE_OPTIONS = [
29+
{
30+
label: "English (US)",
31+
value: "en-US",
32+
},
33+
{
34+
label: "English (UK)",
35+
value: "en-GB",
36+
},
37+
{
38+
label: "French",
39+
value: "fr-FR",
40+
},
41+
{
42+
label: "German",
43+
value: "de-DE",
44+
},
45+
{
46+
label: "Spanish",
47+
value: "es-ES",
48+
},
49+
{
50+
label: "Italian",
51+
value: "it-IT",
52+
},
53+
];
Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,116 @@
1+
import { axios } from "@pipedream/platform";
2+
13
export default {
24
type: "app",
35
app: "sage_accounting",
4-
propDefinitions: {},
6+
propDefinitions: {
7+
contactTypeIds: {
8+
type: "string[]",
9+
label: "Contact Type IDs",
10+
description: "The IDs of the Contact Types",
11+
async options() {
12+
const contactTypes = await this.listContactTypes();
13+
return contactTypes.map((contactType) => ({
14+
label: contactType.displayed_as,
15+
value: contactType.id,
16+
}));
17+
},
18+
default: [
19+
"CUSTOMER",
20+
],
21+
},
22+
currencyId: {
23+
type: "string",
24+
label: "Currency ID",
25+
description: "The ID of the Currency",
26+
async options() {
27+
const currencies = await this.listCurrencies();
28+
return currencies.map((currency) => ({
29+
label: currency.displayed_as,
30+
value: currency.id,
31+
}));
32+
},
33+
optional: true,
34+
},
35+
},
536
methods: {
637
// this.$auth contains connected account data
738
authKeys() {
839
console.log(Object.keys(this.$auth));
940
},
41+
_baseUrl() {
42+
return "https://api.accounting.sage.com/v3.1";
43+
},
44+
async _makeRequest(opts = {}) {
45+
const {
46+
$ = this,
47+
path,
48+
headers,
49+
...otherOpts
50+
} = opts;
51+
return axios($, {
52+
...otherOpts,
53+
url: this._baseUrl() + path,
54+
headers: {
55+
...headers,
56+
"Authorization": `Bearer ${this.$auth.oauth_access_token}`,
57+
"Content-Type": "application/json",
58+
},
59+
});
60+
},
61+
async listContactTypes(opts = {}) {
62+
const response = await this._makeRequest({
63+
path: "/contact_types",
64+
...opts,
65+
});
66+
return response.$items || response.items || [];
67+
},
68+
async listCurrencies(opts = {}) {
69+
const response = await this._makeRequest({
70+
path: "/currencies",
71+
...opts,
72+
});
73+
return response.$items || response.items || [];
74+
},
75+
async listContacts(opts = {}) {
76+
const response = await this._makeRequest({
77+
path: "/contacts",
78+
...opts,
79+
});
80+
return response.$items || response.items || [];
81+
},
82+
async createContact(opts = {}) {
83+
return this._makeRequest({
84+
method: "POST",
85+
path: "/contacts",
86+
...opts,
87+
});
88+
},
89+
async getContact({
90+
contactId, ...opts
91+
}) {
92+
return this._makeRequest({
93+
path: `/contacts/${contactId}`,
94+
...opts,
95+
});
96+
},
97+
async updateContact({
98+
contactId, ...opts
99+
}) {
100+
return this._makeRequest({
101+
method: "PUT",
102+
path: `/contacts/${contactId}`,
103+
...opts,
104+
});
105+
},
106+
async deleteContact({
107+
contactId, ...opts
108+
}) {
109+
return this._makeRequest({
110+
method: "DELETE",
111+
path: `/contacts/${contactId}`,
112+
...opts,
113+
});
114+
},
10115
},
11116
};

0 commit comments

Comments
 (0)