@aglyn/plugins-crm 1.0.0-beta.220 → 1.0.0-beta.222
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/package.json +13 -13
- package/src/lib/components/activity-list.js +12 -5
- package/src/lib/components/activity-list.js.map +1 -1
- package/src/lib/components/companies-bulk-bar.d.ts +1 -4
- package/src/lib/components/companies-bulk-bar.js +7 -20
- package/src/lib/components/companies-bulk-bar.js.map +1 -1
- package/src/lib/components/companies-section.d.ts +3 -3
- package/src/lib/components/companies-section.js +149 -46
- package/src/lib/components/companies-section.js.map +1 -1
- package/src/lib/components/company-edit-drawer.js +281 -20
- package/src/lib/components/company-edit-drawer.js.map +1 -1
- package/src/lib/components/company-properties-card.js +99 -8
- package/src/lib/components/company-properties-card.js.map +1 -1
- package/src/lib/components/contact-detail-page.js +3 -1
- package/src/lib/components/contact-detail-page.js.map +1 -1
- package/src/lib/components/contact-merge-dialog.js +33 -10
- package/src/lib/components/contact-merge-dialog.js.map +1 -1
- package/src/lib/components/contact-properties-card.d.ts +0 -69
- package/src/lib/components/contact-properties-card.js +350 -60
- package/src/lib/components/contact-properties-card.js.map +1 -1
- package/src/lib/components/contact-reports-to-field.d.ts +46 -0
- package/src/lib/components/contact-reports-to-field.js +67 -0
- package/src/lib/components/contact-reports-to-field.js.map +1 -0
- package/src/lib/components/contacts-bulk-bar.d.ts +1 -8
- package/src/lib/components/contacts-bulk-bar.js +7 -19
- package/src/lib/components/contacts-bulk-bar.js.map +1 -1
- package/src/lib/components/contacts-section.js +46 -33
- package/src/lib/components/contacts-section.js.map +1 -1
- package/src/lib/components/crm-call-actions.d.ts +10 -0
- package/src/lib/components/crm-call-actions.js +26 -9
- package/src/lib/components/crm-call-actions.js.map +1 -1
- package/src/lib/components/crm-record-picker.d.ts +15 -0
- package/src/lib/components/crm-record-picker.js +16 -10
- package/src/lib/components/crm-record-picker.js.map +1 -1
- package/src/lib/components/crm-transfer-buttons.d.ts +54 -0
- package/src/lib/components/crm-transfer-buttons.js +167 -0
- package/src/lib/components/crm-transfer-buttons.js.map +1 -0
- package/src/lib/components/deal-contact-roles-card.d.ts +46 -0
- package/src/lib/components/deal-contact-roles-card.js +368 -0
- package/src/lib/components/deal-contact-roles-card.js.map +1 -0
- package/src/lib/components/deal-detail-page.d.ts +3 -2
- package/src/lib/components/deal-detail-page.js +25 -6
- package/src/lib/components/deal-detail-page.js.map +1 -1
- package/src/lib/components/deal-edit-drawer.d.ts +10 -0
- package/src/lib/components/deal-edit-drawer.js +219 -10
- package/src/lib/components/deal-edit-drawer.js.map +1 -1
- package/src/lib/components/deal-properties-card.d.ts +7 -0
- package/src/lib/components/deal-properties-card.js +34 -3
- package/src/lib/components/deal-properties-card.js.map +1 -1
- package/src/lib/components/deal-stage-card.d.ts +4 -0
- package/src/lib/components/deal-stage-card.js +10 -2
- package/src/lib/components/deal-stage-card.js.map +1 -1
- package/src/lib/components/deals-bulk-bar.d.ts +0 -3
- package/src/lib/components/deals-bulk-bar.js +7 -20
- package/src/lib/components/deals-bulk-bar.js.map +1 -1
- package/src/lib/components/deals-section.d.ts +3 -3
- package/src/lib/components/deals-section.js +123 -63
- package/src/lib/components/deals-section.js.map +1 -1
- package/src/lib/components/fields-section.js +31 -17
- package/src/lib/components/fields-section.js.map +1 -1
- package/src/lib/components/lead-convert-dialog.d.ts +4 -0
- package/src/lib/components/lead-convert-dialog.js +23 -1
- package/src/lib/components/lead-convert-dialog.js.map +1 -1
- package/src/lib/components/lead-detail-page.js +8 -2
- package/src/lib/components/lead-detail-page.js.map +1 -1
- package/src/lib/components/lead-profile-fields.d.ts +71 -0
- package/src/lib/components/lead-profile-fields.js +386 -0
- package/src/lib/components/lead-profile-fields.js.map +1 -0
- package/src/lib/components/lead-properties-card.d.ts +2 -1
- package/src/lib/components/lead-properties-card.js +85 -176
- package/src/lib/components/lead-properties-card.js.map +1 -1
- package/src/lib/components/lead-source-select.d.ts +4 -23
- package/src/lib/components/lead-source-select.js +9 -73
- package/src/lib/components/lead-source-select.js.map +1 -1
- package/src/lib/components/lead-status-chip.d.ts +9 -3
- package/src/lib/components/lead-status-chip.js +8 -4
- package/src/lib/components/lead-status-chip.js.map +1 -1
- package/src/lib/components/lead-status-options.d.ts +20 -0
- package/src/lib/components/lead-status-options.js +51 -0
- package/src/lib/components/lead-status-options.js.map +1 -0
- package/src/lib/components/lead-unqualify-dialog.d.ts +5 -0
- package/src/lib/components/lead-unqualify-dialog.js +50 -18
- package/src/lib/components/lead-unqualify-dialog.js.map +1 -1
- package/src/lib/components/leads-bulk-bar.d.ts +0 -3
- package/src/lib/components/leads-bulk-bar.js +29 -29
- package/src/lib/components/leads-bulk-bar.js.map +1 -1
- package/src/lib/components/leads-section.js +120 -68
- package/src/lib/components/leads-section.js.map +1 -1
- package/src/lib/components/linked-deals-card.d.ts +4 -0
- package/src/lib/components/linked-deals-card.js +47 -3
- package/src/lib/components/linked-deals-card.js.map +1 -1
- package/src/lib/components/log-activity-dialog.js +43 -3
- package/src/lib/components/log-activity-dialog.js.map +1 -1
- package/src/lib/components/new-contact-drawer.d.ts +8 -0
- package/src/lib/components/new-contact-drawer.js +108 -6
- package/src/lib/components/new-contact-drawer.js.map +1 -1
- package/src/lib/components/new-lead-drawer.d.ts +9 -2
- package/src/lib/components/new-lead-drawer.js +88 -121
- package/src/lib/components/new-lead-drawer.js.map +1 -1
- package/src/lib/components/picklist-select.d.ts +36 -0
- package/src/lib/components/picklist-select.js +114 -0
- package/src/lib/components/picklist-select.js.map +1 -0
- package/src/lib/components/picklist-values-card.d.ts +34 -0
- package/src/lib/components/{lead-source-values-card.js → picklist-values-card.js} +241 -58
- package/src/lib/components/picklist-values-card.js.map +1 -0
- package/src/lib/components/pipeline-stages-dialog.d.ts +7 -0
- package/src/lib/components/pipeline-stages-dialog.js +26 -4
- package/src/lib/components/pipeline-stages-dialog.js.map +1 -1
- package/src/lib/components/pipelines-dialog.js +15 -6
- package/src/lib/components/pipelines-dialog.js.map +1 -1
- package/src/lib/components/recent-activity-feed.js +20 -5
- package/src/lib/components/recent-activity-feed.js.map +1 -1
- package/src/lib/components/recipes-card.js +4 -2
- package/src/lib/components/recipes-card.js.map +1 -1
- package/src/lib/components/record-tasks-card.js +15 -8
- package/src/lib/components/record-tasks-card.js.map +1 -1
- package/src/lib/components/reports/forecast-card.d.ts +6 -0
- package/src/lib/components/reports/forecast-card.js +101 -3
- package/src/lib/components/reports/forecast-card.js.map +1 -1
- package/src/lib/components/reports/lead-funnel-card.d.ts +12 -0
- package/src/lib/components/reports/lead-funnel-card.js +9 -5
- package/src/lib/components/reports/lead-funnel-card.js.map +1 -1
- package/src/lib/components/reports/lead-source-card.d.ts +23 -0
- package/src/lib/components/reports/lead-source-card.js +318 -0
- package/src/lib/components/reports/lead-source-card.js.map +1 -0
- package/src/lib/components/reports/report-export.js +1 -1
- package/src/lib/components/reports/report-export.js.map +1 -1
- package/src/lib/components/reports-section.js +8 -0
- package/src/lib/components/reports-section.js.map +1 -1
- package/src/lib/components/sharing-rule-drawer.d.ts +5 -0
- package/src/lib/components/sharing-rule-drawer.js +108 -19
- package/src/lib/components/sharing-rule-drawer.js.map +1 -1
- package/src/lib/components/sharing-rules-card.js +11 -3
- package/src/lib/components/sharing-rules-card.js.map +1 -1
- package/src/lib/components/task-cells.d.ts +9 -1
- package/src/lib/components/task-cells.js +9 -4
- package/src/lib/components/task-cells.js.map +1 -1
- package/src/lib/components/task-edit-drawer.js +111 -43
- package/src/lib/components/task-edit-drawer.js.map +1 -1
- package/src/lib/components/tasks-bulk-bar.d.ts +0 -3
- package/src/lib/components/tasks-bulk-bar.js +7 -20
- package/src/lib/components/tasks-bulk-bar.js.map +1 -1
- package/src/lib/components/tasks-calendar.d.ts +3 -0
- package/src/lib/components/tasks-calendar.js +8 -1
- package/src/lib/components/tasks-calendar.js.map +1 -1
- package/src/lib/components/tasks-section.d.ts +3 -3
- package/src/lib/components/tasks-section.js +58 -43
- package/src/lib/components/tasks-section.js.map +1 -1
- package/src/lib/constants/api-routes.d.ts +2 -9
- package/src/lib/constants/api-routes.js +1 -7
- package/src/lib/constants/api-routes.js.map +1 -1
- package/src/lib/constants/bundle-common.d.ts +6 -0
- package/src/lib/constants/bundle-common.js +11 -0
- package/src/lib/constants/bundle-common.js.map +1 -1
- package/src/lib/constants/company-filters.d.ts +14 -0
- package/src/lib/constants/company-filters.js +51 -1
- package/src/lib/constants/company-filters.js.map +1 -1
- package/src/lib/constants/contact-filters.d.ts +2 -0
- package/src/lib/constants/contact-filters.js +18 -1
- package/src/lib/constants/contact-filters.js.map +1 -1
- package/src/lib/constants/deal-filters.d.ts +22 -1
- package/src/lib/constants/deal-filters.js +67 -4
- package/src/lib/constants/deal-filters.js.map +1 -1
- package/src/lib/declarations.console-server.d.ts +3 -0
- package/src/lib/declarations.console-server.js +35 -0
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/declarations.d.ts +26 -0
- package/src/lib/declarations.js +35 -0
- package/src/lib/declarations.js.map +1 -0
- package/src/lib/declarations.server.d.ts +11 -0
- package/src/lib/declarations.server.js +92 -1
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/hooks/use-company-picklists.d.ts +15 -0
- package/src/lib/hooks/use-company-picklists.js +55 -0
- package/src/lib/hooks/use-company-picklists.js.map +1 -0
- package/src/lib/hooks/use-crm-picklist.d.ts +25 -0
- package/src/lib/hooks/use-crm-picklist.js +53 -0
- package/src/lib/hooks/use-crm-picklist.js.map +1 -0
- package/src/lib/hooks/use-crm-record-names.d.ts +16 -0
- package/src/lib/hooks/use-crm-record-names.js +45 -19
- package/src/lib/hooks/use-crm-record-names.js.map +1 -1
- package/src/lib/hooks/use-crm-task-picklists.d.ts +11 -0
- package/src/lib/hooks/use-crm-task-picklists.js +45 -0
- package/src/lib/hooks/use-crm-task-picklists.js.map +1 -0
- package/src/lib/hooks/use-deals.d.ts +14 -0
- package/src/lib/hooks/use-deals.js +29 -0
- package/src/lib/hooks/use-deals.js.map +1 -1
- package/src/lib/hooks/use-lead-picklists.d.ts +14 -0
- package/src/lib/hooks/use-lead-picklists.js +46 -0
- package/src/lib/hooks/use-lead-picklists.js.map +1 -0
- package/src/lib/hooks/use-lead-source-picklist.d.ts +5 -19
- package/src/lib/hooks/use-lead-source-picklist.js +12 -22
- package/src/lib/hooks/use-lead-source-picklist.js.map +1 -1
- package/src/lib/hooks/use-lead-status-picklist.d.ts +9 -0
- package/src/lib/hooks/use-lead-status-picklist.js +40 -0
- package/src/lib/hooks/use-lead-status-picklist.js.map +1 -0
- package/src/lib/model/companies.d.ts +32 -3
- package/src/lib/model/companies.js +133 -16
- package/src/lib/model/companies.js.map +1 -1
- package/src/lib/model/contact-merge.d.ts +27 -3
- package/src/lib/model/contact-merge.js +81 -7
- package/src/lib/model/contact-merge.js.map +1 -1
- package/src/lib/model/contact-record.d.ts +17 -0
- package/src/lib/model/contact-record.js +15 -1
- package/src/lib/model/contact-record.js.map +1 -1
- package/src/lib/model/contact-update.d.ts +31 -2
- package/src/lib/model/contact-update.js +14 -0
- package/src/lib/model/contact-update.js.map +1 -1
- package/src/lib/model/crm-list-query.d.ts +5 -0
- package/src/lib/model/crm-list-query.js +8 -0
- package/src/lib/model/crm-list-query.js.map +1 -1
- package/src/lib/model/crm-recipes.d.ts +40 -0
- package/src/lib/model/crm-recipes.js +244 -0
- package/src/lib/model/crm-recipes.js.map +1 -0
- package/src/lib/model/crm-record-counts.d.ts +36 -0
- package/src/lib/model/crm-record-counts.js +54 -0
- package/src/lib/model/crm-record-counts.js.map +1 -0
- package/src/lib/model/crm-record-lists.d.ts +23 -0
- package/src/lib/model/crm-record-lists.js +161 -0
- package/src/lib/model/crm-record-lists.js.map +1 -0
- package/src/lib/model/crm-reports.d.ts +73 -3
- package/src/lib/model/crm-reports.js +120 -1
- package/src/lib/model/crm-reports.js.map +1 -1
- package/src/lib/model/crm-sharing.d.ts +21 -3
- package/src/lib/model/crm-sharing.js +27 -6
- package/src/lib/model/crm-sharing.js.map +1 -1
- package/src/lib/model/deal-board-model.d.ts +8 -2
- package/src/lib/model/deal-board-model.js +15 -2
- package/src/lib/model/deal-board-model.js.map +1 -1
- package/src/lib/model/deal-contact-roles.d.ts +45 -0
- package/src/lib/model/deal-contact-roles.js +73 -0
- package/src/lib/model/deal-contact-roles.js.map +1 -0
- package/src/lib/model/deal-form-model.d.ts +56 -0
- package/src/lib/model/deal-form-model.js +79 -7
- package/src/lib/model/deal-form-model.js.map +1 -1
- package/src/lib/model/download-text-file.d.ts +23 -0
- package/src/lib/model/download-text-file.js +34 -0
- package/src/lib/model/download-text-file.js.map +1 -0
- package/src/lib/model/lead-filters.d.ts +36 -2
- package/src/lib/model/lead-filters.js +123 -2
- package/src/lib/model/lead-filters.js.map +1 -1
- package/src/lib/model/lead-source-direction.d.ts +38 -0
- package/src/lib/model/lead-source-direction.js +52 -0
- package/src/lib/model/lead-source-direction.js.map +1 -0
- package/src/lib/model/picklist-values.d.ts +119 -0
- package/src/lib/model/picklist-values.js +256 -0
- package/src/lib/model/picklist-values.js.map +1 -0
- package/src/lib/model/record-facts-disclosed.d.ts +81 -0
- package/src/lib/model/record-facts-disclosed.js +281 -0
- package/src/lib/model/record-facts-disclosed.js.map +1 -0
- package/src/lib/model/record-facts.d.ts +215 -34
- package/src/lib/model/record-facts.js +307 -128
- package/src/lib/model/record-facts.js.map +1 -1
- package/src/lib/model/task-picklists.d.ts +52 -0
- package/src/lib/model/task-picklists.js +83 -0
- package/src/lib/model/task-picklists.js.map +1 -0
- package/src/lib/model/task-routes.d.ts +13 -0
- package/src/lib/model/task-routes.js +23 -4
- package/src/lib/model/task-routes.js.map +1 -1
- package/src/lib/plan-entitlements.js +6 -4
- package/src/lib/plan-entitlements.js.map +1 -1
- package/src/lib/plugin.js +17 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/api-v1/contacts.js +220 -14
- package/src/lib/server/api-v1/contacts.js.map +1 -1
- package/src/lib/server/api-v1/crm-activities.js +14 -1
- package/src/lib/server/api-v1/crm-activities.js.map +1 -1
- package/src/lib/server/api-v1/crm-companies.js +123 -14
- package/src/lib/server/api-v1/crm-companies.js.map +1 -1
- package/src/lib/server/api-v1/crm-deals.js +291 -26
- package/src/lib/server/api-v1/crm-deals.js.map +1 -1
- package/src/lib/server/api-v1/crm-leads.js +144 -38
- package/src/lib/server/api-v1/crm-leads.js.map +1 -1
- package/src/lib/server/api-v1/crm-pipelines.d.ts +6 -0
- package/src/lib/server/api-v1/crm-pipelines.js +8 -2
- package/src/lib/server/api-v1/crm-pipelines.js.map +1 -1
- package/src/lib/server/api-v1/crm-tasks.js +75 -33
- package/src/lib/server/api-v1/crm-tasks.js.map +1 -1
- package/src/lib/server/api-v1/openapi.d.ts +0 -11
- package/src/lib/server/api-v1/openapi.js +171 -16
- package/src/lib/server/api-v1/openapi.js.map +1 -1
- package/src/lib/server/assign-contact-owner.d.ts +162 -0
- package/src/lib/server/assign-contact-owner.js +340 -0
- package/src/lib/server/assign-contact-owner.js.map +1 -0
- package/src/lib/server/associate-company-by-domain.d.ts +70 -0
- package/src/lib/server/associate-company-by-domain.js +153 -0
- package/src/lib/server/associate-company-by-domain.js.map +1 -0
- package/src/lib/server/automation-steps.d.ts +139 -0
- package/src/lib/server/automation-steps.js +472 -0
- package/src/lib/server/automation-steps.js.map +1 -0
- package/src/lib/server/capture-contact.js +69 -22
- package/src/lib/server/capture-contact.js.map +1 -1
- package/src/lib/server/capture-host-contact.d.ts +104 -0
- package/src/lib/server/capture-host-contact.js +151 -0
- package/src/lib/server/capture-host-contact.js.map +1 -0
- package/src/lib/server/company-children.d.ts +25 -0
- package/src/lib/server/company-children.js +42 -0
- package/src/lib/server/company-children.js.map +1 -0
- package/src/lib/server/company-delete.d.ts +18 -0
- package/src/lib/server/company-delete.js +44 -21
- package/src/lib/server/company-delete.js.map +1 -1
- package/src/lib/server/contact-email-history.js +21 -19
- package/src/lib/server/contact-email-history.js.map +1 -1
- package/src/lib/server/contact-remove.js +27 -2
- package/src/lib/server/contact-remove.js.map +1 -1
- package/src/lib/server/contact-reports-to.d.ts +61 -0
- package/src/lib/server/contact-reports-to.js +114 -0
- package/src/lib/server/contact-reports-to.js.map +1 -0
- package/src/lib/server/contact-update.d.ts +42 -1
- package/src/lib/server/contact-update.js +204 -23
- package/src/lib/server/contact-update.js.map +1 -1
- package/src/lib/server/convert-host-lead.d.ts +46 -1
- package/src/lib/server/convert-host-lead.js +173 -15
- package/src/lib/server/convert-host-lead.js.map +1 -1
- package/src/lib/server/convert-open-lead.js +12 -5
- package/src/lib/server/convert-open-lead.js.map +1 -1
- package/src/lib/server/crm-record-indexes.d.ts +45 -0
- package/src/lib/server/crm-record-indexes.js +78 -0
- package/src/lib/server/crm-record-indexes.js.map +1 -0
- package/src/lib/server/crm-sharing.d.ts +9 -1
- package/src/lib/server/crm-sharing.js +23 -3
- package/src/lib/server/crm-sharing.js.map +1 -1
- package/src/lib/server/deal-contact-roles.d.ts +27 -0
- package/src/lib/server/deal-contact-roles.js +89 -0
- package/src/lib/server/deal-contact-roles.js.map +1 -0
- package/src/lib/server/lead-convert.d.ts +5 -0
- package/src/lib/server/lead-convert.js +19 -3
- package/src/lib/server/lead-convert.js.map +1 -1
- package/src/lib/server/lead-create.d.ts +17 -2
- package/src/lib/server/lead-create.js +46 -14
- package/src/lib/server/lead-create.js.map +1 -1
- package/src/lib/server/lead-nurturing.d.ts +6 -0
- package/src/lib/server/lead-nurturing.js +57 -20
- package/src/lib/server/lead-nurturing.js.map +1 -1
- package/src/lib/server/lead-picklists.d.ts +35 -0
- package/src/lib/server/lead-picklists.js +52 -0
- package/src/lib/server/lead-picklists.js.map +1 -0
- package/src/lib/server/lead-source-picklist.d.ts +1 -13
- package/src/lib/server/lead-source-picklist.js +6 -33
- package/src/lib/server/lead-source-picklist.js.map +1 -1
- package/src/lib/server/merge-contacts.js +22 -4
- package/src/lib/server/merge-contacts.js.map +1 -1
- package/src/lib/server/person-eraser.d.ts +53 -0
- package/src/lib/server/person-eraser.js +149 -0
- package/src/lib/server/person-eraser.js.map +1 -0
- package/src/lib/server/person-records.d.ts +69 -0
- package/src/lib/server/person-records.js +317 -0
- package/src/lib/server/person-records.js.map +1 -0
- package/src/lib/server/person-refund.d.ts +97 -0
- package/src/lib/server/person-refund.js +221 -0
- package/src/lib/server/person-refund.js.map +1 -0
- package/src/lib/server/picklist-values.d.ts +21 -0
- package/src/lib/server/picklist-values.js +308 -0
- package/src/lib/server/picklist-values.js.map +1 -0
- package/src/lib/server/read-picklist.d.ts +44 -0
- package/src/lib/server/read-picklist.js +65 -0
- package/src/lib/server/read-picklist.js.map +1 -0
- package/src/lib/server/recipe-routes.js +15 -7
- package/src/lib/server/recipe-routes.js.map +1 -1
- package/src/lib/server/record-email-state.js +7 -1
- package/src/lib/server/record-email-state.js.map +1 -1
- package/src/lib/server/record-facts.d.ts +3 -0
- package/src/lib/server/record-facts.js +233 -31
- package/src/lib/server/record-facts.js.map +1 -1
- package/src/lib/server/record-origin.d.ts +27 -0
- package/src/lib/server/record-origin.js +104 -0
- package/src/lib/server/record-origin.js.map +1 -0
- package/src/lib/server/record-timeline.js +15 -2
- package/src/lib/server/record-timeline.js.map +1 -1
- package/src/lib/server/suite-gate.js +4 -3
- package/src/lib/server/suite-gate.js.map +1 -1
- package/src/lib/server/task-routes.js +30 -16
- package/src/lib/server/task-routes.js.map +1 -1
- package/src/lib/server-deal-stage.d.ts +5 -1
- package/src/lib/server-deal-stage.js +10 -5
- package/src/lib/server-deal-stage.js.map +1 -1
- package/src/lib/server.d.ts +8 -3
- package/src/lib/server.js +47 -43
- package/src/lib/server.js.map +1 -1
- package/src/lib/testing/memory-firestore.d.ts +55 -0
- package/src/lib/testing/memory-firestore.js +335 -0
- package/src/lib/testing/memory-firestore.js.map +1 -0
- package/src/lib/testing/stand-in-email-send-index.d.ts +25 -0
- package/src/lib/testing/stand-in-email-send-index.js +49 -0
- package/src/lib/testing/stand-in-email-send-index.js.map +1 -0
- package/src/lib/transfer/activities.d.ts +30 -0
- package/src/lib/transfer/activities.js +132 -0
- package/src/lib/transfer/activities.js.map +1 -0
- package/src/lib/transfer/aliases.d.ts +22 -0
- package/src/lib/transfer/aliases.js +1342 -0
- package/src/lib/transfer/aliases.js.map +1 -0
- package/src/lib/transfer/common.d.ts +222 -0
- package/src/lib/transfer/common.js +832 -0
- package/src/lib/transfer/common.js.map +1 -0
- package/src/lib/transfer/companies.d.ts +43 -0
- package/src/lib/transfer/companies.js +549 -0
- package/src/lib/transfer/companies.js.map +1 -0
- package/src/lib/transfer/contacts.d.ts +31 -0
- package/src/lib/transfer/contacts.js +727 -0
- package/src/lib/transfer/contacts.js.map +1 -0
- package/src/lib/transfer/deals.d.ts +66 -0
- package/src/lib/transfer/deals.js +698 -0
- package/src/lib/transfer/deals.js.map +1 -0
- package/src/lib/transfer/email-templates-package.d.ts +40 -0
- package/src/lib/transfer/email-templates-package.js +76 -0
- package/src/lib/transfer/email-templates-package.js.map +1 -0
- package/src/lib/transfer/email-templates-package.server.d.ts +32 -0
- package/src/lib/transfer/email-templates-package.server.js +176 -0
- package/src/lib/transfer/email-templates-package.server.js.map +1 -0
- package/src/lib/transfer/fields.d.ts +102 -0
- package/src/lib/transfer/fields.js +1755 -0
- package/src/lib/transfer/fields.js.map +1 -0
- package/src/lib/transfer/leads.d.ts +30 -0
- package/src/lib/transfer/leads.js +582 -0
- package/src/lib/transfer/leads.js.map +1 -0
- package/src/lib/transfer/pipelines.d.ts +21 -0
- package/src/lib/transfer/pipelines.js +172 -0
- package/src/lib/transfer/pipelines.js.map +1 -0
- package/src/lib/transfer/register.d.ts +47 -0
- package/src/lib/transfer/register.js +277 -0
- package/src/lib/transfer/register.js.map +1 -0
- package/src/lib/transfer/tasks.d.ts +30 -0
- package/src/lib/transfer/tasks.js +418 -0
- package/src/lib/transfer/tasks.js.map +1 -0
- package/src/lib/transfer/ui.d.ts +20 -0
- package/src/lib/transfer/ui.js +42 -0
- package/src/lib/transfer/ui.js.map +1 -0
- package/src/lib/components/company-import-drawer.d.ts +0 -42
- package/src/lib/components/company-import-drawer.js +0 -99
- package/src/lib/components/company-import-drawer.js.map +0 -1
- package/src/lib/components/contact-import-drawer.d.ts +0 -46
- package/src/lib/components/contact-import-drawer.js +0 -149
- package/src/lib/components/contact-import-drawer.js.map +0 -1
- package/src/lib/components/crm-export-all-button.d.ts +0 -39
- package/src/lib/components/crm-export-all-button.js +0 -98
- package/src/lib/components/crm-export-all-button.js.map +0 -1
- package/src/lib/components/csv-import-drawer.d.ts +0 -139
- package/src/lib/components/csv-import-drawer.js +0 -757
- package/src/lib/components/csv-import-drawer.js.map +0 -1
- package/src/lib/components/deal-import-drawer.d.ts +0 -24
- package/src/lib/components/deal-import-drawer.js +0 -83
- package/src/lib/components/deal-import-drawer.js.map +0 -1
- package/src/lib/components/lead-import-drawer.d.ts +0 -27
- package/src/lib/components/lead-import-drawer.js +0 -118
- package/src/lib/components/lead-import-drawer.js.map +0 -1
- package/src/lib/components/lead-source-values-card.d.ts +0 -27
- package/src/lib/components/lead-source-values-card.js.map +0 -1
- package/src/lib/components/task-import-drawer.d.ts +0 -24
- package/src/lib/components/task-import-drawer.js +0 -82
- package/src/lib/components/task-import-drawer.js.map +0 -1
- package/src/lib/model/companies-csv.d.ts +0 -36
- package/src/lib/model/companies-csv.js +0 -38
- package/src/lib/model/companies-csv.js.map +0 -1
- package/src/lib/model/contacts-csv.d.ts +0 -54
- package/src/lib/model/contacts-csv.js +0 -67
- package/src/lib/model/contacts-csv.js.map +0 -1
- package/src/lib/model/crm-company-import.d.ts +0 -154
- package/src/lib/model/crm-company-import.js +0 -331
- package/src/lib/model/crm-company-import.js.map +0 -1
- package/src/lib/model/crm-csv.d.ts +0 -239
- package/src/lib/model/crm-csv.js +0 -467
- package/src/lib/model/crm-csv.js.map +0 -1
- package/src/lib/model/crm-deal-import.d.ts +0 -112
- package/src/lib/model/crm-deal-import.js +0 -263
- package/src/lib/model/crm-deal-import.js.map +0 -1
- package/src/lib/model/crm-import.d.ts +0 -250
- package/src/lib/model/crm-import.js +0 -467
- package/src/lib/model/crm-import.js.map +0 -1
- package/src/lib/model/crm-lead-import.d.ts +0 -138
- package/src/lib/model/crm-lead-import.js +0 -446
- package/src/lib/model/crm-lead-import.js.map +0 -1
- package/src/lib/model/crm-task-import.d.ts +0 -94
- package/src/lib/model/crm-task-import.js +0 -275
- package/src/lib/model/crm-task-import.js.map +0 -1
- package/src/lib/model/deals-csv.d.ts +0 -32
- package/src/lib/model/deals-csv.js +0 -36
- package/src/lib/model/deals-csv.js.map +0 -1
- package/src/lib/model/import-column-shapes.d.ts +0 -36
- package/src/lib/model/import-column-shapes.js +0 -76
- package/src/lib/model/import-column-shapes.js.map +0 -1
- package/src/lib/model/lead-source-values.d.ts +0 -82
- package/src/lib/model/lead-source-values.js +0 -149
- package/src/lib/model/lead-source-values.js.map +0 -1
- package/src/lib/model/leads-csv.d.ts +0 -40
- package/src/lib/model/leads-csv.js +0 -40
- package/src/lib/model/leads-csv.js.map +0 -1
- package/src/lib/model/tasks-csv.d.ts +0 -28
- package/src/lib/model/tasks-csv.js +0 -28
- package/src/lib/model/tasks-csv.js.map +0 -1
- package/src/lib/server/companies-import.d.ts +0 -57
- package/src/lib/server/companies-import.js +0 -242
- package/src/lib/server/companies-import.js.map +0 -1
- package/src/lib/server/contacts-import.d.ts +0 -109
- package/src/lib/server/contacts-import.js +0 -393
- package/src/lib/server/contacts-import.js.map +0 -1
- package/src/lib/server/deals-import.d.ts +0 -76
- package/src/lib/server/deals-import.js +0 -248
- package/src/lib/server/deals-import.js.map +0 -1
- package/src/lib/server/export-route.d.ts +0 -60
- package/src/lib/server/export-route.js +0 -447
- package/src/lib/server/export-route.js.map +0 -1
- package/src/lib/server/import-context.d.ts +0 -87
- package/src/lib/server/import-context.js +0 -182
- package/src/lib/server/import-context.js.map +0 -1
- package/src/lib/server/lead-source-values.d.ts +0 -50
- package/src/lib/server/lead-source-values.js +0 -191
- package/src/lib/server/lead-source-values.js.map +0 -1
- package/src/lib/server/leads-import.d.ts +0 -84
- package/src/lib/server/leads-import.js +0 -367
- package/src/lib/server/leads-import.js.map +0 -1
- package/src/lib/server/tasks-import.d.ts +0 -54
- package/src/lib/server/tasks-import.js +0 -160
- package/src/lib/server/tasks-import.js.map +0 -1
|
@@ -56,11 +56,36 @@ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_wi
|
|
|
56
56
|
* the client; the last sum stays until it is retyped. Changing the currency
|
|
57
57
|
* of a deal with lines needs the lines resent in that currency, because
|
|
58
58
|
* their sum is one number in one unit.
|
|
59
|
-
|
|
59
|
+
*
|
|
60
|
+
* ## Salesforce's Opportunity fields (AGL-3516)
|
|
61
|
+
*
|
|
62
|
+
* `type` and `leadSource` are judged against the org's `opportunityType`
|
|
63
|
+
* and `leadSource` picklists, as every door judges them: an active value
|
|
64
|
+
* is stored as the list spells it, a deal's own current value is kept, and
|
|
65
|
+
* anything else is a `400` naming the values allowed. A create with no
|
|
66
|
+
* `type` takes the list's default; `leadSource` is never defaulted.
|
|
67
|
+
* `forecastCategory` is one of a FIXED set. Every stage move stamps the new
|
|
68
|
+
* stage's `forecastCategory` and clears the `probability` override — a
|
|
69
|
+
* body that sets either beside the move wins. `campaignId` names one of the
|
|
70
|
+
* org's live campaigns.
|
|
71
|
+
*
|
|
72
|
+
* ## Contact roles (AGL-3521)
|
|
73
|
+
*
|
|
74
|
+
* `contactRoles` is the whole list of the deal's contacts — `{ contactId,
|
|
75
|
+
* role, primary }` — replaced as sent. Each contact must exist, none twice,
|
|
76
|
+
* at most one Primary, and each `role` is judged against the org's
|
|
77
|
+
* `opportunityContactRole` list (a contact's current role kept). The
|
|
78
|
+
* Primary IS `contactId`: a body that sends both must agree, and a body
|
|
79
|
+
* that sends `contactId` alone makes that contact Primary — added with no
|
|
80
|
+
* role when the deal did not name them — so an integration written before
|
|
81
|
+
* roles keeps meaning what it meant.
|
|
82
|
+
*/ import { CRM_COLLECTIONS, CRM_MEDIA_IDS_MAX, createResourceUid, CRM_FORECAST_CATEGORIES, crmListFieldsTouched, crmNewRecordListFields, DEAL_CONTACT_ROLES_MAX, DEAL_NEXT_STEP_MAX, dealContactRoleFields, dealContactRolesOf, dealContactRolesWithPrimary, dealPrimaryContactId, dealStageById, judgeDealContactRoles, dealStageMoveFields, lineItemsTotalCents, normalizeCrmMediaIds, readDealLineItems } from "@aglyn/aglyn/server";
|
|
60
83
|
import { apiJson, ApiErrors, restampCrmListFieldsAt } from "@aglyn/tenant-data-admin";
|
|
61
|
-
import { Timestamp } from "firebase-admin/firestore";
|
|
84
|
+
import { FieldValue, Timestamp } from "firebase-admin/firestore";
|
|
62
85
|
import { claimWrite, readJsonBody, requireScope } from "@aglyn/tenant-data-admin/server/api-v1-kit";
|
|
86
|
+
import { readOrgContainers } from "@aglyn/tenant-data-admin/server/org-containers";
|
|
63
87
|
import { floorContactLifecycleStage } from "../contact-lifecycle-floor.js";
|
|
88
|
+
import { readCrmPicklist, resolveCrmPicklistWrite } from "../read-picklist.js";
|
|
64
89
|
import { orderedStages, resolvePipeline } from "./crm-pipelines.js";
|
|
65
90
|
import { CRM_TEXT_MAX, CRM_TITLE_MAX, createPayload, crmCollection, crmCreateStamp, crmCustomUpdate, crmCustomView, crmRecordsBandRefusal, crmRefErrors, crmTimes, crmValidationFailed, isoFromMs, listCrm, memberError, parseIsoInstant, readChoice, readCrmCustomBody, readCrmSite, readEqualityFilters, readOptionalText, readRefId, refuseUnknownKeys, updatePayload } from "./crm-shared.js";
|
|
66
91
|
const DEAL_STATUSES = [
|
|
@@ -79,7 +104,7 @@ const DEAL_STATUSES = [
|
|
|
79
104
|
};
|
|
80
105
|
}
|
|
81
106
|
/** The deal object as published. Every writable field appears here. */ function dealView(doc) {
|
|
82
|
-
var _doc_data, _data_title, _data_pipelineId, _data_stageId, _data_status, _data_currency, _data_ownerUid, _data_contactId, _data_companyId, _data_lostReason, _data_notes, _data_hostId;
|
|
107
|
+
var _doc_data, _data_title, _data_pipelineId, _data_stageId, _data_status, _data_currency, _data_ownerUid, _data_contactId, _data_companyId, _data_lostReason, _data_notes, _data_type, _data_leadSource, _data_nextStep, _data_forecastCategory, _data_campaignId, _data_hostId;
|
|
83
108
|
const data = (_doc_data = doc.data()) != null ? _doc_data : {};
|
|
84
109
|
return _extends({
|
|
85
110
|
id: doc.id,
|
|
@@ -98,9 +123,26 @@ const DEAL_STATUSES = [
|
|
|
98
123
|
stageChangedAt: isoFromMs(data.stageChangedAtMs),
|
|
99
124
|
ownerUid: (_data_ownerUid = data.ownerUid) != null ? _data_ownerUid : null,
|
|
100
125
|
contactId: (_data_contactId = data.contactId) != null ? _data_contactId : null,
|
|
126
|
+
// Every contact on the deal and the part each plays (AGL-3521); the
|
|
127
|
+
// Primary is `contactId`.
|
|
128
|
+
contactRoles: dealContactRolesOf(data).map((row)=>{
|
|
129
|
+
var _row_role;
|
|
130
|
+
return {
|
|
131
|
+
contactId: row.contactId,
|
|
132
|
+
role: (_row_role = row.role) != null ? _row_role : null,
|
|
133
|
+
primary: row.primary
|
|
134
|
+
};
|
|
135
|
+
}),
|
|
101
136
|
companyId: (_data_companyId = data.companyId) != null ? _data_companyId : null,
|
|
102
137
|
lostReason: (_data_lostReason = data.lostReason) != null ? _data_lostReason : null,
|
|
103
138
|
notes: (_data_notes = data.notes) != null ? _data_notes : null,
|
|
139
|
+
// Salesforce's Opportunity fields (AGL-3516).
|
|
140
|
+
type: (_data_type = data.type) != null ? _data_type : null,
|
|
141
|
+
leadSource: (_data_leadSource = data.leadSource) != null ? _data_leadSource : null,
|
|
142
|
+
nextStep: (_data_nextStep = data.nextStep) != null ? _data_nextStep : null,
|
|
143
|
+
probability: typeof data.probability === 'number' ? data.probability : null,
|
|
144
|
+
forecastCategory: (_data_forecastCategory = data.forecastCategory) != null ? _data_forecastCategory : null,
|
|
145
|
+
campaignId: (_data_campaignId = data.campaignId) != null ? _data_campaignId : null,
|
|
104
146
|
// The org's deal custom fields, keyed by field key (AGL-2661).
|
|
105
147
|
custom: crmCustomView(data),
|
|
106
148
|
// When the earliest open task against the deal is due — see
|
|
@@ -124,8 +166,80 @@ const DEAL_WRITABLE = new Set([
|
|
|
124
166
|
'lostReason',
|
|
125
167
|
'notes',
|
|
126
168
|
'custom',
|
|
127
|
-
'mediaIds'
|
|
169
|
+
'mediaIds',
|
|
170
|
+
'type',
|
|
171
|
+
'leadSource',
|
|
172
|
+
'nextStep',
|
|
173
|
+
'probability',
|
|
174
|
+
'forecastCategory',
|
|
175
|
+
'campaignId',
|
|
176
|
+
'contactRoles'
|
|
177
|
+
]);
|
|
178
|
+
/** The keys one contact role takes. */ const CONTACT_ROLE_KEYS = new Set([
|
|
179
|
+
'contactId',
|
|
180
|
+
'role',
|
|
181
|
+
'primary'
|
|
128
182
|
]);
|
|
183
|
+
/**
|
|
184
|
+
* `contactRoles` as sent, shape-checked: a list of at most
|
|
185
|
+
* {@link DEAL_CONTACT_ROLES_MAX} entries, each naming a contact once, and
|
|
186
|
+
* at most one of them Primary. `null` is the empty list.
|
|
187
|
+
*/ function readContactRolesBody(raw, errors) {
|
|
188
|
+
if (raw === undefined) return undefined;
|
|
189
|
+
if (raw === null) return [];
|
|
190
|
+
if (!Array.isArray(raw)) {
|
|
191
|
+
errors.contactRoles = 'Must be a list of { contactId, role, primary }';
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
194
|
+
if (raw.length > DEAL_CONTACT_ROLES_MAX) {
|
|
195
|
+
errors.contactRoles = `At most ${DEAL_CONTACT_ROLES_MAX} contacts per deal`;
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
const seen = new Set();
|
|
199
|
+
let primaries = 0;
|
|
200
|
+
for (const [at, entry] of raw.entries()){
|
|
201
|
+
const row = entry && typeof entry === 'object' && !Array.isArray(entry) ? entry : null;
|
|
202
|
+
const contactId = typeof (row == null ? void 0 : row['contactId']) === 'string' ? row['contactId'].trim() : '';
|
|
203
|
+
const unknownKey = row ? Object.keys(row).find((key)=>!CONTACT_ROLE_KEYS.has(key)) : undefined;
|
|
204
|
+
if (!row || unknownKey) {
|
|
205
|
+
errors.contactRoles = unknownKey ? `Entry ${at}: unknown field ${unknownKey}` : `Entry ${at}: must be { contactId, role, primary }`;
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
if (!contactId || contactId.length > 200 || contactId.includes('/')) {
|
|
209
|
+
errors.contactRoles = `Entry ${at}: contactId must be a contact id`;
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
if (seen.has(contactId)) {
|
|
213
|
+
errors.contactRoles = `Entry ${at}: ${contactId} is on the list twice`;
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
seen.add(contactId);
|
|
217
|
+
if (row['role'] !== undefined && row['role'] !== null && typeof row['role'] !== 'string') {
|
|
218
|
+
errors.contactRoles = `Entry ${at}: role must be a contact role, or null`;
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
if (row['primary'] !== undefined && typeof row['primary'] !== 'boolean') {
|
|
222
|
+
errors.contactRoles = `Entry ${at}: primary must be true or false`;
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
if (row['primary'] === true) primaries += 1;
|
|
226
|
+
}
|
|
227
|
+
if (primaries > 1) {
|
|
228
|
+
errors.contactRoles = 'At most one contact may be Primary';
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
return raw.map((entry)=>{
|
|
232
|
+
const row = entry;
|
|
233
|
+
const role = typeof row['role'] === 'string' ? row['role'].trim() : '';
|
|
234
|
+
return _extends({
|
|
235
|
+
contactId: String(row['contactId']).trim()
|
|
236
|
+
}, role ? {
|
|
237
|
+
role
|
|
238
|
+
} : {}, {
|
|
239
|
+
primary: row['primary'] === true
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
}
|
|
129
243
|
/**
|
|
130
244
|
* The writable half of a deal, validated. `pipelineId` is accepted on a
|
|
131
245
|
* create only: a deal's stages are its pipeline's, and moving one between
|
|
@@ -219,6 +333,36 @@ const DEAL_WRITABLE = new Set([
|
|
|
219
333
|
if (lostReason !== undefined) values.lostReason = lostReason;
|
|
220
334
|
const notes = readOptionalText(body, 'notes', CRM_TEXT_MAX, errors);
|
|
221
335
|
if (notes !== undefined) values.notes = notes;
|
|
336
|
+
for (const key of [
|
|
337
|
+
'type',
|
|
338
|
+
'leadSource'
|
|
339
|
+
]){
|
|
340
|
+
const label = readOptionalText(body, key, CRM_TITLE_MAX, errors);
|
|
341
|
+
if (label !== undefined) values[key] = label;
|
|
342
|
+
}
|
|
343
|
+
const nextStep = readOptionalText(body, 'nextStep', DEAL_NEXT_STEP_MAX, errors);
|
|
344
|
+
if (nextStep !== undefined) values.nextStep = nextStep;
|
|
345
|
+
if (body.probability !== undefined) {
|
|
346
|
+
if (body.probability === null) {
|
|
347
|
+
values.probability = null;
|
|
348
|
+
} else if (typeof body.probability !== 'number' || !Number.isInteger(body.probability) || body.probability < 0 || body.probability > 100) {
|
|
349
|
+
errors.probability = 'Must be a whole number from 0 to 100, or null for the stage’s';
|
|
350
|
+
} else {
|
|
351
|
+
values.probability = body.probability;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
const forecastCategory = readChoice(body, 'forecastCategory', CRM_FORECAST_CATEGORIES, errors);
|
|
355
|
+
if (forecastCategory) values.forecastCategory = forecastCategory;
|
|
356
|
+
const campaignId = readRefId(body, 'campaignId', errors);
|
|
357
|
+
if (campaignId !== undefined) values.campaignId = campaignId;
|
|
358
|
+
const contactRoles = readContactRolesBody(body.contactRoles, errors);
|
|
359
|
+
if (contactRoles !== undefined) {
|
|
360
|
+
values.contactRoles = contactRoles;
|
|
361
|
+
// The Primary IS `contactId`, so a body naming both says one thing twice.
|
|
362
|
+
if (values.contactId !== undefined && values.contactId !== dealPrimaryContactId(contactRoles)) {
|
|
363
|
+
errors.contactId = 'Must name the Primary in contactRoles, or be left out';
|
|
364
|
+
}
|
|
365
|
+
}
|
|
222
366
|
// `custom` is shape-checked here and judged against the org's
|
|
223
367
|
// definitions by the writers, which is where the read is paid.
|
|
224
368
|
if (body.custom !== undefined) {
|
|
@@ -320,24 +464,116 @@ const DEAL_WRITABLE = new Set([
|
|
|
320
464
|
console.error('[api-v1] deals: the customer floor failed', contactId, error);
|
|
321
465
|
}
|
|
322
466
|
}
|
|
323
|
-
/**
|
|
324
|
-
|
|
467
|
+
/**
|
|
468
|
+
* The fields a stage move writes, beside the stage itself — and the new
|
|
469
|
+
* stage's forecast category with the probability override cleared
|
|
470
|
+
* (`dealStageMoveFields`, AGL-3516).
|
|
471
|
+
*/ function stageMove(stage, nowMs) {
|
|
472
|
+
return _extends({
|
|
325
473
|
stageId: stage.id,
|
|
326
474
|
status: stage.kind,
|
|
327
475
|
stageChangedAtMs: nowMs,
|
|
328
476
|
closedAtMs: stage.kind === 'open' ? null : nowMs
|
|
329
|
-
};
|
|
477
|
+
}, dealStageMoveFields(stage));
|
|
330
478
|
}
|
|
331
|
-
/**
|
|
332
|
-
|
|
333
|
-
|
|
479
|
+
/**
|
|
480
|
+
* The membership and reference checks a deal write makes, merged. A
|
|
481
|
+
* campaign is checked against the org's live campaigns, except the one the
|
|
482
|
+
* deal already names, which it keeps even once the campaign is retired.
|
|
483
|
+
*/ async function dealRefErrors(ctx, values, stored) {
|
|
484
|
+
var _values_campaignId, _values_contactId, _values_companyId;
|
|
485
|
+
const campaignId = (_values_campaignId = values.campaignId) != null ? _values_campaignId : undefined;
|
|
486
|
+
const [owner, refs, campaign, roles] = await Promise.all([
|
|
334
487
|
memberError(ctx, 'ownerUid', values.ownerUid),
|
|
335
488
|
crmRefErrors(ctx, {
|
|
336
489
|
contactId: (_values_contactId = values.contactId) != null ? _values_contactId : undefined,
|
|
337
490
|
companyId: (_values_companyId = values.companyId) != null ? _values_companyId : undefined
|
|
338
|
-
})
|
|
491
|
+
}),
|
|
492
|
+
campaignId && campaignId !== (stored == null ? void 0 : stored.campaignId) ? readOrgContainers(ctx.firestore, 'campaign', ctx.orgId, [
|
|
493
|
+
campaignId
|
|
494
|
+
]).then(([record])=>(record == null ? void 0 : record.live) ? {} : {
|
|
495
|
+
campaignId: 'No such campaign in this organization'
|
|
496
|
+
}) : Promise.resolve({}),
|
|
497
|
+
contactRoleRefErrors(ctx, values.contactRoles, stored)
|
|
339
498
|
]);
|
|
340
|
-
return _extends({}, owner, refs);
|
|
499
|
+
return _extends({}, owner, refs, campaign, roles);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Every contact a sent `contactRoles` adds to the deal must exist; one the
|
|
503
|
+
* deal already names is kept as it is, as a campaign is.
|
|
504
|
+
*/ async function contactRoleRefErrors(ctx, roles, stored) {
|
|
505
|
+
const held = new Set(stored ? dealContactRolesOf(stored).map((row)=>row.contactId) : []);
|
|
506
|
+
const added = (roles != null ? roles : []).map((row)=>row.contactId).filter((id)=>!held.has(id));
|
|
507
|
+
if (!added.length) return {};
|
|
508
|
+
const contacts = ctx.firestore.collection('orgs').doc(ctx.orgId).collection('contacts');
|
|
509
|
+
const snapshots = await ctx.firestore.getAll(...added.map((id)=>contacts.doc(id)));
|
|
510
|
+
const missing = snapshots.find((snapshot)=>!snapshot.exists);
|
|
511
|
+
return missing ? {
|
|
512
|
+
contactRoles: `No such contact in this organization: ${missing.id}`
|
|
513
|
+
} : {};
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* What a write stores for the deal's contacts (AGL-3521): `contactRoles`
|
|
517
|
+
* judged and `contactId` beside its Primary when the body sent the list;
|
|
518
|
+
* when it sent `contactId` alone, the stored roles with that contact as the
|
|
519
|
+
* Primary. Nothing, when it sent neither.
|
|
520
|
+
*/ async function dealContactRoleWrites(ctx, values, stored) {
|
|
521
|
+
const current = stored ? dealContactRolesOf(stored) : [];
|
|
522
|
+
if (values.contactRoles !== undefined) {
|
|
523
|
+
const judged = judgeDealContactRoles(await readCrmPicklist(ctx.firestore, ctx.orgId, 'opportunityContactRole'), values.contactRoles, current);
|
|
524
|
+
if (judged.ok === false) return {
|
|
525
|
+
errors: {
|
|
526
|
+
contactRoles: judged.error
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
return {
|
|
530
|
+
values: dealContactRoleFields(judged.roles)
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
if (values.contactId !== undefined) {
|
|
534
|
+
return {
|
|
535
|
+
values: dealContactRoleFields(dealContactRolesWithPrimary(current, values.contactId))
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
return {
|
|
539
|
+
values: {}
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* `type` and `leadSource` as the deal will store them, judged against the
|
|
544
|
+
* org's lists (AGL-3510's `resolveCrmPicklistWrite`): the values to write,
|
|
545
|
+
* or the refusals by field. Only a list the write touches is read — and the
|
|
546
|
+
* type list on every create, for its default.
|
|
547
|
+
*/ async function dealPicklistWrites(ctx, values, stored) {
|
|
548
|
+
const created = stored === null;
|
|
549
|
+
const fields = [
|
|
550
|
+
{
|
|
551
|
+
key: 'type',
|
|
552
|
+
id: 'opportunityType',
|
|
553
|
+
defaulted: created
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
key: 'leadSource',
|
|
557
|
+
id: 'leadSource',
|
|
558
|
+
defaulted: false
|
|
559
|
+
}
|
|
560
|
+
];
|
|
561
|
+
const written = {};
|
|
562
|
+
const errors = {};
|
|
563
|
+
for (const { key, id, defaulted } of fields){
|
|
564
|
+
if (values[key] === undefined && !defaulted) continue;
|
|
565
|
+
const judged = resolveCrmPicklistWrite(id, await readCrmPicklist(ctx.firestore, ctx.orgId, id), values[key], {
|
|
566
|
+
current: stored == null ? void 0 : stored[key],
|
|
567
|
+
created: defaulted
|
|
568
|
+
});
|
|
569
|
+
if (judged.ok === false) errors[key] = judged.error;
|
|
570
|
+
else if (judged.write !== undefined) written[key] = judged.write;
|
|
571
|
+
}
|
|
572
|
+
return Object.keys(errors).length ? {
|
|
573
|
+
errors
|
|
574
|
+
} : {
|
|
575
|
+
values: written
|
|
576
|
+
};
|
|
341
577
|
}
|
|
342
578
|
/**
|
|
343
579
|
* `POST /v1/deals`. The pipeline is resolved AFTER the claim because
|
|
@@ -357,18 +593,25 @@ const DEAL_WRITABLE = new Set([
|
|
|
357
593
|
const custom = await readCrmCustomBody(ctx, body, 'deal');
|
|
358
594
|
if (custom && 'errors' in custom) return crmValidationFailed(ctx, 'deal', custom.errors);
|
|
359
595
|
const customValues = custom && 'values' in custom ? custom.values : {};
|
|
596
|
+
// And against the org's picklists (AGL-3516), above the claim too.
|
|
597
|
+
const picklists = await dealPicklistWrites(ctx, parsed.values, null);
|
|
598
|
+
if ('errors' in picklists) return crmValidationFailed(ctx, 'deal', picklists.errors);
|
|
599
|
+
const roles = await dealContactRoleWrites(ctx, parsed.values, null);
|
|
600
|
+
if ('errors' in roles) return crmValidationFailed(ctx, 'deal', roles.errors);
|
|
360
601
|
const collection = crmCollection(ctx, CRM_COLLECTIONS.deals);
|
|
361
602
|
const claimed = await claimWrite(ctx, '*', request.headers.get('Idempotency-Key'), 'deals');
|
|
362
603
|
if ('replay' in claimed) return claimed.replay;
|
|
363
604
|
const { claim } = claimed;
|
|
364
605
|
try {
|
|
365
606
|
var _placed_stage;
|
|
366
|
-
const _parsed_values = parsed.values, { title, pipelineId, stageId, status, lineItems } = _parsed_values, rest = _object_without_properties_loose(_parsed_values, [
|
|
607
|
+
const _parsed_values = parsed.values, { title, pipelineId, stageId, status, lineItems, probability, forecastCategory } = _parsed_values, rest = _object_without_properties_loose(_parsed_values, [
|
|
367
608
|
"title",
|
|
368
609
|
"pipelineId",
|
|
369
610
|
"stageId",
|
|
370
611
|
"status",
|
|
371
|
-
"lineItems"
|
|
612
|
+
"lineItems",
|
|
613
|
+
"probability",
|
|
614
|
+
"forecastCategory"
|
|
372
615
|
]);
|
|
373
616
|
const placedLines = placeLineItems({
|
|
374
617
|
lineItems,
|
|
@@ -415,15 +658,20 @@ const DEAL_WRITABLE = new Set([
|
|
|
415
658
|
title,
|
|
416
659
|
titleLower: (title != null ? title : '').toLowerCase(),
|
|
417
660
|
pipelineId: resolved.id
|
|
418
|
-
}, createPayload(_extends({}, rest, placedLines.fields, stageMove(stage, stamp.createdAt.toMillis())
|
|
661
|
+
}, createPayload(_extends({}, rest, picklists.values, roles.values, placedLines.fields, stageMove(stage, stamp.createdAt.toMillis()), probability !== undefined ? {
|
|
662
|
+
probability
|
|
663
|
+
} : {}, forecastCategory ? {
|
|
664
|
+
forecastCategory
|
|
665
|
+
} : {})), Object.keys(customValues).length ? {
|
|
419
666
|
custom: createPayload(customValues)
|
|
420
667
|
} : {}, stamp);
|
|
421
668
|
// What the console's Deals list searches and filters by (AGL-3321).
|
|
422
669
|
await collection.doc(id).create(_extends({}, record, crmNewRecordListFields('deals', record)));
|
|
423
670
|
// A deal created won is a won deal: its contact is a customer from birth.
|
|
424
671
|
if (stage.kind === 'won') {
|
|
672
|
+
var _roles_values_contactId;
|
|
425
673
|
await floorWonDealContact(ctx, {
|
|
426
|
-
contactId: rest.contactId,
|
|
674
|
+
contactId: (_roles_values_contactId = roles.values.contactId) != null ? _roles_values_contactId : rest.contactId,
|
|
427
675
|
hostId: site.siteId
|
|
428
676
|
});
|
|
429
677
|
}
|
|
@@ -439,7 +687,7 @@ const DEAL_WRITABLE = new Set([
|
|
|
439
687
|
}
|
|
440
688
|
}
|
|
441
689
|
/** `PATCH /v1/deals/{id}`. */ async function updateDeal(request, ctx, ref) {
|
|
442
|
-
var _stored_currency;
|
|
690
|
+
var _stored_currency, _stored_contactId;
|
|
443
691
|
const body = await readJsonBody(request);
|
|
444
692
|
const parsed = readDealInput(body, {
|
|
445
693
|
partial: true
|
|
@@ -452,17 +700,23 @@ const DEAL_WRITABLE = new Set([
|
|
|
452
700
|
headers: ctx.headers
|
|
453
701
|
});
|
|
454
702
|
}
|
|
455
|
-
const
|
|
703
|
+
const stored = snap.data();
|
|
704
|
+
const refErrors = await dealRefErrors(ctx, parsed.values, stored);
|
|
456
705
|
if (Object.keys(refErrors).length) return crmValidationFailed(ctx, 'deal', refErrors);
|
|
457
706
|
const custom = await readCrmCustomBody(ctx, body, 'deal');
|
|
458
707
|
if (custom && 'errors' in custom) return crmValidationFailed(ctx, 'deal', custom.errors);
|
|
459
|
-
const
|
|
708
|
+
const picklists = await dealPicklistWrites(ctx, parsed.values, stored);
|
|
709
|
+
if ('errors' in picklists) return crmValidationFailed(ctx, 'deal', picklists.errors);
|
|
710
|
+
const roles = await dealContactRoleWrites(ctx, parsed.values, stored);
|
|
711
|
+
if ('errors' in roles) return crmValidationFailed(ctx, 'deal', roles.errors);
|
|
712
|
+
const _parsed_values = parsed.values, { title, stageId, status, lineItems, probability, forecastCategory } = _parsed_values, rest = _object_without_properties_loose(_parsed_values, [
|
|
460
713
|
"title",
|
|
461
714
|
"stageId",
|
|
462
715
|
"status",
|
|
463
|
-
"lineItems"
|
|
716
|
+
"lineItems",
|
|
717
|
+
"probability",
|
|
718
|
+
"forecastCategory"
|
|
464
719
|
]);
|
|
465
|
-
const stored = snap.data();
|
|
466
720
|
const storedLines = Array.isArray(stored.lineItems) && stored.lineItems.length > 0;
|
|
467
721
|
const keepsLines = storedLines && lineItems === undefined;
|
|
468
722
|
if (keepsLines && rest.amountCents !== undefined) {
|
|
@@ -483,7 +737,9 @@ const DEAL_WRITABLE = new Set([
|
|
|
483
737
|
const update = _extends({}, title !== undefined ? {
|
|
484
738
|
title,
|
|
485
739
|
titleLower: title.toLowerCase()
|
|
486
|
-
} : {}, updatePayload(_extends({}, rest, placedLines.fields)), custom && 'values' in custom ? crmCustomUpdate(custom.values) : {})
|
|
740
|
+
} : {}, updatePayload(_extends({}, rest, picklists.values, roles.values, placedLines.fields)), custom && 'values' in custom ? crmCustomUpdate(custom.values) : {}, roles.values.contactId !== undefined && roles.values.contactId !== ((_stored_contactId = stored.contactId) != null ? _stored_contactId : null) ? {
|
|
741
|
+
contactName: FieldValue.delete()
|
|
742
|
+
} : {});
|
|
487
743
|
// The write's one instant: `updatedAt`, and the stage move if there is one,
|
|
488
744
|
// so a deal closed at T reads updated at T.
|
|
489
745
|
const now = Timestamp.now();
|
|
@@ -510,16 +766,21 @@ const DEAL_WRITABLE = new Set([
|
|
|
510
766
|
won = placed.stage.kind === 'won' && current.status !== 'won';
|
|
511
767
|
}
|
|
512
768
|
}
|
|
769
|
+
// What the body set beside a stage move wins over what the stage stamps
|
|
770
|
+
// (AGL-3516); without a move, they are plain edits. `null` clears the
|
|
771
|
+
// override back to the stage's.
|
|
772
|
+
if (probability !== undefined) update['probability'] = probability;
|
|
773
|
+
if (forecastCategory) update['forecastCategory'] = forecastCategory;
|
|
513
774
|
if (Object.keys(update).length > 0) {
|
|
514
775
|
await ref.update(_extends({}, update, {
|
|
515
776
|
updatedAt: now
|
|
516
777
|
}));
|
|
517
|
-
// What the console's Deals list searches (AGL-3321).
|
|
518
|
-
if ('
|
|
778
|
+
// What the console's Deals list searches and filters by (AGL-3321, AGL-3516).
|
|
779
|
+
if (crmListFieldsTouched('deals', update)) await restampCrmListFieldsAt(ref, 'deals');
|
|
519
780
|
}
|
|
520
781
|
if (won) {
|
|
521
782
|
await floorWonDealContact(ctx, {
|
|
522
|
-
contactId:
|
|
783
|
+
contactId: roles.values.contactId !== undefined ? roles.values.contactId : stored.contactId,
|
|
523
784
|
hostId: stored.hostId
|
|
524
785
|
});
|
|
525
786
|
}
|
|
@@ -572,7 +833,11 @@ const DEAL_WRITABLE = new Set([
|
|
|
572
833
|
'companyId',
|
|
573
834
|
'pipelineId',
|
|
574
835
|
'ownerUid',
|
|
575
|
-
'status'
|
|
836
|
+
'status',
|
|
837
|
+
'type',
|
|
838
|
+
'leadSource',
|
|
839
|
+
'forecastCategory',
|
|
840
|
+
'campaignId'
|
|
576
841
|
]);
|
|
577
842
|
return listCrm(ctx, collection, url, filters, dealView);
|
|
578
843
|
}
|