feat(vtiger-crm): add create opportunity action
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
export const fields = [
|
||||
{
|
||||
label: 'Deal Name',
|
||||
key: 'dealName',
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: '',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Amount',
|
||||
key: 'amount',
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Organization Name',
|
||||
key: 'organizationName',
|
||||
type: 'dropdown',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listOrganizations',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Contact Name',
|
||||
key: 'contactName',
|
||||
type: 'dropdown',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listContacts',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Expected Close Date',
|
||||
key: 'expectedCloseDate',
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'Format: yyyy-mm-dd',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Pipeline',
|
||||
key: 'pipeline',
|
||||
type: 'dropdown',
|
||||
required: true,
|
||||
value: 'Standart',
|
||||
description: '',
|
||||
variables: true,
|
||||
options: [{ label: 'Standart', value: 'Standart' }],
|
||||
},
|
||||
{
|
||||
label: 'Sales Stage',
|
||||
key: 'salesStage',
|
||||
type: 'dropdown',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listOpportunityOptions',
|
||||
},
|
||||
{
|
||||
name: 'parameters.salesStage',
|
||||
value: 'sales_stage',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Assigned To',
|
||||
key: 'assignedTo',
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Default is the id of the account connected to Automatisch.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Lead Source',
|
||||
key: 'leadSource',
|
||||
type: 'dropdown',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listOpportunityOptions',
|
||||
},
|
||||
{
|
||||
name: 'parameters.leadSource',
|
||||
value: 'leadsource',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Next Step',
|
||||
key: 'nextStep',
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Type',
|
||||
key: 'type',
|
||||
type: 'dropdown',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listOpportunityOptions',
|
||||
},
|
||||
{
|
||||
name: 'parameters.type',
|
||||
value: 'opportunity_type',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Probability',
|
||||
key: 'probability',
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Campaign Source',
|
||||
key: 'campaignSource',
|
||||
type: 'dropdown',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listCampaignSources',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Weighted Revenue',
|
||||
key: 'weightedRevenue',
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Adjusted Amount',
|
||||
key: 'adjustedAmount',
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Lost Reason',
|
||||
key: 'lostReason',
|
||||
type: 'dropdown',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listOpportunityOptions',
|
||||
},
|
||||
{
|
||||
name: 'parameters.lostReason',
|
||||
value: 'lost_reason',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Record Currency',
|
||||
key: 'recordCurrency',
|
||||
type: 'dropdown',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listRecordCurrencies',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Description',
|
||||
key: 'description',
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: '',
|
||||
variables: true,
|
||||
},
|
||||
];
|
@@ -0,0 +1,64 @@
|
||||
import defineAction from '../../../../helpers/define-action.js';
|
||||
import { fields } from './fields.js';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Create opportunity',
|
||||
key: 'createOpportunity',
|
||||
description: 'Create a new opportunity.',
|
||||
arguments: fields,
|
||||
|
||||
async run($) {
|
||||
const {
|
||||
dealName,
|
||||
amount,
|
||||
organizationName,
|
||||
contactName,
|
||||
expectedCloseDate,
|
||||
pipeline,
|
||||
salesStage,
|
||||
assignedTo,
|
||||
leadSource,
|
||||
nextStep,
|
||||
type,
|
||||
probability,
|
||||
campaignSource,
|
||||
weightedRevenue,
|
||||
adjustedAmount,
|
||||
lostReason,
|
||||
recordCurrency,
|
||||
description,
|
||||
} = $.step.parameters;
|
||||
|
||||
const elementData = {
|
||||
potentialname: dealName,
|
||||
amount,
|
||||
related_to: organizationName,
|
||||
contact_id: contactName,
|
||||
closingdate: expectedCloseDate,
|
||||
pipeline,
|
||||
sales_stage: salesStage,
|
||||
assigned_user_id: assignedTo || $.auth.data.userId,
|
||||
leadsource: leadSource,
|
||||
nextstep: nextStep,
|
||||
opportunity_type: type,
|
||||
probability: probability,
|
||||
campaignid: campaignSource,
|
||||
forecast_amount: weightedRevenue,
|
||||
adjusted_amount: adjustedAmount,
|
||||
lost_reason: lostReason,
|
||||
record_currency_id: recordCurrency,
|
||||
description,
|
||||
};
|
||||
|
||||
const body = {
|
||||
operation: 'create',
|
||||
sessionName: $.auth.data.sessionName,
|
||||
element: JSON.stringify(elementData),
|
||||
elementType: 'Potentials',
|
||||
};
|
||||
|
||||
const response = await $.http.post('/webservice.php', body);
|
||||
|
||||
$.setActionItem({ raw: response.data });
|
||||
},
|
||||
});
|
3
packages/backend/src/apps/vtiger-crm/actions/index.js
Normal file
3
packages/backend/src/apps/vtiger-crm/actions/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import createOpportunity from './create-opportunity/index.js';
|
||||
|
||||
export default [createOpportunity];
|
13
packages/backend/src/apps/vtiger-crm/dynamic-data/index.js
Normal file
13
packages/backend/src/apps/vtiger-crm/dynamic-data/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import listCampaignSources from './list-campaign-sources/index.js';
|
||||
import listContacts from './list-contacts/index.js';
|
||||
import listOpportunityOptions from './list-opportunity-options/index.js';
|
||||
import listOrganizations from './list-organizations/index.js';
|
||||
import listRecordCurrencies from './list-record-currencies/index.js';
|
||||
|
||||
export default [
|
||||
listCampaignSources,
|
||||
listContacts,
|
||||
listOpportunityOptions,
|
||||
listOrganizations,
|
||||
listRecordCurrencies,
|
||||
];
|
@@ -0,0 +1,29 @@
|
||||
export default {
|
||||
name: 'List campaign sources',
|
||||
key: 'listCampaignSources',
|
||||
|
||||
async run($) {
|
||||
const campaignSources = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
const params = {
|
||||
operation: 'query',
|
||||
sessionName: $.auth.data.sessionName,
|
||||
query: 'SELECT * FROM Campaigns ORDER BY createdtime DESC;',
|
||||
};
|
||||
|
||||
const { data } = await $.http.get(`/webservice.php`, { params });
|
||||
|
||||
if (data.result?.length) {
|
||||
for (const campaignSource of data.result) {
|
||||
campaignSources.data.push({
|
||||
value: campaignSource.id,
|
||||
name: campaignSource.campaignname,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return campaignSources;
|
||||
},
|
||||
};
|
@@ -0,0 +1,29 @@
|
||||
export default {
|
||||
name: 'List contacts',
|
||||
key: 'listContacts',
|
||||
|
||||
async run($) {
|
||||
const contacts = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
const params = {
|
||||
operation: 'query',
|
||||
sessionName: $.auth.data.sessionName,
|
||||
query: 'SELECT * FROM Contacts ORDER BY createdtime DESC;',
|
||||
};
|
||||
|
||||
const { data } = await $.http.get(`/webservice.php`, { params });
|
||||
|
||||
if (data.result?.length) {
|
||||
for (const contact of data.result) {
|
||||
contacts.data.push({
|
||||
value: contact.id,
|
||||
name: `${contact.firstname} ${contact.lastname}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return contacts;
|
||||
},
|
||||
};
|
@@ -0,0 +1,38 @@
|
||||
export default {
|
||||
name: 'List opportunity options',
|
||||
key: 'listOpportunityOptions',
|
||||
|
||||
async run($) {
|
||||
const opportunityOptions = {
|
||||
data: [],
|
||||
};
|
||||
const leadSource = $.step.parameters.leadSource;
|
||||
const lostReason = $.step.parameters.lostReason;
|
||||
const type = $.step.parameters.type;
|
||||
const salesStage = $.step.parameters.salesStage;
|
||||
const picklistFields = [leadSource, lostReason, type, salesStage];
|
||||
|
||||
const params = {
|
||||
operation: 'describe',
|
||||
sessionName: $.auth.data.sessionName,
|
||||
elementType: 'Potentials',
|
||||
};
|
||||
|
||||
const { data } = await $.http.get(`/webservice.php`, { params });
|
||||
|
||||
if (data.result.fields?.length) {
|
||||
for (const field of data.result.fields) {
|
||||
if (picklistFields.includes(field.name)) {
|
||||
field.type.picklistValues.map((item) =>
|
||||
opportunityOptions.data.push({
|
||||
value: item.value,
|
||||
name: item.label,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return opportunityOptions;
|
||||
},
|
||||
};
|
@@ -0,0 +1,29 @@
|
||||
export default {
|
||||
name: 'List organizations',
|
||||
key: 'listOrganizations',
|
||||
|
||||
async run($) {
|
||||
const organizations = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
const params = {
|
||||
operation: 'query',
|
||||
sessionName: $.auth.data.sessionName,
|
||||
query: 'SELECT * FROM Accounts ORDER BY createdtime DESC;',
|
||||
};
|
||||
|
||||
const { data } = await $.http.get(`/webservice.php`, { params });
|
||||
|
||||
if (data.result?.length) {
|
||||
for (const organization of data.result) {
|
||||
organizations.data.push({
|
||||
value: organization.id,
|
||||
name: organization.accountname,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return organizations;
|
||||
},
|
||||
};
|
@@ -0,0 +1,29 @@
|
||||
export default {
|
||||
name: 'List record currencies',
|
||||
key: 'listRecordCurrencies',
|
||||
|
||||
async run($) {
|
||||
const recordCurrencies = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
const params = {
|
||||
operation: 'query',
|
||||
sessionName: $.auth.data.sessionName,
|
||||
query: 'SELECT * FROM Currency;',
|
||||
};
|
||||
|
||||
const { data } = await $.http.get(`/webservice.php`, { params });
|
||||
|
||||
if (data.result?.length) {
|
||||
for (const recordCurrency of data.result) {
|
||||
recordCurrencies.data.push({
|
||||
value: recordCurrency.id,
|
||||
name: recordCurrency.currency_code,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return recordCurrencies;
|
||||
},
|
||||
};
|
@@ -3,6 +3,8 @@ import addAuthHeader from './common/add-auth-header.js';
|
||||
import setBaseUrl from './common/set-base-url.js';
|
||||
import auth from './auth/index.js';
|
||||
import triggers from './triggers/index.js';
|
||||
import actions from './actions/index.js';
|
||||
import dynamicData from './dynamic-data/index.js';
|
||||
|
||||
export default defineApp({
|
||||
name: 'Vtiger CRM',
|
||||
@@ -16,4 +18,6 @@ export default defineApp({
|
||||
beforeRequest: [setBaseUrl, addAuthHeader],
|
||||
auth,
|
||||
triggers,
|
||||
actions,
|
||||
dynamicData,
|
||||
});
|
||||
|
@@ -454,6 +454,7 @@ export default defineConfig({
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: 'Triggers', link: '/apps/vtiger-crm/triggers' },
|
||||
{ text: 'Actions', link: '/apps/vtiger-crm/actions' },
|
||||
{ text: 'Connection', link: '/apps/vtiger-crm/connection' },
|
||||
],
|
||||
},
|
||||
|
12
packages/docs/pages/apps/vtiger-crm/actions.md
Normal file
12
packages/docs/pages/apps/vtiger-crm/actions.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
favicon: /favicons/vtiger-crm.svg
|
||||
items:
|
||||
- name: Create opportunity
|
||||
desc: Create a new opportunity.
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import CustomListing from '../../components/CustomListing.vue'
|
||||
</script>
|
||||
|
||||
<CustomListing />
|
Reference in New Issue
Block a user