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 setBaseUrl from './common/set-base-url.js';
|
||||||
import auth from './auth/index.js';
|
import auth from './auth/index.js';
|
||||||
import triggers from './triggers/index.js';
|
import triggers from './triggers/index.js';
|
||||||
|
import actions from './actions/index.js';
|
||||||
|
import dynamicData from './dynamic-data/index.js';
|
||||||
|
|
||||||
export default defineApp({
|
export default defineApp({
|
||||||
name: 'Vtiger CRM',
|
name: 'Vtiger CRM',
|
||||||
@@ -16,4 +18,6 @@ export default defineApp({
|
|||||||
beforeRequest: [setBaseUrl, addAuthHeader],
|
beforeRequest: [setBaseUrl, addAuthHeader],
|
||||||
auth,
|
auth,
|
||||||
triggers,
|
triggers,
|
||||||
|
actions,
|
||||||
|
dynamicData,
|
||||||
});
|
});
|
||||||
|
@@ -454,6 +454,7 @@ export default defineConfig({
|
|||||||
collapsed: true,
|
collapsed: true,
|
||||||
items: [
|
items: [
|
||||||
{ text: 'Triggers', link: '/apps/vtiger-crm/triggers' },
|
{ text: 'Triggers', link: '/apps/vtiger-crm/triggers' },
|
||||||
|
{ text: 'Actions', link: '/apps/vtiger-crm/actions' },
|
||||||
{ text: 'Connection', link: '/apps/vtiger-crm/connection' },
|
{ 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